tome-235-src/0000755000076400017500000000000011012107763010666 5ustar dgdgtome-235-src/lib/0000755000076400017500000000000011012107763011434 5ustar dgdgtome-235-src/lib/apex/0000755000076400017500000000000011012107763012371 5ustar dgdgtome-235-src/lib/apex/delete.me0000644000076400017500000000000111012107760014142 0ustar dgdgatome-235-src/lib/apex/.cvsignore0000644000076400017500000000001311012107760014360 0ustar dgdgscores.raw tome-235-src/lib/apex/scores.raw0000644000076400017500000001015011012107760014374 0ustar dgdg2.3.4 530559 100 2823010/18/07Oniatha 500m18 8 4 3 25 98 25 98 0 0 0 1an Osyluth2.3.4 168292 100 886610/18/07Oniatha 500m18 8 4 3 14 98 14 98 0 0 0 1a Greater Balrog2.3.4 48178 100 1038510/18/07Oniatha 500m18 8 4 3 3 96 3 98 0 0 0 1an Ice troll2.3.4 16174 100 54910/18/07Oniatha 500m18 8 4 3 7 98 7 98 0 0 0 1a Mountain ogre Mage2.3.4 12946 100 8810/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1an Inertia hound2.3.4 12946 100 17810/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Nether hound2.3.4 12946 100 25710/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Ninja2.3.4 12946 100 18810/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Small kobold2.3.4 12946 100 46410/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Half-troll2.3.4 12946 100 7410/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Forest troll2.3.4 12946 100 58110/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Grey wraith2.3.4 12946 100 11910/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Shardstorm2.3.4 12946 100 310/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1an Impact hound2.3.4 12946 100 13110/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Skeleton Dark elven warlock2.3.4 12946 100 1210/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Nexus vortex2.3.4 12946 100 74710/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Multi-hued hound2.3.4 12946 100 16310/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Catoblepas2.3.4 12946 100 1210/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Bodak2.3.4 12946 100 2310/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Water hound2.3.4 12946 100 28710/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Fire hound2.3.4 12946 100 58110/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Giant tarantula2.3.4 12946 100 135810/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Dread2.3.4 12946 100 2910/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1an Ethereal hound2.3.4 12946 100 25810/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1an Ancient blue dragon2.3.4 12946 100 38910/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Rattlesnake2.3.4 12946 100 104010/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Spectral Dracolisk2.3.4 12946 100 34810/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a White wraith2.3.4 12946 100 42910/18/07Oniatha 500m18 8 4 3 1 98 1 98 0 0 0 1a Nycadaemontome-235-src/lib/bone/0000755000076400017500000000000011012107763012357 5ustar dgdgtome-235-src/lib/bone/bone001.0120000644000076400017500000000002111012107760013735 0ustar dgdgTruigar 162 7 13 tome-235-src/lib/bone/bone004.0010000644000076400017500000000002011012107760013735 0ustar dgdgOlorin 13 21 10 tome-235-src/lib/bone/bone004.0020000644000076400017500000000002111012107760013737 0ustar dgdgPruirk 108 12 24 tome-235-src/lib/bone/bone004.0030000644000076400017500000000002011012107760013737 0ustar dgdgBearn 166 11 24 tome-235-src/lib/bone/bone004.0040000644000076400017500000000001711012107760013746 0ustar dgdgDruldo 64 19 0 tome-235-src/lib/bone/bone004.0050000644000076400017500000000001511012107760013745 0ustar dgdgSook 56 0 23 tome-235-src/lib/bone/bone004.0060000644000076400017500000000001511012107760013746 0ustar dgdgSook 55 0 23 tome-235-src/lib/bone/bone004.0070000644000076400017500000000001511012107760013747 0ustar dgdgSook 45 0 23 tome-235-src/lib/bone/bone004.0080000644000076400017500000000001511012107760013750 0ustar dgdgSook 44 0 23 tome-235-src/lib/bone/bone004.0090000644000076400017500000000001511012107760013751 0ustar dgdgSook 46 0 23 tome-235-src/lib/bone/bone004.0100000644000076400017500000000002211012107760013737 0ustar dgdgLuthien 114 20 22 tome-235-src/lib/data/0000755000076400017500000000000011012107763012345 5ustar dgdgtome-235-src/lib/data/delete.me0000644000076400017500000000000011012107760014115 0ustar dgdgtome-235-src/lib/data/.cvsignore0000644000076400017500000000002011012107760014332 0ustar dgdg.cvsignore *.rawtome-235-src/lib/cmov/0000755000076400017500000000000011012107763012400 5ustar dgdgtome-235-src/lib/cmov/delete.me0000644000076400017500000000000111012107760014151 0ustar dgdgatome-235-src/lib/core/0000755000076400017500000000000011012107763012364 5ustar dgdgtome-235-src/lib/core/xml.lua0000644000076400017500000002214211012107760013665 0ustar dgdg-- The xml module xml = {} function xml:parseargs (s) local arg = {} gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a) %arg[w] = a end) return arg end -- s is a xml stream, returns a table function xml:collect (s) local stack = {n=0} local top = {n=0} tinsert(stack, top) local ni,c,label,args, empty local i, j = 1, 1 while 1 do ni,j,c,label,args, empty = strfind(s, "<(%/?)(%w+)(.-)(%/?)>", j) if not ni then break end local text = strsub(s, i, ni-1) if not strfind(text, "^%s*$") then tinsert(top, text) end if empty == "/" then -- empty element tag tinsert(top, {n=0, label=label, args=xml:parseargs(args), empty=1}) elseif c == "" then -- start tag top = {n=0, label=label, args=xml:parseargs(args)} tinsert(stack, top) -- new level else -- end tag local toclose = tremove(stack) -- remove top top = stack[stack.n] if stack.n < 1 then error("nothing to close with "..label) end if toclose.label ~= label then error("trying to close "..toclose.label.." with "..label) end tinsert(top, toclose) end i = j+1 end local text = strsub(s, i) if not strfind(text, "^%s*$") then tinsert(stack[stack.n], text) end if stack.n > 1 then error("unclosed "..stack[stack.n].label) end return stack[1] end -- Viewport coordinates xml.write_out_y = 0 xml.write_out_x = 0 xml.write_out_h = 24 xml.write_out_w = 80 -- Offsets xml.write_off_y = 0 xml.write_off_x = 0 -- Current position xml.write_y = 0 xml.write_x = 0 xml.write_screen = function(color, s) local i for i = 1, strlen(s) do local c = strsub(s, i, i + 1) if c ~= "\n" then if xml.write_y - xml.write_off_y >= 0 and xml.write_y - xml.write_off_y < xml.write_out_h and xml.write_x - xml.write_off_x >= 0 and xml.write_x - xml.write_off_x < xml.write_out_w then Term_putch(xml.write_x - xml.write_off_x + xml.write_out_x, xml.write_y - xml.write_off_y + xml.write_out_y, color, strbyte(c)) end xml.write_x = xml.write_x + 1 else xml.write_x = 0 xml.write_y = xml.write_y + 1 end end end xml.write_file = function (color, s) print_hook(s) end xml.write = xml.write_screen xml.rule2string = { ['name'] = {"Its ", "name", " is"}, ['contain'] = {"Its ", "name", " contains"}, ['symbol'] = {"Its ", "symbol", " is"}, ['inscribed'] = {"Its ", "inscription", " contains"}, ['state'] = {"Its ", "state", " is"}, ['status'] = {"Its ", "status", " is"}, ['tval'] = {"Its ", "tval", " is"}, ['race'] = {"Your ", "race", " is"}, ['subrace'] = {"Your ", "subrace", " is"}, ['class'] = {"Your ", "class", " is"}, ['foo1'] = {"The result of ", "test 1 ", "is"}, ['foo2'] = {"The result of ", "test 2 ", "is"}, ['foo3'] = {"The result of ", "test 3 ", "is"}, } xml.display_english = 1 function xml:display_xml(t, tab) if xml.display_english then xml:english_xml(t, tab) else xml:print_xml(t, tab) end end function xml:english_xml(t, tab, not_flag) local i, k, e local pre, post, recurse local children_not_flag local nextlevel local bcol, ecol = TERM_L_GREEN, TERM_GREEN if xml.write_active and t == auto_aux.rule then bcol, ecol = TERM_VIOLET, TERM_VIOLET end nextlevel = tab .. " " recurse = 1 if t.label == "rule" then if t.args.type == "inscribe" then xml.write(TERM_WHITE, tab) xml.write(ecol, "A rule named \"") xml.write(TERM_WHITE, tostring(t.args.name)) xml.write(ecol, "\" to ") xml.write(bcol, "inscribe") xml.write(ecol, " an item with \"") xml.write(TERM_WHITE, t.args.inscription) xml.write(ecol, "\" when") xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "A rule named \"") xml.write(TERM_WHITE, tostring(t.args.name)) xml.write(ecol, "\" to ") xml.write(bcol, t.args.type) xml.write(ecol, " when") xml.write(TERM_WHITE, "\n") end elseif t.label == "and" then if not_flag then xml.write(TERM_WHITE, tab) xml.write(ecol, "At least one of the following is false:") xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "All of the following are true:") xml.write(TERM_WHITE, "\n") end elseif t.label == "or" then if not_flag then xml.write(TERM_WHITE, tab) xml.write(ecol, "All of the following are false:") xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "At least one of the following are true:") xml.write(TERM_WHITE, "\n") end elseif t.label == "not" then if bcol == TERM_VIOLET or getn(t) == 0 then xml.write(ecol, "(a negating rule)") xml.write(TERM_WHITE, "\n") else nextlevel = tab end children_not_flag = not nil elseif t.label == "comment" then xml.write(TERM_WHITE, tab) xml.write(TERM_WHITE, "(" .. t[1] .. ")") xml.write(TERM_WHITE, "\n") elseif t.label == "skill" then local s = t[1] if not_flag then xml.write(TERM_WHITE, tab) xml.write(ecol, "Your skill in ") xml.write(bcol, s) xml.write(ecol, " is not from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "Your skill in ") xml.write(bcol, s) xml.write(ecol, " is from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") end elseif t.label == "ability" then local s = t[1] if not_flag then xml.write(TERM_WHITE, tab) xml.write(ecol, "You do not have the ") xml.write(bcol, s) xml.write(ecol, " ability") xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "You have the ") xml.write(bcol, s) xml.write(ecol, " ability") xml.write(TERM_WHITE, "\n") end elseif t.label == "level" then if not_flag then xml.write(TERM_WHITE, tab) xml.write(ecol, "Your ") xml.write(bcol, "level") xml.write(ecol, " is not from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "Your ") xml.write(bcol, "level") xml.write(ecol, " is from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") end elseif t.label == "sval" then if not_flag then xml.write(TERM_WHITE, tab) xml.write(ecol, "Its ") xml.write(bcol, "sval") xml.write(ecol, " is not from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "Its ") xml.write(bcol, "sval") xml.write(ecol, " is from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") end elseif t.label == "discount" then if not_flag then xml.write(TERM_WHITE, tab) xml.write(ecol, "Its ") xml.write(bcol, "discount") xml.write(ecol, " is not from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") else xml.write(TERM_WHITE, tab) xml.write(ecol, "Its ") xml.write(bcol, "discount") xml.write(ecol, " is from ") xml.write(TERM_WHITE, tostring(t.args.min)) xml.write(ecol, " to ") xml.write(TERM_WHITE, tostring(t.args.max)) xml.write(TERM_WHITE, "\n") end else if xml.rule2string[t.label] then local rule = xml.rule2string[t.label] a, b, c = rule[1], rule[2], rule[3] if not_flag then c = c .. " not" end xml.write(TERM_WHITE, tab) xml.write(ecol, a) xml.write(bcol, b) xml.write(ecol, c) xml.write(ecol, " \"") xml.write(TERM_WHITE, t[1]) xml.write(ecol, "\"") xml.write(TERM_WHITE, "\n") else if not_flag then xml.write(bcol, "Not:\n") tab = tab .. " " xml:print_xml(t, tab) return end end end for i = 1, getn(t) do if type(t[i]) == "string" then -- xml.write(TERM_WHITE, t[i].."\n") else xml:english_xml(t[i], nextlevel, children_not_flag) end end end function xml:print_xml(t, tab) local i, k, e local inside = nil local bcol, ecol = TERM_L_GREEN, TERM_GREEN if xml.write_active and t == auto_aux.rule then bcol, ecol = TERM_VIOLET, TERM_VIOLET end xml.write(bcol, tab.."<"..t.label) for k, e in t.args do xml.write(TERM_L_BLUE, " "..k) xml.write(TERM_WHITE, "=\"") xml.write(TERM_YELLOW, e) xml.write(TERM_WHITE, "\"") end xml.write(bcol, ">") for i = 1, getn(t) do if type(t[i]) == "string" then xml.write(TERM_WHITE, t[i]) else if not inside then xml.write(TERM_WHITE, "\n") end inside = not nil xml:print_xml(t[i], tab.." ") end end if not inside then xml.write(ecol, "\n") else xml.write(ecol, tab.."\n") end end -- t is a table representing xml, outputs the xml code via xml.write() function xml:output(t) local i for i = 1, getn(t) do xml:print_xml(t[i], "") end end tome-235-src/lib/core/crpt_aux.lua0000644000076400017500000001434511012107760014720 0ustar dgdg-- Core functions for corruptions __corruptions = {} __corruptions_max = 0 __corruptions_callbacks_max = 0 -- Get the corruption function player.corruption(c, set) if set then player.corruptions_aux[c + 1] = set player.redraw = bor(player.redraw, PR_BASIC) player.update = bor(player.update, PU_BONUS, PU_TORCH, PU_BODY, PU_POWERS) if (set == TRUE) and (__corruptions[c].gain) then __corruptions[c].gain() end if (set == FALSE) and (__corruptions[c].lose) then __corruptions[c].lose() end else return player.corruptions_aux[c + 1] end end -- Test if we have that corruption -- We must: -- 1) have it or be willing to get it -- 2) have all its dependancies -- 3) have none of its opposing corruptions -- 4) pass the possible tests function test_depend_corrupt(corrupt, can_gain) local i, c if not can_gain then can_gain = FALSE end if can_gain == TRUE then if (player.corruption(corrupt) ~= FALSE) then return FALSE end else if (player.corruption(corrupt) ~= TRUE) then return FALSE end end for c, i in __corruptions[corrupt].depends do if test_depend_corrupt(c) ~= TRUE then return FALSE end end for c, i in __corruptions[corrupt].oppose do if test_depend_corrupt(c) ~= FALSE then return FALSE end end -- are we even allowed to get it? if __corruptions[corrupt].can_gain and (not __corruptions[corrupt].can_gain()) then return FALSE end return TRUE end -- Gain a new corruption function gain_corruption(group) local i, max local pos = {} -- Get the list of all possible ones max = 0 for i = 0, __corruptions_max - 1 do if __corruptions[i].group == group and test_depend_corrupt(i, TRUE) == TRUE and __corruptions[i].random == TRUE and __corruptions[i].allow() then pos[max] = i max = max + 1 end end -- Ok now get one of them if (max > 0) then local ret = rand_int(max) player.corruption(pos[ret], TRUE) cmsg_print(TERM_L_RED, __corruptions[pos[ret]].get_text) return pos[ret] else return -1 end end -- Lose an existing corruption function lose_corruption() local i, max local pos = {} -- Get the list of all possible ones max = 0 for i = 0, __corruptions_max - 1 do if test_depend_corrupt(i) == TRUE and __corruptions[i].removable == TRUE then pos[max] = i max = max + 1 end end -- Ok now get one of them if (max > 0) then local ret = rand_int(max) player.corruption(pos[ret], FALSE) cmsg_print(TERM_L_RED, __corruptions[pos[ret]].lose_text) -- Ok now lets see if it broke some dependancies for i = 0, max - 1 do if player.corruption(pos[i]) ~= test_depend_corrupt(pos[i]) then player.corruption(pos[i], FALSE) cmsg_print(TERM_L_RED, __corruptions[pos[i]].lose_text) end end return pos[ret] else return -1 end end -- Lose all corruptions (for e.g. Potion of New Life) function lose_all_corruptions() local i; for i = 0, __corruptions_max - 1 do lose_corruption() end return -1 end -- Creates a new corruption function add_corruption(c) assert(c.color, "No corruption color") assert(c.name, "No corruption name") assert(c.get_text, "No corruption get_text") assert(c.lose_text, "No corruption lose_text") assert(c.desc, "No corruption desc") assert(c.hooks, "Nothing to do for corruption") if not c.random then c.random = TRUE end if not c.removable then c.removable = TRUE end if not c.allow then c.allow = function() return not nil end end if c.depends == nil then c.depends = {} end if c.oppose == nil then c.oppose = {} end -- We must make sure the other ones opposes too local o, i for o, i in c.oppose do __corruptions[o].oppose[__corruptions_max] = TRUE end local index, h for index, h in c.hooks do add_hook_script(index, "__lua__corrupt_callback"..__corruptions_callbacks_max, "__lua__corrupt_callback"..__corruptions_callbacks_max) setglobal("__lua__corrupt_callback"..__corruptions_callbacks_max, function (...) if test_depend_corrupt(%__corruptions_max) == TRUE then return call(%h, arg) end end ) __corruptions_callbacks_max = __corruptions_callbacks_max + 1 end if type(c.desc) == "table" then local new_desc = "" for index, h in c.desc do new_desc = new_desc..h.."\n" end c.desc = new_desc end __corruptions[__corruptions_max] = c __corruptions_max = __corruptions_max + 1 return (__corruptions_max - 1) end ---------- Corruption spoiler generator ----------- function corruption_spoiler_generate() make_temp_file() print_hook( [[~~~~~01|Corruptions (Spoiler) ~~~~~02|Spoilers|Corruptions #####R=== ToME Corruptions Spoiler === Sometimes adventurers become exposed to the dark powers of Morgoth. If they are unable to resist these powers, they become corrupted. Corruptions can change their physical or mental abilities, some of which can be good, and some bad. Most corruptions will affect you permanently, although some only operate when they are activated (whether by player choice or as a random event). You can check which corruptions you have in the knowledge screen 6 (accessed through the '~' menu) or in a character dump. #####GGaining and (not) losing corruptions There are several ways that you can become corrupted. You can become corrupted by quaffing a Potion of Corruption or by drinking from a Fountain of Corruption. Also some strange items can be activated for corruption. Corruptions are permanent. Once you have one, you have it for life. ]]) local i, e for i = 0, __corruptions_max - 1 do print_hook("[[[[[B"..__corruptions[i].name.."]\n") print_hook(__corruptions[i].desc) print_hook("[[[[[GGain message: "..__corruptions[i].get_text.."]\n") if __corruptions[i].removable == TRUE then print_hook("[[[[[RLose message: "..__corruptions[i].lose_text.."]\n") else print_hook("It is not removable.\n") end local ok ok = nil for e, _ in __corruptions[i].depends do ok = not nil end if ok then print_hook("It depends on:\n") for e, _ in __corruptions[i].depends do print_hook(" "..__corruptions[e].name.."\n") end end ok = nil for e, _ in __corruptions[i].oppose do ok = not nil end if ok then print_hook("It is opposed to:\n") for e, _ in __corruptions[i].oppose do print_hook(" "..__corruptions[e].name.."\n") end end print_hook("\n\n") end close_temp_file() msg_print("File created as: "..get_temp_name()) end tome-235-src/lib/core/s_aux.lua0000644000076400017500000004171511012107760014213 0ustar dgdg-- Functions to help with spells, do not touch __schools = {} __schools_num = 0 __tmp_spells = {} __tmp_spells_num = 0 function add_school(s) __schools[__schools_num] = s __schools_num = __schools_num + 1 return (__schools_num - 1) end function finish_school(i) local s s = __schools[i] assert(s.name, "No school name!") assert(s.skill, "No school skill!") -- Need hooks? if s.hooks then add_hooks(s.hooks) end new_school(i, s.name, s.skill) end function add_spell(s) __tmp_spells[__tmp_spells_num] = s __tmp_spells_num = __tmp_spells_num + 1 return (__tmp_spells_num - 1) end function finish_spell(must_i) local i, s s = __tmp_spells[must_i] assert(s.name, "No spell name!") assert(s.school, "No spell school!") assert(s.level, "No spell level!") assert(s.mana, "No spell mana!") if not s.mana_max then s.mana_max = s.mana end assert(s.fail, "No spell failure rate!") assert(s.spell, "No spell function!") if not s.info then s.info = function() return "" end end assert(s.desc, "No spell desc!") if not s.random then s.random = SKILL_MAGIC end if s.lasting then assert(type(s.lasting) == "function", "Spell lasting is not function") end if s.stick then local k, e for k, e in s.stick do if type(k) == "table" then assert(e.base_level, "Arg no stick base level") assert(e.max_level, "Arg no stick max level") end end end i = new_spell(must_i, s.name) assert(i == must_i, "ACK ! i != must_i ! please contact the maintainer") if type(s.school) == "number" then __spell_school[i] = {s.school} else __spell_school[i] = s.school end spell(i).mana = s.mana spell(i).mana_max = s.mana_max spell(i).fail = s.fail spell(i).skill_level = s.level __spell_spell[i] = s.spell __spell_info[i] = s.info __spell_desc[i] = s.desc return i end -- Creates the school books array __spell_spell = {} __spell_info = {} __spell_desc = {} __spell_school = {} school_book = {} -- Find a spell by name function find_spell(name) local i i = 0 while (i < __tmp_spells_num) do if __tmp_spells[i].name == name then return i end i = i + 1 end return -1 end -- Find if the school is under the influence of a god, returns nil or the level function get_god_level(sch) if __schools[sch].gods[player.pgod] then return (s_info[__schools[sch].gods[player.pgod].skill + 1].value * __schools[sch].gods[player.pgod].mul) / __schools[sch].gods[player.pgod].div else return nil end end -- Change this fct if I want to switch to learnable spells function get_level_school(s, max, min) local lvl, sch, index, num, bonus local allow_spell_power = TRUE lvl = 0 num = 0 bonus = 0 -- No max specified ? assume 50 if not max then max = 50 end if not min then min = 1 end -- Do we pass tests? if __tmp_spells[s].depend then if __tmp_spells[s].depend() ~= TRUE then return min, "n/a" end end for index, sch in __spell_school[s] do local r, s, p, ok = 0, 0, 0, 0 -- Does it require we worship a specific god? if __schools[sch].god then if __schools[sch].god ~= player.pgod then if min then return min, "n/a" else return 1, "n/a" end end end -- Take the basic skill value r = s_info[(school(sch).skill) + 1].value -- Do we pass tests? if __schools[sch].depend then if __schools[sch].depend() ~= TRUE then return min, "n/a" end end -- Are we under sorcery effect ? if __schools[sch].sorcery then s = s_info[SKILL_SORCERY + 1].value end -- Are we affected by spell power ? -- All teh schools must allow it for it to work if not __schools[sch].spell_power then allow_spell_power = nil end -- Are we under a god effect ? if __schools[sch].gods then p = get_god_level(sch) if not p then p = 0 end end -- Find the higher ok = r if ok < s then ok = s end if ok < p then ok = p end -- Do we need to add a special bonus ? if __schools[sch].bonus_level then bonus = bonus + (__schools[sch].bonus_level() * (SKILL_STEP / 10)) end -- All schools must be non zero to be able to use it if ok == 0 then return min, "n/a" end -- Apply it lvl = lvl + ok num = num + 1 end -- Add the Spellpower skill as a bonus if allow_spell_power then bonus = bonus + (get_skill_scale(SKILL_SPELL, 20) * (SKILL_STEP / 10)) end -- Add bonus from objects bonus = bonus + (player.to_s * (SKILL_STEP / 10)) -- / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative -- The loss of information should be negligible since 1 skill = 1000 internally lvl = (lvl / num) / 10 lvl = lua_get_level(s, lvl, max, min, bonus) return lvl, nil end -- This is the function to use when casting through a stick function get_level_device(s, max, min) local lvl -- No max specified ? assume 50 if not max then max = 50 end lvl = s_info[SKILL_DEVICE + 1].value lvl = lvl + (get_level_use_stick * SKILL_STEP) -- Sticks are limited if lvl - ((spell(s).skill_level + 1) * SKILL_STEP) >= get_level_max_stick * SKILL_STEP then lvl = (get_level_max_stick + spell(s).skill_level - 1) * SKILL_STEP end -- / 10 because otherwise we can overflow a s32b and we can use a u32b because the value can be negative -- The loss of information should be negligible since 1 skill = 1000 internally lvl = lvl / 10 if not min then lvl = lua_get_level(s, lvl, max, 1, 0) else lvl = lua_get_level(s, lvl, max, min, 0) end return lvl end -- The real get_level, works for schooled magic and for innate powers get_level_use_stick = -1 get_level_max_stick = -1 function get_level(s, max, min) if type(s) == "number" then -- Ahah shall we use Magic device instead ? if get_level_use_stick > -1 then return get_level_device(s, max, min) else local lvl, na = get_level_school(s, max, min) return lvl end else return get_level_power(s, max, min) end end -- Can we cast the spell ? function is_ok_spell(s, obj) if get_level(s, 50, 0) == 0 then return nil end if __tmp_spells[s].pval and obj.pval < __tmp_spells[s].pval then return nil end return 1 end -- Get the amount of mana(or power) needed function get_mana(s) return spell(s).mana + get_level(s, spell(s).mana_max - spell(s).mana, 0) end -- Return the amount of power(mana, piety, whatever) for the spell function get_power(s) if check_affect(s, "piety", FALSE) then return player.grace else return player.csp end end -- Return the amount of power(mana, piety, whatever) for the spell function get_power_name(s) if check_affect(s, "piety", FALSE) then return "piety" else return "mana" end end -- Changes the amount of power(mana, piety, whatever) for the spell function adjust_power(s, x) if check_affect(s, "piety", FALSE) then inc_piety(GOD_ALL, x) else increase_mana(x) end end -- Print the book and the spells function print_book(book, spl, obj) local x, y, index, sch, size, s x = 0 y = 2 size = 0 -- Hack if the book is 255 it is a random book if book == 255 then school_book[book] = {spl} end -- Parse all spells for index, s in school_book[book] do local color = TERM_L_DARK local lvl, na = get_level_school(s, 50, -50) local xx, sch_str if is_ok_spell(s, obj) then if get_mana(s) > get_power(s) then color = TERM_ORANGE else color = TERM_L_GREEN end end xx = nil sch_str = "" for index, sch in __spell_school[s] do if xx then sch_str = sch_str.."/"..school(sch).name else xx = 1 sch_str = sch_str..school(sch).name end end if na then c_prt(color, format("%c) %-20s%-16s %3s %4s %3d%s %s", size + strbyte("a"), spell(s).name, sch_str, na, get_mana(s), spell_chance(s), "%", __spell_info[s]()), y, x) else c_prt(color, format("%c) %-20s%-16s %3d %4s %3d%s %s", size + strbyte("a"), spell(s).name, sch_str, lvl, get_mana(s), spell_chance(s), "%", __spell_info[s]()), y, x) end y = y + 1 size = size + 1 end prt(format(" %-20s%-16s Level Cost Fail Info", "Name", "School"), 1, x) return y end -- Output the describtion when it is used as a spell function print_spell_desc(s, y) local index, desc, x x = 0 if type(__spell_desc[s]) == "string" then c_prt(TERM_L_BLUE, __spell_desc[s], y, x) else for index, desc in __spell_desc[s] do c_prt(TERM_L_BLUE, desc, y, x) y = y + 1 end end if check_affect(s, "piety", FALSE) then c_prt(TERM_L_WHITE, "It uses piety to cast.", y, x) y = y + 1 end if not check_affect(s, "blind") then c_prt(TERM_ORANGE, "It is castable even while blinded.", y, x) y = y + 1 end if not check_affect(s, "confusion") then c_prt(TERM_ORANGE, "It is castable even while confused.", y, x) y = y + 1 end end -- Output the desc when sued as a device function print_device_desc(s) local index, desc if type(__spell_desc[s]) == "string" then text_out(__spell_desc[s]) else for index, desc in __spell_desc[s] do text_out("\n" .. desc) end end end function book_spells_num(book) local size, index, sch size = 0 -- Hack if the book is 255 it is a random book if book == 255 then return 1 end -- Parse all spells for index, s in school_book[book] do size = size + 1 end return size end function spell_x(book, spl, s) if book == 255 then return spl else local i, x, val i, val = next(school_book[book], nil) x = 0 while x < s do i, val = next(school_book[book], i) x = x + 1 end return val end end function spell_in_book(book, spell) local i, s for i, s in school_book[book] do if s == spell then return TRUE end end return FALSE end -- Returns spell chance of failure for spell function spell_chance(s) local chance, s_ptr s_ptr = spell(s) -- Extract the base spell failure rate if get_level_use_stick > -1 then chance = lua_spell_device_chance(s_ptr.fail, get_level(s, 50), s_ptr.skill_level) else chance = lua_spell_chance(s_ptr.fail, get_level(s, 50), s_ptr.skill_level, get_mana(s), get_power(s), get_spell_stat(s)) end -- Return the chance return chance end function check_affect(s, name, default) local s_ptr = __tmp_spells[s] local a if type(s_ptr[name]) == "number" then a = s_ptr[name] else a = default end if a == FALSE then return nil else return TRUE end end -- Returns the stat to use for the spell, INT by default function get_spell_stat(s) if not __tmp_spells[s].stat then return A_INT else return __tmp_spells[s].stat end end function cast_school_spell(s, s_ptr, no_cost) local use = FALSE -- No magic if (player.antimagic > 0) then msg_print("Your anti-magic field disrupts any magic attempts.") return end -- No magic if (player.anti_magic == TRUE) then msg_print("Your anti-magic shell disrupts any magic attempts.") return end -- if it costs something then some condition must be met if not no_cost then -- Require lite if (check_affect(s, "blind")) and ((player.blind > 0) or (no_lite() == TRUE)) then msg_print("You cannot see!") return end -- Not when confused if (check_affect(s, "confusion")) and (player.confused > 0) then msg_print("You are too confused!") return end -- Enough mana if (get_mana(s) > get_power(s)) then if (get_check("You do not have enough "..get_power_name(s)..", do you want to try anyway?") == FALSE) then return end end -- Invoke the spell effect if (magik(spell_chance(s)) == FALSE) then if (__spell_spell[s]() ~= nil) then use = TRUE end else local index, sch -- added because this is *extremely* important --pelpel if (flush_failure) then flush() end msg_print("You failed to get the spell off!") for index, sch in __spell_school[s] do if __schools[sch].fail then __schools[sch].fail(spell_chance(s)) end end use = TRUE end else __spell_spell[s]() end if use == TRUE then -- Reduce mana adjust_power(s, -get_mana(s)) -- Take a turn if is_magestaff() == TRUE then energy_use = 80 else energy_use = 100 end end player.redraw = bor(player.redraw, PR_MANA) player.window = bor(player.window, PW_PLAYER) end -- Helper functions HAVE_ARTIFACT = 0 HAVE_OBJECT = 1 HAVE_EGO = 2 function have_object(mode, type, find, find2) local o, i, min, max max = 0 min = 0 if band(mode, USE_EQUIP) == USE_EQUIP then min = INVEN_WIELD max = INVEN_TOTAL end if band(mode, USE_INVEN) == USE_INVEN then min = 0 if max == 0 then max = INVEN_WIELD end end i = min while i < max do o = get_object(i) if o.k_idx ~= 0 then if type == HAVE_ARTIFACT then if find == o.name1 then return i end end if type == HAVE_OBJECT then if find2 == nil then if find == o.k_idx then return i end else if (find == o.tval) and (find2 == o.sval) then return i end end end if type == HAVE_EGO then if (find == o.name2) or (find == o.name2b) then return i end end end i = i + 1 end return -1 end -- Can the spell be randomly found(in random books) function can_spell_random(i) return __tmp_spells[i].random end -- Find a random spell function get_random_spell(typ, level) local spl, tries tries = 1000 while tries > 0 do tries = tries - 1 spl = rand_int(__tmp_spells_num) if (can_spell_random(spl) == typ) and (rand_int(spell(spl).skill_level * 3) < level) then break end end if tries > 0 then return spl else return -1 end end -- Execute a lasting spell function exec_lasting_spell(spl) assert(__tmp_spells[spl].lasting, "No lasting effect for spell "..__tmp_spells[spl].name.." but called as such") return __tmp_spells[spl].lasting() end -- Helper function for spell effect to know if they are or not obvious function is_obvious(effect, old) if old then if old == TRUE or effect == TRUE then return TRUE else return FALSE end else return effect end end -------------------------Sticks------------------------- -- Fire off the spell function activate_stick(spl) local ret = __spell_spell[spl]() local charge, obvious if not ret then charge = FALSE obvious = FALSE else charge = TRUE obvious = ret end return obvious, charge end ----------------------------------- Wand, Staves, Rods specific functions ---------------------------- -- Get a spell for a given stick(wand, staff, rod) function get_random_stick(stick, level) local spl, tries tries = 1000 while tries > 0 do tries = tries - 1 spl = rand_int(__tmp_spells_num) if __tmp_spells[spl].stick and (type(__tmp_spells[spl].stick[stick]) == "table") then if (rand_int(spell(spl).skill_level * 3) < level) and (magik(100 - __tmp_spells[spl].stick[stick].rarity) == TRUE) then break end end end if tries > 0 then return spl else return -1 end end -- Get a random base level function get_stick_base_level(stick, level, spl) -- Paranoia if spl < 0 or spl >= __tmp_spells_num or not __tmp_spells[spl].stick[stick] then return 0 end local min, max = __tmp_spells[spl].stick[stick].base_level[1], __tmp_spells[spl].stick[stick].base_level[2] local range = max - min; -- Ok the basic idea is to have a max possible level of half the dungeon level if range * 2 > level then range = level / 2 end -- Randomize a bit range = m_bonus(range, dun_level) -- And get the result return min + range end -- Get a random max level function get_stick_max_level(stick, level, spl) -- Paranoia if spl < 0 or spl >= __tmp_spells_num or not __tmp_spells[spl].stick[stick] then return 0 end local min, max = __tmp_spells[spl].stick[stick].max_level[1], __tmp_spells[spl].stick[stick].max_level[2] local range = max - min; -- Ok the basic idea is to have a max possible level of half the dungeon level if range * 2 > level then range = level / 2 end -- Randomize a bit range = m_bonus(range, dun_level) -- And get the result return min + range end -- Get the number of desired charges function get_stick_charges(spl) return __tmp_spells[spl].stick.charge[1] + randint(__tmp_spells[spl].stick.charge[2]); end -- Get activation desc function get_activation_desc(spl) local turns if type(__tmp_spells[spl].activate) == 'number' then turns = __tmp_spells[spl].activate else turns = __tmp_spells[spl].activate[1] .. '+d' .. __tmp_spells[spl].activate[2] end return __tmp_spells[spl].desc[1] .. ' every ' .. turns .. ' turns' end -- Compute the timeout of an activation function get_activation_timeout(spl) if type(__tmp_spells[spl].activate) == 'number' then return __tmp_spells[spl].activate else return __tmp_spells[spl].activate[1] + randint(__tmp_spells[spl].activate[2]) end end -- Fire off the spell function activate_activation(spl, item) __spell_spell[spl](item) end ------- Add new GF type ---------- max_gf = MAX_GF function add_spell_type(t) t.index = max_gf max_gf = max_gf + 1 assert(t.color, "No GF color") if not t.monster then t.monster = function() end end if not t.angry then t.angry = function() end end if not t.object then t.object = function() end end if not t.player then t.player = function() end end if not t.grid then t.grid = function() end end add_hooks { [HOOK_GF_COLOR] = function (gf, new_gfx) local t = %t if gf == t.index then return TRUE, t.color[new_gfx + 1] end end, [HOOK_GF_EXEC] = function (action, who, gf, dam, rad, y, x, extra) local t = %t if t.index == gf then return t[action](who, dam, rad, y, x, extra) end end, } return t.index end tome-235-src/lib/core/dungeon.lua0000644000076400017500000000432111012107760014523 0ustar dgdg-- Internal lua file in charge of dungeon stuff function place_dungeon(y, x, d_idx) if d_idx then wild_map(y, x).entrance = 1000 + d_idx else wild_map(y, x).entrance = 0 end end function dungeon(d_idx) return d_info[1 + d_idx] end function wild_feat(wild) return wf_info[1 + wild.feat] end function explode_dir(dir) return ddy[dir + 1], ddx[dir + 1] end function rotate_dir(dir, mov) if mov > 0 then if dir == 7 then dir = 8 elseif dir == 8 then dir = 9 elseif dir == 9 then dir = 6 elseif dir == 6 then dir = 3 elseif dir == 3 then dir = 2 elseif dir == 2 then dir = 1 elseif dir == 1 then dir = 4 elseif dir == 4 then dir = 7 end elseif mov < 0 then if dir == 7 then dir = 4 elseif dir == 4 then dir = 1 elseif dir == 1 then dir = 2 elseif dir == 2 then dir = 3 elseif dir == 3 then dir = 6 elseif dir == 6 then dir = 9 elseif dir == 9 then dir = 8 elseif dir == 8 then dir = 7 end end return dir end -- Check if the map is a filename or directly a map function load_map(map, y, x) if strsub(map, 1, 5) == "#!map" then %load_map(TRUE, map, y, x) else %load_map(FALSE, map, y, x) end end function get_map_size(map) if strsub(map, 1, 5) == "#!map" then return %get_map_size(TRUE, map) else return %get_map_size(FALSE, map) end end -- Place a trap for a specific level function place_trap(y, x, level) local old_dun = dun_level dun_level = level %place_trap(y, x) dun_level = old_dun end -- Level generators processing __level_generators = {} function level_generator(t) assert(t.name, "no generator name") assert(t.gen, "no generator function") if not t.stairs then t.stairs = TRUE end if not t.monsters then t.monsters = TRUE end if not t.objects then t.objects = TRUE end if not t.miscs then t.miscs = TRUE end __level_generators[t.name] = t.gen add_scripted_generator(t.name, t.stairs, t.monsters, t.objects, t.miscs) end function level_generate(name) assert(__level_generators[name], "Unknown level generator '"..name.."'") return __level_generators[name]() end --[[ Example level_generator { ["name"] = "test", ["gen"] = function() print("zog") for i = 1, 30 do cave(i, 2).feat = 1 end return new_player_spot(get_branch()) end, } ]] tome-235-src/lib/core/mimc_aux.lua0000644000076400017500000000413411012107760014670 0ustar dgdg-- Mimic shapes helper file __mimics = {} __mimics_max = 1 __mimics_names = {} function add_mimic_shape(t) assert(t.name, "no mimic name") assert(t.desc, "no mimic desc") assert(t.calc, "no mimic calc") assert(t.level, "no mimic level") assert(t.duration, "no mimic duration") if not t.limit then t.limit = 0 end if not t.obj_name then t.obj_name = t.name end t.show_name = '['..t.name..']' -- if it needs hooks, add them if t.hooks then add_hooks(t.hooks) end -- Add it in a name to index hash table __mimics_names[t.name] = __mimics_max __mimics[__mimics_max] = t __mimics_max = __mimics_max + 1 end function resolve_mimic_name(name) if __mimics_names[name] then return __mimics_names[name] else return -1 end end function find_random_mimic_shape(level, limit, realm) local mimic, tries tries = 1000 while tries > 0 do tries = tries - 1 mimic = rand_range(1, __mimics_max - 1) if (not realm) or (__mimics[mimic].realm == realm) then if limit >= __mimics[mimic].limit then if (rand_int(__mimics[mimic].level * 3) < level) and (__mimics[mimic].rarity < 100) and (magik(100 - __mimics[mimic].rarity) == TRUE) then break end end end end if tries > 0 then return mimic else return resolve_mimic_name("Abomination") end end function get_mimic_info(mimic, info) if not __mimics[mimic] then return 0 end return __mimics[mimic][info] end function get_mimic_rand_dur(mimic) return rand_range(__mimics[mimic].duration[1], __mimics[mimic].duration[2]) end function calc_mimic(mimic) return __mimics[mimic].calc() end function calc_mimic_power(mimic) if __mimics[mimic].power then __mimics[mimic].power() end end --- Here comes the only vital shape add_mimic_shape { ["name"] = "Abomination", ["obj_name"] = "Abominable Cloak", ["desc"] = "Abominations are failed experiments of powerful wizards.", ["realm"] = nil, ["level"] = 1, ["rarity"] = 101, ["duration"] = {20, 100}, ["calc"] = function () apply_flags(TR1_SPEED + TR1_STR + TR1_INT + TR1_WIS + TR1_DEX + TR1_CON + TR1_CHR, 0, TR3_AGGRAVATE, 0, 0, 0, -10) end, } tome-235-src/lib/core/quests.lua0000644000076400017500000000237711012107760014421 0ustar dgdg-- Quest helper files -- Quest structs __quest_hook = {} __quest_callbacks = {} __quest_callbacks_max = 0 __quest_dynamic_desc = {} function add_quest(q) local i, index, d, z, qq assert(q.global, "No quest global name") assert(q.name, "No quest name") assert(q.desc, "No quest desc") assert(q.level, "No quest level") assert(q.hooks, "No quest hooks") i = new_quest(q.name); setglobal(q.global, i) -- Make it save & load add_loadsave("quest("..q.global..").status", QUEST_STATUS_UNTAKEN) if type(q.desc) == "table" then z = 0 for index, d in q.desc do quest_desc(i, z, d); z = z + 1 end else __quest_dynamic_desc[i] = q.desc quest(i).dynamic_desc = TRUE end quest(i).level = q.level if not q.silent then quest(i).silent = FALSE else quest(i).silent = q.silent end __quest_hook[i] = q.hooks for index, d in q.hooks do add_hook_script(index, "__lua__quest_callback"..__quest_callbacks_max, "__lua__quest_callback"..__quest_callbacks_max) setglobal("__lua__quest_callback"..__quest_callbacks_max, d) __quest_callbacks_max = __quest_callbacks_max + 1 end if q.data then for index, d in q.data do -- Besure it exists setglobal(index, d) -- Make it save & load add_loadsave(index, d) end end return i end tome-235-src/lib/core/powers.lua0000644000076400017500000000462011012107760014405 0ustar dgdg-- -- Helper functions for magic powers -- __magic_powers = {} function add_magic(m) local i, ret if type(m.spell_list) ~= "table" then error("add_magic called without a table") end -- Ok iterate over all the powers to add local index, p, max -- First, count them max = 0 for index, p in m.spell_list do max = max + 1 end -- Now register it ret = {} i = new_magic_power(max) ret.spells = i ret.max = max ret.fail_fct = m.fail if m.stat then ret.stat = m.stat else ret.stat = A_INT end if m.get_level then ret.get_current_level = m.get_level else ret.get_current_level = function() return player.lev end end -- And add each spells max = 0 ret.info = {} ret.spell = {} for index, p in m.spell_list do assert(p.name, "No name for the spell!") assert(p.desc, "No desc for the spell!") assert(p.mana, "No mana for the spell!") assert(p.level, "No level for the spell!") assert(p.fail, "No fail for the spell!") assert(p.info, "No info for the spell!") assert(p.spell, "No spell for the spell!") get_magic_power(i, max).name = p.name get_magic_power(i, max).desc = p.desc get_magic_power(i, max).mana_cost = p.mana get_magic_power(i, max).min_lev = p.level get_magic_power(i, max).fail = p.fail ret.info[max] = p.info ret.spell[max] = p.spell max = max + 1 end return ret end function __get_magic_info(power) return __current_magic_power_info[power]() end function execute_magic(m) local sn, ret -- Ask for a spell __current_magic_power_info = m.info ret, sn = select_magic_power(0, m.spells, m.max, "__get_magic_info", m.get_current_level(), m.stat) if (ret == FALSE) then return end -- Verify mana needs if (get_magic_power(m.spells, sn).mana_cost > player.csp) then msg_print("Not enough mana!") return end -- Verify failure(second parameter is optional) if m.fail then __current_magic_power_fail = m.fail_fct if (magic_power_sucess(get_magic_power(m.spells, sn), m.stat, "__current_magic_power_fail") == FALSE) then return end else if (magic_power_sucess(get_magic_power(m.spells, sn), m.stat) == FALSE) then return end end -- Actually cast the spells m.spell[sn]() -- use up some mana increase_mana(-get_magic_power(m.spells, sn).mana_cost) end -- Get the level of a power function get_level_power(s, max, min) if not max then max = 50 end if not min then min = 1 end return value_scale(s.get_current_level(), 50, max, min) end tome-235-src/lib/core/auto.lua0000644000076400017500000005036711012107760014047 0ustar dgdg-- This file is the core of the Automatizer -- Please do not touch unless you know what you are doing __rules = {} __rules_max = 0 rule_aux = {} -- Rule apply function, does .. nothing function auto_nothing(obj, item) return end function auto_inscribe(obj, item, note) if obj.note ~= 0 then return end msg_print("") obj.note = quark_add(note) return TRUE end -- Rule apply function, pickup object function auto_pickup(obj, item) if item >= 0 then return end if inven_carry_okay(obj) == FALSE then return end msg_print("") object_pickup(-item) return TRUE end -- Rule apply function, destroy item function auto_destroy(obj, item) -- be carefull to what we can destroy -- Unaware things won't be destroyed. if is_aware(obj) == FALSE then return end -- Inscribed things won't be destroyed! if obj.note ~= 0 then return end -- Keep Artifacts -- they cannot be destroyed anyway if is_artifact(obj) == TRUE then return end -- Cannot destroy CURSE_NO_DROP objects local f1, f2, f3, f4, f5, esp = object_flags(obj); if band(f4, TR4_CURSE_NO_DROP) ~= 0 and band(obj.ident, IDENT_CURSED) then return end msg_print("") -- Eliminate the item (from the pack) if item >= 0 then inven_item_increase(item, -obj.number) inven_item_describe(item) inven_item_optimize(item) -- Eliminate the item (from the floor) else floor_item_increase(0 - item, -obj.number) floor_item_describe(0 - item) floor_item_optimize(0 - item) end return TRUE end -- Report the status of an object function object_status(obj) local sense = { [SENSE_CURSED] = "bad", [SENSE_WORTHLESS] = "very bad", [SENSE_AVERAGE] = "average", [SENSE_GOOD_LIGHT] = "good", [SENSE_GOOD_HEAVY] = "good", [SENSE_EXCELLENT] = "very good", [SENSE_SPECIAL] = "special", [SENSE_TERRIBLE] = "terrible", } if is_known(obj) == FALSE then if sense[obj.sense] then return sense[obj.sense] else return "" end else if nil then -- test local osense = -1 local type = select_sense(obj, TRUE, TRUE) if type == 1 then osense = value_check_aux1(obj) elseif type == 2 then osense = value_check_aux1_magic(obj) end print("type : "..type) if sense[osense] then print("sense: "..sense[osense]) return sense[osense] else print("sense: ") return "" end else -- the real one local slot = wield_slot_ideal(obj, TRUE) -- Arts items if is_artifact(obj) == TRUE then if band(obj.ident, IDENT_CURSED) == 0 then return "special" else return "terrible" end -- Ego items elseif (obj.name2 > 0 or obj.name2b > 0) then if band(obj.ident, IDENT_CURSED) == 0 then return "very good" else return "very bad" end -- weapon elseif (slot == INVEN_WIELD) or (slot == INVEN_BOW) or (slot == INVEN_AMMO) or (slot == INVEN_TOOL) then if obj.to_h + obj.to_d < 0 then return "bad" elseif obj.to_h + obj.to_d > 0 then return "good" else return "average" end -- armor elseif (slot >= INVEN_BODY) and (slot <= INVEN_FEET) then if obj.to_a < 0 then return "bad" elseif obj.to_a > 0 then return "good" else return "average" end -- ring elseif slot == INVEN_RING then if (obj.to_d + obj.to_h < 0) or (obj.to_a < 0) or (obj.pval < 0) then return "bad" else return "average" end -- amulet elseif slot == INVEN_NECK then if (obj.pval < 0) then return "bad" else return "average" end -- chests elseif obj.tval == TV_CHEST then if obj.pval == 0 then return "empty" elseif obj.pval < 0 then return "disarmed" else return "average" end else return "average" end end end end -- Recursive function to generate a rule function tree function gen_rule_fct(r) -- It is a test rule (or, and, ...) if r.label == "and" or r.label == "or" then local i local fct_tbl = {} for i = 1, getn(r) do if r[i].label ~= "comment" then tinsert(fct_tbl, gen_rule_fct(r[i])) end end if r.label == "and" then return function(object) local fcts = %fct_tbl local i for i = 1, getn(fcts) do if not fcts[i](object) then return end end return TRUE end elseif r.label == "or" then return function(object) local fcts = %fct_tbl local i for i = 1, getn(fcts) do if fcts[i](object) then return TRUE end end end end -- It is a condition rule (name, type, level, ...) else if r.label == "not" then local f if not r[1] then f = function (object) return TRUE end else f = gen_rule_fct(r[1]) end return function(object) return not %f(object) end elseif r.label == "name" then return function(object) if strlower(object_desc(object, -1, 0)) == strlower(%r[1]) then return TRUE end end elseif r.label == "contain" then return function(object) if strfind(strlower(object_desc(object, -1, 0)), strlower(%r[1])) then return TRUE end end elseif r.label == "symbol" then return function(object) if strchar(get_kind(object).d_char) == %r[1] then return TRUE end end elseif r.label == "inscribed" then return function(object) if object.note ~= 0 and strfind(strlower(quark_str(object.note)), strlower(%r[1])) then return TRUE end end elseif r.label == "discount" then local d1 = r.args.min local d2 = r.args.max if tonumber(d1) == nil then d1 = getglobal(d1) else d1 = tonumber(d1) end if tonumber(d2) == nil then d2 = getglobal(d2) else d2 = tonumber(d2) end return function(object) if is_aware(object) == TRUE and object.discount >= %d1 and object.discount <= %d2 then return TRUE end end elseif r.label == "tval" then local tv = r[1] if tonumber(tv) == nil then tv = getglobal(tv) else tv = tonumber(tv) end return function(object) if object.tval == %tv then return TRUE end end elseif r.label == "sval" then assert(r.args.min and r.args.max, "sval rule lacks min or max") local sv1 = r.args.min local sv2 = r.args.max if tonumber(sv1) == nil then sv1 = getglobal(sv1) else sv1 = tonumber(sv1) end if tonumber(sv2) == nil then sv2 = getglobal(sv2) else sv2 = tonumber(sv2) end return function(object) if is_aware(object) == TRUE and object.sval >= %sv1 and object.sval <= %sv2 then return TRUE end end elseif r.label == "status" then return function(object) if object_status(object) == strlower(%r[1]) then return TRUE end end elseif r.label == "state" then if r[1] == "identified" then return function(object) if is_known(object) == TRUE then return TRUE end end else return function(object) if is_known(object) == FALSE then return TRUE end end end elseif r.label == "race" then return function(object) if strlower(get_race_name()) == strlower(%r[1]) then return TRUE end end elseif r.label == "subrace" then return function(object) if strlower(get_subrace_name()) == strlower(%r[1]) then return TRUE end end elseif r.label == "class" then return function(object) if strlower(get_class_name()) == strlower(%r[1]) then return TRUE end end elseif r.label == "level" then assert(r.args.min and r.args.max, "level rule lacks min or max") return function(object) if player.lev >= tonumber(%r.args.min) and player.lev <= tonumber(%r.args.max) then return TRUE end end elseif r.label == "skill" then assert(r.args.min and r.args.max, "skill rule lacks min or max") local s = find_skill_i(r[1]) assert(s ~= -1, "no skill "..r[1]) return function(object) if get_skill(%s) >= tonumber(%r.args.min) and get_skill(%s) <= tonumber(%r.args.max) then return TRUE end end elseif r.label == "ability" then local s = find_ability(r[1]) assert(s ~= -1, "no ability "..r[1]) return function(object) if has_ability(%s) == TRUE then return TRUE end end end end end function auto_inscribe_maker(inscription) return function(...) arg.n = arg.n + 1 arg[getn(arg)] = %inscription return call(auto_inscribe, arg) end end -- Generate a rule from a table function gen_full_rule(t) -- only honor rules for this module if not t.args.module then t.args.module = "ToME" end if not ((t.args.module == "all") or (t.args.module == game_module)) then return function() end end -- Check for which action to do local apply_fct = auto_nothing if t.args.type == "destroy" then apply_fct = auto_destroy elseif t.args.type == "pickup" then apply_fct = auto_pickup elseif t.args.type == "inscribe" then apply_fct = auto_inscribe_maker(t.args.inscription) end -- create the function tree local rf if t[1] then rf = gen_rule_fct(t[1]) else rf = function (object) end end -- create the final function return function(...) local rf = %rf if rf(arg[1]) then if call(%apply_fct, arg) == TRUE then return TRUE end end end end -- Create a function that checks for the rules(passed in xml form) function add_ruleset(s) local tbl = xml:collect(s) local i -- Add all rules for i = 1, getn(tbl) do local t = tbl[i] if t.label == "rule" then -- Create the function tree local fct = gen_full_rule(t) -- Create the test function __rules[__rules_max] = { ["table"] = t, ["fct"] = fct } __rules_max = __rules_max + 1 end end end -- Apply the current rules to an object -- call with at least (object, idx) function apply_rules(...) local i for i = 0, __rules_max - 1 do if call(__rules[i].fct, arg) then return TRUE end end return FALSE end -- Clear the current rules function clean_ruleset() __rules_max = 0 __rules = {} end ------ helper fonctions for the GUI auto_aux = {} auto_aux.stack = { n = 0 } auto_aux.idx = 1 auto_aux.rule = 1 function auto_aux:go_right() if auto_aux.rule[1] and type(auto_aux.rule[1]) == "table" then tinsert(auto_aux.stack, auto_aux.idx) tinsert(auto_aux.stack, auto_aux.rule) auto_aux.rule = auto_aux.rule[1] auto_aux.idx = 1 end end function auto_aux:go_left(sel) local n = getn(auto_aux.stack) if n > 0 then auto_aux.idx = auto_aux.stack[n - 1] auto_aux.rule = auto_aux.stack[n] tremove(auto_aux.stack) tremove(auto_aux.stack) end end function auto_aux:go_down() if getn(auto_aux.stack) > 1 then if auto_aux.stack[getn(auto_aux.stack)][auto_aux.idx + 1] then auto_aux.idx = auto_aux.idx + 1 auto_aux.rule = auto_aux.stack[getn(auto_aux.stack)][auto_aux.idx] end end end function auto_aux:go_up() if getn(auto_aux.stack) > 1 then if auto_aux.stack[getn(auto_aux.stack)][auto_aux.idx - 1] then auto_aux.idx = auto_aux.idx - 1 auto_aux.rule = auto_aux.stack[getn(auto_aux.stack)][auto_aux.idx] end end end function auto_aux:scroll_up() xml.write_off_y = xml.write_off_y - 1 end function auto_aux:scroll_down() xml.write_off_y = xml.write_off_y + 1 end function auto_aux:scroll_left() xml.write_off_x = xml.write_off_x + 1 end function auto_aux:scroll_right() xml.write_off_x = xml.write_off_x - 1 end function auto_aux:adjust_current(sel) if __rules_max == 0 then return end xml.write_off_y = 0 xml.write_off_x = 0 auto_aux.idx = 1 auto_aux.stack = { n = 0 } auto_aux.rule = __rules[sel].table end function auto_aux:move_up(sel) if sel > 0 then local u = __rules[sel - 1] local d = __rules[sel] __rules[sel - 1] = d __rules[sel] = u return sel - 1 end return sel end function auto_aux:move_down(sel) if sel < __rules_max - 1 then local u = __rules[sel] local d = __rules[sel + 1] __rules[sel + 1] = u __rules[sel] = d return sel + 1 end return sel end function auto_aux:new_rule(sel, nam, typ, arg) local r -- nam can also directly be the table itself if type(nam) == "table" then r = { ["table"] = nam, ["fct"] = function (object) end } elseif typ == "inscribe" then if arg == "" then arg = input_box("Inscription?", 79) end r = { ["table"] = { label = "rule", args = { name = nam, type = typ, inscription = arg, module = game_module }, }, ["fct"] = function (object) end } else r = { ["table"] = { label = "rule", args = { name = nam, type = typ, module = game_module }, }, ["fct"] = function (object) end } end tinsert(__rules, sel, r) __rules_max = __rules_max + 1 end function auto_aux:rename_rule(sel, nam) if sel >= 0 and sel < __rules_max then __rules[sel].table.args.name = nam end end function auto_aux:save_ruleset() xml.write = xml.write_file print_hook("clean_ruleset()\nadd_ruleset\n[[\n") local i for i = 0, __rules_max - 1 do xml:print_xml(__rules[i].table, '') end print_hook("]]\n") xml.write = xml.write_screen end function auto_aux:del_self(sel) if auto_aux.rule.label == "rule" then tremove(__rules, sel) __rules_max = __rules_max - 1 return sel - 1 else local idx = auto_aux.idx auto_aux:go_left(sel) tremove(auto_aux.rule, idx) return sel end end auto_aux.types_desc = { ["and"] = { "Check is true if all rules within it are true", xml:collect([[.........]]), function () return xml:collect("") end, }, ["or"] = { "Check is true if at least one rule within it is true", xml:collect([[.........]]), function () return xml:collect("") end, }, ["not"] = { "Invert the result of its child rule", xml:collect([[...]]), function () return xml:collect("") end, }, ["comment"] = { "Comments are meaningless", xml:collect([[Comment explaining something]]), function () local n = input_box("Comment?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["name"] = { "Check is true if object name matches name", xml:collect([[potion of healing]]), function () local n = input_box("Object name to match?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["contain"] = { "Check is true if object name contains word", xml:collect([[healing]]), function () local n = input_box("Word to find in object name?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["inscribed"] = { "Check is true if object inscription contains word", xml:collect([[=g]]), function () local n = input_box("Word to find in object inscription?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["discount"] = { "Check is true if object discount is between 2 values", xml:collect([[]]), function () local s = "" return xml:collect(s) end, }, ["symbol"] = { "Check is true if object symbol is ok", xml:collect([[!]]), function () local n = input_box("Symbol to match?", 1) if n == "" then return end return xml:collect(""..n.."") end, }, ["status"] = { "Check is true if object status is ok", xml:collect([[good]]), function () local n = msg_box("[t]errible, [v]ery bad, [b]ad, [a]verage, [G]ood, [V]ery good, [S]pecial?") local t = { ["t"] = "terrible", ["v"] = "very bad", ["b"] = "bad", ["a"] = "average", ["G"] = "good", ["V"] = "very good", ["S"] = "special", } if not t[strchar(n)] then return end return xml:collect(""..t[strchar(n)].."") end, }, ["state"] = { "Check is true if object is identified/unidentified", xml:collect([[identified]]), function () local n = msg_box("[i]dentified, [n]on identified?") local t = { ["i"] = "identified", ["n"] = "not identified", } if not t[strchar(n)] then return end return xml:collect(""..t[strchar(n)].."") end, }, ["tval"] = { "Check is true if object tval(from k_info.txt) is ok", xml:collect([[55]]), function () local n = input_box("Tval to match?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["sval"] = { { "Check is true if object sval(from k_info.txt) is between", "2 values", }, xml:collect([[]]), function () local s = "" return xml:collect(s) end, }, ["race"] = { "Check is true if player race is ok", xml:collect([[dunadan]]), function () local n = input_box("Player race to match?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["subrace"] = { "Check is true if player subrace is ok", xml:collect([[vampire]]), function () local n = input_box("Player subrace to match?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["class"] = { "Check is true if player class is ok", xml:collect([[sorceror]]), function () local n = input_box("Player class to match?", 79) if n == "" then return end return xml:collect(""..n.."") end, }, ["level"] = { "Check is true if player level is between 2 values", xml:collect([[]]), function () local s = "" return xml:collect(s) end, }, ["skill"] = { "Check is true if player skill level is between 2 values", xml:collect([[Divination]]), function () local s = "" n = input_box("Skill name?", 79) if n == "" then return end if find_skill_i(n) == -1 then return end s = s..n.."" return xml:collect(s) end, }, ["ability"] = { "Check is true if player has the ability", xml:collect([[Ammo creation]]), function() local n = input_box("Ability name?", 79) if n == "" then return end if find_ability(n) == -1 then return end return xml:collect(""..n.."") end, }, } function auto_aux:display_desc(sel) local d = auto_aux.types_desc[sel][1] if type(d) == "string" then c_prt(TERM_WHITE, d, 1, 17) else local k, e, i i = 0 for k, e in d do c_prt(TERM_WHITE, e, 1 + i, 17) i = i + 1 end end end function auto_aux:add_child(sel) -- and contain only one match if (auto_aux.rule.label == "rule" or auto_aux.rule.label == "not") and auto_aux.rule[1] then return end -- Only and can contain if auto_aux.rule.label ~= "rule" and auto_aux.rule.label ~= "and" and auto_aux.rule.label ~= "or" and auto_aux.rule.label ~= "not" then return end -- get it local r = auto_aux.types_desc[sel][3]() if not r then return end -- Ok add it tinsert(auto_aux.rule, r[1]) end function auto_aux.regen_ruleset() local i for i = 0, __rules_max - 1 do __rules[i].fct = gen_full_rule(__rules[i].table) end end -- Easily add new rules function easy_add_rule(typ, mode, do_status, obj) local detect_rule if mode == "tval" then detect_rule = ""..obj.tval.."" elseif mode == "tsval" then detect_rule = ""..obj.tval.."" elseif mode == "name" then detect_rule = ""..strlower(object_desc(obj, -1, 0)).."" end if do_status == TRUE then local status = object_status(obj) if status and not (status == "") then detect_rule = ""..detect_rule..""..status.."" end end local rule = ""..detect_rule.."" auto_aux:new_rule(0, xml:collect(rule)[1], '') auto_aux.regen_ruleset() msg_print("Rule added. Please go to the Automatizer screen (press = then T)") msg_print("to save the modified ruleset.") end tome-235-src/lib/core/monsters.lua0000644000076400017500000000052111012107760014734 0ustar dgdg-- SYSTEM FILE -- -- Monster stuff, do not touch -- function summon_monster(y, x, lev, friend, typ) if type(typ) == "number" then if friend == TRUE then return summon_specific_friendly(y, x, lev, typ, FALSE) else return summon_specific(y, x, lev, typ) end else return summon_monster_aux(y, x, lev, friend, typ) end end tome-235-src/lib/core/load2.lua0000644000076400017500000000322411012107760014066 0ustar dgdg-- Savefile helpers -- function called when a key in the variable part ofthe savefile is read -- if the key matches what we need, we use it, otehrwise just ignore it function __savefile_load(key, val) local index, elem for index, elem in __loadsave_name do if (key == elem.name) then dostring(elem.name.." = "..val) end end end function dump_loadsave() local k, e for k, e in __loadsave_name do msg_print(k.." :: ".. e.name.." ["..e.default.."]") end end -- called when the game is saved, can only save numbers -- assosiate a key with them to allow the loading code to recognize them function __savefile_save() local index, elem for index, elem in __loadsave_name do dostring("__loadsave_tmp = "..elem.name) save_number_key(elem.name, __loadsave_tmp); end end register_savefile(__loadsave_max) add_hook_script(HOOK_LOAD_GAME, "__savefile_load", "__hook_load") add_hook_script(HOOK_SAVE_GAME, "__savefile_save", "__hook_save") -- Parse a flattened(i.e: foo.bar.zog) table path and recrate tables function reconstruct_table(name) for i = 1, strlen(name) - 1 do if strsub(name, i, i) == "." then local tbl = strsub(name, 1, i - 1) if dostring("return "..tbl) == nil then dostring(tbl.."={}") end end end end -- Automagically set unkown variables, otherwise the savefile code -- might get VERY upset do local k, e -- We need to be able to check for unknown globals unset_safe_globals() for k, e in __loadsave_name do reconstruct_table(e.name) if dostring("return "..(e.name)) == nil then dostring((e.name).." = "..(e.default)) end end -- Now taht we did, we set it back, for it is usefull ;) set_safe_globals() end tome-235-src/lib/core/load.lua0000644000076400017500000000140111012107760013777 0ustar dgdg-- Savefile stuff -- Do not meddle in the affairs of savefiles for they are subtle and quick to be become incompatible __loadsave_name = {} __loadsave_max = 0 __loadsave_tmp = 0 function add_loadsave(name, default) assert(name, "No variable name to save") assert(default, "No default value") -- if it is a table we must create many entries if type(default) == "table" then for k, e in default do add_loadsave(name.."."..k, e) end else __loadsave_name[__loadsave_max] = { name = name, default = default } __loadsave_max = __loadsave_max + 1 end end -- Example of how to save a table -- NOTE: { 1, 2, 3 } will NOT work, the key MUST be a string --[[ add_loadsave("t", { foo = 7, tab = { a = 1, b = 2, tab = { a=1, b=2, c=3, }, }, }) ]] tome-235-src/lib/core/objects.lua0000644000076400017500000000160611012107760014520 0ustar dgdg-- SYSTEM FILE -- -- Lua object funtions -- function create_object(tval, sval) local obj = new_object() object_prep(obj, lookup_kind(tval, sval)) return (obj) end function set_item_tester(tester) if tolua.type(tester) == "number" then lua_set_item_tester(tester, "") end if tolua.type(tester) == "string" then lua_set_item_tester(0, tester) end if tolua.type(tester) == "function" then __get_item_hook_default = tester lua_set_item_tester(0, "__get_item_hook_default") end end function create_artifact(a_idx) local obj local tval, sval tval = a_info[a_idx + 1].tval sval = a_info[a_idx + 1].sval obj = create_object(tval, sval) obj.name1 = a_idx apply_magic(obj, -1, TRUE, TRUE, TRUE) return (obj) end function get_kind(obj) return k_info[obj.k_idx + 1] end function get_item(ask, deny, flags, mask) set_item_tester(mask) return get_item_aux(0, ask, deny, flags) end tome-235-src/lib/core/stores.lua0000644000076400017500000000137711012107760014413 0ustar dgdg-- Take care of all concerning stores function store_buy_list(t) assert(type(t) == "table", "store_buy_list got no table") add_hooks { [HOOK_STORE_BUY] = function (index, name, obj) local tbl = %t local elt = tbl[index] if not elt then elt = tbl[name] end if elt then if elt then if type(elt) == "function" then return TRUE, elt(obj) elseif type(elt) == "table" then local k, e for k, e in elt do if type(e) == "number" then if obj.tval == e then return TRUE, TRUE end else if (obj.tval == e[1]) and (obj.sval >= e[2]) and (obj.sval <= e[3]) then return TRUE, TRUE end end end elseif elt == -1 then return TRUE, FALSE end end end end, } end tome-235-src/lib/core/gods.lua0000644000076400017500000000145211012107760014022 0ustar dgdg-- Gods helper files -- Gods structs __gods_hook = {} __gods_callbacks = {} __gods_callbacks_max = 0 function add_god(q) local i, index, d, z, qq assert(q.name, "No god name") assert(q.desc, "No god desc") assert(q.hooks, "No god hooks") i = add_new_gods(q.name); z = 0 for index, d in q.desc do desc_god(i, z, d); z = z + 1 end __gods_hook[i] = q.hooks for index, d in q.hooks do add_hook_script(index, "__lua__gods_callback"..__gods_callbacks_max, "__lua__gods_callback"..__gods_callbacks_max) setglobal("__lua__gods_callback"..__gods_callbacks_max, d) __gods_callbacks_max = __gods_callbacks_max + 1 end if q.data then for index, d in q.data do -- Besure it exists setglobal(index, d) -- Make it save & load add_loadsave(index, d) end end return i end tome-235-src/lib/core/gen_idx.lua0000644000076400017500000001233011012107760014500 0ustar dgdg-- Place here the list of files to parse files = { "birth.txt", "experien.hlp", "gods.txt", "explore.hlp", "newbie.hlp", "advanced.hlp", "help.hlp", "general.txt", "whattome.txt", "dungeon.txt", "spoiler.hlp", "g_melkor.txt", "skills.txt", "c_bard.txt", "c_druid.txt", "c_lorema.txt", "c_mage.txt", "c_mimic.txt", "c_mindcr.txt", "c_monk.txt", "c_palad.txt", "c_posses.txt", "c_pr_drk.txt", "c_pr_eru.txt", "c_pr_man.txt", "c_symbia.txt", "c_alchem.txt", "c_archer.txt", "c_assass.txt", "c_axemas.txt", "c_demono.txt", "c_geoman.txt", "c_hafted.txt", "c_necro.txt", "c_polear.txt", "c_ranger.txt", "c_rogue.txt", "c_runecr.txt", "c_sorcer.txt", "c_swordm.txt", "c_thaum.txt", "c_unbel.txt", "c_warper.txt", "c_warrio.txt", "m_meta.txt", "rm_skel.txt", "rm_zomb.txt", "luckspoi.txt", "m_air.txt", "dunspoil.txt", "g_eru.txt", "g_manwe.txt", "g_tulkas.txt", "m_divin.txt", "m_mimic.txt", "m_water.txt", "magic.txt", "r_drkelf.txt", "r_dwarf.txt", "r_elf.txt", "r_hielf.txt", "r_hobbit.txt", "r_pettyd.txt", "r_wodelf.txt", "rm_spec.txt", "tome_faq.txt", "ability.txt", "automat.txt", "c_summon.txt", "command.txt", "corspoil.txt", "debug.txt", "m_music.txt", "rm_barb.txt", "macrofaq.txt", "m_necrom.txt", "m_mindcr.txt", "m_symbio.txt", "m_thaum.txt", "magic.hlp", "m_convey.txt", "m_fire.txt", "m_mana.txt", "m_mind.txt", "m_nature.txt", "m_tempo.txt", "m_udun.txt", "m_geoman.txt", "essences.txt", "r_ent.txt", "g_yavann.txt", "defines.txt", "rm_vamp.txt", "inscrip.txt", "m_earth.txt", "option.txt", "attack.txt", "version.txt", "m_demono.txt", "r_beorn.txt", "r_deathm.txt", "r_rohank.txt", "r_hafogr.txt", "r_human.txt", "r_kobold.txt", "r_maia.txt", "r_orc.txt", "r_thlord.txt", "r_troll.txt", "r_yeek.txt", "rm_class.txt", "rm_herm.txt", "rm_lsoul.txt", "wishing.txt", "c_priest.txt", "fatespoi.txt", "gambling.txt", "r_dunad.txt", "r_gnome.txt", "r_hafelf.txt", "c_merch.txt", "spoil_faq.txt", } out_file = "index.txt" index = {} function parse_file(file) local fff = openfile(path_build(ANGBAND_DIR_HELP, file), "r") local line line = read(fff, "*l") while line do local i, j, anchor, name, subname = strfind(line, "~~~~~(%d+)|([%d%a -]+)|([%d%a -]+)") if not i then i, j, anchor, name = strfind(line, "~~~~~(%d+)|([%d%a -]+)") subname = nil end if i then if not index[name] then index[name] = {} end if subname then tinsert(index[name], { __name__ = subname, __file__ = file, __anchor__ = anchor}) else tinsert(index[name], { __name__ = "__primary__", __file__ = file, __anchor__ = anchor}) end end line = read(fff, "*l") end closefile(fff) end function sort_fct(a, b) local i, len a = a.__name__ b = b.__name__ if strlen(a) > strlen(b) then len = strlen(b) else len = strlen(a) end for i = 1, len do local ac = strbyte(a, i) local bc = strbyte(b, i) if ac < bc then return not nil elseif ac > bc then return nil end end if strlen(a) > strlen(b) then return nil else return not nil end end function generate_index() local k, e, index_list for _, e in files do parse_file(e) end index_list = {} for k, e in index do -- Ok either my sort function or lua sort function sucks ass .. sort(e, sort_fct) sort(e, sort_fct) sort(e, sort_fct) sort(e, sort_fct) sort(e, sort_fct) tinsert(index_list, {__name__= k, __table__ = e}) end -- Ok either my sort function or lua sort function sucks ass .. sort(index_list, sort_fct) sort(index_list, sort_fct) sort(index_list, sort_fct) sort(index_list, sort_fct) sort(index_list, sort_fct) index = index_list end function out_link(fff, space, name, file, anchor) write(fff, space.."*****"..file.."*"..anchor.."["..name.."]\n") end function print_index() local i, j, c, new_c local fff = openfile(path_build(ANGBAND_DIR_HELP, out_file), "w") write(fff, [[|||||oy #####R /----------------------------------------\ #####R < Help Index > #####R \----------------------------------------/ This is the index of everything in the T.o.M.E. documentation. #####BHit a letter key to jump to the entries for that letter. Some entries in the index link to the same place as other entries. This is intentional, so that the information you want is easy to find. Don't forget you can browse the help from the *****help.hlp*02[Main menu]. #####sSpotted a problem with the help files, or some content thats missing? #####sContact fearoffours@t-o-m-e.net . ]]) c = ' ' for i = 1, getn(index) do new_c = strbyte(index[i].__name__, 1) if c ~= new_c then c = new_c write(fff, "~~~~~"..c.."\n") write(fff, "*****/"..strchar(c)..out_file.."*"..c.."["..strchar(c).."]\n") end for j = 1, getn(index[i].__table__) do if index[i].__table__[j].__name__ == "__primary__" then out_link(fff, " ", index[i].__name__, index[i].__table__[j].__file__, index[i].__table__[j].__anchor__) end end for j = 1, getn(index[i].__table__) do if index[i].__table__[j].__name__ ~= "__primary__" then out_link(fff, " ", index[i].__table__[j].__name__, index[i].__table__[j].__file__, index[i].__table__[j].__anchor__) end end end closefile(fff) end generate_index() print_index() tome-235-src/lib/core/building.lua0000644000076400017500000000057511012107760014670 0ustar dgdg__building_actions = {} function add_building_action(a) assert(a.index, "No building action index") assert(a.action, "No building action action") __building_actions[a.index] = a.action end function __bact_activate(bact) if __building_actions[bact] then return __building_actions[bact]() end end add_hook_script(HOOK_BUILDING_ACTION, "__bact_activate", "__bact_activate") tome-235-src/lib/core/init.lua0000644000076400017500000000556211012107760014037 0ustar dgdg-- -- This file is loaded at the initialisation of ToME -- Load the system functions -- -- Name of globals to save tome_dofile_anywhere(ANGBAND_DIR_CORE, "load.lua") -- Very thin xml parser(49 lines ;) tome_dofile_anywhere(ANGBAND_DIR_CORE, "xml.lua") -- various vital helper code tome_dofile_anywhere(ANGBAND_DIR_CORE, "util.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "player.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "objects.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "monsters.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "powers.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "building.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "dungeon.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "s_aux.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "crpt_aux.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "mimc_aux.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "quests.lua") tome_dofile_anywhere(ANGBAND_DIR_CORE, "gods.lua") -- Load the ingame contextual help tome_dofile_anywhere(ANGBAND_DIR_CORE, "help.lua") -- let the store specific stuff happen! tome_dofile_anywhere(ANGBAND_DIR_CORE, "stores.lua") -------------------------------------------------------------- -------------------------------------------------------------- -------------------------------------------------------------- -------------Here we load the non vital scripts--------------- -----------------------from lib/scpt-------------------------- -------------------------------------------------------------- -------------------------------------------------------------- tome_dofile("init.lua") -- The dofile functions for each patch patch_dofile = {} -- Now load patches function load_patches() scansubdir(ANGBAND_DIR_PATCH) for i = 0, scansubdir_max - 1 do if (scansubdir_result[i + 1] ~= ".") and (scansubdir_result[i + 1] ~= "..") then local dir = path_build(ANGBAND_DIR_PATCH, scansubdir_result[i + 1]) local file = path_build(dir, "patch.lua") if file_exist(file) == TRUE then patch_init = nil tome_dofile_anywhere(dir, "patch.lua", TRUE) unset_safe_globals() if patch_init == nil then set_safe_globals() quit("Patch in "..file.." did not include a patch_init() function") else set_safe_globals() -- create the dofile function patch_dofile[scansubdir_result[i + 1]] = function(f) tome_dofile_anywhere(%dir, f, TRUE) end local name, version = patch_init() if name == nil or version == nil then quit("Patch in "..file.." did not return valid name or version.\nIt must return name, version") end patch_version(name, version) end end end end end load_patches() -------------------------------------------------------------- -------------------------------------------------------------- -------------------------------------------------------------- -- -- Do not thouch after this line -- tome_dofile_anywhere(ANGBAND_DIR_CORE, "load2.lua") tome-235-src/lib/core/help.lua0000644000076400017500000000676311012107760014030 0ustar dgdg-- Ingame contextual help -- We use our own hook list as to not overburn the hook proccessor -- with many hooks that would slow down things -- It would be very meaningless if the option is not even on __ingame_hooks = {} __ingame_help_max = 0 function ingame_help(t, ...) -- This function can also be used to call the callbacks if type(t) == "string" then local f = getglobal("__ingame_help_fct_"..t) call(f, arg) return end assert(t.desc or t.fct, "no ingame help desc/fct") assert(t.hook or t.callback, "no ingame help hook/callback") if t.hook then assert(t.event, "no ingame hepl event needed by hook") end -- Set it to only trigger once setglobal("__ingame_help_activated_"..__ingame_help_max, FALSE) -- Save/load it add_loadsave("__ingame_help_activated_"..__ingame_help_max, FALSE) if t.hook then -- If the hok list didnt exist yet, add it if not __ingame_hooks[t.hook] then -- Set it to empty, we'll fill it later __ingame_hooks[t.hook] = {} -- Add the global hook add_hooks { [t.hook] = function (...) if option_ingame_help ~= TRUE then return end local k, e for k, e in __ingame_hooks[%t.hook] do if k ~= "n" then call(e, arg) end end end } end if t.desc then tinsert(__ingame_hooks[t.hook], function (...) local tbl = %t if getglobal("__ingame_help_activated_"..%__ingame_help_max) == FALSE then if call(tbl.event, arg) == TRUE then local k, e for k, e in tbl.desc do msg_print(TERM_YELLOW, e) end setglobal("__ingame_help_activated_"..%__ingame_help_max, TRUE) end end end ) elseif t.fct then tinsert(__ingame_hooks[t.hook], function (...) local tbl = %t if getglobal("__ingame_help_activated_"..%__ingame_help_max) == FALSE then if call(tbl.event, arg) == TRUE then if tbl.fct() == TRUE then setglobal("__ingame_help_activated_"..%__ingame_help_max, TRUE) end end end end ) end else local no_test = FALSE if t.no_test == TRUE then no_test = TRUE end if t.desc then setglobal ( "__ingame_help_fct_"..(t.callback), function (...) local tbl = %t if ((option_ingame_help == TRUE) or (%no_test == TRUE)) and (getglobal("__ingame_help_activated_"..%__ingame_help_max) == FALSE) then local k, e for k, e in tbl.desc do msg_print(TERM_YELLOW, e) end setglobal("__ingame_help_activated_"..%__ingame_help_max, TRUE) end end ) elseif t.fct then setglobal ( "__ingame_help_fct_"..(t.callback), function (...) local tbl = %t if ((option_ingame_help == TRUE) or (%no_test == TRUE)) and (getglobal("__ingame_help_activated_"..%__ingame_help_max) == FALSE) then if call(tbl.fct, arg) == TRUE then setglobal("__ingame_help_activated_"..%__ingame_help_max, TRUE) end end end ) end end __ingame_help_max = __ingame_help_max + 1 end -- Clean up the ingame help seen at birth add_hooks { [HOOK_BIRTH_OBJECTS] = function() local i for i = 0, __ingame_help_max - 1 do setglobal("__ingame_help_activated_"..i, FALSE) end end } function ingame_clean() local i for i = 0, __ingame_help_max - 1 do setglobal("__ingame_help_activated_"..i, FALSE) end end -- helper function, brings up a doc function ingame_help_doc(name, anchor) -- Save screen screen_save(); -- Peruse the help file if not anchor then anchor = 0 end show_file(name, 0, -anchor, 0) -- Load screen screen_load() end tome-235-src/lib/core/player.lua0000644000076400017500000000520611012107760014363 0ustar dgdg-- SYSTEM FILE -- -- Lua player funtions -- -- Gods function deity(i) return deity_info[1 + i] end -------- skill stuff --------- -- Easy skill access function skill(i) return s_info[i + 1] end -- Sart a lasting spell function player.start_lasting_spell(spl) player.music_extra = -spl end -- stat mods function player.modify_stat(stat, inc) player.stat_add[1 + stat] = player.stat_add[1 + stat] + inc end -- powers mods function player.add_power(pow) player.powers[1 + pow] = TRUE end -- easier inventory access function player.inventory(i) return player.inventory_real[i + 1] end -- modify mana -- returns TRUE if there is a pb function increase_mana(amt) player.csp = player.csp + amt player.redraw = bor(player.redraw, PR_MANA) if (player.csp < 0) then player.csp = 0 return TRUE end if (player.csp > player.msp) then player.csp = player.msp end return FALSE end -- Return the coordinates of the player whether in wild or not function player.get_wild_coord() if player.wild_mode == TRUE then return player.py, player.px else return player.wilderness_y, player.wilderness_x end end -- Create a new power __power_fct = {} function add_power(p) local i assert(p.name, "No power name!") assert(p.desc, "No power desc!") assert(p.desc_get, "No power desc get!") assert(p.desc_lose, "No power desc lose!") assert(p.stat, "No power stat!") assert(p.level, "No power level!") assert(p.cost, "No power cost!") assert(p.fail, "No power fail!") assert(p.power, "No power power!") i = add_new_power(p.name, p.desc, p.desc_get, p.desc_lose, p.level, p.cost, p.stat, p.fail) __power_fct[i] = p.power return i end function __power_fct_activate(power) if __power_fct[power] then __power_fct[power]() return TRUE else return FALSE end end -- Register in the hook list add_hook_script(HOOK_ACTIVATE_POWER, "__power_fct_activate", "__power_fct_activate") --- Mkeys -- Create a new power __mkey_fct = {} function add_mkey(p) local i assert(p.mkey, "No mkey mkey!") assert(p.fct, "No mkeey fct!") __mkey_fct[p.mkey] = p.fct end function __mkey_fct_activate(power) if __mkey_fct[power] then __mkey_fct[power]() return TRUE else return FALSE end end -- Register in the hook list add_hook_script(HOOK_MKEY, "__mkey_fct_activate", "__mkey_fct_activate") -- Subraces function subrace(racem) return race_mod_info[racem + 1] end function subrace_add_power(subrace, power) for i = 1, 4 do if subrace.powers[i] == -1 then subrace.powers[i] = power return not nil end end return nil end -- Body parts function player.add_body_part(part, nb) player.extra_body_parts[part + 1] = player.extra_body_parts[part + 1] + nb end tome-235-src/lib/core/util.lua0000644000076400017500000001332411012107760014044 0ustar dgdg-- various stuff to make scripters life easier -- Beware of the scary undefined globals function safe_getglobal(x) local v = rawget(globals(), x) if v then return v else error("undefined global variable '"..x.."'") end end function set_safe_globals() settagmethod(tag(nil), "getglobal", safe_getglobal) end function unset_safe_globals() settagmethod(tag(nil), "getglobal", nil) end set_safe_globals() -- Patch modules __patch_modules = {} function patch_version(name, version) assert(not __patch_modules[name], "Patch " .. name .. " already loaded!!!") __patch_modules[name] = version end function patchs_list() local k, e, first first = FALSE for k, e in __patch_modules do if first == FALSE then print_hook("\n\n [Patch modules]\n") first = TRUE end print_hook("\n "..k.." version "..e) end if first == TRUE then print_hook("\n") end end function patchs_display() local k, e for k, e in __patch_modules do msg_print("Patch: "..k.." version "..e) end end -- Better hook interface __hooks_list_callback = {} __hooks_list_callback_max = 0 function add_hooks(h_table, name_prefix) local k, e if not name_prefix then name_prefix = "" end for k, e in h_table do add_hook_script(k, "__"..name_prefix.."__hooks_list_callback"..__hooks_list_callback_max, "__"..name_prefix.."__hooks_list_callback"..__hooks_list_callback_max) setglobal("__"..name_prefix.."__hooks_list_callback"..__hooks_list_callback_max, e) __hooks_list_callback_max = __hooks_list_callback_max + 1 end end -- Wrapper for the real msg_print and cmsg_print -- it understands if we want color or not function msg_print(c, m) if type(c) == "number" then cmsg_print(c, m) else call(%msg_print, { c }) end end -- Returns the direction of the compass that y2, x2 is from y, x -- the return value will be one of the following: north, south, -- east, west, north-east, south-east, south-west, north-west, -- or "close" if it is within 2 tiles. function compass(y, x, y2, x2) local y_axis, x_axis, y_diff, x_diff, compass_dir -- is it close to the north/south meridian? y_diff = y2 - y -- determine if y2, x2 is to the north or south of y, x if (y_diff > -3) and (y_diff < 3) then y_axis = nil elseif y2 > y then y_axis = "south" else y_axis = "north" end -- is it close to the east/west meridian? x_diff = x2 - x -- determine if y2, x2 is to the east or west of y, x if (x_diff > -3) and (x_diff < 3) then x_axis = nil elseif x2 > x then x_axis = "east" else x_axis = "west" end -- Maybe it is very close if ((not x_axis) and (not y_axis)) then compass_dir = "close" -- Maybe it is (almost) due N/S elseif not x_axis then compass_dir = y_axis -- Maybe it is (almost) due E/W elseif not y_axis then compass_dir = x_axis -- or if it is neither else compass_dir = y_axis.."-"..x_axis end return compass_dir end -- Returns a relative approximation of the 'distance' of y2, x2 from y, x. function approximate_distance(y, x, y2, x2) local y_diff, x_diff, most_dist -- how far to away to the north/south y_diff = y2 - y -- make sure it's a positive integer if y_diff < 0 then y_diff = 0 - y_diff end -- how far to away to the east/west x_diff = x2 - x -- make sure it's a positive integer if x_diff < 0 then x_diff = 0 - x_diff end -- find which one is the larger distance if x_diff > y_diff then most_dist = x_diff else most_dist = y_diff end -- how far away then? if most_dist >= 41 then how_far = "a very long way" elseif most_dist >= 25 then how_far = "a long way" elseif most_dist >= 8 then how_far = "quite some way" else how_far = "not very far" end return how_far end -- better timer add function __timers_callback_max = 0 function new_timer(t) assert(t.delay > 0, "no timer delay") assert(t.enabled, "no timer enabled state") assert(t.callback, "no timer callback") local timer if type(t.callback) == "function" then setglobal("__timers_callback_"..__timers_callback_max, t.callback) timer = %new_timer("__timers_callback_"..__timers_callback_max, t.delay) __timers_callback_max = __timers_callback_max + 1 else timer = %new_timer(t.callback, t.delay) end timer.enabled = t.enabled return timer end -- saves all timer values function save_timer(name) add_loadsave(name..".enabled", FALSE) add_loadsave(name..".delay", 1) add_loadsave(name..".countdown", 1) end -- displays a scrolling list function display_list(y, x, h, w, title, list, begin, sel, sel_color) local l = create_list(getn(list)) for i = 1, getn(list) do add_to_list(l, i - 1, list[i]) end %display_list(y, x, h, w, title, l, getn(list), begin - 1, sel - 1, sel_color) delete_list(l, getn(list)) end -- Easier access to special gene stuff function set_monster_generation(monster, state) if type(monster) == "string" then m_allow_special[test_monster_name(monster) + 1] = state else m_allow_special[monster + 1] = state end end function set_object_generation(obj, state) if type(obj) == "string" then m_allow_special[test_item_name(obj) + 1] = state else m_allow_special[obj + 1] = state end end function set_artifact_generation(obj, state) m_allow_special[obj + 1] = state end -- Strings function strcap(str) if strlen(str) > 1 then return strupper(strsub(str, 1, 1))..strsub(str, 2) elseif strlen(str) == 1 then return strupper(str) else return str end end function msg_format(...) msg_print(call(format, arg)) end -- Stacks function stack_push(stack, val) tinsert(stack, val) end function stack_pop(stack) if getn(stack) >= 1 then return tremove(stack) else error("Tried to unstack an empty stack") return nil end end -- A way to check if the game is now running(as opposed to initialization/character gen) game = {} add_hooks { [HOOK_GAME_START] = function () game.started = TRUE end } tome-235-src/lib/dngn/0000755000076400017500000000000011012107763012362 5ustar dgdgtome-235-src/lib/dngn/dun1.140000644000076400017500000000011311012107760013367 0ustar dgdg# On this level there is a stairway leading to the Heart of the Earth B:10 tome-235-src/lib/dngn/dun10.00000644000076400017500000000006511012107760013370 0ustar dgdg# Father branch is Mirkwood(1), on level 14 A:1 L:14 tome-235-src/lib/dngn/dun18.00000644000076400017500000000006711012107760013402 0ustar dgdg# The level is SAVED in the playername.mz? file #S:mz0 tome-235-src/lib/dngn/dun18.10000644000076400017500000000006711012107760013403 0ustar dgdg# The level is SAVED in the playername.mz? file #S:mz1 tome-235-src/lib/dngn/dun2.310000644000076400017500000000010211012107760013365 0ustar dgdg# On this level there is a stairway leading to the Mount Doom B:5 tome-235-src/lib/dngn/dun22.50000644000076400017500000000020111012107760013370 0ustar dgdgN:Orc Town U:s_orc.map D:You hear orc warcries. F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:ASK_LEAVE | NO_TELEPORT tome-235-src/lib/dngn/dun24.00000644000076400017500000000007011012107760013371 0ustar dgdg# Father branch is the Moria(22), on level 10 A:22 L:10 tome-235-src/lib/dngn/dun3.180000644000076400017500000000021611012107760013401 0ustar dgdgN:Dim Gates U:s_gates.map D:Visions of death fill your mind. F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:ASK_LEAVE | NO_TELEPORT tome-235-src/lib/dngn/dun3.280000644000076400017500000000021711012107760013403 0ustar dgdgN:Nameless U:s_name.map D:You sense a powerful artifact here. F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:ASK_LEAVE | NO_TELEPORT tome-235-src/lib/dngn/dun5.140000644000076400017500000000043411012107760013401 0ustar dgdg# The level is SAVED in the playername.mdm file S:mdm # Use the map in s_doom.map file U:s_doom.map # Use Mt Doom as level name N:Mt Doom D:You finally reach the top of Mount Doom, here must lie the Great Fire. F:DESC F:NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:NO_TELEPORT tome-235-src/lib/dngn/dun3.30000644000076400017500000000021111012107760013306 0ustar dgdgN:Crypt U:s_crypt.map D:Looks like a forgotten crypt... F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:ASK_LEAVE | NO_TELEPORT tome-235-src/lib/dngn/dun5.00000644000076400017500000000006411012107760013313 0ustar dgdg# Father branch is the Mordor, on level 32 A:2 L:31 tome-235-src/lib/dngn/dun6.00000644000076400017500000000006311012107760013313 0ustar dgdg# Father branch is Void(11), on level 20 A:11 L:20 tome-235-src/lib/dngn/dun11.200000644000076400017500000000010411012107760013445 0ustar dgdg# On this level there is a stairway leading to the Nether Realm B:6 tome-235-src/lib/dngn/dun11.220000644000076400017500000000004111012107760013447 0ustar dgdg#I'm downright evil F:NO_GENO | tome-235-src/lib/dngn/dun17.150000644000076400017500000000023511012107760013464 0ustar dgdgN:Machine U:s_factory.map D:The clatter of strange machinery surrounds you. F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:ASK_LEAVE | NO_TELEPORT tome-235-src/lib/dngn/dun19.110000644000076400017500000000022511012107760013461 0ustar dgdgN:Deathwatch U:s_death.map D:This level looks filled with evilness. F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:ASK_LEAVE | NO_TELEPORT tome-235-src/lib/dngn/dun22.100000644000076400017500000000011111012107760013444 0ustar dgdg# On this level there is a stairway leading to the Small Water Cave B:24 tome-235-src/lib/dngn/dun29.150000644000076400017500000000024111012107760013464 0ustar dgdgN:Galleon U:s_ship.map D:A ship of antique design lies jammed in the ice here. F:DESC | NO_GENO | NO_NEW_MONSTER | SPECIAL | NO_STAIR F:ASK_LEAVE | NO_TELEPORT tome-235-src/lib/edit/0000755000076400017500000000000011012107763012361 5ustar dgdgtome-235-src/lib/edit/numenor.txt0000644000076400017500000003232111012107760014603 0ustar dgdg# File: numenor.txt # Way to the lost land of Numenor F:>:7:3:0:0:0:0:0:7 ############### Town Layout ############### D:###################################################################################################################################################################################################### D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW>VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:#WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW# D:###################################################################################################################################################################################################### ############### Starting positions ############### # Standard starting position for normal races ?:[EQU $LEAVING_QUEST 0] P:46:128 tome-235-src/lib/edit/t_d_mina.txt0000644000076400017500000003247511012107760014704 0ustar dgdg# File: t_d_mina.txt # Minas Anor: The Royal City of Gondor (destroyed) # original town by Mynstral (mynstral@thehelm.com) # # screwing up by fearoffours (fearoffours@moppy.co.uk) # # Created for ToME # Completed: 23/07/02 # Dead/burnt tree F:D:92:3 # Ash F:A:93:3 # Fire F:F:205:3 # Permanent rubble F:R:206:3 ############### Town Layout ############### D:###################################################################################################################################################################################################### D:#^^########------------------AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF@@@@@@@AAAAAAAAAAAAAAAAAAF@@@@@@@@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF# D:#^^^----#####AF------##FF-------AAAAAAAAAAFFF^AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF@@VVVVV@@AAAAAAAAAAAAAAFFF@@VVVVVVV@@@@@@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF,,,AAAAAAAAAAAAAAAAAAAAAAAAF# D:#^^^----------#R##---###F###-------AAAAAAAAF^^^^^AAAAAAAAAAAAAAAAAAAAAAAAAAADDDAAAAAAAAAAAA@VVVVVVV@@@@@AAAAAAAAAAFF@@VV@@@@@@VVVVVV@@@@AAAAAAAAADDDAAADDDAAAAAAAAAAAAAF,,AAAAAAAAAAAAAAAAAAAAAAAAFFF# D:#^^----ssss-----#R#--------###FF-----AAAAAAAA^^^^^^AAAAAAAAAAAAAAAAAAAAAAADDAAAAAAAAAAAAAFF@VVVVVV@@VVV@@@AAAAAAAAAA@VV@@AAAA@@@@@@VVVV@@AAAAAAAAADDDDDAAAAAAAAAAAAAFFF,,AAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^^---St-RF--------F--#ssss--###-------AAAAFF^^^^^^^^AAAAAAAAAAFFAAAAAAAAAAFFFAAAAAAAAAFFF@@VVVVVVVV@VVV@@@@@@@@F@@@V@@AAAAAAAAAA@@@@VV@@@@AAAAAAAAAAAAAAAAAAAAAAAAAAA,AAAAAAAAAAAFFAAAAAAAAAAAAAAAA# D:#^^----sFss----OO---##--#StSS--FFF##F-----AAAAF^^^^^^^^AAAAAAAAAFFFAAAAAAAAAAAFFFAAAAAAAAFFF@@V@V,@@@@@@VVVVVVVV@@@VVV@AAAAAAAAAAAAAA@@VVVV@@AAAAAAAAAAAAAAAAAAAAAAAAA,,AAAAAAAAAAAFFADDDAAAAAAAAAAAA# D:#^^----##-#-----OOO--#---#s--RF----###------AAAA^^^^^^^^AAAAAAAAAAFFAAAAAAAAAAAAAAAAAAAAAAFFF@@@@@AAAAF@@@@@@@@VVVVV@@@AAAAAAAAAAAAAAF@@@@VV@@@AAAAAAAAAADDAAAAAAAAA,,,AAAAADDDAAAAAFFAAAAAAAAAAAAAAF# D:#^F---------------OO---#-####-#------AAAA----FFF^^^^^^^^^^AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF@VVV@@AAAAAAAAAAAAAAAAA@@VVV@@AAAAAAAAAAAAAAAAAFFF,O,AAAAAAAAADDDDAAAAAAAFAAAAAAAAAAAF# D:#^FStSSSS-----ss---OO---##-----OOOOO---###----FFF^^^^^^^^^^^AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@@AAAAAAAAAAAAAAAAAFFF@@VVV@@AAAAAAAAAAAAAAAAAFFOOAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAFF# D:#^^ss-AFF----Ssss---AFO--#-F--R#O-O-OO---##----FFFAD^^^^^^^AAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAADDDAAAAAAAAAAAAAAAAAAAAAAAAAAAF@@VVV@AAAAAAAAAAAAAAAAAFFOOAAAAAAAAAAAAAAAAAAAAAAAAAADDAAAAAAAFFF# D:#^F#-R###---sAFR--F--OOO--F#-OOOOOOO-OOO--##----AAAA^^^^^AAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF@@VVV@@AAAAAAAAAAAAAAAAAFOOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^^-------##sssSss---AAO--#OOO--s--OOOOO--###F--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@@@@@@@@@AAAAF@@VVV@@AAAAAAAAAAAAAAAAAFOOAAAAAAAAAAAAAAAAAAAAAADDDAAAAAAAAAAAF# D:#^^^##RR##---##AFA--s--OOO-OOO--StS#-OOOO----#FF--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF@@VVVVVVVV@@@@@@@V@@@@AAAAAAAAAAAAAAAAAFOOAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAFF# D:#^AA^----###---##--ssS--OOO--##-ssss--OOOOOO--#R---AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFFAAAAAAAADDDDAAAAF@VVVVVVVVVVVV@@VV@@AAAAFFOOOAAAAAAAAAAAAAAOOAAAAAAAAAAAAAAAAAAFFAAAAAAAAAAAAAFFF# D:#^^--------#R-----ssSs#--AF#-#--#AFAF#-OOAAAO--##-AAAAAAAAAAAAAA----AAAAAAAAAAAAAAAAAAAAAAAAFFFFFFFFFAAAAAAAAAAAAAAAAAAA@VVVV@@@@VVVVVVV@@AAAAFFOOOOOAAAAAAAAFOOOOOAAAAAAAAAAAAFAAAAAAAAAADDDAAAAAAAA# D:#^F-----------#--#s-RRF-OO-O--#---------OOOOOO--FF-----AAAAFFF--------AAAAAAAAAAAAAAAAAAAAAAAAAFFFFAAAAAAAAAAAADAAAAAAF@@VVV@@FF@@VVV@@@@AAAAFFFOOFFOOAAAAFFFOOAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAFF# D:#^^----AAA----R---###--OOOOOO-#--#sss#RF-OOOOOO,#FFFF---AAAAF---#-------AAAAAAAAAAAAAAAAAAAAAAAAFFAAAAAAAAAAAAAAAAAAFF@@VVV@@AAAA@@@@@AAAAAAAAFOO-FFFOOOOOOOOOAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAFFF# D:#^^-------------##-#-#-O#-OOO--#--ssssss----OOO,,,,,#----FF-AAssAF--R----AAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAADDDAAAAAAF@VVV@@AAAAAAAAAAAAAAFFF-ORAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFAAAAAAAF# D:#^^-------------R#---O-O-t-OOO-F#-#SS-##--OOOOOO,##,##--------sssssssAAA-#AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDAAAAAA@VV@@AAAAAAAAAAAAAAFF--OO-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAF# D:#^^^-FAF--AA-----##-OOO-sssOOAA-#--ssssss-OOOOOO--#,#RR##-----SSR---SS-----AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDAAAAAAA@@VV@AAAAAAAAAAAAAAFF--OR-AAAAAAAAAAAFFAAAAAAAADDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^^--AF----------#OOORA#-RFOOO-#--ss#sss--OAAOOOFFAAAF##FF---sFFFAFss--O---AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF@@VVV@AAAAAAAAAAAAAAFF-OO--AAAAAAAAAAAAAAAAAAAAAAAFFAAAAAFFFAAAAAAAAAAAAAAAAAAAAA# D:#^^--###--AAAA--AA--O-------OOAAA--####AAA-OOOOOO-##,###,,##--sssFAFAs--AAA-AAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAF@VVV@@AAAAAAAAAAAAAAF--O--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFAAAAAAAAAAAAAAAAF# D:#^^^-##AFA-------OOO#--SSStS---OAAAAA----AAAOOOO---#AAAAAAF#F-ssssR-#F--O-----AAAAAAAAAAAAAAAAAAAAAAAAAFFAAAAAAAFFF@@VV@@AAAAAAAAAAAAAAF--OR-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF# D:#^^-####R-------OOO-#--sssss-OOO-##---#s--OOOOO--T-#,--AAAAA--AFA##AA#--O---AA-AAAAAAAAAAAAAAAAAAAAFFAAAAAAAAAAAAFF@VVV@AAAAAAAAAAAAAAF--OO--AAAAAAAAAAFFAAAAAAAADDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^#######------OO--##-###R-AAAO-##-ssss---OOOO-TT-FAA-AAA,#----AAA,,,,,O------AAAAAAAAAAFFFAAAAAAAAAFFFFAAAAAAAAF@@VV@@AAAAAAAAAAAAAA--OO--AAAAAAAAAAAAAAAAAAAAADAFFAAAADDDAAAAAAAAAAAAAAAAAAAAAAAAF# D:#^^^###AFAF#----OOO--#---R---OOO--AAS#-R--OOOOAAAT-#---AA,,###----------O---AA--AAAAAAAAAFFAFAAAAAAAAAAFFFAAAAAAAA@VVV@@AAAAAAAAAAFFF--OO--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFAAAAAAAAAAAAAAAAAAFF# D:#^^#####R--####-OR---##-StSSS-AAO-#-sss-RFOOOOO--T-#F---,,##FF-s-ssAFF--O--------AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@VV@@AAAAAAAAAAFFF--ODR--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF# D:#^^^#########---OOOAAA#-sss-RF--O---ssss-AAOOOOO---FF,AAA#FF---SSSAFAFF-O--AAA-AA-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF@@@VVV@AAAAAAAAAAFFF--ORO--AAAAAAAAAFAAAAAAAAAAAAAAAAAAADDDAAAAAAAAAAAAFFFAAAAAAFFF# D:#^^###AAA###----OOO#--#-###A##OOO-#-##A#---OOOOOO--##FF#A#-----sR-ssss--O----------AAAAAAAAFFFAAAAAAAAAAAAAAAAAAAA@VVVV@@AAAAAAAAAAF---OOO--AAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAA# D:#^^^##R##-------OOO---#-#--^--OOO-#----#----OO--RROOFOOOOOOOO--####--R#-O-----------AAAAAAAAFFAAAAAAAAAAAAAAAAAFF@@VVV@@AAAAAAAAF-A----OO--AAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAFFFAAAAAAAAF# D:#^^######-##OOOROOO-^^^^^^^^-^MMM^^^^^^^^#^^^OOOOOO-ROOOO-ROOAOOOOOOOAAOO----AAA----AAAAAAAAAAFAAAAAAAAAAAAAAAA@@@VVV@@AAAAAAAAFA-AOOOOOO--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDFAAAAFFAFFFAAAAAAAAF# D:#^^####AFFAAOROOOO######A#####III##-#########^OOAAAOOOOOOO#OOOOOOOOOO#OOOOO-------AAAAAAAAAAAAAAAAAAAAAAAAAAAF@@VVVV@@AAAAAAAAF---OOOOOO--AAAAAAAAAAAAAAAAAAAAAAAFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF# D:#^F######-##OOOO-##-####AA#AA#III#####-##--##^OOOOR-OOOOOOOOAAAOO-OOOOOOOOOO------A--AAAAAAAAAAAAAAAAAAAAAAAAA@VVVV@@AAAAAAAA----OOORRO----AAAAAAAAAAAAAAAAAAAAAAAFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^F###-A##-OOOOOOOO-^#^^^^^#A^MM#^^^^#^^#^^-#AFOOAFOOOOOR-OOOOAOOOOOOOOOOOOOOO--AA---AAAAAAAAAAAAAAAAAAAAAAAAA@VVV@@AAAAFFA--AD-OOOR-----AAAAAAAAAAFAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF# D:#^^^#######-----OOO---A-sAA#--OOO##--##-----R--OOOOOOOOOOOOOO-----------OOO-R-O----AAAAAAAAAAAAAAAAFFF---------##@VVVR##F--------OOOOO-----AAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAFFFFFAAAAAAAAAA# D:#^^#########----OAO---#-sSss--OOO---ssss#--OOOOOO--##FF###---AA---ss-#-#O-OOOOO-AA--AAAAAAAAAAAAAAFFF--OOOO-----######R--------OOOOOO-----AAAAAAAAAAAAADDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAF# D:#^^####R-AFA#---OOR--R--sts##-O-R-#-SSASS-OOOOOO---##F##AFF---------t-S-O-OOROO----AAAAAAAAAAAAAAFFF--OOOOOOOOOOOOO#OOOOROOOOOOOOOOO-AAA-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFDDAAAAFFAAAAAAAAAAA# D:#^^###########--OOO--##-sSFR--OOO-R-s-#---AFOOO--TFF#F#,,,##F#--A-sssss-O--OOOOO---AAAAAAAAAAAAAAFF--ROOOOOOOOOOOOOOOOOOOOOOOOO#AOO-----AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFADDDAAAAAF# D:#^^#R--R--##----OOO--#--####-OOO--#-sssss-OOAOO-TT-#,,,,-AAFF-----sAAFA-R---OR-O---AAAAAAAAAAAAAAF--OOOAA-OOOOOOORAAO#OOOOOOOOOOO------AAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFFAAAAAAAAAF# D:#^^#######------O-R-##-------OO---#-###A#-OOOOO-TT-F#----AFF#F----###R--O-AAOOOOAA--AAAAAAAAAAFFF--OOOO---------#######------------A--AAAAAAAAAAAAAAAAAAAFAAAAADDAAAAAADDAAAAAAAAAAAAADDDAAAAAAAAAFFF# D:#^^-###R-#-AA---OOO-#--S-ss##OOO-#--------OOOOO--T-##-----AAA----A------A----OOOO----AAAAAAAAAAF--OOOA----DD---##@VVV@##-D-----A---AAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF# D:#^^^-###---------OO-#-#stss--OOO-#-ssssss--OR-RO---#,--AA,A#----sss-#s--O-----OOOO--A-AAAAAAAA---OOOO---AAAAAAAAF@VVV@@AAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAFFAAAAAAAAAA# D:#^^--####---------OOO--#s#s-OOO--FRStS##---OAFAOO-#FF-,,#F##----S--#AA--O------OOR-----AAAAFF--OOOOO----AAAAAAAAF@VVV@@AAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF# D:#^^---#AA--AA-----#OOO--##--OOO-###ssssss--OOOOOO-#,,,##FF#------RsAFA--O--A----OOR#----AAAA--OOOOO----AAAAAAAAAA@VVVV@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^^--#------AFF-R--AFAAA--OO----#-###A##-OOR-OO--#F####AAA-AA--ss#-ss-OO----D---OOOO----AA--OOOOO---FFFAAAAAAAAF@@VVV@@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF@@@@AAAAAAAAAAAAAAAAAAAAFFF# D:#^^^-------------#---OOO---OOO--#F------##OOOOOO##AAAAF-AA--AA--#-##-AAA-R-AA-----R--A----OOOOOO-AA--AAAAAAAAAAFFF@@VVVV@@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF@@@@@@AAAAAAAAAADDAAAAAAAAFFF# D:#^^----------AFFA-----AFAAOOO-----ss------OOR-O,,##FAAA--------AAA-----AAA--A--AAA-OOOOOOOOROO-----AAAAAAAAAAAAAAFF@@@VVVV@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@@@@@@@@V@@@AAAAAAAAAAAADDDDAAAAFF# D:#^^^----AAAA-R-##-#ss--OOO#OO-##F-#Ss----OOOA-O,F#AAA---AAAAA-------AA-O--------F---OOO#OOOOO--AAAAFFFAAAAAAAAAAAAAAF@@VVVV@@AAAAAAAAAAAAAAAAAAAA@@@@@AAAAAAAAAA@@@@@@@@@@@@@AAAAAAAAAAAAAAAAAAAAAAAA# D:#^^^---------##---ss-s--OOOO----Fsst#DD-OOOOOO--#F-----F------ssss-s--OR---A--AAAA---OOOOO-A--AAFFAAAAAAAAAAAAAAAAAFFF@@VVVV@@@AAAAAAAAAAAAAAFF@@@VVV@@@AAAAAAAA@@@V@@@@@@@@AAAAAAAAAAAAAAAAAAAAAAAAF# D:#^^--------##R---sstss#--OOO-##FssS-#--OOO#OO--##F----AAAA-----#S--RR-OA-----AAAAFF----------AAAAAAAAAAAAAAAAAAAAAAAAAF@@@VVVV@@@@@AAAAAAAAF@@@@VVVVVVV@@FFF@@@@@V@@V@@@V@@AAAAAAAAAAAAAAAAAAAAAAAAFF# D:#^^-AAAA-###-----#Ss-R--OOOOO###sSs#--OOOOOO--##-----AAAAFF---ssssss--O-----AAAAAAAAAAA-AA-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@@@VVVVVV@@@@@@@@@@@VVVVV@@@VVV@@@@@VVVV@@@@F@@@@AAAAAAAAAAAAAAAAAAAAAAAAFFF# D:#^^^######----#---#s#--OOO-OOO--Ss#--#OAA#---##-#AAAAAAAAAAA--##--##-OO--DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFF@@VVVVVVVVVVVVVVVVV@@@@@F@@@VVVVVVV@@@@AAAAAAAAAAAAAAAAAAAAAAAAAAADDAAAAAF# D:#^^^-------ss-#S---#--OOO---AA#--#--OOOOR--#-------AAAAAAAAAA--------O-----AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF@@@@@@@@@@@@@@@@@@@AAAAFFF@@@@@@@@@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^-sssss-#sssts-----OOO--#--OOO---OOOOO---#AF-AAAAAAAAAAAAAAF------OO-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFF# D:#^^-SSStA--#sSAFs#--OOO--#----AOOOOOOAA--#-------AAAAFFAAAFFAAAFAA--O----AAAAADDAAAAAAAAAAAAAAAAAAAAAFFFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^-sFAF----#ss-R--OO----#--AF-OAOOO------------AAAAAAAAFAAAFFAA---O---AAAAAAADDDAAAAAFFFFAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAADDAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAFF# D:#^^^#####----##---OO--###--XXX-OOO----#-------AAAAAAAAAAAAAFAAAAFF---AAAAAAAAAAAAAAAAAAAAAAAADDAAAADDDFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDAAAAAFAFFFAAAAAAAAAAAAAAAAFFFFFFFAAAAAAFFFAAAAAAAAAAAAAA# D:#^^^------------OOO--###--XXX#----FAFFA----AAAAAAAAADDDDAAFAAAFAAAAAAAAAAAADDDAAAAAAAAADDAAADDAAAAAFDDFAAAAAADDAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDDAAAAAAAAAAAAAFFAFFAAAAAAAAFFFFAAAAAAAAAAFFF# D:#^^--SStSSAAA--OO-AAA#--XXAA#---#AFA-AAA-AAAAAAADDDDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDAAAAAAAAAAAAFFFFAAAAAAAAAAAAAAAAAAAFFFFAAAAAAAAAAAAAAAAAAAAFFAFFAAAAAAFFFFFADDAAAAADDDAAAAF# D:#^^^-sss-R----------#--###-----AF#-----AAAAAAAAADDDDAFAAFAAAFAAAFAAADDDAAAAAAAAAADDAAAAADDDAAAAAAAAAAAAAAAADDDAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAADDADDDAAAAAFFFFFAAAAAAAAAAAAAAAAAAAAAAAAAAA# D:#^^--####-------###--------###-#-#---AAAAAAAAAAAAAAAAAAFAAFAAFAAAAAADDDDAAAAAAAAAFFAAADDDAAAAAAFFAFFFFFAADDAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFF# D:#^^^----------##-----##-#-#-AFF---AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFFFAAAAAAAAAAAAAFFFFAAAAAAAAAAAAAAAAADDDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFF# D:#^^^------##-#--##-###--#-------AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADDDAAAAAAFFFFFAAAAAAAAAAAAAFFFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF# D:#^^######-#-----------------AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF# D:###################################################################################################################################################################################################### tome-235-src/lib/edit/s_orc.map0000644000076400017500000000700011012107760014157 0ustar dgdg# Special level "The Orc Barracks" in the Pits of Angband # # Created for PernAngband 5.0.1 on 18/8/01 %:special.txt #Y:40:118:126:149:264:238:285:313:330:404:15:0:0:35:22 # Shrieker F:a:1:0:40 # snaga F:b:1:0:118 # cave orc F:c:1:0:126 # hill orc F:d:1:0:149 # half orc F:e:1:0:264 # ogre F:f:1:0:238 # ogrillion F:g:1:0:285 # bolg F:h:1:0:330 # uruk F:i:1:0:313 # black orc F:j:1:0:244 ### Random Monsters and/or Items # Random monster (upto 5 levels ood) on normal floor F:&:1:0:*35 # Random monster (upto 11 levels ood) on normal floor F:@:1:0:*46 # Random monster (upto 9 levels ood) and # Random object (upto 7 levels ood) on normal floor F:8:1:0:*44:*42 # Random monster (upto 40 levels ood) and # Random object (upto 20 levels ood F:9:1:0:*75:*55 # Random monster (upto 3 levels ood) F:-:1:0:*38 # Random object (upto 7 levels ood) F:=:1:0:0:*42 ### Guaranteed Items # The stone of lore F:1:1:0:0:0:0:15 ### Level Design D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:Xa.......................ccccccccc.......................aX D:X.lllllllllllllllllllllllllllllllllllllllllllllllllllllll.X D:X.l......................ccccccccc.....g.g..............l.X D:X.l.XXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXDXXXXXXXXXXXXXX.l.X D:X.l.Xa.......efX1Xfe.......aX.X.aaa.D.gX.XacbdddccjjjaX.l.X D:X.l.D........efG.Gfe........D.D.bbb.XXXX.XcfbcbcbbjjeeX.l.X D:X.l.X........efX.Xfe........X.X.bbb.D.gX.XfbbgdcbdbjjjX.l.X D:X.l.XXXXXX...efG.Gfe...XXXXXX.X.bbb.XXXX.XebdcfbdccejjX.l.X D:X.l.X.c..XXX.efX.Xfe.XXXcc.aX.D.ccc.D.gX.XcfcbgeebdebfX.l.X D:X.l.D..d..aXXXfX.XfXXXe.....D.X.ccc.XXXX.XedbcdbcdcggeX.l.X D:X.l.X........XXX.XXX..bbb.ddX.X.ddd.D.gX.XdgfcfegbeebcX.l.X D:X.l.X..f.c.bf.G...G.c..cc...X.D.ddd.XXXX.XcbeefccbfbdbX.l.X D:X.l.X.d..bb.d.Gi.iG...cbb.bdX.X.eee.D.gX.XbgcfbgcfdebcX.l.X D:X.l.X.cc...c..G.7.G.cc..d.e.X.X.eee.XXXX.XcbdfeccdbcdbX.l.X D:X.l.X..b.f.bbXGGGGGX.bbb.bb.X.D.f.f.D.gX.XfdebbdgeefgdX.l.X D:X.l.D.c..dbbXXa...aXXX..d...D.X.f.f.XXXX.DdefddbcbdbddX.l.X D:X.l.X...c.XXX..g.g...XXX...bX.X.....D..XGXXeegcefdcefcX.l.X D:X.l.Xbb..aXg.gggjgggg.gX.bbaXDXaaa..XXjIa8XacbddbegbdaX.l.X D:X.l.XXXXXXXXDXXXXXXXXDXXXXXXXaXXXXXXXXXXXXXXXXXXXXXXXXX.l.X D:X.l........................Da.aD........................l.X D:X.l.XXXXXXXXXXXXXXXXXXXXXXXXXaXXXXXXXXXXXXXXXXXXXXXXXXX.l.X D:X.l.....eeeeee.........fffXXXDXXXfff.........eeeeee.....l.X D:X.l.....eeeeee.........fffX.....Xfff.........eeeeee.....l.X D:X.llllllllllllllllllllllllX.....Xllllllllllllllllllllllll.X D:Xa.....................XXXXGGGGGXXXX.....................aX D:XXXXXXXXXXIXXXXXXXXXXXXXgafff>fffagXXXXXXXXXXXXXIXXXXXXXXXX D:XjjjX.#########.XfffXXgggfffffffffgggXXfffX.#########.XjjjX D:XfffX...........XeeeXggggjjj...jjjggggXgggX...........XfffX D:XfffXGGGDX.XXXXXX...Xgggg....h....ggggX...XXXXXX.XDGGGXfffX D:Xgg......X.X........Xgggg.........ggggX........X.X......eeX D:Xgg....ggX.X.XXXXXX.XXgggggggggggggggXX.XXXXXX.X.Xee....eeX D:Xgg....ggX.X.X......XXXXgggggggggggXXXX......X.X.Xee....eeX D:Xgg....ggX.X.X.XXXXXX..XXXXfffffXXXX..XXXXXX.X.X.Xee....eeX D:Xgg....ggX.X.X.........#.4XXXDXXX4.#.........X.X.Xee....eeX D:Xgg....ggX.X.XXXXXXXXXIXXXXa...aXXXXIXXXXXXXXX.X.Xee....eeX D:Xgg....ggX.X.Xigfedcba.XiX..X#X..XiX.abcdefgiX.X.Xee....eeX D:Xgg....ggX.X.XGGGGGGGGGX....X.X....IGGGGGGGGGX.X.Xee....eeX D:XggggggggX.X.X@@@@@@@@@IXXXaX7XaXXXX@@@@@@@@@X.X.XeeeeeeeeX D:XggggggggI.X+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+X.IeeeeeeeeX D:XaaaaagggX.......................................XeeeaaaaaX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ### Starting Location P:22:31 tome-235-src/lib/edit/qrand1.map0000644000076400017500000000045211012107760014244 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Door F:D:38:6 # Floor with Trap F:t:1:8:0:0:0:0:* # Deep lava F:F:85:12 # Dungeon layout D: D: xxxxxxx D: xpGF..x D: xGGF,.D D: xFFF..x D: xxxxxxx D: tome-235-src/lib/edit/trolls.map0000644000076400017500000000163711012107760014403 0ustar dgdg# Permanent wall F:X:63:3 # up stairs F:<:6:3 # Floor with tree F:T:96:3 # Floor with tree(marked) F:H:96:1027 # Floor with dirt F:.:88:3 # Floor with grass F:;:89:3 # Floor with forest troll F:f:89:3:297 # Floor with stone troll F:s:89:3:401 # Floor with algroth F:a:89:3:424 # Floor with Bert F:b:89:3:493 # Floor with Bill F:i:89:3:494 # Floor with a Dwarven skeleton F:k:89:8:0:396 # Marker F:,:172:6 # Dungeon layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X..HTTTTTTTTTTTTTTTTTTTTTTTX D:XH...;TTTTTTTTTTTTTTTTTTTTTX D:XTTT;;HTTTTTTTTTTTTTa.TTTTTX D:XTTH.k...TTTHHkTHTs.fTTTTTTX D:XTTTT;..f.TT.;...HTTTTaTTTTX D:XTTTTTHT...;......TTT..HTTTX D:XTTTTTTT;;.k..;k.HH.i.TTTTTX D:XTTTTTTH.HTHTT..TH.,.HTTTTTX D:XTTTTT;THTTTTTHTH.bTTTTTTTTX D:XTTT.f.TTTTTTTaTTs;TTTTTTTTX D:XTTs..TTTTTTT...fHTTTTTTTTTX D:XTTTas.TTTTTTTTTTTTTTTTTTTTX D:XTTTTTTTTTTTTTTTTTTTTTTTTTTX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXX # Starting position P:3:3 tome-235-src/lib/edit/qrand5.map0000644000076400017500000000057311012107760014254 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Dungeon layout D: D: xxxx.xxxx D: xx.......xx D: xxx..,...,..xxx D: xx.....GGG.....xx D: x......GpG......x D: xx..,..GGG..,..xx D: xxx....,....xxx D: xx.......xx D: xxxx.xxxx D: tome-235-src/lib/edit/qrand6.map0000644000076400017500000000062311012107760014251 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Door F:D:38:6 # Floor with Trap F:t:1:8:0:0:0:0:* # Deep water F:W:84:6 # Shallow water F:w:187:6 # Dungeon wayout D: D: xxxx xxxx D: xxxx xxxx D: xxxxxxxxxxDxx D: D,,,GpG,,,D D: xxxxxxxxxxDxx D: xxxx xxxx D: xxxx xxxx D: tome-235-src/lib/edit/qrand7.map0000644000076400017500000000052311012107760014251 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Door F:D:38:6 # Floor with Trap F:t:1:8:0:0:0:0:* # Deep water F:W:84:6 # Shallow water F:w:187:6 # Dungeon wayout D:ttttt D:tGGGt ,x, D:tGpGt x,x D:tGGGt ,x, D:ttttt D: ,x, D: tome-235-src/lib/edit/t_bree.txt0000644000076400017500000003431311012107760014363 0ustar dgdg# File: t_bree.txt # Bree ############### Additional default terrain settings ############### # Default for Quest 1 = entrance is quest entrance F:z:8:3:0:0:0:0:0:4 # Default for Quest 18 = entrance is tree F:y:96:3 # Default for Quest 18 = entrance is tree F:x:96:3 ############### Quest 4 - Thieves Hideout finished = house ############### ?:[EQU $QUEST4 2] F:z:74:3:0:0:0:0:0:7 ?:[EQU $QUEST4 5] F:z:74:3:0:0:0:0:0:7 ?:1 ############### Quest 8 - Troll Glade ############### ?:[AND [EQU $QUEST8 1] [EQU $DAYTIME 0] ] F:y:8:3:0:0:0:0:0:8 ?:1 ############### Quest 9 - Wights Grave ############### ?:[EQU $QUEST9 1] F:x:8:3:0:0:0:0:0:9 ?:1 ###### Additionnal buildings ####### # Castle: Plot Bree F:B:75:3:0:0:0:0:0:1 # Mayor's house F:b:74:3:0:0:0:0:0:10 # The Prancing Pony F:a:74:3:0:0:0:0:0:58 # Soothsayer F:c:74:3:0:0:0:0:0:12 # Merchant Guild F:d:74:3:0:0:0:0:0:56 # The Mathom-house F:e:74:3:0:0:0:0:0:57 ############### Town Layout ############### D:###################################################################################################################################################################################################### D:# VV -- # D:# V -- # D:# VV -- # D:# VVV -- # D:# VV -- # D:#OOOO V -- # D:# OOOO V -- # D:#--- OOOOO VVV --- VV # D:#------ OOOOOO V -- VVVV # D:#---------- OO V -- VVWWVVV # D:#-------------- OO VVV -- VVVWWWWWVVV # D:#--------------- OOO VVV -- VVWWWWWWWWWVV # D:#----------------- OO VVVVVVV VVWWWWWWWWWWWV # D:#------------------- OOOOO --VVVV VVVVV VVWWWWWWWWWWWVV # D:###------------------ OO ,,,,,,,,,,,,,,,,,, -- VVVVV VV VVVVVVVWWWWWWWVVV # D:#CC####------------------ OOO ,,,,,CCCCCCCCCCCCCCCCCC,,,,,,,,, -- VVVVVV VVVVWWVVV # D:#TTCCCC###---------------,, OO ,,,CCCCCCTTTTTTTTTTTTTTTTCCCCCCCCCC,,,, -- VVVV # D:#--TTTTCCC###---------,,,-- OO ,,CCCCTTTTTT--------------TTTTTTTTTTCCCCC,,,,, ^-- # D:#------TTTCCC##-----,,------ O ,,CCCTTTT..................----------TTTTTCCCCCC,, ^^^ -- # D:#---------TTTCC##,,,-------- OO ,CCCTTT....--ssssssss-..---..........-----TTTTTTCCC,,, ^^ -- # D:#------------TC,,###- --- OO ,CCTTT...-----SSSSSSSS--.----------,,.....------TTTCCCC,, ^^ -- # D:#-------------,TTCCC### -- OOO ,,CCTT...-,,,,--ssssssss-..-sssssssssss,---......---TTTTCCT,, ^^ -- # D:#--------- ,,,--TTTCCC -- OO ,,CCCTT..-------,,##9#####-.--sssssssssss-,-------...----TTCCTT, ^^^ -- # D:#-------- ,, ,,----TTTCC O ,CCC T..--sssSsss,,,,------.--StSStSSSStS--,------.-....--TTCCTT,^^^ -- # D:#------ ,, , OO ,CCTTT...---ssstSSS---,,,----.--sssssssssss---,---...----..--TTCCT^^^^ ^^ -- # D:#------- x, ,, OO ,CCTT...-----sssssss--,,-,,---.--sssssssssss---,-...-------..--TTC^^^ ^ ---- # D:#------- {, OO ,CTT..---,,,,###6###,,,---,,--.--###########----..----------..--T^^^^ ^ --- -- # D:#--------- OOO ,CT..,,,,----,,,,,,,,------,,-.--###b###e###-....,---sssss---.--T^^ ^ -- -- # D:#---------- OO ,CCT.,sssssss----,-----------,,.-----.-----....-,--,,-StSSS---.-T^^^ ^ -- ----- # D:#------------- OO ,CCTT.-StStSSS---,-----ssssss--..-----.--....--,,,,,,-,sssss---.-T^^^ ^ -- -- ,,, # D:#----------- OOOOO ,CTT-.-sssssss---,-----SSSSSS--.------.-..--,,,-ssss--,#####---.-T^^ ^ -- ----- ,, # D:#-------- OO ,CCT-..-##5####----,----ssssss-..........--XXXX,-ssss--,------...-^^^ ^ ^^ ^ --- ---- ,,, # D:#- ---- OOOOOOOO ,C OOOO--OOOOO----,----#c##4#-.---.,----,-UUUU,-SSSS--,-----..---^^ ^ ^ --- -----, OOOOOOOOOOOOOO# D:#- ---- OOOOOOO ,CT-OssOOOO---OOOOOOOOO--OOOO--.-T-.-sss--,XXXX,-ssss---,---..--T^^ -- -- OOO # D:#- ----- OOOOOOOOSt.---------XXXX-OOOO--OOOO---.-StS--,#0##,-ssss---,---.---^^ ^ ^ -- --- OOOO # D:#- --- ----- ,,CT--.ss.-sssss---XXXX,---------OOOO.-sss---,,,,,-####--,---..-T^^ ^ ^ -- --- OO # D:# ---- ---- ,,CT--.B#.-SStSS---####,------------OO-#z#-ssssss-,,,---,----.--T^^ ^ -,- OOOOO # D:# ------- ---- ,,CTT-....-sssss--,,,,,,-------------OO-,--SSSSSt-ss-,-,---...-T^^ ^ ^ -, OOOO # D:# ------- ------ ,,CCTT---..#2###-,sssss,-SSSSSSSS-----OO,--ssssss-tS--,.....---^^ ^^ ^^^ -, OOOOOOOO # D:# ----- ----- ,,CCT----..,,,,,-StSSS,-ssssssss------OOO-#1##a#-ss....-----T^^ ^^ -,- OOOOO # D:# ---- -------- ,,CCTT----..----,sssss,-##7###d#--------OO,.,,.,-##.----TTTT^^ ^ ^^ -, OOOOO # D:# --------------- ,,,CCTTTT--..---,##3##-,--,,,---------...OOOOOOOOOOOTTTTTCC^^^ ^^ ^^ ,- OOO # D:# -------- ,,,CCCC --..........,-,,---,--.......-------TTTTTOCCCCC,,^^^^^^^^^^^ -.- OOOOO # D:# ---------- ,, ,,CCCTT----------.....-......-------TTTTTTTCCCCO,,,,, ^^^^^^^ -.- O # D:# ------- ,, ,,CCTTTTTTTTTT-----...------TTTTTTTCCCCCC,,,,OOO -.- OOOO # D:# ---- ,,, ,CCCCCCCCCCTTTTT-----TTTTTTCCCCCC,,,,,, OOO OOOOOOOOO # D:# ^^ ---- ,, ,,,,,,,,,,CCCCCTTTTTTCCCCC,,,,,, OO OOO-- # D:# ^^^^^ ,,, ,,,,,CCCCCC,,,,, OOOO OOO-- # D:# ^^^^^^^^^ ,, ,,,,,, OOOOOOO OOO--- # D:# ^^^^^^^^^ ,, OOOOOOO---- # D:# ^^^^^^^^^^^^^^^ ,,, ..------ # D:# ^^^^^^^^^^^^^^ ,,, ...... ....----- # D:# ^^^^^^^^^^^^^^^ ,,, ........... ............ ............-------,,,, # D:#^^^^^^^^^^^^^^^^^ ,, ... .........-------------- ,,,,,,, ,,,,,,,,, # D:# ^^^^^^^^^^^^^ ,, . ,,,,,, ,,,,,,,,, # D:# ^^^^^^^^^^^^^^ ,, ... ,,,,, ------ --- # D:# ^^^^^^^^^^^^^^^ ,, . ,,,,,,,,------- ----- # D:# ^^^^^^^^^^^^^^ , .. ---------------- # D:# ^^^^^^^^^^^^^^^^ ,, .. ---------y-------- # D:# ^^^^^^^^^^^^^^^ , .. ----------------- # D:# ^^^^^^^^^^^^^^^^ ,,. --- ---- ---- # D:# ^^^^^^^^^^^^^ ,. - -- -- # D:# ^^^^^^^^^^^^^^ . # D:# ^^^^^^^^^^^^^^ . # D:###################################################################################################################################################################################################### ############### Starting positions ############### # Standard starting position for normal races ?:[AND [EQU $LEAVING_QUEST 0] [NOT [EQU $RACE Vampire] ] ] P:33:131 # Standard starting position for vampires (at the dungeon entrance) ?:[AND [EQU $LEAVING_QUEST 0] [EQU $RACE Vampire] ] P:31:150 tome-235-src/lib/edit/f_info.txt0000644000076400017500000004471511012107760014372 0ustar dgdg# File: f_info.txt # This file is used to initialize the "lib/raw/f_info.raw" file, which is # used to initialize the "terrain feature" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/raw/f_info.raw" file. # Note that the terrain feature are grouped into very regular groups, # such that each of the bits in the feature type conveys information. # Note that terrain feature zero contains the "darkness" picture. # Version stamp (required) V:2.0.0 # 0x00 --> nothing N:0:nothing G: :w F:FLOOR # 0x01 --> open floor N:1:open floor G:.:w F:FLOOR | DONT_NOTICE_RUNNING | SUPPORT_LIGHT | CAN_RUN F:SUPPORT_GROWTH # 0x02 -> fountain N:2:fountain G:_:w F:FLOOR | NOTICE | REMEMBER | CAN_RUN D:0:The liquid here seems magical. # 0x03 --> glyph of warding N:3:glyph of warding G:;:y F:FLOOR | NOTICE | SUPPORT_LIGHT | CAN_RUN | REMEMBER D:0:There is a mighty spell of protection here. # 0x04 --> open door N:4:open door G:':U F:FLOOR | NOTICE | REMEMBER | CAN_RUN | DOOR # 0x05 --> broken door N:5:broken door G:':U F:FLOOR | NOTICE | REMEMBER | CAN_RUN | DOOR # 0x06 --> up stairs (perm) N:6:up staircase G:<:w F:FLOOR | PERMANENT | NOTICE | SUPPORT_LIGHT | REMEMBER | CAN_RUN D:0:There is an up staircase here. D:1:You cannot tunnel a stair. # 0x07 --> down stairs (perm) N:7:down staircase G:>:w F:FLOOR | PERMANENT | NOTICE | SUPPORT_LIGHT | REMEMBER | CAN_RUN D:0:There is a down staircase here. D:1:You cannot tunnel a stair. N:8:quest entrance G:>:y F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN D:1:You cannot tunnel a quest entrance. N:9:quest exit G:<:y F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN D:1:You cannot tunnel a quest exit. N:10:quest down level G:>:r F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN N:11:quest up level G:<:r F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN N:12:town exit G:>:g F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN N:13:shaft down G:>:U F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN D:0:There is a shaft down here. D:1:You cannot tunnel a shaft. N:14:shaft up G:<:U F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN D:0:There is a shaft up here. D:1:You cannot tunnel a shaft. # 0x0F -> empty fountain N:15:fountain G:_:D F:FLOOR | NOTICE | REMEMBER | CAN_RUN D:0:The fountain seems empty. N:16:web G:+:y F:CAN_PASS | NOTICE | WEB | NOTICE | TUNNELABLE D:1:You tunnel through the web. D:2:a web blocking your way # Trap -- the flags are not used by the program N:17:trap G:^:w F:FLOOR | NOTICE | REMEMBER # 0x12 --> 0x1F -- UNUSED # 0x2x --> locked door (power 0) N:32:door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> locked door (power 1) N:33:locked door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> locked door (power 2) N:34:locked door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> locked door (power 3) N:35:locked door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> locked door (power 4) N:36:locked door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> locked door (power 5) N:37:locked door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> locked door (power 6) N:38:locked door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> locked door (power 7) N:39:locked door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | REMEMBER | DOOR F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 0) N:40:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 1) N:41:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 2) N:42:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 3) N:43:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 4) N:44:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 5) N:45:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 6) N:46:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x2x --> jammed door (power 7) N:47:jammed door G:+:U M:32 F:WALL | NO_WALK | CAN_PASS | NO_VISION | REMEMBER | NOTICE F:TUNNELABLE D:1:You bash the boor. # 0x30 --> secret door N:48:secret door G:#:w M:56 F:WALL | NO_WALK | CAN_PASS | NO_VISION | DOOR F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel. # 0x31 --> rubble N:49:pile of rubble G:::w F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE F:CAN_FLY | SUPPORT_LIGHT F:TUNNELABLE D:1:You dig in the rubble. # 0x32 --> magma vein N:50:magma vein G:%:s F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the magma vein. # 0x33 --> quartz vein N:51:quartz vein G:%:w F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the quartz vein. # 0x34 --> magma vein + treasure N:52:magma vein G:%:s M:50 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the magma vein. # 0x35 --> quartz vein + treasure N:53:quartz vein G:%:w M:51 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the quartz vein. # 0x36 --> magma vein + known treasure N:54:magma vein with treasure G:*:o F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the magma vein. # 0x37 --> quartz vein + known treasure N:55:quartz vein with treasure G:*:o F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the quartz vein. # 0x38 --> granite wall -- basic N:56:granite wall G:#:w F:WALL | NO_WALK | CAN_PASS | NO_VISION | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the granite wall. # 0x39 --> granite wall -- inner N:57:granite wall G:#:w M:56 F:WALL | NO_WALK | CAN_PASS | NO_VISION | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the granite wall. # 0x3A --> granite wall -- outer N:58:granite wall G:#:w M:56 F:WALL | NO_WALK | CAN_PASS | NO_VISION | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the granite wall. # 0x3B --> granite wall -- solid N:59:granite wall G:#:w M:56 F:WALL | NO_WALK | CAN_PASS | NO_VISION | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the granite wall. # 0x3C --> permanent wall -- basic (perm) N:60:permanent wall G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING # 0x3D --> permanent wall -- inner (perm) N:61:permanent wall G:#:w M:60 F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING # 0x3E --> permanent wall -- outer (perm) N:62:permanent wall G:#:w M:60 F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING # 0x3F --> permanent wall -- solid (perm) N:63:permanent wall G:#:w M:60 F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING N:64:explosive rune G:*:R F:FLOOR | CAN_LEVITATE | CAN_FLY | NOTICE | SUPPORT_LIGHT D:0:This rune seems unstable. N:65:Straight Road startpoint G:*:w F:FLOOR | REMEMBER | NOTICE N:66:section of the Straight Road G:*:B F:FLOOR | REMEMBER | NOTICE N:67:section of the Straight Road G:*:b F:FLOOR | REMEMBER | NOTICE N:68:section of the Straight Road G:*:B F:FLOOR | REMEMBER | NOTICE N:69:section of the Straight Road G:*:b F:FLOOR | REMEMBER | NOTICE N:70:section of the Straight Road G:*:W F:FLOOR | REMEMBER | NOTICE N:71:section of the Straight Road (discharged) G:*:W F:FLOOR | REMEMBER | NOTICE N:72:Straight Road exit G:*:w F:FLOOR | REMEMBER | NOTICE N:73:corrupted section of the Straight Road G:*:D F:FLOOR | REMEMBER | NOTICE # 74 --> shop N:74:Building G:1:U F:FLOOR | PERMANENT | REMEMBER | NOTICE | CAN_RUN # 75 --> 78 Quests index N:75:permanent wall G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING N:76:permanent wall G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING N:77:permanent wall G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING N:78:permanent wall G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING # 79 --> 83 UNSUSED N:84:stream of shallow water G:~:B S:B:B:B:B:B:B:b F:ATTR_MULTI F:FLOOR | CAN_LEVITATE | CAN_FLY | REMEMBER | SUPPORT_LIGHT | CAN_RUN F:DONT_NOTICE_RUNNING F:SUPPORT_GROWTH # -1 = player level N:85:pool of deep lava G:.:R E:-1d2:1:FIRE F:FLOOR | CAN_LEVITATE | CAN_FLY | REMEMBER | SUPPORT_LIGHT D:0:You move across the deep lava. N:86:stream of shallow lava G:.:r E:-1d1:1:FIRE F:FLOOR | CAN_LEVITATE | CAN_FLY | REMEMBER | SUPPORT_LIGHT D:0:You move across the shallow lava. N:87:dark pit G:#:D F:CAN_LEVITATE | CAN_FLY F:NO_WALK | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING D:0:Ohhh, it is dark and deep. N:88:dirt G:.:U F:FLOOR | SUPPORT_LIGHT | CAN_RUN F:DONT_NOTICE_RUNNING F:SUPPORT_GROWTH N:89:patch of grass G:.:G F:FLOOR | SUPPORT_LIGHT | CAN_RUN F:DONT_NOTICE_RUNNING F:SUPPORT_GROWTH N:90:ice G:.:W E:1d1:50:ICE F:FLOOR | NOTICE N:91:sand G:.:y F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN F:SUPPORT_GROWTH N:92:dead tree G:#:D F:CAN_FLY | CAN_PASS F:WALL | NO_WALK | NO_VISION | NOTICE F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You chop away at the dead tree. D:2:a tree blocking your way N:93:ash G:.:s F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN F:SUPPORT_GROWTH N:94:mud G:.:u F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN F:SUPPORT_GROWTH N:95:ice wall G:#:W F:WALL | NO_WALK | CAN_PASS | NO_VISION | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the ice wall... #BOh chilly#w. D:2:an ice wall blocking your way N:96:tree G:#:G F:CAN_FLY | CAN_PASS | SUPPORT_LIGHT F:WALL | NO_WALK | NO_VISION F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You chop away at the tree. D:2:a tree blocking your way N:97:mountain chain G:^:U F:CAN_CLIMB | CAN_PASS | SUPPORT_LIGHT F:WALL | NO_WALK | NO_VISION F:DONT_NOTICE_RUNNING F:PERMANENT D:1:You cannot tunnel into such a hard stone. D:2:a hard stone block blocking your way # 0x62 --> sandwall N:98:sandwall G:#:y F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You easily dig into the sandwall. D:2:a sandwall blocking your way # 0x63 --> sandwall + treasure N:99:sandwall G:%:y M:98 F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You easily dig into the sandwall. D:2:a sandwall blocking your way # 0x64 --> sandwall + known treasure N:100:sandwall with treasure G:*:o F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You easily tunnel into the sandwall. D:2:a sandwall blocking your way N:101:high mountain chain G:^:W F:WALL | NO_WALK | NO_VISION | PERMANENT F:DONT_NOTICE_RUNNING D:1:This rock is far too hard. D:2:a very hard stone block blocking your way N:102:nether mist G:.:v S:v:R:r:v:R:r:D E:1d1:40:NETHER F:ATTR_MULTI F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN N:160:Void Jumpgate G:+:v F:FLOOR | REMEMBER | NOTICE | PERMANENT | CAN_RUN D:0:A dark rift opens to the void here. ###### Here are the altars. ###### N:161:Altar of Being G:0:W F:FLOOR | REMEMBER | NOTICE | CAN_RUN D:0:You feel at peace. N:162:Altar of Winds G:0:B F:FLOOR | REMEMBER | NOTICE | CAN_RUN D:0:You grow a desire to become a bird. N:163:Altar of Force G:0:R F:FLOOR | REMEMBER | NOTICE | CAN_RUN D:0:You grow a desire to fight evil. N:164:Altar of Darkness G:0:D F:FLOOR | REMEMBER | NOTICE | CAN_RUN D:0:Images of pain and death fill your mind. N:165:Altar of Nature G:0:g F:FLOOR | REMEMBER | NOTICE | CAN_RUN D:0:You feel the desire to walk in a great forest. # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # Used as a marker for random quests N:172:open floor G:.:w F:FLOOR | CAN_RUN | DONT_NOTICE_RUNNING F:SUPPORT_GROWTH # Underground Tunnel N:173:Underground Tunnel G:#:s F:FLOOR | REMEMBER | SUPPORT_LIGHT | DONT_NOTICE_RUNNING | CAN_RUN D:0:Oh, an underground tunnel! # Tainted water N:174:stream of tainted water G:~:u F:FLOOR | CAN_LEVITATE | CAN_FLY | REMEMBER | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING N:175:monster trap G:;:v F:FLOOR N:176:Void Jumpgate G:+:v F:FLOOR | REMEMBER | NOTICE | PERMANENT | CAN_RUN D:0:A dark rift opens to the void here. N:177:lava wall G:#:R S:R:R:r:r:U:u:R F:ATTR_MULTI F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING D:1:The lava is far too hot to tunnel into it. D:2:a lava wall blocking your way N:178:Great Fire G:%:v S:R:R:y:v:y:v:R E:150d2:1:HELL_FIRE F:ATTR_MULTI F:FLOOR | REMEMBER | NOTICE | PERMANENT D:0:This fire is so powerful it could destroy even the most powerful artifacts. N:179:path to the next area G:>:w F:FLOOR | PERMANENT | NOTICE | REMEMBER | CAN_RUN D:0:There is a path leading to the next area here. D:1:You cannot tunnel a path. N:180:path to the previous area G:<:w F:FLOOR | PERMANENT | NOTICE | REMEMBER | CAN_RUN D:0:There is a path leading to the previous area here. D:1:You cannot tunnel a path. N:181:field G:::g F:FLOOR | PERMANENT | NOTICE | REMEMBER F:DONT_NOTICE_RUNNING D:1:You cannot tunnel a field. N:182:Ekkaia, the Encircling Sea G:*:b S:b:b:b:b:b:b:B F:ATTR_MULTI F:WALL | NO_WALK | NO_VISION | PERMANENT | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING N:183:void G: :d F:FLOOR # XXX 182 - 186 # 187 --> terrain -- deep water N:187:pool of deep water G:~:b S:b:b:b:b:b:b:B F:ATTR_MULTI F:FLOOR | CAN_LEVITATE | CAN_FLY | REMEMBER | SUPPORT_LIGHT # Glass wall -- can see but not pass N:188:glass wall G:.:B F:NO_WALK | WALL | PERMANENT | NOTICE F:DONT_NOTICE_RUNNING D:1:This glass seems to be totaly impenetrable. D:2:a glass wall blocking your way # Illusion wall -- can't see but can pass N:189:illusion wall G:#:w F:FLOOR | NO_VISION | REMEMBER | SUPPORT_LIGHT | DONT_NOTICE_RUNNING D:0:Looks like this wall is not so real. # Grass roof N:190:Grass roof G:#:y F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # grass roof top N:191:grass roof top G:#:y F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # grass roof chimney N:192:grass roof chimney G:#:y F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # brick roof N:193:brick roof G:#:r F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # brick roof top N:194:brick roof top G:#:r F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # brick roof chimney N:195:brick roof chimney G:#:r F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # window N:196:window G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # small window N:197:small window G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # rain barrel N:198:rain barrel G:#:w F:WALL | NO_WALK | NO_VISION | PERMANENT | DONT_NOTICE_RUNNING # grass with flowers N:199:grass with flowers G:;:G F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN F:SUPPORT_GROWTH # cobblestone road N:200:cobblestone road G:.:w F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN # cobblestone with outlet N:201:cobblestone with outlet G:.:w F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN N:202:small tree G:#:g F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN | SUPPORT_LIGHT | REMEMBER F:NO_VISION # Just to have a town entrance picture N:203:town G:*:w F:FLOOR | NOTICE # Underground Tunnel N:204:Underground Tunnel G:^:U F:FLOOR | REMEMBER | SUPPORT_LIGHT | DONT_NOTICE_RUNNING | CAN_RUN D:0:Oh, an underground tunnel! # Fire N:205:a blazing fire G:%:y S:y:y:y:R:r:y:R E:-1d2:1:FIRE D:0:The blazing fire burns you! F:ATTR_MULTI F:FLOOR | CAN_FLY | REMEMBER | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING # Permanent rubble -- town use N:206:pile of rubble G:::w F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE F:CAN_FLY | SUPPORT_LIGHT | PERMANENT D:1:Looks like this pile of rubble is quite hard. # Rocky ground - rougher terrain. N:207:rocky ground G:.:s F:FLOOR | SUPPORT_LIGHT | CAN_RUN F:DONT_NOTICE_RUNNING # cloud-like vapour. Floor for Eru's temple N:208:cloud-like vapour G:.:W S:W:B:B:W:w:W:B F:FLOOR | CAN_LEVITATE | CAN_FLY | SUPPORT_LIGHT F:ATTR_MULTI | CAN_RUN | DONT_NOTICE_RUNNING # condensing water N:209:condensing water G:~:B S:B:B:B:B:B:B:b F:ATTR_MULTI F:FLOOR | CAN_LEVITATE | CAN_FLY | REMEMBER | SUPPORT_LIGHT | CAN_RUN F:DONT_NOTICE_RUNNING # Dense mist. Can pass through, but not see through N:210:dense mist G:#:w S:w:W:s:s:s:w:w F:FLOOR | NO_VISION | REMEMBER | SUPPORT_LIGHT F:ATTR_MULTI | DONT_NOTICE_RUNNING D:0:You wander through the mist. D:1:You cannot tunnel through mist! # Hail-stone wall N:211:hail-stone wall G:#:W F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING F:TUNNELABLE D:1:You tunnel into the hail-stone wall. N:212:dead small tree G:#:D F:FLOOR | DONT_NOTICE_RUNNING | CAN_RUN | SUPPORT_LIGHT | REMEMBER F:NO_VISION # New features for the Maps of Lord Dimwit N:213:copper pillar G:#:u S:u:u:u:o:u:u:u F:WALL | NO_WALK | CAN_PASS | NO_VISION | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING | ATTR_MULTI D:1:The copper is too tough to tunnel through. D:2:a copper pillar blocking your way N:214:ethereal wall G:.:w F:WALL | NO_WALK | PERMANENT | NOTICE | DONT_NOTICE_RUNNING D:1:You can't even see your obstruction! D:2:an unseen force blocking your way N:215:glacial wall G:#:B F:WALL | NO_WALK | CAN_PASS | NO_VISION | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING | TUNNELABLE D:1:You tunnel into the glacial wall... #BOh chilly#w. D:2:a hard glacial wall blocking your way N:216:battlement G:#:w F:NO_WALK | CAN_PASS | NOTICE | SUPPORT_LIGHT F:DONT_NOTICE_RUNNING | TUNNELABLE D:1:You tunnel into the battlement. D:2:a hard stone battlement blocking your way tome-235-src/lib/edit/t_khazad.txt0000644000076400017500000003315011012107760014706 0ustar dgdg# Town Name: Khazad-Dum # by fearoffours (fearoffours@moppy.co.uk) # # Created for ToME F:o:207:3 ###################### Buildings ######################## # Fighters Hall F:f:74:3:0:0:0:0:0:17 # Paladins Guild F:g:74:3:0:0:0:0:0:20 # Inner Temple F:h:74:3:0:0:0:0:0:19 # Mining Supplies F:i:74:3:0:0:0:0:0:59 # Default for Quest 25 = entrance is quest entrance F:w:8:3:0:0:0:0:0:25 # Force dwarven monsters f:DWARVEN ############### Quest 25 - Evil cave finished = house ############### ?:[EQU $QUEST25 2] F:w:74:3:0:0:0:0:0:7 ?:[EQU $QUEST25 5] F:w:74:3:0:0:0:0:0:7 ?:1 # Town Layout D:###################################################################################################################################################################################################### D:#ooooooooooooo####^^^^^^^^^#######^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#####oooo#######oo######^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^##########oooooooooo CCCCCCC # D:#ooo##ooooooooo#####^^^^^##########^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^########ooo########ooo##########^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^################oooooooooooo CCCCCCCC # D:##oo###oo####oo##############################^^^^^^^^^^^^^^^^^########################oooo#########oo#### ###########^^^^^^^^^^^^^^^^^^^^^^^^####### #######oooo########## CCCCCCCC # D:##############o#########oo###oo###################^^^^^^^############################oooo#########oo###### ################################# #####ooooooooo############# CCCCCCCC ; # D:#^^^^########oooooooooooooo##ooooooooo############################# #################oooo########oo########### ########################## ######ooooooooo################ CCCCCCCC ; # D:#############ooooooooooooooooooooooooooo###### ###########1###### ##############2####oooo#######o##o##3####f##### ##g####4####h###### ###########ooo######################## CCCCCCCC ; # D:#^#############ooooo##################oo### # #### # ##### #### ############### ###ooo########ooo## ## ###### # ## ## ## # #######ooooo########################### CCCCCCCC # D:#^^################oo#################ooooo#### ## ; ;; o ; o ## # ooooooooo############################ CCCCCCCC # D:#^^^^################o##########o#####oooooooooooooooooooooo o o ; oooooooooooooooooooooooo##ooo############################ CCCCCCC # D:#^^^^^^################################# ## ; o ; ; o o ; o ##o################################### CCCCCCC# D:#^^^^^^################################ ### o ### o ### o ###; o ### ######################################## CCCCCC# D:#^^^^^################################# ##### o ##### o ##### o ##### o ##### ######################################## CCCCCC# D:#^^^^^^^################################ #######;; o ####### o ####### o ####### o ####### ####################################### ; CCCCCC# D:#^^^^^^^^################################ # ####### o ; ####### o ####### o ####### o ####### ######################################## CCCCCC # D:#^^^^^^^################################### ##### o ; ;##### o ##### o ##### ; o ##### ;####################################### CCCCCCC # D:#^^^^^^^^^################################ ### o ### o ### o ### o ### # #################################### CCCCCC ; # D:#^^^^^^^^^################################# o o o o ## ################################## CCCCCC # D:#^^^^^^^^^^################################ ; oooooooooooo o o oooooooooooo 5################################ CCCCCC ; # D:#^^^^^^^^^^^^^########################### o o o o ################################# CCCCCCC # D:#^^^^^^^^^^^^^^^########################## ### o ### o o ;### o ### ################################ CCCCCCC ; # D:#^^^^^^^^^^^^############################# ##### ; o ##### o o ##### o ##### ; ###############################; CCCCCCC ; # D:#^^^^^^^^^############################### ; ####### o ####### o ; o ####### o ####### ############################ CCCCCCC # D:#^######################################### ; ####### oooooooo ####### o o ####### oooooo ####### o ; ##############################; CCCCCCC # D:#################ooo###################### ; ##### o ##### o o ##### o ##### ###############oo############## CCCCC; # D:####oo##ooo#####o#######o###ooo########### ### ; o ### o o ### o ; ### ; ;; #########oo###oooooo#####oo###### CCCCC ; # D:#ooooooooooooooooooooooooooooooo##oooooooo ; o ; o o o ; ;; ; oooooooooooo##oooooooo##oooooooooo CCCCC ; # D:#ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo CCCCCC # D:#oooooooooooooooooo##oooooo##oooooo##ooooo ; o o ; ooooooooo#oooooooooooooooooooooooo CCCCC # D:#^#######################oo####ooooo####### ### ### o o ###; ### ######o####oo####oo######oo######; CCCCC # D:#^^#######################o########### ##### ##### o o ##### ##### ######o####################oo#### CCCCC # D:#^####################################### #######;; ; ####### o o ####### ####### ####oo######################### CCCCCC # D:#^^######################################## ####### ; ####### o o ####### ####### ######o############oo########## CCCCCCC # D:#^^^###############ooo################### ##### ; ;##### o o ##### ; ##### ;; ######oo########ooooo####### CCCCCCCC # D:#####oo##oo#####oooooooo##############oo## ### ; ### o o ### ### ########oooo##oooooo####### CCCCCCCCC ; # D:#ooooooooooo###ooooooooooooooooooooooooooo o o ooooooooooooooooooooooooooo CCCCCCCC # D:#oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo CCCCCCCC ; # D:#^ooooooooooooooooo###oooooooooo##oooooooo o o o o ooooooo####ooooooooooooo CCCCCCCC # D:#^^#o###ooo#####ooo#####ooooo########oo# ### ; o ### o o ;### o ### oo#########ooooo###oo# CCCCCCCC ; # D:#^^^^^###o################oo############# ##### ; o ##### o o ##### o ##### ; ###########oo######## CCCCCCCC ; # D:#^^^^^^^################################## ; ####### ooooooo ####### o ; o ####### ooooo ####### ######################## CCCCCCCCC # D:#^^^^^^^^^^############################## ; ####### o ; ####### o o ####### o ####### o ; ########################## CCCCCCCC # D:#^^^^^^^^^^^^^^^######################### ; ##### o ##### o o ##### o ##### ############################ CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^^################### ### ; o ### o o ### o ; ### ; ;; ############################ CCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^#################### ; o ;; o ; o o ; ############################ CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^###################### ooooooooooo o o oooooooooooo ;; ; 7########################### CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^^^^^################# ; o ; ; o o ; o ############################# CCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^############## ### o ### o ### o ###; o ### ############################# CCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^############ ##### o ##### o ##### o ##### o ##### ######################## CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^^########## #######;; ; o ####### o ####### o ####### o ####### ########################### CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^^#########i ####### o ; ####### o ####### o ####### o ####### ############################ CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^########### ##### o ; ;##### o ##### o ##### ; o ##### ; ############################## CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^############## ### ; o ### o ### o ### o ### ############################## CCCCCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^^^^^################# o o o o #########oo###oo################# CCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^#############o#######oooooooooooooooooooooo ## o o oooooooooooooooooooooooooooooooooooo################## CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^############ooooooooooo# ### ## ######## o o ## o ## ## oooooo##oooooooooo################### CCCCCCC # D:#^^^^^^^^^^^#################ooooooooooo#### ###### ### #### ############# ####oooo###### #ooo# ### ###### # ### ## ##### ####################ooo##################### CCCCCCC # D:#^^^^^^^^^^###################oo######oo### ########### #######9####################oooo########oooo############w### ######## ###### ####################oo###################### CCCCCCC # D:#^^^^^^^##########oo####oo####ooo######### ############# ##############^^^##########ooooo########oo###################################### #########^######oooo##ooo################## CCCCCCC # D:##^^^^^#########oooooooooooooooo#################^^####### ###########^^^^^###########ooooo######ooo####################################### #####^^^#######ooooooooooooo############# ; CCCCCCC# D:#^^^##########ooooooooooo##ooooo######^#########^^^^##################^^^^^^^^^^^######ooo#######oooo#########^^^^^^^^^^^^^^^^^^^########### #####^^^#######oo##oooooooo############# CCCCCC# D:##############ooooo##########oo######^^^#####^^^^^^^^###############^^^^^^^^^^^^^^#####oooo#######ooo######^^^^^^^^^^^^^^^^^^^^^^^^^^^^###### ####^^^^^###############ooo############## CCCCC# D:########ooo#####oo##################^^^^^^^^^^^^^^^^^#############^^^^^^^^^^^^^^^^^####oo########oooo#####^^^^^^^^^^^^^^^^^^^^^^^^^^^########### #######^^^^^#############ooo#ooo######## CCCCCC# D:#o##oooooooooooooooo##############^^^^^^^^^^^^^^^^^^^^^^#########^^^^^^^^^^^^^^^^^^#####oo########oo######^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^####### # ######^^^^^^^^^^^^########oooooooooooooo CCCCC # D:#oooooooooooooooooo########^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^########oooo#######ooooo###^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^##############^^^^^^^^^^^^^^^#######ooooooooooo CCCCC # D:###################################################################################################################################################################################################### # Default starting position # ?:[EQU $LEAVING_QUES 0] # P:31:32 tome-235-src/lib/edit/spiders.map0000644000076400017500000000472011012107760014531 0ustar dgdg# Lit permanent wall F:X:61:6 # up staircase F:<:6:8 # Grass F:-:89:3 # Trees F:t:96:3 # Grass with Giant spider F:a:89:3:175 # Grass with Giant tarantula F:b:89:3:275 # Grass with Mirkwood Spider F:c:89:3:277 # Grass with Aranea F:d:89:3:963 # Grass with Elder aranea F:e:89:3:964 # Dungeon layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X<---tttttttttttttttttttttttttttttttttttttttttttttttttttttttX D:X---ttttttttttttttttttttttttttta--ctttttttttttttttttttttttttX D:Xtt---------------ttttttttttttt--tttttttttttttttttttttttttttX D:Xttttttttt--------------cttttttt--ttttttttttttttttttttttttttX D:Xtttttttttttttt--tttttt---------c--tttttttttttttttttttttttttX D:Xttttttttttttta-bttt---cttttttttttttttttttttttttttttttttttttX D:Xttttttttttttttttttttt---tttt-ttd--c-ttt---c---tttttttttttttX D:Xtttttttttttttttttttc---btttttttt-----ttc-----ttttttttttttttX D:Xtttttttttttttttttt----tttttttttc-c---------d---c-ctttttttttX D:Xtttttttttttttttttb-tttt---c---t----tttttt----------ctttttttX D:Xtttttttttttttttttt----ttttt-----c---tttttt-c--cttttttttttttX D:Xttttttttttttttttc--at----c---ttttttttttttttttttttttttttttttX D:Xttttttttttttta----ttttt-b--tttttttttd--etttttttttttttttttttX D:Xtttttttttttt---c--ttttt------tttt-c-tttttttte----dtttttttttX D:Xttttttttttttttttttt----c--d----tttt---ttttttt--d----ettttttX D:Xttttttttttttttttttttt-c-d---tttttttc--cttttttt-----ttttttttX D:Xttttttttttta-c--ttt-------tttt-------ttttt----d--ttttttttttX D:Xtttttttttttt----ttttt--ttt--c--c--t-----c--ttttttttttttttttX D:Xttttttttttt--c---ttt--c--c---ttttt--c----t----tttttttttttttX D:Xtttttttttt-c----c---t-----tttttttt-----ttt-------dtttttttttX D:Xttttttttttt---c---tttt--c--ttttttttt-ttttttttt-d---ttttttttX D:Xtttttttttttta-----tttttt---d---dttd----cttttt-----tttttttttX D:Xtttttttttttttttttttt---c-----ttttt---c----ettd--tttttttttttX D:Xtttttttttttttttt----d----tttttttttttttttttttttt---tttttttttX D:Xttttttt-------c---tttt-d----c--ettttttttttttd-----dttttttttX D:Xtttttc--c-c------tttttt-------------ettttttt----tttttttttttX D:Xttttttt------ttttttt--c---d---ttttttttttttt--d--tttttttttttX D:Xttttt----cc-tttttttttttte----d-ttttttttttttttt----tttttttttX D:Xttttt--c------ttttttttttttttttttttttttttte--tt------ettttttX D:Xttt--c----ctttttttttttttttttttttttttte------------tttttttttX D:Xtttttttttttttttttttttttttttttttttttttttttt--e--ttttttttttttX D:XtttttttttttttttttttttttttttttttttttttttttttttttttttttttttttX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Starting position P:3:3 tome-235-src/lib/edit/v_info.txt0000644000076400017500000023143511012107760014407 0ustar dgdg# File: v_info.txt # This file is used to initialize the "lib/raw/v_info.raw" file, which is # used to initialize the "vault template" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/raw/v_info.raw" file. # Note that the "spacing" in the "description" lines is very important! # New vault types added for Zangband -TY # Quest vaults added - rr9 # Version stamp (required) V:2.0.0 ### Simple Vaults (type 7) -- maximum size 44x22 ### N:0:Lesser vault (round) X:7:5:12:20 D: %%%%%% D: %%%..##..%%% D: %%....####....%% D: %......#**#......% D:%...,.##+##+##.,...% D:%.,.,.#*#*&#*#.,.,.% D:%.,.,.#*#&*#*#.,.,.% D:%...,.##+##+##.,...% D: %......#**#......% D: %%....####....%% D: %%%..##..%%% D: %%%%%% N:1:Lesser vault (octagon) X:7:5:14:20 D: %%%%%%%%%%%%%% D: %%.##########.%% D: %%..#..,,,,..#..%% D:%%,..#.,####,.#..,%% D:%....#.,#**#,.#....% D:%.###+,##&&##,+###.% D:%.#..,,#*&**#,,..#.% D:%.#..,,#**&*#,,..#.% D:%.###+,##&&##,+###.% D:%....#.,#**#,.#....% D:%%,..#.,####,.#..,%% D: %%..#..,,,,..#..%% D: %%.##########.%% D: %%%%%%%%%%%%%% N:2:Lesser vault (octagon) X:7:5:12:20 D: %%%%%%%%%%%% D: %%%%..........%%%% D: %...###+##+###...% D:%%...#,,#,,#,,#...%% D:%.###+##+##+##+###.% D:%.#,,#&&#**#&&#,,#.% D:%.#,,#&&#**#&&#,,#.% D:%.###+##+##+##+###.% D:%%...#,,#,,#,,#...%% D: %...###+##+###...% D: %%%%..........%%%% D: %%%%%%%%%%%% N:3:Lesser vault (square) X:7:5:12:20 D:%%%%%%%%%%%%%%%%%%%% D:%*.......&........*% D:%.################.% D:%.#,.,.,.,.,.,.,.#.% D:%.#.############,#.% D:%.#,+,&&+**#&*,#.#&% D:%&#.#,*&#**+&&,+,#.% D:%.#,############.#.% D:%.#.,.,.,.,.,.,.,#.% D:%.################.% D:%*........&.......*% D:%%%%%%%%%%%%%%%%%%%% N:4:Lesser vault (diagonal) X:7:5:12:20 D:%%%%%%%%%%%%%%%%% D:%,,,##,,,,##....%% D:%,,,,##,,,,##....%% D:%#,,,,##,,,,##....%% D:%##,,,,##,,,,##....% D:%.##,,,,,,,,,,#+...% D:%..#+,,,,,,,,,,##..% D:%...##,,,,##,,,,##.% D:%%...##,,,,##,,,,##% D: %%...##,,,,##,,,,#% D: %%...##,,,,##,,,,% D: %%%%%%%%%%%%%%%%% N:5:Lesser vault (diagonal) X:7:5:12:20 D: %%%%%%%%%%%%%%%%% D: %%....##,,,,##,,,% D: %%....##,,,,##,,,,% D:%%....##,,,,##,,,,#% D:%....##,,,,##,,,,##% D:%...+#,,,,,,,,,,##.% D:%..##,,,,,,,,,,+#..% D:%.##,,,,##,,,,##...% D:%##,,,,##,,,,##...%% D:%#,,,,##,,,,##...%% D:%,,,,##,,,,##...%% D:%%%%%%%%%%%%%%%%% N:6:Lesser vault (square) X:7:5:12:20 D:%%%%%%%%%%%%%%%%%%%% D:%,################,% D:%^#.*...&..,....,#^% D:%^#...,......&...#^% D:%^#######++#######^% D:%^+.,..&+,*+*....+^% D:%^+..*.,+.&+.,.&.+^% D:%^#######++#######^% D:%^#....,.,.....,.#^% D:%^#..&......*....#^% D:%,################,% D:%%%%%%%%%%%%%%%%%%%% N:7:Lesser vault (spiral) X:7:5:19:21 D:%%%%%%%%%%%%%%%%%%%%% D:%...................% D:%.+################.% D:%.#^#*&..,.......*#.% D:%.#.#.###########.#.% D:%.#.#.#*.,.....*#.#.% D:%.#.#.#.#######.#.#.% D:%.#.#.#.#,...*#.#.#.% D:%.#.#.#.#,###.#.#.#.% D:%.#,#,#,#,,*#,#,#,#.% D:%.#.#.#.###,#.#.#.#.% D:%.#.#.#*.,.*#.#.#.#.% D:%.#.#.#######.#.#.#.% D:%.#.#*...,...*#.#.#.% D:%.#.###########.#.#.% D:%.#*.....,....&*#^#.% D:%.################+.% D:%...................% D:%%%%%%%%%%%%%%%%%%%%% N:8:Lesser vault (layers) X:7:5:21:21 D:%%%%%%%%%%%%%%%%%%%%% D:%...................% D:%.########+########.% D:%.#.......,.......#.% D:%.#.#############.#.% D:%.#.#....+.#*...#.#.% D:%.#.#.####+####.#.#.% D:%.#.#.#...&...#.#.#.% D:%.#.#.#.#####.#.#.#.% D:%.#.#.#.#*,*#.#.#.#.% D:%.#^#^#^#,,,#^#^#.#.% D:%.#.#.#.#*,*#.#.#.#.% D:%.#.#.#.##+##.#.#.#.% D:%.#.#.#..+,#*.#.#.#.% D:%.#.#.#########.#.#.% D:%.#.#.....,.....#.#.% D:%.#.######+######.#.% D:%.#.....*#.+......#.% D:%.#################.% D:%...................% D:%%%%%%%%%%%%%%%%%%%%% N:9:Lesser vault (bank) X:7:7:9:21 D:%%%%%%%%%%%%%%%%%%%%% D:%...................% D:%.&XXXXXXXXXXXXXXXXX% D:%&&XXXXX+XXX+XX*,XXX% D:%&&+###########,*XXX% D:%.&XXX+XXX+XXX+XXXXX% D:%.&XXXXXXXXXXXXXXXXX% D:%...................% D:%%%%%%%%%%%%%%%%%%%%% N:10:Lesser vault (mine) X:7:7:9:21 D:%%%%%%%%%%%%%%%%%%%%% D:%...................% D:%.XXXXXXXXXXXXXXXXXX% D:%.XX##XXXX*,,XX,*,XX% D:%.*#XX,*##X*#XX***XX% D:%.XXXX*,XXXXX##,*,XX% D:%.XXXXXXXXXXXXXXXXXX% D:%...................% D:%%%%%%%%%%%%%%%%%%%%% N:11:Lesser vault (maze) X:7:5:22:22 D:%%%%%%%%%%%%%%%%%%%%%% D:%.XXXXXXX............% D:%.XX,,.XXXXXXXXXXXXX.% D:%.XXXX*...&........X.% D:%.X.,,XXXXXXXXXXXX*X.% D:%.X.XXX.....*......X.% D:%.X..XX.XXXXXXXXXX.X.% D:%.XX.X.&.XX.X.....*X.% D:%.XX.XXX...*X,XXXX.^.% D:%.X.XX,XXXX.XXXX,XXX.% D:%.X.XX.....*..&.*X,X.% D:%.X.,XXXXXXXXXXX.X,X.% D:%.XXXX....*..X,X.X,X.% D:%.X....XXX.X.X.X.X.X.% D:%.X.XXXX,X.X.&.X.X.X.% D:%.X.X...*X.XXXXX.X.X.% D:%.X.X,XX&X....&..X.X.% D:%.X.XXXX.XXXXXXXXX.X.% D:%.X.....*...X*X*X..X.% D:%.XX^XXXXXX..X*X,XXX.% D:%........XXXXXXXXXXX.% D:%%%%%%%%%%%%%%%%%%%%%% N:12:Lesser vault (prison) X:7:10:16:35 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.+..&..+..&..+..&..+..&..+..&..+.% D:%.###.#####.#####.#####.#####.###.% D:% #,+.+,#,+.+,#,+.+,#,+.+,#,+.+,#.% D:%.###.#####.#####.#####.#####.###.% D:%.#,+.+,#,+.+,#,+.+,#,+.+,#,+.+,#.% D:%.###.#####.#####.#####.#####.###.% D:%.#,+.+,#,+.+,#,+.+,#,+.+,#,+.+,#.% D:%.###.#####.#####.#####.#####.###.% D:%.#,+.+,#,+.+,#,+.+,#,+.+,#,+.+,#.% D:%.###.#####.#####.#####.#####.###.% D:%.#,+.+,#,+.+,#,+.+,#,+.+,#,+.+,#.% D:%.###.#####.#####.#####.#####.###.% D:%&+..&..+..&..+..&..+..&..+..&..+.% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:13:Lesser vault (camp) X:7:10:15:37 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%...................................% D:%.####^^^^^^^^^^^^^^^^^^^^^^^^^####.% D:%.#,&############+++############&,#.% D:%.###+.........................+###.% D:%.^#....##+#.....#+#....##+#....#^..% D:%.^+....#,,#.....#,#....#,,#....+^..% D:%.^+....+&&+..&..+&+..&.+&&+....+^..% D:%.^+....#,,#.....#,#....#,,#....+^..% D:%.^#....#+##.....#+#....#+##....#^..% D:%.###+.........................+###.% D:%.#,&############+++############&,#.% D:%.####^^^^^^^^^^^^^^^^^^^^^^^^^####.% D:%...................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:14:Lesser vault (serpent) X:7:10:17:32 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%..............................% D:%..##########################..% D:%.##...#.^.#.^.#...#...#.,.###.% D:%.#..#.*.#...#...#.^.#...#...+.% D:%.#.##########################.% D:%.#..#..#.,.#.^.#.^.#.*.#...##.% D:%.##^#.#..#...#...#...#...#..#.% D:%.#..#.####################..#.% D:%.#,##.&+,,,,,,,,,,,,,,,,,#*##.% D:%.#..##&+,,,,,,,,,,,,,,,,,#..#.% D:%.##^#######################.#.% D:%.#..#...#...#...#...#.^.#...#.% D:%.##...#.^.#.,.#.*.#.^.#...###.% D:%..##########################..% D:%..............................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:15:Lesser vault (zelazny) X:7:5:18:19 D:%%%%%%%%%%%%%%%%%%% D:%.................% D:%.###############.% D:%.+,,,,,,,,,,,,,#.% D:%.###########,,,#.% D:%.#,,,,+..##,,,##.% D:%.#,,,##.##,,,##..% D:%.#,*##.##,,,##...% D:%.#&##.##,,,##.##.% D:%.###.##,,,##.###.% D:%.##.##,,,##.##&#.% D:%...##,,,##.##*,#.% D:%..##,,,##..+,,,#.% D:%.##,,,##########.% D:%.#,,,,,,,,,,,,,+.% D:%.###############.% D:%.................% D:%%%%%%%%%%%%%%%%%%% N:16:Lesser vault (overlap) X:7:5:12:18 D:%%%%%%%%%%%%%%%%%% D:%................% D:%.##########.....% D:%.#,,,^^^^^+&....% D:%.#,,,##########.% D:%.#,,,#****+,,,#.% D:%.#,,,+****#,,,#.% D:%.##########,,,#.% D:%....&+^^^^^,,,#.% D:%.....##########.% D:%................% D:%%%%%%%%%%%%%%%%%% N:17:Lesser vault (celtic) X:7:5:17:21 D:%%%%%%%%%%%%%%%%%%%%% D:%...................% D:%.#####..#+#..#####.% D:%.#&,##.##&##.##,&#.% D:%.#+##..#*^*#..##+#.% D:%.#....###.###....#.% D:%...####..&..####...% D:%.###*##.#+#.##*###.% D:%.+&.^..&+*+&..^.&+.% D:%.###*##.#+#.##*###.% D:%...####..&..####...% D:%.#....###.###....#.% D:%.#+##..#*^*#..##+#.% D:%.#&,##.##&##.##,&#.% D:%.#####..#+#..#####.% D:%...................% D:%%%%%%%%%%%%%%%%%%%%% N:18:Lesser vault (mirror) X:7:5:17:19 D:%%%%%%%%%%%%%%%%%%% D:%.................% D:%.+#############+.% D:%.##&,,,,#,,,,&##.% D:%.#&#,,,###,,,#&#.% D:%.#,,,,,,#,,,,,,#.% D:%.##,,,,,#,,,,,##.% D:%.###,,,^#^,,,###.% D:%.#######+#######.% D:%.###,,,^#^,,,###.% D:%.##,,,,,#,,,,,##.% D:%.#,,,,,,#,,,,,,#.% D:%.#&#,,,###,,,#&#.% D:%.##&,,,,#,,,,&##.% D:%.+#############+.% D:%.................% D:%%%%%%%%%%%%%%%%%%% N:19:Lesser vault (tower) X:7:5:18:15 D:%%%%%%%%%%%%%%% D:%.............% D:%..XXX...XXX..% D:%..X&XXXXX&X..% D:%..XX*****XX..% D:%...XX***XX...% D:%....X#+#X....% D:%....X&&&X....% D:%....X^^^X....% D:%....X#+#X....% D:%....X,,,X....% D:%....X^^^X....% D:%...XX+#+XX...% D:%..XX,&,&,XX..% D:%..X^^^*^^^X..% D:%.##+#####+##.% D:%...&.....&...% D:%%%%%%%%%%%%%%% ### Greater vaults (type 8) -- maximum size 66x44 ### N:20:Greater vault (huge) X:8:20:17:39 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%+########X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#X% D:%X8#########&X% D:%X#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X########X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#X% D:%X8###�#8###&X% D:%X#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X########X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#X% D:%X8#########&X% D:%X#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X########&#&+% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:21:Greater vault (large) X:8:35:18:40 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X,#,#,#,#,#,#,#,#*@@*#,#,#,#,#,#,#,#,X% D:%X+XXXXXXXXXXXXXXXX##XXXXXXXXXXXXXXXX+X% D:%X.,..,.X&.&.,*XX******XX*,.&.&X.,...,#% D:%X..,.^^X....,XX***@@***XX,....X^^..,.#% D:%XXXXXX+X^&.&XX***@##@***XX&.&^X+XXXXXX% D:%X,.&.^^X+XXXX***@#XX#@***XXXX+X^^.,..X% D:%X..,&,.X^^^@X**@#X88X#@**#@^^^X.,..&,X% D:%X.,....X^^^@#**@#X88X#@**X@^^^X.&.,..X% D:%X...,^^X+XXXX***@#XX#@***XXXX+X^^..,.X% D:%XXXXXX+X^&.&XX***@##@***XX&.&^X+XXXXXX% D:%#.,..^^X.....XX***@@***XX,....X^^.,..X% D:%#...,..X&.&.,*XX******XX*,.&.&X..,..,X% D:%X+XXXXXXXXXXXXXXXX##XXXXXXXXXXXXXXXX+X% D:%X,#,#,#,#,#,#,#,#*@@*#,#,#,#,#,#,#,#,X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:22:Greater vault (butterfly) X:8:25:18:40 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X*9..&XX***++^^^^^^^^^^^^++***XX&..*9X% D:%X9..&XX,,,,,XX^^^^^^^^^^XX,,,,,#X&..*X% D:%X..&#X.....,.XX^^^^^^^^XX..&....XX&..X% D:%X.&XX..,.&....XX^^^^^^XX..,...&..XX&.X% D:%X&XX..*...&.^..XX^^^^XX..*....,..,XX&X% D:%XXXX+XXXXXXXXXXXXX++XXXXXXXXXXXXX+XXXX% D:%+....,.,.X&&&&***+99+***&&&&X,.,.,...+% D:%+...,.,.,X&&&&***+99+***&&&&X.,.,....+% D:%XXXX+XXXXXXXXXXXXX++XXXXXXXXXXXXX+XXXX% D:%X&XX..*....&...XX^^^^XX...*...&,..#X&X% D:%X.&XX..&.^....XX^^^^^^XX....&....XX&.X% D:%X..&XX....&..XX^^^^^^^^XX..,..*.XX&..X% D:%X*..&#X,,,,,XX^^^^^^^^^^XX,,,,,XX&..9X% D:%X9*..&XX***++^^^^^^^^^^^^++***XX&..*9X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:23:Greater vault (castle) X:8:35:27:27 D:%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.........................% D:%..XXXXX..XXX+XXX..XXXXX..% D:%..X,,,X..X.,,,.X..X,,,X..% D:%..X,,*XXXX.&&&.XXXX*,,X..% D:%..XXXX+....&&&....+XXXX..% D:%.....X.....,,,.....X.....% D:%.....X..,XXX+XXX,..X.....% D:%.....X.XXX^^^^^XXX.X.....% D:%.&...X.X,,*****,,X.X..&..% D:%....XX.X,XXX+XXX,X.XX....% D:%....X..X,X@@@@@X,X..X....% D:%....X..X,X@999@X,X..X....% D:%....X..X,X@989@X,X..X....% D:%....X..X,X@999@X,X..X....% D:%....X..X,X@@@@@X,X..X....% D:%....XX.X,XXX+XXX,X.XX....% D:%.....X.X,,*****,,X.X.....% D:%.....X.XXX^^^^^XXX.X.....% D:%.....X..,XXX+XXX,..X.....% D:%.....X.....&&&.....X.....% D:%..XXXX+....&&&....+XXXX..% D:%..X,,*XXXX.&&&.XXXX*,,X..% D:%..X,,,X..X.,,,.X..X,,,X..% D:%..XXXXX..XX^^^XX..XXXXX..% D:%.........................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%% N:24:Greater vault (chambers) X:8:25:15:40 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%&+.^..^..^..^..^..^..^..^..^..^..^..+&% D:%+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+% D:%.X.&.^,X&^&^X****+^*^@^X.*.&..X..*.,X.% D:%^X.,.&^+^&^@X^^^^X@^*^*X....*^+.^...X^% D:%.X*..,.XXX+XXXX+XXXX+XXX.&.^..X..&,.X.% D:%^X..^.*X*..^&&@@*X,,,,,XXXX+XXX,....X^% D:%.XX+XXXXXXXXXXXXXX,*8*,X,,,,,,XXX+XXX.% D:%^X*&X.&,*.X,*&^*^X,,,,,X,,,,,,X....,X^% D:%.X&,+....*+,*&^*^XXXXXXXXXX+XXX.,...+.% D:%^X.,X.*.&.X,*&^*^+.,.&.^*.&^&^X.....X^% D:%.X^*X.,..,X,*&^*^X*.^*.,..&&&^X,..,.X.% D:%+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+% D:%&+..^..^..^..^..^..^..^..^..^..^..^.+&% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:25:Greater vault (Sierpinski) X:8:35:28:39 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%..................X..................% D:%.................XXX.................% D:%.................X8X.................% D:%.....&..........XX+XX................% D:%...............XX999XX........&......% D:%......&........X@X9X@X...............% D:%..............XXXX+XXXX..............% D:%.............XX*@*@*@*XX....&........% D:%.............X@X*@*@*X@X.............% D:%............XXXX**@**XXXX............% D:%..........&XX,,,X***X,,,XX&..........% D:%..........XX,X@X,X,X,X@X,XX..........% D:%.........XXXXX+XXXXXXX+XXXXX.........% D:%........XX+,,,,,,,,,,,,,,,+XX........% D:%........X@X,,,,,,,,,,,,,,,X@X........% D:%.......XX+XX,,,,,,,,,,,,,XX+XX.......% D:%......XX,,,XX,,,,,,,,,,,XX,,,XX......% D:%......X,X,X,X,,,,,,,,,,,X,X,X,X......% D:%.....XXXX+XXXX,,,,,,,,,XXXX+XXXX.....% D:%....XX*******XX,,,,,,,XX*******XX....% D:%....X,X*****X,X,,,,,,,X,X*****X,X....% D:%...XXXX*****XXXX,,,,,XXXX*****XXXX...% D:%..XX,,,X***X,,,XX,,,XX,,,X***X,,,XX..% D:%..X,X,X,X*X,X,X,X,,,X,X,X,X*X,X,X,X..% D:%.XXXXXXXX+XXXXXXXXXXXXXXXXX+XXXXXXXX.% D:%.........&.................&.........% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:26:Greater vault (swastika) X:8:25:23:29 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%....^^^^^^^^^^^^^^^^^^^^^..% D:%^^^^^###################^..% D:%^####+..#..............#^..% D:%^#.....####.XXXXXXXXXX.#^..% D:%^#...&.#,&..X,,,@,@,9X.#^..% D:%^#.XXX.####.X,XXXXXXXX.#^..% D:%^#.X9X..&,#.X,X......&.#^^^% D:%^#.X,X.####.X,X.#######+##^% D:%^#.X@X.....^X^X^.........#^% D:%^#.X@XXXXXXX+*+XXXXXXXXX.#^% D:%^#.X,,,,,,,^*X*^,,,,,,,X.#^% D:%^#.XXXXXXXXX+*+XXXXXXX@X.#^% D:%^#.........^X^X^.....X@X.#^% D:%^##+#######.X,X.####.X,X.#^% D:%^^^#.&......X,X.#,&..X9X.#^% D:%..^#.XXXXXXXX,X.####.XXX.#^% D:%..^#.X9,@,@,,,X..&,#.&...#^% D:%..^#.XXXXXXXXXX.####.....#^% D:%..^#..............#..+####^% D:%..^###################^^^^^% D:%..^^^^^^^^^^^^^^^^^^^^^....% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:27:Greater vault (great spiral) X:8:40:39:39 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.....................................% D:%.X+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X@X.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^^+.% D:%.X.X^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X.X.X,..,..,..,..,..,..,..,..,..,.X.% D:%.X.X^X.XXXXXXXXXXXXXXXXXXXXXXXXXXX.X.% D:%.X.X.X.X......&...&...&...&...@..X,X.% D:%.X.X^X,X@XXXXXXXXXXXXXXXXXXXXXXX.X.X.% D:%.X.X.X.X.X&.........8.........&X*X.X.% D:%.X.X^X.X.X.XXXXXXXXXXXXXXXXXXX.X.X,X.% D:%.X.X.X,X.X.X.^.^.^.^.^.^.^.^.X.X.X.X.% D:%.X.X^X.X.X.X^XXXXXXXXXXXXXXX*X.X*X.X.% D:%.X.X.X.X&X.X.X,..,..,..,..,X.X.X.X,X.% D:%.X.X^X,X.X.X^X.XXXXXXXXXXX.X*X.X.X.X.% D:%.X.X.X.X.X.X.X.X..&..&..9X.X.X.X*X.X.% D:%.X.X^X.X&X.X^X,X9XXXXXXX.X,X*X.X.X,X.% D:%.X.X.X,X.X.X.X.X&X@@..&X.X.X.X.X.X.X.% D:%.X.X^X.X.X9X^X.X*X+XXX.X&X.X*X.X*X.X.% D:%.X.X.X.X.X.X.X,X^+8+^X.X.X,X.X.X.X,X.% D:%.X9X^X,X.X.X^X.XXX+X^X.X*X.X*X.X.X.X.% D:%.X.X.X.X&X.X.X.,.,,X.X9X.X.X.X.X*X.X.% D:%.X.X^X.X.X.X^XXXXXXX^X.X*X,X*X9X.X,X.% D:%.X.X.X,X.X.X.^.^.^.^.X.X.X.X.X.X.X.X.% D:%.X.X^X.X.X.XXXXXXXXXXX.X^X.X^X.X*X.X.% D:%.X.X.X.X8X&.....9.....&X.X,X.X.X.X,X.% D:%.X.X^X,X.XXXXXXXXXXXXXXX^X.X^X.X.X.X.% D:%.X.X.X.X..&....8......@..X.X.X.X*X.X.% D:%.X.X^X.XXXXXXXXXXXXXXXXXXX,X^X.X.X,X.% D:%.X.X.X,..,..,..,..,..,..,..X.X.X.X.X.% D:%.X.X^XXXXXXXXXXXXXXXXXXXXXXX^X.X*X.X.% D:%.X.X.*.^.*.*.*.*.*.*.*.*.*.^.X.X.X,X.% D:%.X.XXXXXXXXXXXXXXXXXXXXXXXXXXX.X.X.X.% D:%.X&.............9.............&X*X.X.% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.X,X.% D:%.+^^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.X,X.% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+X.% D:%.....................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:28:Greater vault (greater castle) X:8:40:25:51 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.................................................% D:%...XXXXXX...............................XXXXXX...% D:%..XX,,,,XX.............................XX,,,,XX..% D:%.XX,*99*,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,*99*,XX.% D:%.XX,*99*,+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+,*99*,XX.% D:%..XX,,,,XXXXXXXXXXXXXXX+X+XXXXXXXXXXXXXXX,,,,XX..% D:%...XX++XX...............X...............XX++XX...% D:%....X^^X.............XXXXXXX.............X^^X....% D:%....X^^X.X^^^^^^^^^^^^^^^^^^^^^^^^^^^^^X.X^^X....% D:%....X^^X.X^^^XXXXXXXXXXXXXXXXXXXXXXX^^^X.X^^X....% D:%....X^^+&X^^XX@.+***************+.@XX^^X&+^^X....% D:%....X^^XXX^^+@.@X*9999988899999*X@.@+^^XXX^^X....% D:%....X^^+.X^^XX@.+***************+.@XX^^X.+^^X....% D:%....X^^X.X^^^XXXXXXXXXXXXXXXXXXXXXXX^^^X.X^^X....% D:%....X^^X.X^^^^^^^^^^^^^^^^^^^^^^^^^^^^^X.X^^X....% D:%....X^^X............XXXX+XXXX............X^^X....% D:%...XX++XX..........XX&.&.&.&XX..........XX++XX...% D:%..XX,,,,XXXXXXXXXXXX&.&.&.&.&XXXXXXXXXXXX,,,,XX..% D:%.XX,*99*,+********9XXXXX+XXXXX9********+,*99*,XX.% D:%.XX,*99*,XXXXXXXXXXX&.&.&.&.&XXXXXXXXXXX,*99*,XX.% D:%..XX,,,,XX.........XX&.&.&.&XX.........XX,,,,XX..% D:%...XXXXXX...........XXXX+XXXX...........XXXXXX...% D:%.................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:29:Lesser vault (x-factor) X:8:25:25:26 D:%%%%%%%%%%%%%%%%%%%%%%%%%% D:%^^^^^^^^^^^^^^^^^^^^^^^^% D:%^##########++##########^% D:%^#XX,,,,,,,,,,,,,,,,XX#^% D:%^#,XX,,,,,,,,,,,,,,XX,#^% D:%^#,,XX,,,,,,,,,,,,XX,,#^% D:%^#,,,XX,,,,,,,,,,XX,,,#^% D:%^#,,,,XX,,,,,,,,XX,,,,#^% D:%^#,,,,,XX,,,,,,XX,,,,,#^% D:%^#,,,,,,XX,,,,XX,,,,,,#^% D:%^#,,,,,,,X+XX+X,,,,,,,#^% D:%^+,,,,,,,,X99X,,,,,,,,+^% D:%^+,,,,,,,,X99X,,,,,,,,+^% D:%^+,,,,,,,,X99X,,,,,,,,+^% D:%^#,,,,,,,X+XX+X,,,,,,,#^% D:%^#,,,,,,XX,,,,XX,,,,,,#^% D:%^#,,,,,XX,,,,,,XX,,,,,#^% D:%^#,,,,XX,,,,,,,,XX,,,,#^% D:%^#,,,XX,,,,,,,,,,XX,,,#^% D:%^#,,XX,,,,,,,,,,,,XX,,#^% D:%^#,XX,,,,,,,,,,,,,,XX,#^% D:%^#XX,,,,,,,,,,,,,,,,XX#^% D:%^##########++##########^% D:%^^^^^^^^^^^^^^^^^^^^^^^^% D:%%%%%%%%%%%%%%%%%%%%%%%%%% N:30:Greater vault (university) X:8:30:29:38 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%....................................% D:%.##################################.% D:%.#*+..&#..,#,#..,#,#..,#,#.,#&+*#*#.% D:%.#####.#.###.#.###.#.###.#.##.###+#.% D:%.#***#.#.#*..#.#*..#.#*..#.#..#..&#.% D:%.#+###+#+###+#+###+#+###+#+##+###+#.% D:%.#...+&......................&+...#.% D:%.#.###.##########++##########.###.#.% D:%.#,#.+.#,,,,,,,,,,,,,,,,,,,,#.#*#,#.% D:%.###.#.#,.,..,..,@.,..,..,.,#.#.###.% D:%.#,..#.#,..,..,..,..,..,..,,#.+..,#.% D:%.#####.#,9&,,,9,,&,,&,,.,,,,#.#####.% D:%.+^^^+.+,,,&,,,&,,,9,,&,,&,,+.+^^^+.% D:%.+^^^+.+,.,...,...,...,...,,+.+^^^+.% D:%.###+#.#,,,,&,,&,,,9,&,,,&,,#.#####.% D:%.#*#&#.#,,,&,,,9,&,,&,,,,,9,#.#..,#.% D:%.#+#*#.#,.,...,....,....,..,#.#.###.% D:%.#.###.#,,,&,,,,&,9,,&,,,&,,#.+.#,#.% D:%.#&..+.#,,,,,,,,.,,,,,,,,,,,#.###.#.% D:%.#####.##########++##########.+...#.% D:%.#&..+&......................&#+###.% D:%.#.###+#+###+#+###+#+###+#+##+#...#.% D:%.#.+*#.#.#*..#.#*..#.#*..#.#..###,#.% D:%.#####.#.###.#.###.#.###.#.##&#*###.% D:%.#*+..&#..,#,#..,#,#..,#,#.,#.+,*,#.% D:%.##################################.% D:%....................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:31:Greater vault (nethack castle (almost)) X:8:35:19:62 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%............................................................% D:%.XXXXXXX............................................XXXXXXX.% D:%.X,,9,,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,9,,X.% D:%.X,,,,,+.......^....*....^ ..........^.......*...^..+,,,,,X.% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+XXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%......X,.,9,,,,X,,,,,,,,,+,.,.,.,.,.,X,.,.,.+^+,.,.,.X......% D:%......X,.9*9,.,X,,,,,,,,,X,.,..,..,.,X,.,.,.X^X,.,.,.X......% D:%....&.X.&*@*&,.XXXXXXXXXXX,.,.,9,.,.,XXXXXXXX+XXXXXXXX......% D:%......+9*@8@*9.+^^^^^^^^^+,.,,9@9,,.,+^^^^^^^^^^^^^^^+......% D:%....&.X.&*@*&,.XXXXXXXXXXX,.,.,9,.,.,XXXXXXXX+XXXXXXXX......% D:%......X,.9*9,.,X,,,,,,,,,X,.,.,,,.,.,X.,.,.,X^X.,.,.,X......% D:%......X,.,9,,,,X,,,,,,,,,+,.,.,.,.,.,X.,.,.,+^+.,.,.,X......% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+XXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X,,,,,+.......^....*....^...........^.......*...^..+,,,,,X.% D:%.X,,9,,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,9,,X.% D:%.XXXXXXX............................................XXXXXXX.% D:%............................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:32:Greater vault (another nethack-style castle) X:8:30:18:52 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%..................................................% D:%.XXXXX......................................XXXXX.% D:%.X9,,X......................................X,,9X.% D:%.XXX+XXXXXXXXXXXXXXXXXXX++XXXXXXXXXXXXXXXXXXX+XXX.% D:%...X^^^^^^^^^^^^^^^^^^^+..+^^^^^^^^^^^^^^^^^^^X...% D:%...X^XXXXXXXXXXXXXXXXXXX++XXXXXXXXXXXXXXXXXXX^X...% D:%...X^X,,,,,,,,,,,,,,,,,X..X,,,,,,,,,X,,@@@@,X^X...% D:%...X^X,,,,,,,,,,,,,,,,,+..+,,,,,,,,,+,,,,998X^X...% D:%...X^X,,,,,,,,,,,,,,,,,+..+,,,,,,,,,+,,,,998X^X...% D:%...X^X,,,,,,,,,,,,,,,,,X..X,,,,,,,,,X,,@@@@,X^X...% D:%...X^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX^X...% D:%...X^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^X...% D:%.XXX+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+XXX.% D:%.X9,,X......................................X,,9X.% D:%.XXXXX......................................XXXXX.% D:%..................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:33:Lesser vault (nethack-style tower) X:7:5:15:19 D:%%%%%%%%%%%%%%%%%%% D:%.................% D:%...###.###.###...% D:%...#&#.#&#.#&#...% D:%.###+###+###+###.% D:%.#.,.,.,.+.+,,,#.% D:%.###+#####.#####.% D:%...+*&*&*#.+,#...% D:%.###+#####.#####.% D:%.#.,.,.,.+.+,,,#.% D:%.###+###+###+###.% D:%...#&#.#&#.#&#...% D:%...###.###.###...% D:%.................% D:%%%%%%%%%%%%%%%%%%% N:34:Lesser vault (nethack, rooms) X:7:5:14:27 D:%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.........................% D:%.#+#####################.% D:%.#.^.^.^.+^+^...^#,,,,,#.% D:%.#^###+###^#####.+,,,,,#.% D:%.#.#,,,,,#.#,,,#^#,,,,,#.% D:%.#^#,,,,,#^+,,,#+#######.% D:%.#.#######.#,,,#.......#.% D:%.#^#,,,,,#^#,,,#..&.&..#.% D:%.#.#,,,,,#.#####.......#.% D:%.#^+,,,,,#^.^.^+..&.&.^+.% D:%.#######################.% D:%.........................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%% N:35:Lesser vault (nethack city) X:7:9:17:33 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%...............................% D:%.############.....############.% D:%.#,,,#,,,#,,#.....#**#,,,#***#.% D:%.#,,,#,,,#,,#.....+**#,,,#***#.% D:%.#,,,#,,,#,,#.....#**#,,,#&&&#.% D:%.#^,,#,,,#+##.....####+###+###.% D:%.#+####+##.....................% D:%...............................% D:%.#+###+###....###+##...........% D:%.#^,,#^,,####.#,,,,#.######+##.% D:%.#,,,#,,,#**#.#,&&,#.+^^#,,,,#.% D:%.#,,,#,,,#*^+.#,&@,#.#^^#,,,,#.% D:%.#,,,#,,,#**#.#,,,,#.#**#,,,,#.% D:%.############.######.#########.% D:%...............................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:36:Greater vault (nethack, large city) X:8:25:21:54 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%....................................................% D:%.##################################################.% D:%.#................................................#.% D:%.#.####################.########..#####.#########.#.% D:%.#.#^,,,,^#^****^#^,,^#.#^,,,,^#..#^^^#.#^,,,,,^#.#.% D:%.#.#^,,,,^#^****^#^,,^#.#^,,,,^#..+^**#.#^,,,,,^#.#.% D:%.#.#^,,,,^#^,,,,^#^^^^#.#^^^^^^#..#^^^#.#^,,,,,^#.#.% D:%.#.#^^^^^^#^^^^^^###+##.###+####..#####.#^^^^^^^#.#.% D:%.#.#+#########+###......................######+##.#.% D:%.#................................................#.% D:%.#.###+######+####......###+########..............#.% D:%.#.#^^^^^^#^^^^^^######.#^^^^^^^^^^#...###+#####..#.% D:%.#.#^,,,,^#^,,,,^#^^^^+.#^,,,,,,,,^#...#^^^^^^^#..#.% D:%.#.#^****^#^,,,,^#,,,^#.#^@999999@^#...#^,,,,,^#..#.% D:%.#.#^****^#^,,,,^#,,,^#.#^^^^^^^^^^#...#^,,,,,^#..#.% D:%.+.####################.############...#########..#.% D:%.#................................................#.% D:%.##################################################.% D:%....................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:37:Lesser vault (nethack, tiny castle) X:7:5:14:34 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%................................% D:%.#####....................#####.% D:%.#*,&#....................#&,*#.% D:%.###+######################+###.% D:%...#,,,,,,,,,,,,,#,,,,,,,,,,#...% D:%...+,,,,,,,,,,,,,+,,,,,,,,,,+...% D:%...+,,,,,,,,,,,,,+,,,,,,,,,,+...% D:%...#,,,,,,,,,,,,,#,,,,,,,,,,#...% D:%.###+######################+###.% D:%.#*,&#....................#&,*#.% D:%.#####....................#####.% D:%................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:38:Greater vault (nethack mirror) X:8:25:22:41 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.......................................% D:%...............XXXX+XXXX...............% D:%...............X**X^X**X...............% D:%....XXXXXXXXXXXX**X^X**XXXXXXXXXXXX....% D:%....X^+99999999X+XX^XX+X99999999+^X....% D:%....X^X9*******X,,X^X,,X*******9X^X....% D:%....X^X9*******X,,X^X,,X*******9X^X....% D:%.XXXX+XXXXXXXXXXX+X+X+XXXXXXXXXXX+XXXX.% D:%.X**X,,,,,,,,,,X,,,,,,,X,,,,,,,,,,X**X.% D:%.X*@+,,,,,,,,,,+,,,,8,,X,,,,,,,,,,+@*X.% D:%.X*@+,,,,,,,,,,X,,,8,,,+,,,,,,,,,,+@*X.% D:%.X**X,,,,,,,,,,X,,,,,,,X,,,,,,,,,,X**X.% D:%.XXXX+XXXXXXXXXXX+X+X+XXXXXXXXXXX+XXXX.% D:%....X^X9*******X,,X^X,,X*******9X^X....% D:%....X^X9*******X,,X^X,,X*******9X^X....% D:%....X^+99999999X+XX^XX+X99999999+^X....% D:%....XXXXXXXXXXXX**X^X**XXXXXXXXXXXX....% D:%...............X**X^X**X...............% D:%...............XXXX+XXXX...............% D:%.......................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:39:Greater vault (nethack tomb) X:8:25:13:57 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.......................................................% D:%..........XXXXX.XXXXX.XXXXX.XXXXX.XXXXX................% D:%..........X,,,X.X,,,X.X,,,X.X,,,X.X,,,X................% D:%.XXXXXXXXXX,&,XXX,&,XXX,&,XXX,&,XXX,&,XXXXXXXXXXXXXXXX.% D:%.X&^&X....^...^...^...^...^...^...^..^..X,,,,,,,,X,,9X.% D:%.+^^^+..^...^...^...^...^...^...^...^.@.+,,,,,,,,+,98X.% D:%.X&^&X....^...^...^...^...^...^...^.....X,,,,,,,,X,,9X.% D:%.XXXXXXXXXX,&,XXX,.,XXX,.,XXX,&,XXX,&,XXXXXXXXXXXXXXXX.% D:%..........X,,,X.X,,,X.X,,,X.X,,,X.X,,,X................% D:%..........XXXXX.XXXXX.XXXXX.XXXXX.XXXXX................% D:%.......................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:40:Greater vault (nethack hell level #1) X:8:30:17:55 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.....................................................% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.XX*XXXXXXXXXX**XXXXXXXXXXXX***********************X.% D:%.XX*X,,,,X***X+XX,,,,,,X***XXXXXXXXXXXX^^^^^^^^^^^^X.% D:%.XX,X,,,,+***X@^+,,,,,,X***+,,,,,,,,,,X^^^^^^^^^^^^X.% D:%.XX&X,,,,XXXXXXXX^^^^^^^^^^X,,,XXXXXXXXXXXXXX^^^^^^X.% D:%.XX+X....XXXX.............^X,,,+,,,,,,,,,,,9XXXXX^^X.% D:%.+^^^^^^^^^^+^^^^^^^^^^^^^^XXXXX,,,,,,,,,,,9+888+@@X.% D:%.XX+X....XXXX.............^X,,,+,,,,,,,,,,,9XXXXX^^X.% D:%.XX&X,,,,XXXXXXXX^^^^^^^^^^X,,,XXXXXXXXXXXXXX^^^^^^X.% D:%.XX,X,,,,+***X@^+,,,,,,X***+,,,,,,,,,,X^^^^^^^^^^^^X.% D:%.XX*X,,,,X***X+XX,,,,,,X***XXXXXXXXXXXX^^^^^^^^^^^^X.% D:%.XX*XXXXXXXXXX**XXXXXXXXXXXX***********************X.% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.....................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:41:Greater vault (nethack hell level #2) X:8:30:15:54 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%....................................................% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...% D:%.+^XX,+^^^^^X^^^^^^^^^^^^^^^^^^^^^X,,,X,@^X*^*+9X...% D:%.X^XX,X^XXX,X@XXXXXXXXXXXXXXXXXXX^X,X,X,X^X*X*X9X...% D:%.X^XX,X^^^X,X^^^^^^^^^^^^^^^^^^@X^X,X,X,X^X*X*X9X...% D:%.X^XXXXXX^X,XXXXXXXXXXXXXXXXXXX^X^X,X,X,X^X*X*X+XXX.% D:%.X^^^^^^X^X,X,,,,,,,,,,,,,,,,,X^X^X,X,X,X^X*X*X888X.% D:%.X+XXXX^X^X,X,XXXXXXXXXXXXXXX,X^X^X,X,X,X^X*X*X+XXX.% D:%.X,XX,X^X^X,X,X,,,,,,,,,,,,,,,X^X^X,X,X,X^X*X*X9X...% D:%.X,XX,X^X&X,X,X,XXXXXXXXXXXXXXX^X^X,X,X,X^X*X*X9X...% D:%.X,XX,+^^^X,,,X^^^^^^^^^^^^^^^^^X^@,X,,,X^@*X*+9X...% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...% D:%....................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:42:Greater vault (nethack hell level #3) X:8:30:17:55 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.....................................................% D:%...XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.........% D:%...X,,,,,,,,,,,,,,,,,,,,,XXX^^^^^^^^^^^^^^^X.........% D:%...X,^^^^^^^^^^XXXX,,,,,,+&&^XXXXXXXXXXXX^^+.........% D:%...X,^XXXXXX******X,,XXXXXXXXX^^^^******XXXX.........% D:%...X,^X****X@*XXXXXXXX,,,,,,,,,,,XXXXXXXXXXXXXX......% D:%.XXXX+X,,,,XXXX,,,,,,,,,,,,,,,,,^+************XXXXX..% D:%.X@,,,,,XX,,,,+,,XXXXXXXXXXXXXXXXX****9999****+888X..% D:%.XXXX+X,,,,XXXX,,,,,,,,,,,,,,,,,^+************XXXXX..% D:%...X,^X****X@*XXXXXXXX,,,,,,,,,,,XXXXXXXXXXXXXX......% D:%...X,^XXXXXX******X,,XXXXXXXXX^^^^******XXXX.........% D:%...X,^^^^^^^^^^XXXX,,,,,+&&^^XXXXXXXXXXXX^^+.........% D:%...X,,,,,,,,,,,,,,,,,,,,XXX^^^^^^^^^^^^^^^^X.........% D:%...XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.........% D:%.....................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:43:Lesser vault (easter egg) X:7:5:14:19 D:%%%%%%%%%%%%%%%%%%% D:%.................% D:%.###############.% D:%.#,^,^,^,^,^,^,#.% D:%.#+###########^#.% D:%.#,^,^,^,^,^,#,#.% D:%.###########,#^#.% D:%.#,^,^,^,^,#^#,#.% D:%.#+#######,#,#^#.% D:%.#,,,,,,,#^#^#,#.% D:%.#,,,,,,,#,+,#^+.% D:%.###############.% D:%.................% D:%%%%%%%%%%%%%%%%%%% N:44:Greater vault (nethack samurai castle) X:8:35:20:59 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.........................................................% D:%.XXXXX.............................................XXXXX.% D:%.X***X.............................................X***X.% D:%.X***XXX.....XX+XXXXXXXXXXXXXXXXXXXXXXXXX+XX.....XXX***X.% D:%.XXX@,,X.....X^&^X,,,X***X,,,X***X^^^+8X^&^X.....X,,@XXX.% D:%...X,,,XXXXXXX^^^X,,,X^^^X,,,X^^^X@@^X8X^^^XXXXXXX,,,X...% D:%...XXX^^^^^^^^^XXXXX+XXX+X+XXXXX+X+XXXXXXX^^^^^^^^^XXX...% D:%.....X^^XXXXXXXX*X,,,,,,,,,,,,,,,,,,,,,X*XXXXXXXX^^X.....% D:%.....X^^+,,,,,,,,+,,,,,,,,,99,,,,,,,,,,+,,,,,,,,+^^X.....% D:%.....X^^+,,,,,,,,+,,,,,,,,,99,,,,,,,,,,+,,,,,,,,+^^X.....% D:%.....X^^XXXXXXXX*X,,,,,,,,,,,,,,,,,,,,,X*XXXXXXXX^^X.....% D:%...XXX^^^^^^^^^XXXXXXX+X+XXXXX+X+XXX+XXXXX^^^^^^^^^XXX...% D:%...X,,,XXXXXXX^^^X8X^@@X^^^X^^^X,,,X,,,X^^^XXXXXXX,,,X...% D:%.XXX@,,X.....X^&^X8+^^^X***X***X,,,X,,,X^&^X.....X,,@XXX.% D:%.X***XXX.....XX+XXXXXXXXXXXXXXXXXXXXXXXXX+XX.....XXX***X.% D:%.X***X.............................................X***X.% D:%.XXXXX.............................................XXXXX.% D:%.........................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:45:Greater vault (nethack samurai castle #2) X:8:35:20:61 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%...........................................................% D:%.XXXXXXXXXXXXX...............................XXXXXXXXXXXXX.% D:%.X,,^^^^^^^,,X...............................X,,^^^^^^^,,X.% D:%.X,,^XXXXX^,,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,^XXXXX^,,X.% D:%.X,,^+999X^,,X,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X,,^X999+^,,X.% D:%.X,,^XXXXX^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^XXXXX^,,X.% D:%.X^^^^^^^^^^^XXXXXX+XXXXXXXXXXXXXXXXXXX+XXXXXX^^^^^^^^^^^X.% D:%.XXXX^^^XXXXXXXX*X,,,,,,,,,,,,,,,,,,,,,,,X*XXXXXXXX^^^XXXX.% D:%....+^^^X********+,,,,,,,,,,,,,,,,,,,,,,,+********X^^^+....% D:%....+^^^X********+,,,,,,,,,,,,,,,,,,,,,,,+********X^^^+....% D:%.XXXX^^^XXXXXXXX*X,,,,,,,,,,,,,,,,,,,,,,,X*XXXXXXXX^^^XXXX.% D:%.X^^^^^^^^^^^XXXXXX+XXXXXXXXXXXXXXXXXXX+XXXXXX^^^^^^^^^^^X.% D:%.X,,^XXXXX^,,^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^XXXXX^,,X.% D:%.X,,^+999X^,,X,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,X,,^X999+^,,X.% D:%.X,,^XXXXX^,,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,,^XXXXX^,,X.% D:%.X,,^^^^^^^,,X...............................X,,^^^^^^^,,X.% D:%.XXXXXXXXXXXXX...............................XXXXXXXXXXXXX.% D:%...........................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:46:Greater vault (nethack spiral) X:8:30:19:38 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.........XXXXXXXXX+XXXXXXXXX........% D:%......XXXX^^^^^^^^^^^^^^^^^XXXX.....% D:%...XXXX^^^^^XXXXXXXXXXXXX^^^^^XXXX..% D:%..XX^^^^^XXXX^^^^^^^^^^^XXXX^^^^^XX.% D:%.XX^^^^XXX^^^^XXXXXXXXX^^^^XXX^^^^XX% D:%.X^^^^XX^^^^XXX,^^^^^,XXX^^^^XX^^^^X% D:%.X,,,XX,,,XXX,,^XX+XX^,,XXX,,,XX,,,X% D:%.X,,,X,,,,X,,,^XX***XX^,,,X,,,,X,,,X% D:%.X,,,X,99,X,,,^+@888@+^,,,X,,,,+,,,X% D:%.X,,,X,,,,X,,,^XX***XX^,,,X,,,,X,,,X% D:%.X,,,XX,,,XXX,,^XX+XX^,,XXX,,,XX,,,X% D:%.X,,,,XX^^^^XXX,^^^^^,XXX^^^^XX,,,,X% D:%.XX,,,,XXX^^^^XXXX+XXXX^^^^XXX,,,,XX% D:%..XX,,,**XXXX^^^^^^^^^^^XXXX,,,,,XX.% D:%...XXXX**,,,XXXXXXXXXXXXX,,,,,XXXX..% D:%......XXXX,,,,,,,,,,,,,,,,,XXXX.....% D:%.........XXXXXXXXXXXXXXXXXXX........% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:47:Greater vault (nethack building) X:8:30:16:41 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%...XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%...X^^^^^^^^^^^^^^^^X**@**X**@**X**@**X% D:%...X^^XXXXXXXXXXXX^^XXX+XXXXX+XXXXX+XXX% D:%...X^^X,,,,,,,,,,X^^X^^^^^^^^^^^^^^^^^X% D:%...X^^X,,,,,,,,,,X^^X+XXX+XXX+XXXXX+XXX% D:%.XXX^^X,,,,,,,,,,X^^^^^^X,,,X,,,X,,,,,X% D:%.+^&^^X,,,,,,,,,,+^^^^^^X,,,X,,,X,989,X% D:%.+^&^^X,,,,,,,,,,+^^^^^^X,,,X,,,X,989,X% D:%.XXX^^X,,,,,,,,,,X^^^^^^X,,,X,,,X,,,,,X% D:%...X^^X,,,,,,,,,,X^^X+XXXXX+XXX+XXX+XXX% D:%...X^^X,,,,,,,,,,X^^X^^^^^^^^^^^^^^^^^X% D:%...X^^XXXXXXXXXXXX^^XXX+XXXXX+XXXXX+XXX% D:%...X^^^^^^^^^^^^^^^^X**@**X**@**X**@**X% D:%...XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:48:Lesser vault (nethack, spiral rooms) X:7:5:13:32 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%..............................% D:%....#######################...% D:%..###^+,,,,,,#^^^^^^^^^^+*###.% D:%..#,#^#,,,,,,#+############,#.% D:%..#^#^#,,,,,,#,,,+,,,,,,#^#^#.% D:%..+^+^#,,,,,,#,,,#,,,,,,#^+^+.% D:%..#^#^#,,,,,,+,,,#,,,,,,#^#^#.% D:%..#,############+#,,,,,,#^#,#.% D:%..###*+^^^^^^^^^^#,,,,,,+^###.% D:%....#######################...% D:%..............................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:49:Greater vault (nethack building) X:8:30:17:54 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%....................................................% D:%........XXXXXXXXXXXXX.................XXXXXXXXXXXXX.% D:%........X***********X.................X***********X.% D:%.XXXXXXXX***********XXXXXXXXXXXXXXXXXXX***********X.% D:%.+^^^^^^X,,,,,,,,,,,X**X**X**X**X**X**X*,,,,,,,,,*X.% D:%.X^,,,,^X^,,,,,,,,,,X,@X,@X,@X,@X,@X,@X,,,,,,,,,,,X.% D:%.X^^^^^^+^^^^^^^^^^^XX+XX+XX+XX+XX+XX+X,,,,,,,,,,,X.% D:%.XXXXXXXX^^^^^^^^^^^+^^^^^^^^^^^^^^^^^+,,,,,89,,,,X.% D:%.X^^^^^^+^^^^^^^^^^^XX+XX+XX+XX+XX+XX+X,,,,,98,,,,X.% D:%.X^,,,,^X^,,,,,,,,,,X,@X,@X,@X,@X,@X,@X,,,,,,,,,,,X.% D:%.+^^^^^^X,,,,,,,,,,,X**X**X**X**X**X**X*,,,,,,,,,*X.% D:%.XXXXXXXX***********XXXXXXXXXXXXXXXXXXX***********X.% D:%........X***********X.................X***********X.% D:%........XXXXXXXXXXXXX.................XXXXXXXXXXXXX.% D:%....................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:50:Lesser vault (nethack, head) X:7:7:17:29 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%........###########........% D:%...#####################...% D:%...######,,,,,,,,,######...% D:%..#+^^^^#,,,,,,,,,#^^^^+#..% D:%..##^^^^#,,,,,,,,,+^,,^##..% D:%.#####+##,,,,,,,,,#^^^^###.% D:%.##^^^^^^,,,,,,,,,########.% D:%.####+###++#########*@+*##.% D:%.##^^^^^#^^#,,,#^@^####*##.% D:%.##^^,,^#^^#,###^#^#****##.% D:%..##^,,^#^^#,,,.^#^#@####..% D:%..#+^^^^#^^#####^#^^^^^##..% D:%...######^^^^^^^^#######...% D:%...#####################...% D:%........###########........% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:51:Lesser vault (maze of rooms) X:7:10:16:32 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%..............................% D:%.#+##########################.% D:%.#^#,,,+^#*#^+,,+*#^+^#*#**@#.% D:%.#^+,,,#^+^+^######^#^#*###+#.% D:%.#########+###,,,,#^#,+@#,,,#.% D:%.#,,,,,,+^^+,,,,,,+^#######+#.% D:%.###+#######,,,,,#####,,+^^^#.% D:%.#,,,+**#**+,,,,,#^^^+,,#^,^#.% D:%.#############+###^,^#+##^^^#.% D:%.#***#^+,,#,,,,,,+^^^#^######.% D:%.#+###^#,,+,,,,,,#####^+,^^^#.% D:%.#,,,+^#,,########,,,+^#,^^^#.% D:%.##########################+#.% D:%..............................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:52:Lesser vault (tetris tiles) X:7:5:20:13 D:%%%%%%%%%%%%% D:%..#######..% D:%..#**#**#..% D:%..#,###,#..% D:%..#,#^#,#..% D:%.##+#^#+##.% D:%.#&,#^#,&#.% D:%.#,,+^+,,#.% D:%.####+####.% D:%.###,^,###.% D:%.#*##^##*#.% D:%.#,,#+#,,#.% D:%.##,#^#,##.% D:%.##+#^#+##.% D:%.#,,#^#,,#.% D:%.##,+^+,##.% D:%..#,#+#,#..% D:%..###.###..% D:%...........% D:%%%%%%%%%%%%% N:53:Lesser vault (hospital ward) X:7:5:14:20 D:%%%%%%%%%%%%%%%%%%%% D:%..................% D:%.################.% D:%.#,,#,,#,,#,,#,,#.% D:%.#,,#,,#,,#,,#,,#.% D:%.##+##+##+##+##+#.% D:%.+..............+.% D:%.+..............+.% D:%.#+##+##+##+##+##.% D:%.#,,#,,#,,#,,#,,#.% D:%.#,,#,,#,,#,,#,,#.% D:%.################.% D:%..................% D:%%%%%%%%%%%%%%%%%%%% N:54:Lesser vault (lesser crypt) X:7:5:13:26 D:%%%%%%%%%%%%%%%%%%%%%%%%%% D:%................###.....% D:%................#,#.....% D:%......#######.###+###...% D:%..###.#,#,#,#.#^^^^^#...% D:%.##&###+#+#+###^###^###.% D:%.+^^^+^^^^^^^+^^#9#^+,#.% D:%.##&###+#+#+###^###^###.% D:%..###.#,#,#,#.#^^^^^#...% D:%......#######.###+###...% D:%................#,#.....% D:%................###.....% D:%%%%%%%%%%%%%%%%%%%%%%%%%% N:55:Lesser vault (arena) X:7:5:15:17 D:%%%%%%%%%%%%%%%%% D:%...............% D:%.+###########+.% D:%.#...........#.% D:%.#.####^####.#.% D:%.#.#,,,,,,,#.#.% D:%.#.#,,,,,,,#.#.% D:%.#.^,,,,,,,^.#.% D:%.#.#,,,,,,,#.#.% D:%.#.#,,,,,,,#.#.% D:%.#.####^####.#.% D:%.#...........#.% D:%.+###########+.% D:%...............% D:%%%%%%%%%%%%%%%%% N:56:Lesser vault (monster wc) X:7:5:12:12 D:%%%%%%%%%%%% D:%..#######.% D:%..#.&&&&#.% D:%..#^#####.% D:%.##...+,#.% D:%.#*...###.% D:%.#*...+,#.% D:%.#*...###.% D:%.##...+,#.% D:%..#+#####.% D:%..........% D:%%%%%%%%%%%% N:57:Lesser vault ('not' 'and') X:7:5:11:15 D:%%%%%%%%%%%%%%% D:%.............% D:%..#########..% D:%.#+,,,#,,,+#.% D:%.#,#,#+#,#,#.% D:%.#,,#+*+#,,#.% D:%.#,#,#+#,#,#.% D:%.#+,,,#,,,+#.% D:%..#########..% D:%.............% D:%%%%%%%%%%%%%%% N:58:Lesser vault (brain's lair) X:7:5:18:17 D:%%%%%%%%%%%%%%%%% D:%...............% D:%.#############.% D:%.#...........#.% D:%.#.####^####.#.% D:% #.#...&...#.#.% D:%.#.#.#####.#.#.% D:%.#.#.#,,,#.#.#.% D:%.#.#.#,,,#.#.#.% D:%.#.#.#,,,#.#.#.% D:%.#.#.##+##.#.#.% D:%.^.#..#^#..#.^.% D:%.####.#^#.####.% D:%.#,,#.#+#.#,,#.% D:%.#,,+..&..+,,#.% D:%.#############.% D:%...............% D:%%%%%%%%%%%%%%%%% N:59:Lesser vault (yin-yang) X:7:5:17:16 D:%%%%%%%%%%%%%%%% D:%..............% D:%.#+##########.% D:%.#&#^^^^^^^^#.% D:%.#.#^######^#.% D:%.#&#^#****#^#.% D:%.#.#^#*,**#^#.% D:%.#&#^#****#^#.% D:%.#.#+####+#^#.% D:%.#&#,,,,#.#^#.% D:%.#.#,,*,#&#^#.% D:%.#&#,,,,#.#^#.% D:%.#.######&#^#.% D:%.#&.&.&.&.#^#.% D:%.##########+#.% D:%..............% D:%%%%%%%%%%%%%%%% N:60:Greater vault (der el bahri) X:8:35:28:45 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X***X,,X^^^^^^^^X9988899X^^^^^^^^+******X.% D:%.X***X,,+^..,...^X9999999X^...,..^XXXX***X.% D:%.X***XXXX^......^XXXX+XXXX^......^X**XXXXX.% D:%.X^^^X,,X^..,...^^^^^^^^^^^...,..^X******X.% D:%.X@@@X,,X^.......................^X,,,,,,X.% D:%.X^^^X,,X^..,..,..,..,..,..,..,..^X,,,,,,X.% D:%.X^^^X++X^.......................^X,,,,,,X.% D:%.X^^^X^^X^..,..,..,..,..,..,..,..^X,,,,,,X.% D:%.X^^^^^^+^.......................^X,,,,,,X.% D:%.X^^^^^^X^..,..,..,..,..,..,..,..^X,,,,,,X.% D:%.XXX+XXXX^.......................^X,,,,,,X.% D:%.X***X**X^..,..,..,..,..,..,..,..^X,,,,,,X.% D:%.XXXXX**X^.......................^X,,,,,,X.% D:%.X,,,,,,+^.......................^+,,,,,,X.% D:%.X,,,,,,+^^^^^^^^^^^^^^^^^^^^^^^^^+,,,,,,X.% D:%.XXXXXXXXXXXXXXXXXXX+++XXXXXXXXXXXXXXXXXXX.% D:%.X.............^^^^^^^^^^^^..............X.% D:%.X................^^^^^^^................X.% D:%.XXXXXXXXXXXXXXXXXXX^^^XXXXXXXXXXXXXXXXXXX.% D:%.X.................X.^.X.................X.% D:%.X.X.X.X.X.X.X.X.X.X^^^X.X.X.X.X.X.X.X.X.X.% D:%.X.................X.^.X.................X.% D:%.X.X.X.X.X.X.X.X.X.X^^^X.X.X.X.X.X.X.X.X.X.% D:%.X.................X.^.X.................X.% D:%...........................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:61:Lesser vault (der el bahri sanctuary) X:7:5:12:22 D:%%%%%%%%%%%%%%%%%%%%%% D:%....................% D:%..........###.......% D:%..........#,#.......% D:%..###.###.#,#.......% D:%.##,###,###,#######.% D:%.+^^^^^^^+^^^+,,,,#.% D:%.+^^^^^^^+^^^+,,,,#.% D:%.######+###########.% D:%......###...........% D:%....................% D:%%%%%%%%%%%%%%%%%%%%%% N:62:Greater vault (hypostyle of ramses III) X:8:40:38:34 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X888888+*******X*******+88888X.% D:%.XXXXXXXXX+XXXXXXXXXXX+XXXXXXXX.% D:%.X99+***+^^^+^^^^^^^+^^^+**+99X.% D:%.XXXXXXXXXXXXXX+++XXXXXXXXXXXXX.% D:%.X**X,,X,,+^X^^^^^^^X^X,,,+***X.% D:%.X**X,,X,,X^X^X...X^X^X,,,XXXXX.% D:%.X+XX,,X,,X^X^..@..^X^X,,,X***X.% D:%.X,,X,,XXXX^X^X...X^X^X^^^X***X.% D:%.X,,X,,X,*X^X^^^^^^^X^XX+XXXX+X.% D:%.X+XXX+X+XX^XXX+++XXX^X^^X,,,,X.% D:%.X^^^^^X^^+^^^^^^^^^^^+^^X,**,X.% D:%.X+XXXXXXXX^X.X...X.X^XXXX,**,X.% D:%.X^^^^^X,,X^.........^X**X,**,X.% D:%.X^X,X^X,,X^X.X.@.X.X^X++X,,,,X.% D:%.X^^^^^X,,X^.........^+^^X^^^^X.% D:%.XXX+XXX++X^XXX...XXX^XXXX+XXXX.% D:%.X^^^^^^^^+^....&....^+****+^^X.% D:%.XXXXXXXXXX^X.X...X.X^XXXXXXX^X.% D:%.X^^^^^+^^X^.........^X^^^^^^^X.% D:%.X^#X#^X^^X^X.X.&.X.X^X^,*XXXXX.% D:%.X^X9X^X^^X^.........^X^,*X***X.% D:%.X^#X#^X^^X^X.X...X.X^X^,*XXX+X.% D:%.X^^^^^X^^X^^^^^^^^^^^X^^^X,,,X.% D:%.XXXXXXX++XXXXX+++XXXXXX+XX,,,X.% D:%.X*****+^^^^^^^^^^^^^^^^^+,,,,X.% D:%.XXXXXXX^.X.X.X...X.X.X.^XXXXXX.% D:%.X,,X,,X^...............^+,,,,X.% D:%.X,,X,,X^.X.X.X...X.X.X.^XXXXXX.% D:%.X++X++X^.....&.&.&.....^+,,,,X.% D:%.X^^^^^+^.X.X.X...X.X.X.^XXXXXX.% D:%.X++X++X^...............^+,,,,X.% D:%.X,,X,,X^.X.X.X...X.X.X.^XXXXXX.% D:%.X,,X,,X^^^^^^^^^^^^^^^^^+,,,,X.% D:%.XXXXXXXXXXXXXX+++XXXXXXXXXXXXX.% D:%................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:63:Lesser vault (amada temple) X:7:10:15:30 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%............................% D:%.######################.....% D:%.#**#,,,,+^^#.....&...#.....% D:%.#**#,,,,#^^#...&.....#.....% D:%.#+#######^^#..#.#.#.##.....% D:%.#,,,,,,,#^^#^^^^^^^^^#####.% D:%.#,,,,,,,+^^+^^^^^^^^^+^^^+.% D:%.#,,,,,,,#^^#^^^^^^^^^#####.% D:%.#+#######^^#..#.#.#.##.....% D:%.#**#,,,,#^^#...&..&..#.....% D:%.#**#,,,,+^^#.........#.....% D:%.######################.....% D:%............................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:64:Lesser vault (amenhotep I) X:7:10:18:34 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%................................% D:%...............######...........% D:%...............#.&&.#...........% D:%.###############.##.#...........% D:%.#**#,,,+^^^^^^^^##.###.........% D:%.#**#,,,#^^^^^^^^^^...#########.% D:%.##+#####^^#######^&#.#.......#.% D:%.#,,,,,,+^^+,*,*,+^^^^^^^^^^^^+.% D:%.#,,,,,,+^^+*,*,*+^^^^^^^^^^^^+.% D:%.##+#####^^#######^&#.#.......#.% D:%.#**#,,,#^^^^^^^^^^...#########.% D:%.#**#,,,+^^^^^^^^##.###.........% D:%.###############.##.#...........% D:%...............#.&&.#...........% D:%...............######...........% D:%................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:65:Lesser vault (hathor chapel) X:7:10:21:19 D:%%%%%%%%%%%%%%%%%%% D:%.................% D:%......##+###.....% D:%.######^^^######.% D:%.#,,#^#...#^#,,#.% D:%.#,,+^..*..^+,,#.% D:%.#,,#^#...#^#,,#.% D:%.####^.....^####.% D:%....#^^^^^^^#....% D:%....#.##+##.#....% D:%....#&#^^^#&#....% D:%....###,^,###....% D:%....#,,,,,,,#....% D:%....####+####....% D:%....#,,,,,,,#....% D:%....####+####....% D:%....#,,,,,,,#....% D:%....####+####....% D:%.....#*****#.....% D:%.....#######.....% D:%%%%%%%%%%%%%%%%%%% N:66:Lesser vault (osiris halls) X:7:10:17:34 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%................................% D:%.###########################....% D:%.#*,+^^^^^#^^^^^^^^^^^^+,,*#....% D:%.####^#.#^#^#.#.#.#.#.^#####....% D:%.#*,+^.&.^+^..&...&...^+,,*#....% D:%.####^#.#^#^#.#.#.#.#.^#####....% D:%.#*,+^^^^^#^^^^^^^^^^^^+,,*#....% D:%.####################++########.% D:%.#,,#,,#,,#,,#,,#,,#....#,,#,,#.% D:%.#,,#,,#,,#,,#,,#,,#....#,,#,,#.% D:%.#,,#,,#,,#,,#,,#,,#.&..#,,#,,#.% D:%.#++#++#++#++#++#++#....#++#++#.% D:%.#^^^^^^^^^^^^^^^^^^^^^^^^^^^^+.% D:%.##############################.% D:%................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:67:Lesser vault (temple of sety) X:7:10:22:25 D:%%%%%%%%%%%%%%%%%%%%%%%%% D:%.##########+##########.% D:%.#,,,,,,,#^^^#,,,,,,,#.% D:%.#,,,,,,,+^^^+,,,,,,,#.% D:%.#########^^^#########.% D:%.#,,,,,,,#^^^#,,,,,,,#.% D:%.#,,,,,,,+^^^+,,,,,,,#.% D:%.#########+###########.% D:%.#^^^+^^^+^^^^^#,.,.,#.% D:%.#.#^#^#.#^#.#.#.#.#.#.% D:%.#.&^#^.&#^.&..#,.,.,#.% D:%.#.#^+^#.#^#.#.#.#.#.#.% D:%.#^^^#^^^#^^^^^#,.,.,#.% D:%.#+#+###+###+###.#.#.#.% D:%.#,#^^^^^^^^^^^#,.,.,#.% D:%.#,#.#.#.#.#.#.#+###^#.% D:%.#,#...........#,**#^#.% D:%.#*#.#.#.#.#.#.#####+#.% D:%.#*#^^^^^^^^^^^+&^^^&#.% D:%.#######+#############.% D:%.......................% D:%%%%%%%%%%%%%%%%%%%%%%%%% N:68:Lesser vault (temple at abydos) X:7:10:21:23 D:%%%%%%%%%%%%%%%%%%%%%%% D:%^^^^^^^^^^^^^^^^^^^^^% D:%^#+#+#####+#####+#+#^% D:%^#,#,#^^^^^^^^^#,#,#^% D:%^#,#,#^#.#.#.#^#,#,#^% D:%^#,#,#^...&...^#,#,#^% D:%^#####^#.#.#.#^#####^% D:%^#*,,+^^^^^^^^^+,,*#^% D:%^#########+#########^% D:%^#*,,+^^^^^^^^^+,,*#^% D:%^#####^#.#.#.#^#####^% D:%^#*,,+^...&...^+,,*#^% D:%^#####^#.#.#.#^#####^% D:%^#*,,+^^^^^^^^^+,,*#^% D:%^##+###+##+##+###+##^% D:%^#,,,,#,#^^^#,#,,,,#^% D:%^#,##,#,#,#,#,#,##,#^% D:%^#,,,,#,#***#,#,,,,#^% D:%^###################^% D:%^^^^^^^^^^^^^^^^^^^^^% D:%%%%%%%%%%%%%%%%%%%%%%% N:69:Greater vault (Spiral castle) X:8:35:31:25 D:%%%%%%%%%%%%%%%%%%%%%%%%% D:%.......................% D:%.XXXXX...........XXXXX.% D:%.X,,,X...........X,,,X.% D:%.X,,,X...........X,,,X.% D:%.XXX+XXXXXXXXXXXXX+XXX.% D:%...X^^^^^^^^^^^^^^^X...% D:%...X^XXXXXXXXXXXXX^X...% D:%...X^X^^^^^^^^^^^+^X...% D:%...X^X^XXXXXXXXXXX^X...% D:%...X^X^X&..&....&X^X...% D:%...X^X^X.XXXXXXX.X^X...% D:%...X^X^X.X^^^^^X.X^X...% D:%...X^X^X&X+XXX^X.X^X...% D:%...X^X^X.X*9*X^X&X^X...% D:%...+^X^X,X989X^X.X^+...% D:%...X^X^X.X*9*X^X.X^X...% D:%...X^X^X.XXX+X^X,X^X...% D:%...X^X^X..&..X^X.X^X...% D:%...X^X.XXXXXXX^X.X^X...% D:%...X^X^^^^^^^^^X&X^X...% D:%...X^XXXXXXXXXXX.X^X...% D:%...X^+...&..&...,X^X...% D:%...X^XXXXXXXXXXXXX^X...% D:%...X^^^^^^^^^^^^^^^X...% D:%.XXX+XXXXXXXXXXXXX+XXX.% D:%.X,,,X...........X,,,X.% D:%.X,,,X...........X,,,X.% D:%.XXXXX...........XXXXX.% D:%.......................% D:%%%%%%%%%%%%%%%%%%%%%%%%% N:70:Lesser vault (temple of dendereh) X:7:10:20:22 D:%%%%%%%%%%%%%%%%%%%%%% D:%....................% D:%.##################.% D:%.#***+^&#**#&^+***#.% D:%.#***#^^#,,#^^#***#.% D:%.#####++#++#++#####.% D:%.#,,,+^^^^^^^^+,,,#.% D:%.#####^######^#####.% D:%.#,,,+^#,,,,#^+,,,#.% D:%.#####^#,**,#^#####.% D:%.#,,,+^#,**,#^#***#.% D:%.#####^#,**,#^#^^^#.% D:%.#,,,+^#,**,#^##+##.% D:%.#####^#,,,,#^#,,,#.% D:%.#,,,#^##++##^#&,&#.% D:%.#,,,+^^^^^^^^##+##.% D:%.#,,,#^^^^^^^^^^^^#.% D:%.########++########.% D:%....................% D:%%%%%%%%%%%%%%%%%%%%%% N:71:Greater vault (Karnak, part I) X:8:35:24:44 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X*****+^+^^^^+^^^X,,,X***X***X***X,****X.% D:%.XXXXXXXXX^XX^X,,,X,X,X,X,X,X,X*X*X,X*X*X.% D:%.X,X,X,X,X^..^X,,,X,,,X^^^X^^^X**@+^,,,,X.% D:%.X^^^^^^^+^@.^X,,,XX+XX+XXXXX+XXXXX+XXXXX.% D:%.X,X^^^X,X^XX^X***X^^^+^^^^^^^+,,*X^^^^^X.% D:%.XXXX+XXXX^^^^X,,,XXXXX^X.X.X^XXXXX^X^X^X.% D:%.X^^^^^^^XXXXXX,,,X,,,X^..@..^+,,*X^^^^&X.% D:%.X^X,X,X^X,,,,X,,,X,X,X^X.X.X^XXXXX^XXXXX.% D:%.X^^^^^^^X,,,,X^^^X,,,X^^^^^^^+,,*X^+,,*X.% D:%.XXXX+XXXXX++XXX+XXX+XXXXX+XXXXXXXX^XXXXX.% D:%.X*,+^^^^^^^^^^^^^^^^^^^^^^^^^+,,*X^+,,*X.% D:%.XXXX^X.X.X.X.X.X.X.X.X.X.X.X^XXXXX^XXXXX.% D:%.X*,+^.........&.....&.......^X,,*X^+,,*X.% D:%.XXXX^X.X.X.X.X.X.X.X.X.X.X.X^+,X*X^XXXXX.% D:%.X**X^.......................^X,,*X^+,,*X.% D:%.X,,+^X.X.X.X.X.X.X.X.X.X.X.X^XXXXX^XXXXX.% D:%.XXXX^.........&.....&.......^+^^^^^+,,*X.% D:%.X,,+^X.X.X.X.X.X.X.X.X.X.X.X^X,X,X^XXXXX.% D:%.X**X^^^^^^^^^^^^^^^^^^^^^^^^^X.*.X^+,,*X.% D:%.XXXXXXXXXXXXXXXX+XXXXXXXXXXXXXXXXXXXXXXX.% D:%..........................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:72:Lesser vault (Karnak, part II) X:7:10:20:29 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%...........................% D:%.###+######################% D:%.#,+^#,,#,,#^+^+^#*#,#^+,#.% D:%.###.#,,#,,#^#^#^#*#,#^###.% D:%.#,+^#,,#,,#^#^#^#*#+#^+,#.% D:%.###.#++#++#^#^#^#+#.#^###.% D:%.#,+^#^^^^^+^#^#^+,,,#^+,#.% D:%.###.#^^^^^+^#^#+#+###^###.% D:%.#,+^#+#+#+#^#^#,#^+,#^+,#.% D:%.###.#,#,#,#^#^#######^###.% D:%.#,+^#######+#,,+,,,,,^+,#.% D:%.###^^^^^^#,^#,,+,,,,#^###.% D:%.#,+^#,#*^##+####,,,,,^+,#.% D:%.###^,,,*^#^^^^^#,,,,#^###.% D:%.#,+^#,#*^#,,,,^+,,,,,^+,#.% D:%.###^^^^^^#^^^^^#,,,,,^###.% D:%...##########+##########...% D:%...........................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:73:Greater vault (mortuary temple of sety) X:8:35:25:34 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%................................% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X^+,,***X,,+^^^^^+,,X*X,,X*X9X.% D:%.X^XXXXXXX,,X^X*X^X,,X,X,,X*X9X.% D:%.X^+,,***XXXX^*@*^X,,X^X,,X@X9X.% D:%.X^XXXXXXX,,X^X*X^XXXX^X,,X^X9X.% D:%.X^+,,***X,,+^^^^^+..X^X,,X^X^X.% D:%.X^XXXXXXXXXXXX+XXXXXX+X++X+X+X.% D:%.X^X*X*X*X**X,+.+,X**X^^^^+^^^X.% D:%.X+X,X,X,X,,XXX.XXX,,X^^^^+^^^X.% D:%.X^X^X^X^X,,X,X.X,X,,X^^XXXXXXX.% D:%.X^X+X+X+X^^X,X.X,X^^X^^X,,,,,X.% D:%.X^+^^^^^X++X+X+X+X++X^^X,X,X,X.% D:%.X^XXXXXXX^^^^^^^^^^^X^^X,,,,,X.% D:%.X^X*X*X*XXXX^...^XXXX^^X,X,X,X.% D:%.X^X,X,X,X,,+^X*X^+,,X^^X,,,,,X.% D:%.X^X^X^X^XXXX^.&.^XXXX^^X,X,X,X.% D:%.X^X+X+X+X,,+^X*X^+,,X^^X,,,,,X.% D:%.X^X^^^^^XXXX^...^XXXX^^X,X,X,X.% D:%.X^X*X,X*X,,X^X*X^X,,X^^X,,,,,X.% D:%.X^+^^^^^+^^+^^^^^+^^+^^X,,,,,X.% D:%.XXXXXXXXXXXXXX+XXXXXXXXXXX+XXX.% D:%................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:74:Lesser vault (edfu) X:7:5:15:15 D:%%%%%%%%%%%%%%% D:%.............% D:%.###########.% D:%.#,+^#,#^+,#.% D:%.###+#+#+###.% D:%.#,+^...^+,#.% D:%.###.###.###.% D:%.#,+.#*#.+,#.% D:%.###.#,#.###.% D:%.#,+.#^#.#,#.% D:%.###^...^#+#.% D:%.#,+,#+#,+,#.% D:%.#####^#####.% D:%.............% D:%%%%%%%%%%%%%%% N:75:Greater vault (kom ombo) X:8:40:36:30 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X****X,99,X9889X,99,X****X.% D:%.X****X,,,,X9999X,,,,X****X.% D:%.X+XXXX+XXXX+XXXX+XXXX+XXXX.% D:%.X@^^^^^^^^^^^^^^^^^^^^^^@X.% D:%.X^XXXXXXXXXXXXXXXXXXXXXX^X.% D:%.X^X**X,,X,,X,,X,,X,,X**X^X.% D:%.X^X,,X+XX+XX+XXX+XX+X,,X^X.% D:%.X^X,^+^^^^^^^^^^^^^^+^,X^X.% D:%.X^XXXX^XX+XX^^XX+XX^XXXX^X.% D:%.X^X,,X^X,,,X^^X,,,X^+^,X^X.% D:%.X^X,,X^X***X^^X***X^X,*X^X.% D:%.X^X,,X^X9X9X^^X9X9X^XXXX^X.% D:%.X^X,,X^X***X^^X***X^+^,X^X.% D:%.X^X++X^X,,,X^^X,,,X^X,*X^X.% D:%.X^X^^X^XX+XX^^XX+XX^XXXX^X.% D:%.X^X^^+^^^^^^^^^^^^^^X,*X^X.% D:%.X^X,,X^^^^^^^^^^^^^^+^,X^X.% D:%.X^XXXXXXX+XXXXXX+XXXXXXX^X.% D:%.X^X,X,X,,,,,XX,,,,,X***X^X.% D:%.X^X,X^X,***,++,***,+*@*X^X.% D:%.X^X,+^+,,,,,XX,,,,,X***X^X.% D:%.X^XXX+XXX+XXXXXX+XXXX+XX^X.% D:%.X^X*,^X,,,,,XX,,,,,+^^*X^X.% D:%.X^X,,^+,,*,,++,,*,,XX+XX^X.% D:%.X^X*,*X,,,,,XX,,,,,X,,,X^X.% D:%.X^XXXXXXX+XXXXXX+XXXXXXX^X.% D:%.X^X^^^^^^^^^^^^^^^^^^^^X^X.% D:%.X^X^^XX,XX^^XX^^XX,XX^^X^X.% D:%.X^X^^^^^^^^^^^^^^^^^^^^X^X.% D:%.X^+^^XX,XX^^XX^^XX,XX^^+^X.% D:%.X,X^^^^^^^^^^^^^^^^^^^^X,X.% D:%.XXXXXXXXX+XXXXXX+XXXXXXXXX.% D:%............................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:76:Lesser vault (belvoir keep) X:7:5:19:21 D:%%%%%%%%%%%%%%%%%%%%% D:%...................% D:%.###...........###.% D:%.#,######+######,#.% D:%.##+^^^^+&+^^^^+##.% D:%..#&^####+####^.#..% D:%..#.^#,^+^+,,#^.#..% D:%..#.^#,^#^#,,#^.#..% D:%..#.^#,*#^##+#^.#..% D:%..#.^#,^#^#,,#^&#..% D:%..#.^#,^+^#*,#^.#..% D:%..#.^####+####^.#..% D:%.##+^^^^^^^^^^^+##.% D:%.#,######+######,#.% D:%.###...#,*,#...###.% D:%.......#*,*#.......% D:%.......#####.......% D:%...................% D:%%%%%%%%%%%%%%%%%%%%% #N:77:Lesser vault (Pattern) #X:8:30:31:47 #D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% #D:%X@&+.............................+&@X,,,,,,X.% #D:%XXXX.p...bad.bad.bad.bad.cbb.....XXXX,,,,,,X.% #D:%X@&X.a.dcb.dcb.dcb.dcb.dcc.baa...X&@X,,,,,,X.% #D:%XX+X.b.d.....................ad..X+XX,,,,,,X.% #D:%X....c.a.dabcdabcda...........dc....X,,,,,,X.% #D:%X....d.b.d........a..cbadcba...c....X,,,,,,X.% #D:%X...ad.c.c.dcbadcba..c.....ad..cb...X++XXX+X.% #D:%X...a..d.b.d.........cdabc..d...b...X^^X^^^X.% #D:%X...b.ad.a.a..abcd.......cd.dcb.a...X**X^X+X.% #D:%X..cb.a..d.b..a..d..adcb..d...b.ad..X,,X^X^X.% #D:%X..c..b..c.c..d.ad..a..ba.a...a..d..X&&X^X&X.% #D:%X.dc.cb..b.d..c.a..PPP..a.a.cda..dc.X^^X^X+X.% #D:%X.d..c...a.a..b.b.PPAPP.d.b.c.....c.+^^X^X*X.% #D:%X.da.cd..d.b..a.c.PABAP.c.b.cba..bc.X^^X^X*X.% #D:%X..a..d..c.c..d.d.PPAPP.b.c...a..b..X&&X^XXX.% #D:%X..ab.da.b.d..c.a..PPP..a.c...d.ab..X,,X^X,X.% #D:%X...b..a.a.a..b.ab.....da.d..cd.a...XXXX+X+X.% #D:%X...c..b.d.b..a..bcd.bcd..a.bc..d...X**^^^,X.% #D:%X...cd.bcd.c..ad...dab...ba.b..cd...X,,,,,,X.% #D:%X....d.....d...dc......dcb..a..c....X,,,XXXX.% #D:%X....da....da...cbadcbad...da.bc....X,,,+,,X.% #D:%X.....a.....abc...........cd..b.....X,,,X,,X.% #D:%XX+X..ab......cdabcdabcdabc..ab..X+XXXXXX,,X.% #D:%X@&X...bc...................da...X&@X,,,,,,X.% #D:%XXXX....cddaabbccddaabbcdabcd....XXXX,,,,,&+.% #D:%X@&+.............................+&@X****&&+.% #D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX++X.% #D:%.............................................% #D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # # #N:78:Greater vault (Pattern 2) #X:8:30:29:45 #D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% #D:%X8+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+8X% #D:%X+XXXXXXXXXXXXXXXXXXX+XXXXXXXXXXXXXXXXXXX+X% #D:%X^X.....................................X^X% #D:%X^X.................p...................X^X% #D:%X^X.........adcbadcba.dcbadcbad.........X^X% #D:%X@X......dcba.........d.......dcba......X@X% #D:%X,X...baad.....abcdab.dabcda.....addc...X,X% #D:%X,X..cb.....bcda....b......abcd.....cb..X,X% #D:%X,X.dc....dab....adcb.adcb....dab....ba.X,X% #D:%X,X.d....cd....cba....a..bad....bc....a.X,X% #D:%X,X.a...bc...adc...PPPPP...dcb...cd...d.X,X% #D:%X,X.b...b....a....PPPAPPP....b....d...c.X,X% #D:%X,X.c...a....b....PPABAPP....a....a...c.X,X% #D:%X,X.d...d....c....PPPAPPP....d....b...b.X,X% #D:%X,X.a...dc...cda...PPPPP...bcd...cb...b.X,X% #D:%X,X.b....cb....abc.......dab....dc....a.X,X% #D:%X,X.bc....bad....cddaabbcd....bad....da.X,X% #D:%X,X..cd.....dcba...........adcb.....cd..X,X% #D:%X,X...dabc.....adcbadcbadcba.....dabc...X,X% #D:%X^X......cdab.................abcd......X^X% #D:%X^X.........bccddaabcdabcdabcda.........X^X% #D:%X^X.....................................X^X% #D:%X+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+X% #D:%X9+^^^@,,,,,&,,,,,,,,&,,,,,,,&,,,,,,@^^^+9X% #D:%XXXXXXXXXXXXXXXXXXXXX+XXXXXXXXXXXXXXXXXXXXX% #D:%...........................................% #D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # # # #N:79:Greater vault (Pattern 2) #X:8:30:30:42 #D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% #D:%.X9+^^^^^^^^^^^^^^^^^+,,,,,,,,,,,,,,,+8X% #D:%.X+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+X% #D:%.X,X.................................X^X% #D:%.X,X....adcbadcbadcbadcbadcbadc......X^X% #D:%.X,X...ba.....................cbad...X^X% #D:%.X,X..cb..bad.bad.bad.bad.bad....d...X^X% #D:%.X,X..c..cb.dcb.dcb.dcb.dcb.dcba.dc..X^X% #D:%.X&X..d.dc.....................a..c..X^X% #D:%.X&X..d.d..bbcc...cbadcba..adc.ad.b..X^X% #D:%.X+X..a.a.ab..cd.dc.....ad.a.c..d.a..X+X% #D:%.X^X..a.b.a....d.d..PPP..d.b.c.cd.d..X@X% #D:%&X^X..b.c.ad...a.a.PPAPP.c.c.b.c..dc.X9X% #D:%.+^X..b.d..dc..a.b.PABAP.b.d.b.cb..c.+8X% #D:%&X^X..c.a...cb.b.c.PPAPP.a.a.a..b..b.X9X% #D:%.X^X..d.b....b.c.d..PPP..d.b.d.ab..a.X@X% #D:%.X+X..a.c.cdab.d.da..d...dcb.d.a..da.X+X% #D:%.X&X..b.d.c....a..abcd.......c.ad.d..X^X% #D:%.X&X..c.a.cbad.ab......abc..bc..d.c..X^X% #D:%.X,X..d.b....d..bcdabcda.cdab..cd.b..X^X% #D:%.X,X..a.bcda.c................bc..a..X^X% #D:%.X,X..b....abc..dab.dab.dab.dab..da..X^X% #D:%.X,X..bcda.....cd.bcd.bcd.bcd...cd...X^X% #D:%.X,X.....abcdabc..............pbc....X^X% #D:%.X,X.................................X^X% #D:%.X+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+X% #D:%.X9+^^^^^^^^^^^^^^^^^+,,,,,,,,,,,,,,,+8X% #D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% #D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # XXX # XXX N:82:Lesser vault (checker.oard) X:7:5:13:21 D:%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXX% D:%X # # # #&+% D:%X#XXXXXXXXXXXXXXXXX% D:%X9# # # # X% D:%XXXXXXXXXXXXXXXXX#X% D:%X #𕬸# #&X% D:%X#XXXXXXXXXXXXXXXXX% D:%X9# # # # X% D:%XXXXXXXXXXXXXXXXX#X% D:%+ # # # #&X% D:%XXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%% N:83:Lesser vault (spiral checkers) X:7:5:14:17 D:%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXX% D:%X # # #&X% D:%+XXXXXXXXXXXX#X% D:%XXX@#9#@#9#@X9X% D:%X9#XXXXXXXX#X#X% D:%X#XXX98X89#9X&X% D:%X&X9#98X89XXX#X% D:%X#X#XXXXXXXX#9X% D:%X9X@#9#@#9#@XXX% D:%X#XXXXXXXXXXXX+% D:%X # # #&X% D:%XXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%% N:84:Greater vault (monstrosity) X:8:25:17:28 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X^@^@^@^@^@#X9X9X9X9X9X9XX% D:%X#XXXXXXXXXX9X9X9X9X9X9X9X% D:%XX9X9X9X9XXXXXXXXXXXXXXX#X% D:%X9X9X9X9X9X##############X% D:%XXXXXXXXX#X#XXXXXXXXXXXXXX% D:%X&,&X&,&X&X8888X&,&X&,&X&+% D:%X,X,X,X,X,XXXXXX,X,X,X,X,X% D:%+&X&,&X&,&X8888X&X&,&X&,&X% D:%XXXXXXXXXXXXXX#X#XXXXXXXXX% D:%X##############X9X9X9X9X9X% D:%X#XXXXXXXXXXXXXXX9X9X9X9XX% D:%X9X9X9X9X9X9X9XXXXXXXXXX#X% D:%XX9X9X9X9X9X9X#@^@^@^@^@^X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:85:Cyclone X:8:40:23:91 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%XXXX^^^^^^^^^XXX^^^^^^^^^XXX^^^#XXX8.X.&.X.&.X..*X+^.^.^.^.^.^..XX*^.^.^.^.^.^.^.^.^.^#8X% D:%XX***XXX...XXX...XXX...XXX...XXX^^X*.X^X^X^X^X^X.*XXXXXXXXXXXXX..XX^^XXXXXXXXXXXXXXXXXX#X% D:%X88XXX...XXX...XXX...XXX...XXX^^^,X*.X^X^X^X^X^X..*XX8@,,,,,,@XX,.XX^^..........@&.,**X.X% D:%XXXX@&@XXX@@@XXX&&&XXX&@&XXX^^^,..X*.X^X^X^X^X^X...@X@........@X,..X...........@&..,**X.X% D:%XX...XXX...XXX...XXX...XXX^^^,....X*.X^X^X^X^X^X...@X*..*9*..@XX^^XXXX*.......@&@..,**X.X% D:%X*.XXX...XXX...XXX...XXX^^^^....,,X*.&.X.&.X.&.X..*XX*.....,XXX.XXX@@XXX*....@&..@.,**X.X% D:%X*XX...XXX...XXX...XXX^^^,.^...XX+XXXXXXXXXXXXXX.*XX*....,,XXX.XXXXXX&&XXX*.@&....@8**X.X% D:%X^^^^XXX^^^^^^^^^XXX^^^,..*^.&XX.*X&^^*****^^#X.*XX*....,XXX&&XXX@@X#X*..XX@&.....8@**X.X% D:%XXXXXXXXXXXXXXXXXX^^^,...**^.&X8.*X@XXXXXXXXXX^.XX&....XXX&&XXX*****XXX*..XXXXXXXXXXXXX.X% D:%#^^^^^^^^^^^^^9#^^^.....*99^.@X8.*#^^^*****8XXXXX8@..XX#@@XX#@@@....8XXX*.+^.^.^.^.^.^+.X% D:%XXXXXXXXXXXXXXXXXX^^^,...**^.&X8.*X@XXXXXXXXXX^.XX&....XXX&&XXX*****XXX*..XXXXXXXXXXXXX.X% D:%X^^^^XXX^^^^^^^^^XXX^^^,..*^.&XX.*X&^^*****^^#X.*XX*....,XXX&&XXX@@X#X*..XX@&.....8@**X.X% D:%X*XX...XXX...XXX...XXX^^^,.^...XX+XXXXXXXXXXXXXX.*XX*....,,XXX.XXXXXX&&XXX*.@&....@8**X.X% D:%X*.XXX...XXX...XXX...XXX^^^^....,,X*.&.X.&.X.&.X..*XX*.....,XXX.XXX@@XXX*....@&..@.,**X.X% D:%XX...XXX...XXX...XXX...XXX^^^,....X*.X^X^X^X^X^X...@X*..*9*..@XX^^XXXX*.......@&@..,**X.X% D:%XXXX@&@XXX@@@XXX&&&XXX&@&XXX^^^,..X*.X^X^X^X^X^X...@X@........@X,..X...........@&..,**X.X% D:%X88XXX...XXX...XXX...XXX...XXX^^^,X*.X^X^X^X^X^X..*XX8@,,,,,,@XX,.XX^^..........@&.,**X.X% D:%XX***XXX...XXX...XXX...XXX...XXX^^X*.X^X^X^X^X^X.*XXXXXXXXXXXXX..XX^^XXXXXXXXXXXXXXXXXX#X% D:%XXXX^^^^^^^^^XXX^^^^^^^^^XXX^^^#XXX8.X.&.X.&.X..*X+^.^.^.^.^.^..XX*^.^.^.^.^.^.^.^.^.^#8X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:86:Miniature Cell X:7:5:5:5 D:%%%%% D:%#8#% D:%888% D:%#8#% D:%%%%% N:87:Castle Death X:8:35:20:60 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+XX....+XX...X****X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....XXX....@X****X% D:%X.........................................XXX....&.@X****X% D:%X+XXXXX+XXXXX+XXXXX+XXXXX+XXXXX+XXXXX+XXXXX....@.&.@X*99*X% D:%X999X..9..X&&&&&X,,,,,X@@@@@X..&..X@@@XXX....&.@.&.@X*99*X% D:%X@@@X.&.&.X&&&&&X,,,,,X@@@@@X99.99X9XXX.X..@.&.@.&.@X****X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...X..@.&.@.&.@XX##XX% D:%+^...&.&.&+...@.@.@+...@@@@@+.....99+...+..@.&.@.&.8+^^^^X% D:%+^...&.&.&+...@.@.@+...@@@@@+.....99+...+..@.&.@.&.8+^^^^X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX...X..@.&.@.&.@XX##XX% D:%X@@@X.&.&.X&&&&&X,,,,,X@@@@@X99.99X9XXX.X..@.&.@.&.@X****X% D:%X999X..9..X&&&&&X,,,,,X@@@@@X..&..X@@@XXX....&.@.&.@X*99*X% D:%X+XXXXX+XXXXX+XXXXX+XXXXX+XXXXX+XXXXX+XXXXX....@.&.@X*99*X% D:%X.........................................XXX....&.@X****X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX....XXX....@X****X% D:%X,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+XX....+XX...X****X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:88:Mirrored Quartet X:8:20:21:49 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X89@@@XXX,,,,XXX....^^^^^^^....XXX,,,,XXX@@@98X% D:%X9@@#XX....XXX**....XXX#XXX....**XXX....XX#@@9X% D:%X@XXX&&&&XXX**....@XX&&@&&XX@....**XXX&&&&XXX@X% D:%XXX....XXX**......@X**...**X@......**XXX....XXX% D:%X@...XXX**.......XXXXX...XXXXX.......**XXX...@X% D:%X@.#XX**.......9XX888XX^XX888XX9.......**XX#.@X% D:%XXXX&&&&&&&&&&&9#,,,,,X^X,,,,,#9&&&&&&&&&&&XXXX% D:%XXXXXXXXXXXXXXXXXXXXXXX#XXXXXXXXXXXXXXXXXXXXXXX% D:%%,,,,,,,,,,,,,,,,,,,,,#8#,,,,,,,,,,,,,,,,,,,,,%% D:%XXXXXXXXXXXXXXXXXXXXXXX#XXXXXXXXXXXXXXXXXXXXXXX% D:%XXXX&&&&&&&&&&&9#,,,,,X^X,,,,,#9&&&&&&&&&&&XXXX% D:%X@.#XX**.......9XX888XX^XX888XX9.......**XX#.@X% D:%X@...XXX**.......XXXXX...XXXXX.......**XXX...@X% D:%XXX....XXX**......@X**...**X@......**XXX....XXX% D:%X@XXX&&&&XXX**....@XX&&@&&XX@....**XXX&&&&XXX@X% D:%X9@@#XX....XXX**....XXX#XXX....**XXX....XX#@@9X% D:%X89@@@XXX,,,,XXX**..^^^^^^^..**XXX,,,,XXX@@@98X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:89:False Wall X:8:20:15:64 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%X+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+X% D:%X^+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^+^X% D:%X^XXXXXXXXXXXXXXXXXXXXXXXXXX+X##X+XXXXXXXXXXXXXXXXXXXXXXXXXX^X% D:%X^+@*&*@*&*@*&*@*&*@*&*@*&*@*X@@X*@*&*@*&*@*&*@*&*@*&*@*&*@+^X% D:%X^XXXXXXXXXXXXXXXXXXXXXXXXX+XX,,XX+XXXXXXXXXXXXXXXXXXXXXXXXX^X% D:%X^+&.@.&.@.&.@.&.@.&.@.&.@.&X*..*X&.@.&.@.&.@.&.@.&.@.&.@.&+^X% D:%X^XXXXXXXXXXXXXXXXXXXXXXXX+XX*..*XX+XXXXXXXXXXXXXXXXXXXXXXXX^X% D:%X^+,,,,,,,,,,,,,,,,,,,,,,,,X,,..,,X,,,,,,,,,,,,,,,,,,,,,,,,+^X% D:%X^XXXXXXXXXXXXXXXXXXXXXXX+XX##99##XX+XXXXXXXXXXXXXXXXXXXXXXX^X% D:%X^+&.@.&.@.&.@.&.@.&.@.&.@X..####..X@.&.@.&.@.&.@.&.@.&.@.&+^X% D:%X^XXXXXXXXXXXXXXXXXXXXXX+XX...##...XX+XXXXXXXXXXXXXXXXXXXXXX^X% D:%X^+*&*@*&*@*&*@*&*@*&*@*&X&@&@88&@&@X&*@*&*@*&*@*&*@*&*@*&*+^X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:90:Hellpit X:8:20:19:60 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%..........................................................% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X@@&....#8.#9....^^&&&&&&&&&&&&###.^^,,......+8*9+,,,,,X.% D:%.X@&@.............^^................^^,,......+9*9+,,,,,X.% D:%.X&@@.............^^@@@@@@@@@@@###..^^,,......+9*9+,,,,,X.% D:%.X.....#8....#9...^^................^^,,......+9*9+,,,,,X.% D:%.X................^^&&&&&&&&&&&&###.^^,,.&&&&&+9*9+,,,,,X.% D:%.X.......@@@@.....^^................^^,,.&@@@&+9*9+,,,,,X.% D:%.#....#8.@@@@.#9..^^@@@@@@@@@@@###..^^,,.&@9@&+8*9+,,,,,X.% D:%.X.......@@@@.....^^................^^,,.&@@@&+9*9+,,,,,X.% D:%.X................^^&&&&&&&&&&&&###.^^,,.&&&&&+9*9+,,,,,X.% D:%.X.....#8....#9...^^................^^,,......+9*9+,,,,,X.% D:%.X&@@.............^^@@@@@@@@@@@###..^^,,......+9*9+,,,,,X.% D:%.X@&@.............^^................^^,,......+9*9+,,,,,X.% D:%.X@@&....#8.#9....^^&&&&&&&&&&&&###.^^,,......+8*9+,,,,,X.% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%..........................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:91:Roundabout Three X:8:30:20:97 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X,&,,,,,,,,,,,^^^^^^^^^^......XX.#X.XXX.......X.X.......XXX.X#.XX......^^^^^^^^^^,,,,,,,,,,,&,X% D:%X,&,,,,,,,,,,,^^^^^^^^^^.....XX.XX.XXX..XXXX..X.X..XXXX..XXX.XX.XX.....^^^^^^^^^^,,,,,,,,,,,&,X% D:%X,&,,,,,,,,,,,XXXXXXXXXX....XX.XX.XXX^^XX@@XX.X&X.XX@@XX^^XXX.XX.XX....XXXXXXXXXX,,,,,,,,,,,&,X% D:%X,&&&&&&&&&&XXX********XXX..XX.XX.XXX^^X****X.X&X.X****X^^XXX.XX.XX..XXX********XXX&&&&&&&&&&,X% D:%X,,,,,,,,,,XXX..XXXXXX...XX+XX.XX.XXX^^XX&&...X@X...&&XX^^XXX.XX.XX+XX...XXXXXX..XXX,,,,,,,,,,X% D:%X@@@@@@@@XXX..XXX****XXX.....XX.XX.XXX..XX...XX+XX...XX..XXX.XX.XX.....XXX****XXX..XXX@@@@@@@@X% D:%X9988899XXX..XXX.XXXX@@XXXXXX.XX.XX.XXX..XXXXX^^^XXXXX..XXX.XX.XX.XXXXXX@@XXXX.XXX..XXX9998999X% D:%X######XXX**X##&&@**XX&&&@98X^^^^^XX.##X^^^^^^^^^^^^^^^X##.XX^^^^^X89@&&&XX**@&&##X**XXX######X% D:%X######XXX**X##&&@**XX&&&@98X^^^^^XX.##X^^^^^^^^^^^^^^^X##.XX^^^^^X89@&&&XX**@&&##X**XXX######X% D:%X9988899XXX..XXX.XXXX@@XXXXXX.XX.XX.XXX..XXXXX^^^XXXXX..XXX.XX.XX.XXXXXX@@XXXX.XXX..XXX9998999X% D:%X@@@@@@@@XXX..XXX****XXX.....XX.XX.XXX..XX...XX+XX...XX..XXX.XX.XX.....XXX****XXX..XXX@@@@@@@@X% D:%X,,,,,,,,,,XXX..XXXXXX...XX+XX.XX.XXX^^XX&&...X@X...&&XX^^XXX.XX.XX+XX...XXXXXX..XXX,,,,,,,,,,X% D:%X,&&&&&&&&&&XXX********XXX..XX.XX.XXX^^X****X.X&X.X****X^^XXX.XX.XX..XXX********XXX&&&&&&&&&&,X% D:%X,&,,,,,,,,,,,XXXXXXXXXX....XX.XX.XXX^^XX@@XX.X&X.XX@@XX^^XXX.XX.XX....XXXXXXXXXX,,,,,,,,,,,&,X% D:%X,&,,,,,,,,,,,^^^^^^^^^^.....XX.XX.XXX..XXXX..X.X..XXXX..XXX.XX.XX.....^^^^^^^^^^,,,,,,,,,,,&,X% D:%X,&,,,,,,,,,,,^^^^^^^^^^......XX.#X.XXX.......X.X.......XXX.X#.XX......^^^^^^^^^^,,,,,,,,,,,&,X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:92:The Reward is Worth It X:8:20:16:63 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXX##XXXXXXXXXXXXX#XXXXXXXXXXXXX##XXXXXXXXXXXXXXX% D:%X@@@@@@@@@@@.XX88XX.......,,,X^X,,,.......XX88XX.@@@@@@@@@@@X% D:%X@XXXXXXXXXX..XXXX...XXXX.,,,X^X,,,.XXXX...XXXX..XXXXXXXXXX@X% D:%X@X8888888XXX..XX...XXX@XX,,,X^X,,,XX@XXX...XX..XXX8888888X@X% D:%X@X88899999XXX.....XXX@@@X..&X^X&..X@@@XXX.....XXX99999888X@X% D:%X@X8899.....XXX...XXX@@@@@..&X^X&..@@@@@XXX...XXX.....9988X@X% D:%X@X899.......XXX...XXX......&X^X&......XXX...XXX.......998X@X% D:%X+XXX...XXX&&&XXX^^^XXX.....&X^X&.....XXX^^^XXX&&&XXX...XXX+X% D:%X@@XXX.XXXX&&&&XXX^^^XXX....&X^X&....XXX^^^XXX&&&&XXXX.XXX@@X% D:%X^^^^XXX88X^^^^^^XXX^^^XXX..&X^X&..XXX^^^XXX^^^^^^X88XXX^^^^X% D:%X&&&&&&&&XX^^^^^^^^XXX...XXX&X^X&XXX...XXX^^^^^^^^XX&&&&&&&&X% D:%X,,,,,,,XX,,,,,,,,,,,XXX&&&XXX^XXX&&&XXX,,,,,,,,,,,XX,,,,,,,X% D:%X,,,,,,X#@@@@@@@@@@@@@@XXX&&&&&&&&&XXX@@@@@@@@@@@@@@#X,,,,,,X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:93:Little League Treasure Hoard X:7:2:5:19 D:%%%%%%%%%%%%%%%%%%% D:%....#...&...#....% D:%.#.#.##***##.#.#.% D:%....#...&...#....% D:%%%%%%%%%%%%%%%%%%% N:94:Mini Maze X:7:2:15:25 D:%%%%%%%%%%%%%%%%%%%%%%%%% D:%.......................% D:%.X+XXXXXXXXXXXXXXXXXXX.% D:%.X.X,.......X........X.% D:%.X.X..XXX.X...XXXX.X.X.% D:%.X.XX.X...X.XXX..X...X.% D:%.X......X.X.X....XXX.X.% D:%.X.XXXXX..X.X.X..X,X.X.% D:%.X.X,..XXXX.X.X.XX.X.X.% D:%.X.XXX........X...XX.X.% D:%.X...XXXXXX.XXXXXXX..X.% D:%.X.X........X,.......X.% D:%.XXXXXXXXXXXXXXXXXXXXX.% D:%.......................% D:%%%%%%%%%%%%%%%%%%%%%%%%% N:95:Circlular Room X:7:2:8:9 D:%%%%%%%%% D:%.......% D:%..###..% D:%.#+*+#.% D:%.#+*+#.% D:%..###..% D:%.......% D:%%%%%%%%% N:96:Minor Boss Vault X:7:3:10:10 D:%%%%%%%%%% D:%........% D:%..XXXX..% D:%.XX.9XX.% D:%.X....X.% D:%.XX++XX.% D:%.XX^^XX.% D:%..X++X..% D:%........% D:%%%%%%%%%% N:97:(Lesser) Major Boss Vault X:7:20:10:10 D:%%%%%%%%%% D:%........% D:%..XXXX..% D:%.XX.8XX.% D:%.X....X.% D:%.XX++XX.% D:%.XX^^XX.% D:%..X++X..% D:%........% D:%%%%%%%%%% N:98:(Greater) Majorly Bossy Vault X:8:37:10:10 D:%%%%%%%%%% D:%........% D:%.@XXXX@.% D:%.XX88XX.% D:%.X8888X.% D:%.XX++XX.% D:%.XX^^XX.% D:%.@X++X@.% D:%........% D:%%%%%%%%%% N:99:Bubbles X:8:35:25:41 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXX#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X8X#X8XXX8XXX8XXX8XXX8XXX8XXX8XXX8XXX8X% D:%XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.#XX% D:%XX.9.#.9.X.9.#.9.X.9.#.9.X.9.#.9.#.9.XX% D:%XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX% D:%X8XXX8X#X8X#X8X#X8X#X8X#X8X#X8X#X8X#X8X% D:%XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.#XX% D:%XX.9.#.9.X.9.X.9.#.9.X.9.#.9.X.9.X.9..X% D:%XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX% D:%X8X#X8XXX8X#X8XXX8XXX8XXX8XXX8XXX8X#X8X% D:%XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.#XX% D:%XX.9.X.9.#.9.X.9.#.9.#.9.#.9.#.9.X.9.XX% D:%XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX% D:%X8X#X8X#X8X#X8XXX8XXX8XXX8XXX8X#X8X#X8X% D:%XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.#XX% D:%XX.9.#.9.X.9.#.9.#.9.#.9.#.9.#.9.X.9.XX% D:%XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX.XXX% D:%X8XXX8XXX8XXX8XXX8XXX8XXX8XXX8XXX8X#X8X% D:%XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.#XX% D:%##.9.#.9.#.9.#.9.#.9.#.9.#.9.#.9.X.9.XX% D:%XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.XX#.#XX% D:%X8XXX8XXX8XXX8XXX8XXX8XXX8XXX8XXX8XXX8X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:100:Lesser Vault (Cross) X:7:10:13:20 D:%%%%%%%%%%%%%%%%%%%% D:%########++########% D:%#*....*#..#*....*#% D:%#....&,#^^#,&....#% D:%#....,##..##,....#% D:%#+#####*..*#####+#% D:%#^^.....,,.....^^#% D:%#+#####*..*#####+#% D:%#....,##..##,....#% D:%#....&,#^^#,&....#% D:%#*....*#..#*....*#% D:%########++########% D:%%%%%%%%%%%%%%%%%%%% N:101:The I in the Storm X:8:30:25:41 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXX#XXXXXXXXXXXXXXXXXXX% D:%X&&..^..#9X..^^^^^^^^^^^^^..X9#..^..&&X% D:%X&...#....X..XXXXXX^XXXXXX..X....#...&X% D:%X...&#..#.X9XX.@8XX^XX8@.XX9X.#..#&...X% D:%X..&9#....XXX...@X,,,X@...XXX....#9&..X% D:%X^####..#...XX..XX,.,XX..XX...#..####^X% D:%X........,#..XX^X,,.,,X^XX..#,........X% D:%X.......#.....^XX,...,XX^.....#.......X% D:%X........,#...9X,,...,,X9...#,........X% D:%X.......#.....XX.......XX.....#.......X% D:%X.#......,#..XX^.......^XX..#,......#.X% D:%X.9#....#....#^^...9...^^#....#....#9.X% D:%X.#......,#..XX^.......^XX..#,......#.X% D:%X.......#.....XX.......XX.....#.......X% D:%X........,#...9X,,...,,X9...#,........X% D:%X.......#.....^XX,...,XX^.....#.......X% D:%X........,#..XX^X,,.,,X^XX..#,........X% D:%X^####..#...XX..XX,.,XX..XX...#..####^X% D:%X..&9#....XXX...@X,,,X@...XXX....#9&..X% D:%X...&#..#.X9XX.@8XX^XX8@.XX9X.#..#&...X% D:%X&...#....X&&XXXXXX^XXXXXX&&X....#...&X% D:%X&&..^..#9X..^^^^^^^^^^^^^..X9#..^..&&X% D:%XXXXXXXXXXXXXXXXXXX#XXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:102:Roundabout Two X:8:30:25:40 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%#^X.^^+X@XX.+X^^^^^+.X...X8#@&*X*****X% D:%X^X.^XX@XX.XX^^^^^^X.X.X^XXX@.&+9....X% D:%X^X.XX&XX.XX^^^^^^^X.X.X^X8#@&*X99...X% D:%X^X.X^^X&.XXXXXXXXXX.X.X^XXXXXXXXXX++X% D:%X^X.X.*X&.X.......&..X.X^X........X^^X% D:%X^X&X.*X^^X.XXXXXXXXXX.X&X#XXXXXX.X^.X% D:%X^X.X..X^^X...@........X.X......X.X^^X% D:%X^X.X..X^^XXXXXXXXXXXXXX.XXXXXX.X.X.^X% D:%X^X.X..X^^X..,.....,....&X8#,*X.X.X^^X% D:%X^X&X,,X^^X^XXXXXXXXXXXXXX##,,X.X.X^.X% D:%X^+&X..+^^X^^^^^^^^^^^^^^^9...#.X.#^^X% D:%X^X&X,,X^^X^XXXXXXXXXXXXXX##,*X.X.X.^X% D:%X^X.X..X^^X..,.....,....&X8#,,X.X.X^^X% D:%X^X.X..X^^XXXXXXXXXXXXXX.XXXXXX.X.X^.X% D:%X^X.X..X^^X...@........X.X......X.X^^X% D:%X^X&X.*X^^X.XXXXXXXXXX.X&X#XXXXXX.X.^X% D:%X^X.X.*X&.X.......&..X.X^X........X^^X% D:%X^X.X^^X&.XXXXXXXXXX.X.X^XXXXXXXXXX++X% D:%X^X.XX&XX.XX^^^^^^^X.X.X^X8#@&*X99...X% D:%X^X.^XX@XX.XX^^^^^^X.X.X^XXX@.&+9....X% D:%#^X.^^+X@XX.+X^^^^^+.X...X8#@&*X*****X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:103:Modified Greater Vault (Huge) X:8:45:17:39 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#X% D:%X8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8X.X% D:%X#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#X#X% D:%X8X8#8#8#8#8#8#8#8#8#8#8#8#8#8#8X8X.X% D:%X#X#XXXXXXXXXXXXXXXXXXXXXXXXXXX#X#X#X% D:%X8X8X8#8#8#8#8#8#8#8#8#8#8#8#8#8X8X.X% D:%X#X#X#XXXXXXXXXXXXXXXXXXXXXXXXXXX#X#X% D:%X8X8X8#8#8#8#8#8#8#8#8#8#8#8#8#8#8X.X% D:%X#X#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#X% D:%X8X8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#.X% D:%X#XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%X8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#8#% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% N:104:The Bank from Hell X:8:30:20:31 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%XXXXXXXXXXXXXX+XXXXXXXXXXXXXX% D:%X.&.&.&.&.&.#...#.&.&.&.&.&.X% D:%X.#.#.#.#.#.#...#.#.#.#.#.#.X% D:%X...........#...#...........X% D:%X##########+##+##+##########X% D:%X@........^^^^^^^^^........@X% D:%X@^^^.....^^^...^^^.....^^^@X% D:%X##+#######+#####+#######+##X% D:%X.^^^.#@..^^^...^^^..@#.^^^.X% D:%X#...##...............#.###.X% D:%X@...@#.&.&.&.&.&.&.&.#..@..X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXX+X% D:%X.+^*****X*******^+^******X.X% D:%X@X^....^X^......^X^.....*X@X% D:%X.X*****^+^*******X*******X.X% D:%X@XXXXXXXXXXXXXXXXXXXXXXXXX@X% D:%X.@.@.@.@.@.@.@.@.@.@.@.@.@.X% D:%XXXXXXXXXXXXXXXXXXXXXXXXXXXXX% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Between vaults from weisiger N:105:The Between Vault X:8:15:6:25 D:XXXXXXXXXXXXXXXXXXXXXXXXX D:#,,,,,X&...@X..**&X....9X D:#...&1X.,,,2X..**&X3...9X D:#...&.X1,,,.X2.**3X....9X D:#,,,,,X&...@X..**&X....9X D:XXXXXXXXXXXXXXXXXXXXXXXXX N:106:Greater Vault (Mix&Match) X:8:35:28:73 D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% D:%.......................................................................% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X1.^^^^*&XX,,,9,,,XX...X...X...X&..X@..X@.8X7X8#X8#X8#X8#X8#X8#X8#.7X.% D:%.X..^^^*,XX@&@&@&@&X.X...X...X..#X&..X&..X@.#XXX#8XX8XX8XX8XX8XX8XXXXX.% D:%.X^^^^*,XXXX.......X6.X...X...X.#.X&..X@..X@.8X8XXXXXXXXXXXXXXXXXX88XX.% D:%.X^^^*,XX&&XX.....XXXXXXXX.X...X#..X&.#X&..X@.XX#9#9#9#9X88XX^^XX#8XXX.% D:%.X^^*,X#^^^^XX^XXX.X***&@XXXX...X...X&#.X@..X@X8X9X9X9X9X8#X^^XX8#X#8X.% D:%.X^*,XX^^^^^^XX^XX5X***@&,,XXX...X...X#..X&..XX#X#X#X#X#XXX^^XX##XX88X.% D:%.X*,XX........XX^XXX***&@,,,,XXX..X..#X&..X@..X8X8X8X8X8XX^^XX88XXXXXX.% D:%.X&XX..........XX^XX***@&,,,,#.XXX.X.#.X&..X&.X#X#X#X#X#X^^X#8XXXX,#.X.% D:%.XXX************XX6X@&@&@,,,,#...XXXX#..X&.#X@X8X8X8X8X8#XXXXXX,,,,#.X.% D:%.XX&,&,&,&,&,&,&,XXXX@&@&,,,,#.....XXX...X&#.XX8X8X8X8X8XXXX,,,,,,,#.X.% D:%.XX#************XX.^#X,,,,,,,#.......XXXXXXXXXX8X8X8XXXXX@&#,,,,,,XX#X.% D:%.X^XX..........XXX.XXXX,,,,,,#................X8XXXXX&&#&@&#,,XXXXX#.X.% D:%.X.XXX........XX3X^X99XXXXXXXXXXXXXXX#XXXXXXX.XXXX,#&&&#&@&XXXX,#^X#.X.% D:%.X.XXXX......XXX.X.X@@,,,,,,,,,,,,X1X.......X.X,,,,#&&&#XXXX,,,,#^X.#X.% D:%.X^XXXXX....XXXX.^.XXXXXXXXXXXXXX*X^X+XXXXX.X.X,,,,#&&XXX##9,,,,#^X.#X.% D:%.X.X^^.XX@@XXXXXXXXX9@&,,,,,,,,,X*X.X^^&,,X.X.X#####XXX#9@##@,,,#^X#.X.% D:%.X.X^X.XXXXX^^^XXXXXXXXXXXXXXXX,X*X.X^^^,,X.X.X&&&XXX@8##&@##@,,#^X#.X.% D:%.X^X.X2XXXX3^^^XXX.^..^..^..^.X,X*X^X&^^^&X.X.X##XX5.@89##9@##&,#^#.#X.% D:%.X.X^XXXXXXXXX^^XX.XXXXXXXXXX.X,X*X.X..^^^X.X.X^XXXXXXXXXXXXXXXXXXXXXX.% D:%.X.X^^.^..^..X^^^X.^..^..^.4X^X,X*X.X2.&^^+.+.X.^.^.^.^.^.^.^.^.^.^.4X.% D:%.X^XXXXXXXXX^X^^^XXXXXXXXXXXX#X#X#X^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.X..^..^..^..X^^^#................X..^..^..^..^..^..^..^..^..^..^..^.+.% D:%.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.% D:%.......................................................................% D:%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Wilderness vault test N:107:The Wilderness Vault X:10:1:3:7 D:XXXXXXX D:T,,,,8X D:XXXXXXX tome-235-src/lib/edit/r_info.txt0000644000076400017500000174113111012107760014403 0ustar dgdg# File: r_info.txt # With new monsters for Zangband 2.2 (or 2.3) # With new monsters for PernAngband 3.x.x # With lots of monsters for PernAngband 4.x.x # With Spirits for ToME 2.1.x # This file is used to initialize the "lib/raw/r_info.raw" file, which is # used to initialize the "monster race" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/raw/r_info.raw" file. # PernAngband notes: # Currently, "unique" monsters are just "special" monster races, with # the requirement that only one monster of that race can exist at a time, # and when it is killed, it can never again be generated. # ATTR_CLEAR monsters acquire their attr from the item/floor below them, # and use "white" for the recall window. See "cave.c" for info. # ATTR_MULTI monsters have a "flickering" attr, and use "violet" for the # recall window. See "cave.c" for info. # CHAR_CLEAR monsters use special symbols (.) as given below, # and use those symbols for the recall window. In theory, normally, # these monsters cannot be targetted, and when examined look like normal # floors, until the player "notices" them (perhaps check "awake"). # CHAR_MULTI monsters use special symbols (!, ?, =) as given below, # and use those symbols for the recall window. In theory, normally, # these monsters cannot be targetted, and when examined look like normal # objects, until the player "notices" them (perhaps check "awake"). # Note that there are (a few) normal monsters who are "violet" but not # ATTR_MULTI, and a lot of monsters which are "white" but not ATTR_CLEAR. # Note that currently both CHAR_CLEAR and CHAR_MULTI monsters are treated # as normal monsters that are just a little hard to see. # Note that the monster list underwent several changes for Angband 2.7.9, # including some monster name changes, some symbol redistributions, and # some color changes. # The Umber Hulk joined the Xorn/Xaren (X). The ticks (t) joined the # spiders (S). The townspeople (t) left the people (p). The "Jabberwock" # became the "Chaos beetle" (K). The major demons (&) became (U) and the # minor demons (I) became (u). Multiplying insects (fleas, fruit flies, # hummerhorns) became (I), visually "matching" the multiplying lice (l). # The "ant lions" (a) became "ants" (a). The mummified monsters (M) # joined the zombified monsters (z). The multi-headed hydras (M) left # the reptiles (R). The snakes (J) left the reptiles (R). # Some of the old "red" or "brown" monsters became "pink" if they lower # strength, while some of the old "fire" monsters became simply "red" # monsters. The "dragons" and "hounds" and related monsters underwent # a "color scheme regularization" ('w' = White/Cold, 's' = Black/Acid, # 'o' = Lite/Dark, 'r' = Red/Fire, 'g' = Green/Poison, 'b' = Blue/Elec, # 'u' = Brown/Earth/Force, 'D' = Dark/etc, 'W' = Stone/Inertia/Gravity/etc, # 'v' = Multihued/Chaos/Disenchantment/etc, 'y' = Gold/Sound, 'R' = Nexus, # 'G' = Nether, 'B' = Left-overs, and 'U' = Bronze/Confusion). # In several situations, two or more monsters with identical symbols and # colors were changed so that maximal information is conveyed by the symbol # and color. # The "people" (p), with more than 50 entries, got a new "color scheme" # ('w' = Paladin, 's' = Knight, 'o' = Mystic, 'r' = Mage, 'g' = High Priest, # 'b' = Thief, 'u' = Warrior, 'D' = Death knight, 'W' = Ranger/Archer, # 'v' = Sorcerer, 'y' = Ninja, 'R' = High Mage, 'G' = Priest, 'B' = High # Thief, 'U' = High Warrior). Note that most non-unique "people" already # had these colors, or colors close to these colors. A similar color scheme # was enforced for the "humanoid" (h) monsters as well, more or less. # TY: This is no longer entirely accurate. The monster coloring has been # changed 'back' to pre-2.7.* coloring in several cases. For example, I # prefer "black" thief characters. Also color can be (and should) be used to # convey information, but more importantly it is a visual presentation # of the creature and should be what the creature "looks" like. # Many of the "unique" monsters were changed to "match" the "base" monster # from which they were derived. Angband 2.8.0 may require every "unique" # monster to be based on a "normal" monster, and may enforce color matching. # This may result in the addition of some new monsters, to serve as "base" # monsters, possibly including Ogre captains, Greater Balrogs, Black Trolls, # Vampire Queens, Giant Werewolves, and others. This may be accompanied by # a separation of the monster list into a "normal" monster list (r_info) # with 512 entries, and a "unique" monster list (u_info) with 128 entries, # which will require reorganization of the list. Some new "player ghost" # unique monsters will probably be added at the same time. # Mushrooms look just like food (and use the "," symbol for both the recall # window and for normal display), Creeping coins look just like coins (and # use the "$" symbol for both the recall window and for normal display), and # Trappers/Lurkers can never be seen (and use the "." symbol for the recall # window). All other monsters use "alphabetic" symbols, and "alphabetic" # symbols are used only for monsters. # The "0" and "9" symbols are reserved for internal debugging use. # The "&" symbol is reserved for future use as a special "terrain feature". # The "`" symbol is reserved as an "alternate" open door picture, since # the "'" symbol looks like the "," symbol in some fonts (esp. IBM). # The "x" symbol is free for use as an "attr/char mapping" for annoying # monsters, such as magic mushrooms, drolems, etc. # Certain symbols ("X", "Y", "B", "l", "I", etc) are used by # very few monsters, and could be reorganized somewhat. # There are still too many "p" monsters, perhaps they should be broken up. # As always, you can enforce any "visual picture" you want with a "pref file". ###### Understanding the entries ###### # N: serial number : monster name # G: symbol : color # I: speed : hit points : vision : armor class : alertness # W: depth : rarity : corpse weight : experience for kill # E: weapons : torso : arms : finger : head : leg # O: treasure : combat : magic : tool # B: attack method : attack effect : damage # F: flag | flag | etc # S: spell frequency | # S: spell type | spell type | etc # D: Description # 'N' indicates the beginning of an entry. The serial number must # increase for each new item. Entry 0 is used for the player. # 'G' is for graphics - symbol and color. There are 16 colors, as # follows: # D - Dark Gray w - White s - Gray o - Orange # r - Red g - Green b - Blue u - Brown # d - Black W - Light Gray v - Violet y - Yellow # R - Light Red G - Light Green B - Light Blue U - Light Brown # 'I' is for information - speed, health, vision in tens of feet, # armor class, and alertness. 110 is normal speed. Alertness ranges # from 0 (ever vigilant for intruders) to 255 (prefers to ignore # intruders). # 'W' is for more information - level, rarity, corpse weight (expressed # in deci-pounds) [19 deci-pounds seem to get added to these number # in practice], and experience for killing. # 'E' is for equipment slots - weapon slots, torso slots (the "on body" # and "about body" equipment slots), arm slots (expressed in number # of pairs), finger slots, head slots, and leg slots (expressed # in number of pairs). # 'O' is for object drop chances - % chance to drop treasure, % chance # to drop combat items, % chance to drop magic type items (not # items of good blessing), and % chance to drop tools. The four # percents added together must be equal to or less than 100. If # the percent is less than 100, that is the chance for the monster # to drop junk. # 'B' is for blows - method of attack, effect of attack, and damage # from attack. There may be up to four of these lines; effect and # damage are optional. # 'S' is for spells. The first S: line must be S:1_IN_X with X the # number of monster turns, on average, before the monster will cast # one of its spells. X must not be zero. # 'F' is for flags. These are fairly self-explanatory. As many F: # lines may be used as are needed to specify all the flags and flags # are separated by the '|' symbol. The '|' symbol must also be used # to end all but the last line. # 'D' is for description. As many D: lines may be used as are needed # to describe the monster. Note that lines may need spaces at their # ends to prevent words from running together in the monster memory. # Note that monster zero is used for the "player" picture. # Version stamp (required) V:2.2.0 ##### The Player ##### N:0:Player G:@:w E:1:1:1:2:1:1 O:0:0:0:0 ##### Town monsters ##### N:1:Filthy street urchin G:t:D I:110:1d4:4:1:40 W:0:2:1200:0 E:1:1:1:2:1:1 O:1:1:1:1 B:BEG:* B:TOUCH:EAT_GOLD F:MALE | EVIL | WILD_TOWN | WILD_ONLY | F:RAND_25 | FRIENDS | F:TAKE_ITEM | OPEN_DOOR | DROP_CORPSE | DROP_SKELETON | F:MORTAL | BASEANGBAND | HAS_LITE D:He looks squalid and thoroughly revolting. N:2:Scrawny cat G:f:U I:110:1d2:30:1:10 W:0:3:100:0 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d1 F:RAND_25 | WILD_TOO | WILD_GRASS | WILD_TOWN | WILD_ONLY | F:ANIMAL | DROP_CORPSE | DROP_SKELETON | F:MORTAL | BASEANGBAND D:A skinny little furball with sharp claws and a menacing look. N:3:Sparrow G:B:U I:110:1d1:30:1:10 W:0:3:90:0 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:1d1 F:RAND_25 | CAN_FLY | WILD_TOWN | WILD_ONLY | F:ANIMAL | DROP_SKELETON | HAS_EGG | IMPRESED | F:MORTAL | BASEANGBAND D:Utterly harmless, except when angry. N:4:Chaffinch G:B:r I:110:1d1:30:1:10 W:0:3:80:0 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:1d1 F:RAND_25 | CAN_FLY | WILD_ONLY | WILD_WOOD | WILD_GRASS | F:ANIMAL | DROP_SKELETON | HAS_EGG | IMPRESED | F:MORTAL | BASEANGBAND D:Utterly harmless, except when angry. N:5:Wild rabbit G:r:U I:110:1d2:30:1:10 W:0:3:100:0 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d1 F:RAND_50 | WILD_ONLY | WILD_GRASS | WILD_WOOD | F:ANIMAL | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND D:It is not a carnivore, but will defend itself if you stray too D:close. N:6:Woodsman G:t:g I:110:3d3:10:1:255 W:0:1:1000:0 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d6 F:MALE | WILD_ONLY | WILD_WOOD | F:RAND_25 | DROP_SKELETON | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | HAS_LITE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND D:He has a strong axe with a sharp edge. N:7:Scruffy little dog G:C:U I:110:1d3:20:1:5 W:0:3:300:0 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d1 F:RAND_25 | DROP_SKELETON | DROP_CORPSE | WILD_TOWN | WILD_ONLY | F:ANIMAL | MORTAL | BASEANGBAND D:A thin flea-ridden mutt, growling as you get close. N:8:Farmer Maggot G:h:w I:110:35d10:40:10:3 W:0:4:730:0 E:0:1:1:2:1:1 O:0:100:0:0 #B:MOAN:* #B:MOAN:* F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE | F:FORCE_MAXHP | WILD_TOWN | WILD_ONLY | NO_TARGET F:NEVER_MOVE F:OPEN_DOOR | BASH_DOOR | SPECIAL_GENE F:NEUTRAL | NO_DEATH F:MORTAL | BASEANGBAND | HAS_LITE D:He's lost his dogs. He's had his mushrooms stolen. He's not a happy D:hobbit! N:9:Blubbering idiot G:t:W I:110:1d2:6:1:0 W:0:1:1500:0 E:1:1:1:2:1:1 O:0:0:0:0 B:DROOL:* F:MALE | DROP_CORPSE | DROP_SKELETON | WILD_TOWN | WILD_ONLY | F:RAND_25 | DROP_1D2 | TAKE_ITEM | F:MORTAL | BASEANGBAND | HAS_LITE D:He tends to blubber a lot. N:10:Boil-covered wretch G:t:g I:110:1d2:6:1:0 W:0:1:1400:0 E:1:1:1:2:1:1 O:0:0:0:0 B:DROOL:* F:MALE | DROP_SKELETON | DROP_CORPSE | WILD_TOWN | WILD_ONLY | F:RAND_25 | DROP_1D2 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE D:Ugly doesn't begin to describe him. N:11:Village idiot G:t:G I:120:4d4:6:1:0 W:0:1:1400:0 E:1:1:1:2:1:1 O:0:0:0:0 B:DROOL:* F:MALE | DROP_CORPSE | DROP_SKELETON | WILD_TOWN | WILD_ONLY | F:RAND_25 | DROP_1D2 | TAKE_ITEM | F:MORTAL | BASEANGBAND | HAS_LITE D:Drooling and comical, but then, what do you expect? N:12:Pitiful-looking beggar G:t:U I:110:1d4:10:1:40 W:0:1:1300:0 E:1:1:1:2:1:1 O:0:0:0:0 B:BEG:* F:MALE | DROP_SKELETON | DROP_CORPSE | F:RAND_25 | WILD_TOWN | WILD_ONLY | DROP_1D2 | F:TAKE_ITEM | OPEN_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE D:You just can't help feeling sorry for him. N:13:Mangy-looking leper G:t:u I:110:1d1:10:1:50 W:0:1:1300:0 E:1:1:1:2:1:1 O:0:0:0:0 B:BEG:* B:TOUCH:DISEASE F:MALE | DROP_CORPSE | DROP_SKELETON | F:RAND_25 | WILD_TOWN | WILD_ONLY | DROP_1D2 | F:TAKE_ITEM | OPEN_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE D:You feel it isn't safe to touch him. N:14:Agent of the black market G:t:b I:110:2d8:10:8:99 W:0:1:1200:0 E:1:1:1:2:1:1 O:25:50:20:5 B:HIT:HURT:1d6 B:TOUCH:EAT_ITEM B:INSULT:* F:MALE | DROP_CORPSE | DROP_SKELETON | F:DROP_60 | WILD_TOWN | F:WILD_SWAMP | WILD_WOOD | WILD_GRASS | WILD_MOUNTAIN | WILD_ONLY | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE D:He 'finds' new wares for the Black Market. From unwary adventurers... N:15:Singing, happy drunk G:t:y I:110:2d3:10:1:0 W:0:1:1100:0 E:1:1:1:2:1:1 O:0:0:0:0 B:BEG:* F:MALE | F:RAND_50 | DROP_SKELETON | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | WILD_TOWN | WILD_ONLY | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE D:He makes you glad to be sober. N:16:Aimless-looking merchant G:t:o I:110:3d3:10:1:255 W:0:1:1500:0 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d3 F:MALE | RAND_50 | F:ONLY_GOLD | DROP_60 | DROP_SKELETON | DROP_CORPSE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | WILD_TOWN | WILD_ONLY | F:MORTAL | BASEANGBAND | HAS_LITE D:The typical ponce around town, with purse jingling, and looking for more D:amulets of adornment to buy. N:17:Mean-looking mercenary G:t:r I:110:5d8:10:20:250 W:0:1:1700:0 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d10 F:MALE | DROP_SKELETON | DROP_CORPSE | F:RAND_50 | DROP_90 | WILD_GRASS | WILD_TOWN | WILD_WOOD | WILD_ONLY | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE D:No job is too low for him. N:18:Battle-scarred veteran G:t:B I:110:7d8:10:30:250 W:0:1:1650:0 E:1:1:1:2:1:1 O:25:50:25:0 B:HIT:HURT:2d6 F:MALE | DROP_SKELETON | DROP_CORPSE | F:RAND_50 | DROP_90 | WILD_TOWN | WILD_ONLY | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE D:He doesn't take to strangers kindly. N:19:Martti Ihrasaari G:P:w I:109:35d20:50:15:4 W:0:4:2794:0 E:0:1:1:2:1:1 O:50:50:0:0 B:SHOW:* B:SHOW:* F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | DROP_CORPSE | WILD_TOWN | WILD_ONLY | F:ONLY_ITEM | DROP_90 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:JOKEANGBAND | HAS_LITE D:He weighs 127 kg. He is the president of some remote country. ##### Normal monsters ##### N:20:Grey mold G:m:s I:110:1d2:2:1:0 W:1:1:20:3 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:HURT:1d4 B:SPORE:HURT:1d4 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:IM_POIS | DROP_CORPSE | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT D:A small strange growth. N:21:Large white snake G:J:w I:100:3d6:4:30:99 W:1:1:600:2 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d1 B:CRUSH:HURT:1d1 F:RAND_50 | WILD_TOO | F:BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | HAS_EGG | MORTAL | BASEANGBAND D:It is about eight feet long. N:22:Grey mushroom patch G:,:s I:110:1d2:2:1:0 W:1:1:10:1 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:CONFUSE:1d4 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:IM_POIS | DROP_CORPSE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:Yum! It looks quite tasty. N:23:Newt G:R:y I:110:2d6:8:12:30 W:1:1:10:2 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d3 B:BITE:HURT:1d3 F:WEIRD_MIND | CAN_SWIM | WILD_TOO | DROP_CORPSE | F:WILD_GRASS | WILD_WASTE | WILD_SHORE | WILD_SWAMP | WILD_MOUNTAIN | F:ANIMAL | HAS_EGG | MORTAL | BASEANGBAND D:A small, harmless lizard. N:24:Giant white centipede G:c:w I:110:3d5:7:10:40 W:1:1:500:2 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d2 B:STING:HURT:1d2 F:RAND_50 | DROP_SKELETON | F:WEIRD_MIND | BASH_DOOR | WILD_TOO | F:ANIMAL | MORTAL | BASEANGBAND D:It is about four feet long and carnivorous. N:25:White icky thing G:i:w I:110:2d5:12:7:10 W:1:1:500:1 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:HURT:1d2 F:RAND_50 | RAND_25 | CAN_SWIM | F:EMPTY_MIND | DROP_CORPSE | BASEANGBAND D:It is a smallish, slimy, icky creature. N:26:Clear icky thing G:i:B I:110:2d5:12:6:10 W:1:1:500:2 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:HURT:1d2 F:ATTR_CLEAR | CAN_SWIM | F:RAND_50 | RAND_25 | F:INVISIBLE | EMPTY_MIND | DROP_CORPSE | BASEANGBAND D:It is a smallish, slimy, icky, blobby creature. N:27:Giant white mouse G:r:w I:110:1d3:8:4:20 W:1:1:600:1 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d2 F:RAND_50 | WILD_TOO | WILD_GRASS | F:CAN_SWIM | F:ANIMAL | DROP_CORPSE | F:MORTAL | BASEANGBAND | S:MULTIPLY D:It is about three feet long with large teeth. N:28:Large brown snake G:J:u I:100:4d6:4:35:99 W:1:1:800:3 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d3 B:CRUSH:HURT:1d4 F:RAND_25 | CAN_SWIM | F:BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | HAS_EGG | MORTAL | BASEANGBAND D:It is about eight feet long. N:29:Small kobold G:k:y I:110:2d7:20:16:10 W:1:1:800:5 E:1:1:1:2:1:1 O:0:50:0:30 B:HIT:HURT:1d5 F:DROP_60 | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:It is a small, dog-headed humanoid figure. N:30:Kobold G:k:G I:110:3d7:20:16:10 W:2:1:900:5 E:1:1:1:2:1:1 O:0:50:0:30 B:HIT:HURT:1d8 F:DROP_60 | WILD_TOO | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:It is a squat and ugly dog-headed humanoid. N:31:White worm mass G:w:w I:100:4d4:7:1:10 W:1:1:30:2 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:POISON:1d2 F:RAND_50 | RAND_25 | CAN_SWIM | F:STUPID | WEIRD_MIND | F:ANIMAL | IM_POIS | HURT_LITE | NO_FEAR F:MORTAL | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a large slimy mass of worms. N:32:Floating eye G:e:o I:110:3d6:2:6:10 W:1:1:500:1 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:PARALYZE F:NEVER_MOVE | CAN_FLY | DROP_CORPSE | F:HURT_LITE | NO_FEAR | BASEANGBAND D:A disembodied eye, floating a few feet above the ground. N:33:Rock lizard G:R:U I:110:3d4:20:4:15 W:1:1:100:2 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d1 F:ANIMAL | CAN_SWIM | WILD_TOO | WILD_MOUNTAIN | F:DROP_CORPSE | HAS_EGG | F:MORTAL | BASEANGBAND D:It is a small lizard with a hardened hide. N:34:Grid bug G:I:v I:110:2d4:10:2:10 W:1:1:10:2 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:ELEC:1d4 F:RAND_25 | FRIENDS | CAN_FLY | F:STUPID | WEIRD_MIND | F:ANIMAL | NO_FEAR | IM_ELEC | ZANGBAND D:A strange electric bug. N:35:Jackal G:C:U I:110:1d4:10:3:10 W:1:1:400:1 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d1 F:FRIENDS | F:WILD_TOO | WILD_WOOD | WILD_GRASS | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:It is a yapping snarling dog, dangerous when in a pack. N:36:Soldier ant G:a:u I:110:2d5:10:3:10 W:1:1:300:3 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d2 F:WEIRD_MIND | BASH_DOOR | DROP_SKELETON | F:ANIMAL | WILD_TOO | WILD_GRASS | F:MORTAL | BASEANGBAND D:A large ant with powerful mandibles. N:37:Fruit bat G:b:o I:120:1d6:20:3:10 W:1:1:20:1 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:1d1 F:ANIMAL | CAN_FLY | WILD_TOO | WILD_WOOD | WILD_SWAMP | DROP_CORPSE F:MORTAL | BASEANGBAND | AI_ANNOY D:A fast-moving pest. N:38:Insect swarm G:I:u I:120:1d5:20:4:10 W:1:1:100:1 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:HURT:1d1 B:STING:HURT:1d1 F:ANIMAL | WEIRD_MIND | CAN_FLY | RAND_25 | WILD_TOO | WILD_GRASS | F:WILD_WOOD | WILD_SWAMP | F:MORTAL | SUSCEP_FIRE | BASEANGBAND | NO_CUT D:A lone insect may be harmless, but there's a whole swarm of D:them here! N:39:The Greater hell-beast G:U:s I:120:15d100:10:1:99 W:1:16:2000:2500 E:0:1:0:2:1:0 O:0:0:0:0 B:GAZE:* B:GAZE:* B:CRUSH:* F:EVIL | IM_ACID | IM_ELEC | IM_FIRE | IM_POIS | IM_COLD | UNIQUE | F:RES_NETH | RES_WATE | RES_PLAS | RES_DISE | RES_NEXU | NO_SLEEP | NO_CONF F:KILL_WALL | FORCE_MAXHP | CAN_SWIM | DROP_CORPSE | JOKEANGBAND | HAS_LITE S:1_IN_9 | S:TPORT | BLINK | TELE_AWAY D:This unholy abomination will crush you. Flee while you can! N:40:Shrieker mushroom patch G:,:R I:110:1d1:4:1:0 W:2:1:40:1 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | NEVER_MOVE | NEVER_BLOW | F:STUPID | EMPTY_MIND | F:IM_POIS | WILD_TOO | WILD_SWAMP | DROP_CORPSE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_4 | S:SHRIEK D:Yum! It looks quite tasty. It doesn't sound so nice, though... N:41:Blubbering icky thing G:i:W I:110:5d6:14:4:10 W:2:1:400:8 E:0:0:0:0:0:0 O:20:20:20:20 B:CRAWL:POISON:1d4 B:CRAWL:EAT_FOOD B:DROOL:* B:DROOL:* F:RAND_50 | DROP_90 | CAN_SWIM | DROP_CORPSE | F:EMPTY_MIND | TAKE_ITEM | KILL_BODY | F:IM_POIS | BASEANGBAND D:It is a smallish, slimy, icky, hungry creature. N:42:Metallic green centipede G:c:g I:120:4d4:5:4:10 W:3:1:500:5 E:0:0:0:0:1:0 O:0:0:0:0 B:CRAWL:HURT:1d2 F:RAND_50 | WILD_TOO | DROP_SKELETON F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | MORTAL | BASEANGBAND D:It is about four feet long and carnivorous. N:43:Novice warrior G:p:u I:110:9d4:20:16:5 W:2:1:1600:6 E:1:1:1:2:1:1 O:25:50:0:20 B:HIT:HURT:1d7 B:HIT:HURT:1d6 F:MALE | F:DROP_60 | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE D:He looks inexperienced but tough. N:44:Novice rogue G:p:b I:110:8d4:20:12:5 W:2:1:1400:6 E:1:1:1:2:1:1 O:50:25:0:20 B:HIT:HURT:1d6 B:TOUCH:EAT_GOLD F:MALE | F:DROP_60 | DROP_SKELETON | DROP_CORPSE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | WILD_TOO | F:EVIL | MORTAL | BASEANGBAND D:A rather shifty individual. N:45:Novice priest G:p:g I:110:7d4:20:10:10 W:2:1:1500:6 E:1:1:1:2:1:1 O:25:0:50:20 B:HIT:HURT:1d5 F:MALE | F:FORCE_SLEEP | GOOD | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_12 | S:HEAL | SCARE | CAUSE_1 D:He is tripping over his priestly robes. N:46:Novice mage G:p:r I:110:6d4:20:6:5 W:2:1:1400:6 E:1:1:1:2:1:1 O:25:0:70:0 B:HIT:HURT:1d4 F:MALE | F:FORCE_SLEEP | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_12 | S:BLINK | BLIND | CONF | MISSILE D:He is leaving behind a trail of dropped spell components. N:47:Yellow mushroom patch G:,:y I:110:1d1:2:1:0 W:2:1:30:2 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:TERRIFY:1d6 F:NEVER_MOVE | WILD_TOO | WILD_SWAMP | F:STUPID | EMPTY_MIND | F:IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT D:Yum! It looks quite tasty. N:48:White jelly G:j:w I:120:8d8:2:1:99 W:2:1:2000:10 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:POISON:1d2 F:NEVER_MOVE | CAN_SWIM | F:STUPID | EMPTY_MIND | F:IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It's a large pile of white flesh. N:49:Giant black ant G:a:D I:110:3d6:8:20:80 W:2:1:500:8 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d4 F:RAND_25 | F:WEIRD_MIND | DROP_SKELETON | F:BASH_DOOR | WILD_TOO | WILD_WOOD | WILD_GRASS | F:ANIMAL | MORTAL | BASEANGBAND D:It is about three feet long. N:50:Salamander G:R:o I:110:4d6:8:20:80 W:2:1:100:10 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:FIRE:1d3 F:RAND_25 | CAN_SWIM | WILD_TOO | WILD_VOLCANO | DROP_CORPSE | F:ANIMAL | IM_FIRE | SUSCEP_COLD | F:MORTAL | BASEANGBAND D:A small black and orange lizard. N:51:White harpy G:H:w I:110:2d5:16:17:10 W:2:1:500:5 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:1d1 B:CLAW:HURT:1d1 B:BITE:HURT:1d2 F:FEMALE | CAN_FLY | WILD_TOO | WILD_MOUNTAIN | F:RAND_50 | DROP_CORPSE | ANIMAL | EVIL | MORTAL | BASEANGBAND D:A flying, screeching bird with a woman's face. N:52:Blue yeek G:y:b I:110:2d6:18:14:10 W:2:1:700:4 E:1:1:1:2:1:1 O:25:0:0:55 B:HIT:HURT:1d5 F:DROP_60 | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:ANIMAL | IM_ACID | F:MORTAL | BASEANGBAND D:A small humanoid figure. N:53:Grip, Farmer Maggot's dog G:C:w I:120:7d5:30:30:0 W:2:2:600:30 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 F:UNIQUE | SPECIAL_GENE F:FORCE_MAXHP | RAND_25 | DROP_CORPSE F:BASH_DOOR | ANIMAL F:MORTAL | BASEANGBAND D:A rather vicious dog belonging to Farmer Maggot. It thinks you are D:stealing mushrooms. N:54:Wolf, Farmer Maggot's dog G:C:w I:120:7d5:30:30:0 W:2:2:650:30 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 F:UNIQUE | SPECIAL_GENE F:FORCE_MAXHP | RAND_25 | DROP_CORPSE F:BASH_DOOR F:ANIMAL | MORTAL | BASEANGBAND D:A rather vicious dog belonging to Farmer Maggot. It thinks you are D:stealing mushrooms. N:55:Fang, Farmer Maggot's dog G:C:w I:120:7d5:30:30:0 W:2:2:700:30 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 F:UNIQUE | SPECIAL_GENE F:FORCE_MAXHP | RAND_25 | DROP_CORPSE F:BASH_DOOR F:ANIMAL | MORTAL | BASEANGBAND D:A rather vicious dog belonging to Farmer Maggot. It thinks you are D:stealing mushrooms. N:56:Giant green frog G:R:g I:110:2d8:12:8:30 W:2:1:200:6 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d3 F:RAND_25 | WILD_ONLY | WILD_SHORE | WILD_SWAMP | DROP_CORPSE | F:BASH_DOOR | F:ANIMAL | MORTAL | BASEANGBAND D:It is as big as a wolf. N:57:Freesia G:f:u I:120:6d5:30:30:0 W:2:1:450:32 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d4 F:UNIQUE | F:FORCE_MAXHP | DROP_SKELETON F:BASH_DOOR | F:ANIMAL F:MORTAL | ZANGBAND D:A striped housecat who enjoys hunting. N:58:Green worm mass G:w:g I:100:6d4:7:3:10 W:2:1:40:3 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:ACID:1d3 F:RAND_50 | RAND_25 | F:STUPID | WEIRD_MIND | F:ANIMAL | IM_ACID | CAN_SWIM | F:HURT_LITE | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a large slimy mass of worms. N:59:Large yellow snake G:J:y I:100:4d8:5:38:75 W:2:1:1000:9 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d4 B:CRUSH:HURT:1d6 F:RAND_25 | CAN_SWIM | WILD_TOO | DROP_SKELETON | DROP_CORPSE F:BASH_DOOR | HAS_EGG | ANIMAL | MORTAL | BASEANGBAND D:It is about ten feet long. N:60:Cave spider G:S:D I:120:2d6:8:16:80 W:2:1:400:7 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d4 F:FRIENDS | F:WEIRD_MIND | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | SPIDER | HURT_LITE | F:MORTAL | BASEANGBAND D:It is a black spider that moves in fits and starts. N:61:Crow G:B:s I:120:3d5:40:12:0 W:2:2:300:8 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:1d3 B:BITE:HURT:1d3 F:ANIMAL | WILD_TOO | WILD_WOOD | CAN_FLY | DROP_CORPSE F:MORTAL | HAS_EGG | BASEANGBAND D:It is a hooded crow, gray except for the black wings and head. N:62:Wild cat G:f:U I:120:3d5:40:12:0 W:2:2:200:8 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 F:BASH_DOOR | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:A larger than normal feline, hissing loudly. Its velvet claws conceal a D:fistful of needles. N:63:Smeagol G:h:B I:130:20d20:20:12:5 W:3:2:670:16 E:1:1:1:2:1:1 O:50:50:0:0 B:TOUCH:EAT_GOLD F:UNIQUE | MALE | CAN_SWIM | DROP_SKELETON | DROP_CORPSE | DROP_CHOSEN | F:FORCE_MAXHP | CAN_SPEAK | SMART | F:RAND_50 | RAND_25 | WILD_TOO | F:ONLY_ITEM | DROP_90 | DROP_GOOD | DROP_GREAT | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | INVISIBLE F:EVIL | BASEANGBAND D:Usually known as Gollum. He's been sneaking, and he wants his 'precious.' N:64:Green ooze G:j:g I:120:3d4:8:16:80 W:3:2:300:4 E:0:0:0:0:0:0 O:50:0:25:20 B:CRAWL:ACID:1d3 F:RAND_50 | RAND_25 | DROP_90 | F:STUPID | EMPTY_MIND | F:IM_ACID | IM_POIS | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It's green and it's oozing. N:65:Poltergeist G:G:s I:130:2d5:8:15:10 W:3:1:0:8 E:0:0:0:0:0:0 O:50:5:30:10 B:TOUCH:TERRIFY F:RAND_50 | RAND_25 | CAN_FLY | F:DROP_60 | DROP_90 | F:INVISIBLE | COLD_BLOOD | PASS_WALL | TAKE_ITEM | F:EVIL | UNDEAD | F:IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:BLINK D:It is a ghastly, ghostly form. N:66:Yellow jelly G:j:y I:120:10d8:2:1:99 W:3:1:2000:12 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:POISON:1d3 F:NEVER_MOVE | CAN_SWIM | F:STUPID | EMPTY_MIND | F:IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_15 | S:DRAIN_MANA D:It's a large pile of yellow flesh. N:67:Metallic blue centipede G:c:b I:120:4d5:6:6:15 W:4:1:770:6 E:0:0:0:0:1:0 O:0:0:0:0 B:CRAWL:HURT:1d3 F:RAND_50 | DROP_SKELETON F:WEIRD_MIND | BASH_DOOR | WILD_TOO | F:ANIMAL | MORTAL | BASEANGBAND D:It is about four feet long and carnivorous. N:68:Raven G:B:D I:120:4d5:40:12:0 W:4:2:500:8 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:1d4 B:BITE:HURT:1d4 F:ANIMAL | WILD_TOO | WILD_WOOD | CAN_FLY | DROP_CORPSE F:MORTAL | HAS_EGG | BASEANGBAND D:Larger than a crow, and pitch black. N:69:Giant white louse G:I:w I:120:1d1:6:5:10 W:3:1:100:1 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:HURT:1d1 F:RAND_50 | RAND_25 | CAN_FLY | F:WEIRD_MIND | ANIMAL | MORTAL | BASEANGBAND S:MULTIPLY D:It is six inches long. N:70:Giant yellow centipede G:c:y I:110:3d6:8:12:30 W:2:1:500:3 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d3 B:STING:HURT:1d3 F:RAND_50 | DROP_SKELETON | F:WEIRD_MIND | BASH_DOOR | WILD_TOO | F:ANIMAL | MORTAL | BASEANGBAND D:It is about four feet long and carnivorous. N:71:Black naga G:n:D I:110:6d8:16:40:120 W:3:1:1700:20 E:0:0:0:0:1:0 O:0:75:20:5 B:CRUSH:HURT:1d8 F:FEMALE | F:RAND_25 | DROP_60 | DROP_CORPSE | F:BASH_DOOR | CAN_SWIM | F:EVIL | MORTAL | BASEANGBAND D:A large black serpent's body with a female torso. N:72:Spotted mushroom patch G:,:o I:110:1d1:2:1:0 W:3:1:30:3 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:POISON:2d4 F:NEVER_MOVE | WILD_TOO | WILD_SWAMP | F:STUPID | EMPTY_MIND | F:IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:Yum! It looks quite tasty. N:73:Silver jelly G:j:W I:120:10d8:2:1:99 W:3:2:2000:12 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:EAT_LITE:1d3 B:TOUCH:EAT_LITE:1d3 F:NEVER_MOVE | CAN_SWIM | F:STUPID | EMPTY_MIND | F:IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_15 | S:DRAIN_MANA D:It is a large pile of silver flesh that sucks all light from its D:surroundings. N:74:Scruffy-looking hobbit G:h:s I:110:3d5:16:8:10 W:3:1:1000:4 E:1:1:1:2:1:1 O:0:50:0:40 B:HIT:HURT:1d4 B:TOUCH:EAT_GOLD F:MALE | F:DROP_60 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL F:MORTAL | BASEANGBAND D:A short little guy, in bedraggled clothes. He appears to be looking D:for a good tavern. N:75:Giant white ant G:a:w I:110:3d6:8:16:80 W:3:1:800:7 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d4 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | WILD_GRASS | F:ANIMAL | DROP_SKELETON | F:MORTAL | BASEANGBAND D:It is about two feet long and has sharp pincers. N:76:Yellow mold G:m:y I:110:8d8:2:10:99 W:3:1:30:9 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:HURT:1d4 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a strange growth on the dungeon floor. N:77:Metallic red centipede G:c:r I:120:4d8:8:9:20 W:5:1:800:10 E:0:0:0:0:1:0 O:0:0:0:0 B:CRAWL:HURT:2d3 F:RAND_25 | F:WEIRD_MIND | BASH_DOOR | WILD_TOO | DROP_SKELETON F:ANIMAL | MORTAL | BASEANGBAND D:It is about four feet long and carnivorous. N:78:Yellow worm mass G:w:y I:100:4d8:7:4:10 W:3:2:200:4 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:LOSE_DEX:1d3 F:RAND_50 | RAND_25 | CAN_SWIM | F:STUPID | WEIRD_MIND | F:ANIMAL | HURT_LITE | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a large slimy mass of worms. N:79:Clear worm mass G:w:B I:100:4d4:7:1:10 W:3:2:200:4 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:POISON:1d2 F:ATTR_CLEAR | CAN_SWIM | F:RAND_50 | RAND_25 | F:STUPID | WEIRD_MIND | INVISIBLE | F:ANIMAL | F:IM_POIS | HURT_LITE | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a disgusting mass of poisonous worms. N:80:Radiation eye G:e:R I:110:3d6:2:6:10 W:3:1:500:6 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:LOSE_STR:1d6 F:NEVER_MOVE | CAN_FLY | DROP_CORPSE | F:HURT_LITE | NO_FEAR | BASEANGBAND | HAS_LITE S:1_IN_11 | S:DRAIN_MANA D:A disembodied eye, crackling with energy. N:81:Yellow light G:*:y I:120:2d6:8:12:30 W:4:1:0:4 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:BLIND F:EMPTY_MIND | CAN_FLY | NONLIVING | SUSCEP_ELEC | F:BASEANGBAND | HAS_LITE | RAND_50 | RAND_25 | NO_CUT D:A fast-moving bright light, apparently totally random in its movement. N:82:Cave lizard G:R:u I:110:3d6:8:16:80 W:4:1:100:8 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d5 F:ANIMAL | CAN_SWIM | DROP_CORPSE | HAS_EGG | F:MORTAL | BASEANGBAND D:It is an armoured lizard with a powerful bite. N:83:Novice ranger G:p:W I:110:6d8:20:8:5 W:4:1:1400:18 E:1:1:1:2:1:1 O:25:45:25:0 B:HIT:HURT:1d5 B:HIT:HURT:1d5 F:MALE | F:FORCE_SLEEP | DROP_SKELETON | DROP_CORPSE F:DROP_60 | F:OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_WOOD | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_9 | S:ARROW_2 | MISSILE D:An agile hunter, ready and relaxed. N:84:Blue jelly G:j:b I:110:12d8:2:1:99 W:4:1:2000:14 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:COLD:1d6 F:NEVER_MOVE | COLD_BLOOD | F:STUPID | EMPTY_MIND | CAN_SWIM | F:IM_COLD | HURT_LITE | F:NO_CONF | NO_SLEEP | NO_FEAR | SUSCEP_FIRE | BASEANGBAND | NO_CUT D:It's a large pile of pulsing blue flesh. N:85:Creeping copper coins G:$:u I:100:7d8:3:24:10 W:4:3:0:9 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d4 B:TOUCH:POISON:2d4 F:ONLY_GOLD | DROP_1D2 | SUSCEP_ACID | F:COLD_BLOOD | BASH_DOOR | F:IM_ELEC | IM_POIS | CHAR_MULTI | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:It appears to be a pile of copper coins, until it starts crawling towards you D:on tiny legs. N:86:Giant white rat G:r:W I:110:2d2:8:7:30 W:4:1:200:1 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:1d3 F:RAND_25 | F:ANIMAL | MORTAL | BASEANGBAND S:MULTIPLY D:It is a very vicious rodent. N:87:Snotling G:o:U I:110:5d5:20:32:30 W:4:1:900:15 E:1:1:1:2:1:1 O:25:50:0:20 B:HIT:HURT:1d6 F:MALE | F:FRIENDS | DROP_60 | RAND_50 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_WOOD | F:EVIL | ORC | HURT_LITE | F:MORTAL | BASEANGBAND | HAS_LITE D:Immature Orclings, running wild and screaming all the time. N:88:Swordfish G:~:W I:120:4d7:14:10:20 W:4:2:800:15 E:0:0:0:0:1:0 O:0:0:0:0 B:HIT:HURT:1d5 B:HIT:HURT:1d5 F:ANIMAL | AQUATIC | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:A fish with a swordlike "beak". N:89:Blue worm mass G:w:b I:100:5d8:7:12:10 W:4:1:40:5 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:COLD:1d4 F:RAND_50 | RAND_25 | F:STUPID | WEIRD_MIND | COLD_BLOOD | F:ANIMAL | IM_COLD | CAN_SWIM | F:HURT_LITE | NO_FEAR | F:MORTAL | SUSCEP_FIRE | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a large slimy mass of worms. N:90:Large grey snake G:J:s I:100:6d8:6:41:50 W:4:1:1300:14 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d5 B:CRUSH:HURT:1d8 F:RAND_25 | CAN_SWIM | DROP_SKELETON | DROP_CORPSE | WILD_TOO | F:BASH_DOOR | HAS_EGG | ANIMAL | MORTAL | BASEANGBAND D:It is about ten feet long. N:91:Skeleton kobold G:s:W I:110:5d8:20:26:40 W:5:1:800:12 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d6 F:COLD_BLOOD | EMPTY_MIND | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a small animated kobold skeleton. N:92:Ewok G:h:G I:120:3d5:10:10:10 W:9:2:700:20 E:1:1:1:2:1:1 O:50:0:50:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:DROP_60 | OPEN_DOOR | BASH_DOOR | FRIENDS | DROP_CORPSE | F:WILD_TOO | WILD_WOOD | F:MORTAL | JOKEANGBAND S:1_IN_8 S:ARROW_1 D:A cute little bear, full of merchandising potential. N:93:Novice mage G:p:r I:110:6d4:20:6:10 W:6:2:1400:6 E:1:1:1:2:1:1 O:25:0:70:0 B:HIT:HURT:1d4 F:MALE | F:FORCE_SLEEP | F:FRIENDS | DROP_60 | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_12 | S:BLINK | BLIND | CONF | MISSILE D:He is leaving behind a trail of dropped spell components. N:94:Green naga G:n:g I:110:9d8:18:40:120 W:5:1:1700:30 E:0:0:0:0:1:0 O:0:25:0:65 B:CRUSH:HURT:1d8 B:SPIT:ACID:2d6 F:FEMALE | F:RAND_25 | TAKE_ITEM | DROP_60 | DROP_CORPSE | F:BASH_DOOR | CAN_SWIM | WILD_TOO | WILD_SHORE | F:EVIL | IM_ACID | MORTAL | BASEANGBAND D:A large green serpent with a female torso. Her green skin glistens with D:acid. N:95:Giant leech G:w:u I:120:6d8:10:20:50 W:5:1:30:20 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:3d1 B:BITE:HURT:3d1 F:ANIMAL | AQUATIC | WEIRD_MIND | RAND_25 | BASEANGBAND D:Yech! The disgusting thing only wants your blood! N:96:Barracuda G:~:G I:120:6d8:20:45:20 W:5:2:150:30 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d10 B:BITE:HURT:1d10 F:AQUATIC | ANIMAL | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:A predatory fish with razor-sharp teeth. N:97:Novice paladin G:p:w I:110:6d8:20:16:5 W:4:1:1700:18 E:1:1:1:2:1:1 O:0:70:25:0 B:HIT:HURT:1d7 B:HIT:HURT:1d7 F:MALE | GOOD | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:FORCE_SLEEP | F:DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_9 | S:SCARE | CAUSE_1 D:An adventurer both devoutly religious and skilful in combat. D:He seems to consider you an agent of the devil. N:98:Zog G:h:b I:110:13d9:20:20:20 W:5:1:600:25 E:0:1:0:2:1:0 O:50:0:25:20 B:HIT:HURT:1d8 B:HIT:HURT:1d8 B:DROOL:* F:EVIL | OPEN_DOOR | BASH_DOOR | DROP_90 | DROP_SKELETON | F:MORTAL | ZANGBAND D:Drooling, insectoid aliens with disgusting habits. N:99:Blue ooze G:j:b I:110:3d4:8:16:80 W:5:1:300:7 E:0:0:0:0:0:0 O:45:20:20:0 B:CRAWL:COLD:1d4 F:RAND_50 | RAND_25 | DROP_60 | F:STUPID | EMPTY_MIND | CAN_SWIM | F:IM_COLD | SUSCEP_FIRE F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It's blue and it's oozing. N:100:Green glutton ghost G:G:g I:130:3d4:10:20:10 W:5:1:0:15 E:0:0:0:0:0:0 O:30:30:30:5 B:TOUCH:EAT_FOOD:1d1 F:RAND_50 | RAND_25 | F:DROP_60 | DROP_90 | CAN_FLY | F:INVISIBLE | COLD_BLOOD | PASS_WALL | F:EVIL | UNDEAD | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:It is a very ugly green ghost with a voracious appetite. N:101:Green jelly G:j:g I:120:22d8:2:1:99 W:5:1:2500:18 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:ACID:1d2 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | CAN_SWIM | F:IM_ACID | HURT_LITE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a large pile of pulsing green flesh. N:102:Large kobold G:k:b I:110:13d9:20:32:30 W:5:1:1000:25 E:1:1:1:2:1:1 O:0:90:0:5 B:HIT:HURT:1d10 F:DROP_90 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:It a man-sized figure with the all too recognisable face of a kobold. N:103:Grey icky thing G:i:s I:110:4d8:14:12:15 W:5:1:500:10 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:HURT:1d5 F:RAND_50 | CAN_SWIM | DROP_CORPSE | F:EMPTY_MIND | BASEANGBAND D:It is a smallish, slimy, icky, nasty creature. N:104:Disenchanter eye G:e:v I:100:7d8:2:10:10 W:5:2:500:20 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:UN_BONUS F:ATTR_MULTI | ATTR_ANY | RES_DISE | DROP_CORPSE | F:NEVER_MOVE | CAN_FLY | F:HURT_LITE | NO_FEAR | BASEANGBAND S:1_IN_9 | S:DRAIN_MANA D:A disembodied eye, crackling with magic. N:105:Red worm mass G:w:r I:100:5d8:7:12:10 W:5:1:40:6 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:FIRE:1d6 F:RAND_50 | RAND_25 | SUSCEP_COLD | F:STUPID | EMPTY_MIND | BASH_DOOR | F:ANIMAL | IM_FIRE | CAN_SWIM | F:HURT_LITE | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a large slimy mass of worms. N:106:Copperhead snake G:J:o I:110:4d6:6:20:1 W:5:1:200:15 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:POISON:2d4 F:RAND_50 | CAN_SWIM | WILD_TOO | DROP_SKELETON | DROP_CORPSE | BASH_DOOR | F:ANIMAL | IM_POIS | HAS_EGG | MORTAL | BASEANGBAND D:It has a copper head and sharp venomous fangs. N:107:Death sword G:|:W I:130:6d6:20:40:0 W:6:5:0:30 E:0:0:0:0:0:0 O:50:0:50:0 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:NEVER_MOVE | NONLIVING | NO_FEAR | SUSCEP_ACID | F:STUPID | EMPTY_MIND | COLD_BLOOD | CHAR_MULTI | NO_CONF | NO_SLEEP | F:DROP_90 | EVIL | IM_COLD | IM_FIRE | FORCE_MAXHP | IM_ELEC | IM_POIS | F:BASEANGBAND | HAS_LITE | NO_CUT D:A bloodthirsty blade lurking for prey. Beware! N:108:Purple mushroom patch G:,:v I:110:1d1:2:1:0 W:6:2:40:15 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:LOSE_CON:1d2 B:SPORE:LOSE_CON:1d2 B:SPORE:LOSE_CON:1d2 F:NEVER_MOVE | CAN_SWIM | F:STUPID | EMPTY_MIND | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:Yuk! It doesn't look so tasty. N:109:Novice priest G:p:g I:110:7d4:20:10:5 W:6:2:1500:6 E:1:1:1:2:1:1 O:20:50:20:5 B:HIT:HURT:1d5 F:MALE | GOOD | F:FORCE_SLEEP | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_12 | S:HEAL | SCARE | CAUSE_1 D:He is tripping over his priestly robes. N:110:Novice warrior G:p:u I:110:9d4:20:16:5 W:6:2:1600:6 E:1:1:1:2:1:1 O:0:95:0:0 B:HIT:HURT:1d7 B:HIT:HURT:1d6 F:MALE | F:FRIENDS | DROP_60 | WILD_TOO | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE D:He looks inexperienced but tough. N:111:Nibelung G:h:D I:110:8d4:20:12:5 W:6:1:900:6 E:1:1:1:2:1:1 O:90:0:0:5 B:HIT:HURT:1d6 B:TOUCH:EAT_GOLD F:MALE | F:FRIENDS | DROP_60 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | HURT_LITE | RES_DISE | DROP_SKELETON | DROP_CORPSE | F:MORTAL | ZANGBAND | HAS_LITE D:Night dwarfs collecting riches. N:112:The disembodied hand that strangled people G:z:g I:130:7d8:30:15:20 W:6:2:300:20 E:0:0:0:1:0:0 O:0:0:0:0 B:CRUSH:HURT:1d8 F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_POIS | CAN_FLY | UNIQUE | F:NO_CONF | NO_SLEEP | NO_FEAR | ZANGBAND | NO_CUT D:Even today, nobody knows where it lurks... N:113:Brown mold G:m:u I:110:15d8:2:12:99 W:6:1:50:20 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:CONFUSE:1d4 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:IM_POIS | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:A strange brown growth on the dungeon floor. N:114:Giant brown bat G:b:u I:130:3d8:10:15:30 W:6:1:600:10 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:1d3 F:RAND_50 | CAN_FLY | WILD_TOO | WILD_MOUNTAIN | WILD_WOOD | F:ANIMAL | DROP_CORPSE | AI_ANNOY F:MORTAL | BASEANGBAND D:It screeches as it attacks. N:115:Rat-thing G:r:R I:120:9d9:12:20:20 W:6:1:1000:10 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:3d2 B:BITE:HURT:3d1 B:BITE:HURT:3d2 F:EVIL | ANIMAL | DROP_CORPSE | F:MORTAL | ZANGBAND S:1_IN_9 S:SCARE | CONF D:A ratlike creature with a humanlike face. N:116:Novice rogue G:p:b I:110:8d4:20:12:5 W:6:2:1400:6 E:1:1:1:2:1:1 O:50:25:0:20 B:HIT:HURT:1d6 B:TOUCH:EAT_GOLD F:MALE | FRIENDS | F:DROP_60 | DROP_SKELETON | DROP_CORPSE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | WILD_TOO | F:EVIL | MORTAL | BASEANGBAND D:A rather shifty individual. N:117:Creeping silver coins G:$:s I:100:12d8:4:30:10 W:6:3:0:18 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d6 B:TOUCH:POISON:2d6 F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:COLD_BLOOD | BASH_DOOR | SUSCEP_ACID | CHAR_MULTI | F:IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:It appears to be a pile of silver coins, until it starts crawling towards you D:on tiny legs. N:118:Snaga G:o:U I:110:8d8:20:32:30 W:6:1:1600:15 E:1:1:1:2:1:1 O:20:50:5:15 B:HIT:HURT:1d8 F:MALE | F:FRIENDS | DROP_60 | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | HURT_LITE | F:MORTAL | BASEANGBAND | HAS_LITE D:He is one of the many weaker 'slave' orcs, often mistakenly known as a D:goblin. N:119:Rattlesnake G:J:r I:110:6d7:6:24:1 W:6:1:200:20 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:POISON:2d5 F:RAND_50 | CAN_SWIM | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:BASH_DOOR | HAS_EGG | ANIMAL | IM_POIS | MORTAL | BASEANGBAND D:It is recognised by the hard-scaled end of its body that is often rattled D:to frighten its prey. N:120:Giant slug G:w:U I:100:12d9:10:25:25 W:6:1:600:25 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:ACID:2d4 B:BITE:ACID:2d6 F:ANIMAL | EMPTY_MIND | KILL_ITEM | KILL_BODY | CAN_SWIM | WILD_TOO | F:DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_10 S:BR_ACID D:It is slowly making its way towards you, eating everything in D:its path... N:121:Giant pink frog G:R:r I:110:5d8:12:16:50 W:7:1:200:16 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:LOSE_STR:2d4 F:RAND_50 | WILD_ONLY | WILD_SHORE | WILD_SWAMP | F:BASH_DOOR | DROP_CORPSE F:ANIMAL | MORTAL | BASEANGBAND D:It looks poisonous. N:122:Dark elf G:h:D I:110:7d10:20:16:20 W:7:2:1200:25 E:1:1:1:2:1:1 O:20:20:50:10 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:MALE | F:FORCE_SLEEP | F:DROP_90 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | HURT_LITE | BASEANGBAND | HAS_LITE S:1_IN_10 | S:CONF | DARKNESS | MISSILE D:An elven figure with jet black skin and white hair, his eyes are large and D:twisted with evil. N:123:Zombified kobold G:z:s I:110:6d8:20:14:30 W:7:1:750:14 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d2 B:HIT:HURT:1d2 F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is an animated kobold corpse. Flesh falls off in large chunks as it D:shambles forward. N:124:Crypt creep G:s:D I:110:6d8:20:12:14 W:7:2:0:25 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:1d2 B:CLAW:HURT:1d2 B:BITE:POISON F:RAND_25 F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | FRIENDS | F:EVIL | UNDEAD | IM_POIS | IM_COLD | F:NO_CONF | NO_SLEEP | HURT_LITE | BASEANGBAND | NO_CUT S:1_IN_10 S:CAUSE_1 | S_UNDEAD D:A frightening skeletal figure in a black robe. N:125:Rotting corpse G:z:R I:110:8d8:20:20:20 W:8:1:0:15 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:POISON:1d3 B:CLAW:POISON:1d3 F:OPEN_DOOR | BASH_DOOR | FRIENDS | F:NO_CONF | NO_SLEEP | UNDEAD | EVIL | NO_FEAR | IM_POIS | F:IM_COLD | COLD_BLOOD | EMPTY_MIND | BASEANGBAND | NO_CUT D:Corpses awakened from their sleep by dark sorcery. N:126:Cave orc G:o:G I:110:11d9:20:32:30 W:7:1:1900:20 E:1:1:1:2:1:1 O:20:70:0:0 B:HIT:HURT:1d8 F:MALE | F:FRIENDS | DROP_60 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | HURT_LITE | F:MORTAL | BASEANGBAND | HAS_LITE D:He is often found in huge numbers in deep caves. N:127:Wood spider G:S:U I:120:3d6:8:16:80 W:7:3:600:15 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d3 B:STING:POISON:1d4 F:FRIENDS | DROP_SKELETON | F:WEIRD_MIND | BASH_DOOR | WILD_TOO | WILD_WOOD | F:ANIMAL | SPIDER | IM_POIS | F:MORTAL | BASEANGBAND D:It scuttles towards you. N:128:Manes G:u:r I:110:8d8:20:32:30 W:7:2:300:16 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d8 F:FRIENDS | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DEMON | IM_FIRE | NO_FEAR | BASEANGBAND D:It is a minor but aggressive demon. N:129:Bloodshot eye G:e:r I:110:10d8:2:6:10 W:7:3:550:30 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:BLIND:2d6 F:NEVER_MOVE | CAN_FLY | DROP_CORPSE | F:HURT_LITE | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_7 | S:DRAIN_MANA D:A disembodied eye, bloodshot and nasty. N:130:Red naga G:n:r I:110:11d8:20:40:120 W:7:2:1800:40 E:0:0:0:0:1:0 O:50:0:50:0 B:CRUSH:HURT:1d10 B:BITE:LOSE_STR:1d4 F:FEMALE | CAN_SWIM | WILD_TOO | WILD_SHORE | F:RAND_25 | DROP_60 | F:TAKE_ITEM | BASH_DOOR | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND D:A large red snake with a woman's torso. N:131:Red jelly G:j:r I:110:26d8:2:1:99 W:7:1:2500:26 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:LOSE_STR:1d5 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:HURT_LITE | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a large pulsating mound of red flesh. N:132:Green icky thing G:i:g I:110:5d8:14:12:20 W:7:2:500:18 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:ACID:2d5 F:RAND_50 | CAN_SWIM | DROP_CORPSE | F:EMPTY_MIND | F:IM_ACID | BASEANGBAND D:It is a smallish, slimy, icky, acidic creature. N:133:Lost soul G:G:W I:110:2d8:12:10:10 W:7:2:0:18 E:0:0:0:0:0:0 O:60:0:25:0 B:HIT:HURT:2d2 B:TOUCH:LOSE_WIS F:RAND_50 | DROP_60 | DROP_90 | CAN_FLY | F:INVISIBLE | COLD_BLOOD | TAKE_ITEM | PASS_WALL | F:EVIL | UNDEAD | F:IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:TPORT | DRAIN_MANA D:It is almost insubstantial. N:134:Night lizard G:R:b I:110:4d8:20:16:30 W:7:2:400:35 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 B:BITE:HURT:1d6 F:ANIMAL | CAN_SWIM | WILD_TOO | DROP_CORPSE F:MORTAL | HAS_EGG | BASEANGBAND D:It is a black lizard with overlapping scales and a powerful jaw. N:135:Mughash, the Kobold Lord G:k:v I:110:17d10:20:20:20 W:7:3:1100:100 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d12 B:HIT:HURT:1d12 B:HIT:HURT:1d12 F:UNIQUE | MALE | CAN_SPEAK F:FORCE_MAXHP | F:ESCORT | ESCORTS | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:Strong and powerful, for a kobold. N:136:Skeleton orc G:s:W I:110:10d8:20:36:40 W:8:1:1700:26 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:2d5 F:COLD_BLOOD | EMPTY_MIND | OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | UNDEAD | F:IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is an animated orc skeleton. N:137:Wormtongue, Agent of Saruman G:p:B I:110:28d10:20:30:20 W:9:2:1500:150 E:1:1:1:2:1:1 O:10:50:35:0 B:HIT:HURT:1d7 B:HIT:HURT:1d7 B:TOUCH:EAT_GOLD B:INSULT:* F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | DROP_GREAT | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | F:EVIL | RES_TELE | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_5 | S:HEAL | SLOW | TRAPS | BO_COLD | BA_POIS D:He's been spying for Saruman. He is a snivelling wretch with no morals. N:138:Robin Hood, the Outlaw G:p:G I:120:16d12:20:30:20 W:10:2:1600:150 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:HURT:1d5 B:HIT:HURT:1d5 B:TOUCH:EAT_GOLD B:TOUCH:EAT_ITEM F:UNIQUE | MALE | FORCE_SLEEP | FORCE_MAXHP | CAN_SPEAK | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | DROP_GREAT | WILD_TOO | WILD_WOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | EVIL | DROP_SKELETON | DROP_CORPSE F:MORTAL | ZANGBAND | HAS_LITE S:1_IN_5 S:ARROW_2 | HEAL | TRAPS D:The legendary archer steals from the rich (you qualify). N:139:Nurgling G:u:o I:110:9d8:20:32:30 W:8:2:800:19 E:1:1:1:2:1:1 O:0:0:0:0 B:BITE:DISEASE:1d8 F:FRIENDS | FRIEND | F:OPEN_DOOR | BASH_DOOR | IM_POIS | F:EVIL | DEMON | IM_FIRE | NO_FEAR | ZANGBAND D:It is a minor demon servitor of Nurgle. It looks like a hairless D:teddy bear, with twisted eyes and rotting, ghoulish skin. N:140:Lagduf, the Snaga G:o:y I:110:22d10:20:32:30 W:8:2:1700:80 E:1:1:1:2:1:1 O:10:80:0:0 B:HIT:HURT:1d11 B:HIT:HURT:1d11 B:HIT:HURT:1d10 B:HIT:HURT:1d10 F:UNIQUE | MALE | EVIL | ORC | FORCE_MAXHP | ESCORT | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | SPECIAL_GENE | F:OPEN_DOOR | BASH_DOOR | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE D:A captain of a regiment of weaker orcs, Lagduf keeps his troop in order D:with displays of excessive violence. N:141:Brown yeek G:y:u I:110:4d8:18:18:10 W:8:1:800:11 E:1:1:1:2:1:1 O:0:50:0:30 B:HIT:HURT:1d6 F:DROP_60 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:ANIMAL | IM_ACID | F:MORTAL | BASEANGBAND D:It is a strange small humanoid. N:142:Novice ranger G:p:W I:110:6d8:20:8:5 W:8:2:1500:18 E:1:1:1:2:1:1 O:0:80:0:15 B:HIT:HURT:1d5 B:HIT:HURT:1d5 F:MALE | F:FORCE_SLEEP | FRIENDS | DROP_60 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_9 | S:ARROW_2 | MISSILE D:An agile hunter, ready and relaxed. N:143:Giant salamander G:R:R I:110:6d7:6:40:1 W:8:1:600:50 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:FIRE:3d6 F:FORCE_SLEEP | SUSCEP_COLD | F:RAND_25 | F:ANIMAL | IM_FIRE | CAN_SWIM | DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_9 S:BR_FIRE D:A large black and yellow lizard. You'd better run away! N:144:Space monster G:.:d I:110:21d8:30:14:20 W:8:2:0:28 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:TERRIFY:1d4 F:PASS_WALL | NO_CONF | NO_SLEEP | NONLIVING | IM_ACID | CAN_FLY | JOKEANGBAND | NO_CUT D:A black hole in the fabric of reality. N:145:Carnivorous flying monkey G:H:R I:110:20d8:30:20:20 W:8:2:800:30 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:1d8 B:CLAW:HURT:1d8 B:BITE:HURT:5d1 F:ANIMAL | CAN_FLY | WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | F:DROP_CORPSE | MORTAL | ZANGBAND | HAS_LITE D:It looks fantastic, yet frightening. N:146:Green mold G:m:g I:110:21d8:2:14:75 W:8:1:40:28 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:TERRIFY:1d4 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:IM_ACID | IM_POIS | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a strange growth on the dungeon floor. N:147:Novice paladin G:p:w I:110:6d8:20:16:5 W:8:2:1500:18 E:1:1:1:2:1:1 O:30:55:10:0 B:HIT:HURT:1d7 B:HIT:HURT:1d7 F:MALE | GOOD | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:FORCE_SLEEP | F:FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_9 | S:SCARE | CAUSE_1 D:He thinks you are an agent of the devil. N:148:Lemure G:u:U I:110:13d9:20:32:30 W:8:3:1000:16 E:0:0:0:0:1:0 O:0:0:0:0 B:HIT:HURT:1d8 F:FRIENDS | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DEMON | IM_FIRE | NO_FEAR | BASEANGBAND D:It is the larval form of a major demon. N:149:Hill orc G:o:u I:110:13d9:20:32:30 W:8:1:2000:25 E:1:1:1:2:1:1 O:10:70:10:0 B:HIT:HURT:1d10 F:MALE | F:FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | ORC | HURT_LITE | F:MORTAL | BASEANGBAND | HAS_LITE D:He is a hardy well-weathered survivor. N:150:Bandit G:p:b I:110:8d8:20:24:10 W:10:2:1500:26 E:1:1:1:2:1:1 O:25:60:0:0 B:HIT:HURT:2d4 B:TOUCH:EAT_GOLD F:MALE | F:DROP_1D2 | WILD_TOO | WILD_WOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE D:He is after your possessions! N:151:Hunting hawk G:B:u I:120:8d8:30:25:10 W:8:2:800:22 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d4 F:ANIMAL | NO_FEAR | CAN_FLY | WILD_WOOD | WILD_TOO | DROP_CORPSE F:MORTAL | HAS_EGG | BASEANGBAND D:Trained to hunt and kill without fear. N:152:Phantom warrior G:G:B I:110:5d5:20:10:40 W:8:1:0:15 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d11 B:HIT:HURT:1d11 F:PASS_WALL | NO_SLEEP | FRIENDS | COLD_BLOOD | NONLIVING | F:NO_FEAR | EMPTY_MIND | CAN_FLY | BASEANGBAND | NO_CUT D:Spectral creatures that are half real, half illusion. N:153:Gremlin G:u:u I:110:5d5:30:30:20 W:8:3:500:6 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:EAT_FOOD:1d2 B:CLAW:EAT_FOOD:1d2 B:BITE:EAT_FOOD:1d3 F:IM_POIS | HURT_LITE | EVIL | DEMON | OPEN_DOOR | F:TAKE_ITEM | CAN_SWIM | F:MORTAL | ZANGBAND S:MULTIPLY D:Don't feed them after midnight! N:154:Yeti G:Y:w I:110:11d9:20:24:10 W:9:3:3500:30 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d4 F:OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | DROP_CORPSE | F:ANIMAL | IM_COLD | F:MORTAL | SUSCEP_FIRE | BASEANGBAND D:A large white figure covered in shaggy fur. N:155:Bloodshot icky thing G:i:r I:110:7d8:14:18:20 W:9:3:60:24 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:HURT:1d4 B:CRAWL:ACID:2d4 F:RAND_50 | F:EMPTY_MIND | CAN_SWIM | DROP_CORPSE | F:IM_POIS | BASEANGBAND S:1_IN_11 | S:DRAIN_MANA D:It is a strange, slimy, icky creature. N:156:Giant grey rat G:r:s I:110:2d3:8:12:20 W:9:1:250:2 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:1d4 F:RAND_25 | F:ANIMAL | IM_POIS | F:MORTAL | BASEANGBAND S:MULTIPLY D:It is a rodent of unusual size. N:157:Black harpy G:H:D I:120:3d8:16:22:10 W:9:1:600:19 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:1d2 B:CLAW:HURT:1d2 B:BITE:HURT:1d3 F:FEMALE | CAN_FLY | WILD_TOO | WILD_MOUNTAIN | DROP_CORPSE | F:RAND_25 | ANIMAL | EVIL | MORTAL | BASEANGBAND D:A woman's face on the body of a vicious black bird. N:158:Skaven G:r:G I:110:11d8:15:25:20 W:9:1:600:20 E:1:1:1:2:1:1 O:35:35:20:0 B:HIT:HURT:1d4 B:HIT:HURT:1d4 F:EVIL | FRIENDS | DROP_60 | DROP_90 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | MALE | WILD_TOO | WILD_WASTE | WILD_SWAMP | F:MORTAL | ZANGBAND D:A mutated rat-creature from the great waste, it is vaguely D:humanoid in appearance and walks on its hind legs. This race D:serves chaos fervently and is greatly feared by others. N:159:The wounded bear G:q:r I:110:11d10:10:35:10 W:12:1:3000:30 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d10 B:CLAW:HURT:1d10 B:BITE:HURT:1d11 F:BASH_DOOR | FORCE_MAXHP | FORCE_SLEEP | UNIQUE | DROP_CORPSE | F:ANIMAL | WILD_ONLY | WILD_WOOD | WILD_GRASS | WILD_MOUNTAIN | F:MORTAL | BASEANGBAND D:A wounded bear, who has occasionally attacked humans. N:160:Cave bear G:q:u I:110:8d8:10:35:10 W:9:1:3000:25 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d6 B:CLAW:HURT:1d6 B:BITE:HURT:1d8 F:BASH_DOOR | FORCE_MAXHP | FORCE_SLEEP | DROP_CORPSE | F:ANIMAL | WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | F:MORTAL | BASEANGBAND D:A large bear appears to have made its home in this cave. It is hungry, D:and you are trespassing in its territory. N:161:Rock mole G:r:s I:110:10d10:20:30:75 W:9:2:60:25 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d10 B:BITE:HURT:1d10 F:WEIRD_MIND | BASH_DOOR | KILL_WALL | KILL_ITEM | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:Despite its unimpressive size, this mole creature has fangs powerful D:enough to bore through solid rock. N:162:Mindcrafter G:p:y I:110:9d8:20:15:20 W:16:2:1700:50 E:1:1:1:2:1:1 O:30:40:30:0 B:HIT:HURT:2d4 B:HIT:HURT:2d4 F:MALE | F:FORCE_SLEEP | DROP_90 | WILD_TOO | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 | S:CONF | BLIND | HOLD | SLOW | MIND_BLAST | S_MONSTER | BLINK D:A master of the mental arts, able to damage or dominate the D:minds of others. N:163:Baby blue dragon G:d:b I:110:10d10:20:30:70 W:9:2:4000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | DROP_1D2 | HAS_EGG | IMPRESED | F:OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | DRAGON | IM_ELEC | BASEANGBAND | ATTR_MULTI | ATTR_MULTI S:1_IN_12 | S:BR_ELEC D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales a pale blue. N:164:Baby white dragon G:d:w I:110:10d10:20:30:70 W:9:2:4000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | CAN_FLY | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | ATTR_MULTI F:EVIL | DRAGON | IM_COLD | SUSCEP_FIRE | HAS_EGG | IMPRESED | BASEANGBAND F:ATTR_MULTI S:1_IN_12 | S:BR_COLD D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales a pale white. N:165:Baby green dragon G:d:g I:110:10d10:20:30:70 W:9:2:4000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | CAN_FLY | DROP_CORPSE | F:EVIL | DRAGON | IM_POIS | HAS_EGG | IMPRESED | BASEANGBAND | ATTR_MULTI S:1_IN_12 | S:BR_POIS D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales a sickly green. N:166:Baby black dragon G:d:s I:110:10d10:20:30:70 W:9:2:4000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | CAN_FLY | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_ACID | HAS_EGG | IMPRESED | BASEANGBAND | ATTR_MULTI S:1_IN_12 | S:BR_ACID D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales a dull black. N:167:Baby red dragon G:d:r I:110:10d10:20:30:70 W:9:2:4000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | CAN_FLY | DROP_CORPSE | SUSCEP_COLD | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_FIRE | HAS_EGG | IMPRESED | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_11 | S:BR_FIRE D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales a pale red. N:168:Giant red ant G:a:r I:110:4d8:12:34:60 W:9:2:600:22 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d4 B:STING:LOSE_STR:1d4 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | DROP_SKELETON F:ANIMAL | MORTAL | BASEANGBAND | HAS_LITE D:It is large and has venomous mandibles. N:169:Brodda, the Easterling G:p:U I:110:24d10:20:25:20 W:9:2:2200:100 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:1d13 B:HIT:HURT:1d13 B:HIT:HURT:1d13 B:HIT:HURT:1d13 F:UNIQUE | MALE | EVIL F:FORCE_MAXHP | CAN_SPEAK | WILD_TOO | DROP_SKELETON | DROP_CORPSE F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR F:MORTAL | BASEANGBAND | HAS_LITE D:A nasty piece of work, Brodda picks on defenceless women and children. N:170:Bloodfang, the Wolf G:C:R I:120:8d6:30:30:20 W:9:1:1600:30 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d12 B:BITE:HURT:1d12 F:BASH_DOOR | WILD_ONLY | WILD_GRASS | WILD_WOOD | DROP_CORPSE | F:ANIMAL | UNIQUE | FORCE_MAXHP | F:MORTAL | BASEANGBAND D:It has been terrorising the nearby villages. N:171:King cobra G:J:g I:110:8d10:8:30:1 W:9:2:300:28 E:0:0:0:0:1:0 O:0:0:0:0 B:SPIT:BLIND:1d2 B:BITE:POISON:3d4 F:RAND_50 | WILD_TOO | WILD_SWAMP | WILD_WOOD | DROP_SKELETON | DROP_CORPSE | F:BASH_DOOR | CAN_SWIM | ANIMAL | IM_POIS | HAS_EGG | MORTAL | BASEANGBAND D:It is a large snake with a hooded face. N:172:Eagle G:B:u I:120:9d9:30:25:10 W:12:2:600:22 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d6 F:ANIMAL | CAN_FLY | WILD_ONLY | WILD_WASTE | WILD_MOUNTAIN | WILD_WOOD | F:DROP_CORPSE | MORTAL | BASEANGBAND | HAS_EGG D:A magnificent huge predatory bird. N:173:War bear G:q:u I:110:10d10:10:35:10 W:9:1:2000:25 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d4 B:CLAW:HURT:1d4 B:BITE:HURT:1d6 F:WEIRD_MIND | BASH_DOOR | FRIENDS | DROP_SKELETON | DROP_CORPSE F:ANIMAL F:MORTAL | BASEANGBAND D:Bears with tusks, trained to kill. N:174:Killer bee G:I:y I:120:2d4:12:34:10 W:9:2:50:22 E:0:0:0:0:0:0 O:0:0:0:0 B:STING:POISON:1d4 B:STING:LOSE_STR:1d4 F:WEIRD_MIND | FRIENDS | CAN_FLY | WILD_TOO | F:ANIMAL | MORTAL | BASEANGBAND D:It is poisonous and aggressive. N:175:Giant spider G:S:v I:110:10d10:8:16:80 W:10:2:700:35 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d10 B:BITE:POISON:1d6 B:BITE:POISON:1d6 B:BITE:HURT:1d10 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | DROP_SKELETON | F:ANIMAL | SPIDER | IM_POIS | F:MORTAL | BASEANGBAND D:It is a vast spider whose bulbous body is bloated with poison. N:176:Giant white tick G:S:w I:100:12d8:12:40:20 W:10:2:200:27 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:2d6 F:WEIRD_MIND | BASH_DOOR | CAN_FLY | F:ANIMAL | IM_POIS | F:MORTAL | BASEANGBAND D:It is moving slowly towards you. N:177:The Borshin G:g:w I:110:12d20:40:30:0 W:10:2:600:45 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:2d12 B:CRUSH:HURT:2d15 B:TOUCH:TERRIFY F:BASH_DOOR | UNIQUE | FORCE_MAXHP | NO_CONF F:IM_POIS | IM_COLD | NO_FEAR F:MORTAL | CTHANGBAND | NO_CUT D:Pallid and twisted, this creature hates the very sight of you. D:"It looked like something that had started out to be a man but had never D:quite made it. It had been stepped on, twisted, had holes poked into the D:sickly dough of its head-bulge. Bones showed through the transparent flesh D:of its torso and its short legs were as thick as trees, terminating in D:disk-shaped pads from which dozens of long toes hung like roots or worms. D:its arms were longer than its entire body. it was a crushed slug, a thing D:that had been frozen and thawed before it was fully baked. It was - D:'It is the Borshin', said the Lord of Bats." N:178:Dark elven mage G:h:r I:120:7d10:20:16:20 W:10:1:1200:50 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:MALE | F:FORCE_SLEEP | F:ONLY_ITEM | DROP_1D2 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_POIS | HURT_LITE | BASEANGBAND | HAS_LITE S:1_IN_5 | S:BLIND | CONF | MISSILE | DARKNESS | BA_POIS D:A dark elven figure, dressed all in black, hurling spells at you. N:179:Kamikaze yeek G:y:r I:113:4d8:18:18:10 W:10:1:800:10 E:1:1:1:2:1:1 O:0:0:0:0 B:EXPLODE:HURT:15d2 F:OPEN_DOOR | BASH_DOOR | F:ANIMAL | IM_ACID | F:MORTAL | ZANGBAND D:The evil wizard Bruce has trained them to be living weapons. N:180:Orfax, Son of Boldor G:y:B I:120:14d10:18:20:10 W:11:3:600:80 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:1d10 B:HIT:HURT:1d9 B:INSULT:* B:INSULT:* F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | ESCORTS | F:ONLY_ITEM | DROP_90 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | F:ANIMAL | EVIL | IM_ACID | F:MORTAL | BASEANGBAND S:1_IN_4 | S:HEAL | BLINK | TELE_TO | SLOW | CONF | S:S_MONSTER D:He's just like his daddy! He knows mighty spells, but fortunately he is a D:yeek. N:181:Servant of Glaaki G:z:G I:110:9d9:20:20:20 W:10:1:600:25 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:1d8 B:CLAW:DISEASE:1d3 F:OPEN_DOOR | BASH_DOOR | FRIENDS | HURT_LITE | F:NO_CONF | NO_SLEEP | UNDEAD | EVIL | NO_FEAR | IM_POIS | F:IM_COLD | COLD_BLOOD | CTHANGBAND | NO_CUT S:1_IN_12 S:CAUSE_1 | SCARE D:"...the hand of a corpse -- bloodless and skeletal, and with D:impossibly long, cracked nails." N:182:Dark elven warrior G:h:u I:110:10d11:20:16:20 W:10:1:1400:50 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:MALE | F:DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | HURT_LITE | BASEANGBAND | HAS_LITE S:1_IN_12 S:MISSILE D:A dark elven figure in armour, ready with his sword. N:183:Sand-dweller G:u:y I:110:9d9:20:20:20 W:10:1:600:30 E:1:1:1:2:1:1 O:20:50:20:5 B:CLAW:HURT:1d6 B:CLAW:HURT:1d6 F:FRIENDS | WILD_TOO | WILD_WASTE | DROP_SKELETON | F:OPEN_DOOR | BASH_DOOR | HURT_LITE | EVIL | DROP_60 | DROP_90 | F:MALE F:MORTAL | CTHANGBAND D:"Rough-skinned, large-eyed, large-eared, with a horrible, D:distorted resemblance to the koala bear facially, though D:his body had an appearance of emaciation." N:184:Clear mushroom patch G:,:B I:120:1d1:4:1:0 W:10:2:30:3 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:HURT:1d1 F:ATTR_CLEAR | F:NEVER_MOVE | INVISIBLE | COLD_BLOOD | F:STUPID | EMPTY_MIND | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:MULTIPLY D:Yum! It smells quite tasty. If you could only see it... N:185:Quiver slot G:,:U I:120:1d1:4:1:0 W:10:2:60:3 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:CONFUSE:1d1 F:NEVER_MOVE | COLD_BLOOD | F:STUPID | EMPTY_MIND | F:NO_CONF | NO_SLEEP | NO_FEAR | JOKEANGBAND | NO_CUT S:MULTIPLY | S:1_IN_5 | ARROW_1 D:What looks like the remains of a quiver dropped by a past adventurer D:has become overgrown with a strange mold intent on using the contents D:of the quiver to grab prey. N:186:Grishnakh, the Hill Orc G:o:y I:110:25d10:20:20:20 W:10:3:2300:160 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d13 B:HIT:HURT:1d11 B:HIT:HURT:1d13 B:HIT:HURT:1d11 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | SPECIAL_GENE | F:ESCORT | WILD_TOO | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:He is a cunning and devious orc with a chaotic nature. N:187:Giant tan bat G:b:U I:130:3d8:12:20:50 W:10:2:600:18 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:TERRIFY:1d3 B:CLAW:HURT:1d2 B:CLAW:HURT:1d2 F:RAND_50 | CAN_FLY | WILD_TOO | WILD_MOUNTAIN | WILD_WOOD | F:FORCE_SLEEP | ANIMAL | DROP_CORPSE | AI_ANNOY | F:MORTAL | BASEANGBAND D:A giant bat, the beating of whose wings produces a strangely unnerving noise. N:188:Owlbear G:H:o I:110:12d12:20:20:20 W:10:1:2000:35 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:CRUSH:HURT:1d10 F:EVIL | ANIMAL | OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:MORTAL | BASEANGBAND D:A bizarre bear-creature with the claws and the face of an owl. N:189:Blue horror G:u:B I:110:14d9:20:35:20 W:10:3:1200:25 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:TERRIFY:1d8 B:CLAW:TERRIFY:1d8 F:FRIENDS | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DEMON | IM_FIRE | NO_FEAR | NO_CONF | ZANGBAND D:An ugly screaming little demon servant of Tzeentch. N:190:Hairy mold G:m:o I:110:15d8:2:15:70 W:10:1:50:32 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:POISON:1d3 F:NEVER_MOVE | CAN_SWIM | F:STUPID | EMPTY_MIND | F:IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a strange hairy growth on the dungeon floor. N:191:Grizzly bear G:q:U I:110:15d15:10:35:10 W:16:2:2600:55 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d8 B:CLAW:HURT:1d8 B:BITE:HURT:1d12 B:CRUSH:HURT:1d10 F:WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | DROP_CORPSE | F:ANIMAL | BASH_DOOR | F:MORTAL | BASEANGBAND D:A huge, beastly bear, more savage than most of its kind. N:192:Disenchanter mold G:m:v I:110:16d8:2:20:70 W:10:1:40:40 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:UN_BONUS:1d6 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | RES_DISE | F:IM_POIS | ATTR_MULTI | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_11 | S:DRAIN_MANA D:It is a strange glowing growth on the dungeon floor. N:193:Pseudo dragon G:d:o I:110:20d10:20:30:40 W:10:2:10000:150 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | CAN_FLY | DROP_CORPSE | F:DROP_60 | BASH_DOOR | HAS_EGG | F:EVIL | DRAGON | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_11 | S:CONF | SCARE | BR_LITE | BR_DARK D:A small relative of the dragon that inhabits dark caves. N:194:Tengu G:u:b I:120:16d9:20:32:30 W:10:1:600:40 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d8 F:OPEN_DOOR | BASH_DOOR | F:EVIL | DEMON | IM_FIRE | NO_FEAR | RES_TELE | CAN_FLY | BASEANGBAND S:1_IN_3 | S:BLINK | TELE_TO | TELE_AWAY | TPORT D:It is a fast-moving demon that blinks quickly in and out of existence; no D:other demon matches its teleporting mastery. N:195:Creeping gold coins G:$:y I:100:18d8:5:36:10 W:10:3:0:32 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:2d5 B:TOUCH:POISON:3d5 F:ONLY_GOLD | DROP_90 | DROP_1D2 | F:COLD_BLOOD | BASH_DOOR | F:IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:It appears to be a pile of gold coins, until it starts crawling towards you D:on tiny legs. N:196:Wolf G:C:u I:120:6d6:30:30:20 W:10:1:600:30 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 F:RAND_25 | FRIENDS | F:BASH_DOOR | WILD_TOO | WILD_WOOD | WILD_WASTE | WILD_MOUNTAIN | F:ANIMAL | DROP_CORPSE | F:MORTAL | BASEANGBAND D:It howls and snaps at you. N:197:Giant fruit fly G:I:G I:120:2d2:8:14:10 W:10:3:100:4 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:HURT:1d2 F:RAND_50 | RAND_25 | CAN_FLY | WEIRD_MIND | F:ANIMAL | MORTAL | BASEANGBAND S:MULTIPLY D:A fast-breeding, annoying pest. N:198:Panther G:f:D I:120:10d8:40:30:0 W:10:2:1300:25 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d8 B:CLAW:HURT:1d8 F:BASH_DOOR | WILD_TOO | WILD_WOOD | WILD_GRASS | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:A large black cat, stalking you with intent. It thinks you're its next D:meal. N:199:Brigand G:p:b I:110:9d8:20:32:10 W:10:2:1700:35 E:1:1:1:2:1:1 O:25:60:0:0 B:HIT:HURT:2d4 B:TOUCH:EAT_ITEM F:MALE | F:DROP_1D2 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | DROP_SKELETON | F:MORTAL | BASEANGBAND | HAS_LITE D:He is eyeing your backpack. N:200:Hobbes the Tiger G:f:y I:120:12d10:40:30:0 W:10:2:1600:45 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d12 B:CLAW:HURT:1d12 B:BITE:HURT:1d5 F:BASH_DOOR | UNIQUE | FORCE_MAXHP | F:ANIMAL | MALE | CAN_SPEAK | DROP_CORPSE | F:MORTAL | JOKEANGBAND D:Fast-moving, with a taste for tuna sandwiches. N:201:Shadow Creature of Fiona G:h:s I:110:11d8:12:12:16 W:10:2:1000:35 E:1:1:1:2:1:1 O:20:30:50:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:BASH_DOOR | OPEN_DOOR | FRIENDS | DROP_60 | IM_POIS | NO_SLEEP | NO_CONF F:MALE | DROP_SKELETON | ZANGBAND D:"There was something unusual about their appearance... For one thing, D:all had uniformly bloodshot eyes. Very, very bloodshot eyes. With them, D:though, the condition seemed normal. For another, all had an extra joint D:to each finger and thumb, and sharp, forward-curving spurs on the backs D:of their hands. All of them had prominent jaws and forty-four teeth, D:most of them longer than human teeth, and several looking to be much D:sharper. Their flesh was grayish and hard and shiny. There were D:undoubtedly other differences also, but those were sufficient to prove D:a point of some sort." N:202:Undead mass G:j:u I:110:8d8:70:12:5 W:10:2:200:33 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:DISEASE:1d6 B:TOUCH:LOSE_CON:1d6 F:UNDEAD | EMPTY_MIND | NO_CONF | NO_SLEEP | IM_POIS | IM_COLD | NO_FEAR | F:HURT_LITE | COLD_BLOOD | EVIL | NEVER_MOVE | BASEANGBAND | NO_CUT S:MULTIPLY D:A sickening mound of decaying flesh, bones, hands and so on. It seems to D:be growing. N:203:Chaos shapechanger G:H:v I:110:20d9:10:14:12 W:11:2:0:38 E:1:1:1:2:1:1 O:20:50:20:6 B:HIT:HURT:1d5 B:HIT:HURT:1d5 B:HIT:CONFUSE:1d3 F:DROP_60 | EVIL | SHAPECHANGER | ATTR_MULTI | ATTR_ANY F:MORTAL | ZANGBAND S:1_IN_5 S:BO_FIRE | BO_COLD | CONF D:A vaguely humanoid form constantly changing its appearance. N:204:Baby multi-hued dragon G:d:v I:110:13d10:20:30:70 W:11:2:5000:45 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d4 B:CLAW:HURT:1d4 B:BITE:HURT:1d6 F:ATTR_MULTI | F:FORCE_MAXHP | FORCE_SLEEP | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:EVIL | DRAGON | CAN_FLY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | HAS_EGG | IMPRESED | F:BASEANGBAND | HAS_LITE S:1_IN_12 | S:BR_ACID | BR_FIRE | BR_COLD | BR_ELEC | BR_POIS D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales shimmering with a hint of colour. N:205:Vorpal bunny G:r:w I:120:10d10:40:40:0 W:11:3:600:40 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:6d1 B:BITE:HURT:7d1 F:BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | DROP_CORPSE | F:ANIMAL | MORTAL | ZANGBAND S:1_IN_8 S:BLINK D:It looks very cute, except for the razor sharp teeth. It moans D:ominously as it jumps at your throat! N:206:Old Man Willow G:#:s I:110:32d30:20:20:20 W:25:5:3000:150 E:1:1:1:2:1:1 O:0:50:50:0 B:TOUCH:PARALYZE:1d14 B:TOUCH:PARALYZE:1d14 B:CRUSH:HURT:2d12 F:ANIMAL | NEVER_MOVE | COLD_BLOOD | DROP_RANDART F:EMPTY_MIND | UNIQUE | FORCE_MAXHP | FORCE_SLEEP | F:RES_WATE | IM_POIS | IM_ACID | SUSCEP_FIRE | SPECIAL_GENE | F:DROP_1D2 | DROP_GOOD | ONLY_ITEM | BASEANGBAND | NO_CUT S:1_IN_10 | S:TELE_TO | HOLD | D:The ancient grey willow tree, ruler of the Old Forest. He despises D:trespassers in his territory. "...a huge willow-tree, old and hoary. D:Enormous it looked, its sprawling branches going up like racing arms D:with may long-fingered hands, its knotted and twisted trunk gaping in D:wide fissures that creaked faintly as the boughs moved." N:207:Hippocampus G:H:B I:110:20d9:12:14:10 W:11:1:900:30 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:2d5 B:BITE:HURT:2d5 F:AQUATIC | WILD_TOO | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:A truly strange hybrid of a horse and a fish. N:208:Zombified orc G:z:s I:110:11d8:20:24:25 W:11:1:1800:30 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d4 B:HIT:HURT:1d4 B:HIT:HURT:1d4 F:COLD_BLOOD | EMPTY_MIND | OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | UNDEAD | F:IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a shambling orcish corpse leaving behind a trail of flesh. N:209:Hippogryph G:H:U I:110:20d9:12:14:10 W:11:1:1500:30 E:0:1:0:2:1:0 O:0:0:0:0 B:HIT:HURT:2d5 B:BITE:HURT:2d5 F:BASH_DOOR | CAN_FLY | WILD_TOO | WILD_MOUNTAIN | WILD_GRASS | F:ANIMAL | DROP_CORPSE | MORTAL | BASEANGBAND D:A strange hybrid of eagle and horse. It looks weird. N:210:Black mamba G:J:D I:120:10d8:10:32:1 W:12:3:300:40 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:POISON:4d4 F:RAND_50 | BASH_DOOR | CAN_SWIM | F:WILD_TOO | WILD_WOOD | WILD_GRASS | WILD_SWAMP | F:ANIMAL | IM_POIS | DROP_SKELETON | DROP_CORPSE | HAS_EGG | F:MORTAL | BASEANGBAND D:It has glistening black skin, a sleek body, and highly venomous fangs. N:211:White wolf G:C:w I:120:7d7:30:30:20 W:12:1:700:30 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d3 B:BITE:HURT:1d4 F:RAND_25 | F:FRIENDS | SUSCEP_FIRE | F:BASH_DOOR | WILD_TOO | WILD_WASTE | F:ANIMAL | IM_COLD | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND D:A large and muscled wolf from the northern wastes. Its breath is cold and D:icy and its fur coated in frost. N:212:Grape jelly G:j:v I:110:52d8:2:1:99 W:12:3:2600:60 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:EXP_10 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:IM_POIS | HURT_LITE | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_11 | S:DRAIN_MANA D:Yum! It looks quite tasty. It is a pulsing mound of glowing flesh. N:213:Nether worm mass G:w:D I:100:5d8:10:15:3 W:12:4:200:6 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:EXP_10 F:RAND_50 | RAND_25 | CAN_SWIM | F:STUPID | WEIRD_MIND | BASH_DOOR | F:ANIMAL | HURT_LITE | NO_FEAR | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a disgusting mass of dark worms, eating each other, the floor, D:the air, you... N:214:Abyss worm mass G:w:D I:100:5d8:10:15:3 W:12:4:200:7 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:EXP_10 F:RAND_50 | RAND_25 | F:STUPID | WEIRD_MIND | BASH_DOOR | EVIL | CAN_SWIM | F:ANIMAL | HURT_LITE | NO_FEAR | KILL_WALL | COLD_BLOOD | INVISIBLE | F:MORTAL | ZANGBAND | NO_CUT S:MULTIPLY D:Even more disgusting dark worms, their essence that of unbeing. N:215:Golfimbul, the Hill Orc Chief G:o:y I:110:26d10:20:60:20 W:12:3:2200:230 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:1d13 B:HIT:HURT:1d13 B:HIT:HURT:1d11 B:HIT:HURT:1d11 F:UNIQUE | MALE | F:FORCE_MAXHP | WILD_TOO | SPECIAL_GENE | F:ESCORT | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | CAN_SPEAK | F:EVIL | ORC | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:A leader of a band of raiding orcs, he picks on hobbits. N:216:Swordsman G:p:u I:110:12d8:20:34:20 W:12:1:1800:40 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:MALE | WILD_TOO | F:DROP_1D2 | DROP_SKELETON | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR F:MORTAL | BASEANGBAND | HAS_LITE D:A warrior of considerable skill. N:217:Skaven shaman G:r:g I:110:10d8:20:15:20 W:12:1:600:36 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:1d7 B:HIT:HURT:1d7 F:MALE | WILD_TOO | WILD_SWAMP | WILD_WASTE | F:FORCE_SLEEP | DROP_90 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | MORTAL | ZANGBAND S:1_IN_8 | S:BLINK | CAUSE_1 | MISSILE | CONF | SCARE D:The shaman of a skaven tribe gets his powers from a mystic D:stone corrupted by chaos, called a Warp Stone. N:218:Baby bronze dragon G:d:U I:110:10d10:20:30:70 W:9:2:4000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | CAN_FLY | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | NO_CONF | HAS_EGG | IMPRESED | BASEANGBAND | ATTR_MULTI S:1_IN_12 | S:BR_CONF D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales a dull bronze. N:219:Baby gold dragon G:d:y I:110:10d10:20:30:70 W:9:2:4000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | CAN_FLY | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | NO_STUN | HAS_EGG | IMPRESED | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_12 | S:BR_SOUN D:This hatchling dragon is still soft, its eyes unaccustomed to light and D:its scales a pale gold. N:220:Evil eye G:e:D I:110:15d8:2:6:10 W:18:3:600:80 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:EXP_10 B:GAZE:EXP_10 F:NEVER_MOVE | EVIL | CAN_FLY | DROP_CORPSE | F:HURT_LITE | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_7 | S:HOLD | TELE_TO D:A huge disembodied eye. As you stare into the black nothingness of its pupil, D:you feel your will and vitality draining away, and are unable to do anything D:except approach it in horrified fascination. N:221:Mine-dog G:C:u I:120:6d6:30:30:20 W:12:4:500:40 E:0:1:0:2:1:0 O:0:0:0:0 B:EXPLODE:HURT:6d6 F:RAND_50 | FRIENDS | BASH_DOOR | ANIMAL | F:MORTAL | ZANGBAND D:An explosive charge has been attached to this poor animal, who D:has been trained to search for its target and detonate. N:222:Hellcat G:f:R I:120:9d8:20:30:30 W:12:1:400:40 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d5 B:CLAW:HURT:1d5 B:BITE:HURT:1d8 F:ANIMAL | WEIRD_MIND | FRIENDS | RAND_25 | IM_FIRE | EVIL | SUSCEP_COLD | F:MORTAL | ZANGBAND | HAS_LITE D:It is as large as a tiger, and its yellow eyes are pupilless. N:223:Moon beast G:q:W I:120:9d10:30:30:20 W:12:1:800:57 E:0:1:0:2:1:0 O:50:0:40:5 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BUTT:HURT:1d6 F:DROP_1D2 | ONLY_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_FIRE | ANIMAL | DROP_CORPSE F:MORTAL | ZANGBAND S:1_IN_6 S:HEAL | BLIND | DARKNESS | CONF | CAUSE_2 D:"Great greyish-white slippery things which could expand and D:contract at will, and whose principle shape... was that of a D:sort of toad without any eyes, but with a curious vibrating mass D:of short pink tentacles on the end of its blunt, vague snout." N:224:Master yeek G:y:g I:110:12d9:18:24:10 W:12:2:600:28 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:1d8 F:FORCE_SLEEP | F:DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:ANIMAL | EVIL | IM_ACID | DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_4 | S:BLINK | TPORT | BLIND | SLOW | BA_POIS | S:S_MONSTER D:A small humanoid that radiates some power. N:225:Priest G:p:g I:110:12d8:20:22:40 W:12:1:1500:36 E:1:1:1:2:1:1 O:0:20:80:0 B:HIT:HURT:2d3 B:HIT:HURT:2d3 F:MALE | GOOD | F:FORCE_SLEEP | F:DROP_1D2 | F:SMART | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | SCARE | CAUSE_2 | S:S_MONSTER D:A robed man dedicated to his god. N:226:Dark elven priest G:h:g I:120:7d10:20:30:30 W:12:1:1200:50 E:1:1:1:2:1:1 O:0:10:90:0 B:HIT:HURT:1d9 B:HIT:HURT:1d10 F:MALE | F:FORCE_SLEEP | F:ONLY_ITEM | DROP_1D2 | F:SMART | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | HURT_LITE | BASEANGBAND | HAS_LITE S:1_IN_5 | S:HEAL | BLIND | CONF | CAUSE_2 | DARKNESS | MISSILE D:A dark elven figure, dressed all in black, chanting curses and waiting to D:deliver your soul to hell. N:227:Air spirit G:E:B I:130:8d8:12:40:20 W:12:2:0:40 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d3 F:RAND_50 | RAND_25 | IM_ELEC | IM_POIS | F:EMPTY_MIND | INVISIBLE | COLD_BLOOD | BASH_DOOR | F:IM_POIS | CAN_FLY | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:A whirlwind of sentient air. N:228:Skeleton human G:s:W I:110:10d8:20:30:30 W:12:1:1500:38 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d8 F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is an animated human skeleton. N:229:Zombified human G:z:s I:110:12d8:20:24:20 W:12:1:1500:34 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d4 B:HIT:HURT:1d4 F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a shambling human corpse dropping chunks of flesh behind it. N:230:Tiger G:f:o I:120:12d10:40:40:0 W:12:2:1500:40 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d8 B:CLAW:HURT:1d8 B:BITE:HURT:1d6 F:BASH_DOOR | WILD_TOO | WILD_GRASS | WILD_WOOD | WILD_MOUNTAIN | F:ANIMAL | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND D:One of the largest of its species, a sleek orange and black shape creeps D:towards you, ready to pounce. N:231:Moaning spirit G:G:u I:120:5d8:14:20:10 W:12:2:0:44 E:0:0:0:0:0:0 O:45:15:25:0 B:WAIL:TERRIFY B:TOUCH:LOSE_DEX:1d8 F:FORCE_SLEEP | RAND_25 | F:DROP_60 | DROP_90 | CAN_FLY | F:INVISIBLE | COLD_BLOOD | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:TPORT | SCARE D:A ghostly apparition that shrieks horribly. N:232:Stegocentipede G:c:u I:120:13d8:12:30:30 W:12:2:1200:40 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:2d4 B:BITE:HURT:2d4 B:STING:HURT:2d4 F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | DROP_SKELETON | MORTAL | BASEANGBAND D:It is a vast armoured centipede with massive mandibles and a spiked tail. N:233:Spotted jelly G:j:o I:120:13d8:12:18:1 W:12:3:2500:33 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:ACID:1d10 B:TOUCH:ACID:2d6 B:TOUCH:ACID:2d6 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | COLD_BLOOD | F:IM_ACID | IM_POIS | HURT_LITE | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:A strange jelly thing, covered in discoloured blotches. N:234:Drider G:S:b I:110:10d13:8:30:80 W:13:2:2000:55 E:1:1:1:2:1:0 O:0:0:0:0 B:HIT:HURT:1d12 B:HIT:HURT:1d12 B:BITE:POISON:1d6 F:FORCE_SLEEP | F:BASH_DOOR | DROP_SKELETON | F:EVIL | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_8 | S:CONF | CAUSE_1 | DARKNESS | MISSILE | ARROW_2 D:A dark elven torso merged with the bloated form of a giant spider. N:235:Mongbat G:b:U I:110:10d10:20:80:8 W:13:2:800:65 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:1d4 B:CLAW:HURT:1d4 B:BITE:POISON:1d8 F:ANIMAL | EVIL | FRIENDS | CAN_FLY | FORCE_MAXHP | F:IM_COLD | IM_ELEC | IM_POIS | WEIRD_MIND | DROP_CORPSE F:MORTAL | BASEANGBAND D:Devil-bats, notoriously difficult to kill. N:236:Killer brown beetle G:K:u I:110:13d8:10:40:30 W:13:1:500:38 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:3d4 F:WEIRD_MIND | BASH_DOOR | CAN_FLY | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:It is a vicious insect with a tough carapace. N:237:Boldor, King of the Yeeks G:y:v I:120:20d10:18:24:10 W:13:3:650:200 E:1:1:1:2:1:1 O:0:90:10:0 B:HIT:HURT:1d10 B:HIT:HURT:1d10 B:HIT:HURT:1d9 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | ESCORTS | F:ONLY_ITEM | DROP_90 | DROP_1D2 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | CAN_SPEAK | DROP_CORPSE | F:ANIMAL | EVIL | IM_ACID | F:MORTAL | BASEANGBAND S:1_IN_2 | S:HEAL | BLINK | TPORT | BLIND | SLOW | S:S_KIN | S_MONSTER D:A great yeek, powerful in magic and sorcery, but a yeek all the same. N:238:Ogre G:O:U I:110:13d9:20:33:30 W:13:2:2100:50 E:1:1:1:2:1:1 O:10:85:0:0 B:HIT:HURT:2d8 F:FRIENDS | F:DROP_60 | WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | F:MORTAL | BASEANGBAND | HAS_LITE D:A hideous, smallish giant that is often found near or with orcs. N:239:Creeping mithril coins G:$:B I:110:20d8:5:50:10 W:13:3:0:45 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:2d5 B:TOUCH:POISON:3d5 F:ONLY_GOLD | DROP_90 | DROP_2D2 | F:COLD_BLOOD | BASH_DOOR | IM_ACID | CHAR_MULTI | F:IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:It appears to be a pile of sentient mithril coins that doesn't like being D:picked up. N:240:Illusionist G:p:R I:110:12d8:20:10:10 W:13:2:1500:50 E:1:1:1:2:1:1 O:20:0:80:0 B:HIT:HURT:2d2 F:MALE | F:FORCE_SLEEP | DROP_1D2 | DROP_SKELETON | DROP_CORPSE F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HASTE | BLINK | TPORT | BLIND | HOLD | SLOW | CONF | DARKNESS D:A deceptive spell caster. N:241:Druid G:p:G I:110:12d12:20:10:10 W:13:2:1400:50 E:1:1:1:2:1:1 O:20:0:80:0 B:HIT:HURT:2d4 B:HIT:HURT:2d4 F:MALE | WILD_TOO | WILD_WOOD | F:FORCE_SLEEP | DROP_1D2 | DROP_SKELETON | DROP_CORPSE F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HASTE | BLINK | BLIND | HOLD | SLOW | BO_FIRE | BO_ELEC | S_ANIMAL D:A priest devoted to Nature. N:242:Pink horror G:u:R I:110:15d9:20:35:20 W:13:3:1200:64 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:TERRIFY:1d8 B:CLAW:TERRIFY:1d8 B:BITE:CONFUSE:1d6 F:FRIENDS | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DEMON | IM_FIRE | NO_FEAR | NO_CONF | ZANGBAND S:1_IN_8 | S:CONF | SCARE D:An ugly screaming little demon servant of Tzeentch. N:243:Cloaker G:(:g I:130:7d7:20:40:0 W:13:5:60:30 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:PARALYZE:5d5 B:HIT:TERRIFY:5d5 F:NEVER_MOVE | NO_FEAR | F:STUPID | EMPTY_MIND | COLD_BLOOD | CHAR_MULTI | NO_CONF | NO_SLEEP | F:DROP_90 | IM_COLD | FORCE_MAXHP | IM_ELEC | IM_POIS | F:BASEANGBAND | NO_CUT D:It resembles a normal cloak until some poor fool ventures too close! N:244:Black orc G:o:D I:110:12d10:20:36:20 W:13:1:2000:45 E:1:1:1:2:1:1 O:10:50:20:15 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:MALE | WILD_TOO | DROP_SKELETON | DROP_CORPSE | F:FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | HURT_LITE | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_9 S:ARROW_2 D:He is a large orc with powerful arms and deep black skin. N:245:Ochre jelly G:j:U I:120:13d8:12:18:1 W:13:3:2300:40 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:ACID:1d10 B:TOUCH:ACID:2d6 B:TOUCH:ACID:2d6 F:STUPID | EMPTY_MIND | COLD_BLOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_POIS | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:A fast moving highly acidic jelly thing, that is eating away the floor it D:rests on. N:246:Software bug G:I:r I:120:2d2:8:25:10 W:14:1:0:4 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:HURT:1d2 F:RAND_50 | RAND_25 | F:WEIRD_MIND | BASH_DOOR | CAN_FLY | F:ANIMAL | MORTAL | JOKEANGBAND S:MULTIPLY D:Oh no! They are everywhere! N:247:Lurker G:.:w I:110:20d10:30:25:10 W:14:3:0:80 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:CHAR_CLEAR | ATTR_CLEAR | CHAR_MULTI | F:NEVER_MOVE | FORCE_MAXHP | F:EMPTY_MIND | INVISIBLE | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND D:A strange creature that merges with the dungeon floor, trapping its D:victims by enveloping them within its perfectly disguised form. N:248:Tangleweed G:#:g I:100:5d5:5:5:5 W:10:4:50:10 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:PARALYZE B:HIT:PARALYZE F:FORCE_SLEEP | NEVER_MOVE | STUPID | EMPTY_MIND | FRIENDS | F:KILL_TREES | SUSCEP_FIRE | ANIMAL | F:WILD_ONLY | COLD_BLOOD | WILD_WOOD | WILD_GRASS | F:NO_CONF | NO_SLEEP | NO_FEAR | MORTAL | BASEANGBAND | DROP_60 | NO_CUT D:A mass of vegetation. As you pass near it, it reaches out tendrils to D:ensnare you. You can just make out skeletons of its previous victims D:deep within the thickets. N:249:Vlasta G:R:B I:120:12d6:12:20:12 W:14:3:1000:40 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:BLIND:1d10 B:BITE:BLIND:1d10 F:OPEN_DOOR | DROP_SKELETON | DROP_CORPSE | F:MORTAL | ZANGBAND D:This strange creature looks like a miniature tyrannosaur. It has D:empty, pale eyes and a sharp beak, which it aims at your eyes D:as it jumps at you! N:250:Giant white dragon fly G:F:w I:110:3d8:12:20:50 W:14:2:150:60 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:COLD:1d6 F:FORCE_SLEEP | WILD_TOO | WILD_WASTE | F:RAND_50 | CAN_FLY | SUSCEP_FIRE | F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | IM_COLD | F:MORTAL | BASEANGBAND S:1_IN_10 | S:BR_COLD D:It is a large fly that drips frost. N:251:Snaga sapper G:o:U I:111:8d8:20:32:30 W:14:1:80:15 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d8 B:EXPLODE:HURT:20d2 F:MALE | F:WILD_TOO | SUSCEP_FIRE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | HURT_LITE | F:MORTAL | ZANGBAND | HAS_LITE D:He is one of the many weaker 'slave' orcs, often mistakenly known as a D:goblin. He is equipped with an explosive charge. N:252:Blue icky thing G:i:b I:100:10d6:15:20:20 W:14:4:600:20 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:POISON:1d4 B:CRAWL:EAT_FOOD B:HIT:HURT:1d4 B:HIT:HURT:1d4 F:FORCE_SLEEP | F:RAND_50 | F:OPEN_DOOR | BASH_DOOR | CAN_SWIM | DROP_CORPSE | F:EVIL | IM_POIS | BASEANGBAND S:MULTIPLY | S:1_IN_8 | S:BLIND | CONF | SCARE D:It is a strange, slimy, icky creature, with rudimentary intelligence, D:but evil cunning. It hungers for food, and you look tasty. N:253:Gibbering mouther G:j:o I:110:8d6:15:20:20 W:14:4:2600:20 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:POISON:1d4 F:NEVER_MOVE | EVIL | CAN_SWIM | F:IM_POIS | EMPTY_MIND | NO_FEAR | BASEANGBAND | NO_CUT S:MULTIPLY | S:1_IN_7 | S:SCARE | CONF | BR_LITE D:A chaotic mass of pulsating flesh, mouths and eyes. N:254:Wolfhound of Flora G:C:s I:120:9d9:20:20:0 W:14:2:1600:40 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d5 B:BITE:HURT:1d5 F:ANIMAL | NO_FEAR | FRIENDS | DROP_SKELETON | DROP_CORPSE | F:MORTAL | ZANGBAND D:Well-trained watchdogs, obedient to death. N:255:Hill giant G:P:U I:110:30d15:20:45:50 W:25:1:3500:150 E:1:1:1:2:1:1 O:20:50:20:5 B:HIT:HURT:4d8 B:HIT:HURT:4d8 F:DROP_60 | WILD_TOO | WILD_MOUNTAIN | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | MALE | F:MORTAL | BASEANGBAND | HAS_LITE D:A ten foot tall humanoid with powerful muscles. N:256:Flesh golem G:g:R I:110:12d8:12:30:10 W:14:2:3000:50 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:EMPTY_MIND | BASH_DOOR | CAN_SWIM | F:IM_ELEC | IM_COLD | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | F:MORTAL | BASEANGBAND | NO_CUT D:A shambling humanoid monster with long scars. N:257:Warg G:C:D I:120:8d8:20:20:40 W:16:2:700:40 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 B:BITE:HURT:1d6 F:RAND_25 | BASH_DOOR | FRIENDS | F:WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | EVIL | MORTAL | BASEANGBAND D:It is a large wolf with eyes full of cunning. N:258:Cheerful leprechaun G:h:G I:120:2d5:8:6:6 W:14:2:800:23 E:1:1:1:2:1:1 O:0:0:0:0 B:TOUCH:EAT_GOLD B:TOUCH:EAT_FOOD F:DROP_60 | ONLY_GOLD | RAND_50 | OPEN_DOOR | MALE | F:GOOD | MORTAL | ZANGBAND S:MULTIPLY | S:1_IN_6 | S:BLINK D:A merry little gnome. N:259:Giant flea G:I:s I:120:1d2:6:7:10 W:14:3:90:3 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:HURT:1d2 F:RAND_50 | CAN_FLY | WEIRD_MIND | F:ANIMAL | MORTAL | BASEANGBAND S:MULTIPLY D:It makes you itch just to look at it. N:260:Ufthak of Cirith Ungol G:o:g I:110:34d10:20:50:20 W:14:3:2600:250 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:UNIQUE | MALE | F:FORCE_MAXHP | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE | F:ESCORT | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_COLD | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:A strong orc guarding the pass of Cirith Ungol. He is mortally afraid of D:spiders: he was captured by Shelob once, but escaped when she forgot D:completely about him. N:261:Clay golem G:g:U I:110:14d8:12:30:10 W:15:2:3200:60 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_ROCK | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a massive animated statue made out of hardened clay. N:262:Black ogre G:O:D I:110:20d9:20:33:30 W:15:2:2300:70 E:1:1:1:2:1:1 O:0:70:0:15 B:HIT:HURT:2d8 B:HIT:HURT:2d8 F:RAND_25 | WILD_TOO | WILD_MOUNTAIN | DROP_CORPSE | F:FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | F:MORTAL | BASEANGBAND | HAS_LITE D:A massive orc-like figure with black skin and powerful arms. N:263:Dweller on the threshold G:Y:s I:110:30d8:30:30:20 W:15:5:3000:50 E:1:1:1:2:1:1 O:45:0:40:10 B:GAZE:PARALYZE:4d4 B:GAZE:TERRIFY:3d3 B:GAZE:CONFUSE:3d3 F:NEVER_MOVE | DROP_60 | EVIL | DEMON | DROP_CORPSE | F:IM_POIS | IM_COLD |IM_FIRE | NO_FEAR | NO_CONF | NO_SLEEP F:MORTAL | ZANGBAND S:1_IN_6 S:BO_ACID | S_MONSTER | SCARE | DRAIN_MANA D:A gorilla-shaped arcane guardian with an appetite for mages. N:264:Half-orc G:o:s I:110:16d10:20:40:20 W:15:2:1700:50 E:1:1:1:2:1:1 O:30:30:30:5 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:MALE | WILD_TOO | F:FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | ORC | MORTAL | BASEANGBAND | HAS_LITE D:He is a hideous deformed cross-breed of man and orc, combining man's D:strength and cunning with orcish evil. The traitorous wizard Saruman is D:generally believed to be responsible for this abomination. N:265:Dark naga G:n:s I:110:22d11:60:65:60 W:15:2:1900:90 E:0:0:0:0:1:0 O:0:0:80:20 B:STING:HURT:1d10 B:BITE:HURT:1d10 F:FEMALE | F:RAND_25 | DROP_60 | DROP_1D2 | IM_POIS | IM_COLD | RES_WATE | F:OPEN_DOOR | BASH_DOOR | EMPTY_MIND | CAN_SWIM | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND S:1_IN_8 S:HOLD | CONF | BO_COLD | HEAL | DARKNESS D:A giant snake-like figure with a woman's torso, talented in magic. N:266:Poison ivy G:#:g I:100:5d5:5:5:5 W:10:4:50:10 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:POISON:2d2 B:HIT:POISON:2d2 F:FORCE_SLEEP | NEVER_MOVE | STUPID | EMPTY_MIND | FRIENDS | F:KILL_TREES | SUSCEP_FIRE | ANIMAL | F:WILD_ONLY | COLD_BLOOD | WILD_WOOD | WILD_GRASS | F:NO_CONF | NO_SLEEP | NO_FEAR | MORTAL | BASEANGBAND | DROP_60 | NO_CUT S:MULTIPLY D:A mass of vegetation. It seems to be growing... N:267:Magic mushroom patch G:,:B I:140:1d1:40:10:0 W:15:2:50:10 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:CONFUSE B:SPORE:CONFUSE B:SPORE:HALLU B:SPORE:HALLU F:FORCE_SLEEP | NEVER_MOVE | F:STUPID | RES_TELE | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_2 | S:BLINK | SLOW | SCARE | DARKNESS D:Yum! It looks quite tasty. It seems to glow with an unusual light. N:268:Plaguebearer of Nurgle G:z:o I:110:9d10:20:50:20 W:15:2:2800:75 E:1:1:1:2:1:1 O:50:20:20:10 B:CLAW:DISEASE:2d5 B:CLAW:DISEASE:2d5 B:BUTT:HURT:3d5 F:FORCE_MAXHP | DROP_60 | F:OPEN_DOOR | BASH_DOOR | IM_COLD | F:EVIL | DEMON | UNDEAD | IM_POIS | NONLIVING | ZANGBAND | NO_CUT S:1_IN_8 | S:SCARE | S_ANT | CAUSE_2 | SLOW D:An unfortunate individual, who was killed by the incurable D:disease known as Nurgle's Rot, and was transformed into a D:rotting demon zombie. It has but one eye, and a single D:pale horn in its forehead. N:269:Guardian naga G:n:y I:110:24d11:20:65:120 W:15:2:1900:80 E:0:0:0:0:1:0 O:0:0:80:20 B:CRUSH:HURT:2d8 B:BITE:HURT:1d8 B:BITE:HURT:1d8 F:FEMALE | F:RAND_25 | DROP_60 | DROP_1D2 | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR | CAN_SWIM | F:EVIL F:MORTAL | BASEANGBAND D:A giant snake-like figure with a woman's torso. N:270:Wererat G:r:D I:110:20d8:10:10:10 W:15:2:30:55 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d8 B:CLAW:HURT:1d8 B:BITE:HURT:2d6 F:FORCE_SLEEP | F:ONLY_GOLD | DROP_60 | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR | F:ANIMAL | EVIL F:MORTAL | BASEANGBAND S:1_IN_9 | S:BLINK | CAUSE_2 | BO_COLD | BA_POIS | S_KIN D:A large rat with glowing red eyes, which can also assume human form. The wererat D:is a disgusting creature, relishing in filth and disease. N:271:Light hound G:Z:o I:110:6d6:30:30:0 W:15:1:600:50 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d4 B:CLAW:HURT:1d4 B:BITE:HURT:1d6 F:FORCE_SLEEP | DROP_CORPSE | F:FRIENDS | F:BASH_DOOR | F:ANIMAL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_5 | S:BR_LITE D:A brilliant canine form whose light hurts your eyes, even at this distance. N:272:Dark hound G:Z:D I:110:6d6:30:30:0 W:15:1:600:50 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d4 B:CLAW:HURT:1d4 B:BITE:HURT:1d6 F:FORCE_SLEEP | DROP_CORPSE | F:FRIENDS | F:BASH_DOOR | HURT_LITE | F:ANIMAL | MORTAL | BASEANGBAND S:1_IN_5 | S:BR_DARK D:A hole in the air in the shape of a huge hound. No light falls upon its D:form. N:273:Flying skull G:s:s I:110:10d10:30:30:20 W:15:3:500:50 E:0:0:0:0:1:0 O:90:0:10:0 B:BITE:POISON:1d3 B:BITE:LOSE_STR:1d4 F:UNDEAD | EVIL | IM_POIS | IM_COLD | WEIRD_MIND | NO_FEAR | CAN_FLY | F:NO_CONF | NO_SLEEP | DROP_60 | BASH_DOOR | FRIENDS | COLD_BLOOD | F:BASEANGBAND | NO_CUT D:A pack of skulls animated by necromantic spells. N:274:Mi-Go G:I:R I:120:13d8:20:30:20 W:15:2:800:80 E:0:0:0:0:1:0 O:0:0:0:0 B:STING:POISON:1d4 B:BITE:LOSE_STR:1d2 F:IM_POIS | IM_COLD | COLD_BLOOD | ANIMAL | EVIL | F:NO_SLEEP | NO_CONF | CAN_FLY | DROP_SKELETON | CTHANGBAND S:1_IN_6 S:CONF | S_MONSTER | S_DEMON D:"They were pinkish things about five feet long; with crustaceous D:bodies bearing vast pairs of dorsal fins or membranous wings and D:several sets of articulate limbs, and with a sort of convoluted D:ellipsoid, covered with multitudes of very short antenna, where D:a head would ordinarily be..." N:275:Giant tarantula G:S:o I:120:10d15:8:32:80 W:15:3:1100:70 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:1d6 B:BITE:POISON:1d6 B:BITE:POISON:1d6 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | F:ANIMAL | SPIDER | IM_POIS | DROP_SKELETON | F:MORTAL | BASEANGBAND D:A giant spider with hairy black and red legs. N:276:Giant clear centipede G:c:B I:110:5d8:12:30:30 W:15:2:400:30 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:2d4 B:STING:HURT:2d4 F:ATTR_CLEAR | F:INVISIBLE | WEIRD_MIND | BASH_DOOR | WILD_TOO | F:ANIMAL | DROP_SKELETON | F:MORTAL | BASEANGBAND D:It is about four feet long and carnivorous. N:277:Mirkwood spider G:S:G I:120:9d8:15:25:80 W:15:2:1200:25 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d8 B:BITE:POISON:1d6 B:BITE:POISON:1d6 F:FRIENDS | WILD_TOO | WILD_WOOD | F:WEIRD_MIND | BASH_DOOR | HURT_LITE | F:ANIMAL | SPIDER | EVIL | IM_POIS | DROP_SKELETON | F:MORTAL | BASEANGBAND D:A strong and powerful spider from Mirkwood forest. Cunning and evil, it D:seeks to taste your juicy insides. N:278:Frost giant G:P:w I:110:32d15:20:50:50 W:28:1:4000:180 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:COLD:5d8 B:HIT:COLD:5d8 F:DROP_60 | WILD_TOO | WILD_WASTE | WILD_MOUNTAIN | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | GIANT | MALE | AURA_COLD | SUSCEP_FIRE | F:IM_COLD | BASEANGBAND | HAS_LITE | MORTAL D:A twelve foot tall giant covered in furs. N:279:Griffon G:H:u I:110:30d8:12:15:10 W:15:1:2500:70 E:0:1:0:2:1:0 O:0:0:0:0 B:HIT:HURT:3d4 B:BITE:HURT:2d6 F:BASH_DOOR | CAN_FLY | WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | WILD_GRASS | F:ANIMAL | DROP_CORPSE | MORTAL | BASEANGBAND D:It is half lion, half eagle. It flies menacingly towards you. N:280:Homunculus G:u:y I:110:8d8:20:32:30 W:15:3:100:40 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:PARALYZE:1d2 B:HIT:HURT:1d10 F:OPEN_DOOR | BASH_DOOR | NONLIVING | CAN_FLY | F:EVIL | DEMON | IM_FIRE | NO_FEAR | BASEANGBAND | HAS_LITE D:It is a small demonic spirit full of malevolence. N:281:Gnome mage G:h:R I:110:7d8:20:20:20 W:15:2:900:40 E:1:1:1:2:1:1 O:20:0:80:0 B:HIT:HURT:1d5 F:MALE | F:FORCE_SLEEP | FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_4 | S:BLINK | DARKNESS | BO_COLD | S:S_MONSTER D:A mage of short stature. N:282:Clear hound G:Z:B I:110:6d6:30:30:0 W:15:1:600:50 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d6 B:CLAW:HURT:1d6 B:BITE:HURT:1d8 F:ATTR_CLEAR | F:FRIENDS | DROP_SKELETON | DROP_CORPSE | F:INVISIBLE | BASH_DOOR | F:ANIMAL | MORTAL | BASEANGBAND D:A faint sense of motion in the air, hound shaped, stands before you. N:283:Umber hulk G:X:U I:110:20d10:20:50:10 W:16:1:5000:75 E:0:1:0:2:1:0 O:0:0:0:0 B:GAZE:CONFUSE B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:BITE:HURT:2d6 F:EMPTY_MIND | COLD_BLOOD | F:BASH_DOOR | KILL_WALL | DROP_SKELETON | F:ANIMAL | EVIL | F:IM_POIS | F:HURT_ROCK | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:This bizarre creature has glaring eyes and large mandibles capable of D:slicing through rock. N:284:Rust monster G:q:o I:110:20d15:12:55:10 W:16:2:900:50 E:0:1:0:2:1:0 O:0:0:0:0 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 F:STUPID | WEIRD_MIND | KILL_ITEM | F:IM_ACID | IM_POIS | DROP_CORPSE | F:NO_CONF | F:MORTAL | BASEANGBAND D:It is a weird, small animal with two antennae popping forth from D:its forehead. It looks hungry. N:285:Ogrillon G:O:W I:110:22d9:20:33:30 W:16:2:2400:75 E:1:1:1:2:1:1 O:20:70:0:10 B:HIT:HURT:2d10 B:HIT:HURT:2d10 F:FRIENDS | DROP_60 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | ORC | F:MORTAL | BASEANGBAND | HAS_LITE D:An unholy hybrid of ogre and orc. N:286:Gelatinous cube G:j:G I:110:36d10:12:18:1 W:16:4:40000:80 E:0:0:0:0:0:0 O:40:30:20:0 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 F:FORCE_MAXHP | F:DROP_1D2 | DROP_4D2 | F:STUPID | EMPTY_MIND | COLD_BLOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | CAN_SWIM | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a strange, vast gelatinous structure that assumes cubic proportions D:as it lines all four walls of the corridors it patrols. Through its D:transparent jelly structure you can see treasures it has engulfed, and a D:few corpses as well. N:287:Giant green dragon fly G:F:G I:110:3d8:12:20:50 W:16:2:150:65 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:1d6 F:FORCE_SLEEP | RAND_50 | RAND_25 | WILD_TOO | WILD_SWAMP | F:WEIRD_MIND | BASH_DOOR | CAN_FLY | F:ANIMAL | IM_POIS | F:MORTAL | BASEANGBAND S:1_IN_10 | S:BR_POIS D:A vast, foul-smelling dragonfly. N:288:Fire giant G:P:r I:110:34d16:20:60:50 W:30:1:5000:220 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:FIRE:6d8 B:HIT:FIRE:6d8 F:DROP_60 | F:OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_VOLCANO | SUSCEP_COLD | F:EVIL | GIANT | MALE | AURA_FIRE | DROP_SKELETON | DROP_CORPSE | F:IM_FIRE | BASEANGBAND | HAS_LITE | MORTAL D:A glowing fourteen foot tall giant. Flames drip from its red skin. N:289:Hummerhorn G:I:y I:120:2d2:8:14:10 W:16:4:100:4 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:CONFUSE:2d2 F:RAND_50 | RAND_25 | CAN_FLY | F:WEIRD_MIND | ANIMAL | BASEANGBAND S:MULTIPLY D:A giant buzzing wasp, its stinger drips venom. N:290:Lizard man G:h:G I:110:16d10:20:40:20 W:16:3:1300:55 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:4d4 B:HIT:HURT:4d4 F:MALE | CAN_SWIM | IM_ACID | F:FRIENDS | DROP_60 | WILD_TOO | WILD_SHORE | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON F:EVIL F:MORTAL | BASEANGBAND | HAS_LITE D:Intelligent lizard beings from the depths. N:291:Ulfast, Son of Ulfang G:p:U I:110:37d10:20:40:40 W:16:3:1700:200 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:HIT:HURT:3d6 F:UNIQUE | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE | F:MALE | F:FORCE_MAXHP | F:ONLY_ITEM | DROP_90 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE D:A short and swarthy Easterling. N:292:Crebain G:B:D I:120:3d5:40:12:0 W:16:4:500:20 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:1d4 B:CLAW:HURT:1d4 F:ANIMAL | EVIL | MORTAL | FRIENDS | BASEANGBAND | DROP_CORPSE | HAS_EGG | F:WILD_TOO | WILD_WASTE | WILD_MOUNTAIN | WILD_WOOD | WILD_VOLCANO | F:WILD_GRASS | WILD_SWAMP | WILD_SHORE | WILD_OCEAN | CAN_FLY S:1_IN_8 | SHRIEK D:A type of crow, specially bred by the forces of evil as spies; their D:rudimentary intelligence guided by an evil mind has tracked you down, D:and now they seek to alert other evil creatures to your presence. N:293:Berserker G:p:u I:120:60d25:20:80:10 W:45:2:2300:2500 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:HURT:7d7 B:HIT:HURT:7d7 B:HIT:HURT:7d7 F:MALE | NO_FEAR | NO_STUN | BASH_DOOR | KILL_BODY | FORCE_MAXHP | F:DROP_SKELETON | DROP_CORPSE F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_4 | HASTE | SCARE D:Even the strongest of normal human warriors fears the Berserker - the one who D:can drive himself into such a terrible battle-frenzy that he can survive blows D:which should kill him, and still apparently feel no pain. He tramples weaker D:creatures underfoot in his eagerness to get to his real enemy, and his D:battle-cry strikes terror into his foes. N:294:Quasit G:u:o I:110:6d8:20:30:20 W:16:2:500:50 E:1:1:1:2:1:1 O:0:50:30:10 B:BITE:LOSE_DEX:1d6 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 F:FORCE_SLEEP | CAN_FLY | F:RAND_25 | F:ONLY_ITEM | DROP_1D2 | F:SMART | INVISIBLE | BASH_DOOR | F:EVIL | DEMON | IM_FIRE | NONLIVING | BASEANGBAND | HAS_LITE S:1_IN_10 | S:BLINK | TPORT | TELE_TO | TELE_LEVEL | BLIND | CONF | SCARE D:The chaotic evil master's favourite pet. N:295:Sphinx G:H:o I:110:60d5:20:60:20 W:17:2:6000:80 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 F:FORCE_SLEEP | F:ONLY_GOLD | DROP_1D2 | CAN_FLY | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | F:ANIMAL | MORTAL | BASEANGBAND S:1_IN_11 | S:SCARE | CONF D:It will eat you if you cannot answer its riddle. N:296:Imp G:u:g I:110:6d8:20:30:20 W:17:2:400:55 E:0:1:1:0:1:0 O:30:20:50:0 B:HIT:POISON:3d4 B:HIT:POISON:3d4 F:FORCE_SLEEP | CAN_FLY | F:RAND_25 | F:ONLY_ITEM | DROP_1D2 | F:SMART | INVISIBLE | COLD_BLOOD | BASH_DOOR | F:EVIL | DEMON | IM_FIRE | RES_TELE | BASEANGBAND | HAS_LITE S:1_IN_10 | S:BLINK | TPORT | TELE_TO | TELE_LEVEL | BLIND | CONF | SCARE | BO_FIRE D:The lawful evil master's favourite pet. N:297:Forest troll G:T:g I:110:20d10:20:50:40 W:17:1:3000:70 E:1:1:1:2:1:1 O:30:70:0:0 B:HIT:HURT:1d4 B:HIT:HURT:1d4 B:BITE:HURT:1d6 F:MALE | F:FRIENDS | DROP_60 | WILD_TOO | WILD_WOOD | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | SUSCEP_FIRE | REGENERATE | F:EVIL | TROLL | HURT_LITE | BASEANGBAND D:He is green-skinned and ugly. N:298:Freezing sphere G:*:w I:120:6d6:100:30:0 W:17:1:0:50 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:COLD:8d8 F:FORCE_SLEEP | CAN_FLY | SUSCEP_FIRE | RAND_50 | RAND_25 | F:EMPTY_MIND | AURA_COLD | F:IM_COLD | NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | BASEANGBAND | HAS_LITE | NO_CUT D:A semi-sentient snowball, hurling itself at targets at random. N:299:Jumping fireball G:*:r I:120:6d6:100:30:0 W:17:1:0:50 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:FIRE:8d8 F:FORCE_SLEEP | CAN_FLY | SUSCEP_COLD | F:EMPTY_MIND | AURA_FIRE | RAND_50 | RAND_25 | F:IM_FIRE | NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | BASEANGBAND | HAS_LITE | NO_CUT D:A semi-sentient fireball that moves around randomly. N:300:Ball lightning G:*:B I:120:6d6:100:30:0 W:17:1:0:50 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:ELEC:8d8 F:FORCE_SLEEP | CAN_FLY | RAND_25 | RAND_50 | F:EMPTY_MIND | AURA_ELEC | F:IM_ELEC | NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | BASEANGBAND | HAS_LITE |NO_CUT D:A crackling ball of energy, zooming about seemingly at random. N:301:2-headed hydra G:M:u I:110:100d3:20:60:20 W:17:2:4000:80 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:HURT:2d6 B:BITE:HURT:2d6 F:FORCE_SLEEP | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:ONLY_GOLD | DROP_1D2 | CAN_SWIM | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | HAS_EGG | IMPRESED | F:ANIMAL | MORTAL | BASEANGBAND S:1_IN_11 | S:SCARE D:A strange reptilian creature with two heads, guarding its hoard. N:302:Swamp thing G:H:g I:110:8d12:20:60:30 W:17:2:2000:80 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:TERRIFY:2d5 B:CLAW:TERRIFY:5d2 F:CAN_SWIM | OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_SWAMP F:MORTAL | BASEANGBAND D:A creature that was once human, but is now as green as moss. N:303:Water spirit G:E:b I:120:9d8:12:28:40 W:17:2:0:58 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:2d4 B:HIT:HURT:2d4 F:RAND_25 | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | F:IM_POIS | IM_ACID | CAN_FLY | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:A whirlpool of sentient liquid. N:304:Giant red scorpion G:S:r I:110:11d8:12:44:20 W:17:1:1000:62 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d4 B:STING:LOSE_STR:1d7 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | F:ANIMAL | DROP_SKELETON | F:MORTAL | BASEANGBAND D:It is fast and poisonous. N:305:Earth spirit G:E:u I:120:13d8:10:40:50 W:17:2:0:64 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:RAND_25 | F:EMPTY_MIND | COLD_BLOOD | F:PASS_WALL | CAN_FLY | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | HURT_ROCK | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:A whirling form of sentient rock. N:306:Fire spirit G:E:r I:120:10d9:16:30:20 W:18:2:0:75 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:FIRE:2d6 B:HIT:FIRE:2d6 F:RAND_25 | F:EMPTY_MIND | BASH_DOOR | CAN_FLY | SUSCEP_COLD | F:IM_FIRE | IM_POIS | WILD_TOO | WILD_VOLCANO | F:NO_CONF | NO_SLEEP | NO_FEAR | AURA_FIRE | BASEANGBAND | HAS_LITE | NO_CUT D:A whirlwind of sentient flame. N:307:Fire hound G:Z:r I:110:10d6:30:30:0 W:18:1:600:70 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:FIRE:2d6 F:FORCE_SLEEP | F:FRIENDS | F:BASH_DOOR | SUSCEP_COLD | F:ANIMAL | IM_FIRE | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_10 | S:BR_FIRE D:Flames lick at its feet and its tongue is a blade of fire. You can feel a D:furnace heat radiating from the creature. N:308:Cold hound G:Z:w I:110:10d6:30:30:0 W:18:1:600:70 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:COLD:2d6 F:FORCE_SLEEP | F:FRIENDS | F:BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | IM_COLD | SUSCEP_FIRE | F:MORTAL | BASEANGBAND S:1_IN_10 | S:BR_COLD D:A hound as tall as a man, this creature appears to be composed of angular D:planes of ice. Cold radiates from it and freezes your breath in the air. N:309:Energy hound G:Z:b I:110:10d6:30:30:0 W:18:1:600:70 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:ELEC:2d6 F:FORCE_SLEEP | F:FRIENDS | DROP_SKELETON | DROP_CORPSE | F:BASH_DOOR | F:ANIMAL | IM_ELEC | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_10 | S:BR_ELEC D:Saint Elmo's Fire forms a ghostly halo around this hound, and sparks sting D:your fingers as energy builds up in the air around you. N:310:Lesser Mimic G:m:y I:110:10d10:25:30:250 W:18:3:100:60 E:0:0:0:0:0:0 O:10:10:10:10 B:HIT:POISON:3d4 B:HIT:HURT:2d3 B:HIT:HURT:2d3 F:MIMIC | F:FORCE_SLEEP | NEVER_MOVE | SUSCEP_COLD | F:EMPTY_MIND | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_6 | S:BLIND | CONF | SCARE | CAUSE_2 | BO_COLD D:A strange creature that disguises itself as some object to lure D:unsuspecting adventurers within reach of its venomous claws. N:311:Door mimic G:+:U I:110:10d10:25:30:0 W:18:6:100:70 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:POISON:3d4 B:HIT:CONFUSE:2d3 B:HIT:PARALYZE:2d3 F:CHAR_MULTI | F:FORCE_SLEEP | NEVER_MOVE | F:EMPTY_MIND | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_6 | S:BLIND | CONF | SCARE | CAUSE_2 | BO_COLD D:A strange creature that disguises itself as a door to lure D:unsuspecting adventurers within reach of its venomous claws. N:312:Blink dog G:C:B I:120:8d8:20:20:10 W:18:2:400:50 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d8 F:RAND_25 | FRIENDS | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | RES_TELE | MORTAL | BASEANGBAND S:1_IN_4 | BLINK | TELE_TO D:A strange magical member of the canine race, its form seems to shimmer and D:fade in front of your very eyes. N:313:Uruk G:o:B I:110:8d10:20:50:20 W:16:1:2300:60 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:MALE | F:FORCE_MAXHP | FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | ORC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_9 | S:ARROW_2 D:It is a cunning orc of power, as tall as a man, and stronger. It fears D:little. N:314:Shagrat, the Orc Captain G:o:g I:110:42d10:20:60:20 W:19:2:2600:400 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:3d9 B:HIT:HURT:3d9 B:HIT:HURT:3d6 B:HIT:HURT:3d6 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | SPECIAL_GENE F:ESCORT | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:He is an orc of power and great cunning, leader of the garrison at Cirith Ungol. N:315:Gorbag, the Orc Captain G:o:g I:110:42d10:20:60:20 W:19:2:2600:400 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:3d9 B:HIT:HURT:3d9 B:HIT:HURT:3d6 B:HIT:HURT:3d6 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | F:ESCORT | DROP_SKELETON | DROP_CORPSE F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_POIS F:MORTAL | BASEANGBAND | HAS_LITE D:He is an orc of power and great cunning, leader of the garrison at Minas Morgul. N:316:Shambling mound G:,:g I:110:20d6:20:16:40 W:18:2:3000:75 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:ONLY_GOLD | DROP_90 | WILD_TOO | WILD_SWAMP | F:STUPID | EMPTY_MIND | OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_4 | S:SHRIEK D:A pile of rotting vegetation that slides towards you with a disgusting D:stench, waking all it nears. N:317:Giant Venus Flytrap G:#:g I:120:10d10:20:5:0 W:15:5:200:30 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:PARALYZE:3d3 B:HIT:PARALYZE:3d3 B:HIT:PARALYZE:3d3 F:NEVER_MOVE | EMPTY_MIND | STUPID | CHAR_CLEAR | CHAR_MULTI | F:WILD_ONLY | WILD_WOOD | WILD_SWAMP | ANIMAL | SUSCEP_FIRE | NO_CUT D:A carnivorous plant that is difficult to detect, until it suddenly snaps shut D:around its prey and releases paralysing enzymes to stop its struggles. N:318:Chaos beastman G:H:u I:110:20d8:20:50:30 W:18:2:2300:75 E:0:0:0:0:0:0 O:25:45:20:0 B:HIT:CONFUSE:3d5 B:HIT:EXP_20:3d5 F:DROP_1D2 F:OPEN_DOOR | BASH_DOOR | NO_CONF | NO_SLEEP | DROP_CORPSE F:EVIL | IM_POIS | IM_FIRE | ATTR_ANY | ATTR_MULTI F:MORTAL | ZANGBAND S:1_IN_8 S:MISSILE | BO_FIRE | CONF | TPORT D:A truly loathsome thing, twisted by chaos, it is a mixture D:of several different kinds of creature. N:319:Daemonette of Slaanesh G:u:R I:120:12d8:20:50:30 W:18:2:2000:75 E:1:1:1:0:1:1 O:30:0:30:40 B:CLAW:CONFUSE:3d5 B:CLAW:CONFUSE:3d5 F:FORCE_MAXHP | DROP_60 | FEMALE | F:OPEN_DOOR | BASH_DOOR | IM_COLD | NO_CONF | NO_SLEEP | F:EVIL | DEMON | IM_POIS | IM_FIRE | ZANGBAND S:1_IN_8 S:SCARE | S_DEMON | CAUSE_2 | CONF | BO_FIRE | BO_COLD D:It is minor female demon, vaguely human-like, but with crab-like D:pincers instead of hands. She wears a rather indecent skimpy D:leather bikini, moves quickly and casts deadly spells! N:320:Giant bronze dragon fly G:F:U I:120:3d8:12:20:50 W:18:2:150:80 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:CONFUSE:1d6 F:FORCE_SLEEP | RAND_50 | RAND_25 | CAN_FLY | F:WEIRD_MIND | BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | F:ANIMAL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND S:1_IN_10 | S:BR_CONF D:This vast gleaming bronze fly has wings which beat mesmerically fast. N:321:Stone giant G:P:W I:110:35d18:20:75:50 W:33:1:7000:250 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:3d8 B:HIT:HURT:3d8 F:DROP_60 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | GIANT | MALE | WILD_TOO | WILD_MOUNTAIN | BASEANGBAND | HAS_LITE D:It is eighteen feet tall and looking at you. N:322:Giant black dragon fly G:F:s I:120:3d8:12:20:50 W:20:2:150:70 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:ACID:1d6 F:FORCE_SLEEP | RAND_50 | RAND_25 | F:WEIRD_MIND | BASH_DOOR | CAN_FLY | WILD_TOO | WILD_SWAMP | F:ANIMAL | IM_ACID | F:MORTAL | BASEANGBAND S:1_IN_10 | S:BR_ACID D:The size of a large bird, this fly drips caustic acid. N:323:Stone golem G:g:W I:100:28d8:12:75:10 W:19:2:3500:100 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d10 B:HIT:HURT:1d10 F:COLD_BLOOD | EMPTY_MIND | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_ROCK | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT D:It is a massive animated statue. N:324:Red mold G:m:r I:110:17d8:2:16:70 W:19:1:40:64 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:FIRE:4d4 F:NEVER_MOVE | SUSCEP_COLD | F:STUPID | EMPTY_MIND | F:IM_FIRE | IM_POIS | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a strange red growth on the dungeon floor; it seems to burn with D:flame. N:325:Giant gold dragon fly G:F:y I:120:3d8:12:20:50 W:22:2:150:75 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 F:FORCE_SLEEP | F:RAND_50 | RAND_25 | WILD_TOO | WILD_MOUNTAIN | F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | IM_FIRE | CAN_FLY | F:MORTAL | BASEANGBAND S:1_IN_10 | S:BR_SOUN D:Large beating wings support this dazzling insect. A loud buzzing noise D:pervades the air. N:326:Stunwall G:#:W I:110:4d8:45:25:0 W:18:5:1000:50 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:PARALYZE:10d1 B:TOUCH:PARALYZE:10d1 F:NEVER_MOVE | IM_COLD | COLD_BLOOD | IM_ACID | IM_ELEC | NO_FEAR | F:IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | CHAR_MULTI | F:EMPTY_MIND | HURT_ROCK | ZANGBAND | NO_CUT D:A sentient section of wall. N:327:Ghast G:z:u I:120:30d10:40:40:20 W:30:1:1500:130 E:1:1:1:2:1:1 O:20:35:25:10 B:CLAW:PARALYZE:2d4 B:CLAW:PARALYZE:2d4 B:BITE:LOSE_CON:2d4 B:BITE:LOSE_CHR:2d4 F:DROP_60 | OPEN_DOOR | BASH_DOOR | ESCORT | F:NO_SLEEP | NO_CONF | UNDEAD | EVIL | IM_POIS | IM_COLD | F:COLD_BLOOD | HURT_LITE | CAN_SWIM | BASEANGBAND | NO_CUT D:This vile abomination is a relative of ghouls, and often leads packs D:of them. It smells foul, and its bite carries a rotting disease. N:328:Neekerbreeker G:I:D I:120:3d2:8:18:10 W:19:4:100:4 B:BITE:POISON:2d2 F:RAND_50 | RAND_25 | CAN_FLY | WILD_SWAMP | WILD_TOO | F:WEIRD_MIND | ANIMAL | EVIL | BASEANGBAND S:MULTIPLY | S:1_IN_12 | S:SHRIEK D:Believed to be an evil relative of the cricket, this creature gets its name D:from its incessant squeaking, which can best be described as "neek-breek, D:neek-breek". The noise can drive people frantic, and worse still, can be D:heard for quite some distance, alerting other monsters to your presence. N:329:Huorn G:#:g I:110:50d10:40:45:20 W:19:1:4000:75 E:0:0:0:0:0:0 O:30:30:30:5 B:CRUSH:HURT:3d6 B:CRUSH:HURT:3d6 B:CRUSH:HURT:3d6 B:CRUSH:HURT:3d6 F:DROP_60 | NO_SLEEP | NO_CONF | ANIMAL | WEIRD_MIND | SUSCEP_FIRE | F:RES_WATE | IM_COLD | NEVER_MOVE | WILD_ONLY | WILD_WOOD | F:BASEANGBAND | NO_CUT S:1_IN_9 S:BLINK | TELE_TO D:A very strong near-sentient tree, which has become hostile to other living things. N:330:Bolg, Son of Azog G:o:v I:120:52d10:20:50:20 W:20:4:2300:800 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:3d7 B:HIT:HURT:3d7 B:HIT:HURT:3d7 B:HIT:HURT:3d7 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | SPECIAL_GENE | F:ESCORT | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:A large and powerful orc, he looks just like his father. He is tall and D:fast, but fortunately blessed with orcish brains. N:331:Phase spider G:S:B I:120:6d8:15:25:80 W:20:2:500:60 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d8 B:BITE:POISON:1d6 B:BITE:POISON:1d6 F:FRIENDS | WILD_TOO | WILD_WOOD | DROP_SKELETON | F:WEIRD_MIND | BASH_DOOR | CAN_SWIM | F:ANIMAL | SPIDER | IM_POIS | RES_TELE | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BLINK | TELE_TO D:A spider that never seems quite there. Everywhere you look it is just D:half-seen in the corner of one eye. N:332:Lizard king G:h:g I:120:18d11:20:40:20 W:20:3:1600:150 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:WAIL:TERRIFY F:MALE | CAN_SWIM | IM_ACID | IM_POIS | WILD_SHORE | F:DROP_60 | DROP_1D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | FORCE_MAXHP | F:MORTAL | BASEANGBAND | HAS_LITE D:A lizardman leader. N:333:Landmine G:.:w I:110:6d6:30:25:10 W:20:5:300:50 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:HURT:25d2 F:CHAR_CLEAR | ATTR_CLEAR | CHAR_MULTI | F:NEVER_MOVE | FORCE_MAXHP | F:EMPTY_MIND | INVISIBLE | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | JOKEANGBAND | NO_CUT D:It was left here to be used against intruders. N:334:Wyvern G:d:g I:120:100d5:20:65:20 W:22:2:4500:250 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:2d6 B:BITE:HURT:2d6 B:BITE:HURT:2d6 B:STING:POISON:1d6 F:FORCE_SLEEP | F:ONLY_GOLD | DROP_2D2 | IM_POIS | CAN_FLY | HAS_EGG | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | DROP_CORPSE | F:WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | DROP_SKELETON | F:ANIMAL | EVIL | DRAGON | BASEANGBAND | ATTR_MULTI D:A fast-moving and deadly draconian animal. Beware its poisonous sting! N:335:Great eagle G:B:u I:120:100d5:20:65:20 W:20:2:1000:150 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:6d3 B:CLAW:HURT:6d3 B:BITE:HURT:3d6 F:CAN_FLY | F:WILD_ONLY | WILD_MOUNTAIN | WILD_VOLCANO | WILD_WASTE | WILD_WOOD | F:ANIMAL | GOOD | DROP_CORPSE | BASEANGBAND | HAS_EGG D:Greater and more intelligent than most of its kind, this great eagle is D:a messenger between the forces of good. N:336:Livingstone G:#:W I:110:6d8:45:28:20 W:20:4:1000:56 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:2d5 B:HIT:HURT:2d5 F:NEVER_MOVE | IM_COLD | COLD_BLOOD | IM_ACID | IM_ELEC | NO_FEAR | F:IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | FRIENDS | CHAR_MULTI | HURT_ROCK | F:BASEANGBAND | NO_CUT S:MULTIPLY D:A sentient section of wall. N:337:Earth hound G:Z:u I:110:15d8:30:30:0 W:20:1:600:200 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d8 B:BITE:HURT:1d8 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 F:FORCE_SLEEP | F:FRIENDS | DROP_SKELETON | DROP_CORPSE | F:BASH_DOOR | F:ANIMAL | MORTAL | BASEANGBAND | NO_CUT S:1_IN_10 | S:BR_SHAR D:A beautiful crystalline shape does not disguise the danger this hound D:clearly presents. Your flesh tingles as it approaches. N:338:Air hound G:Z:g I:110:15d8:30:30:0 W:20:1:600:200 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:1d8 B:BITE:POISON:1d8 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 F:FORCE_SLEEP | F:FRIENDS | CAN_FLY | F:BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | IM_POIS | MORTAL | BASEANGBAND S:1_IN_10 | S:BR_POIS D:Swirling vapours surround this beast as it floats towards you, seemingly D:walking on air. Noxious gases sting your throat. N:339:Sabre-tooth tiger G:f:y I:120:20d14:40:50:0 W:20:2:1800:120 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d10 B:CLAW:HURT:1d10 B:BITE:HURT:1d10 B:BITE:HURT:1d10 F:BASH_DOOR | WILD_WOOD | WILD_TOO | WILD_GRASS | F:ANIMAL | DROP_SKELETON | DROP_CORPSE F:MORTAL | BASEANGBAND D:A fierce and dangerous cat, its huge tusks and sharp claws would lacerate D:even the strongest armour. N:340:Acid hound G:Z:s I:110:15d8:30:30:0 W:20:1:600:200 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:ACID:1d8 B:BITE:ACID:1d8 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 F:FORCE_SLEEP | F:FRIENDS | F:BASH_DOOR | CAN_SWIM | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | IM_ACID | MORTAL | BASEANGBAND S:1_IN_10 | S:BR_ACID D:Footprints are burned in the ground behind this hound as it pads D:around the dungeon. An acrid smell of acid rises from the dog's pelt. N:341:Chimaera G:H:r I:110:20d15:12:15:10 W:20:2:1600:200 E:0:1:0:2:2:0 O:0:0:0:0 B:BUTT:HURT:2d8 B:BITE:HURT:2d10 B:BITE:FIRE:2d6 F:FORCE_SLEEP | CAN_FLY | DROP_CORPSE | SUSCEP_COLD | F:BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | F:IM_FIRE | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_10 | S:BR_FIRE D:It is a strange concoction of goat, lion and dragon, with the heads of all D:three beasts. N:342:Quylthulg G:Q:y I:110:6d8:10:1:0 W:20:1:3000:250 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | NEVER_MOVE | NEVER_BLOW F:EMPTY_MIND | INVISIBLE | ANIMAL | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_4 | S:BLINK | S:S_MONSTER D:It is a strange pulsing mound of flesh. N:343:Sasquatch G:Y:W I:120:20d19:15:40:10 W:20:3:3500:180 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:1d10 B:CLAW:HURT:1d10 B:BITE:HURT:2d8 F:OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | WILD_WOOD | WILD_WASTE | F:ANIMAL | IM_COLD | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND D:A tall shaggy, furry humanoid, it could call the yeti brother. N:344:Weir G:C:W I:110:10d12:15:30:40 W:20:2:2010:150 E:1:1:1:2:1:1 O:0:0:0:0 B:BITE:HURT:1d8 B:BITE:HURT:1d8 F:RAND_25 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | EVIL | FRIENDS | F:MORTAL | ZANGBAND D:It is a tracker; half human, half beast. N:345:Ranger G:p:W I:110:15d11:20:40:40 W:20:1:1700:55 E:1:1:1:2:1:1 O:20:50:20:0 B:HIT:HURT:5d4 B:HIT:HURT:5d4 F:MALE | F:DROP_1D2 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:DROP_SKELETON | DROP_CORPSE | BASEANGBAND | MORTAL | HAS_LITE S:1_IN_4 | S:ARROW_2 | MISSILE | BO_COLD | BO_ELEC | BLINK | S_ANIMAL D:A warrior who is at one with nature. A master of both bow and sword, with D:minor spellcasting skills. N:346:Paladin G:p:w I:110:15d11:20:40:40 W:20:1:1700:55 E:1:1:1:2:1:1 O:20:60:0:10 B:HIT:HURT:4d5 B:HIT:HURT:4d5 F:MALE | GOOD | DROP_SKELETON | DROP_CORPSE | F:DROP_1D2 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:BASEANGBAND | MORTAL | HAS_LITE S:1_IN_4 | S:HEAL | CAUSE_2 | SLOW | SCARE | BLIND D:A warrior for a holy cause. Unfortunately, his god is not yours, and there is D:rivalry even between the various gods of Good, so he is your enemy. N:347:Werewolf G:C:D I:110:20d22:15:30:70 W:20:2:900:150 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:2d10 F:RAND_25 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | F:ANIMAL | EVIL | MORTAL | BASEANGBAND D:It is a huge wolf with eyes that glow with manly intelligence. N:348:Dark elven lord G:h:s I:120:18d15:20:40:30 W:20:2:1400:500 E:1:1:1:2:1:1 O:0:80:20:0 B:HIT:HURT:3d8 B:HIT:HURT:3d5 F:MALE | FORCE_SLEEP | F:ONLY_ITEM | DROP_2D2 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | HURT_LITE | BASEANGBAND | HAS_LITE S:1_IN_5 | S:HASTE | BLIND | CONF | DARKNESS | BO_FIRE | BO_COLD | MISSILE D:A dark elven figure in armour and radiating evil power. N:349:Cloud giant G:P:b I:110:35d20:20:60:50 W:36:1:9000:500 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:ELEC:8d8 B:HIT:ELEC:8d8 F:DROP_90 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | GIANT | IM_ELEC | MALE | BASEANGBAND | HAS_LITE D:It is a twenty foot tall giant wreathed in clouds. N:350:Ugluk, the Uruk G:o:v I:110:72d10:20:95:20 W:21:3:2400:600 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE | F:ESCORT | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_FIRE | IM_COLD | IM_POIS F:MORTAL | BASEANGBAND | HAS_LITE D:A strong and cunning orc warrior, the commander of Saruman's orcish horde. N:351:Blue dragon bat G:b:b I:130:4d4:12:26:50 W:21:1:100:54 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:ELEC:1d3 F:FORCE_SLEEP | F:RAND_50 | F:BASH_DOOR | CAN_FLY | F:ANIMAL | IM_ELEC | AI_ANNOY F:MORTAL | BASEANGBAND S:1_IN_4 | S:BR_ELEC D:It is a glowing blue bat with a sharp tail. N:352:Mimic G:m:y I:110:10d14:30:40:0 W:21:3:100:70 E:0:0:0:0:0:0 O:20:20:20:20 B:HIT:POISON:3d4 B:HIT:POISON:3d4 B:HIT:HURT:2d3 B:HIT:HURT:2d3 F:MIMIC | F:FORCE_SLEEP | NEVER_MOVE | F:EMPTY_MIND | COLD_BLOOD | SUSCEP_FIRE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_5 | S:BLIND | CONF | SCARE | CAUSE_2 | BO_FIRE | S:S_MONSTER D:A strange creature that disguises itself as an object to lure D:unsuspecting adventurers within reach of its venomous claws. N:353:Ultimate Mimic G:m:y I:110:15d40:30:40:0 W:35:4:100:250 E:0:0:0:0:0:0 O:25:25:25:25 B:BITE:POISON:4d4 B:BITE:POISON:4d4 B:BUTT:CONFUSE:4d4 B:SPIT:BLIND:4d4 F:MIMIC | F:FORCE_SLEEP | NEVER_MOVE | F:EMPTY_MIND | COLD_BLOOD F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_5 | S:BLIND | CONF | SCARE | CAUSE_2 | BA_POIS | S:S_MONSTER D:A strange creature that disguises itself as an object to lure D:unsuspecting adventurers within reach of its venomous claws. N:354:Fire vortex G:v:r I:110:9d9:100:30:0 W:21:1:0:100 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:FIRE:3d3 F:FORCE_SLEEP | RAND_50 | CAN_FLY | WILD_VOLCANO | WILD_TOO | SUSCEP_COLD | F:EMPTY_MIND | BASH_DOOR | POWERFUL | AURA_FIRE | F:IM_FIRE | NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | BASEANGBAND | HAS_LITE F:NO_CUT S:1_IN_6 | S:BR_FIRE D:A whirling maelstrom of fire. N:355:Acid vortex G:v:s I:110:9d9:100:30:0 W:21:1:0:100 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:ACID:3d3 F:FORCE_SLEEP | RAND_50 | F:EMPTY_MIND | BASH_DOOR | POWERFUL | CAN_FLY | F:IM_ACID | NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_6 | S:BR_ACID D:A caustic spinning whirlpool of foaming, steaming water. N:356:Lugdush, the Uruk G:o:v I:110:66d10:20:90:20 W:21:4:2500:550 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:HIT:HURT:3d6 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE | F:ESCORT | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:A large and powerful orc, captain of one of Saruman's orcish regiments. N:357:Arch-vile G:u:W I:130:11d11:100:30:0 W:21:1:100:300 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:3d9 B:CLAW:HURT:3d9 F:RAND_50 | EVIL | DEMON | FORCE_SLEEP | FORCE_MAXHP | F:OPEN_DOOR | BASH_DOOR | POWERFUL | COLD_BLOOD | F:IM_FIRE | RES_NETH | NO_CONF | NO_SLEEP | NONLIVING | NO_STUN | F:ZANGBAND S:1_IN_3 | S:BA_FIRE | ANIM_DEAD D:A pale, corpse-like lesser demon, who moves very fast and spawns evil D:everywhere. N:358:Cold vortex G:v:w I:110:9d9:100:30:0 W:21:1:0:100 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:COLD:3d3 F:FORCE_SLEEP | RAND_50 | AURA_COLD | COLD_BLOOD | SUSCEP_FIRE | F:EMPTY_MIND | BASH_DOOR | POWERFUL | CAN_FLY | F:IM_COLD | NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_6 | S:BR_COLD D:A twisting whirlpool of frost. N:359:Energy vortex G:v:b I:110:9d9:100:30:0 W:21:1:0:100 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:ELEC:3d3 F:FORCE_SLEEP | RAND_50 | CAN_FLY | HAS_LITE | F:EMPTY_MIND | BASH_DOOR | POWERFUL | AURA_ELEC | F:IM_ELEC | NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_6 | S:BR_ELEC D:A shimmering tornado of air, sparks crackle along its length. N:360:Globefish G:~:w I:110:10d10:20:30:30 W:21:1:600:111 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:POISON:10d5 B:BITE:POISON:10d5 F:EMPTY_MIND | BASH_DOOR | POWERFUL | AQUATIC | F:IM_POIS | NO_STUN | WILD_TOO | COLD_BLOOD | F:ANIMAL | MORTAL | BASEANGBAND S:1_IN_8 | S:BR_POIS D:This fish is among the most poisonous creatures there are. N:361:Giant firefly G:I:r I:120:3d2:8:18:10 W:24:4:100:4 B:BITE:BLIND:1d2 F:RAND_50 | RAND_25 | CAN_FLY | F:WEIRD_MIND | ANIMAL | BASEANGBAND S:MULTIPLY D:Clouds of these monsters light up the dungeon - so brightly that you can D:barely see through them. N:362:Mummified orc G:z:w I:110:15d8:20:28:75 W:21:1:1700:56 E:1:1:1:2:1:1 O:10:70:0:10 B:HIT:HURT:2d4 B:HIT:HURT:2d4 F:DROP_90 | F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | UNDEAD | F:IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is an orcish figure covered in wrappings. N:363:Wolf chieftain G:C:D I:120:22d22:20:20:5 W:26:5:1000:120 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:2d10 B:WAIL:TERRIFY F:ESCORTS | FORCE_MAXHP | IM_COLD | IM_ACID | F:SMART | ESCORT | ANIMAL | EVIL | MORTAL | BASEANGBAND | F:OPEN_DOOR | BASH_DOOR | NO_FEAR | MALE S:1_IN_8 | DARKNESS D:A great wolf-chieftain whose pack is in the service of the Dark Lord, D:and whose howls strike fear into even the boldest heart. N:364:Serpent man G:J:G I:120:15d10:20:40:20 W:22:3:900:75 E:1:1:1:2:1:1 O:25:20:25:20 B:BITE:POISON:5d5 B:BITE:POISON:5d5 F:MALE | CAN_SWIM | IM_POIS | IM_ACID | F:DROP_60 | DROP_2D2 | FRIENDS | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | EVIL | MORTAL | ZANGBAND S:1_IN_8 S:BA_POIS | S_MONSTER | SCARE | HOLD D:"They walked lithely and sinuously erect on pre-mammalian D:members, their pied and hairless bodies bending with great D:suppleness. There was a loud hissing of formulae as they D:went to and fro." N:365:Vampiric mist G:#:D I:110:10d8:12:55:30 W:22:1:0:40 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:EXP_20:1d6 B:ENGULF:EXP_20:1d6 F:RAND_25 | SUSCEP_ELEC | UNDEAD | F:IM_COLD | IM_POIS | IM_ACID | RES_NETH | WILD_TOO | WILD_SWAMP | F:EVIL | EMPTY_MIND | COLD_BLOOD | FRIENDS | BASEANGBAND | NO_CUT D:A cloud of evil, sentient mist. N:366:Killer stag beetle G:K:g I:110:15d8:12:55:30 W:22:1:500:80 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d12 B:CLAW:HURT:1d12 F:RAND_25 | WILD_TOO | DROP_CORPSE | F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | CAN_FLY | MORTAL | BASEANGBAND D:It is a giant beetle with vicious claws. N:367:Iron golem G:g:s I:110:80d12:12:80:10 W:22:2:3800:160 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d12 F:FORCE_SLEEP | SUSCEP_ACID | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_7 | S:SLOW D:It is a massive metal statue that moves steadily towards you. N:368:Auto-roller G:g:s I:120:70d12:10:80:12 W:22:2:0:230 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:1d8 B:CRUSH:HURT:1d8 B:CRUSH:HURT:1d8 B:CRUSH:HURT:1d8 F:FORCE_SLEEP | RES_TELE F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS F:NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | JOKEANGBAND | NO_CUT D:It looks like a huge spiked roller, moving on its own towards you. N:369:Giant yellow scorpion G:S:y I:110:12d8:12:38:20 W:22:1:1200:60 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d8 B:STING:POISON:2d5 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | F:ANIMAL | DROP_SKELETON | F:MORTAL | BASEANGBAND D:It is a giant scorpion with a sharp stinger. N:370:Jade monk G:p:G I:120:10d9:22:45:5 W:23:1:1200:100 E:1:1:1:2:1:1 O:30:0:60:10 B:KICK:HURT:4d1 B:KICK:HURT:4d1 B:HIT:HURT:4d5 B:HIT:HURT:4d5 F:OPEN_DOOR | BASH_DOOR | NO_FEAR | NO_CONF | NO_SLEEP | F:MALE | DROP_60 | DROP_1D2 | IM_FIRE | IM_COLD | IM_POIS | F:DROP_SKELETON | DROP_CORPSE | F:MORTAL | ZANGBAND | HAS_LITE D:A monk trained in martial arts. N:371:Black ooze G:j:D I:90:6d8:10:6:1 W:23:1:400:7 E:0:0:0:0:0:0 O:30:0:40:15 B:TOUCH:ACID:2d6 F:RAND_50 | DROP_60 | STUPID | EMPTY_MIND | CAN_SWIM | F:TAKE_ITEM | KILL_BODY | OPEN_DOOR | BASH_DOOR | F:IM_POIS | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT S:MULTIPLY S:1_IN_11 | S:DRAIN_MANA D:It is a strangely moving puddle. N:372:Hardened warrior G:p:u I:110:15d11:20:40:40 W:23:1:1900:60 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:6d5 B:HIT:HURT:6d5 F:MALE | F:DROP_1D2 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE D:A scarred warrior who moves with confidence. N:373:Azog, King of the Uruk-Hai G:o:v I:120:94d10:20:80:20 W:23:5:2700:1111 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:5d6 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE | F:ESCORT | ESCORTS | SPECIAL_GENE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:He is also known as the King of Khazad-dum. His ego is renowned to be D:bigger than his head. N:374:Fleshhound of Khorne G:C:R I:120:25d25:15:30:70 W:30:3:700:150 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:4d1 B:CLAW:HURT:4d1 B:BITE:HURT:6d1 B:BITE:HURT:6d1 F:BASH_DOOR | DEMON | NO_STUN | NO_FEAR | F:ANIMAL | EVIL | IM_FIRE | NO_SLEEP | NO_CONF | F:RES_NETH | RES_NEXU | RES_DISE | RES_PLAS | ZANGBAND D:A revolting canine creature, a huge demon hound with a somewhat D:reptilian head. N:375:Dark elven warlock G:h:v I:120:7d10:20:16:20 W:23:1:1700:75 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:MALE | F:FORCE_SLEEP | F:ONLY_ITEM | DROP_1D2 | DROP_SKELETON | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR | FRIENDS F:EVIL | IM_POIS | HURT_LITE | BASEANGBAND | HAS_LITE S:1_IN_5 | S:CONF | MISSILE | DARKNESS | BO_MANA D:A dark elven mage with spells of frightening destructive power. N:376:Master rogue G:p:b I:120:15d9:20:30:40 W:23:2:1600:110 E:1:1:1:2:1:1 O:80:10:10:0 B:HIT:HURT:2d8 B:HIT:HURT:2d8 B:HIT:EAT_GOLD:4d4 F:MALE | DROP_SKELETON | DROP_CORPSE | F:DROP_2D2 | SUSCEP_ELEC | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE D:A thief of great power and shifty speed. N:377:Red dragon bat G:b:r I:130:3d8:12:28:50 W:23:1:100:60 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:FIRE:1d3 F:FORCE_SLEEP | RAND_50 | SUSCEP_COLD | F:BASH_DOOR | CAN_FLY | DROP_CORPSE | AI_ANNOY F:ANIMAL | IM_FIRE | BASEANGBAND S:1_IN_4 | S:BR_FIRE D:It is a sharp-tailed bat, wreathed in fire. N:378:Killer white beetle G:K:w I:110:18d8:14:55:30 W:23:1:500:85 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:4d5 F:RAND_25 | F:WEIRD_MIND | BASH_DOOR | WILD_TOO | DROP_CORPSE | F:ANIMAL | CAN_FLY | MORTAL | BASEANGBAND D:It is looking for prey. N:379:Ice skeleton G:s:w I:110:16d9:20:34:60 W:23:1:0:70 E:1:1:1:2:1:1 O:20:0:80:0 B:CLAW:COLD:2d3 B:CLAW:COLD:2d3 F:ONLY_ITEM | DROP_90 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | SUSCEP_FIRE | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a skeleton covered in frost. N:380:Angamaite of Umbar G:p:U I:110:82d10:25:80:25 W:24:2:2400:400 E:1:1:1:2:1:1 O:0:80:20:0 B:HIT:HURT:4d7 B:HIT:HURT:4d7 B:HIT:HURT:4d6 B:HIT:HURT:4d6 F:UNIQUE | MALE | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_90 | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_FIRE | IM_ELEC F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_4 | S:SLOW | FORGET D:A Black Numenorean who hates the men of the west. N:381:Forest wight G:W:g I:110:12d8:20:30:30 W:24:1:0:140 E:0:0:0:0:0:0 O:0:50:50:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:TOUCH:EXP_20 F:FORCE_SLEEP | RAND_25 | F:DROP_60 | DROP_90 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_10 | S:SCARE | DRAIN_MANA D:It is a ghostly apparition with a humanoid form. N:382:Khim, Son of Mim G:h:o I:110:84d10:20:80:10 W:24:2:2300:300 E:1:1:1:2:1:1 O:10:80:0:10 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:HIT:HURT:3d7 B:HIT:UN_BONUS F:UNIQUE | MALE | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:IM_FIRE | IM_COLD F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_8 | S:HEAL | SLOW | BO_FIRE D:One of the last of the Petty-Dwarves. Khim is a tricky sorcerous little D:being, full of mischief. N:383:Ibun, Son of Mim G:h:o I:110:84d10:20:80:10 W:24:2:2300:300 E:1:1:1:2:1:1 O:10:80:0:5 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:HIT:HURT:3d7 B:HIT:UN_BONUS F:UNIQUE | MALE | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:IM_FIRE | IM_COLD F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_8 | S:HEAL | SLOW | BO_FIRE D:One of the last of the Petty-Dwarves. Ibun is a tricky sorcerous little D:being, full of mischief. N:384:Meneldor the Swift G:B:u I:140:80d10:20:65:20 W:24:6:1200:360 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:7d3 B:CLAW:HURT:7d3 B:BITE:HURT:3d7 F:CAN_FLY | UNIQUE | FORCE_MAXHP | DROP_CORPSE | CAN_SPEAK | F:WILD_ONLY | WILD_MOUNTAIN | WILD_VOLCANO | PET | F:ANIMAL | GOOD | BASEANGBAND D:Among all the eagles of Middle-earth he is the swiftest, and in his time D:has borne messages between all of the Wise. It was Meneldor who bore the D:Ring-bearer away from the destruction of Mount Doom. N:385:Phantom beast G:G:B I:110:12d12:20:40:40 W:24:1:0:100 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:2d33 B:HIT:HURT:2d44 F:PASS_WALL | NO_SLEEP | COLD_BLOOD | NONLIVING | NO_FEAR | F:FORCE_MAXHP | RES_TELE | EMPTY_MIND | CAN_FLY | BASEANGBAND | NO_CUT D:A creature that is half real, half illusion. N:386:Giant silver ant G:a:W I:110:9d8:10:38:40 W:23:1:800:45 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:ACID:4d4 F:RAND_25 | F:WEIRD_MIND | BASH_DOOR | WILD_TOO | DROP_SKELETON | F:ANIMAL | MORTAL | BASEANGBAND | HAS_LITE D:A giant silver ant with a caustic bite. N:387:4-headed hydra G:M:y I:120:100d6:20:70:20 W:24:2:5000:450 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:HURT:2d6 B:BITE:HURT:2d6 B:BITE:HURT:2d6 B:BITE:HURT:2d6 F:FORCE_SLEEP | F:ONLY_GOLD | DROP_4D2 | WILD_TOO | WILD_SWAMP | WILD_SHORE | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND S:1_IN_7 | S:SCARE D:A strange reptilian creature with four heads, guarding its hoard. N:388:Lesser hell-beast G:U:s I:115:15d100:10:100:50 W:24:4:4000:400 E:0:1:0:2:1:0 O:0:0:0:0 B:GAZE:TERRIFY:1d4 B:GAZE:TERRIFY:1d4 B:CRUSH:HURT:44d1 F:EVIL | IM_ACID | IM_ELEC | IM_FIRE | IM_POIS | IM_COLD | F:RES_NETH | RES_WATE | RES_PLAS | RES_DISE | RES_NEXU | F:KILL_WALL | FORCE_MAXHP | CAN_SWIM | DROP_CORPSE | JOKEANGBAND | HAS_LITE S:1_IN_9 | S:TPORT | BLINK | TELE_AWAY D:This creature just might crush you. N:389:Tyrannosaur G:R:g I:120:200d3:20:70:20 W:24:2:5000:350 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d6 B:CLAW:HURT:1d6 B:BITE:HURT:3d6 B:BITE:HURT:3d6 F:FORCE_SLEEP | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | DROP_CORPSE | F:ANIMAL | MORTAL | ZANGBAND D:A horror from prehistory, reawakened by chaos. N:390:Mummified human G:z:w I:110:17d9:20:34:60 W:24:1:1500:70 E:1:1:1:2:1:1 O:20:40:20:10 B:HIT:HURT:2d4 B:HIT:HURT:2d4 F:ONLY_ITEM | DROP_90 | F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a human form encased in mouldy wrappings. N:391:Vampire bat G:b:D I:120:9d10:12:40:50 W:24:2:50:150 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:EXP_40:1d4 B:BITE:EXP_40:1d4 F:RAND_50 | COLD_BLOOD | REGENERATE | CAN_FLY | F:EVIL | ANIMAL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:A blood-sucking bat that flies at your neck hungrily. N:392:Sangahyando of Umbar G:p:U I:110:82d10:25:80:25 W:24:2:2400:400 E:1:1:1:2:1:1 O:0:90:10:0 B:HIT:HURT:4d7 B:HIT:HURT:4d7 B:HIT:HURT:4d7 B:HIT:HURT:4d7 F:UNIQUE | MALE | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_90 | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_FIRE | IM_ELEC F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_4 | S:SLOW | FORGET D:A Black Numenorean with a blacker heart. N:393:It G:.:W I:110:77d9:25:80:25 W:24:3:500:400 E:0:0:0:0:0:0 O:10:0:90:0 B:GAZE:BLIND:8d8 B:TOUCH:TERRIFY B:GAZE:EXP_40 B:TOUCH:EAT_ITEM F:ONLY_ITEM | DROP_90 | DROP_1D2 | DROP_GOOD | DROP_GREAT | DROP_CORPSE | F:CHAR_MULTI | CHAR_CLEAR | ATTR_CLEAR | INVISIBLE | COLD_BLOOD | F:NO_CONF | UNIQUE | FORCE_MAXHP | NO_SLEEP | CAN_SPEAK | REFLECTING | F:IM_FIRE | IM_ELEC | EMPTY_MIND | EVIL | SMART | RES_TELE | CAN_FLY | F:ZANGBAND S:1_IN_4 S:DRAIN_MANA | BLINK | BLIND | SCARE | CONF | S_UNDEAD | S_MONSTER | S:HEAL | TELE_AWAY | DARKNESS | S_HYDRA | TRAPS | FORGET | TELE_TO | SHRIEK D:Nobody has ever seen It. N:394:Banshee G:G:b I:120:6d8:20:24:10 W:24:2:0:60 E:0:0:0:0:0:0 O:80:0:0:15 B:WAIL:TERRIFY B:TOUCH:EXP_20 F:FEMALE | F:RAND_50 | DROP_1D2 | F:INVISIBLE | COLD_BLOOD | TAKE_ITEM | PASS_WALL | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_15 | S:TPORT | DRAIN_MANA D:It is a ghostly woman's form that wails mournfully. N:395:Carrion crawler G:c:o I:110:20d12:15:40:10 W:25:2:700:60 E:0:0:0:0:1:0 O:0:0:0:0 B:STING:PARALYZE:2d6 B:STING:PARALYZE:2d6 F:RAND_25 | F:WEIRD_MIND | BASH_DOOR | DROP_SKELETON | F:ANIMAL | IM_POIS | MORTAL | BASEANGBAND D:A hideous centipede covered in slime and with glowing tentacles around its D:head. N:396:Xiclotlan G:#:D I:110:25d13:15:60:10 W:25:2:6000:60 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:6d4 B:CRUSH:HURT:6d4 B:BITE:HURT:3d2 F:RAND_25 | SUSCEP_ACID | F:EMPTY_MIND | BASH_DOOR | F:IM_POIS | IM_ELEC | F:MORTAL | CTHANGBAND | NO_CUT D:"...a metallically grey tree... about sixteen feet high with D:very thick cylindrical branches... cylinders further D:divided into six flat circular extensions... and from the top D:of what I had taken for a trunk rose a featureless oval... an D:orifice gaping at the top." N:397:Silent watcher G:g:s I:110:80d25:60:80:0 W:35:3:4000:800 E:3:0:3:3:2:0 O:0:0:0:0 B:GAZE:TERRIFY B:GAZE:PARALYZE B:GAZE:LOSE_STR B:GAZE:HALLU F:EMPTY_MIND | COLD_BLOOD | NONLIVING | NEVER_MOVE | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | EVIL | F:HURT_ROCK | COLD_BLOOD | HURT_LITE | NO_FEAR | F:NO_CONF | NO_SLEEP | NO_STUN | NONLIVING | RES_TELE | BASEANGBAND | NO_CUT S:1_IN_3 | S:SHRIEK | S_MONSTER | S_MONSTERS | HOLD | CONF | MIND_BLAST | DRAIN_MANA D:A figure carved from stone, with three vulture faces whose eyes glow D:with a malevolent light. None escape its vigilance. N:398:Pukelman G:g:D I:110:80d12:12:80:10 W:25:3:10000:600 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d12 B:HIT:HURT:3d6 F:FORCE_SLEEP | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_ROCK | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_4 | S:SLOW | CONF | BO_ACID D:A stumpy figure carved from stone, with glittering eyes. N:399:Disenchanter beast G:q:v I:110:30d30:12:60:12 W:25:2:2000:250 E:0:1:0:2:1:0 O:0:0:0:0 B:TOUCH:UN_BONUS:1d10 B:TOUCH:UN_BONUS:1d10 B:TOUCH:UN_BONUS:1d10 B:TOUCH:UN_BONUS:1d10 F:STUPID | WEIRD_MIND | RES_DISE | DROP_CORPSE | ATTR_MULTI | F:IM_ACID | IM_POIS | F:NO_CONF | ZANGBAND D:It looks like an anteater, and there is a static feeling D:crackling around its long trunk. N:400:Dark elven druid G:h:G I:120:20d20:15:75:10 W:25:3:1200:500 E:1:1:1:2:1:1 O:10:0:80:10 B:HIT:HURT:1d7 B:HIT:HURT:1d7 B:HIT:HURT:3d8 F:MALE | F:FORCE_SLEEP | F:ONLY_ITEM | DROP_1D2 | DROP_SKELETON | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_6 | S:HEAL | CONF | DARKNESS | S:S_MONSTER | S_SPIDER | S_ANIMAL D:A powerful dark elf, with mighty nature-controlling enchantments. N:401:Stone troll G:T:W I:110:23d10:20:50:50 W:25:1:5000:85 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:BITE:HURT:3d4 F:MALE | F:FRIENDS | DROP_60 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | REGENERATE | F:EVIL | TROLL | HURT_LITE | HURT_ROCK | BASEANGBAND | NO_CUT D:He is a giant troll with scabrous black skin. N:402:Black G:j:d I:111:12d12:12:65:30 W:25:1:0:50 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:EXP_40:2d6 B:ENGULF:EXP_40:2d6 F:RAND_25 | F:IM_COLD | IM_POIS | IM_ACID | RES_NETH | F:EVIL | EMPTY_MIND | COLD_BLOOD | FRIENDS | CTHANGBAND | NO_CUT D:The eldritch blood of Yibb-Tstll is know only as "the Black": it is D:an amorphous substance, which will suck your life and deliver it to D:Yibb-Tstll. N:403:Hill troll G:T:s I:110:21d10:20:65:40 W:21:1:4000:75 E:1:1:1:2:1:1 O:30:70:0:0 B:HIT:HURT:1d5 B:HIT:HURT:1d5 B:BITE:HURT:2d6 F:MALE | F:FRIENDS | DROP_60 | WILD_TOO | WILD_WASTE | WILD_MOUNTAIN | F:DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | SUSCEP_FIRE | REGENERATE | F:EVIL | TROLL | HURT_LITE | BASEANGBAND D:A large troll with an extremely tough and warty hide. N:404:Wereworm G:w:u I:110:100d11:15:70:20 W:25:3:6000:300 E:0:0:0:0:1:0 O:0:0:0:0 B:GAZE:EXP_20 B:CRAWL:ACID:2d4 B:BITE:HURT:1d10 B:BITE:POISON:1d6 F:BASH_DOOR | EVIL | CAN_SWIM | WILD_TOO | WILD_SWAMP | F:ANIMAL | IM_ACID | DROP_CORPSE | F:MORTAL | BASEANGBAND D:A huge wormlike shape dripping acid, twisted by evil sorcery into a foul D:monster that breeds on death. N:405:Killer red beetle G:K:r I:110:20d8:14:50:30 W:25:1:600:90 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:LOSE_STR:4d4 F:RAND_25 | WILD_TOO | F:WEIRD_MIND | BASH_DOOR | DROP_CORPSE | F:ANIMAL | CAN_FLY | MORTAL | BASEANGBAND D:A giant beetle with poisonous mandibles. N:406:Disenchanter bat G:b:v I:130:6d8:12:28:50 W:26:4:50:75 E:0:1:1:0:1:0 O:0:0:0:0 B:HIT:UN_BONUS B:HIT:UN_BONUS F:FORCE_SLEEP | RAND_50 | ANIMAL | MORTAL | ATTR_MULTI | F:DROP_CORPSE | AI_ANNOY | CAN_FLY | BASEANGBAND | WEIRD_MIND D:A giant bat which feeds on raw magical energy. N:407:Gnoph-Keh G:q:s I:110:20d8:12:50:25 W:26:2:1500:95 E:0:1:0:2:1:0 O:20:40:20:10 B:CLAW:COLD:2d4 B:CLAW:COLD:2d4 B:BUTT:HURT:2d9 F:RAND_25 | DROP_90 | DROP_60 F:OPEN_DOOR | BASH_DOOR | AURA_COLD | IM_COLD | SUSCEP_FIRE | F:ANIMAL | DROP_CORPSE | CTHANGBAND S:1_IN_8 S:BR_COLD | BO_ICEE | BO_COLD | BA_COLD D:A creature with a sharp horn: "the hairy myth-thing of the D:Greenland ice, that walked sometimes on two legs, sometimes D:on four, and sometimes on six." N:408:Giant grey ant G:a:s I:110:19d8:10:40:40 W:26:1:700:90 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d12 F:RAND_25 | KILL_BODY | DROP_SKELETON F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | BASEANGBAND D:It is an ant encased in shaggy grey fur. N:409:Khufu, the Mummified King G:z:v I:110:85d11:20:40:40 W:26:4:1800:500 E:1:1:1:2:1:1 O:0:80:20:0 B:GAZE:TERRIFY B:HIT:DISEASE:6d6 B:CLAW:LOSE_CON:4d4 B:CLAW:LOSE_CON:4d4 F:UNIQUE | MALE | CAN_SPEAK | UNDEAD | EVIL | ESCORTS | ESCORT | F:FORCE_MAXHP | COLD_BLOOD | IM_POIS | IM_COLD | NO_FEAR | NO_CONF | NO_SLEEP | F:ONLY_ITEM | DROP_90 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | RES_TELE | BASEANGBAND | NO_CUT S:1_IN_5 | S:TRAPS | CAUSE_3 | DARKNESS | S_UNDEAD | SCARE | SLOW | S:S_KIN | ANIM_DEAD D:He is out to have revenge on those who have desecrated his tomb. N:410:Gwaihir the Windlord G:B:u I:130:85d10:20:65:20 W:24:6:1200:360 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:15d2 B:CLAW:HURT:15d2 B:BITE:HURT:3d10 F:CAN_FLY | UNIQUE | FORCE_MAXHP | DROP_CORPSE | CAN_SPEAK | F:WILD_ONLY | WILD_MOUNTAIN | WILD_VOLCANO | PET | F:ANIMAL | GOOD | BASEANGBAND D:The greatest of eagles in the Third Age of Middle-earth, Gwaihir rescued D:Gandalf the Wizard from Orthanc, and has twice brought his flock to the D:aid of Sauron's enemies in battle - first outside the gates of Erebor in D:the Battle of Five Armies, and then before the Black Gate of Mordor itself. N:411:Giant fire tick G:S:R I:110:16d8:14:54:20 W:26:2:200:90 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:FIRE:3d6 F:RAND_25 | SUSCEP_COLD | F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | IM_FIRE | CAN_FLY | F:MORTAL | BASEANGBAND | HAS_LITE D:It is smoking and burning with great heat. N:412:Displacer beast G:f:b I:110:25d10:35:100:20 W:26:2:1800:100 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d8 B:HIT:HURT:1d10 B:HIT:HURT:1d10 B:HIT:HURT:1d10 F:INVISIBLE | BASH_DOOR | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:It is a huge black panther, clubbed tentacles sprouting from its shoulders. N:413:Ulwarth, Son of Ulfang G:p:U I:110:85d10:20:40:40 W:26:4:1800:500 E:1:1:1:2:1:1 O:40:60:0:0 B:HIT:HURT:4d6 B:HIT:HURT:4d6 B:HIT:HURT:4d6 F:UNIQUE | MALE | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE | F:FORCE_MAXHP | WILD_TOO | F:ONLY_ITEM | DROP_90 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL F:MORTAL | BASEANGBAND | HAS_LITE D:A short and swarthy Easterling. N:414:Werebear G:q:D I:110:25d25:20:50:20 W:24:2:0:200 E:0:1:0:2:1:0 O:25:25:25:20 B:CLAW:HURT:1d10 B:CLAW:HURT:1d10 B:BITE:HURT:2d8 B:CRUSH:HURT:2d6 F:BASH_DOOR | OPEN_DOOR | F:WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | DROP_CORPSE | F:ANIMAL | EVIL | DROP_1D2 | BASEANGBAND D:In the eyes of this bear, there glimmers the faintest light of intelligence. D:And then its form begins to change... The combination of animal cunning, D:human intelligence and the great physical strength of the bear makes for D:a dangerous enemy. N:415:Cave ogre G:O:u I:110:30d9:20:33:30 W:26:2:2500:80 E:1:1:1:2:1:1 O:20:70:0:10 B:HIT:HURT:3d8 B:HIT:HURT:3d8 F:FRIENDS | DROP_60 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | F:MORTAL | BASEANGBAND | HAS_LITE D:A giant orc-like figure with an awesomely muscled frame. N:416:White wraith G:W:w I:110:15d8:20:40:10 W:26:1:0:175 E:0:0:0:0:0:0 O:0:50:50:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:TOUCH:EXP_20 F:FORCE_SLEEP | F:DROP_1D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_8 | S:SCARE | CAUSE_2 | DARKNESS D:It is a tangible but ghostly form made of white fog. N:417:Angel G:A:o I:110:30d10:30:60:255 W:26:4:2600:220 E:1:1:1:2:1:1 O:0:40:60:0 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:FORCE_MAXHP | FORCE_SLEEP | NO_FEAR | F:ONLY_ITEM | DROP_2D2 | GOOD | CAN_FLY | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | F:IM_ACID | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_3 | S:BLIND | CONF | SCARE | FORGET D:Who knows why you are now facing an angel as an enemy? Is it a punishment D:from your own god for your sins, or a test of your mettle, or has this angel D:been sent by another god on behalf of someone who wishes to claim the glory D:for his own god? Perhaps you will never know: but it is here, and you must D:fight it. N:418:Ghoul G:z:U I:110:15d9:30:30:20 W:25:1:0:95 E:1:1:1:2:1:1 O:0:45:35:10 B:CLAW:DISEASE:1d4 B:CLAW:DISEASE:1d4 B:BITE:PARALYZE:1d5 F:DROP_60 | OPEN_DOOR | BASH_DOOR | CAN_SWIM | F:EVIL | UNDEAD | FRIENDS | IM_POIS | IM_COLD | NO_CONF | NO_SLEEP | F:COLD_BLOOD | HURT_LITE | BASEANGBAND | NO_CUT S:1_IN_9 S:SCARE | HOLD D:Flesh is falling off in chunks from this decaying abomination. N:419:Mim, Betrayer of Turin G:h:o I:120:11d105:20:80:20 W:27:4:1200:1000 E:1:1:1:2:1:1 O:10:80:10:0 B:HIT:HURT:3d9 B:HIT:HURT:3d9 B:HIT:HURT:3d9 B:HIT:UN_BONUS:3d12 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | FORCE_SLEEP | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:RES_DISE | RES_TELE | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_6 | S:HEAL | SCARE | BO_ACID | BA_ACID | TPORT | S_MONSTER D:The last of his race, Mim is a Petty-Dwarf. Petty-Dwarves are strange D:creatures, powerful in sorcery and originating in the East. They have D:been hunted nearly to extinction by the High Elves. N:420:Hellblade G:|:v I:120:13d13:20:40:20 W:27:2:0:130 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:EXP_20:2d13 B:HIT:EXP_20:2d13 F:CHAR_MULTI | EVIL | IM_POIS | IM_COLD | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | SUSCEP_ACID | F:COLD_BLOOD | BASH_DOOR | NONLIVING | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | HAS_LITE | NO_CUT D:A deadly blade of chaos, moving of its own volition. N:421:Killer fire beetle G:K:R I:110:22d8:14:45:30 W:27:1:600:95 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:3d4 B:SPIT:FIRE:4d5 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | WILD_VOLCANO | DROP_CORPSE | F:ANIMAL | IM_FIRE | CAN_FLY | SUSCEP_COLD | F:MORTAL | BASEANGBAND | HAS_LITE D:It is a giant beetle wreathed in flames. N:422:Beast of Nurgle G:q:y I:110:15d7:14:50:30 W:27:2:2300:100 E:0:1:0:2:1:0 O:0:0:0:0 B:TOUCH:POISON:3d3 B:TOUCH:DISEASE:3d3 B:BITE:ACID:4d5 F:WEIRD_MIND | BASH_DOOR | IM_ACID | IM_POIS | F:DEMON | EVIL | IM_FIRE | CAN_FLY | ZANGBAND D:It walks on four legs, but mostly resembles a slug-shaped jelly. D:It even has two disgusting antennae in its head. Yecch! N:423:Creeping adamantite coins G:$:G I:120:20d25:5:50:10 W:27:3:0:60 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:POISON:3d4 B:TOUCH:POISON:3d5 B:HIT:HURT:1d12 B:HIT:HURT:1d12 F:ONLY_GOLD | DROP_90 | DROP_2D2 | F:COLD_BLOOD | BASH_DOOR | CHAR_MULTI | F:IM_ELEC | IM_ACID | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:It appears to be a pile of coins made of precious adamant, slithering toward D:you on lots of tiny legs. N:424:Algroth G:T:o I:110:21d12:20:60:40 W:27:1:6000:150 E:1:1:1:2:1:1 O:10:80:0:10 B:CLAW:POISON:3d3 B:CLAW:POISON:3d3 B:BITE:HURT:1d6 F:FRIENDS | DROP_60 | WILD_WOOD | WILD_MOUNTAIN | WILD_TOO | WILD_SWAMP | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | REGENERATE | F:EVIL | TROLL | BASEANGBAND D:A powerful troll form. Venom drips from its needlelike claws. N:425:Flamer of Tzeentch G:,:r I:110:60d15:10:70:20 W:27:2:0:500 E:1:0:1:2:0:0 O:0:0:0:0 B:ENGULF:FIRE:3d6 B:ENGULF:FIRE:3d6 F:FORCE_SLEEP | BASH_DOOR | SUSCEP_COLD | F:IM_FIRE | IM_POIS | AURA_FIRE | DEMON | EVIL | RES_PLAS | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | ZANGBAND | HAS_LITE S:1_IN_3 | S:BO_FIRE | BA_FIRE D:It looks like an inverted mushroom, with two flexible arms. N:426:Roper G:#:D I:115:30d10:30:60:255 W:27:5:0:235 E:0:0:0:6:0:0 O:0:0:0:0 B:CRUSH:PARALYZE:3d5 B:CRUSH:PARALYZE:3d5 B:CRUSH:PARALYZE:3d5 B:CRUSH:PARALYZE:3d5 F:FORCE_MAXHP | FORCE_SLEEP | NO_FEAR | NEVER_MOVE | F:ONLY_GOLD | DROP_2D2 | DROP_60 | DROP_1D2 | EVIL | F:IM_ACID | IM_POIS | NO_CONF | NO_SLEEP | IM_COLD | IM_FIRE | BASEANGBAND F:NO_CUT S:1_IN_5 | S:BA_FIRE | BA_ELEC | BA_POIS | HASTE | S:TRAPS | SHRIEK | HOLD | CONF D:This creature look like a pillar of rock. However, a closer D:inspection reveals a glaring eye and powerful tentacles, D:which crush its prey and feed it to the creature's hungry D:mouth. N:427:Headless G:H:u I:110:25d12:20:50:40 W:27:1:1600:175 E:1:1:1:2:0:1 O:0:100:0:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:FRIENDS | DROP_60 | OPEN_DOOR | BASH_DOOR | WILD_TOO | F:WILD_MOUNTAIN | WILD_WASTE | DROP_SKELETON | DROP_CORPSE | F:EVIL | ZANGBAND S:1_IN_6 S:SCARE D:Headless humanoid abominations created by a magical mutation. N:428:Vibration hound G:Z:y I:110:25d10:30:30:0 W:27:2:600:250 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d8 B:BITE:HURT:2d8 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 F:FORCE_SLEEP | F:FRIENDS | F:BASH_DOOR | F:ANIMAL | NO_CONF | NO_SLEEP | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BR_SOUN D:A blurry canine form which seems to be moving as fast as the eye can D:follow. You can feel the earth resonating beneath your feet. N:429:Nexus hound G:Z:v I:110:25d10:30:30:0 W:27:2:600:250 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d8 B:BITE:HURT:2d8 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 F:FORCE_SLEEP | RES_NEXU | DROP_SKELETON | DROP_CORPSE | F:FRIENDS | F:BASH_DOOR | F:ANIMAL | RES_TELE | NO_SLEEP | MORTAL | BASEANGBAND S:1_IN_5 | S:BR_NEXU D:A locus of conflicting points coalesce to form the vague shape of a huge D:hound. Or is it just your imagination? N:430:Half-ogre G:O:o I:110:35d9:20:33:30 W:27:2:2700:80 E:1:1:1:2:1:1 O:20:70:0:10 B:HIT:HURT:4d8 B:HIT:HURT:4d8 F:FRIENDS | DROP_60 | DROP_CORPSE | SMART | F:OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | F:MORTAL | BASEANGBAND | HAS_LITE D:A giant, brutish figure, as ugly as an orc, but with some of the D:intelligence of his half-human ancestry. N:431:Lokkak, the Ogre Chieftain G:O:v I:120:15d103:20:100:20 W:32:2:3000:1500 E:1:1:1:2:1:1 O:5:85:0:5 B:HIT:HURT:6d7 B:HIT:HURT:6d7 B:HIT:HURT:6d7 F:UNIQUE | MALE | CAN_SPEAK | WILD_TOO | WILD_SWAMP | WILD_SHORE | F:FORCE_MAXHP | ESCORT | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | CAN_SWIM | F:EVIL | GIANT | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE D:An ogre renowned for acts of surprising cruelty, Lokkak is the leader of a large D:band of violent ogres. N:432:Vampire G:V:W I:110:25d12:20:45:10 W:27:1:1700:175 E:1:1:1:2:1:1 O:20:40:20:10 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:BITE:EXP_20:2d6 B:BITE:EXP_20:2d6 F:FORCE_SLEEP | FORCE_MAXHP | F:COLD_BLOOD | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | REGENERATE | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | F:BASEANGBAND | NO_CUT S:1_IN_9 | S:TELE_TO | HOLD | SCARE | CAUSE_2 | MIND_BLAST | FORGET | DARKNESS D:It is a humanoid with an aura of power. You notice a sharp set of front D:teeth. N:433:Gorgimaera G:H:o I:110:25d20:12:55:10 W:27:2:2300:400 E:0:1:0:2:2:0 O:0:0:0:0 B:BUTT:HURT:2d10 B:BITE:FIRE:2d10 B:GAZE:PARALYZE:2d6 F:FORCE_SLEEP | SUSCEP_COLD | F:BASH_DOOR | CAN_FLY | DROP_CORPSE | F:IM_FIRE | BASEANGBAND S:1_IN_8 | S:BR_FIRE D:The result of evil experiments, this travesty of nature should never be D:alive. It has three heads - goat, dragon and gorgon - all attached to a D:lion's body. N:434:Shantak G:H:D I:120:25d20:12:55:10 W:27:2:6000:280 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:HURT:1d6 B:BITE:HURT:1d6 B:BITE:HURT:1d6 F:ANIMAL | IM_ACID | EVIL | ELDRITCH_HORROR | CAN_FLY | DROP_CORPSE | F:MORTAL | ZANGBAND S:1_IN_6 S:SCARE | HASTE D:A scaly bird larger than an elephant, with a horse-like head. N:435:Colbran G:g:y I:120:80d12:12:80:10 W:27:2:0:900 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:ELEC:3d8 B:HIT:ELEC:3d8 F:FORCE_SLEEP | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | CAN_FLY | F:IM_ELEC | IM_POIS | AURA_ELEC | REFLECTING | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_3 | S:BO_ELEC D:A man-shaped form of living lightning, sparks and shocks crackle all over D:this madly capering figure, as it leaps and whirls around and about you. N:436:Spirit naga G:n:w I:110:30d15:20:75:120 W:28:2:0:60 E:0:0:0:0:1:0 O:20:0:80:0 B:CRUSH:HURT:2d8 B:CRUSH:HURT:2d8 B:BITE:HURT:1d8 B:BITE:HURT:1d8 F:FEMALE | F:FORCE_SLEEP | CAN_FLY | F:ONLY_ITEM | DROP_90 | DROP_2D2 | DROP_CORPSE | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_4 | S:HEAL | BLIND | MIND_BLAST | DARKNESS D:A wraithly snake-like form with the torso of a beautiful woman, it is the D:most powerful of its kind. N:437:Corpser G:,:D I:112:30d15:20:75:120 W:28:2:0:65 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:2d8 B:CRUSH:HURT:2d8 B:CRUSH:HURT:2d8 B:CRUSH:HURT:2d8 F:WILD_TOO | WILD_GRASS | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP | F:MORTAL | ZANGBAND D:A creature who lives underground and eats surface dwellers that it catches D:with its poisonous tentacle, which is the only part of the creature that D:is ever seen. Perhaps it is better not to see the part which remains D:underground... N:438:Fiend of Slaanesh G:S:R I:120:15d20:12:50:40 W:28:4:0:225 E:0:1:0:2:1:0 O:0:0:0:0 B:STING:POISON:8d1 B:STING:LOSE_STR:8d1 B:WAIL:TERRIFY:1d4 F:BASH_DOOR | F:EVIL | DEMON | ZANGBAND D:Slaanesh's pet, a large scorpion-like creature with a human face and D:reptile skin. N:439:Stairway to Hell G:>:W I:120:15d8:90:40:20 W:28:5:0:125 E:0:0:0:0:0:0 O:0:0:0:0 B:WAIL:UN_BONUS B:WAIL:EXP_20 B:WAIL:EAT_GOLD B:WAIL:EAT_ITEM F:CHAR_MULTI | COLD_BLOOD | EVIL | NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | F:UNDEAD | FORCE_MAXHP | IM_FIRE | IM_ELEC | IM_POIS | IM_ACID | EMPTY_MIND F:NEVER_MOVE | JOKEANGBAND | HAS_LITE | NO_CUT S:1_IN_15 S:S_DEMON | SHRIEK D:Often found in graveyards. N:440:5-headed hydra G:M:g I:120:100d8:20:80:20 W:28:2:5500:650 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:POISON:4d4 B:BITE:POISON:4d4 B:BITE:POISON:4d4 B:BITE:POISON:4d4 F:FORCE_SLEEP | F:ONLY_GOLD | DROP_1D2 | DROP_4D2 | DROP_SKELETON | DROP_CORPSE F:BASH_DOOR | MOVE_BODY | CAN_SWIM | F:ANIMAL | IM_POIS | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:MORTAL | BASEANGBAND S:1_IN_5 | S:SCARE | BA_POIS D:A strange reptilian creature with five heads dripping venom. N:441:Barney the Dinosaur G:R:v I:120:110d9:10:90:20 W:29:2:5000:500 E:0:1:0:2:1:0 O:10:0:90:0 B:SHOW:LOSE_INT B:SHOW:LOSE_WIS B:CHARGE:EAT_GOLD B:CHARGE:EAT_GOLD F:DROP_1D2 | DROP_90 | DROP_GOOD | DROP_GREAT | ONLY_ITEM | F:EVIL | MALE | CAN_SPEAK | SMART | RES_TELE | CAN_SWIM | DROP_CORPSE F:ANIMAL | IM_POIS | FORCE_MAXHP | UNIQUE | FORCE_SLEEP F:MORTAL | JOKEANGBAND S:1_IN_3 S:SHRIEK | CONF | S_HYDRA | SLOW | BLIND | DRAIN_MANA S:BA_POIS | BR_CHAO | FORGET | DARKNESS | BR_NUKE D:The lovable purple reptile is making a guest appearance here. N:442:Black knight G:p:s I:120:30d10:20:70:10 W:28:1:2400:240 E:1:1:1:2:1:1 O:0:90:10:0 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:MALE | F:FORCE_SLEEP | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_8 | S:BLIND | SCARE | CAUSE_3 | DARKNESS D:He is a figure encased in deep black plate armour; he looks at you D:menacingly. N:443:Seahorse G:~:o I:120:111d7:20:60:20 W:28:2:3000:360 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:PARALYZE:4d5 B:BITE:LOSE_DEX:4d5 B:BITE:LOSE_CON:4d5 F:FORCE_SLEEP | AQUATIC | GOOD | ANIMAL | F:IM_COLD | IM_POIS | IM_FIRE | IM_ELEC | WILD_TOO | WILD_OCEAN F:MORTAL | BASEANGBAND S:1_IN_5 | S:BO_WATE | BO_COLD | BO_ICEE | BO_MANA D:Your mind is filled with admiration as you view this wondrous, D:magical seahorse. N:444:Cyclops G:P:u I:120:60d20:20:90:20 W:45:2:3500:1500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:9d9 B:HIT:HURT:9d9 F:FORCE_SLEEP | F:DROP_1D2 | TAKE_ITEM | WILD_TOO | WILD_SHORE | WILD_MOUNTAIN | F:BASH_DOOR | OPEN_DOOR | MOVE_BODY | DROP_CORPSE | F:EVIL | IM_POIS | IM_ACID | IM_FIRE | IM_COLD | GIANT | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_8 | S:ARROW_4 D:A gigantic humanoid with but one eye. N:445:Clairvoyant G:p:y I:120:25d10:100:50:10 W:28:3:1600:250 E:1:1:1:2:1:1 O:0:0:90:10 B:HIT:CONFUSE:5d5 B:HIT:TERRIFY:5d5 F:MALE | F:FORCE_SLEEP | DROP_1D2 | DROP_SKELETON | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR | SMART | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_8 | S:BLIND | MIND_BLAST | HOLD | CAUSE_3 | FORGET | S_MONSTER D:He is using his supernatural talents to bring about your D:destruction. N:446:Purple worm G:w:v I:110:65d8:14:65:30 W:29:4:1000:400 E:0:0:0:0:1:0 O:0:0:0:0 B:HIT:HURT:1d8 B:BITE:ACID:2d8 B:STING:POISON:1d8 F:BASH_DOOR | DROP_CORPSE | F:ANIMAL | IM_ACID | IM_POIS | CAN_SWIM | F:MORTAL | BASEANGBAND D:It is a massive worm form, many feet in length. Its vast maw drips acid D:and poison. N:447:Catoblepas G:q:g I:110:30d10:15:55:40 W:29:2:0:400 E:0:1:0:2:1:0 O:0:0:0:0 B:GAZE:TERRIFY:2d4 B:GAZE:BLIND:2d4 B:BUTT:HURT:2d6 B:BITE:HURT:2d12 F:ONLY_GOLD | DROP_2D2 | DROP_CORPSE F:BASH_DOOR | CAN_SWIM | WILD_TOO | WILD_SWAMP | F:ANIMAL | IM_POIS F:MORTAL | BASEANGBAND D:A strange ox-like form with a huge head but a thin, weak neck, it looks D:like the creation of some deranged alchemist. N:448:Lesser wall monster G:#:W I:110:13d8:20:75:40 W:28:4:0:600 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:2d6 B:HIT:HURT:2d6 B:HIT:HURT:2d6 F:FORCE_SLEEP | COLD_BLOOD | EMPTY_MIND | KILL_WALL | RAND_50 | F:BASH_DOOR | IM_COLD | IM_ACID | IM_FIRE | IM_ELEC | IM_POIS | NONLIVING | F:HURT_ROCK | NO_CONF | NO_SLEEP | CHAR_MULTI | BASEANGBAND | NO_CUT S:MULTIPLY D:A sentient, moving section of wall. N:449:Mage G:p:r I:110:15d8:20:40:10 W:28:1:1500:150 E:1:1:1:2:1:1 O:10:0:90:0 B:HIT:HURT:2d5 B:HIT:HURT:2d5 F:MALE | F:FORCE_SLEEP | F:ONLY_ITEM | DROP_1D2 | DROP_SKELETON | DROP_CORPSE | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HASTE | TPORT | TELE_TO | BLIND | CONF | S:BO_FIRE | BO_COLD | BO_ELEC | S:S_MONSTER D:A fat mage with glasses. And considerable power, too - as you can D:tell from the size of his hat. N:450:Mind flayer G:h:v I:110:15d10:20:60:10 W:28:1:1400:200 E:1:1:1:2:1:1 O:0:10:90:0 B:CRUSH:LOSE_INT:2d6 B:GAZE:INSANITY:2d6 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE F:ONLY_ITEM | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP F:MORTAL | BASEANGBAND S:1_IN_8 | S:BLIND | HOLD | SCARE | MIND_BLAST | BRAIN_SMASH | FORGET D:A humanoid form with a gruesome head, tentacular mouth, and piercing D:eyes. Claws reach out for you and you feel a presence invade your mind. N:451:The Ultimate Dungeon Cleaner G:g:D I:120:70d12:10:80:12 W:28:2:0:555 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:2d10 B:CRUSH:HURT:2d10 B:CRUSH:HURT:2d10 B:CRUSH:HURT:2d10 F:FORCE_SLEEP | FORCE_MAXHP | KILL_BODY | KILL_ITEM | UNIQUE | REFLECTING | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS F:NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | RES_TELE | JOKEANGBAND | NO_CUT D:It looks like a huge spiked roller. It was designed to keep this dungeon D:clean, and you are the biggest spot of dirt in sight. N:452:Deep one G:u:g I:120:35d12:20:50:20 W:28:5:4000:150 E:1:1:1:2:1:1 O:20:80:0:0 B:CLAW:POISON:2d4 B:CLAW:POISON:2d4 B:BITE:HURT:4d4 F:FRIENDS | WILD_TOO | WILD_SHORE | DROP_CORPSE | F:RAND_25 | F:DROP_60 | DROP_90 | F:CAN_SWIM | BASH_DOOR | ELDRITCH_HORROR | RES_TELE | F:EVIL | DEMON | IM_FIRE | IM_COLD | IM_POIS | RES_WATE | CTHANGBAND D:"I thought their predominant color was a greyish-green, D:though they had white bellies. They were mostly shiny and D:slippery, but the ridges of their backs were scaly. Their D:forms vaguely suggested the anthropoid, while their heads were D:the heads of fish, with prodigious bulging eyes that never D:closed. At the sides of their necks were palpitating gills and D:their long paws were webbed." N:453:Basilisk G:R:s I:120:20d30:15:90:30 W:28:3:400:350 E:0:1:0:2:1:0 O:50:0:30:20 B:GAZE:PARALYZE B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 F:ONLY_ITEM | DROP_1D2 | WILD_TOO | WILD_MOUNTAIN | F:OPEN_DOOR | BASH_DOOR | EVIL | IM_POIS | DROP_CORPSE | F:ANIMAL | NO_CONF | NO_SLEEP | CAN_SWIM | F:MORTAL | BASEANGBAND S:1_IN_8 | S:BR_POIS D:An evil reptile that preys on unsuspecting travellers. Its eyes stare D:deeply at you and your soul starts to wilt! N:454:Ice troll G:T:w I:110:24d10:20:56:50 W:28:1:5000:200 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d5 B:HIT:HURT:1d5 B:BITE:COLD:2d6 B:BITE:COLD:2d6 F:MALE | F:FRIENDS | DROP_60 | WILD_TOO | WILD_WASTE | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | SUSCEP_FIRE | REGENERATE | F:EVIL | TROLL | IM_COLD | HURT_LITE | BASEANGBAND D:He is a white troll with powerful clawed hands. N:455:Dhole G:w:s I:110:65d8:14:64:25 W:29:4:1000:555 E:0:0:0:0:1:0 O:0:0:0:0 B:SPIT:ACID:1d8 B:ENGULF:ACID:2d8 B:CRUSH:HURT:4d8 F:ANIMAL | EVIL | KILL_WALL | IM_ACID | ELDRITCH_HORROR | F:CAN_SWIM | FORCE_MAXHP | DROP_CORPSE | F:MORTAL | CTHANGBAND S:1_IN_6 S:BR_ACID D:A gigantic worm dripping with acid. "...even as he looked, one D:reared up several hundred feet and leveled a bleached, viscous end D:at him." N:456:Archangel G:A:B I:110:60d10:30:68:255 W:34:4:4000:1000 E:1:1:1:2:1:1 O:0:40:60:0 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:FORCE_MAXHP | FORCE_SLEEP | NO_FEAR | GOOD | F:ONLY_ITEM | DROP_2D2 | CAN_FLY | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | F:IM_FIRE | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | RES_TELE | F:BASEANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | HASTE | BLIND | CONF | SCARE D:A lesser angel protected by an aura of holiness. Its muscular form looks D:extremely powerful next to your own frail body. N:457:Greater Mimic G:m:y I:120:10d35:30:60:100 W:29:3:100:200 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:POISON:3d4 B:HIT:POISON:3d4 B:HIT:POISON:3d4 B:HIT:POISON:3d4 F:MIMIC | F:FORCE_SLEEP | NEVER_MOVE | SUSCEP_ACID | F:EMPTY_MIND | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_4 | S:BLIND | CONF | SCARE | CAUSE_2 | FORGET | S:BO_ACID | BO_FIRE | BO_COLD | BO_ELEC | S:S_MONSTER D:A strange creature that disguises itself as an object to lure D:unsuspecting adventurers within reach of its venomous claws. N:458:Chaos tile G:.:v I:120:3d5:30:60:100 W:29:6:100:200 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:POISON:3d4 B:HIT:CONFUSE:3d4 F:CHAR_MULTI | ATTR_MULTI | ATTR_ANY | F:FORCE_SLEEP | NEVER_MOVE | F:EMPTY_MIND | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | ZANGBAND | NO_CUT S:MULTIPLY | S:1_IN_4 | S:BLIND | CONF | SCARE | CAUSE_2 | BLINK | S_MONSTER D:It is a floor tile corrupted by chaos. N:459:Young blue dragon G:d:b I:110:27d10:20:50:70 W:29:1:20000:500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:2d6 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_MOUNTAIN | WILD_WOOD | F:DROP_2D2 | DROP_CORPSE | ATTR_MULTI F:OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | DRAGON | IM_ELEC | BASEANGBAND | ATTR_MULTI S:1_IN_10 | S:SCARE | S:BR_ELEC D:It has a form out of legend. Its still-tender scales are a D:deep blue in hue. Sparks crackle along its length. N:460:Young white dragon G:d:w I:110:27d10:20:50:70 W:29:1:20000:500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:2d6 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_MOUNTAIN | WILD_WASTE | F:DROP_2D2 | DROP_CORPSE | ATTR_MULTI F:OPEN_DOOR | BASH_DOOR | CAN_FLY | SUSCEP_FIRE | F:EVIL | DRAGON | IM_COLD | BASEANGBAND | ATTR_MULTI S:1_IN_10 | S:SCARE | S:BR_COLD D:It has a form out of legend. Its still-tender scales are a D:frosty white in hue. Icy blasts of cold air come from it as it breathes. N:461:Young green dragon G:d:g I:110:27d10:20:50:70 W:29:1:20000:500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:2d6 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_MOUNTAIN | WILD_SWAMP | F:DROP_2D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | DRAGON | IM_POIS | BASEANGBAND | ATTR_MULTI S:1_IN_10 | S:SCARE | S:BR_POIS D:It has a form out of legend. Its still-tender scales are a D:deep green in hue. Foul gas seeps through its scales. N:462:Young bronze dragon G:d:U I:110:27d10:20:50:70 W:29:1:20000:500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:2d6 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_MOUNTAIN | F:DROP_2D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | DRAGON | NO_CONF | BASEANGBAND | ATTR_MULTI S:1_IN_10 | S:SCARE | S:BR_CONF D:It has a form out of legend. Its still-tender scales are a D:rich bronze hue, and its shape masks its true form. N:463:Aklash G:T:R I:110:30d8:14:64:25 W:29:4:4000:300 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:1d6 B:CLAW:HURT:1d6 B:BITE:POISON:1d20 B:CRUSH:HURT:2d9 F:TROLL | EVIL | FRIENDS | OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:IM_POIS | IM_ACID | REGENERATE | ZANGBAND | REGENERATE | S:1_IN_9 | BR_POIS D:Pale, bald, fat, hairless troll creatures. Ugly beyond description. D:Not to mention how bad their breath smells... N:464:Mithril golem G:g:B I:110:80d15:12:100:10 W:30:4:10000:500 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:ONLY_GOLD | DROP_2D2 | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | REFLECTING | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT D:It is a massive statue of purest mithril. It looks expensive! N:465:Skeleton troll G:s:W I:110:20d10:20:55:20 W:30:1:5000:225 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:BITE:HURT:3d4 F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | TROLL | UNDEAD | F:IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a troll skeleton animated by dark dweomers. N:466:Skeletal tyrannosaur G:R:w I:120:50d10:20:55:20 W:30:2:6000:225 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:1d8 B:CLAW:HURT:1d8 B:BITE:LOSE_CON:4d6 B:GAZE:TERRIFY F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | ANIMAL | UNDEAD | F:IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | ZANGBAND | NO_CUT D:It is the skeleton of a tyrannosaur, animated by dark dweomers. N:467:Beorn, the Shape-Changer G:q:D I:120:20d70:25:60:25 W:28:3:0:1000 E:0:1:0:2:1:0 O:20:60:20:0 B:CLAW:HURT:2d10 B:CLAW:HURT:2d10 B:BITE:HURT:4d8 B:CRUSH:HURT:3d6 F:UNIQUE | MALE | FORCE_MAXHP | FORCE_SLEEP | F:BASH_DOOR | ANIMAL | MOVE_BODY | SMART | PET F:WILD_TOO | WILD_WOOD | WILD_MOUNTAIN | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | BASEANGBAND S:1_IN_6 | S_ANIMAL D:Beorn is only occasionally seen in human form these days, preferring to D:appear in the shape of a giant black bear: he also prefers the company of D:beasts to that of humans. He has never taken kindly to strangers, even in D:human form - and still less when in bear's shape, as he is now. N:468:Thorondor, Lord of Eagles G:B:u I:130:85d12:20:65:20 W:30:6:1600:555 E:0:1:1:0:1:0 O:0:0:0:0 B:CLAW:HURT:16d2 B:CLAW:HURT:16d2 B:BITE:HURT:4d10 F:CAN_FLY | UNIQUE | FORCE_MAXHP | DROP_CORPSE | CAN_SPEAK | F:WILD_ONLY | WILD_MOUNTAIN | WILD_VOLCANO | PET | F:ANIMAL | GOOD | BASEANGBAND D:Among the mightiest of birds, Thorondor is the messenger of the Valar, and D:brings news of Middle-earth to Valinor itself. Nothing that can be seen D:from the airs of the world is hidden from him. N:469:Giant blue ant G:a:b I:110:8d8:10:50:60 W:30:2:600:80 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:ELEC:5d5 F:RAND_25 | WILD_TOO | DROP_SKELETON F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | IM_ELEC F:MORTAL | BASEANGBAND D:It is a giant ant that crackles with energy. N:470:Grave wight G:W:b I:110:12d10:20:50:30 W:30:1:0:325 E:0:0:0:0:0:0 O:0:50:50:0 B:HIT:HURT:1d7 B:HIT:HURT:1d7 B:TOUCH:EXP_20 F:FORCE_SLEEP | RAND_25 | F:ONLY_ITEM | DROP_1D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | CAN_FLY | F:IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_8 | S:SCARE | CAUSE_3 | DARKNESS D:It is a ghostly form with eyes that haunt you. N:471:Shadow drake G:d:G I:110:30d10:20:70:70 W:33:3:18000:1100 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:EXP_10:3d6 F:FORCE_SLEEP | FORCE_MAXHP | PASS_WALL | F:ONLY_ITEM | DROP_3D2 | CAN_FLY | DROP_CORPSE | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | ATTR_MULTI S:1_IN_6 | S:BR_NETH | SLOW | CONF | SCARE | DARKNESS D:It is a dragon-like form wrapped in shadow. Glowing red eyes shine in D:the dark, and it is surrounded by an aura of unearthly cold that chills D:the soul rather than the body. N:472:Manticore G:H:y I:120:25d10:12:15:10 W:30:2:1900:300 E:1:1:1:2:1:0 O:0:0:0:0 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:FORCE_SLEEP | FORCE_MAXHP | F:BASH_DOOR | CAN_FLY | WILD_TOO | WILD_WOOD | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND S:1_IN_5 | S:ARROW_4 D:It is a winged lion's body with a human torso and a tail covered in D:vicious spikes. N:473:Giant army ant G:a:o I:120:19d6:10:40:40 W:30:3:600:90 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d12 F:RAND_25 | KILL_BODY | FRIENDS | DROP_SKELETON F:WEIRD_MIND | BASH_DOOR | F:ANIMAL F:MORTAL | BASEANGBAND D:An armoured form moving with purpose. Powerful on its own, flee when D:hordes of them march. N:474:Killer slicer beetle G:K:y I:110:25d10:14:60:30 W:30:2:600:200 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:5d8 B:BITE:HURT:5d8 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | WILD_GRASS | DROP_CORPSE F:ANIMAL | CAN_FLY | MORTAL | BASEANGBAND D:It is a beetle with deadly sharp cutting mandibles and a rock-hard D:carapace. N:475:Gorgon G:H:b I:110:30d20:12:88:20 W:31:2:3000:275 E:1:1:1:2:1:1 O:0:0:0:0 B:BUTT:HURT:3d9 B:BUTT:HURT:3d9 B:BITE:POISON:1d10 B:KICK:HURT:2d4 F:FORCE_SLEEP | ANIMAL | MOVE_BODY | WILD_TOO | WILD_WOOD | F:BASH_DOOR | IM_POIS | IM_ACID | DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_8 | S:BR_POIS D:A bull-like creature whose skin is made of steel plates. Watch out for D:its deadly breath! N:476:Gug G:P:G I:110:22d11:14:60:30 W:31:2:1500:210 E:2:0:2:4:1:1 O:0:50:50:0 B:BITE:HURT:10d4 B:CLAW:HURT:2d7 B:CLAW:HURT:2d7 B:CLAW:HURT:2d7 F:FORCE_SLEEP | F:DROP_1D2 | TAKE_ITEM | F:BASH_DOOR | OPEN_DOOR | DROP_CORPSE F:EVIL | IM_POIS | IM_ACID | GIANT | ZANGBAND D:A hideous, beastly, four-armed unclean giant: "...large as a D:barrel... The eyes jutted two inches from each side, shaded by D:bony protuberances overgrown of the mouth. That mouth had great D:yellow fangs and ran from the top to the tally." N:477:Ghost G:G:w I:120:13d8:20:30:10 W:31:1:0:350 E:0:0:0:0:0:0 O:30:40:0:20 B:WAIL:TERRIFY B:TOUCH:EXP_20 B:CLAW:LOSE_INT:1d6 B:CLAW:LOSE_WIS:1d6 F:FORCE_SLEEP | RAND_25 | DROP_60 | DROP_1D2 | F:INVISIBLE | COLD_BLOOD | TAKE_ITEM | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | CAN_FLY | F:IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:BLIND | HOLD | DRAIN_MANA D:You don't believe in them. N:478:Death watch beetle G:K:D I:110:25d12:16:60:30 W:31:3:800:220 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:5d4 B:WAIL:TERRIFY:5d6 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | DROP_CORPSE | F:ANIMAL | CAN_FLY | MORTAL | BASEANGBAND D:It is a giant beetle that produces a chilling sound. N:479:Mountain ogre G:O:s I:110:40d9:20:33:30 W:30:2:3000:100 E:1:1:1:2:1:1 O:20:70:0:10 B:HIT:HURT:5d8 B:HIT:HURT:5d8 F:FRIENDS | DROP_60 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | F:MORTAL | BASEANGBAND | HAS_LITE D:The largest breed of ogre, he is awesomely strong and awesomely ugly. N:480:Nexus quylthulg G:Q:v I:110:10d12:10:1:0 W:32:1:3000:300 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | RES_NEXU | ANIMAL | F:NO_CONF | NO_SLEEP | NO_FEAR | RES_TELE | BASEANGBAND S:1_IN_1 | S:BLINK | TELE_AWAY D:It is a very unstable, strange pulsing mound of flesh. N:481:Shelob, Spider of Darkness G:S:D I:120:35d100:30:120:80 W:55:3:1400:27000 E:0:1:0:2:1:0 O:20:30:40:0 B:CLAW:POISON:5d6 B:CLAW:POISON:5d6 B:BITE:PARALYZE:5d10 B:STING:LOSE_STR:5d4 F:UNIQUE | FEMALE | F:FORCE_SLEEP | FORCE_MAXHP | SPECIAL_GENE | F:ESCORT | ESCORTS | DROP_CORPSE | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_GOOD | DROP_RANDART F:SMART | BASH_DOOR | IM_POIS | IM_ACID | F:ANIMAL | SPIDER | EVIL | HURT_LITE | NO_SLEEP | BASEANGBAND S:1_IN_4 | S:HEAL | BLIND | SLOW | CONF | SCARE | CAUSE_3 | CAUSE_4 | S:TRAPS | BR_DARK | BR_POIS | S:S_SPIDER D:Shelob is an enormous bloated spider, the last daughter of Ungoliant the D:Unlight. Her poison is legendary, as is her ego. She normally guards the D:pass through Cirith Ungol, but occasionally goes out foraging for food to D:feed her voracious appetite. N:482:Giant squid G:~:g I:110:80d10:8:80:80 W:32:3:3000:600 E:3:0:3:6:1:0 O:0:0:0:0 B:CRUSH:HURT:8d4 B:CRUSH:HURT:8d4 B:CRUSH:HURT:8d4 F:IM_ACID | RES_WATE | AQUATIC | ANIMAL | IM_COLD | MOVE_BODY F:FORCE_MAXHP | WILD_TOO | WILD_OCEAN | BASEANGBAND | COLD_BLOOD S:1_IN_8 S:BR_ELEC | BR_ACID | BR_POIS D:Besides being capable of dragging whole ships underwater, D:this creature can also harm you with ranged attacks. N:483:Ghoulking G:z:D I:120:40d12:20:60:10 W:32:2:0:340 E:1:1:1:2:1:1 O:20:40:30:0 B:CLAW:LOSE_STR:3d4 B:CLAW:DISEASE:3d4 B:CLAW:DISEASE:3d4 B:BITE:PARALYZE:3d5 F:DROP_60 | OPEN_DOOR | BASH_DOOR | CAN_SWIM | F:DROP_1D2 | FORCE_MAXHP | ESCORT | FORCE_SLEEP | F:EVIL | UNDEAD | IM_POIS | IM_COLD | NO_CONF | NO_SLEEP | F:COLD_BLOOD | HURT_LITE | BASEANGBAND | NO_CUT S:1_IN_7 S:SCARE | HOLD | DARKNESS | SCARE | S_UNDEAD | ANIM_DEAD D:Flesh is falling off in chunks from this decaying abomination. N:484:Doombat G:b:R I:120:24d14:16:75:30 W:32:2:150:250 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:FIRE:5d4 B:BITE:FIRE:5d4 B:BITE:FIRE:5d4 F:WEIRD_MIND | BASH_DOOR | AURA_FIRE | CAN_FLY | DROP_CORPSE | F:IM_FIRE | AI_ANNOY | F:ANIMAL | MORTAL | BASEANGBAND D:It is a fast moving creature of chaos, a gigantic black bat D:surrounded by flickering bright red flames. N:485:Ninja G:p:u I:120:13d12:20:60:10 W:32:2:1600:300 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:POISON:3d4 B:HIT:LOSE_STR:3d4 B:HIT:LOSE_STR:3d4 F:MALE | F:DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE D:A humanoid clothed in black who moves with blinding speed. N:486:Memory moss G:,:b I:110:1d2:30:1:5 W:32:3:50:150 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:CONFUSE:1d4 B:HIT:CONFUSE:1d4 F:FORCE_SLEEP | NEVER_MOVE | F:STUPID | EMPTY_MIND | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT S:1_IN_6 | S:FORGET D:A mass of vegetation. You don't remember seeing anything like it D:before. N:487:Storm giant G:P:B I:110:40d20:20:60:40 W:40:1:13000:1000 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:ELEC:10d8 B:HIT:ELEC:10d8 F:FORCE_SLEEP | FORCE_MAXHP | DROP_1D2 | WILD_TOO | WILD_MOUNTAIN | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | AURA_ELEC | DROP_SKELETON | DROP_CORPSE | F:EVIL | GIANT | IM_COLD | IM_ELEC | MALE | BASEANGBAND | HAS_LITE S:1_IN_8 | S:BLINK | TELE_TO | CONF | SCARE | BO_ELEC | BA_ELEC D:It is a twenty-five foot tall giant wreathed in lightning. N:488:Spectator G:e:B I:110:15d13:30:1:5 W:28:2:1600:150 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:PARALYZE:1d4 B:GAZE:CONFUSE:1d4 B:BITE:HURT:1d8 F:FORCE_SLEEP | FORCE_MAXHP | F:STUPID | EMPTY_MIND | CAN_FLY | DROP_CORPSE | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL | BASEANGBAND S:1_IN_6 | S:FORGET | CAUSE_2 | HOLD | SLOW D:A lesser relative of the beholder: a globular body with a large toothy mouth, D:a large central eye, and four smaller eyes on stalks protruding from the top D:of its body. N:489:Bokrug G:R:v I:110:11d90:20:70:50 W:33:7:0:2200 E:1:1:1:2:1:1 O:20:0:80:0 B:BITE:HURT:5d5 B:CRUSH:HURT:2d10 B:CRUSH:HURT:2d10 F:UNIQUE | CAN_SPEAK | F:FORCE_MAXHP | NONLIVING | NO_CONF | NO_FEAR | F:ESCORT | ESCORTS | ELDRITCH_HORROR | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | CAN_SWIM | F:EVIL | IM_COLD | IM_POIS | DEMON | CTHANGBAND S:1_IN_5 S:S_UNDEAD | MIND_BLAST | CAUSE_3 | SCARE | BO_WATE | S_KIN D:A lizard-like Great Old One worshipped by the men of Sarnath. N:490:Biclops G:P:u I:120:65d20:20:90:20 W:48:5:3000:1700 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:10d9 B:HIT:HURT:10d9 F:FORCE_SLEEP | F:DROP_1D2 | TAKE_ITEM | DROP_CORPSE | F:BASH_DOOR | OPEN_DOOR | MOVE_BODY | F:EVIL | IM_POIS | IM_ACID | IM_FIRE | IM_COLD | GIANT | F:MORTAL | ZANGBAND | HAS_LITE S:1_IN_8 | S:ARROW_4 D:Oh, no! Aaargh! It is the most unnatural, most disgusting D:creature imaginable: a two-eyed cyclops! This perversion D:of nature must be exterminated! N:491:Half-troll G:T:U I:110:25d14:20:50:50 W:34:2:3000:400 E:1:1:1:2:1:1 O:20:80:0:0 B:CLAW:HURT:1d5 B:CLAW:HURT:1d5 B:BITE:HURT:2d6 B:BITE:HURT:2d6 F:MALE | F:FRIENDS | F:ONLY_ITEM | DROP_90 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | REGENERATE | F:EVIL | TROLL | IM_POIS | BASEANGBAND D:A huge, ugly, half-human in search of plunder. N:492:Ivory monk G:p:w I:120:38d9:22:55:5 W:33:1:1600:900 E:1:1:1:2:1:1 O:40:0:50:10 B:KICK:HURT:8d1 B:HIT:HURT:8d4 B:KICK:HURT:8d1 B:HIT:HURT:8d4 F:OPEN_DOOR | BASH_DOOR | NO_FEAR | NO_CONF | NO_SLEEP | DROP_SKELETON | F:DROP_CORPSE | MALE | DROP_60 | DROP_1D2 | IM_FIRE | IM_COLD | IM_POIS | F:MORTAL | ZANGBAND | HAS_LITE D:A monk trained in the most lethal martial arts. N:493:Bert the Stone Troll G:T:W I:120:11d100:20:70:50 W:34:7:5000:2000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:BITE:HURT:3d10 F:UNIQUE | MALE | F:FORCE_MAXHP | F:ESCORT | SPECIAL_GENE | MOVE_BODY | REGENERATE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | WILD_TOO | WILD_WOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | TROLL | IM_COLD | IM_POIS | HURT_LITE | HURT_ROCK | BASEANGBAND | NO_CUT D:Big, brawny, powerful and with a taste for hobbit. He has friends called D:Bill and Tom. N:494:Bill the Stone Troll G:T:W I:120:11d100:20:70:50 W:34:7:5000:2000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:BITE:HURT:3d10 F:UNIQUE | MALE | F:FORCE_MAXHP | F:ESCORT | SPECIAL_GENE | MOVE_BODY | REGENERATE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | WILD_TOO | WILD_WOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE F:EVIL | TROLL | IM_COLD | IM_POIS | HURT_LITE | HURT_ROCK | BASEANGBAND | NO_CUT D:Big, brawny, powerful and with a taste for hobbit. He has friends called D:Bert and Tom. N:495:Tom the Stone Troll G:T:W I:120:11d100:20:70:50 W:34:7:5000:2000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:BITE:HURT:3d10 F:UNIQUE | MALE | F:FORCE_MAXHP | F:ESCORT | SPECIAL_GENE | MOVE_BODY | REGENERATE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | WILD_TOO | WILD_WOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | TROLL | IM_COLD | IM_POIS | HURT_LITE | HURT_ROCK | BASEANGBAND | NO_CUT D:Big, brawny, powerful and with a taste for hobbit. He has friends called D:Bert and Bill. N:496:Cave troll G:T:u I:110:24d12:20:50:50 W:33:1:6000:350 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:BITE:HURT:1d8 B:BITE:HURT:1d8 F:MALE | F:FRIENDS | DROP_60 | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | SUSCEP_FIRE | REGENERATE | F:EVIL | TROLL | IM_POIS | HURT_LITE | BASEANGBAND D:He is a vicious monster, feared for his ferocity. N:497:Anti-paladin G:p:D I:120:30d20:30:50:30 W:33:2:2400:450 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:2d6 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:MALE | OPEN_DOOR | BASH_DOOR | TAKE_ITEM | DROP_1D2 | ONLY_ITEM | F:EVIL | IM_POIS | IM_COLD | NO_CONF | NO_SLEEP | DROP_SKELETON | DROP_CORPSE F:MORTAL | ZANGBAND | HAS_LITE S:1_IN_4 S:HOLD | SCARE | BLIND | CAUSE_3 | TRAPS | DARKNESS | FORGET | HASTE D:An embodiment of all the cardinal vices, he beholds you scornfully. N:498:Chaos master G:p:v I:120:30d10:30:50:5 W:37:3:2300:550 E:1:1:1:2:1:1 O:10:60:10:10 B:HIT:HURT:10d2 B:KICK:HURT:10d2 B:PUNCH:HURT:10d2 B:KICK:HURT:10d2 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | EVIL | F:ONLY_ITEM | DROP_1D2 | ATTR_ANY | DROP_SKELETON | DROP_CORPSE F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_POIS | NO_CONF | NO_SLEEP F:MORTAL | ZANGBAND | HAS_LITE S:1_IN_6 | S:HEAL | S:S_SPIDER | BA_CHAO | S_DEMON D:An adept of chaos, feared for his skill of invoking raw Chaos. N:499:Barrow wight G:W:v I:110:15d10:20:40:10 W:33:3:0:375 E:0:0:0:0:0:0 O:0:50:50:0 B:HIT:HURT:1d8 B:HIT:HURT:1d8 B:TOUCH:EXP_40 F:FORCE_SLEEP | FRIENDS | DROP_60 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_8 | S:HOLD | SCARE | CAUSE_2 | DARKNESS D:It is a ghostly nightmare of an entity. N:500:Skeleton ettin G:s:W I:110:45d10:20:50:20 W:33:1:7000:325 E:1:1:1:2:2:1 O:0:0:0:0 B:HIT:HURT:1d9 B:HIT:HURT:1d9 B:BITE:HURT:1d5 B:BITE:HURT:1d5 F:FORCE_MAXHP | F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | TROLL | UNDEAD | F:IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is the animated skeleton of a massive two-headed troll. N:501:Chaos drake G:d:v I:110:50d10:20:70:70 W:33:3:18000:1400 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:3d6 F:ATTR_MULTI | ATTR_ANY | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_3D2 | RES_DISE | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:EVIL | DRAGON | F:IM_FIRE | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_6 | S:SLOW | CONF | SCARE | S:BR_DISE | BR_CHAO D:A dragon twisted by the forces of chaos. It seems first ugly, then fair, D:as its form shimmers and changes in front of your eyes. N:502:Law drake G:d:B I:110:50d10:20:70:70 W:33:3:18000:1400 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:3d6 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_3D2 | CAN_FLY | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:DRAGON | EVIL | F:IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | NO_CUT | ATTR_MULTI S:1_IN_6 | S:SLOW | CONF | SCARE | S:BR_SOUN | BR_SHAR D:This dragon is clever and cunning. It laughs at your puny efforts to D:disturb it. N:503:Balance drake G:d:v I:110:60d10:20:70:70 W:33:3:18000:1600 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:3d6 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_3D2 | RES_DISE | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE F:EVIL | DRAGON | CAN_FLY | F:IM_FIRE | IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | NO_CUT F:ATTR_MULTI S:1_IN_6 | S:SLOW | CONF | SCARE | S:BR_SOUN | BR_SHAR | BR_DISE | BR_CHAO D:A mighty dragon, the balance drake seeks to maintain the Cosmic Balance, D:and despises your feeble efforts to destroy evil. N:504:Ethereal drake G:d:o I:110:40d10:20:70:70 W:33:3:0:1200 E:0:1:0:6:1:0 O:40:50:10:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:3d6 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_3D2 | CAN_FLY | F:INVISIBLE | PASS_WALL | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | ATTR_MULTI S:1_IN_6 | S:SLOW | CONF | SCARE | S:BR_LITE | BR_DARK | BR_CONF D:A dragon of great power with control over light and dark, the D:ethereal drake's eyes glare with white hatred from the shadows. N:505:Groo, the Wanderer G:p:U I:120:13d113:20:70:50 W:35:7:5000:2000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:9d1 B:HIT:HURT:6d5 B:HIT:HURT:25d1 B:HIT:HURT:6d5 F:UNIQUE | MALE | WEIRD_MIND | CAN_SPEAK | F:FORCE_MAXHP | WILD_TOO | DROP_CORPSE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:DROP_CHOSEN | F:OPEN_DOOR | BASH_DOOR | F:IM_COLD | IM_POIS | ZANGBAND D:He who laughs at Groo's brains will find there is nothing to laugh D:about... erm, nobody laughs at Groo and lives. N:506:Fasolt the Giant G:P:u I:110:11d111:20:70:50 W:33:4:10000:2000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:7d10 B:HIT:HURT:7d10 B:HIT:EAT_GOLD:2d10 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_MAXHP | WILD_TOO | DROP_CORPSE | F:ESCORT | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | IM_COLD | IM_POIS | BASEANGBAND | HAS_LITE D:Big, brawny, powerful and with a greed for gold. N:507:Shade G:G:D I:120:14d20:20:30:10 W:33:3:0:350 E:0:0:0:0:0:0 O:0:0:100:0 B:WAIL:TERRIFY B:TOUCH:EXP_40 B:CLAW:LOSE_INT:1d10 F:FORCE_SLEEP | RAND_25 | F:ONLY_ITEM | DROP_90 | DROP_2D2 | F:INVISIBLE | COLD_BLOOD | TAKE_ITEM | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | CAN_FLY | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:BLIND | HOLD | DRAIN_MANA | FORGET D:A shadowy form clutches at you from the darkness. A powerful undead with D:a deadly touch. N:508:Spectre G:G:U I:120:14d20:20:30:10 W:33:3:0:350 E:0:0:0:0:0:0 O:0:0:100:0 B:WAIL:TERRIFY B:TOUCH:EXP_40 B:CLAW:LOSE_WIS:5d5 F:FORCE_SLEEP | RAND_25 | F:ONLY_ITEM | DROP_90 | DROP_2D2 | CAN_FLY | F:COLD_BLOOD | TAKE_ITEM | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:BLIND | HOLD | DRAIN_MANA | FORGET D:A phantasmal shrieking spirit. Its wail drives the intense cold of pure D:evil deep within your body. N:509:Water troll G:T:B I:110:36d10:20:50:50 W:35:1:4000:420 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d9 B:HIT:HURT:1d9 B:HIT:HURT:2d2 B:HIT:HURT:2d2 F:MALE | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE | F:FRIENDS | DROP_60 | REGENERATE | F:OPEN_DOOR | BASH_DOOR | CAN_SWIM | F:EVIL | TROLL | IM_COLD | IM_POIS | HURT_LITE | BASEANGBAND D:He is a troll that reeks of brackish water and mud. N:510:Fire elemental G:E:r I:110:30d8:12:50:50 W:33:2:0:350 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:FIRE:4d6 B:HIT:FIRE:4d6 F:FORCE_SLEEP | RAND_25 | F:EMPTY_MIND | CAN_FLY | WILD_TOO | WILD_VOLCANO | F:KILL_ITEM | KILL_BODY | BASH_DOOR | POWERFUL | AURA_FIRE | F:IM_FIRE | IM_POIS | IM_ELEC | IM_ACID | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_6 | S:BO_FIRE D:It is a towering inferno of flames. N:511:Cherub G:A:G I:120:100d10:30:68:255 W:39:4:0:2700 E:1:1:1:2:1:1 O:0:90:10:0 B:HIT:HURT:4d3 B:HIT:HURT:3d8 B:HIT:HURT:4d3 B:HIT:HURT:3d8 F:FORCE_SLEEP | FORCE_MAXHP | NO_FEAR | GOOD | CAN_FLY | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | REFLECTING | RES_TELE F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | HASTE | BLIND | SCARE | MIND_BLAST | BO_FIRE | S:S_MONSTERS D:It is an angel moving very quickly, wielding a holy war hammer and casting D:a volley of powerful spells in your direction. N:512:Water elemental G:E:b I:110:25d8:12:40:50 W:33:2:0:325 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d10 B:HIT:HURT:1d10 B:HIT:HURT:1d10 F:FORCE_SLEEP | RAND_25 | F:EMPTY_MIND | COLD_BLOOD | CAN_FLY | F:KILL_BODY | KILL_ITEM | BASH_DOOR | POWERFUL | F:IM_POIS | IM_ACID | IM_FIRE | IM_COLD | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_6 | S:BO_COLD D:It is a towering tempest of water. N:513:Multi-hued hound G:Z:v I:110:30d10:25:40:0 W:33:3:600:600 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:4d4 B:BITE:HURT:4d4 F:FORCE_SLEEP | F:FRIENDS | F:BASH_DOOR | ATTR_MULTI | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | NO_CONF | NO_SLEEP | F:IM_ELEC | IM_POIS | IM_ACID | IM_FIRE | IM_COLD | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_5 | S:BR_ACID | BR_POIS | BR_COLD | BR_FIRE | BR_ELEC D:Shimmering in rainbow hues, this hound is beautiful and deadly. N:514:Invisible stalker G:E:y I:130:19d12:20:46:20 W:35:3:0:300 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:RAND_50 | F:RES_TELE | F:EMPTY_MIND | INVISIBLE | COLD_BLOOD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING F:BASEANGBAND | NO_CUT D:It is impossible to define its form but its violence is legendary. N:515:Carrion crawler G:c:o I:110:20d12:15:40:10 W:34:2:2000:100 E:0:0:0:0:1:0 O:0:0:0:0 B:STING:PARALYZE:2d6 B:STING:PARALYZE:2d6 F:RAND_25 | FRIENDS | DROP_SKELETON | F:WEIRD_MIND | BASH_DOOR | F:ANIMAL | IM_POIS | MORTAL | BASEANGBAND D:A hideous centipede covered in slime and with glowing tentacles around its D:head. N:516:Master thief G:p:b I:130:18d10:20:30:40 W:34:2:1300:350 E:1:1:1:2:1:1 O:90:10:0:0 B:HIT:HURT:2d8 B:HIT:HURT:3d4 B:HIT:EAT_GOLD:4d4 B:HIT:EAT_ITEM:4d5 F:MALE | F:DROP_90 | DROP_2D2 | DROP_SKELETON | DROP_CORPSE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_6 S:TRAPS | ARROW_2 | BLINK D:Cool and confident, fast and lithe; protect your possessions quickly! N:517:The Watcher in the Water G:~:v I:120:27d100:30:100:80 W:45:3:7000:12000 E:3:0:3:6:1:0 O:50:50:0:0 B:CRUSH:ACID:8d8 B:CRUSH:POISON:8d8 B:CRUSH:PARALYZE:8d8 F:UNIQUE | FORCE_SLEEP | FORCE_MAXHP | CAN_SWIM | AQUATIC | ANIMAL | F:IM_ACID | IM_COLD | IM_POIS | RES_WATE | RES_TELE | DROP_CORPSE | F:NO_CONF | NO_FEAR | EVIL | COLD_BLOOD | BASEANGBAND | F:ONLY_ITEM | DROP_GOOD | DROP_4D2 | DROP_1D2 | SPECIAL_GENE | DROP_RANDART S:1_IN_5 | BA_WATE | BO_WATE | HOLD | BR_POIS | BO_ICEE | TELE_TO D:A vile creature which seems to consist mostly of tentacles, it seeks to D:drag people to their doom in the water. Few have ever escaped its grasp. N:518:Lich G:L:o I:110:30d10:20:60:60 W:34:2:0:1000 E:1:1:1:2:1:1 O:0:10:90:0 B:TOUCH:EXP_40 B:TOUCH:UN_POWER B:TOUCH:LOSE_DEX:2d8 B:TOUCH:LOSE_DEX:2d8 F:FORCE_SLEEP | FORCE_MAXHP | DROP_1D2 | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_4 | S:BLINK | TELE_TO | TELE_AWAY | BLIND | HOLD | SLOW | SCARE | S:CAUSE_3 | DRAIN_MANA | BRAIN_SMASH D:It is a skeletal form dressed in robes. It radiates vastly evil power. N:519:Gas spore G:e:g I:110:25d10:30:1:5 W:34:4:0:100 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:DISEASE:30d2 F:FORCE_SLEEP | F:STUPID | EMPTY_MIND | CAN_FLY | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:From a distance, this creature is often mistaken for the D:much more dangerous beholder. N:520:Master vampire G:V:g I:110:34d20:20:60:10 W:36:1:1600:750 E:1:1:1:2:1:1 O:20:40:30:0 B:HIT:HURT:2d6 B:HIT:HURT:2d6 B:BITE:EXP_40:3d6 B:BITE:EXP_40:3d6 F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_4D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | F:BASEANGBAND | NO_CUT S:1_IN_6 | S:TELE_TO | HOLD | CONF | SCARE | CAUSE_3 | MIND_BLAST | FORGET | S:DARKNESS | BO_NETH D:It is a humanoid form dressed in robes. Power emanates from its chilling D:frame. N:521:Oriental vampire G:V:s I:110:30d30:20:60:10 W:40:3:0:750 E:1:1:1:2:1:1 O:10:45:35:0 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:BITE:EXP_40:3d6 B:BITE:EXP_40:3d6 F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_4D2 | CAN_FLY | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | INVISIBLE | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | RES_TELE | F:BASEANGBAND | NO_CUT S:1_IN_6 | S:TELE_TO | HOLD | CONF | SCARE | CAUSE_3 | MIND_BLAST | FORGET | S:DARKNESS | BO_NETH D:The oriental vampire can transform into a mist at will. N:522:Greater mummy G:z:y I:110:34d10:30:68:255 W:36:3:0:800 E:1:1:1:2:1:1 O:50:50:0:0 B:CLAW:LOSE_CON:3d6 B:CLAW:DISEASE:3d6 B:GAZE:EXP_40:3d4 B:GAZE:TERRIFY:3d4 F:FORCE_SLEEP | FORCE_MAXHP | NO_FEAR | EVIL | UNDEAD |COLD_BLOOD | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | RES_TELE | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_3 | S:HEAL | HASTE | BLIND | SCARE | S_UNDEAD | ANIM_DEAD | S:BA_POIS | BA_NETH | BA_COLD | DRAIN_MANA | S:MIND_BLAST | CAUSE_3 | DARKNESS | FORGET D:Once a powerful ruler, now an even more powerful undead menace. N:523:Bloodletter of Khorne G:U:r I:120:30d8:20:40:30 W:34:1:0:450 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:EXP_20:13d1 B:HIT:EXP_20:13d1 B:HIT:EXP_20:13d1 F:FORCE_MAXHP | OPEN_DOOR | FRIENDS | DROP_60 | REGENERATE | F:ONLY_ITEM | DROP_CHOSEN | NO_FEAR | NONLIVING | F:EVIL | IM_POIS | IM_COLD | IM_FIRE | DEMON | ZANGBAND | HAS_LITE D:Slender, red-skinned demons twisting in nightmarish shapes. D:They are armed with hellblades, which will suck the life from D:your body. N:524:Giant grey scorpion G:S:s I:120:18d20:12:50:40 W:34:4:1200:275 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:1d6 B:STING:POISON:1d4 F:WEIRD_MIND | BASH_DOOR | WILD_TOO | DROP_SKELETON | F:ANIMAL F:MORTAL | BASEANGBAND D:It is a giant grey scorpion. It looks poisonous. N:525:Earth elemental G:E:u I:100:30d10:10:60:90 W:34:2:0:375 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:4d6 B:HIT:HURT:4d6 B:HIT:HURT:4d6 F:FORCE_SLEEP | F:EMPTY_MIND | COLD_BLOOD | F:KILL_ITEM | KILL_BODY | PASS_WALL | POWERFUL | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | HURT_ROCK | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_8 | S:BO_ACID D:It is a towering form composed of rock with fists of awesome power. N:526:Air elemental G:E:B I:120:30d5:12:50:50 W:34:2:0:390 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d10 B:HIT:CONFUSE:1d4 B:HIT:HURT:1d10 F:FORCE_SLEEP | RAND_25 | F:EMPTY_MIND | COLD_BLOOD | CAN_FLY | F:KILL_BODY | KILL_ITEM | BASH_DOOR | POWERFUL | F:IM_ACID | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_8 | S:BO_ELEC D:It is a towering tornado of winds. N:527:Shimmering mold G:m:b I:110:32d8:2:24:70 W:27:1:0:140 B:SPORE:ELEC:5d4 B:SPORE:ELEC:5d4 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | F:IM_ELEC | IM_POIS | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a strange growth on the dungeon floor, glowing and crackling with sparks. N:528:Gargoyle G:u:s I:110:18d12:10:50:15 W:34:2:3000:110 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:1d6 F:DROP_60 | ONLY_GOLD | EVIL | DEMON | FRIENDS | HURT_LITE | F:WILD_TOO | WILD_MOUNTAIN | WILD_WASTE | F:IM_POIS | IM_FIRE | IM_COLD | IM_ELEC | HURT_ROCK | NONLIVING | F:BASEANGBAND | NO_CUT S:1_IN_12 S:BR_ELEC | BR_FIRE D:A weird demon creature with a stone-like skin. N:529:Malicious leprechaun G:h:v I:120:4d5:8:13:8 W:35:4:1200:85 E:1:1:1:2:1:1 O:0:0:0:0 B:TOUCH:EAT_GOLD B:TOUCH:EAT_ITEM F:INVISIBLE | RAND_25 | TAKE_ITEM | COLD_BLOOD | F:HURT_LITE | EVIL | OPEN_DOOR | MALE | F:MORTAL | BASEANGBAND S:MULTIPLY | S:1_IN_6 | S:BLINK | TPORT | TELE_TO | CAUSE_1 D:This little creature has a fiendish gleam in its eyes. N:530:Eog golem G:g:u I:100:100d20:12:125:10 W:34:4:12000:1200 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:8d6 B:HIT:HURT:8d6 B:HIT:HURT:6d6 B:HIT:HURT:6d6 F:ONLY_GOLD | DROP_2D2 | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | REFLECTING | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT D:It is a massive deep brown statue, striding towards you with an D:all-too-familiar purpose. Your magic surprisingly feels much less D:powerful now. N:531:Little Boy G:{:D I:120:12d12:10:80:12 W:35:2:0:200 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:SHATTER:100d2 F:FORCE_SLEEP | FORCE_MAXHP | UNIQUE | REFLECTING | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS F:NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | RES_TELE | JOKEANGBAND | NO_CUT D:A shining machine of death and destruction. N:532:Dagashi G:p:u I:120:13d25:20:70:10 W:35:4:1600:500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:POISON:3d4 B:HIT:LOSE_STR:3d4 B:HIT:LOSE_STR:3d4 B:HIT:POISON:3d4 F:MALE | F:DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE D:A human warrior, moving with lightning speed. N:533:Headless ghost G:G:u I:120:20d25:20:30:10 W:35:3:0:550 E:0:0:0:0:0:0 O:35:25:25:0 B:TOUCH:TERRIFY B:TOUCH:EXP_40 B:CLAW:LOSE_INT:5d5 B:CLAW:LOSE_WIS:5d5 F:FORCE_SLEEP | RAND_25 | F:ONLY_ITEM | DROP_90 | DROP_2D2 | CAN_FLY | F:COLD_BLOOD | TAKE_ITEM | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:BLIND | DRAIN_MANA | SCARE | BO_COLD | FORGET D:A phantasmal apparition with no head. N:534:Dread G:G:o I:120:25d20:20:30:10 W:35:2:0:600 E:0:0:0:0:0:0 O:0:50:50:0 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:HIT:LOSE_STR:3d4 F:FORCE_SLEEP | RAND_25 | F:ONLY_ITEM | DROP_60 | DROP_2D2 | F:TAKE_ITEM | INVISIBLE | COLD_BLOOD | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | CAN_FLY | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:BLIND | HOLD | CONF | DRAIN_MANA | BO_NETH D:It is a form that screams its presence against the eye. Death incarnate, D:its hideous black body seems to struggle against reality as the universe D:itself struggles to banish it. N:535:Leng spider G:S:v I:120:16d20:12:50:40 W:35:4:600:250 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:1d6 B:STING:POISON:1d6 F:WEIRD_MIND | BASH_DOOR | FRIENDS | ELDRITCH_HORROR | DROP_CORPSE | F:ANIMAL | SPIDER | CTHANGBAND D:Bloated purple spiders with long, bristly legs. N:536:Gauth G:e:s I:110:15d20:20:50:20 W:36:2:1600:600 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:UN_BONUS:5d2 B:GAZE:UN_BONUS:5d2 B:GAZE:UN_POWER:5d2 B:GAZE:UN_POWER:5d2 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | DROP_CORPSE | F:BASH_DOOR | EVIL | BASEANGBAND | MORTAL S:1_IN_5 | S:CAUSE_2 | TELE_AWAY | BA_COLD | BO_ELEC | HOLD | DRAIN_MANA D:Another lesser relative of the beholder, this six-eyed creature feeds on magic. N:537:Smoke elemental G:E:R I:120:15d10:10:80:90 W:36:3:0:375 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:HURT:2d6 B:ENGULF:HURT:2d6 F:FORCE_SLEEP | F:EMPTY_MIND | F:KILL_ITEM | KILL_BODY | BASH_DOOR | POWERFUL | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | CAN_FLY | BASEANGBAND | NO_CUT S:1_IN_5 | S:DARKNESS | BO_FIRE D:It is a towering blackened form, crackling with heat. N:538:Olog G:T:y I:110:42d10:20:50:50 W:36:1:6000:450 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:1d12 B:HIT:HURT:1d12 B:BITE:HURT:2d3 B:BITE:HURT:2d3 F:FORCE_MAXHP | OPEN_DOOR | FRIENDS | DROP_60 | REGENERATE | F:SMART | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | TROLL | IM_POIS | BASEANGBAND D:It is a massive troll, more intelligent than most of its kind, with needle- D:sharp fangs. N:539:Halfling slinger G:h:U I:110:30d9:20:40:30 W:35:1:900:330 E:1:1:1:2:1:1 O:100:0:0:0 B:HIT:HURT:2d6 B:HIT:HURT:2d6 F:FORCE_MAXHP | OPEN_DOOR | FRIENDS | DROP_90 | F:SMART | EVIL | IM_POIS | IM_COLD | MALE | DROP_SKELETON | DROP_CORPSE F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 S:ARROW_4 D:A rebel halfling who has rejected the halfling tradition of archery. N:540:Gravity hound G:Z:W I:110:35d10:30:30:0 W:35:2:700:500 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:2d8 B:BITE:HURT:2d8 F:FORCE_SLEEP | FRIENDS | DROP_SKELETON | DROP_CORPSE | F:BASH_DOOR | F:ANIMAL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BR_GRAV D:Unfettered by the usual constraints of gravity, these unnatural creatures D:are walking on the walls and even the ceiling! The earth suddenly feels D:rather less solid as you see gravity warp all around these monsters. N:541:Acidic cytoplasm G:j:s I:120:40d10:12:18:1 W:35:5:3000:180 E:0:0:0:0:0:0 O:50:0:50:0 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 F:FORCE_MAXHP | TAKE_ITEM | COLD_BLOOD | F:DROP_1D2 | DROP_4D2 | CAN_SWIM | F:STUPID | EMPTY_MIND | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_FEAR | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:A disgusting animated blob of destruction. Flee its gruesome hunger! N:542:Inertia hound G:Z:W I:110:35d10:30:30:0 W:35:2:700:500 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:2d8 B:BITE:HURT:2d8 F:FORCE_SLEEP | FRIENDS | DROP_SKELETON | DROP_CORPSE | F:BASH_DOOR | F:ANIMAL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BR_INER D:Bizarrely, this hound seems to be hardly moving at all, yet it approaches D:you with deadly menace. It makes you tired just to look at it. N:543:Impact hound G:Z:u I:110:35d10:30:30:0 W:35:2:700:500 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:2d8 B:BITE:HURT:2d8 F:FORCE_SLEEP | F:FRIENDS | F:BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | NO_CONF | NO_SLEEP F:MORTAL | BASEANGBAND S:1_IN_5 | S:BR_WALL D:A deep brown shape is visible before you, its canine form striking you with D:an almost physical force. The dungeon floor buckles as if struck by a D:powerful blow as it stalks towards you. N:544:Shardstorm G:v:u I:120:32d10:40:12:0 W:37:1:0:800 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:HURT:6d6 F:FORCE_SLEEP | RAND_50 | NONLIVING | CAN_FLY | F:EMPTY_MIND | BASH_DOOR | POWERFUL | F:NO_FEAR | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_4 | S:BR_SHAR D:A howling blast of razor-sharp mountain fragments, kept intact by perilous D:magics. N:545:Ooze elemental G:E:g I:110:13d10:10:80:90 W:36:3:0:300 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 F:FORCE_SLEEP | F:EMPTY_MIND | COLD_BLOOD | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:KILL_ITEM | KILL_BODY | BASH_DOOR | POWERFUL | F:IM_ACID | IM_FIRE | CAN_SWIM | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_5 | S:BO_ACID | BA_ACID D:It is a towering mass of filth, an eyesore of ooze. N:546:Young black dragon G:d:s I:110:30d10:20:60:70 W:31:1:20000:700 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:2d8 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_SWAMP | F:DROP_3D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | DRAGON | IM_ACID | BASEANGBAND | ATTR_MULTI S:1_IN_10 | S:SCARE | S:BR_ACID D:It has a form out of legend. Its still-tender scales are a D:darkest black hue. Acid drips from its body. N:547:Mumak G:q:s I:110:90d10:20:55:100 W:35:3:150000:2100 E:0:1:0:2:1:0 O:0:0:0:0 B:BUTT:HURT:8d6 B:BUTT:HURT:8d6 B:CRUSH:HURT:8d4 F:BASH_DOOR | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND D:A massive elephantine form with eyes twisted by madness. N:548:Giant fire ant G:a:R I:110:20d10:14:49:40 W:35:1:700:350 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:FIRE:3d12 B:BITE:FIRE:3d12 F:FORCE_MAXHP | KILL_BODY | FRIENDS | DROP_SKELETON F:WEIRD_MIND | BASH_DOOR | SUSCEP_COLD | F:ANIMAL | IM_FIRE F:MORTAL | BASEANGBAND D:A giant ant covered in shaggy fur. Its powerful jaws glow with heat. N:549:Mature white dragon G:d:w I:110:40d10:20:70:70 W:34:1:110000:1200 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:4d8 F:FORCE_SLEEP | FORCE_MAXHP | DROP_4D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | CAN_FLY | WILD_TOO | WILD_WASTE | WILD_MOUNTAIN | F:EVIL | DRAGON | IM_COLD | NO_CONF | NO_SLEEP | SUSCEP_FIRE | BASEANGBAND | F:HAS_LITE | ATTR_MULTI S:1_IN_9 | S:SCARE | S:BR_COLD D:A large dragon, scales gleaming bright white. N:550:Xorn G:X:u I:110:16d10:20:80:10 W:36:2:30000:650 E:0:0:0:3:0:0 O:0:0:0:0 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:FORCE_MAXHP | F:EMPTY_MIND | COLD_BLOOD | F:KILL_ITEM | PASS_WALL | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_ROCK | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:A huge creature of the element Earth. Able to merge with its element, it D:has four huge arms protruding from its enormous torso. N:551:Rogrog the Black Troll G:T:D I:120:15d100:20:70:50 W:41:5:9000:5000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:6d7 B:HIT:HURT:6d7 B:BITE:HURT:4d10 B:SPIT:ACID:4d8 F:UNIQUE | MALE | F:FORCE_MAXHP | F:ESCORT | MOVE_BODY | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | DROP_CORPSE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | REGENERATE | F:EVIL | TROLL | IM_COLD | IM_POIS | BASEANGBAND D:A massive and cruel troll of great power, drool slides caustically down D:his muscular frame. Despite his bulk, he strikes with stunning speed. N:552:Mist giant G:#:B I:120:35d10:20:50:50 W:36:2:0:450 E:0:0:0:0:0:0 O:10:90:0:0 B:CRUSH:HURT:4d8 B:CRUSH:HURT:4d8 B:CRUSH:HURT:4d8 B:BITE:EXP_40:3d9 F:FORCE_MAXHP | OPEN_DOOR | DROP_60 | WILD_TOO | WILD_SWAMP | F:SMART | BASH_DOOR | F:EVIL | GIANT | IM_POIS | CAN_FLY | CTHANGBAND | NO_CUT D:"Two eyes, the colour of a thin, yellow wine, were set high in the D:thing's body; though it had no separate head. A mouthing, obscene slit, D:filled with fangs lay just beneath the eyes. It had no nose or ears... D:Four appendages sprang from its upper parts and its lower body D:slithered along the ground, unsupported by any limbs... incredibly D:disgusting to behold and its amorphous body gave off a stench of death D:and decay..." N:553:Phantom G:G:v I:120:20d25:30:30:20 W:36:3:0:400 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:EXP_80 B:TOUCH:EXP_40 B:CLAW:LOSE_INT:1d10 B:CLAW:LOSE_WIS:1d10 F:FORCE_SLEEP | F:ONLY_ITEM | DROP_1D2 | F:INVISIBLE | COLD_BLOOD | PASS_WALL | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_5 | S:FORGET | MIND_BLAST D:An unholy creature of darkness, the aura emanating from this evil being D:saps your very soul. N:554:Grey wraith G:W:s I:110:19d10:20:50:10 W:36:1:0:700 E:0:0:0:0:0:0 O:0:50:50:0 B:HIT:HURT:1d10 B:HIT:HURT:1d10 B:TOUCH:EXP_40 F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_60 | DROP_90 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | HURT_LITE | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_7 | S:HOLD | SCARE | CAUSE_3 | DARKNESS D:A tangible but ghostly form, made of grey fog. The air around it feels D:deathly cold. N:555:Revenant G:W:u I:110:2d111:20:50:10 W:36:1:0:725 E:1:1:1:2:1:1 O:0:0:100:0 B:GAZE:PARALYZE B:CLAW:LOSE_CON:1d10 B:CLAW:LOSE_CON:1d10 B:GAZE:EXP_40 F:FORCE_SLEEP | FORCE_MAXHP | REGENERATE | F:DROP_60 | DROP_90 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | HURT_LITE | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_7 | S:CONF | SCARE | CAUSE_3 | DARKNESS D:Back from the grave, to wreak vengeance upon the living. A skeletal figure D:wearing a black robe, with eyes that burn with undying hatred. N:556:Young multi-hued dragon G:d:v I:110:32d10:20:60:70 W:32:1:20000:900 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:3d8 F:ATTR_MULTI | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE F:DROP_1D2 | DROP_3D2 | CAN_FLY | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | F:IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_8 | S:SCARE | S:BR_ACID | BR_FIRE | BR_COLD | BR_ELEC | BR_POIS D:It has a form out of legend. Beautiful scales of shimmering D:and magical colours cover it. N:557:Raal's Tome of Destruction G:?:r I:120:50d15:20:150:15 W:36:4:0:1500 E:0:0:0:0:0:0 O:20:0:80:0 F:NEVER_MOVE | NEVER_BLOW | NONLIVING | F:FORCE_SLEEP | DROP_90 | DROP_GOOD | EVIL | COLD_BLOOD | EMPTY_MIND | F:FORCE_MAXHP | NO_CONF | NO_FEAR | NO_SLEEP | CHAR_MULTI | F:IM_ACID | IM_POIS | IM_COLD | IM_ELEC | SUSCEP_FIRE | RES_NETH | RES_TELE | F:ZANGBAND | HAS_LITE | NO_CUT S:1_IN_2 | S:BO_ACID | BR_FIRE | BO_MANA | BR_COLD | BR_POIS | S:BO_WATE | BA_POIS | BR_NETH D:A sentient arcane tome casting spells with malevolent intent. N:558:Colossus G:g:G I:110:30d100:15:150:10 W:36:4:35000:900 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:HIT:HURT:6d6 B:HIT:HURT:6d6 F:FORCE_MAXHP | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_ELEC | F:IM_POIS | NONLIVING | REFLECTING | F:NO_CONF | NO_SLEEP | NO_FEAR F:MORTAL | BASEANGBAND | NO_CUT S:1_IN_8 S:ARROW_4 D:An enormous construct resembling a titan made from stone. It strides D:purposefully towards you, swinging its slow fists with earth-shattering D:power. N:559:Young gold dragon G:d:y I:110:30d10:20:60:70 W:31:1:20000:700 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:2d8 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_3D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | F:EVIL | DRAGON | BASEANGBAND | NO_STUN | HAS_LITE | ATTR_MULTI S:1_IN_10 | S:SCARE | S:BR_SOUN D:It has a form out of legend. Its still-tender scales are a D:tarnished gold hue, and light is reflected from its form. N:560:Mature blue dragon G:d:b I:110:40d10:20:70:70 W:34:1:110000:1200 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:4d8 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_4D2 | DROP_CORPSE F:BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | WILD_WOOD | F:EVIL | DRAGON | IM_ELEC | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_9 | S:SCARE | S:BR_ELEC D:A large dragon, scales tinted deep blue. N:561:Mature green dragon G:d:g I:110:40d10:20:70:70 W:34:1:110000:1200 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:4d8 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_4D2 | DROP_CORPSE | F:BASH_DOOR | WILD_TOO | WILD_MOUNTAIN | WILD_WOOD | F:EVIL | DRAGON | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_9 | S:SCARE | S:BR_POIS D:A large dragon, scales tinted deep green. N:562:Mature bronze dragon G:d:U I:110:40d10:20:70:70 W:34:1:110000:1200 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d8 B:CLAW:HURT:2d8 B:BITE:HURT:4d8 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_MOUNTAIN | F:DROP_4D2 | CAN_FLY | F:BASH_DOOR | DROP_CORPSE | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_9 | S:CONF | SCARE | S:BR_CONF D:A large dragon with scales of rich bronze. N:563:Young red dragon G:d:r I:110:30d10:20:60:70 W:31:1:20000:700 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:2d8 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | SUSCEP_COLD | F:DROP_3D2 | WILD_TOO | WILD_MOUNTAIN | WILD_VOLCANO | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE F:EVIL | DRAGON | IM_FIRE | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_10 | S:SCARE | S:BR_FIRE D:It has a form out of legend. Its still-tender scales are a D:deepest red hue. Heat radiates from its form. N:564:Nightblade G:h:D I:120:19d13:20:60:10 W:36:2:1600:315 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:POISON:3d4 B:HIT:POISON:3d4 B:HIT:LOSE_CON:3d4 F:MALE | F:DROP_1D2 | FRIENDS | INVISIBLE | DROP_SKELETON | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR | HURT_LITE | F:EVIL | NO_CONF | NO_SLEEP | ZANGBAND D:A dark elven assassin, so stealthy that he is almost impossible to see. N:565:Trapper G:.:w I:120:60d10:30:75:10 W:36:3:1300:580 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:HIT:PARALYZE:15d1 B:HIT:PARALYZE:15d1 F:CHAR_CLEAR | ATTR_CLEAR | CHAR_MULTI | F:NEVER_MOVE | FORCE_MAXHP | F:INVISIBLE | EMPTY_MIND | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL | BASEANGBAND D:This creature traps unsuspecting victims D:and paralyzes them, to be slowly digested later. N:566:Bodak G:u:r I:110:35d10:10:68:90 W:36:2:0:750 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:FIRE:4d6 B:HIT:FIRE:4d6 B:GAZE:EXP_20 F:FORCE_SLEEP | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | AURA_FIRE | NONLIVING | F:EVIL | DEMON | IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:HAS_LITE S:1_IN_4 | S:BO_FIRE | BA_FIRE | S:S_DEMON D:It is a humanoid form composed of flames and hatred. N:567:Time bomb G:.:w I:130:12d12:30:40:0 W:36:5:0:50 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:TIME:30d2 F:CHAR_CLEAR | ATTR_CLEAR | CHAR_MULTI | F:NEVER_MOVE | FORCE_MAXHP | F:EMPTY_MIND | INVISIBLE | COLD_BLOOD | F:NO_CONF | NO_SLEEP | NO_FEAR | JOKEANGBAND | NO_CUT D:It was left here to be used against intruders. N:568:Mezzodaemon G:u:o I:110:40d10:10:68:90 W:36:2:0:750 E:1:1:1:0:1:1 O:0:0:0:0 B:CLAW:HURT:5d6 B:CLAW:HURT:5d6 F:FORCE_SLEEP | PASS_WALL | INVISIBLE | F:IM_POIS | IM_COLD | IM_ACID | IM_FIRE | F:NO_SLEEP | NO_CONF | NO_STUN | NONLIVING | F:EVIL | DEMON | BASEANGBAND S:1_IN_4 | S:BLINK | DARKNESS | S_DEMON D:An ugly demon with insect-like extremities and large bulbous eyes. N:569:Elder thing G:u:G I:110:35d10:10:70:50 W:36:3:0:800 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:4d6 B:CRUSH:HURT:4d6 B:CRUSH:HURT:4d6 B:TOUCH:LOSE_WIS F:FORCE_SLEEP | OPEN_DOOR | BASH_DOOR | ELDRITCH_HORROR | NONLIVING | F:EVIL | DEMON | IM_POIS | IM_ACID | NO_CONF | NO_SLEEP | RES_TELE | F:CAN_SWIM | CTHANGBAND S:1_IN_4 | S:SCARE | TELE_AWAY | BA_NUKE | CAUSE_4 | BA_POIS | S:CONF | S_DEMON | S_UNDEAD D:"...some ridged barrel-shaped objects with thin D:horizontal arms radiating spoke-like from a central ring and with D:vertical knobs or bulbs projecting from the head and base of the D:barrel. Each of these knobs was the hub of a system of five long, D:flat, triangularly tapering arms arranged around it like the arms D:of a starfish." N:570:Ice elemental G:E:w I:110:35d10:10:60:90 W:37:3:0:650 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:COLD:4d3 B:HIT:HURT:4d6 B:TOUCH:COLD:4d3 F:FORCE_SLEEP | F:EMPTY_MIND | COLD_BLOOD | AURA_COLD | F:KILL_ITEM | KILL_BODY | BASH_DOOR | POWERFUL | F:IM_COLD | IM_ELEC | CAN_SWIM | IM_POIS | IM_ACID | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_5 | S:BO_ICEE | BA_COLD D:It is a towering glacier of ice. N:571:Necromancer G:p:R I:110:28d10:20:50:10 W:36:2:1600:666 E:1:1:1:2:1:1 O:10:0:90:0 B:HIT:HURT:2d6 B:HIT:HURT:2d6 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_SKELETON F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HASTE | TPORT | TELE_TO | BLIND | HOLD | SCARE | CAUSE_3 | S:BO_NETH | MIND_BLAST | FORGET | S:S_UNDEAD | ANIM_DEAD D:A gaunt figure, clothed in black robes. N:572:The Greater hell magic mushroom were-quylthulg G:Q:s I:120:19d99:50:80:50 W:36:3:0:2500 E:0:0:0:0:0:0 O:0:50:50:0 B:GAZE:EXP_40:4d8 B:GAZE:EXP_40:4d8 B:CRUSH:ACID:8d8 B:CRUSH:ACID:8d8 F:FORCE_MAXHP | FORCE_SLEEP | UNIQUE | NO_STUN | NO_CONF | F:NO_SLEEP| EVIL | IM_ACID | IM_ELEC | IM_FIRE | IM_POIS | F:IM_COLD | RES_NETH | RES_WATE | RES_PLAS | RES_DISE | SMART | F:RES_NEXU | NONLIVING | RES_TELE | KILL_WALL | ELDRITCH_HORROR | F:BASH_DOOR | DEMON | COLD_BLOOD | ANIMAL | CAN_SWIM | F:DROP_GOOD | DROP_GREAT | ONLY_ITEM | DROP_2D2 | JOKEANGBAND | NO_CUT S:1_IN_3 | S:BLINK | SLOW | SCARE | DARKNESS | HEAL | ANIM_DEAD S:TPORT | TELE_AWAY | HASTE | S_MONSTER | DRAIN_MANA | S:S_UNDEAD | S_DEMON | S_DRAGON | S_KIN D:This unholy abomination will crush you too. Flee while you can! N:573:Lorgan, Chief of the Easterlings G:p:v I:120:18d100:25:100:10 W:36:2:0:1200 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:HIT:HURT:3d8 B:HIT:HURT:3d8 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:BASEANGBAND | HAS_LITE S:1_IN_4 | S:TELE_TO | S_MONSTERS D:A mighty warrior from the east, Lorgan hates everything that he cannot D:control. N:574:Chaos spawn G:e:s I:110:21d21:20:50:20 W:38:2:1900:700 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:HURT:10d10 B:GAZE:UN_BONUS:5d2 B:GAZE:EXP_40:5d2 B:GAZE:PARALYZE:5d2 F:FORCE_MAXHP | BASH_DOOR | EVIL | CAN_FLY | ZANGBAND D:It has two eyestalks and a large central eye. Its gaze can kill. N:575:Mummified troll G:z:w I:110:25d10:20:50:50 W:34:1:5000:420 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:4d6 B:HIT:HURT:4d6 F:FORCE_MAXHP | F:DROP_60 | F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | F:EVIL | TROLL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a massive figure clothed in wrappings. You are wary of its massive D:fists. N:576:Storm of Unmagic G:v:v I:130:32d20:50:40:0 W:53:3:0:4000 B:ENGULF:EXP_80:5d5 B:ENGULF:UN_POWER:5d5 B:ENGULF:UN_BONUS:5d5 B:HIT:LOSE_ALL:5d5 F:ATTR_MULTI | F:FORCE_SLEEP | FORCE_MAXHP | F:RAND_50 | RAND_25 | NONLIVING | CAN_FLY | F:EMPTY_MIND | BASH_DOOR | POWERFUL | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_6 | S:BR_TIME | BR_DISE D:Howling through the disintegrating dungeon, this awesome whirlpool of Unmagic D:rips the enchantments from everything it touches. N:577:Crypt thing G:L:G I:120:80d10:20:60:60 W:37:2:0:2500 E:1:1:1:2:1:1 O:50:50:0:0 B:TOUCH:EXP_40 B:TOUCH:UN_POWER B:TOUCH:LOSE_DEX:2d10 B:TOUCH:LOSE_DEX:2d10 F:FORCE_SLEEP | FORCE_MAXHP | DROP_1D2 | RES_TELE | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_3 | S:BLINK | TELE_TO | TELE_AWAY | TELE_LEVEL | S:CAUSE_3 | DRAIN_MANA | BRAIN_SMASH D:It is a skeletal form dressed in robes. It looks evil and devious... N:578:Chaos butterfly G:I:G I:120:60d10:40:60:10 W:37:2:0:1000 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:3d7 B:CLAW:HURT:3d7 B:CRUSH:HURT:10d5 F:FORCE_SLEEP | F:CAN_FLY | F:WEIRD_MIND | BASH_DOOR | ATTR_MULTI | ATTR_ANY | F:NO_CONF | NO_SLEEP | MORTAL | ZANGBAND S:1_IN_9 S:BR_CONF | BR_CHAO D:With fractal patterns on its wings, it is clearly one of those butterflies D:that mathematicians keep talking about - the ones that flap their wings on the D:other side of the world to cause storms here. Now's your chance to stop it... N:579:Time elemental G:E:G I:120:35d10:90:70:10 W:39:2:0:1000 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:TIME:3d4 B:TOUCH:TIME:3d4 F:PASS_WALL | IM_POIS | IM_FIRE | IM_ELEC | IM_FIRE | IM_ACID | CAN_FLY | F:NO_CONF | NO_SLEEP | EMPTY_MIND | KILL_ITEM | RAND_50 | F:ZANGBAND | NO_CUT S:1_IN_7 S:SLOW | BR_TIME | D:You have not seen it yet. N:580:Flying polyp G:~:R I:120:35d10:90:70:10 W:37:2:0:1000 E:3:0:3:6:1:0 O:0:0:0:0 B:CRUSH:PARALYZE:8d4 B:CRUSH:PARALYZE:8d4 B:CRUSH:PARALYZE:8d4 F:PASS_WALL | INVISIBLE | FORCE_MAXHP | RES_DISE | F:IM_POIS | IM_COLD | IM_ACID | ELDRITCH_HORROR | F:NO_CONF | NO_SLEEP | EVIL | CAN_FLY | CTHANGBAND |NO_CUT S:1_IN_7 S:BR_WALL | D:"They were only partly material and had the power of aerial motion, D:despite the absence of wings... Suggestions of monstrous plasticity D:and of temporary lapses of visibility..." N:581:The Queen Ant G:a:v I:120:15d100:30:100:10 W:37:2:2000:1000 E:0:1:0:2:1:0 O:50:50:0:0 B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d8 B:BITE:HURT:2d8 F:UNIQUE | FEMALE | GOOD | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | ESCORTS | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:WEIRD_MIND | OPEN_DOOR | BASH_DOOR | F:ANIMAL | F:MORTAL | BASEANGBAND S:1_IN_2 | S:S_KIN D:She's upset because you hurt her children. N:582:Will o' the wisp G:E:W I:130:20d10:30:150:0 W:38:4:0:500 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:1d9 B:HIT:HURT:1d9 B:HIT:HALLU:1d9 B:HIT:HALLU:1d9 F:FORCE_SLEEP | FORCE_MAXHP | RAND_50 | F:SMART | EMPTY_MIND | INVISIBLE | F:PASS_WALL | POWERFUL | CAN_FLY | WILD_TOO | WILD_SWAMP | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_2 | S:BLINK | TPORT | CONF | CAUSE_2 D:A strange ball of glowing light. It disappears and reappears and seems to D:draw you to it. You seem somehow compelled to stand still and watch its D:strange dancing motion. N:583:Shan G:I:B I:120:20d8:20:120:20 W:37:4:0:250 E:0:0:0:0:0:0 O:0:0:0:0 F:IM_POIS | IM_COLD | COLD_BLOOD | ANIMAL | EVIL | F:NO_SLEEP | NO_CONF | CAN_FLY | NEVER_BLOW | CTHANGBAND | S:1_IN_2 S:CONF | HOLD | DRAIN_MANA | FORGET | MIND_BLAST | SHRIEK D:"Those huge lidless eyes which stared with hate at me, the jointed D:tendrils which seemed to twist from the head in cosmic rhythms, D:the ten legs, covered with black shining tentacles and folded into D:the pallid underbelly, and the semi-circular ridged wings covered D:with triangular scales -- all this cannot convey the soul-ripping D:horror of the shape which darted at me. I saw the three mouths D:of the thing move moistly, and then it was upon me." N:584:Magma elemental G:E:o I:110:35d10:10:70:90 W:37:3:0:950 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:FIRE:3d7 B:HIT:HURT:4d6 B:HIT:FIRE:3d7 F:FORCE_SLEEP | F:EMPTY_MIND | AURA_FIRE | WILD_TOO | WILD_VOLCANO | F:KILL_ITEM | KILL_BODY | PASS_WALL | POWERFUL | F:IM_FIRE | IM_ELEC | IM_ACID | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_7 | S:BO_PLAS | BA_FIRE D:It is a towering glowing form of molten rock. N:585:Black pudding G:j:D I:110:40d10:12:18:1 W:37:5:300:50 E:0:0:0:0:0:0 O:90:0:0:0 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 B:TOUCH:ACID:1d10 F:FORCE_MAXHP | F:FRIENDS | F:DROP_60 | DROP_90 | DROP_1D2 | F:STUPID | EMPTY_MIND | COLD_BLOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | CAN_SWIM | BASEANGBAND | NO_CUT D:A lump of rotting black flesh that slurrrrrrrps across the dungeon floor. N:586:Killer iridescent beetle G:K:v I:110:25d15:16:60:30 W:37:2:600:850 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:ELEC:1d12 B:CLAW:ELEC:1d12 B:GAZE:PARALYZE F:ATTR_MULTI | FORCE_MAXHP | F:WEIRD_MIND | BASH_DOOR | AURA_ELEC | DROP_CORPSE | F:ANIMAL | IM_ELEC | CAN_FLY | F:MORTAL | BASEANGBAND | HAS_LITE D:It is a giant beetle, whose carapace shimmers with vibrant energies. N:587:Nexus vortex G:v:v I:120:32d10:100:40:0 W:37:1:0:800 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:HURT:5d5 F:FORCE_SLEEP | F:RAND_50 | RAND_25 | RES_NEXU | CAN_FLY | F:EMPTY_MIND | BASH_DOOR | POWERFUL | RES_TELE | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_6 | S:BR_NEXU D:A maelstrom of potent magical energy. N:588:Plasma vortex G:v:R I:120:32d10:100:40:0 W:37:1:0:800 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:FIRE:4d8 B:ENGULF:ELEC:4d8 F:FORCE_SLEEP | SUSCEP_COLD | F:RAND_50 | RAND_25 | RES_PLAS | AURA_FIRE | AURA_ELEC | F:EMPTY_MIND | BASH_DOOR | POWERFUL | F:IM_FIRE | CAN_FLY | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_6 | S:BR_PLAS D:A whirlpool of intense flame, charring the stones at your feet. N:589:Mature red dragon G:d:r I:110:50d10:20:80:70 W:36:1:110000:1500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d10 B:CLAW:HURT:2d10 B:BITE:HURT:4d10 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_MOUNTAIN | WILD_VOLCANO | F:DROP_1D2 | DROP_4D2 | CAN_FLY | DROP_CORPSE | SUSCEP_COLD | F:BASH_DOOR | F:EVIL | DRAGON | IM_FIRE | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_9 | S:CONF | SCARE | S:BR_FIRE D:A large dragon, scales tinted deep red. N:590:Mature gold dragon G:d:y I:110:50d10:20:80:70 W:36:1:110000:1500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d10 B:CLAW:HURT:2d10 B:BITE:HURT:4d10 F:FORCE_SLEEP | FORCE_MAXHP | WILD_TOO | WILD_MOUNTAIN | F:DROP_1D2 | DROP_4D2 | CAN_FLY | DROP_CORPSE | F:BASH_DOOR | F:EVIL | DRAGON | NO_STUN | NO_SLEEP | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_9 | S:CONF | SCARE | S:BR_SOUN D:A large dragon with scales of gleaming gold. N:591:Crystal drake G:d:u I:110:45d10:20:70:70 W:33:3:18000:1350 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d4 B:CLAW:HURT:2d4 B:BITE:HURT:3d6 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:ONLY_ITEM | DROP_3D2 | REFLECTING | F:OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | DRAGON | IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | NO_CUT F:ATTR_MULTI S:1_IN_6 | S:SLOW | CONF | SCARE | S:BR_SHAR D:A dragon of strange crystalline form. Light shines through it, dazzling D:your eyes with spectrums of colour. N:592:Mature black dragon G:d:s I:110:50d10:20:80:70 W:36:1:110000:1500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d10 B:CLAW:HURT:2d10 B:BITE:HURT:4d10 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | DROP_CORPSE | F:DROP_1D2 | DROP_4D2 | WILD_TOO | WILD_SWAMP | WILD_MOUNTAIN | F:BASH_DOOR | F:EVIL | DRAGON | IM_ACID | NO_CONF | NO_SLEEP | BASEANGBAND | ATTR_MULTI S:1_IN_9 | S:SCARE | S:BR_ACID D:A large dragon, with scales of deepest black. N:593:Mature multi-hued dragon G:d:v I:110:60d10:20:80:70 W:38:1:110000:1800 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d12 B:CLAW:HURT:2d12 B:BITE:HURT:4d12 F:ATTR_MULTI | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_2D2 | DROP_4D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_ACID | IM_FIRE | IM_COLD | F:IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_7 | S:BLIND | CONF | SCARE | S:BR_ACID | BR_FIRE | BR_COLD | BR_ELEC | BR_POIS D:A large dragon, scales shimmering many colours. N:594:Sky whale G:~:G I:110:80d10:20:75:30 W:38:6:4000:1750 E:0:0:0:0:1:0 O:50:50:0:0 B:CRUSH:HURT:20d2 B:CRUSH:HURT:20d2 B:CRUSH:HURT:20d2 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_60 | DROP_90 | DROP_2D2 | DROP_CORPSE | F:BASH_DOOR | SMART | GOOD | F:NO_CONF | NO_SLEEP | RES_NEXU | RES_TELE | RES_DISE F:MORTAL | ZANGBAND S:1_IN_9 | S:BRAIN_SMASH | CONF | SCARE | FORGET | TELE_TO | TELE_AWAY | SHRIEK D:A vastly intelligent whale-like being from the stars. N:595:Draebor, the Imp G:u:v I:120:19d99:12:80:50 W:38:3:3000:3250 E:0:1:1:0:1:0 O:30:20:50:0 B:CLAW:POISON:8d4 B:CLAW:POISON:8d4 B:BITE:HURT:8d8 B:INSULT:* F:ESCORT F:DROP_60 | DROP_90 | DROP_1D2 | DROP_GOOD | ONLY_ITEM | DROP_CORPSE | F:CAN_SWIM | BASH_DOOR | RES_TELE | CAN_SPEAK | F:EVIL | DEMON | IM_FIRE | IM_COLD | IM_POIS | RES_WATE | F:UNIQUE | MALE | FORCE_SLEEP | FORCE_MAXHP | POWERFUL | F:NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_5 | S:S_KIN | BLINK | TPORT | TELE_TO | TELE_AWAY | TELE_LEVEL | BLIND | S:CONF | SCARE D:An intensely irritating git of a monster. N:596:Mother Hydra G:u:v I:120:25d99:12:80:50 W:40:3:30000:3250 E:0:1:0:2:2:0 O:0:50:50:0 B:CLAW:POISON:8d4 B:CLAW:POISON:8d4 B:BITE:HURT:8d8 F:ESCORT | F:DROP_60 | DROP_90 | DROP_1D2 | DROP_GOOD | ONLY_ITEM | DROP_CORPSE | F:CAN_SWIM | BASH_DOOR | ELDRITCH_HORROR | RES_TELE | CAN_SPEAK | F:EVIL | DEMON | IM_FIRE | IM_COLD | IM_POIS | RES_WATE | F:UNIQUE | FEMALE | FORCE_SLEEP | FORCE_MAXHP | POWERFUL | F:NO_CONF | F:MORTAL | CTHANGBAND S:1_IN_7 | S:S_HYDRA | S_DEMON | DARKNESS | BA_WATE | BO_ACID | BA_ACID D:The queen of the deep ones. "Vast, Polyphemus-like, and loathsome, it D:darted like a stupendous monster of nightmares..." N:597:Death knight G:p:D I:120:60d10:20:100:10 W:38:1:2700:1111 E:1:1:1:2:1:1 O:0:90:0:10 B:HIT:EXP_20:6d6 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:FORCE_SLEEP | FORCE_MAXHP | SMART | RES_NETH | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_COLD | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_5 | S:BLIND | SCARE | CAUSE_3 | BO_NETH | S:S_MONSTERS D:It is a humanoid figure dressed in armour of an ancient form. From beneath D:its helmet, eyes glow a baleful red and seem to pierce you like lances of D:fire. N:598:Castamir the Usurper G:p:R I:120:88d10:20:90:40 W:38:5:0:1600 E:1:1:1:2:1:1 O:10:60:10:10 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:SMART | OPEN_DOOR | TAKE_ITEM | BASH_DOOR | F:EVIL | BASEANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | TRAPS | BO_FIRE | BO_COLD | BO_ELEC | BO_ICEE D:A Black Numenorean who usurped the throne of Gondor, he is treacherous and D:evil. N:599:Time vortex G:v:B I:130:32d10:100:40:0 W:38:4:0:800 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:TIME:5d5 F:FORCE_SLEEP | F:RAND_50 | RAND_25 | F:EMPTY_MIND | BASH_DOOR | POWERFUL | CAN_FLY | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_6 | S:BR_TIME D:You haven't seen it yet. N:600:Shimmering vortex G:v:o I:140:32d10:100:40:0 W:38:4:0:800 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:BLIND:4d4 B:ENGULF:BLIND:4d4 F:FORCE_SLEEP | F:RAND_50 | RAND_25 | CAN_FLY | F:EMPTY_MIND | BASH_DOOR | POWERFUL | RES_TELE | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_4 | S:BR_LITE | SHRIEK D:A strange pillar of shining light that hurts your eyes. Its shape changes D:constantly as it cuts through the air towards you. It is like a beacon, D:waking monsters from their slumber. N:601:Ancient blue dragon G:D:b I:120:72d10:20:90:80 W:40:1:170000:2000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d8 B:CLAW:HURT:4d8 B:BITE:ELEC:7d8 F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_3D2 | DROP_4D2 | DROP_CORPSE | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | CAN_FLY | F:EVIL | DRAGON | IM_ELEC | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | SCARE | S:BR_ELEC D:A huge draconic form. Lightning crackles along its length. N:602:Ancient bronze dragon G:D:U I:120:72d10:20:90:80 W:40:1:170000:2000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d8 B:CLAW:HURT:4d8 B:BITE:HURT:7d8 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:DROP_3D2 | DROP_4D2 | CAN_FLY | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | SCARE | S:BR_CONF D:A huge draconic form enveloped in a cascade of colour. N:603:Beholder G:e:U I:120:16d100:30:80:10 W:40:3:1600:6000 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:EXP_20:2d6 B:GAZE:UN_POWER:2d6 B:GAZE:INSANITY:2d6 B:BITE:HURT:6d6 F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | CAN_FLY | F:BASH_DOOR | DROP_CORPSE | F:EVIL | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND S:1_IN_2 | S:BLIND | SLOW | CONF | SCARE | DRAIN_MANA | MIND_BLAST | S:FORGET | DARKNESS | BO_ACID | BO_FIRE | BO_COLD | BO_ELEC D:A vile creature with one huge central eye, twelve smaller eyes on stalks, and D:a huge mouth filled with sharp teeth. N:604:Emperor wight G:W:r I:120:38d10:20:40:10 W:38:2:0:1600 E:0:0:0:0:0:0 O:0:40:60:0 B:HIT:HURT:1d12 B:HIT:HURT:1d12 B:TOUCH:EXP_80 B:TOUCH:EXP_80 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_90 | DROP_4D2 | CAN_FLY | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_6 | S:HOLD | SCARE | CAUSE_3 | BO_NETH D:Your life force is torn from your body as this powerful unearthly being D:approaches. N:605:Seraph G:A:r I:120:150d10:30:68:255 W:45:4:3100:5000 E:1:1:1:2:1:1 O:0:30:70:0 B:HIT:HURT:4d6 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:4d6 F:FORCE_SLEEP | FORCE_MAXHP | SMART | NO_FEAR | GOOD | CAN_FLY | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | REFLECTING | RES_TELE F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_11 | S:HEAL | HASTE | TELE_AWAY | CONF | BO_MANA | BO_PLAS | S:S_MONSTERS | S_ANGEL D:It is an angel, fast and strong. You are stunned by its extreme holiness D:and try to resist all desires to obey it. N:606:Vargo, Tyrant of Fire G:E:r I:120:24d100:12:50:50 W:43:3:0:4000 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:FIRE:6d6 B:HIT:FIRE:6d6 B:HIT:FIRE:6d6 B:HIT:FIRE:6d6 F:UNIQUE | SUSCEP_COLD | F:FORCE_SLEEP | FORCE_MAXHP | RAND_25 | CAN_SPEAK | F:EMPTY_MIND | CAN_SPEAK | MALE | AURA_FIRE | F:KILL_ITEM | KILL_BODY | BASH_DOOR | POWERFUL | F:IM_FIRE | IM_ACID | IM_POIS | IM_ELEC | NO_STUN | F:NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_4 | S:BO_PLAS | BA_FIRE D:A towering fire elemental, Vargo burns everything beyond recognition. N:607:Black wraith G:W:D I:120:50d10:20:55:10 W:38:2:0:1700 E:0:0:0:0:0:0 O:50:0:50:0 B:HIT:HURT:1d12 B:HIT:HURT:1d12 B:TOUCH:EXP_40 B:TOUCH:EXP_40 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP F:BASEANGBAND | NO_CUT S:1_IN_7 | S:BLIND | HOLD | SCARE | CAUSE_3 | BO_NETH D:A figure that seems made of void, its strangely human shape is cloaked in D:shadow. It reaches out at you. N:608:Nightgaunt G:U:D I:110:24d10:20:50:80 W:38:2:0:1000 E:0:0:0:0:0:0 O:50:0:50:0 B:STING:LOSE_STR:1d5 B:TOUCH:PARALYZE:3d4 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_60 | ELDRITCH_HORROR | F:OPEN_DOOR | BASH_DOOR | POWERFUL | CAN_FLY | F:EVIL | DEMON | F:IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | ZANGBAND S:1_IN_7 | S:BLIND | CONF | BO_FIRE D:It is a black, horned humanoid with wings. N:609:Baron of hell G:U:U I:110:150d12:10:130:40 W:38:3:0:1000 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:11d2 B:CLAW:HURT:11d2 B:CLAW:HURT:22d1 F:IM_POIS | OPEN_DOOR | BASH_DOOR | MALE | RES_PLAS | IM_FIRE | NONLIVING | F:IM_FIRE | NO_CONF | NO_SLEEP | EVIL | DEMON | FORCE_MAXHP | RES_TELE | F:ZANGBAND | HAS_LITE S:1_IN_2 | S:BO_PLAS D:A minor demon lord with a goat's head, tough to kill. N:610:Scylla G:M:B I:125:100d20:20:100:70 W:42:1:15000:13000 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:POISON:10d3 B:BITE:POISON:10d3 B:BITE:POISON:10d3 B:BITE:POISON:10d3 F:FORCE_SLEEP | UNIQUE | AQUATIC | FORCE_MAXHP | COLD_BLOOD | F:ONLY_GOLD | DROP_2D2 | DROP_4D2 | DROP_CORPSE | F:BASH_DOOR | MOVE_BODY | EVIL | ZANGBAND | RES_WATE | F:ANIMAL | IM_POIS | IM_FIRE S:1_IN_5 | S:BR_POIS | BR_FIRE | SCARE | CONF | S_HYDRA D:A many-headed sea-monster, this foul creature preys on all those who D:escape the clutches of Charybdis. N:611:Monastic lich G:L:u I:120:12d100:30:80:30 W:39:2:2000:5000 E:1:1:1:2:1:1 O:0:50:50:0 B:KICK:HURT:24d1 B:KICK:HURT:24d1 B:CLAW:EXP_80:4d2 B:CLAW:LOSE_DEX:4d2 F:FORCE_SLEEP | FORCE_MAXHP | SMART | RES_TELE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | SMART | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_3 | S:BLINK | TELE_TO | BLIND | HOLD | CONF | SCARE | CAUSE_3 | CAUSE_4 | S:DRAIN_MANA | BRAIN_SMASH | ANIM_DEAD D:A skeletal form wrapped in priestly robes. Before its un-death, it D:was a monk in an evil order. N:612:Nether wraith G:W:G I:120:48d10:20:55:10 W:39:2:0:1700 E:0:0:0:0:0:0 O:50:0:50:0 B:HIT:HURT:1d12 B:HIT:HURT:1d12 B:TOUCH:EXP_80 B:TOUCH:EXP_80 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_90 | DROP_4D2 | F:INVISIBLE | COLD_BLOOD | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_6 | S:BLIND | SCARE | CAUSE_3 | MIND_BLAST | DARKNESS | BO_NETH D:A form that hurts the eye, death permeates the air around it. As it nears D:you, a coldness saps your soul. N:613:Hellhound G:C:r I:120:48d10:25:80:30 W:35:3:600:600 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:FIRE:3d12 B:BITE:FIRE:3d12 B:BITE:FIRE:3d12 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE F:RAND_25 | FRIENDS | AURA_FIRE | SUSCEP_COLD | F:BASH_DOOR | MOVE_BODY | F:ANIMAL | EVIL | IM_FIRE | BASEANGBAND | HAS_LITE | S:1_IN_5 | BR_FIRE D:It is a giant dog that glows with heat. Flames pour from its nostrils. N:614:7-headed hydra G:M:G I:120:100d10:20:90:20 W:39:2:7000:2000 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:POISON:3d9 B:BITE:POISON:3d9 B:BITE:POISON:3d9 B:SPIT:BLIND:1d2 F:FORCE_SLEEP | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:ONLY_GOLD | DROP_2D2 | DROP_4D2 | CAN_SWIM | DROP_CORPSE F:BASH_DOOR | MOVE_BODY | F:ANIMAL | IM_POIS | MORTAL | BASEANGBAND S:1_IN_5 | S:SCARE | BA_POIS | S:BR_POIS D:A strange reptilian creature with seven heads dripping venom. N:615:Waldern, King of Water G:E:b I:130:25d100:12:80:50 W:43:3:0:4250 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:8d5 B:HIT:HURT:8d5 B:HIT:HURT:8d5 B:HIT:HURT:8d5 F:UNIQUE | F:FORCE_SLEEP | FORCE_MAXHP | F:EMPTY_MIND | COLD_BLOOD | F:KILL_ITEM | KILL_BODY | BASH_DOOR | POWERFUL | F:IM_ACID | IM_FIRE | IM_POIS | IM_COLD | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_3 | S:BO_ICEE | BO_WATE | BA_COLD | BA_WATE D:A towering water elemental, Waldern is master of all things liquid. D:Wave after wave drowns your frail body. N:616:Kavlax the Many-Headed G:d:v I:120:13d100:20:85:30 W:39:3:90000:3000 E:0:1:0:6:2:0 O:50:50:0:0 B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 F:UNIQUE | MALE | ATTR_MULTI | CAN_SPEAK | ATTR_ANY | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | RES_NEXU | F:OPEN_DOOR | BASH_DOOR | POWERFUL | CAN_FLY | F:EVIL | DRAGON | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | F:BASEANGBAND | HAS_LITE | S:1_IN_4 | S:BR_ACID | BR_FIRE | BR_COLD | BR_ELEC | BR_SOUN | BR_CONF | S:BR_SHAR | BR_GRAV | BR_NEXU D:A large dragon with a selection of heads, all shouting and arguing as they D:look for prey, but each with its own deadly breath weapon. N:617:Ancient white dragon G:D:w I:120:72d10:20:90:80 W:40:1:170000:2000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d8 B:CLAW:HURT:4d8 B:BITE:COLD:7d8 F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_3D2 | DROP_4D2 | DROP_CORPSE | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | CAN_FLY | F:EVIL | DRAGON | IM_COLD | NO_CONF | NO_SLEEP | SUSCEP_FIRE | BASEANGBAND F:HAS_LITE | ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | SCARE | S:BR_COLD D:A huge draconic form. Frost covers it from head to tail. N:618:Ancient green dragon G:D:g I:120:72d10:20:90:80 W:40:1:170000:2000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d8 B:CLAW:HURT:4d8 B:BITE:POISON:7d8 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:DROP_3D2 | DROP_4D2 | CAN_FLY | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | SCARE | S:BR_POIS D:A huge draconic form enveloped in clouds of poisonous vapour. N:619:Chthonian G:w:D I:120:100d10:20:90:20 W:39:2:12000:2300 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:SHATTER:3d11 B:CRUSH:SHATTER:3d11 B:TOUCH:LOSE_CON:1d2 B:TOUCH:LOSE_CON:1d2 F:IM_FIRE | RES_PLAS | IM_COLD | IM_POIS | ELDRITCH_HORROR | RES_TELE | F:KILL_WALL | ONLY_GOLD | DROP_4D2 | DROP_2D2 | CAN_SWIM | DROP_CORPSE | F:EVIL | FORCE_MAXHP | CTHANGBAND S:1_IN_5 | S:SCARE | CONF | HOLD | S_DEMON | S:MIND_BLAST | HEAL | HASTE | FORGET | BRAIN_SMASH D:"Flowing tentacles and a pulpy gray-black elongated sack of a body... D:no distinguishing features at all other than the reaching, groping D:tentacles. Or was there -- yes! -- a lump in the upper body of D:the thing... a container of sorts for the brain, ganglia, or D:whichever diseased organ governed this horror's loathsome life!" N:620:Eldrak G:T:r I:110:75d10:20:80:50 W:38:3:7000:1500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:BITE:HURT:3d4 B:BITE:HURT:3d4 F:FORCE_MAXHP | MOVE_BODY | F:ONLY_ITEM | DROP_2D2 | REGENERATE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | WILD_SHORE | WILD_WOOD | F:EVIL | TROLL | IM_POIS | NO_CONF | NO_SLEEP | DROP_CORPSE | BASEANGBAND D:A massive troll of huge strength. Eldraks are extremely stupid and extremely D:violent. N:621:Ettin G:T:b I:110:15d100:20:100:30 W:39:3:8000:2000 E:1:1:1:2:2:1 O:0:100:0:0 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:BITE:HURT:3d8 B:BITE:HURT:3d8 F:FORCE_MAXHP | REGENERATE | MOVE_BODY | F:ONLY_ITEM | DROP_1D2 | WILD_TOO | WILD_MOUNTAIN | WILD_WOOD | WILD_SWAMP | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:EVIL | TROLL | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND D:A massive two-headed troll, larger and stronger than many men together. D:Fortunately, ettins are solitary creatures. They are also living proof that D:two heads are not necessarily more intelligent than one... N:622:Night mare G:q:G I:120:15d100:30:85:0 W:39:3:6000:2900 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:EXP_80:2d6 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:HIT:CONFUSE:6d6 F:FORCE_MAXHP | F:ONLY_GOLD | DROP_2D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:HAS_LITE | NO_CUT D:A fearsome skeletal horse with glowing eyes that watch you with little D:more than a hatred of all that lives. Its flying hooves do not touch the D:ground. N:623:Vampire lord G:V:b I:120:20d100:20:70:10 W:42:1:1700:1800 E:1:1:1:2:1:1 O:0:70:30:0 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:BITE:EXP_80:4d6 B:BITE:EXP_80:4d6 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_60 | DROP_4D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | RES_TELE | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_7 | S:BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | DRAIN_MANA | S:BRAIN_SMASH | DARKNESS | BO_NETH D:A foul wind chills your bones as this ghastly figure approaches. N:624:Ancient black dragon G:D:s I:120:10d100:20:90:80 W:41:1:170000:2500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d9 B:CLAW:HURT:4d9 B:BITE:ACID:7d9 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_3D2 | DROP_4D2 | DROP_CORPSE | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | IM_ACID | NO_CONF | NO_SLEEP | BASEANGBAND | ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | SCARE | S:BR_ACID D:A huge draconic form. Pools of acid melt the floor around it. N:625:Weird fume G:#:v I:120:35d10:100:40:0 W:40:2:0:800 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:CONFUSE:8d4 B:ENGULF:CONFUSE:8d4 F:FORCE_SLEEP | F:RAND_50 | RAND_25 | RES_NEXU | AURA_ELEC | IM_FIRE | IM_ELEC | F:EMPTY_MIND | BASH_DOOR | POWERFUL | F:CAN_FLY | ATTR_MULTI | ATTR_ANY | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | ZANGBAND | NO_CUT S:1_IN_6 | S:BR_CHAO | BR_NEXU | BR_NUKE D:A swirling spiral of mist, constantly changing its appearance. N:626:Spawn of Ubbo-Sathla G:j:v I:120:30d10:100:40:0 W:40:5:0:300 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:ACID:8d4 B:CRUSH:ACID:8d4 F:FORCE_SLEEP | ATTR_MULTI | ATTR_ANY | EVIL | F:RAND_25 | RES_NEXU | AURA_ELEC | IM_FIRE | IM_ELEC | F:EMPTY_MIND | BASH_DOOR | POWERFUL | KILL_BODY | F:CAN_SWIM | NO_CONF | NO_SLEEP | CTHANGBAND | NO_CUT S:MULTIPLY D:Weird, jelly like creatures. No two look the same. N:627:Fat Man G:{:D I:120:14d14:10:80:12 W:40:2:0:200 E:0:0:0:0:0:0 O:0:0:0:0 B:EXPLODE:SHATTER:200d2 F:FORCE_SLEEP | FORCE_MAXHP | UNIQUE | REFLECTING | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS F:NO_FEAR | NO_CONF | NO_SLEEP | NONLIVING | RES_TELE | JOKEANGBAND | NO_CUT | NO_STUN D:A shining machine of death and destruction. N:628:Malekith the Accursed G:h:v I:125:25d100:20:70:10 W:44:2:3500:7500 E:1:1:1:2:1:1 O:50:0:50:0 B:HIT:HURT:12d9 B:HIT:HURT:12d9 F:MALE | REGENERATE | UNIQUE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE F:ONLY_ITEM | DROP_90 | DROP_4D2 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | HURT_LITE | ZANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | TELE_TO | BLIND | CONF | CAUSE_3 | DARKNESS | FORGET | HOLD | S:S_MONSTER | S_MONSTERS | S_DEMON | TPORT | BA_NETH | MIND_BLAST | S:S_KIN D:One of the oldest and most powerful dark elves, Malekith is a master D:sorcerer devoted to evil. The left side of his face is pale, and the other D:is dark. His hair is long and white. N:629:Shadowfax, steed of Gandalf G:q:v I:130:30d100:20:100:50 W:40:3:2600:2000 E:0:1:0:2:1:0 O:0:0:0:0 B:KICK:HURT:5d5 B:KICK:HURT:5d5 B:BITE:HURT:6d6 F:FORCE_MAXHP | UNIQUE | ANIMAL | GOOD | F:REGENERATE | BASH_DOOR | IM_FIRE | IM_COLD | IM_ELEC | F:IM_POIS | NO_FEAR | DROP_CORPSE | F:MORTAL | BASEANGBAND D:Shadowfax is the chief of the "Mearas", the greatest of all horses that are D:bred in the fields of Rohan. Although the Mearas should technically be only D:ridden by the royal family of Rohan, only Gandalf the Wizard has ever D:succeeded in taming Shadowfax: and even then, Shadowfax will not be subjected D:to a bridle or saddle, but must be ridden bareback. N:630:Spirit troll G:G:G I:110:10d100:20:90:5 W:40:3:0:900 E:0:0:0:0:0:0 O:10:90:0:0 B:HIT:HURT:3d6 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:FORCE_MAXHP | F:DROP_90 | F:INVISIBLE | PASS_WALL | CAN_FLY | F:EVIL | TROLL | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:A weird ghostly troll-like being from the ethereal plane. N:631:War troll G:T:b I:120:50d10:20:100:50 W:40:3:6500:800 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:BITE:HURT:3d5 B:BITE:HURT:3d5 F:FORCE_MAXHP | SUSCEP_FIRE | REGENERATE | F:DROP_90 | REGENERATE | FRIENDS | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:EVIL | TROLL | IM_POIS | NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND D:A massive troll, equipped with a scimitar and heavy armour. N:632:Disenchanter worm mass G:w:v I:100:10d8:7:5:10 W:40:3:50:30 E:0:0:0:0:0:0 O:0:0:0:0 B:CRAWL:UN_BONUS:1d4 F:RAND_50 | RES_DISE | ATTR_MULTI | CAN_SWIM | F:STUPID | WEIRD_MIND | BASH_DOOR | F:ANIMAL | HURT_LITE | NO_FEAR | BASEANGBAND | NO_CUT S:MULTIPLY D:It is a strange mass of squirming worms. Magical energy crackles D:around its disgusting form. N:633:Rotting quylthulg G:Q:u I:120:48d10:20:1:0 W:45:1:3000:3000 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | ANIMAL | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_2 | S:BLINK | TPORT | S:S_UNDEAD D:It is a pulsing flesh mound that reeks of death and putrefaction. N:634:Lesser titan G:P:y I:120:24d100:30:80:15 W:56:3:30000:6000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:CONFUSE:9d9 B:HIT:CONFUSE:9d9 B:HIT:CONFUSE:9d9 B:HIT:CONFUSE:9d9 F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_GOOD | DROP_4D2 | DROP_SKELETON | DROP_CORPSE | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | MALE | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | TELE_TO | SCARE | S:S_MONSTERS D:It is a humanoid figure thirty feet tall that gives off an aura of power D:and hate. N:635:9-headed hydra G:M:r I:120:100d12:20:95:20 W:40:2:8000:3000 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:FIRE:3d10 B:BITE:FIRE:3d10 B:BITE:FIRE:3d10 B:BITE:FIRE:3d10 F:FORCE_SLEEP | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:ONLY_GOLD | DROP_3D2 | DROP_4D2 | CAN_SWIM | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | DROP_CORPSE | F:ANIMAL | IM_FIRE | MORTAL | BASEANGBAND S:1_IN_4 | S:SCARE | BO_FIRE | BR_FIRE D:A strange reptilian creature with nine smouldering heads. N:636:Enchantress G:p:R I:130:52d10:20:60:10 W:40:4:1700:2100 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:2d6 B:HIT:HURT:2d6 B:HIT:HURT:2d8 F:FEMALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_2 | S:BLIND | S:S_DRAGON D:This elusive female spellcaster has a special affinity for dragons, without D:whom she rarely fights. N:637:Ranger chieftain G:p:W I:120:50d20:20:60:10 W:41:2:1800:1800 E:1:1:1:2:1:1 O:30:50:20:0 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:MALE | INVISIBLE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE F:ONLY_ITEM | DROP_2D2 | TAKE_ITEM | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP | IM_FIRE | IM_ELEC | IM_COLD | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_4 | S:S_MONSTERS | S:ARROW_2 | ARROW_3 | ARROW_4 | MISSILE | BO_FIRE | BO_ELEC | BA_COLD | S:HASTE | BLINK | S_ANIMALS D:A chieftain among the Rangers. His understanding of nature gives him D:powerful elemental spells to use against you, in addition to his skills D:as an archer and a warrior. Furthermore, he is a master of camouflage, so D:you will need magically enhanced seeing to spot him. N:638:Sorcerer G:p:R I:130:52d10:20:60:10 W:40:2:1700:2150 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:2d8 B:HIT:HURT:2d8 B:HIT:HURT:2d8 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_90 | DROP_4D2 | F:OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_2 | S:BLINK | TELE_TO | BLIND | CONF | CAUSE_3 | TRAPS | S:BO_ACID | BA_FIRE | BA_COLD | S:S_MONSTER | S_UNDEAD | S_DRAGON D:A human figure in robes, he moves with magically improved speed, and his D:hands are ablur with spell casting. N:639:Xaren G:X:s I:120:32d10:20:80:10 W:40:1:500000:1200 E:0:0:0:3:0:0 O:0:0:0:0 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:FORCE_MAXHP | SUSCEP_ACID | F:EMPTY_MIND | COLD_BLOOD | F:ONLY_GOLD | DROP_2D2 | F:KILL_ITEM | PASS_WALL | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_ROCK | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT D:It is a tougher relative of the Xorn. Its hide glitters with metal ores. N:640:Giant roc G:B:u I:110:80d13:20:70:10 W:40:3:6000:1000 E:0:1:1:0:1:0 O:0:0:0:0 B:CRUSH:HURT:8d12 B:CRUSH:HURT:8d12 B:HIT:ELEC:12d12 F:BASH_DOOR | CAN_FLY | WILD_MOUNTAIN | WILD_WOOD | F:ANIMAL | IM_ELEC | DROP_CORPSE | SUSCEP_ACID | HAS_EGG F:MORTAL | BASEANGBAND D:A vast legendary bird, its iron talons rake the most impenetrable of D:surfaces and its screech echoes through the many winding dungeon corridors. N:641:Minotaur G:H:U I:130:100d10:13:25:10 W:40:2:15000:2100 E:1:1:1:2:1:1 O:0:0:0:0 B:BUTT:HURT:4d6 B:BUTT:HURT:4d6 B:BUTT:HURT:2d6 B:BUTT:HURT:2d6 F:BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | MORTAL | BASEANGBAND D:It is a cross between a human and a bull. N:642:Medusa, the Gorgon G:n:v I:120:24d100:30:100:5 W:40:3:4000:9000 E:1:1:1:2:0:1 O:30:35:35:0 B:GAZE:EXP_80 B:GAZE:PARALYZE B:HIT:HURT:8d6 B:HIT:HURT:8d6 F:UNIQUE | FEMALE | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_ACID | IM_FIRE | IM_POIS | F:MORTAL | BASEANGBAND S:1_IN_2 | S:HOLD | SCARE | CAUSE_3 | BO_FIRE | BO_PLAS | BA_ACID | S:S_HYDRA | S_KIN D:One of the original three ugly sisters. Her face could sink a thousand D:ships. Her scales rattle as she slithers towards you, venom dripping from D:her ghastly mouth. N:643:Death drake G:D:G I:120:21d100:25:100:80 W:45:2:170000:10000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d10 B:CLAW:HURT:4d10 B:BITE:EXP_80:7d10 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | RES_TELE F:INVISIBLE | TAKE_ITEM | CAN_FLY | F:PASS_WALL | POWERFUL | MOVE_BODY | RES_NETH | F:EVIL | DRAGON | IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | ATTR_MULTI S:1_IN_6 | S:SLOW | CONF | SCARE | S:BR_NETH D:It is a dragon-like form wrapped in darkness. You cannot make out its D:true form but you sense its evil. N:644:Ancient red dragon G:D:r I:120:10d100:20:90:80 W:41:1:170000:2500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d9 B:CLAW:HURT:4d9 B:BITE:FIRE:7d9 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE F:DROP_3D2 | DROP_4D2 | CAN_FLY | SUSCEP_COLD | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | IM_FIRE | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | SCARE | S:BR_FIRE D:A huge draconic form. Wisps of smoke steam from its nostrils and the D:extreme heat surrounding it makes you gasp for breath. N:645:Ancient gold dragon G:D:y I:120:10d100:20:90:80 W:41:1:170000:2500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d9 B:CLAW:HURT:4d9 B:BITE:HURT:7d9 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE F:DROP_3D2 | DROP_4D2 | CAN_FLY | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | NO_STUN | NO_SLEEP | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | SCARE | S:BR_SOUN D:A huge draconic form wreathed in a nimbus of light. Its roar stuns and D:deafens you. N:646:Great crystal drake G:D:U I:120:21d100:25:100:80 W:45:2:170000:10000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d10 B:CLAW:HURT:4d10 B:BITE:HURT:7d10 F:FORCE_SLEEP | FORCE_MAXHP | REFLECTING | DROP_CORPSE F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | CAN_FLY | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | NO_CUT F:ATTR_MULTI S:1_IN_6 | S:SLOW | CONF | SCARE | S:BR_SHAR D:A huge crystalline dragon. Its claws could cut you to shreds and its D:teeth are razor sharp. Strange colours ripple through it as it moves in D:the light. N:647:Wyrd sister G:p:v I:125:50d11:20:60:10 W:40:4:1600:1900 E:1:1:1:2:1:1 O:10:0:80:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:CLAW:HURT:2d8 F:FEMALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_SKELETON F:OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP F:MORTAL | ZANGBAND S:1_IN_2 | S:BLIND | S:S_DEMON | CONF | SCARE | DARKNESS | BA_CHAO D:This old crone is rumoured to be a witch of chaos... but you don't D:really believe in witches, do you? N:648:Vrock G:U:s I:110:40d10:20:50:80 W:40:2:2700:2000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:3d4 B:CRUSH:HURT:8d12 B:CRUSH:HURT:8d12 F:FORCE_SLEEP | FORCE_MAXHP | F:FRIENDS | F:ONLY_ITEM | DROP_60 | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | BASEANGBAND S:1_IN_8 | S:BLIND | CONF D:It is a demon with a long neck and raking claws. N:649:Death quasit G:u:D I:130:44d10:20:80:0 W:40:3:600:1000 E:1:1:1:2:1:1 O:0:50:50:0 B:BITE:LOSE_DEX:3d6 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_90 | DROP_2D2 | DROP_4D2 | NONLIVING | F:SMART | INVISIBLE | PASS_WALL | CAN_FLY | F:EVIL | DEMON | IM_FIRE | IM_POIS | RES_TELE F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_10 | S:BLIND | CONF | SCARE | CAUSE_3 | FORGET | S:S_DEMON D:It is a demon of small stature, but its armoured frame moves with D:lightning speed and its powers make it a tornado of death and destruction. N:650:Giganto, the Gargantuan G:~:s I:110:80d10:20:75:30 W:38:6:8000:1750 E:0:1:0:0:1:0 O:60:40:0:0 B:CRUSH:HURT:30d2 B:CRUSH:HURT:30d2 B:CRUSH:HURT:30d2 F:FORCE_SLEEP | FORCE_MAXHP | CAN_SWIM | IM_FIRE | F:DROP_60 | DROP_90 | DROP_2D2 | UNIQUE | WEIRD_MIND | F:BASH_DOOR | SMART | EVIL | IM_COLD | DROP_CORPSE F:RES_WATE | WILD_OCEAN | F:MORTAL | ZANGBAND S:1_IN_9 | S:BR_NUKE | BA_WATE D:A gargantuan mutant whale, who has grown legs that enable it to walk D:on dry land as well. N:651:Strygalldwir G:U:W I:120:12d100:90:60:10 W:41:3:5000:8000 E:1:1:1:2:1:1 O:20:0:80:0 B:CLAW:HURT:5d5 B:CLAW:HURT:5d5 B:HIT:LOSE_STR:4d4 B:TOUCH:EXP_80:8d1 F:UNIQUE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:INVISIBLE | COLD_BLOOD | PASS_WALL | MOVE_BODY | NONLIVING | NO_SLEEP | NO_CONF| F:OPEN_DOOR | BASH_DOOR | IM_POIS | IM_COLD | DEMON | EVIL | ZANGBAND S:1_IN_3 | S:CAUSE_3 | HOLD | SCARE | BLIND | BO_ACID | S_DEMON | S:FORGET | BO_NETH | MIND_BLAST | DARKNESS D:"it was well over six feet in height, with great branches of antlers D:growing out of its forehead. Nude, its flesh was a uniform ash-gray D:in color. It appeared to be sexless, and it had gray, leathery wings D:extending far out behind it." N:652:Fallen angel G:A:s I:130:100d25:30:90:255 W:49:6:0:8000 E:1:1:1:2:1:1 O:0:50:50:0 B:GAZE:EXP_40:4d4 B:GAZE:EXP_40:4d4 B:HIT:HURT:6d6 B:HIT:HURT:6d6 F:FORCE_SLEEP | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | NO_FEAR | EVIL | REFLECTING | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | RES_TELE | RES_NETH | F:CAN_FLY | BASEANGBAND | HAS_LITE S:1_IN_3 | S:TELE_TO | BLIND | SCARE | CAUSE_2 | CAUSE_4 | S:S_DEMON | BO_NETH D:An angelic being, who was mighty once, but dared defy its Creator. N:653:Giant headless G:H:u I:110:30d12:20:50:40 W:41:2:4000:900 E:1:1:1:2:1:0 O:0:100:0:0 B:HIT:HURT:4d8 B:HIT:HURT:4d8 B:HIT:HURT:4d8 F:FRIENDS | DROP_60 | DROP_90 | OPEN_DOOR | BASH_DOOR | F:DROP_SKELETON | DROP_CORPSE F:EVIL | ZANGBAND S:1_IN_6 S:SCARE | BA_NUKE | BLIND D:Giant headless humanoid abominations created by a magical mutation. N:654:Judge Fire G:s:R I:120:18d100:90:70:10 W:41:3:0:12000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:FIRE:5d5 B:HIT:FIRE:5d5 B:GAZE:EXP_80 B:WAIL:TERRIFY F:UNIQUE | MALE | CAN_SPEAK | SUSCEP_COLD | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | POWERFUL | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | SUSCEP_COLD | IM_POIS | IM_FIRE | RES_PLAS | F:NO_CONF | NO_SLEEP | JOKEANGBAND | HAS_LITE | NO_CUT | NO_STUN S:1_IN_3 | S:CAUSE_3 | BO_FIRE | BA_FIRE | BR_FIRE | BO_PLAS S:DARKNESS | S_MONSTER | S_DEMON | S_UNDEAD | TPORT | BLINK | SCARE D:One of the Dark Judges, he has come to punish your crime of living. D:He looks like a skeleton enveloped in flames. N:655:Ubbo-Sathla, the Unbegotten Source G:j:W I:120:20d100:90:80:10 W:41:3:0:13500 E:0:0:0:0:0:0 O:30:50:0:10 B:CRUSH:ACID:5d5 B:HIT:POISON:5d5 B:CRUSH:ACID:5d5 B:HIT:POISON:5d5 F:UNIQUE | CAN_SPEAK | NO_STUN | NO_SLEEP | NO_CONF | NO_STUN | F:FORCE_SLEEP | FORCE_MAXHP | ELDRITCH_HORROR | ESCORT | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | REGENERATE | SUSCEP_FIRE | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | KILL_BODY | F:EVIL | SUSCEP_FIRE | IM_COLD | IM_POIS | CTHANGBAND | NO_CUT D:"There, in the gray beginning of Earth, the formless mass that was D:Ubbo-Sathla reposed amid the slime and the vapors. Headless, D:without organs or members..." N:656:Judge Mortis G:z:G I:120:18d100:90:70:10 W:41:3:0:13000 E:1:1:1:2:1:1 O:0:75:0:15 B:HIT:POISON:5d5 B:HIT:DISEASE:5d5 B:TOUCH:LOSE_ALL B:TOUCH:EXP_80 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | SUSCEP_FIRE | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | JOKEANGBAND | NO_CUT | NO_STUN S:1_IN_3 | S:BLIND | SCARE | CAUSE_3 | BO_ACID | BO_NETH | BR_POIS | S:BR_NETH | BO_NETH | BLINK | TPORT | ANIM_DEAD S:BO_POIS | S_UNDEAD D:Another Dark Judge, he is a rotting humanoid with a cow's skull as D:his head. N:657:Dark elven sorcerer G:h:R I:130:80d10:20:70:10 W:41:2:1300:3000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:2d8 B:HIT:HURT:2d8 B:HIT:HURT:2d8 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE F:ONLY_ITEM | DROP_90 | DROP_4D2 | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | BLINK | TELE_TO | BLIND | CONF | CAUSE_3 | DARKNESS | S:BO_ACID | BA_FIRE | BA_COLD | ANIM_DEAD S:S_MONSTER | S_UNDEAD | S_DEMON | MISSILE D:A dark elven figure, dressed in deepest black. Power seems to crackle D:from his slender frame. N:658:Master lich G:L:r I:120:18d100:20:80:50 W:41:2:1800:7000 E:1:1:1:2:1:1 O:10:45:25:10 B:TOUCH:EXP_80 B:TOUCH:UN_POWER B:TOUCH:LOSE_DEX:2d12 B:TOUCH:LOSE_DEX:2d12 F:FORCE_SLEEP | FORCE_MAXHP | SMART | RES_TELE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_3 | S:BLINK | TELE_TO | BLIND | HOLD | CONF | SCARE | CAUSE_3 | CAUSE_4 | S:DRAIN_MANA | BRAIN_SMASH | S_UNDEAD D:A skeletal form wrapped in robes. Powerful magic crackles along its D:bony fingers. N:659:Byakhee G:U:D I:110:40d10:20:40:80 W:41:3:1300:1500 E:0:0:0:0:0:0 O:0:50:50:0 B:CLAW:LOSE_STR:3d4 B:BITE:EXP_20:3d4 F:FORCE_SLEEP | FORCE_MAXHP | FRIENDS | F:ONLY_ITEM | DROP_2D2 | ELDRITCH_HORROR | F:OPEN_DOOR | BASH_DOOR | POWERFUL | CAN_FLY | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | CTHANGBAND S:1_IN_9 | S:BO_FIRE | S:S_DEMON | CONF D:"There flapped rhythmically a horde of tame, trained, hybrid D:winged things... not altogether crows, nor moles, nor buzzards, D:nor ants, nor decomposed human beings, but something I cannot D:and must not recall." N:660:Eol, the Dark Elf G:h:D I:130:80d30:20:100:60 W:49:2:1400:25000 E:1:1:1:2:1:1 O:10:40:40:10 B:HIT:HURT:3d8 B:HIT:HURT:3d8 B:HIT:HURT:3d8 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | CAN_SPEAK | F:ONLY_ITEM | DROP_4D2 | DROP_2D2 | DROP_GOOD | DROP_CHOSEN | F:SMART | IM_ELEC | IM_COLD | IM_POIS | IM_FIRE | F:REFLECTING | OPEN_DOOR | BASH_DOOR | SPECIAL_GENE | F:HURT_LITE | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | BLINK | TELE_TO | BLIND | CONF | CAUSE_4 | DARKNESS | S:BA_NETH | BA_ELEC | BA_ACID | BA_FIRE | BA_COLD | BO_MANA | S:S_MONSTERS | S_UNDEAD | S_DRAGON | S_DEMON D:A lord of the Teleri, Eol is a mighty metalsmith, the first D:one ever to forge weapons of meteorite iron. His dark D:countenance glares at you in disdain. N:661:Archon G:A:y I:130:100d35:30:140:255 W:55:5:3200:12000 E:1:1:1:2:1:1 O:0:100:0:0 B:GAZE:TERRIFY:4d4 B:GAZE:TERRIFY:4d4 B:HIT:HURT:8d6 B:HIT:HURT:8d6 F:FORCE_SLEEP | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | NO_FEAR | GOOD | REFLECTING | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | RES_TELE | CAN_FLY F:BASEANGBAND | HAS_LITE S:1_IN_3 | S:TELE_TO | BLIND | SCARE | CAUSE_2 | CAUSE_4 | BO_MANA | S:S_ANGEL D:Never a more heavenly being have you seen. The very holiness of its D:presence makes you deeply respect it. Few creatures can match the powers D:of an Archon; fewer still live to tell the tale after attacking one. N:662:Formless spawn of Tsathoggua G:U:D I:110:22d20:20:40:80 W:41:2:0:1850 E:0:0:0:0:0:0 O:35:45:0:10 B:HIT:ACID:2d4 B:HIT:ACID:2d4 B:CRUSH:HURT:3d4 B:BITE:ACID:6d6 F:FORCE_SLEEP | FORCE_MAXHP | ELDRITCH_HORROR | NONLIVING | F:ONLY_ITEM | DROP_90 | REGENERATE | RES_TELE | F:OPEN_DOOR | BASH_DOOR | POWERFUL | CAN_SWIM | F:EVIL | DEMON | NO_CONF | NO_SLEEP | SUSCEP_FIRE | IM_POIS | CTHANGBAND | NO_CUT S:1_IN_9 | S:BO_FIRE | BO_ACID | S:S_DEMON | MIND_BLAST | DARKNESS | D:"...living things that oozed along stone channels... D:But they were not toads like Tsathoggua himself. Far worse -- D:they were amorphous lumps of viscous black slime that took D:temporary shapes for various purposes." N:663:Hunting horror G:U:D I:110:30d17:20:90:80 W:42:2:0:2300 E:0:0:0:0:0:0 O:45:35:0:10 B:BITE:LOSE_DEX:1d3 B:BITE:POISON:1d3 B:CRUSH:HURT:9d4 F:FORCE_SLEEP | FORCE_MAXHP | ELDRITCH_HORROR | F:ONLY_ITEM | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | POWERFUL | CAN_FLY | F:EVIL | DEMON | HURT_LITE | IM_POIS | F:IM_FIRE | NO_CONF | NO_SLEEP | CTHANGBAND S:1_IN_9 | S:BLIND | CONF | S_DEMON | BR_DARK D:"And in the air there were great viperine creatures, D:which had curiously distorted heads, and grotesquely great D:clawed appendages, supporting themselves with ease by the aid D:of black rubbery wings of singularly monstrous dimensions." N:664:Undead beholder G:e:u I:120:27d100:30:100:10 W:45:3:1600:8000 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:EXP_40:3d6 B:GAZE:UN_POWER:3d6 B:GAZE:INSANITY:3d6 B:BITE:EXP_40:7d6 F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | F:COLD_BLOOD | BASH_DOOR | F:EVIL | UNDEAD | CAN_FLY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_2 | S:SLOW | CONF | CAUSE_4 | DRAIN_MANA | MIND_BLAST | FORGET | S:BO_MANA | BO_NETH | BRAIN_SMASH | BA_FIRE | BA_COLD | BO_ACID | S:S_UNDEAD | ANIM_DEAD D:A beholder which has cheated death. Black nether storms rage around the D:bloodshot pupil of its central giant eye, and light seems to bend as it D:sucks its power from the very air around it. Your soul chills as it drains D:your vitality for its evil enchantments. N:665:Shadow G:G:D I:120:10d20:30:30:20 W:37:3:0:400 E:0:0:0:0:0:0 O:90:10:0:0 B:TOUCH:EXP_80 B:TOUCH:EXP_40 B:CLAW:LOSE_INT:1d10 B:CLAW:LOSE_WIS:1d10 F:FORCE_SLEEP | CAN_FLY | F:ONLY_ITEM | DROP_1D2 | POWERFUL | REGENERATE | HURT_LITE | F:INVISIBLE | COLD_BLOOD | PASS_WALL | RES_NETH | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_8 | S:BO_NETH | TELE_TO | SLOW D:A mighty spirit of darkness of vaguely humanoid form. Razor-edged claws D:reach out to end your life as it glides towards you, seeking to suck the D:energy from your soul to feed its power. N:666:Iron lich G:L:s I:120:22d100:30:100:10 W:42:4:0:10000 E:0:0:0:0:1:0 O:0:0:100:0 B:BUTT:COLD:3d6 B:BUTT:FIRE:3d6 B:BUTT:ELEC:3d6 F:FORCE_SLEEP | FORCE_MAXHP | REFLECTING | F:COLD_BLOOD | BASH_DOOR | CAN_FLY | SUSCEP_ACID | F:EVIL | UNDEAD | POWERFUL | SMART | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | RES_TELE | F:ONLY_ITEM | DROP_60 | DROP_GOOD | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_2 | S:BA_WATE | BA_FIRE | BO_ICEE | BA_ELEC | BA_COLD | S:CAUSE_4 | DRAIN_MANA | BRAIN_SMASH | S_UNDEAD D:It is a huge, twisted grey skull floating through the air. Its cold eyes D:burn with hatred towards all who live. N:667:Dread G:G:o I:120:25d20:20:30:10 W:42:1:1000:600 E:0:0:0:0:0:0 O:0:50:50:0 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:HIT:LOSE_STR:3d4 F:FORCE_SLEEP | F:RAND_25 | FRIENDS | CAN_FLY | F:ONLY_ITEM | DROP_60 | F:TAKE_ITEM | INVISIBLE | COLD_BLOOD | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_15 | S:BLIND | HOLD | CONF | DRAIN_MANA | BO_NETH D:It is a form that screams its presence against the eye. Death incarnate, D:its hideous black body seems to struggle against reality as the universe D:itself struggles to banish it. N:668:Greater basilisk G:R:D I:120:20d100:25:100:15 W:42:2:3000:10000 E:0:1:0:2:1:0 O:0:50:50:0 B:GAZE:PARALYZE:3d12 B:GAZE:PARALYZE:3d12 B:BITE:POISON:2d12 B:BITE:POISON:2d12 F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | POWERFUL | F:OPEN_DOOR | BASH_DOOR | EVIL | IM_POIS | DROP_CORPSE | F:ANIMAL | NO_CONF | NO_SLEEP | CAN_SWIM | F:MORTAL | BASEANGBAND S:1_IN_8 S:BR_POIS | BR_DARK | BR_NEXU D:A large basilisk, whose shape resembles that of a great wyrm. N:669:Charybdis G:~:r I:120:20d100:20:100:70 W:42:1:15000:13000 E:0:0:0:0:1:0 O:50:50:0:0 B:ENGULF:HURT:10d8 B:ENGULF:HURT:10d8 B:ENGULF:HURT:10d8 F:AQUATIC | EVIL | UNIQUE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_3D2 | DROP_GOOD | F:SMART | POWERFUL | MOVE_BODY | NEVER_MOVE | F:IM_ACID | IM_FIRE | IM_COLD | RES_WATE | COLD_BLOOD | F:IM_ELEC | IM_POIS | NO_STUN | ZANGBAND S:1_IN_5 | S:BA_WATE D:A monstrous dweller of the depths; its hungry maw has been the doom D:of innumerable sailors! N:670:Jack of Shadows G:p:s I:150:30d100:70:150:4 W:60:4:2300:10000 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:HURT:5d10 B:HIT:HURT:5d10 B:HIT:EAT_ITEM:2d10 B:HIT:EAT_ITEM:2d10 F:MALE | FORCE_MAXHP | CAN_SPEAK | REFLECTING | DROP_SKELETON | DROP_CORPSE | F:REGENERATE | F:IM_ACID | IM_ELEC | IM_COLD | IM_FIRE | IM_POIS | RES_TELE | F:ONLY_ITEM | DROP_3D2 | DROP_GOOD | DROP_GREAT | UNIQUE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | SMART | POWERFUL | F:MORTAL | ZANGBAND S:1_IN_3 S:BLIND | HEAL | BA_DARK | HASTE | CONF | D:Deriving his strength from the shadows, this king of thieves D:steals only for the challenge. N:671:Zephyr Lord G:W:v I:130:80d10:20:70:10 W:43:2:600:3000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:EXP_20:8d2 B:HIT:LOSE_STR:8d2 B:HIT:LOSE_CON:8d2 F:MALE | ATTR_MULTI | UNDEAD | EVIL | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS | F:ONLY_ITEM | DROP_90 | DROP_4D2 | F:SMART | OPEN_DOOR | BASH_DOOR | F:NO_STUN | NO_CONF | NO_SLEEP | ZANGBAND | NO_CUT S:1_IN_5 | S:SHRIEK | S_HOUND D:An undead master of the vicious Zephyr hounds. N:672:Juggernaut of Khorne G:g:D I:120:90d19:12:90:10 W:43:3:6000:2500 E:1:1:1:2:1:1 O:0:0:0:0 B:BUTT:HURT:6d6 B:CRUSH:HURT:8d6 B:CRUSH:HURT:8d6 B:BUTT:HURT:6d6 F:COLD_BLOOD | BASH_DOOR | REFLECTING | KILL_ITEM | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | ZANGBAND | NO_CUT D:A great, vicious beast whose flesh is made of steel and whose D:blood is fire. It charges at you ignoring everything else. N:673:Mumak G:q:s I:110:90d10:20:55:100 W:63:2:150000:2100 E:0:1:0:2:1:0 O:0:0:0:0 B:BUTT:HURT:8d6 B:BUTT:HURT:8d6 B:CRUSH:HURT:8d4 F:FRIENDS | DROP_CORPSE | F:BASH_DOOR | ANIMAL | MORTAL | BASEANGBAND D:A massive elephantine form with eyes twisted by madness. N:674:Judge Fear G:W:D I:120:18d100:90:70:10 W:43:4:0:12000 E:1:1:1:2:1:1 O:100:0:0:0 B:GAZE:TERRIFY B:GAZE:EXP_40 B:GAZE:EXP_40 B:GAZE:HURT:2d20 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:INVISIBLE | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | JOKEANGBAND | NO_CUT | NO_STUN S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | MIND_BLAST | BRAIN_SMASH | S:S_UNDEAD | DRAIN_MANA | FORGET | ANIM_DEAD D:A Dark Judge, reputedly so frightening that his gaze can kill. N:675:Ancient multi-hued dragon G:D:v I:120:21d100:25:100:80 W:43:1:170000:13000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d10 B:CLAW:HURT:4d10 B:BITE:HURT:7d10 F:ATTR_MULTI | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | DROP_CORPSE F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | F:SMART | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | IM_ACID | IM_FIRE | IM_COLD | F:IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_5 | S:BLIND | CONF | SCARE | S:BR_ACID | BR_FIRE | BR_COLD | BR_ELEC | BR_POIS D:A huge draconic form. Many colours ripple down its massive frame. Few D:live to see another. N:676:Ethereal dragon G:D:o I:120:21d100:25:100:80 W:45:2:170000:10000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d10 B:CLAW:HURT:4d10 B:BITE:HURT:7d10 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | F:INVISIBLE | CAN_FLY | F:PASS_WALL | POWERFUL | MOVE_BODY | F:DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | ATTR_MULTI S:1_IN_6 | S:BLIND | CONF | S:BR_LITE | BR_DARK | BR_CONF D:A huge dragon emanating from the ethereal plane, this terrible creature is D:a master of light and dark. Its form disappears from sight as it cloaks D:itself in unearthly shadows. N:677:Dark young of Shub-Niggurath G:U:g I:120:12d100:20:75:80 W:43:2:0:5000 E:0:0:0:0:0:0 O:0:40:30:20 B:CRUSH:HURT:5d6 B:CRUSH:HURT:5d6 B:BITE:LOSE_STR:1d6 B:BITE:LOSE_STR:1d6 F:FORCE_SLEEP | FORCE_MAXHP | ELDRITCH_HORROR | F:ONLY_ITEM | DROP_1D2 | NONLIVING | CAN_SWIM | F:OPEN_DOOR | BASH_DOOR | POWERFUL | HURT_LITE | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | RES_TELE | CTHANGBAND S:1_IN_9 | S:BLIND | CAUSE_2 | S:S_DEMON | HEAL D:"Something black in the road, something that wasn't a tree. D:Something big and black and ropy, just squatting there, waiting, D:with ropy arms squirming and reaching... It came crawling up the D:hillside... and it was the black thing of my dreams... that black, D:ropy, slimy jelly tree-thing out of the woods. It crawled up and it D:flowed up on its hoofs and mouths and snaky arms." N:678:Colour out of space G:.:v I:120:12d100:20:100:10 W:43:2:0:8000 E:0:0:0:0:0:0 O:35:35:10:10 B:TOUCH:LOSE_ALL:7d6 B:TOUCH:LOSE_ALL:7d6 F:FORCE_SLEEP | FORCE_MAXHP | RAND_25 | F:INVISIBLE | PASS_WALL | CAN_FLY | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | ATTR_MULTI | ATTR_ANY | F:CHAR_CLEAR | SMART | COLD_BLOOD | EVIL | F:IM_COLD | IM_FIRE | IM_ACID | IM_ELEC | IM_POIS | F:NO_STUN | NO_CONF | NO_SLEEP | CTHANGBAND | HAS_LITE | NO_CUT S:1_IN_9 | S:DRAIN_MANA | BR_DISE | BR_NETH | TPORT D:"The shaft of phosphorescence from the well... was no longer shining D:out, it was pouring out; and as the shapeless stream of unplaceable D:colour left the well it seemed to flow directly into the sky." N:679:Quaker, Master of Earth G:E:u I:110:28d100:10:97:90 W:43:3:0:4500 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:HIT:SHATTER:10d10 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:EMPTY_MIND | COLD_BLOOD | KILL_WALL | F:KILL_ITEM | KILL_BODY | PASS_WALL | POWERFUL | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_ROCK | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT | NO_STUN S:1_IN_6 | S:BO_ACID | BA_ACID D:A towering stone elemental stands before you. The walls and ceiling are D:reduced to rubble as Quaker advances. N:680:Death leprechaun G:h:D I:120:6d6:8:13:8 W:44:6:0:85 E:1:1:1:2:1:1 O:0:0:0:0 B:TOUCH:EXP_40:1d10 B:TOUCH:EAT_GOLD B:TOUCH:EAT_ITEM F:INVISIBLE | RAND_25 | TAKE_ITEM | COLD_BLOOD | SMART | F:HURT_LITE | EVIL | OPEN_DOOR | MALE | UNDEAD | RES_NETH | ZANGBAND | NO_CUT S:MULTIPLY | S:1_IN_6 | S:BLINK | TPORT | TELE_TO | CAUSE_3 | ANIM_DEAD D:Nasty undead little creatures. They are chanting the name of the D:sinister wizard who created them: 'Bruce! Bruce..!' N:681:Chaugnar Faugn, Horror from the Hills G:q:D I:110:20d100:10:125:90 W:44:4:0:6250 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:10d10 B:CRUSH:HURT:10d10 B:BITE:LOSE_CON:8d2 B:BITE:LOSE_CON:8d1 F:UNIQUE | CAN_SPEAK | EVIL | DEMON | F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | F:ELDRITCH_HORROR | POWERFUL | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_ROCK | F:NO_CONF | NO_FEAR | CTHANGBAND S:1_IN_6 | S:HOLD | CAUSE_4 | CONF | SCARE | FORGET | BRAIN_SMASH | S:MIND_BLAST | CAUSE_3 | S_DEMON | S_MONSTERS D:"The ears were webbed and tentacled, the trunk terminated in D:a huge flaring disk at least a foot in diameter... Its forelimbs D:were bent stiffly at the elbow, and its hands... rested palms D:upward on its lap." N:682:Lloigor G:v:B I:120:100d15:20:100:20 W:44:2:0:6000 E:0:0:0:0:0:0 O:90:0:10:0 B:ENGULF:LOSE_CON:4d10 B:ENGULF:LOSE_CON:4d10 B:ENGULF:LOSE_CON:4d10 F:FORCE_SLEEP | ELDRITCH_HORROR | PASS_WALL | F:INVISIBLE | DROP_2D2 | DROP_4D2 | CAN_FLY | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | POWERFUL | F:SMART | IM_FIRE | IM_COLD | IM_ELEC | IM_ACID | IM_POIS | F:MORTAL | CTHANGBAND | HAS_LITE | NO_CUT S:1_IN_4 | S:BR_WALL | TELE_AWAY | BR_GRAV | S:S_KIN | MIND_BLAST | BLIND | BLINK D:"Invisible ones from the stars... They sometimes took forms... D:but existed as vortices of power in their natural state." N:683:Utgard-Loke G:P:v I:120:40d100:30:125:15 W:44:3:0:13500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:COLD:12d12 B:HIT:COLD:12d12 B:HIT:COLD:12d12 B:HIT:COLD:12d12 F:ESCORT | UNIQUE | IM_COLD | AURA_COLD | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | MOVE_BODY | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | MALE | ZANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | TELE_TO | S:S_KIN | BR_COLD D:A frost giant chieftain, unusually smart for a giant. N:684:Quachil Uttaus, Treader of the Dust G:z:D I:120:50d66:30:80:15 W:44:3:0:20000 E:1:1:1:2:1:1 O:0:0:100:0 B:CLAW:HURT:50d1 B:TOUCH:TIME:1d50 B:TOUCH:TIME:1d50 F:ESCORT | UNIQUE | IM_COLD | ELDRITCH_HORROR | RES_NETH | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | KILL_BODY | DROP_GREAT | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | NO_SLEEP | NO_CONF F:EVIL | UNDEAD | DEMON | REGENERATE | CTHANGBAND | NO_CUT S:1_IN_3 | S:BR_TIME | SLOW | HASTE | HEAL D:"It was a figure no larger than a young child, but severe and D:shriveled as some millenial mummy. Its hairless head, its D:unfeatured face, borne on a neck of skeleton thinness, were D:lined with a thousand reticulated wrinkles. The body was like D:that of some monstrous, withered abortion that had never drawn D:breath. The pipelike arms, ending in bony claws, were outhrust as if D:enclosed in a posture of an eternal dreadful grasping." N:685:Shoggoth G:j:D I:140:50d20:20:80:20 W:44:2:0:2500 E:0:0:0:0:0:0 O:30:70:0:0 B:CRUSH:ACID:5d6 B:CRUSH:ACID:5d6 B:CRUSH:ACID:5d6 B:CRUSH:HURT:9d9 F:REGENERATE | ONLY_ITEM | KILL_ITEM | DROP_2D2 | DROP_90 | DROP_60 F:BASH_DOOR | EVIL | NO_CONF | NO_SLEEP | KILL_BODY | CAN_SWIM | F:FORCE_MAXHP | FORCE_SLEEP | HURT_LITE | POWERFUL | F:IM_ACID | IM_FIRE | RES_PLAS | IM_POIS | IM_COLD | IM_ELEC | RES_TELE F:CTHANGBAND | HAS_LITE | NO_CUT D:"The nightmare, plastic column of fetid, black iridescence oozed D:tightly onward... A shapeless congerie of protoplasmic bubbles, D:faintly self-luminous and with myriads of temporary eyes forming D:and unforming as pustules of greenish light all over the D:tunnel-filling front that bore down upon us, crushing the frantic D:penguins and slithering over glistening floor that it and its D:kind had swept so evilly free of all litter. Still came that eldritch D:mocking cry -- 'Tekeli-li! Tekeli-li!'" N:686:Judge Death G:W:D I:120:45d50:90:90:10 W:43:3:0:14000 E:1:1:1:2:1:1 O:0:20:80:0 B:CLAW:POISON:10d5 B:CLAW:POISON:10d5 B:CLAW:EXP_40:10d1 B:GAZE:TERRIFY F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_ELEC | IM_COLD | SUSCEP_FIRE | F:IM_POIS | NO_CONF | NO_SLEEP | JOKEANGBAND | NO_CUT | NO_STUN S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_4 | BA_FIRE | BA_NETH | ANIM_DEAD S:S_MONSTERS | S_UNDEAD | S_HI_UNDEAD | DRAIN_MANA | D:The most powerful Dark Judge, whose touch means death. N:687:Ariel, Queen of Air G:E:B I:130:27d100:12:50:50 W:43:3:0:4750 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:4d6 B:HIT:CONFUSE:4d4 B:HIT:HURT:4d6 B:HIT:CONFUSE:4d4 F:UNIQUE | FEMALE | AURA_ELEC | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:RAND_25 | CAN_FLY | F:EMPTY_MIND | COLD_BLOOD | F:KILL_ITEM | KILL_BODY | BASH_DOOR | POWERFUL | F:IM_ACID | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_5 | S:BO_ELEC | BA_COLD | BA_ELEC D:A towering air elemental, Ariel the sorceress avoids your blows D:with her extreme speed. N:688:11-headed hydra G:M:R I:120:100d18:20:100:20 W:44:2:8500:6000 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:FIRE:3d12 B:BITE:FIRE:3d12 B:BITE:FIRE:3d12 B:BITE:FIRE:3d12 F:FORCE_SLEEP | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:ONLY_GOLD | DROP_2D2 | DROP_4D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:ANIMAL | IM_FIRE | CAN_SWIM | F:MORTAL | BASEANGBAND S:1_IN_4 | S:SCARE | BO_FIRE | BO_PLAS | BA_FIRE | BR_FIRE D:A strange reptilian hybrid with eleven smouldering heads. N:689:Patriarch G:p:G I:120:52d10:20:60:10 W:40:2:1800:1800 E:1:1:1:2:1:1 O:0:10:90:0 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d5 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_90 | DROP_2D2 | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | BLIND | HOLD | CAUSE_4 | CAUSE_3 | ANIM_DEAD | S:S_MONSTERS | S_UNDEAD D:An evil priest, dressed all in black. Deadly spells hit you at an D:alarming rate as his black spiked mace rains down blow after blow on your D:pitiful frame. N:690:Dreadmaster G:G:y I:120:12d100:20:100:10 W:44:2:1000:8000 E:0:0:0:0:0:0 O:10:40:25:10 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:HIT:LOSE_STR:3d4 B:HIT:LOSE_STR:3d4 F:FORCE_SLEEP | FORCE_MAXHP | RAND_25 | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | CAN_FLY | F:SMART | TAKE_ITEM | INVISIBLE | COLD_BLOOD | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_9 | S:TELE_LEVEL | BLIND | HOLD | CONF | CAUSE_4 | DRAIN_MANA | BO_NETH | S:S_UNDEAD D:It is an unlife of power almost unequalled. An affront to existence, its D:very touch abuses and disrupts the flow of life, and its unearthly limbs, D:of purest black, crush rock and flesh with ease. N:691:Drolem G:g:g I:120:30d100:25:130:30 W:44:3:40000:12000 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:3d10 B:CLAW:HURT:3d10 B:BITE:POISON:5d10 B:BITE:POISON:5d10 F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | F:EMPTY_MIND | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:DRAGON | IM_FIRE | IM_COLD | F:IM_ELEC | IM_POIS | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT F:ATTR_MULTI S:1_IN_6 | S:BLIND | SLOW | CONF | ARROW_3 | S:BR_POIS D:A constructed dragon, the drolem has massive strength. Powerful spells D:weaved during its creation make it a fearsome adversary. Its eyes show D:little intelligence, but it has been instructed to destroy all it meets. N:692:Scatha the Worm G:D:W I:120:22d100:30:130:70 W:46:2:210000:17000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d10 B:CLAW:HURT:4d10 B:BITE:COLD:4d14 B:BITE:COLD:4d14 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | SUSCEP_FIRE | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_CORPSE F:BASH_DOOR | POWERFUL | MOVE_BODY | CAN_FLY | F:EVIL | DRAGON | IM_COLD | NO_CONF | BASEANGBAND | HAS_LITE S:1_IN_4 | S:CONF | CAUSE_3 | S:BR_COLD D:An ancient and wise dragon, Scatha has grown clever over the long years. D:His scales are covered with frost, and his breath sends a shower of ice D:into the air. N:693:Warrior of the Dawn G:p:R I:120:25d25:20:70:20 W:45:2:1600:500 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:IM_POIS | IM_FIRE | IM_ELEC | IM_ACID | IM_COLD | F:NO_SLEEP | NO_FEAR | F:FRIENDS | F:MALE | OPEN_DOOR | BASH_DOOR | ZANGBAND | HAS_LITE D:Fierce, barbaric warriors, armed with great spiked clubs, and surrounded D:in an aura of scarlet. Whenever one of them is slain, another appears D:out of nowhere to take his place. N:694:Lesser black reaver G:L:D I:120:25d100:20:120:50 W:45:3:2600:12000 E:0:0:0:0:0:0 O:0:0:100:0 B:HIT:UN_BONUS:4d8 B:HIT:UN_BONUS:4d8 B:HIT:LOSE_STR:4d6 B:HIT:LOSE_STR:4d6 F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | CAN_SWIM | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | RES_TELE F:NO_CONF | NO_SLEEP | KILL_WALL | NO_FEAR F:MORTAL | BASEANGBAND | NO_CUT S:1_IN_3 | S:TELE_TO | BLIND | HOLD | CONF | CAUSE_3 | DRAIN_MANA | S:MIND_BLAST | BA_NETH | ANIM_DEAD D:A humanoid form, black as night, advancing steadily and unstoppably. N:695:Zoth-Ommog G:R:v I:120:25d100:12:50:50 W:45:4:0:18000 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:HURT:25d3 B:CRUSH:HURT:25d3 B:BITE:LOSE_DEX:2d10 B:BITE:LOSE_CON:2d10 F:UNIQUE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:RAND_25 | CAN_SWIM | ELDRITCH_HORROR | F:KILL_ITEM | BASH_DOOR | POWERFUL | F:EVIL | IM_ACID | IM_COLD | IM_ELEC | IM_POIS | F:NO_FEAR | CTHANGBAND S:1_IN_5 | S:S_MONSTER | SCARE | CAUSE_4 | S_HYDRA | S_SPIDER | S:BA_NETH | BA_POIS | BA_ACID | CAUSE_3 | HOLD | MIND_BLAST D:"A body shaped like a road-based, truncated cone. A flat, blunt, D:wedge-shaped, vaguely reptilian head surmounts this conical torso, D:and the head is almost entirely hidden behind swirling tresses. D:This hair, or beard and mane, consists of thickly carved and D:coiling ropes, like serpents or worms... Through this repulsive D:Medusa-mane of ropy tendrils, two fierce, serpent-like eyes D:glare in a horrible intermingling of cold, inhuman mockery and D:what I can only describe as gloating menace." N:696:Grand master thief G:p:b I:130:15d100:50:75:40 W:46:2:0:1500 E:1:1:1:2:1:1 O:70:10:10:10 B:HIT:EAT_ITEM:5d5 B:HIT:EAT_ITEM:5d5 B:HIT:EAT_GOLD:5d5 B:HIT:EAT_GOLD:5d5 F:MALE | DROP_2D2 | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | BASEANGBAND S:1_IN_2 | S:BLINK | TPORT | TELE_TO | CONF | TRAPS | ARROW_2 D:A class of its own: you are already too late to protect your possessions - D:and he seems to have studied magic too, and is a master of setting traps. N:697:Smaug the Golden G:D:R I:120:24d100:30:150:80 W:48:2:230000:23000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:FIRE:5d14 B:BITE:FIRE:5d14 F:UNIQUE | MALE | REFLECTING | CAN_FLY | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_SPEAK | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:SMART | EVIL | DRAGON | IM_FIRE | BASEANGBAND F:HAS_LITE S:1_IN_4 | S:CONF | CAUSE_3 | S:BR_FIRE D:Smaug is one of the Uruloki that still survive, a fire-drake of immense D:cunning and intelligence. His speed through air is matched by few other D:dragons, his dragonfire is legendary, and his hide is D:armoured with diamonds. He is believed to be the greatest dragon still D:surviving into the Third Age. N:698:The Stormbringer G:|:D I:120:13d123:20:99:20 W:45:2:0:13333 E:0:0:0:0:0:0 O:0:0:0:0 B:WAIL:TERRIFY B:HIT:EXP_80:64d1 B:HIT:EXP_80:64d1 B:HIT:EXP_80:8d8 F:CHAR_MULTI | EVIL | IM_POIS | IM_COLD | IM_FIRE | RES_NETH | F:FORCE_SLEEP | UNIQUE | FORCE_MAXHP | CAN_FLY | F:COLD_BLOOD | BASH_DOOR | NONLIVING | F:NO_CONF | NO_SLEEP | NO_FEAR | ZANGBAND | HAS_LITE | NO_CUT | NO_STUN D:The mightiest of hellblades, a black runesword which thirsts for D:your soul. N:699:Knight Templar G:p:w I:120:60d20:20:60:10 W:44:2:1800:2000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:5d5 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:IM_POIS | IM_FIRE | IM_ELEC | IM_ACID | IM_COLD | GOOD | F:RES_NETH | RES_NEXU | RES_DISE | RES_TELE | DROP_SKELETON | DROP_CORPSE F:NO_SLEEP | NO_CONF | NO_FEAR | NO_STUN | F:DROP_2D2 | DROP_90 | REFLECTING | F:MALE | OPEN_DOOR | BASH_DOOR | FORCE_MAXHP | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_4 | S:HEAL | CAUSE_3 | CAUSE_4 | HASTE | SCARE | BLIND | S_ANGEL D:It seems that the more devout the person, the more likely they are to cross D:the boundary between piety and sanctimoniousness. And such is the case with D:the Order of the Knights Templar; they are among the most pious and D:powerful of the religious knightly orders, but noted for their intolerance. D:Thus it is Morgoth's will that is unwittingly done, as the forces of good D:are set against each other. N:700:Leprechaun fanatic G:h:r I:123:6d6:8:13:8 W:46:6:800:80 E:1:1:1:2:1:1 O:0:0:0:0 B:EXPLODE:HURT:20d3 F:RAND_25 | TAKE_ITEM | SMART | F:EVIL | OPEN_DOOR | MALE | F:MORTAL | ZANGBAND S:MULTIPLY | S:1_IN_6 | S:BLINK | TPORT | TELE_TO D:These leprechauns are not afraid to die for their cause. They are D:carrying explosives and making terrorist strikes... N:701:Dracolich G:D:G I:120:35d100:25:120:80 W:55:2:180000:18000 E:0:1:0:6:1:0 O:10:50:40:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:EXP_80:7d14 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | RES_TELE | F:COLD_BLOOD | CAN_FLY | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT | ATTR_MULTI S:1_IN_6 | S:CONF | SCARE | S:BR_COLD | BR_NETH D:The skeletal form of a once-great dragon, enchanted by magic most D:perilous. Its animated form strikes with speed and drains life from its D:prey to satisfy its hunger. N:702:Greater titan G:P:o I:120:38d100:30:125:15 W:66:3:50000:23500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:CONFUSE:12d12 B:HIT:CONFUSE:12d12 B:HIT:CONFUSE:12d12 B:HIT:CONFUSE:12d12 F:FORCE_SLEEP | FORCE_MAXHP | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_4D2 | DROP_1D2 | DROP_GOOD | MOVE_BODY | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | MALE | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | TELE_TO | S:S_MONSTERS D:A forty foot tall humanoid that shakes the ground as it walks. The power D:radiating from its frame shakes your courage, its hatred inspired by your D:defiance. N:703:Dracolisk G:D:R I:120:35d100:25:120:80 W:55:2:180000:18000 E:0:1:0:6:1:0 O:0:50:40:10 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:FIRE:7d14 B:GAZE:PARALYZE F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | RES_NEXU | RES_TELE | F:ANIMAL | EVIL | DRAGON | IM_ACID | IM_FIRE | NO_CONF | NO_SLEEP | F:BASEANGBAND | ATTR_MULTI S:1_IN_6 | S:HOLD | SCARE | S:BR_FIRE | BR_NEXU D:A mixture of dragon and basilisk, the dracolisk stares at you with deep D:piercing eyes, its evil breath burning the ground where it stands. N:704:Winged Horror G:B:D I:120:25d80:30:80:5 W:48:3:4500:4000 B:CLAW:HURT:3d8 B:CLAW:HURT:3d8 B:BITE:EXP_40:4d6 B:BITE:EXP_40:4d6 F:ANIMAL | MORTAL | EVIL | CAN_FLY | BASH_DOOR | IM_COLD | IM_POIS F:WILD_TOO | WILD_WASTE | WILD_WOOD | WILD_SWAMP | BASEANGBAND S:1_IN_6 S:BR_NETH | BR_DARK | BR_POIS D:A terrifying sight: a winged creature greater than any bird you have ever D:seen, and with no feathers on its horrid black leathery wings. Descended D:from a creature of an older world perhaps, bred by Sauron to be a winged D:steed for his Ringwraiths. N:705:Spectral tyrannosaur G:R:G I:120:70d50:25:120:30 W:46:3:0:15000 E:0:0:0:0:0:0 O:20:20:20:20 B:BITE:EXP_40:2d13 B:BITE:EXP_40:2d13 B:BITE:LOSE_STR:5d8 B:GAZE:TERRIFY F:FORCE_SLEEP | FORCE_MAXHP | F:EVIL | UNDEAD | ANIMAL | RES_NEXU | RES_TELE F:NO_CONF | NO_FEAR | NO_SLEEP | F:IM_POIS | IM_ACID | IM_COLD | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | ZANGBAND | NO_CUT S:1_IN_6 | S:HOLD | SCARE | S:BR_NEXU | BR_POIS | BR_NETH D:A deadly undead horror which looks like a skeletal tyrannosaur D:surrounded by a sickly green glow. N:706:Yibb-Tstll, the Patient One G:P:D I:120:99d21:20:100:20 W:46:2:0:16000 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:LOSE_ALL:1d166 B:TOUCH:LOSE_ALL:1d166 F:UNIQUE | FORCE_SLEEP | FORCE_MAXHP | F:ELDRITCH_HORROR | NEVER_MOVE | REGENERATE | POWERFUL | F:DROP_2D2 | DROP_4D2 | DROP_GOOD | ONLY_ITEM | F:SMART | IM_FIRE | IM_COLD | IM_ELEC | IM_ACID | IM_POIS | CTHANGBAND S:1_IN_4 | S:BR_NUKE | S_DEMON | DARKNESS | S_UNDEAD | ANIM_DEAD S:BR_NEXU | BR_CHAO D:"There, about the pulsating body of the Ancient One, hugely D:winged reptilian creatures without faces cluttered and clutched D:at a multitude of blackly writhing, pendulous breasts! Its eyes D:moved quickly, independently -- sliding with vile viscosity over D:the whole rotten surface of Yib-Tstll's pulpy, glistening head!" N:707:Ghatanothoa G:v:D I:120:100d20:20:100:20 W:46:2:0:16000 E:0:0:0:0:0:0 O:0:0:100:0 B:CLAW:LOSE_INT:5d10 B:CLAW:LOSE_WIS:5d10 B:BITE:CONFUSE:5d10 F:FORCE_SLEEP | ELDRITCH_HORROR | PASS_WALL | UNIQUE | F:INVISIBLE | DROP_2D2 | DROP_4D2 | CAN_FLY | DROP_GOOD | ONLY_ITEM | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | POWERFUL | NO_CONF | NO_SLEEP | F:SMART | IM_FIRE | IM_COLD | IM_ELEC | IM_ACID | IM_POIS | F:MORTAL | CTHANGBAND | NO_CUT S:1_IN_4 | S:BR_WALL | TELE_AWAY | BR_GRAV | TELE_LEVEL | S_DEMON | S_UNDEAD | S_KIN | S:BRAIN_SMASH | HASTE | BLIND | BLINK | BR_INER | CAUSE_3 | CAUSE_4 D:The chief among the creatures known as Lloigor. Ghatanothoa, unlike most of D:his kind, has assumed a shape, and one which is too horrible to describe: D:"Nothing I could say could even adumbrate the loathsome, unholy, non-human, D:extra-galactic horror and hatefulness and unutterable evil of that forbidden D:spawn of black chaos, and illimitable night." N:708:Ent G:#:G I:110:40d100:30:120:15 W:46:3:0:12500 E:1:1:1:2:1:1 O:30:50:20:0 B:CRUSH:HURT:12d13 B:CRUSH:HURT:12d13 B:CRUSH:HURT:12d13 B:CRUSH:HURT:12d13 F:FORCE_SLEEP | FORCE_MAXHP | PET | SUSCEP_FIRE | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | MOVE_BODY | F:SMART | TAKE_ITEM | KILL_WALL | BASH_DOOR | F:GOOD | BASEANGBAND | NO_CUT D:A tree-herd: a sentient, moving tree. Its wrath is fearsome, and it could D:split stones and even the very rock of Isengard with its roots. N:709:Hru G:P:s I:120:40d100:30:150:15 W:54:3:40000:14500 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:SHATTER:12d13 B:HIT:SHATTER:12d13 B:HIT:SHATTER:12d13 B:HIT:SHATTER:12d13 F:FORCE_SLEEP | FORCE_MAXHP | HURT_ROCK | F:ONLY_GOLD | DROP_4D2 | MOVE_BODY | KILL_WALL | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | GIANT | MALE | HAS_LITE | NO_CUT D:A rock giant, a being made of living stone. N:710:Itangast the Fire Drake G:D:R I:120:22d100:30:120:70 W:47:2:220000:20000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d10 B:CLAW:HURT:4d10 B:BITE:FIRE:4d14 B:BITE:FIRE:4d14 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | DROP_CORPSE F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | SUSCEP_COLD | F:BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | IM_FIRE | BASEANGBAND | HAS_LITE S:1_IN_4 | S:CONF | CAUSE_3 | S:BR_FIRE D:A mighty ancient dragon, Itangast's form scorches your flesh. Wisps of D:smoke curl up from his nostrils as he regards you with disdain. N:711:Death mold G:m:D I:140:100d20:200:60:0 W:47:1:100:1000 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:UN_BONUS:7d7 B:SPORE:UN_BONUS:7d7 B:SPORE:UN_BONUS:7d7 B:SPORE:EXP_80:5d5 F:FORCE_SLEEP | NEVER_MOVE | CAN_SWIM | F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is the epitome of all that is evil, in a mold. Its lifeless form draws D:power from sucking the souls of those that approach it; a nimbus of pure D:evil surrounds it. Luckily for you, it can't move... N:712:Fafner the Dragon G:D:G I:120:25d110:30:130:80 W:48:2:170000:25000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:FIRE:5d14 B:BITE:POISON:5d14 F:UNIQUE | MALE | SUSCEP_COLD | F:FORCE_SLEEP | FORCE_MAXHP | CAN_SPEAK | DROP_CORPSE | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | INVISIBLE | F:EVIL | DRAGON | IM_FIRE | IM_POIS | ZANGBAND | F:HAS_LITE S:1_IN_3 | S:CONF | CAUSE_3 | S:BR_FIRE | BR_POIS | SCARE | CAUSE_3 | CONF D:The mighty dragon of myth, Fafner was a giant who slew his D:brother to win a treasure hoard, and then transformed himself D:into a dragon, greedily watching over his gold. N:713:Charon, Boatman of the Styx G:W:B I:120:28d100:30:100:10 W:47:3:0:25000 E:1:1:1:2:1:1 O:0:0:0:0 B:WAIL:LOSE_ALL B:TOUCH:UN_POWER B:HIT:EXP_80:8d12 B:HIT:EAT_GOLD:8d12 F:UNIQUE | MALE | SMART | CAN_SWIM | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_GOLD | DROP_3D2 | DROP_4D2 | F:COLD_BLOOD | PASS_WALL | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_STUN | NO_CONF | NO_SLEEP | RES_TELE | ZANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | DARKNESS | S:BO_ICEE | BO_NETH | BA_COLD | BA_NETH | BA_WATE | S:S_UNDEAD D:The ferryman across the river Styx to the land of the dead. D:He wishes to receive payment for your entry. N:714:Quickbeam, the Ent G:#:G I:120:40d100:30:120:15 W:47:3:0:13500 E:1:1:1:2:1:1 O:10:50:20:10 B:CRUSH:HURT:12d13 B:CRUSH:HURT:12d13 B:CRUSH:HURT:12d13 B:CRUSH:HURT:12d13 F:FORCE_SLEEP | FORCE_MAXHP | UNIQUE | CAN_SPEAK | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | MOVE_BODY | SUSCEP_FIRE | F:SMART | TAKE_ITEM | KILL_WALL | BASH_DOOR | F:GOOD | PET | BASEANGBAND | NO_CUT D:Unusually hasty, for an ent. Quickbeam hates evil creatures, and orcs in D:particular, since the destruction of his beloved rowan-trees to feed the D:fires of Orthanc. N:715:Glaurung, Father of the Dragons G:D:R I:130:120d100:20:125:70 W:70:2:300000:50000 E:0:1:0:6:1:0 O:30:70:0:0 B:CLAW:HURT:5d12 B:CLAW:HURT:5d12 B:BITE:FIRE:8d14 B:BITE:POISON:8d14 F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | DROP_RANDART F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:SMART | EVIL | DRAGON | IM_POIS | IM_FIRE | F:BASEANGBAND | HAS_LITE S:1_IN_3 | S:BLIND | CONF | SCARE | S:BR_FIRE | BR_POIS | BR_SOUN | S_HI_DRAGON D:Glaurung is the father of all dragons, and was for a long time the most D:powerful. Though this is no longer so, he still has full command over D:his brood and can command them to appear whenever he so wishes. He is D:the definition of dragonfire. N:716:Behemoth G:H:B I:120:50d100:25:180:30 W:49:3:6000:16000 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:FIRE:5d8 B:BITE:FIRE:5d8 B:CRUSH:HURT:3d15 B:CRUSH:HURT:3d15 F:FORCE_SLEEP | FORCE_MAXHP | CAN_SWIM | ANIMAL | AQUATIC | F:IM_FIRE | IM_ACID | IM_COLD | IM_POIS | DROP_CORPSE | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL | BASEANGBAND S:1_IN_9 S:BR_FIRE D:A great water-beast, with an almost impenetrable skin. N:717:Garm, Guardian of Hel G:C:b I:120:30d100:20:120:70 W:49:2:0:25000 E:0:1:0:2:1:0 O:50:50:0:0 B:CLAW:HURT:7d13 B:CLAW:HURT:7d13 B:BITE:HURT:8d13 B:BITE:HURT:8d13 F:UNIQUE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | RES_NETH | F:ANIMAL | EVIL | IM_FIRE | NO_SLEEP | ZANGBAND S:1_IN_3 | S:BR_NETH | BR_COLD | BR_DARK | S:S_HOUND | S_UNDEAD D:Garm is a gigantic hound, whose job is to guard that none escapes D:the tortures of Hel, the place of punishment for the wicked D:and cowardly dead. N:718:Greater wall monster G:#:W I:120:15d40:20:80:20 W:44:4:0:900 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:HIT:HURT:3d6 F:FORCE_SLEEP | COLD_BLOOD | EMPTY_MIND | PASS_WALL | RAND_50 | F:BASH_DOOR | IM_COLD | IM_ACID | IM_FIRE | IM_ELEC | IM_POIS | NONLIVING | F:HURT_ROCK | NO_CONF | NO_SLEEP | CHAR_MULTI | CAN_FLY | BASEANGBAND F:NO_CUT S:MULTIPLY | D:A sentient, moving section of wall. N:719:Nycadaemon G:U:o I:120:29d99:20:80:80 W:51:3:0:10000 E:1:1:1:2:1:1 O:50:0:50:0 B:TOUCH:TERRIFY B:CLAW:HURT:6d6 B:CLAW:HURT:6d6 B:CLAW:HURT:6d6 F:FORCE_SLEEP | FORCE_MAXHP | AURA_FIRE | NONLIVING | F:REGENERATE | IM_ACID | IM_COLD | IM_FIRE | CAN_FLY | F:NO_SLEEP | NO_STUN | NO_CONF | EVIL | DEMON | F:INVISIBLE | KILL_WALL | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | BASEANGBAND S:1_IN_4 | S:HOLD | BLINK | CONF | S_DEMON | BRAIN_SMASH | BR_NETH D:A loathsome, sturdy, winged, horned demon, with talons that could tear D:a stone wall down. N:720:Barbazu G:U:G I:120:120d10:25:60:80 W:55:2:0:3000 E:1:1:1:2:1:1 O:20:40:20:20 B:HIT:HURT:4d10 B:HIT:HURT:4d10 B:HIT:LOSE_CON:10d2 B:STING:POISON:5d5 F:FORCE_SLEEP | FORCE_MAXHP | FRIENDS | F:ONLY_ITEM | DROP_1D2 | NONLIVING | BASEANGBAND | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | DEMON | IM_POIS | NO_CONF | NO_SLEEP S:1_IN_7 | S:SCARE | S_DEMON D:A foul, humanoid creature with a long tail, clawed hands and feet, D:and a disgusting, wiry, snaky beard. They are the elite shock troops D:of the hells, capable of a terrifying berserk fury. N:721:Goat of Mendes G:q:D I:120:18d111:30:66:40 W:50:3:0:6666 E:0:1:0:2:1:0 O:0:0:100:0 B:GAZE:TERRIFY B:BUTT:HURT:6d6 B:BITE:EXP_40 B:BITE:LOSE_CON F:EVIL | DEMON | FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | SMART | NONLIVING | F:NO_CONF | NO_SLEEP | HURT_LITE | IM_FIRE | IM_COLD | ZANGBAND S:1_IN_4 | S:BLIND | CONF | BRAIN_SMASH | SCARE | ANIM_DEAD S:BA_NETH | FORGET | S_UNDEAD | DRAIN_MANA | S:S_DEMON | CAUSE_4 | BA_COLD D:It is a demonic creature from the lowest hell, vaguely resembling a D:large black he-goat. N:722:Nightwing G:W:D I:120:60d60:20:120:10 W:61:4:0:10000 E:1:1:1:2:1:1 O:0:0:100:0 B:TOUCH:POISON:6d5 B:TOUCH:POISON:6d5 B:HIT:UN_BONUS:6d8 B:HIT:UN_BONUS:6d8 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | RES_TELE | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_4 | S:BLIND | SCARE | CAUSE_4 | BRAIN_SMASH | S:BO_MANA | BO_NETH | BA_NETH | S_UNDEAD D:Everywhere colours seem paler and the air chiller. At the centre of the D:cold stands a mighty figure. Its wings envelop you in the chill of death D:as the nightwing reaches out to draw you into oblivion. Your muscles sag D:and your mind loses all will to fight as you stand in awe of this mighty D:being. N:723:Maulotaur G:H:s I:130:250d13:13:50:10 W:50:2:40000:4500 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:SHATTER:8d8 B:HIT:SHATTER:8d8 B:BUTT:HURT:4d6 B:BUTT:HURT:4d6 F:ONLY_ITEM | DROP_60 | DROP_GOOD | RES_TELE | F:BASH_DOOR | STUPID | DROP_CORPSE | F:EVIL | IM_FIRE | FORCE_SLEEP | FORCE_MAXHP | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BO_PLAS | BA_FIRE D:It is a belligerent minotaur with a destructive magical arsenal, armed D:with a hammer. N:724:Nether hound G:Z:G I:120:60d10:30:100:0 W:51:2:800:5000 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d12 B:CLAW:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 F:FORCE_SLEEP | F:FRIENDS | RES_NETH | DROP_SKELETON | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:ANIMAL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | NO_CUT S:1_IN_5 | S:BR_NETH D:You feel a soul-tearing chill upon viewing this beast, a ghostly form of D:darkness in the shape of a large dog. N:725:Time hound G:Z:B I:130:60d10:30:100:0 W:51:2:800:5000 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d12 B:CLAW:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 F:FORCE_SLEEP | F:FRIENDS | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BR_TIME D:You get a terrible sense of deja vu, or is it a premonition? All at once D:you see a little puppy and a toothless old dog. Perhaps you should give D:up and go to bed. N:726:Plasma hound G:Z:R I:120:60d10:30:100:0 W:51:2:800:5000 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:HURT:2d12 B:CLAW:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 F:FORCE_SLEEP | SUSCEP_COLD | F:FRIENDS | RES_PLAS | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | IM_FIRE | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_5 | S:BR_PLAS D:The very air warps as pure elemental energy stalks towards you in the D:shape of a giant hound. Your hair stands on end and your palms itch as D:you sense trouble. N:727:Demonic quylthulg G:Q:r I:120:48d10:20:1:0 W:45:1:3000:3000 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | ANIMAL | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_2 | S:BLINK | TPORT | S:S_DEMON D:A pile of pulsing flesh that glows with an inner hellish fire. The world D:itself seems to cry out against it. N:728:Great Storm Wyrm G:D:b I:120:40d100:30:150:80 W:63:2:190000:20000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:ELEC:6d14 B:BITE:ELEC:6d14 F:FORCE_SLEEP | FORCE_MAXHP | AURA_ELEC | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | DROP_CORPSE | F:EVIL | DRAGON | IM_ELEC | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_ELEC D:A vast dragon of power. Storms and lightning crash around its titanic D:form. Deep blue scales reflect the flashes and highlight the creature's D:great muscles. It regards you with contempt. N:729:Ulik the Troll G:T:v I:130:35d100:30:120:30 W:51:4:16000:18000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:SHATTER:20d12 B:HIT:SHATTER:20d12 B:BITE:POISON:6d14 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | SPECIAL_GENE | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:DROP_90 | REGENERATE | KILL_WALL | RES_TELE | KILL_BODY | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:EVIL | TROLL | IM_POIS | F:IM_ELEC | IM_COLD | IM_FIRE | BASEANGBAND D:Ulik is the strongest troll who has ever lived. He could challenge D:the immortals and pound them to dust with his great strength. N:730:Baphomet the Minotaur Lord G:H:v I:130:35d100:30:120:30 W:58:4:16000:18000 E:1:1:1:2:1:1 O:0:80:20:0 B:BUTT:HURT:12d13 B:BUTT:HURT:12d13 B:HIT:HURT:10d10 B:HIT:HURT:10d10 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | DROP_CORPSE | F:EVIL | IM_FIRE | IM_POIS | F:MORTAL | BASEANGBAND S:1_IN_6 | S:SLOW | ARROW_4 | BO_MANA | BO_PLAS | BA_ELEC | S:BR_WALL D:A fearsome bull-headed monster, Baphomet swings a mighty axe as he curses D:all that defy him. N:731:Hell knight G:p:D I:120:15d100:20:100:10 W:52:1:2200:10000 E:1:1:1:2:1:1 O:0:40:60:0 B:HIT:HURT:10d5 B:HIT:HURT:10d5 B:HIT:EXP_80:10d5 B:HIT:EXP_80:10d5 F:FORCE_SLEEP | FORCE_MAXHP | SMART | IM_FIRE | IM_COLD | IM_POIS | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | RES_NETH | RES_NEXU | RES_PLAS | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_COLD | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_5 | S:BLIND | SCARE | CAUSE_3 | BA_NETH | BA_FIRE | BO_PLAS S:S_MONSTERS | S_DEMON D:It is a humanoid form dressed in armour of ancient style. From beneath D:its helmet, eyes glow with hellfire. N:732:Bull Gates G:p:D I:140:25d100:40:90:0 W:52:3:1600:20000 E:1:1:1:2:1:1 O:50:50:0:0 B:CHARGE:EAT_GOLD:5d5 B:CHARGE:EAT_ITEM:5d5 B:SPIT:BLIND:10d5 B:DROOL:DISEASE:8d5 F:UNIQUE | MALE | CAN_SPEAK | DROP_SKELETON | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:IM_POIS | EVIL | RES_TELE F:MORTAL | JOKEANGBAND | HAS_LITE S:1_IN_6 | S:TRAPS | S_BUG D:He may not code worth a dime, but he certainly knows how to make money. N:733:Santa Claus G:h:r I:150:25d100:90:100:10 W:52:3:2600:45000 E:1:1:1:2:1:1 O:20:20:20:20 B:HIT:LOSE_CHR:5d5 B:TOUCH:LOSE_ALL:10d1 B:TOUCH:LOSE_ALL:10d1 B:CHARGE:EAT_GOLD F:UNIQUE | MALE | CAN_SPEAK | REFLECTING | DROP_SKELETON | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:NO_STUN | NO_SLEEP | F:IM_ELEC | IM_FIRE | IM_POIS | IM_COLD | F:COLD_BLOOD | RES_TELE | JOKEANGBAND | HAS_LITE S:1_IN_3 | S:CAUSE_4 | HOLD | DRAIN_MANA | SCARE | BLIND | S:S_UNDEAD | S_HI_UNDEAD | S_HI_DRAGON | S_UNIQUE | S:BA_NETH | FORGET | TRAPS | BRAIN_SMASH | TELE_AWAY D:Why would anybody want to kill Santa Claus? To get all the presents, D:of course! N:734:Eihort, the Thing in the Labyrinth G:j:R I:120:33d100:50:90:10 W:53:3:0:45000 E:0:0:0:0:0:0 O:0:0:100:0 B:BITE:PARALYZE:8d1 B:CRUSH:HURT:10d10 B:CRUSH:HURT:10d10 B:CRUSH:HURT:10d10 F:UNIQUE | CAN_SPEAK | ESCORT | REGENERATE | F:FORCE_SLEEP | FORCE_MAXHP | ELDRITCH_HORROR | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_SLEEP | RES_TELE | CTHANGBAND | NO_CUT S:1_IN_4 | S:S_UNDEAD | S_DEMON | S_MONSTER | BLINK | BA_ACID | FORGET D:"Then came pale movement in the well, and something clambered D:up from the dark, a bloated blanched oval supported on myriad D:fleshless legs. Eyes formed in the gelatinous oval and stared D:at him." N:735:The King in Yellow G:L:y I:120:32d100:90:100:10 W:53:3:0:50000 E:0:0:0:0:0:0 O:50:0:40:10 B:CRUSH:HURT:12d12 B:CRUSH:HURT:12d12 B:GAZE:LOSE_WIS:5d10 B:GAZE:TERRIFY:5d10 F:UNIQUE | MALE | CAN_SPEAK | ATTR_MULTI | ATTR_ANY | F:FORCE_SLEEP | FORCE_MAXHP | CTHANGBAND | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_ACID | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | RES_TELE | NO_CUT S:1_IN_2 | S:S_DEMON | S_UNDEAD | S_KIN | SCARE | CAUSE_3 | CAUSE_4 | ANIM_DEAD S:TELE_AWAY | TPORT | BRAIN_SMASH | CONF D:The King in Yellow is an Avatar of Hastur: "He has no D:face, and is twice as tall as a man. He wears pointed shoes under D:his tattered, fantastically colored robes, and a streamer of silk D:appears to fall from the pointed tip of his hood. At times he appears D:to be winged; at others, haloed." N:736:Great unclean one G:U:g I:120:80d80:30:150:20 W:53:3:0:17500 E:0:0:0:0:0:0 O:50:0:50:0 B:BITE:DISEASE:10d10 B:BITE:ACID:10d10 B:BITE:POISON:10d10 B:BITE:CONFUSE:10d10 F:DEMON | EVIL | NONLIVING | CAN_SWIM | F:FORCE_SLEEP | FORCE_MAXHP | ONLY_ITEM | DROP_2D2 | ELDRITCH_HORROR | F:OPEN_DOOR | BASH_DOOR | SMART | POWERFUL | DROP_GOOD | KILL_BODY | F:IM_ACID | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP F:KILL_ITEM | ZANGBAND S:1_IN_3 S:BR_ACID | BR_POIS | BR_NUKE | SCARE | ANIM_DEAD S:CAUSE_3 | CAUSE_4 | S_DEMON | S_UNDEAD D:This disgusting demon resembles a shambling pile of rotting D:green flesh, with dozens of mouths drooling and leaving a D:trail of foul-smelling goo behind. Nurgle must be D:proud of himself to have created this atrocity! N:737:Lord of Chaos G:p:v I:130:45d55:30:80:5 W:60:3:0:17500 E:1:1:1:2:1:1 O:0:0:100:0 B:KICK:HURT:20d2 B:KICK:HURT:10d2 B:HIT:POISON:20d1 B:HIT:LOSE_ALL:15d1 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_SKELETON | F:ONLY_ITEM | DROP_4D2 | ATTR_MULTI | EVIL | SHAPECHANGER | ATTR_ANY | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | SMART | POWERFUL | EVIL | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | F:ZANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | MIND_BLAST | BA_CHAO | S:S_SPIDER | S_HOUND | S_DEMON D:He is one of the few true masters of the art, being extremely skillful in D:all forms of unarmed combat and controlling the Chaos D:with disdainful ease. N:738:Old Sorcerer G:p:R I:130:52d25:20:60:10 W:54:2:0:5000:0 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:6d8 B:HIT:HURT:6d8 B:HIT:HURT:6d8 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | F:OPEN_DOOR | BASH_DOOR | TAKE_ITEM | F:EVIL | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_2 | S:BLINK | TELE_TO | BLIND | CONF | CAUSE_3 | CAUSE_4 | TRAPS | S:BO_ACID | BA_FIRE | BA_COLD | BA_POIS | S:S_MONSTER | S_DEMON | S_HI_DRAGON | S_UNDEAD D:A human figure in robes, he moves with magically improved speed, and his D:hands are ablur with spell casting. You stagger at the mighty sound of his D:spells as they echo hollowly through the dungeon. N:739:Ethereal hound G:Z:G I:120:60d15:30:100:0 W:55:3:900:6000 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:CLAW:HURT:2d12 F:FORCE_SLEEP | FRIENDS | F:INVISIBLE | PASS_WALL | F:ANIMAL | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BR_NETH D:A pale green hound. Pulsing red lines and strange fluorescent light D:hint at internal organs best left to the imagination. N:740:Lesser kraken G:~:G I:120:30d100:30:150:80 W:54:2:8000:20000 E:3:0:3:0:1:0 O:25:25:50:0 B:CRUSH:HURT:16d12 B:CRUSH:HURT:16d12 B:CRUSH:HURT:16d12 B:CRUSH:HURT:16d12 F:FORCE_SLEEP | FORCE_MAXHP | AQUATIC | WILD_TOO | WILD_OCEAN | F:ONLY_ITEM | DROP_3D2 | DROP_GOOD | DROP_CORPSE | F:BASH_DOOR | POWERFUL | MOVE_BODY | SMART | RES_WATE | F:EVIL | IM_ELEC | NO_CONF | NO_SLEEP | IM_POIS | IM_FIRE | BASEANGBAND S:1_IN_4 | S:BLIND | CONF | SCARE | CAUSE_4 | CAUSE_3 | S:BA_WATE | DARKNESS | BR_DARK | TELE_TO D:An enormously fearsome and powerful inhabitant of the depths. It D:resembles a gargantuan octopus and its evil is almost tangible. N:741:Great Ice Wyrm G:D:w I:120:40d100:30:150:80 W:63:2:190000:20000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:COLD:6d14 B:BITE:COLD:6d14 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | AURA_COLD | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | SUSCEP_FIRE | F:BASH_DOOR | POWERFUL | MOVE_BODY | DROP_CORPSE F:EVIL | DRAGON | IM_COLD | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_COLD D:An immense dragon capable of awesome destruction. You have never felt D:such extreme cold, or witnessed such an icy stare. Begone quickly or feel D:its wrath! N:742:Demilich G:L:U I:120:35d100:20:100:50 W:54:2:3000:12500 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:EXP_80 B:TOUCH:UN_POWER B:TOUCH:LOSE_DEX:4d12 B:TOUCH:LOSE_DEX:4d12 F:FORCE_SLEEP | FORCE_MAXHP | SMART | RES_TELE | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_3 | S:BLINK | TELE_TO | BLIND | HOLD | CONF | SCARE | CAUSE_3 | CAUSE_4 | S:DRAIN_MANA | BRAIN_SMASH | S_HI_UNDEAD | S_UNDEAD | FORGET | S_DEMON | S:TPORT | HEAL | ANIM_DEAD D:A lich who is partially immaterial, on its way to a new, ethereal form. N:743:The Phoenix G:B:r I:120:36d100:60:130:0 W:54:3:6000:40000 E:0:1:1:0:1:0 O:0:50:50:0 B:BITE:FIRE:12d6 B:BITE:FIRE:12d6 B:HIT:FIRE:9d12 B:HIT:FIRE:9d12 F:UNIQUE | CAN_SPEAK | RES_PLAS | AURA_FIRE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | SUSCEP_COLD | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:ANIMAL | IM_ACID | IM_FIRE | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP F:BASEANGBAND | HAS_LITE | REGENERATE S:1_IN_3 | S:BO_FIRE | BO_PLAS | BA_FIRE | S:BR_FIRE | BR_LITE | BR_PLAS D:A massive glowing eagle bathed in flames. The searing heat chars your D:skin and melts your armour. N:744:Nightcrawler G:W:D I:120:80d60:20:160:10 W:69:3:10000:1500 E:0:0:0:0:1:0 O:40:0:50:10 B:STING:LOSE_CON:8d8 B:STING:LOSE_CON:8d8 B:BITE:ACID:10d10 B:BITE:ACID:10d10 F:FORCE_SLEEP | SMART | KILL_WALL | CAN_SWIM | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_POIS | RES_TELE | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_4 | S:BLIND | SCARE | BRAIN_SMASH | S:BO_MANA | BO_NETH | BA_NETH | BR_NETH | S_UNDEAD D:This intensely evil creature bears the form of a gargantuan black worm. D:Its gaping maw is a void of blackness, and acid drips from its steely hide. D:It is like nothing you have ever seen before, and a terrible chill runs D:down your spine as you face it. N:745:Lord of Change G:U:v I:130:50d70:30:150:20 W:54:3:0:17000 E:0:1:1:0:1:0 O:0:0:100:0 B:CLAW:CONFUSE:10d10 B:CLAW:CONFUSE:10d10 B:BITE:BLIND:12d12 F:DEMON | EVIL | ATTR_MULTI | DROP_GOOD | MOVE_BODY | NONLIVING | F:FORCE_SLEEP | FORCE_MAXHP | ONLY_ITEM | DROP_2D2 | ELDRITCH_HORROR | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | SMART | POWERFUL | CAN_FLY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | F:ZANGBAND S:1_IN_3 S:MIND_BLAST | BA_CHAO | SCARE | BRAIN_SMASH | DRAIN_MANA | S:S_HOUND | S_DEMON | S_DRAGON | TPORT | HASTE | CONF | SCARE | S:TELE_AWAY | FORGET D:The most powerful of Tzeentch's servitors. This demon looks like D:a huge bird-creature, with the head of a predatory bird and D:fantastically multi-coloured wings. N:746:Keeper of Secrets G:H:G I:130:60d70:30:150:20 W:54:3:0:17000 E:2:0:2:2:1:1 O:0:0:100:0 B:HIT:CONFUSE:10d10 B:HIT:TERRIFY:10d10 B:HIT:BLIND:10d10 B:HIT:TERRIFY:10d10 F:DEMON | EVIL | DROP_GOOD | NONLIVING | CAN_SWIM | F:FORCE_SLEEP | FORCE_MAXHP | ONLY_ITEM | DROP_2D2 | ELDRITCH_HORROR | F:OPEN_DOOR | BASH_DOOR | SMART | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | ZANGBAND S:1_IN_3 S:SCARE | BRAIN_SMASH | DRAIN_MANA | S:BR_CONF | S_DEMON | S_UNDEAD | TPORT | HEAL | S:TELE_AWAY D:This demonic keeper of forbidden secrets looks like a hairless D:minotaur with extra arms, decorated with tattoos and nose rings. D:It is the embodiment of Slaanesh's perverted magic. N:747:Shudde M'ell G:w:s I:125:100d40:20:90:20 W:59:2:0:23000 E:0:0:0:0:0:0 O:0:0:0:0 B:CRUSH:SHATTER:55d2 B:CRUSH:SHATTER:55d2 B:TOUCH:LOSE_CON:1d2 B:TOUCH:LOSE_CON:1d2 F:IM_FIRE | RES_PLAS | IM_COLD | IM_POIS | ELDRITCH_HORROR | RES_TELE | F:KILL_WALL | ONLY_GOLD | DROP_4D2 | DROP_2D2 | CAN_SWIM | F:EVIL | FORCE_MAXHP | SMART | UNIQUE | CTHANGBAND | NO_STUN S:1_IN_5 | S:SCARE | CONF | HOLD | S_DEMON | S_KIN | S:HEAL | HASTE | FORGET | BRAIN_SMASH | S:BR_DARK | BR_ACID | BR_DISE D:The most powerful and most evil of all Chthonians. D:"A great gray thing a mile long chanting and exuding strange acids... D:charging through the depths of the earth at a fantastic speed, in a D:dreadful fury... melting basaltic rocks like butter under a blowtorch." N:748:Hand druj G:s:y I:130:60d10:20:110:10 W:57:2:10:18000 E:0:0:0:1:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | RES_TELE | F:SMART | COLD_BLOOD | CAN_SWIM | F:EVIL | UNDEAD | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_1 | S:TELE_AWAY | BLIND | CONF | SCARE | CAUSE_3 | FORGET | DARKNESS | S:BO_FIRE | BO_ACID | BO_COLD | BO_ELEC D:A skeletal hand floating in the air, motionless except for its flexing D:fingers. N:749:Eye druj G:s:r I:130:10d100:20:90:10 W:58:2:2:21000 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | RES_TELE | F:SMART | COLD_BLOOD | F:EVIL | UNDEAD | CAN_SWIM | F:IM_FIRE | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_1 | S:BO_MANA | BO_NETH | BA_NETH | BRAIN_SMASH | S_UNDEAD D:A bloodshot eyeball floating in the air, you'd be forgiven for assuming it D:harmless. N:750:Skull druj G:s:o I:130:14d100:20:120:10 W:59:2:1000:24000 E:0:0:0:0:1:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | RES_TELE | F:SMART | COLD_BLOOD | F:EVIL | UNDEAD | CAN_SWIM | F:IM_FIRE | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_1 | S:SLOW | CAUSE_4 | MIND_BLAST | BRAIN_SMASH | TRAPS | BO_PLAS | S:BO_NETH | BA_WATE | S_UNDEAD D:A glowing skull possessed by sorcerous power. It need not move, but D:merely blast you with mighty magic. N:751:Chaos vortex G:v:v I:140:32d20:100:80:0 W:53:1:0:4000 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:CONFUSE:5d5 B:ENGULF:CONFUSE:5d5 B:ENGULF:HURT:5d5 B:ENGULF:HURT:5d5 F:ATTR_MULTI | ATTR_ANY | FORCE_SLEEP | F:RAND_50 | RAND_25 | CAN_FLY | F:EMPTY_MIND | BASH_DOOR | POWERFUL | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_6 | S:BR_CHAO D:Void, nothingness, spinning destructively. N:752:Aether vortex G:v:v I:130:40d20:100:40:0 W:54:2:0:5000 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:ELEC:5d5 B:ENGULF:FIRE:5d5 B:ENGULF:ACID:5d5 B:ENGULF:COLD:5d5 F:ATTR_MULTI | ATTR_ANY | FORCE_SLEEP | CAN_FLY | F:RAND_50 | RAND_25 | AURA_COLD | RES_WATE | RES_DISE | F:EMPTY_MIND | BASH_DOOR | POWERFUL | RES_NETH | RES_NEXU | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | AURA_FIRE | AURA_ELEC | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | RES_PLAS | BASEANGBAND | NO_CUT S:1_IN_6 | S:BR_ACID | BR_FIRE | BR_COLD | BR_ELEC | BR_POIS | BR_LITE | S:BR_DARK | BR_SOUN | BR_CONF | BR_CHAO | BR_SHAR | BR_NETH | S:BR_WALL | BR_INER | BR_TIME | BR_GRAV | BR_PLAS | BR_NEXU D:An awesome vortex of pure magic, power radiates from its frame. N:753:Nidhogg, the Hel-Drake G:D:D I:120:39d111:20:133:70 W:55:2:260000:25000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:LOSE_CON:8d12 B:CLAW:LOSE_CON:8d12 B:BITE:EXP_80:8d15 B:BITE:EXP_80:8d15 F:UNIQUE | CAN_FLY | RES_NETH | F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | IM_POIS | F:BASH_DOOR | POWERFUL | MOVE_BODY | CAN_SPEAK | IM_ACID | F:EVIL | DRAGON | IM_FIRE | NO_SLEEP | IM_COLD | ZANGBAND | F:HAS_LITE S:1_IN_5 | S:CAUSE_3 | BR_NETH | BR_COLD | S:BR_ACID | BR_POIS | S:S_DRAGON | S_UNDEAD D:In the bowels of Hel, the dread Nidhogg, a dragon blacker than the D:night, feasts on the essences of the dead. N:754:The Lernaean Hydra G:M:v I:120:45d100:20:140:20 W:55:2:13000:20000 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:POISON:8d6 B:BITE:POISON:8d6 B:BITE:FIRE:12d6 B:BITE:FIRE:12d6 F:UNIQUE | SUSCEP_COLD | F:FORCE_SLEEP | FORCE_MAXHP | SMART | DROP_CORPSE | F:ONLY_GOLD | DROP_3D2 | DROP_4D2 | WILD_TOO | WILD_SHORE | WILD_SWAMP | F:OPEN_DOOR | BASH_DOOR | KILL_BODY | POWERFUL | REGENERATE | F:ANIMAL | IM_FIRE | IM_POIS | F:NO_CONF | NO_STUN | CAN_SWIM | F:MORTAL | BASEANGBAND S:1_IN_3 | S:SCARE | S:BO_FIRE | BO_PLAS | BA_FIRE | BA_POIS | S:BR_FIRE | BR_POIS | S_HYDRA | S_KIN D:A massive legendary hydra. It has twelve powerful heads. Its many eyes D:stare at you as clouds of smoke and poisonous vapour rise from its D:seething form. It grows new heads as fast as you chop them off. N:755:Thuringwethil, the Vampire Messenger G:V:v I:130:50d100:20:145:10 W:67:3:1500:23000 E:1:1:1:2:1:1 O:0:50:50:0 B:BITE:EXP_80:6d6 B:BITE:EXP_80:6d6 B:HIT:CONFUSE:6d6 B:HIT:CONFUSE:6d6 F:UNIQUE | FEMALE | SPECIAL_GENE | F:FORCE_SLEEP | FORCE_MAXHP | SMART | CAN_SPEAK | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | NO_STUN F:RES_TELE | BASEANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | DRAIN_MANA | S:BRAIN_SMASH | BA_NETH | S_KIN | S_HI_UNDEAD D:Chief messenger between Sauron and Morgoth, she is the most deadly of her D:vampire race on Middle-earth. At first she is charming to meet, but her D:wings and eyes give away her true form. N:756:Great Hell Wyrm G:D:r I:120:50d100:30:150:80 W:67:2:190000:23000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:FIRE:6d14 B:BITE:FIRE:6d14 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | SUSCEP_COLD | F:BASH_DOOR | POWERFUL | MOVE_BODY | AURA_FIRE | F:EVIL | DRAGON | IM_FIRE | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_FIRE D:A vast dragon of immense power. Fire leaps continuously from its huge D:form. The air around it scalds you. Its slightest glance burns you, and D:you realise how truly insignificant you are. N:757:Hastur the Unspeakable G:H:b I:120:55d95:20:150:10 W:55:4:0:23000 E:2:0:2:4:1:0 O:25:25:25:10 B:CRUSH:HURT:14d8 B:CRUSH:HURT:14d8 B:BITE:EXP_80:6d6 B:BITE:EXP_80:6d6 F:UNIQUE | ELDRITCH_HORROR | CAN_SWIM | F:FORCE_SLEEP | FORCE_MAXHP | SMART | CAN_SPEAK | AURA_ELEC | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | POWERFUL | SMART | NONLIVING | F:EVIL | DEMON | IM_COLD | IM_POIS | HURT_LITE | NO_SLEEP | F:RES_TELE | CTHANGBAND S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_4 | DRAIN_MANA | S:BRAIN_SMASH | BA_WATE | S_DEMON | HASTE | S:TPORT | TELE_AWAY | TELE_TO | HEAL | BR_DARK | BR_NETH D:His form is partially that of a reptile, partially that of a gigantic D:octopus. He will destroy you. N:758:Bloodthirster G:U:r I:130:60d70:30:180:20 W:55:3:0:18500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:50d1 B:HIT:HURT:50d1 B:HIT:HURT:50d1 F:DEMON | EVIL | DROP_GOOD | REGENERATE | CAN_FLY | NONLIVING | F:FORCE_SLEEP | FORCE_MAXHP | ONLY_ITEM | DROP_4D2 | ELDRITCH_HORROR | F:OPEN_DOOR | BASH_DOOR | RES_NETH | RES_NEXU | RES_TELE | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | NO_FEAR F:CAN_FLY | ZANGBAND | HAS_LITE D:Khorne's mightiest servant, a winged hound-demon walking on D:two paws and wielding a mighty axe and a whip in the other D:two. Intelligent, bloodthirsty eyes leer at you from inside D:the blood-soaked demon armour. N:759:Draconic quylthulg G:Q:g I:120:48d10:20:1:0 W:45:1:3000:3000 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | ANIMAL | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_2 | S:BLINK | TPORT | S:S_DRAGON D:It looks like it was once a dragon corpse, now deeply infected with D:magical bacteria that make it pulse in a foul and degrading way. N:760:Nyogtha, the Thing that Should not Be G:j:D I:130:55d99:20:120:20 W:56:2:0:20000 E:0:0:0:0:0:0 O:50:0:40:10 B:CRUSH:ACID:10d6 B:CRUSH:ACID:10d6 B:CRUSH:ACID:10d6 B:CRUSH:HURT:16d16 F:UNIQUE | ELDRITCH_HORROR | F:FORCE_SLEEP | FORCE_MAXHP | CAN_SPEAK | SMART | CAN_SWIM | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:REGENERATE | ONLY_ITEM | KILL_ITEM | DROP_2D2 | DROP_90 | DROP_60 | F:BASH_DOOR | EVIL | NO_CONF | NO_SLEEP | KILL_BODY | F:FORCE_MAXHP | FORCE_SLEEP | HURT_LITE | POWERFUL | RES_NETH | NONLIVING | F:IM_ACID | IM_FIRE | RES_PLAS | IM_POIS | IM_COLD | IM_ELEC | RES_TELE F:CTHANGBAND | NO_CUT S:1_IN_5 | S:BRAIN_SMASH | MIND_BLAST | HASTE | TPORT | S:S_DEMON | S_UNDEAD | S_HI_UNDEAD | S_KIN | S:BR_DARK | BR_NUKE | BR_ACID | BR_POIS D:"...a little finger of blackness crept out from beneath its edge D:a great wave of iridescent blackness, neither liquid nor solid, D:a frightful gelatinous mass." N:761:Ahtu, Avatar of Nyarlathotep G:#:D I:130:50d110:30:120:15 W:56:3:0:22500 E:1:1:1:2:1:1 O:0:30:60:10 B:CRUSH:HURT:13d13 B:CRUSH:FIRE:10d10 B:CRUSH:HURT:13d13 B:CRUSH:FIRE:10d10 F:FORCE_SLEEP | FORCE_MAXHP | UNIQUE | CAN_SPEAK | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | MOVE_BODY | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | DEMON | NONLIVING | ELDRITCH_HORROR | CTHANGBAND | NO_CUT | NO_SLEEP | NO_CONF | NO_STUN S:1_IN_6 S:BR_FIRE | S_DEMON | CAUSE_4 | BR_PLAS | BR_NETH | BRAIN_SMASH | S:S_UNDEAD | BA_DARK D:"Higher already than the giants of the forest ringing it, the D:fifty-foot-thick column... sprouted a ring of tendrils, ruddy and D:golden and glittering overall with inclusions of quartz." N:762:Fundin Bluecloak G:h:B I:130:50d100:25:195:10 W:56:2:1400:20000 E:1:1:1:2:1:1 O:0:80:20:0 B:HIT:HURT:10d10 B:HIT:HURT:8d6 B:HIT:HURT:8d6 B:HIT:HURT:8d6 F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | PET | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_4 | S:HEAL | BLIND | CONF | SCARE | CAUSE_3 | CAUSE_4 | BRAIN_SMASH | S:FORGET | S_MONSTERS | S_ANIMALS D:He is one of the greatest dwarven priests to walk the earth. Fundin has D:earned a high position in the church, and his skill with both weapon and D:spell only justify his position further. His combination of both dwarven D:strength and priestly wisdom are a true match for any adventurer. N:763:Bile Demon G:U:R I:120:35d100:40:90:80 W:61:2:0:12000 E:1:0:1:2:1:0 O:30:70:0:0 B:HIT:HURT:8d8 B:HIT:HURT:8d8 B:CRUSH:ACID:9d9 B:CRUSH:ACID:9d9 F:FORCE_SLEEP | FORCE_MAXHP | BASEANGBAND | F:ONLY_ITEM | DROP_3D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | NONLIVING | F:EVIL | DEMON | IM_POIS | IM_ACID | NO_CONF | NO_SLEEP S:1_IN_6 | S:BR_POIS | BR_ACID | S_DEMON | BLIND | CONF | ARROW_4 D:It's big. It's fat. It's red. It's ugly. It's got a severe attack of D:highly poisonous flatulence. And its insides are corrosive. All of which D:go together to make the single most repulsive sight - and smell - you have D:ever experienced. N:764:Uriel, Angel of Fire G:A:R I:130:55d100:40:160:10 W:61:3:3400:25000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:FIRE:4d12 B:HIT:FIRE:4d12 B:HIT:HURT:10d10 B:HIT:HURT:10d10 F:UNIQUE | MALE | CAN_SPEAK | NO_FEAR | GOOD | AURA_FIRE | REFLECTING | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | SUSCEP_COLD | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | NO_SLEEP F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_ELEC | IM_POIS | RES_TELE | BASEANGBAND | HAS_LITE S:1_IN_2 | S:TELE_TO | BLIND | S:BO_FIRE | BO_MANA | BA_FIRE | S:BR_FIRE | BR_PLAS | S:S_ANGEL D:A creature of godly appearance. You dare not challenge Uriel's supremacy. D:Those who stood against him before are but a memory, cremated by his D:mastery of elemental fire. N:765:Azriel, Angel of Death G:A:D I:130:60d100:40:170:10 W:62:3:3400:30000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:EXP_80:10d5 B:HIT:EXP_80:10d5 B:HIT:HURT:10d10 B:HIT:HURT:10d10 F:UNIQUE | MALE | CAN_SPEAK | RES_NETH | NO_FEAR | GOOD | F:FORCE_SLEEP | FORCE_MAXHP | SMART | REFLECTING | AURA_COLD | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | CAN_FLY | NO_SLEEP F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | RES_TELE | BASEANGBAND F:HAS_LITE S:1_IN_2 | S:TELE_TO | BLIND | S:BO_MANA | BO_NETH | BA_NETH | S:BR_NETH | S:S_ANGEL D:Azriel commands awesome power, his visage holy enough to shrivel your D:soul. You shriek with disbelief as his mastery of death draws you to your D:grave. It is truly beyond all but the mightiest of warriors to stand D:against him and live. N:766:Ancalagon the Black G:D:D I:140:180d100:40:170:70 W:90:1:330000:60000 E:0:1:0:6:1:0 O:60:40:0:0 B:CLAW:HURT:10d12 B:CLAW:HURT:10d12 B:BITE:HURT:10d14 B:BITE:HURT:10d14 F:UNIQUE | MALE | CAN_FLY | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | F:BASEANGBAND | HAS_LITE S:1_IN_3 | S:BR_ACID | BR_FIRE | BR_DISI | BR_WALL | BR_TIME | S:S_HI_DRAGON | S_KIN D:"Rushing Jaws" is his name, and death is his game; the greatest and most D:terrible of all dragonkind, his power dismayed even the Valar for a time. N:767:Daoloth, the Render of the Veils G:U:s I:120:72d100:20:125:70 W:58:3:0:27500 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:CONFUSE:5d12 B:TOUCH:CONFUSE:5d12 B:TOUCH:CONFUSE:5d12 B:TOUCH:CONFUSE:5d12 F:UNIQUE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:IM_ACID | IM_FIRE | IM_POIS | IM_COLD | ELDRITCH_HORROR | F:NEVER_MOVE | RES_NEXU | REFLECTING | PASS_WALL F:NO_CONF | NO_SLEEP | NO_CUT | NO_STUN | NO_FEAR | CTHANGBAND S:1_IN_3 | S:TELE_AWAY | S_MONSTERS | TELE_LEVEL | BR_NEXU | TPORT | BLINK D:"Not shapeless, but so complex that the eye could recognise no D:describable shape. There were hemispheres and shining metal, D:coupled by long plastic rods. The rods were of a flat gray color, D:so that he could not make out which were nearer; they merged into D:a flat mass from which protruded individual cylinders. As he looked D:at it, he had a curious feeling that eyes gleamed from between D:these rods; but wherever he glanced at the construction, he saw D:only the spaces between them." N:768:Nightwalker G:W:D I:130:80d70:20:175:10 W:73:3:75000:20000 E:1:1:1:2:1:1 O:30:0:70:0 B:HIT:UN_BONUS:10d10 B:HIT:UN_BONUS:10d10 B:HIT:UN_BONUS:7d7 B:HIT:UN_BONUS:7d7 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | CAN_SWIM | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | RES_TELE | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_4 | S:BLIND | SCARE | BRAIN_SMASH | S:BO_MANA | BO_NETH | BA_NETH | S_UNDEAD D:A huge giant garbed in black, more massive than a titan and stronger than D:a dragon. With terrible blows, it breaks your armour from your back, D:leaving you defenceless against its evil wrath. It can smell your fear, D:and you in turn smell the awful stench of death as this ghastly figure D:strides towards you menacingly. N:769:Gabriel, the Messenger G:A:w I:130:75d100:40:180:10 W:64:3:3500:35000 E:1:1:1:2:1:1 O:0:40:60:0 B:HIT:UN_BONUS:6d8 B:HIT:FIRE:6d8 B:HIT:BLIND:10d10 B:HIT:BLIND:10d10 F:UNIQUE | MALE | FORCE_MAXHP | CAN_SPEAK | NO_SLEEP | GOOD | F:FORCE_SLEEP | FORCE_MAXHP | SMART | AURA_ELEC | REFLECTING | RES_TELE F:ESCORT | CAN_FLY | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | BASEANGBAND | HAS_LITE S:1_IN_2 | S:TELE_TO | BLIND | BO_MANA | S:S_ANGEL | S_KIN D:Commanding a legion of angels, Gabriel will destroy you for your sins. He D:will crush you like the pitiful insignificant being he sees you to be. D:Your very soul will be taken into judgement by his supreme authority as he D:cleanses the world of evil. N:770:Artsi, the Champion of Chaos G:h:v I:130:11d666:25:175:10 W:59:2:1600:20000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:EXP_80:10d10 B:HIT:EXP_80:10d10 B:HIT:EXP_80:10d10 F:UNIQUE | MALE | CAN_SPEAK | ATTR_MULTI | F:FORCE_SLEEP | FORCE_MAXHP | SMART | DROP_CORPSE F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | RES_NEXU | RES_NETH | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | F:ZANGBAND | HAS_LITE S:1_IN_4 | S:BA_FIRE | BA_CHAO | CONF | TPORT | S_DEMON | BR_CHAO | BA_MANA D:He is one of the greatest warriors of chaos to walk the earth. D:His bloody blade has slain thousands and tens of thousands, and still D:hungers for more. N:771:Saruman of Many Colours G:p:v I:120:70d100:100:100:0 W:60:1:1600:35000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:UN_BONUS:6d8 B:HIT:UN_BONUS:6d8 B:HIT:HURT:5d5 B:HIT:HURT:5d5 F:UNIQUE | MALE | ATTR_MULTI | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | REFLECTING | RES_TELE F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:DROP_GREAT | DROP_CHOSEN | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_FIRE | IM_COLD | F:IM_ELEC | IM_POIS | BASEANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | HASTE | TPORT | TELE_AWAY | BLIND | CONF | SCARE | S:CAUSE_4 | MIND_BLAST | FORGET | TRAPS | ANIM_DEAD | BO_MANA | S:BO_ICEE | BA_ACID | BA_FIRE | BA_COLD | BA_WATE | BA_CHAO | S:S_UNDEAD | S_DEMON | S_HI_DRAGON | S_ANIMALS D:Originally known as the White, Saruman fell prey to Sauron's wiles. He D:searches forever for the One Ring, to become a mighty Sorcerer-King of the D:world. N:772:Harowen the Black Hand G:p:B I:140:25d100:30:36:0 W:51:3:0:20000 E:1:1:1:2:1:1 O:90:10:0:0 B:TOUCH:EAT_GOLD:5d5 B:TOUCH:EAT_ITEM:5d5 B:HIT:BLIND:10d5 B:HIT:POISON:8d5 F:UNIQUE | MALE | CAN_SPEAK | SMART | F:FORCE_SLEEP | FORCE_MAXHP | MOVE_BODY | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:IM_POIS | BASEANGBAND S:1_IN_6 | S:TELE_TO | TRAPS D:He is a master of disguise, an expert of stealth, a genius at traps, and D:moves with blinding speed. Check your pockets! N:773:Osyluth G:U:W I:130:40d100:20:75:80 W:65:2:0:13000 E:1:1:1:2:1:1 O:20:40:20:20 B:HIT:LOSE_CHR:8d8 B:HIT:LOSE_CHR:8d8 B:BITE:POISON:10d10 B:STING:LOSE_STR:9d9 F:FORCE_SLEEP | FORCE_MAXHP | NONLIVING | F:ONLY_ITEM | DROP_3D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY F:EVIL | DEMON | NO_CONF | NO_SLEEP | INVISIBLE | BASEANGBAND | F:IM_ACID | IM_ELEC | IM_POIS | IM_COLD | IM_FIRE | NO_CUT S:1_IN_6 | S:BA_ELEC | BA_COLD | BO_ICEE | SCARE | S_DEMON D:It is a demon made almost entirely out of bones. It is humanoid, but with D:a large tail similar to that of a giant scorpion, and emits a foul smell D:of decay and rot. They are despised even in the hells. N:774:Dreadlord G:G:r I:120:30d100:20:150:10 W:62:2:0:20000 E:0:0:0:0:0:0 O:10:10:60:10 B:HIT:EXP_40:6d6 B:HIT:EXP_40:6d6 B:HIT:LOSE_STR:4d6 B:HIT:LOSE_STR:4d6 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | F:INVISIBLE | COLD_BLOOD | TAKE_ITEM | PASS_WALL | F:EVIL | UNDEAD | CAN_FLY | F:IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | RES_TELE | BASEANGBAND | NO_CUT S:1_IN_3 | S:HOLD | DRAIN_MANA | BLIND | S_UNDEAD | CONF | S:SCARE | TELE_TO | TPORT | BRAIN_SMASH | ANIM_DEAD S:BA_NETH | DARKNESS D:It is a massive form of animated death, its colour deeper than black. It D:drinks in light, and space around it is twisted and torn by the weight of D:its evil. It is unlife and it knows nothing but the stealing of souls and D:the stench of death. Flee its hunger! N:775:Greater kraken G:~:G I:120:40d100:30:175:80 W:60:2:10000:25000 E:3:0:3:0:1:0 O:10:80:0:10 B:CRUSH:HURT:15d15 B:CRUSH:HURT:15d15 B:CRUSH:HURT:15d15 B:CRUSH:HURT:15d15 F:FORCE_SLEEP | FORCE_MAXHP | AQUATIC | WILD_TOO | WILD_OCEAN | F:ONLY_ITEM | DROP_3D2 | DROP_GOOD | DROP_CORPSE | F:BASH_DOOR | POWERFUL | MOVE_BODY | SMART | RES_WATE | F:EVIL | IM_ELEC | NO_CONF | NO_SLEEP | IM_POIS | IM_FIRE | BASEANGBAND S:1_IN_3 | S:BLIND | CONF | SCARE | CAUSE_4 | CAUSE_3 | TELE_TO | TELE_AWAY | S:BA_WATE | DARKNESS | BR_DARK | BR_ACID | BR_POIS D:An enormously fearsome and powerful inhabitant of the depths. It D:resembles a gargantuan octopus and its evil is almost tangible. N:776:Archlich G:L:B I:120:45d100:20:120:50 W:64:2:0:20000 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:EXP_80 B:TOUCH:UN_POWER B:TOUCH:LOSE_DEX:8d12 B:TOUCH:LOSE_DEX:8d12 F:FORCE_SLEEP | FORCE_MAXHP | SMART | RES_TELE | CAN_FLY | F:ONLY_ITEM | DROP_4D2 | DROP_2D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_3 | S:BLINK | TELE_TO | BLIND | HOLD | SCARE | CAUSE_4 | S:DRAIN_MANA | BRAIN_SMASH | S_HI_UNDEAD | FORGET | S:TPORT | HEAL | S_DEMON | BA_NETH | ANIM_DEAD D:A lich who has reached its ultimate evolutionary stage: a completely D:immaterial state. N:777:The Cat Lord G:f:v I:130:48d100:100:200:0 W:66:3:0:30000 E:0:1:0:2:1:0 O:30:60:0:10 B:CLAW:CONFUSE:12d12 B:CLAW:LOSE_DEX:2d12 B:CLAW:BLIND:10d5 B:BITE:PARALYZE:15d1 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | ESCORTS | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_POIS | NO_CONF | BASEANGBAND S:1_IN_3 | S:TELE_TO | S_KIN D:Master of all things feline, the Cat Lord moves with catlike stealth. N:778:Jabberwock G:H:v I:130:32d100:35:125:255 W:68:3:2300:19000 E:0:1:0:2:1:0 O:20:50:20:0 B:CLAW:HURT:10d10 B:CLAW:HURT:10d10 B:BITE:HURT:10d10 B:BITE:HURT:10d10 F:ATTR_MULTI | F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | F:ONLY_ITEM | DROP_60 | DROP_90 | F:BASH_DOOR | CAN_FLY | DROP_CORPSE | F:ANIMAL | MORTAL | BASEANGBAND | S:1_IN_5 | S:CAUSE_4 | S:BR_CHAO D:'Twas brillig, and the slithy toves / Did gyre and gimble in the wabe: / D:All mimsy were the borogoves, / And the mome raths outgrabe. / D:"Beware the Jabberwock, my son! / The jaws that bite, the claws that catch!" N:779:Chaos hound G:Z:v I:120:60d30:30:100:0 W:65:2:900:10000 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:BITE:HURT:2d12 B:CLAW:HURT:2d12 F:ATTR_MULTI | ATTR_ANY | DROP_SKELETON | DROP_CORPSE | F:FORCE_SLEEP | FRIENDS | BASH_DOOR | F:ANIMAL | NO_CONF | NO_SLEEP | BASEANGBAND S:1_IN_5 | S:BR_CHAO D:A constantly changing canine form, this hound rushes towards you as if D:expecting mayhem and chaos ahead. It appears to have an almost kamikaze D:relish for combat. You suspect all may not be as it seems. N:780:Vlad Dracula, Prince of Darkness G:V:D I:130:70d100:20:166:10 W:76:4:1800:33333 E:1:1:1:2:1:1 O:0:10:90:0 B:BITE:EXP_80:8d8 B:BITE:EXP_80:8d8 B:HIT:CONFUSE:8d8 B:HIT:CONFUSE:8d8 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | SMART | CAN_SPEAK | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | F:RES_TELE | ZANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | DRAIN_MANA | S_HI_UNDEAD | S:BRAIN_SMASH | BA_NETH | S_KIN | DARKNESS | BA_DARK D:The most feared of all vampires, the Prince of Darkness himself. N:781:Beholder hive-mother G:e:y I:120:40d100:30:80:10 W:67:3:2600:17000 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:EXP_80:6d6 B:GAZE:PARALYZE:5d5 B:GAZE:INSANITY:5d5 B:GAZE:UN_POWER:5d5 F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | CAN_FLY | F:BASH_DOOR | FEMALE | SMART | DROP_CORPSE | F:EVIL | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND S:1_IN_2 | S:BLIND | CONF | FORGET | SCARE | DRAIN_MANA | BRAIN_SMASH | S:BA_DARK | BO_MANA | BA_ACID | BA_FIRE | BA_COLD | BO_NETH | S:S_KIN D:A hive mother of the race of beholders, she can summon her brood to her aid D:whenever she wishes. N:782:Leviathan G:~:v I:120:50d100:40:180:30 W:67:3:300000:28000 E:0:1:0:6:1:0 O:0:0:0:0 B:BITE:FIRE:5d12 B:BITE:FIRE:5d12 B:CRUSH:HURT:6d15 B:CRUSH:HURT:6d15 F:FORCE_SLEEP | FORCE_MAXHP | AQUATIC | WILD_TOO | WILD_OCEAN | F:IM_FIRE | IM_ACID | IM_COLD | IM_POIS | F:ANIMAL | NO_CONF | NO_SLEEP | NO_FEAR | DROP_CORPSE | BASEANGBAND S:1_IN_9 S:BR_FIRE | BR_ACID | BR_DARK | BR_POIS | BA_WATE | S:S_DRAGON | S_HYDRA | HEAL | CONF | DARKNESS D:An enormous, terrible sea-monster, the true master of the ocean. N:783:Great Wyrm of Chaos G:D:v I:120:60d100:40:170:100 W:75:2:190000:29000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:5d12 B:CLAW:HURT:5d12 B:BITE:HURT:7d14 B:BITE:HURT:7d14 F:ATTR_MULTI | ATTR_ANY | F:FORCE_SLEEP | FORCE_MAXHP | RES_DISE | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | CAN_FLY | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_CHAO | BR_DISE | S:S_DRAGON | S_HI_DRAGON D:A massive dragon of changing form. As you watch, it appears first fair D:and then foul. Its body is twisted by chaotic forces as it strives to D:stay real. Its very existence distorts the universe around it. N:784:Great Wyrm of Law G:D:B I:120:60d100:40:170:100 W:75:2:190000:29000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:5d12 B:CLAW:HURT:5d12 B:BITE:HURT:7d14 B:BITE:HURT:7d14 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | CAN_FLY | F:EVIL | DRAGON | NO_STUN | NO_SLEEP | BASEANGBAND | HAS_LITE | NO_CUT F:ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_SOUN | BR_SHAR | S:S_DRAGON | S_HI_DRAGON D:A massive dragon of powerful intellect. It seeks to dominate the universe D:and despises all other life. It sees all who do not obey it as mere D:insects to be crushed underfoot. N:785:Great Wyrm of Balance G:D:v I:120:70d100:40:170:100 W:80:2:190000:31000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:6d12 B:CLAW:HURT:6d12 B:BITE:HURT:8d14 B:BITE:HURT:8d14 F:DRAGON | EVIL | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | RES_DISE | F:NO_STUN | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | NO_CUT | ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_SOUN | BR_CHAO | BR_SHAR | BR_DISE | S:S_DRAGON | S_HI_DRAGON D:A massive dragon, it is thousands of D:years old and seeks to maintain the Cosmic Balance. It sees you as an D:upstart troublemaker without the wisdom to control your actions. N:786:Shambler G:E:W I:130:50d100:40:150:50 W:67:4:9000:22500 E:0:0:0:0:0:0 O:20:20:60:0 B:CLAW:HURT:3d12 B:CLAW:HURT:3d12 B:CRUSH:HURT:8d12 B:CRUSH:HURT:8d12 F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | CAN_SWIM | DROP_CORPSE | F:BASH_DOOR | OPEN_DOOR | POWERFUL | MOVE_BODY | F:NO_CONF | NO_SLEEP | EVIL | ZANGBAND | NO_CUT S:1_IN_3 | S:BR_ELEC D:This elemental creature is power incarnate; it looks like a huge polar bear D:with a huge gaping maw instead of a head. N:787:Gelugon G:U:w I:130:45d100:20:100:80 W:69:3:0:14000 E:2:1:2:0:0:1 O:20:60:20:0 B:CLAW:COLD:6d10 B:CLAW:COLD:6d10 B:BITE:COLD:9d9 B:HIT:PARALYZE:8d8 F:FORCE_SLEEP | FORCE_MAXHP | BASEANGBAND | NONLIVING | F:ONLY_ITEM | DROP_GOOD | DROP_4D2 | CAN_FLY | F:OPEN_DOOR | BASH_DOOR | POWERFUL | REGENERATE | F:EVIL | DEMON | IM_COLD | NO_CONF | NO_SLEEP S:1_IN_6 S:BR_COLD | BR_SHAR | BA_COLD | BO_ICEE | S_HI_DEMON | S:SLOW | SCARE | HOLD D:This demon from the ice planes is a truly terrifying sight. It has an D:extremely large, insect-like body towering a full twelve feet tall, with D:great claws on its hands and pincers on its mouth, and its head bulges D:with great multi-faceted eyes. Its tail is covered with razor-sharp D:spikes. N:788:Glaaki G:~:v I:130:52d99:20:150:10 W:67:2:0:36000 E:0:0:0:0:1:0 O:0:0:100:0 B:STING:HURT:20d1 B:STING:DISEASE:20d1 B:CRUSH:HURT:3d20 F:UNIQUE | CAN_SPEAK | ATTR_MULTI | ELDRITCH_HORROR | F:NO_STUN | RES_NEXU | RES_WATE | CAN_SWIM | REGENERATE | F:FORCE_SLEEP | FORCE_MAXHP | EVIL | SMART | DEMON | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:NO_STUN | F:IM_POIS | IM_COLD | IM_ACID | CTHANGBAND S:1_IN_5 S:BA_WATE | S_HYDRA | S_DRAGON | S_DEMON | SCARE | S:BLIND | CONF | CAUSE_4 | BR_POIS D:"From an oval body protruded countless thin, pointed spines of D:multi-colored metal; at the more rounded end of the oval a D:circular, thick-lipped mouth formed the centre of a spongy D:face, from which rose three yellow eyes on thin stalks. Around D:the underside of the body were many white pyramids, presumably D:used for locomotion. The diameter of the body must have been D:at least ten feet at its least wide..." N:789:Trone, the Rebel Thunderlord G:B:D I:130:80d100:20:120:80 W:72:2:400000:45000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:12d10 B:HIT:HURT:12d10 B:CHARGE:HURT:10d10 B:CHARGE:HURT:10d10 F:UNIQUE | MALE | CAN_SPEAK | RES_TELE | SPECIAL_GENE | F:FORCE_MAXHP | REGENERATE | THUNDERLORD | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:SMART | OPEN_DOOR | BASH_DOOR | DROP_CHOSEN | F:EVIL | IM_FIRE | IM_COLD | IM_POIS | F:MORTAL | HAS_LITE S:1_IN_4 | S:TELE_TO | SCARE | BR_TIME | BR_FIRE | S:BO_MANA | S_THUNDERLORD D:As the Thunderlords came from afar to help the elves, Trone and his rebel D:wing came to defend Morgoth! He is an evil and powerful Thunderlord. N:790:Great Wyrm of Many Colours G:D:v I:120:70d100:40:170:255 W:80:2:190000:31000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:6d12 B:CLAW:HURT:6d12 B:CLAW:HURT:8d14 B:BITE:HURT:8d14 F:ATTR_MULTI | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | AURA_FIRE | AURA_ELEC | RES_TELE | F:IM_FIRE | IM_ACID | IM_POIS | IM_COLD | IM_ELEC | AURA_COLD | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | DROP_CORPSE | F:DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_4 | S:BR_POIS | BR_ELEC | BR_ACID | BR_FIRE | BR_COLD | S:CONF | SCARE | BLIND D:A huge dragon whose scales shimmer in myriad hues. N:791:Marda, rider of gold Laronth G:B:y I:130:100d85:100:100:50 W:75:6:420000:35000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:12d15 B:HIT:HURT:12d15 B:HIT:HURT:12d15 B:HIT:HURT:12d15 F:UNIQUE | FEMALE | CAN_SPEAK | THUNDERLORD | ONLY_ITEM | RES_TELE | F:DROP_CHOSEN | DROP_CORPSE | DROP_SKELETON | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_4D2 | DROP_1D2 | DROP_GOOD | DROP_60 | DROP_90 | F:EVIL | IM_POIS | IM_ELEC | SMART | REGENERATE | OPEN_DOOR | BASH_DOOR | F:MORTAL | HAS_LITE S:1_IN_4 | S:SCARE | BLIND | TPORT | BLINK | TELE_AWAY | TELE_TO | S:BR_FIRE | BA_MANA | S_THUNDERLORD D:Former leader among the Thunderlords, she and Trone have fallen under the D:control of Morgoth. Laronth, her eagle, can summon Thunderlords to her aid. N:792:Tselakus, the Dreadlord G:G:R I:130:65d100:20:150:10 W:68:2:1000:35000 E:1:1:1:2:1:1 O:0:80:20:0 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:HIT:LOSE_STR:4d6 B:HIT:LOSE_STR:4d6 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_SPEAK | CAN_FLY | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:INVISIBLE | COLD_BLOOD | PASS_WALL | F:EVIL | UNDEAD | IM_COLD | AURA_COLD | F:IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT | NO_STUN S:1_IN_3 | S:BLIND | HOLD | CONF | S:BA_DARK | BA_NETH | S:S_WRAITH | S_HI_UNDEAD | S_KIN D:This huge affront to existence twists and tears at the fabric of space. D:Darkness itself recoils from the touch of Tselakus as he leaves a trail D:of death and destruction. Mighty claws rend reality as he D:annihilates all in his path to your soul! N:793:Sky Drake G:D:B I:130:60d100:40:200:255 W:77:2:220000:40000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:6d12 B:CLAW:HURT:6d12 B:BITE:ELEC:8d14 B:BITE:ELEC:8d14 F:FORCE_SLEEP | FORCE_MAXHP | AURA_ELEC | AURA_COLD | DROP_CORPSE | F:IM_ELEC | EVIL | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | F:DRAGON | NO_CONF | NO_SLEEP | RES_TELE | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_4 | S:BR_ELEC | BR_GRAV | BR_LITE | S:S_DRAGON | S_HI_DRAGON | S:SCARE | BLIND D:The mightiest elemental dragon of air, it can destroy you with ease. N:794:Eilinel the Entrapped G:p:D I:120:90d10:10:40:1 W:42:10:0:3500 E:1:1:1:2:1:1 O:20:20:50:10 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:TOUCH:UN_POWER:3d3 B:TOUCH:UN_BONUS:3d3 F:UNIQUE | FEMALE | F:FORCE_MAXHP | F:DROP_1D2 | DROP_2D2 | DROP_3D2 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_FIRE | NO_CONF | NO_SLEEP | ZANGBAND | NO_CUT | NO_STUN S:1_IN_2 | S:BLINK | TELE_TO | HEAL | S_MONSTER | BO_ACID | BO_MANA | CAUSE_3 D:In life, she was the wife of Gorlim. In death, her shade was D:entrapped by Morgoth and used to trick her husband into betraying D:Barahir. Now she is totally entrapped by Morgoth's power, and uses D:her magic to do his bidding. N:795:Horned Reaper G:U:B I:130:50d100:40:120:80 W:72:3:0:18000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:11d11 B:HIT:HURT:11d11 B:HIT:HURT:11d11 B:HIT:HURT:11d11 F:FORCE_SLEEP | FORCE_MAXHP | REGENERATE | NONLIVING | F:ONLY_ITEM | DROP_GOOD | DROP_4D2 | DROP_2D2 | BASEANGBAND | F:OPEN_DOOR | BASH_DOOR | KILL_BODY | POWERFUL | F:EVIL | DEMON | NO_CONF | NO_SLEEP | CAN_FLY | F:IM_FIRE | IM_COLD | IM_POIS | IM_ACID | IM_ELEC S:1_IN_5 | S:HASTE | SLOW | SCARE | S_HI_DEMON D:A giant humanoid demon wielding a massive, heavy and sharp scythe. Feared D:by foes and friends alike when it flies into one of its berserk rages, the D:Horned Reaper will cut down anything in its path between it and you - even D:the minions it has just summoned. N:796:The Norsa G:H:B I:130:100d100:20:125:70 W:70:4:16000:47500 E:0:1:0:2:1:0 O:50:0:50:0 B:CRUSH:ACID:8d12 B:CRUSH:FIRE:8d12 B:CRUSH:ELEC:8d12 B:CRUSH:POISON:10d14 F:ATTR_MULTI | ELDRITCH_HORROR | DROP_CORPSE | F:UNIQUE | CAN_SPEAK | AURA_FIRE | AURA_ELEC | AURA_COLD | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | EVIL | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:ZANGBAND S:1_IN_2 | S:BLIND | CONF | SCARE | S:BR_NETH | BR_CHAO | BR_TIME | BR_GRAV | BR_DISI | S:S_HI_DRAGON | S_MONSTERS D:An elephantine horror with five trunks, each capable of breathing D:destructive blasts. It is said that it is better to face the fury D:of a thousand raging lions than the Norsa! N:797:Rhan-Tegoth G:S:b I:130:90d100:20:125:70 W:70:4:0:42500 E:0:1:0:2:1:0 O:0:50:50:0 B:CLAW:HURT:8d12 B:CRUSH:LOSE_STR:5d12 B:CLAW:HURT:8d12 B:CRUSH:ACID:5d12 F:ELDRITCH_HORROR | CAN_SWIM | EVIL | F:UNIQUE | CAN_SPEAK | AURA_FIRE | AURA_ELEC | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_ELEC | IM_POIS | NO_SLEEP | RES_WATE | CTHANGBAND S:1_IN_5 | S:S_DEMON | BR_ACID | S_UNDEAD | S_KIN | CONF | SCARE | S:MIND_BLAST | BR_CONF D:"An almost globular torso, with six long, sinuous limbs terminating D:in crab-like claws. From the upper end a subsidiary globe bulged D:forward bubble-like; its triangle of three staring, fishy eyes, D:its foot-long and evidently flexible proboscis, and a distended D:lateral system analogous to gills, suggested that it was a head." N:798:Black reaver G:L:D I:120:50d100:20:170:50 W:74:3:1900:23000 E:0:0:0:0:0:0 O:0:60:40:0 B:HIT:UN_BONUS:6d8 B:HIT:UN_BONUS:6d8 B:HIT:LOSE_STR:4d6 B:HIT:LOSE_STR:4d6 F:FORCE_SLEEP | FORCE_MAXHP | SMART | CAN_SWIM | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | RES_TELE | F:NO_CONF | NO_SLEEP | KILL_WALL | NO_FEAR | F:MORTAL | BASEANGBAND | NO_CUT S:1_IN_3 | S:TELE_TO | BLIND | HOLD | CONF | CAUSE_3 | CAUSE_4 | DRAIN_MANA | S:BRAIN_SMASH | BA_MANA | BA_NETH | S_UNDEAD D:A humanoid form, black as night, advancing steadily and unstoppably, even D:the very rock of the dungeon cannot prevent it reaching you. N:799:Master mindcrafter G:p:y I:120:80d10:20:60:10 W:40:2:1700:2000 E:1:1:1:2:1:1 O:20:40:40:0 B:HIT:HURT:4d5 B:HIT:HURT:4d5 B:HIT:HURT:4d5 F:MALE | ONLY_ITEM | FORCE_SLEEP | FORCE_MAXHP | DROP_4D2 | F:SMART | BASH_DOOR | TAKE_ITEM | MOVE_BODY | F:EVIL | IM_FIRE | IM_ELEC | IM_POIS | BASEANGBAND | F:NO_CONF | NO_SLEEP | NO_STUN | NO_FEAR S:1_IN_2 | S:HEAL | BLIND | HOLD | CONF | SCARE | TPORT | BA_COLD | BA_FIRE | S:MIND_BLAST | BRAIN_SMASH | S_MONSTERS | TELE_AWAY | BLINK | BO_NETH D:A mindcrafter of the highest order. Powerful and evil, and a dangerous D:enemy: a master of mind over matter, of his own mind, and of the minds of D:others, who slavishly follow him into battle when he calls them. N:800:Greater demonic quylthulg G:Q:R I:120:15d100:20:1:0 W:71:2:5000:10500 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | ANIMAL | RES_TELE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_2 | S:BLINK | TELE_TO | S:S_HI_DEMON D:A massive pulsating mound of flesh, glowing with an inner hellish light. N:801:Greater draconic quylthulg G:Q:G I:120:15d100:20:1:0 W:71:2:5000:10500 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | ANIMAL | RES_TELE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_2 | S:BLINK | TELE_TO | S:S_HI_DRAGON D:A massive mound of scaled flesh, throbbing and pulsating with multi-hued D:light. N:802:Greater rotting quylthulg G:Q:U I:120:15d100:20:1:0 W:71:2:5000:10500 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | ANIMAL | RES_TELE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND |NO_CUT S:1_IN_2 | S:BLINK | TELE_TO | S:S_HI_UNDEAD D:A massive pile of rotting flesh. A disgusting stench fills the air as it D:throbs and writhes. N:803:Null, the Living Void G:.:d I:110:50d100:30:100:20 W:72:2:0:32500 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:LOSE_ALL:6d16 B:TOUCH:EXP_80:6d16 B:TOUCH:UN_POWER:6d16 F:PASS_WALL | NONLIVING | IM_ACID | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | SMART | EMPTY_MIND | F:ELDRITCH_HORROR | IM_COLD | RES_NETH | NO_STUN | UNIQUE | NO_SLEEP | NO_CONF | NO_FEAR | F:REGENERATE | ZANGBAND | NO_CUT S:1_IN_5 S:BR_NETH | BRAIN_SMASH | SCARE | S_UNDEAD | S_HI_UNDEAD | S:DRAIN_MANA | HEAL | ANIM_DEAD D:A black hole in the fabric of reality. It simply is not there. N:804:Feagwath, the Undead Sorcerer G:L:y I:130:60d100:20:85:50 W:77:2:1900:30000 E:1:1:1:2:1:1 O:0:50:50:0 B:TOUCH:EXP_80:6d12 B:TOUCH:UN_POWER:6d12 B:TOUCH:LOSE_DEX:6d12 B:TOUCH:LOSE_DEX:6d12 F:UNIQUE | MALE | CAN_SPEAK | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | SPECIAL_GENE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | F:IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_2 | S:BLINK | TELE_TO | HOLD | SCARE | CAUSE_4 | S:BRAIN_SMASH | TRAPS | BA_MANA | S:BO_MANA | BA_NETH | S:S_MONSTERS | S_UNDEAD | S_KIN | ANIM_DEAD D:A stench of corruption and decay surrounds this sorcerer, who has clearly D:risen from the dead to continue his foul plots and schemes. N:805:Omarax the Eye Tyrant G:e:v I:130:65d100:30:80:10 W:73:3:600:25000 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:UN_BONUS:6d6 B:GAZE:UN_POWER:6d6 B:GAZE:INSANITY:6d6 B:BITE:EXP_80:8d8 F:UNIQUE | MALE | CAN_SPEAK | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:SMART | BASH_DOOR | F:EVIL | IM_POIS | F:BASEANGBAND S:1_IN_2 | S:BLIND | CONF | FORGET | SCARE | DRAIN_MANA | BRAIN_SMASH | S:BA_DARK | BO_MANA | BA_NETH | BA_ACID | BA_FIRE | BA_COLD | S:S_KIN D:A beholder of great size and age, floating in the air. His gaze seems to D:shred your soul and his spells crush your will. He is ancient, his history D:steeped in forgotten evils, his atrocities numerous and sickening. N:806:Tsathoggua, the Sleeper of N'kai G:R:D I:130:66d100:30:80:100 W:74:4:0:16500 E:0:0:0:0:0:0 O:0:50:50:0 B:CRUSH:LOSE_ALL:5d6 B:CRUSH:ACID:5d6 B:CRUSH:LOSE_ALL:5d6 B:CRUSH:ACID:5d6 F:UNIQUE | CAN_SPEAK | RES_TELE | ELDRITCH_HORROR | F:FORCE_SLEEP | FORCE_MAXHP | DROP_1D2 | DROP_2D2 | F:ONLY_ITEM | DROP_GOOD | MOVE_BODY | F:SMART | BASH_DOOR | F:EVIL | DEMON | IM_POIS | IM_ACID | IM_COLD | F:NO_CONF | NO_SLEEP | CTHANGBAND | HAS_LITE | NO_CUT S:1_IN_2 | S:S_DEMON | S_MONSTERS | S_UNDEAD | HOLD | SCARE | MIND_BLAST | S:BR_ACID | BR_NETH | CAUSE_4 D:"...the formless bulking of a couchant mass. And the mass stirred D:a little... and put forth with infinite slothfulness a huge and D:toad-shaped head. And the head opened its eyes very slowly, as if D:half awakened from slumber, so that they were visible as two slits D:of oozing phosphor in the black browless face." N:807:Greater Balrog G:U:v I:130:75d100:40:140:40 W:80:3:0:25000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:FIRE:8d12 B:HIT:FIRE:8d12 B:CRUSH:HURT:7d12 B:TOUCH:UN_POWER F:FORCE_SLEEP | FORCE_MAXHP | AURA_FIRE | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | NONLIVING | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | SMART | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | KILL_WALL | F:RES_NETH | RES_PLAS | REGENERATE | BASEANGBAND | HAS_LITE S:1_IN_3 | S:BLIND | CONF | BRAIN_SMASH | S:BR_FIRE | BA_NETH | BA_FIRE | BR_PLAS | BO_PLAS | S:S_HI_DEMON | S_UNDEAD | S_DEMON | D:Originally of the semi-divine Maiar, this evil spirit swore allegiance D:to Morgoth at the beginning of time and is now one of his most terrible D:demonic servants. With its flaming whip and sword it seeks to destroy you. N:808:Ungoliant, the Unlight G:S:D I:130:130d100:8:160:80 W:75:1:1500:35000 E:0:1:0:2:1:0 O:20:0:80:0 B:CLAW:POISON:8d6 B:CLAW:POISON:8d6 B:BITE:PARALYZE:8d10 B:STING:LOSE_STR:8d4 F:UNIQUE | FEMALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:SMART | BASH_DOOR | IM_ACID | F:ANIMAL | SPIDER | EVIL | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP F:BASEANGBAND S:1_IN_3 | S:HEAL | BLIND | SLOW | CONF | SCARE | DARKNESS | BA_DARK | S:BR_POIS | BR_DARK | S_SPIDER D:This enormous, hideous spirit of void is in the form of a spider of D:immense proportions. She is surrounded by a cloud of Unlight as she sucks D:in all living light into her bloated body, and breathes out the blackest of D:darkness. She is always ravenously hungry and would even eat herself to D:avoid starvation. N:809:Atlach-Nacha, the Spider God G:S:D I:120:110d100:8:160:80 W:73:1:2000:31000 E:0:1:0:2:1:0 O:60:0:40:0 B:BITE:POISON:3d9 B:BITE:LOSE_STR:3d9 B:STING:POISON:2d9 B:STING:LOSE_STR:2d9 F:UNIQUE | CAN_SPEAK | ELDRITCH_HORROR | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:SMART | BASH_DOOR | MOVE_BODY | NONLIVING | F:ANIMAL | SPIDER | EVIL | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | F:CTHANGBAND S:1_IN_3 | S:SCARE | BLIND | CONF | HOLD | BR_POIS | S:DARKNESS | BR_DARK | S_KIN | S_HI_DEMON D:"...there was a kind of face on the squat ebon body, low down amid D:the several-jointed legs. The face peered up with a weird expression D:of doubt and inquiry..." N:810:Y'golonac G:H:R I:120:130d99:8:160:80 W:75:1:0:37500 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:LOSE_INT:1d20 B:BITE:HURT:40d1 B:TOUCH:LOSE_WIS:1d20 B:BITE:HURT:40d1 F:UNIQUE | CAN_SPEAK | ELDRITCH_HORROR | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:SMART | BASH_DOOR | MOVE_BODY | NONLIVING | F:EVIL | IM_POIS | CTHANGBAND S:1_IN_3 | S:SCARE | BLIND | CONF | HOLD | HASTE | DRAIN_MANA | HASTE | S:CAUSE_3 | CAUSE_4 | DARKNESS | FORGET | S_DEMON | S_HOUND | S:TPORT | TELE_TO D:"He saw why the shadow on the frosted pane yesterday had been D:headless and he screamed... but before he could scream out his D:protest his breath was cut off, as the hands descended on his D:face and the wet red mouths opened in their palms." N:811:Aether hound G:Z:v I:120:60d40:30:100:0 W:74:3:1000:10000 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:3d12 B:BITE:HURT:3d12 B:CLAW:HURT:3d12 B:CLAW:HURT:3d12 F:ATTR_MULTI | ATTR_ANY | F:FORCE_SLEEP | CAN_FLY | F:FRIENDS | RES_NETH | RES_PLAS | RES_NEXU | RES_DISE | F:BASH_DOOR | AURA_FIRE | AURA_ELEC | AURA_COLD | F:DROP_CORPSE | DROP_SKELETON | F:ANIMAL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_5 | S:BR_ACID | BR_FIRE | BR_COLD | BR_ELEC | BR_POIS | S:BR_LITE | BR_DARK | BR_SOUN | BR_CONF | BR_CHAO | BR_SHAR | S:BR_NETH | BR_DISE | BR_WALL | BR_INER | BR_TIME | S:BR_GRAV | BR_PLAS | BR_NEXU D:A shifting, swirling form. It seems to be all colours and sizes and D:shapes, though the dominant form is that of a huge dog. You feel very D:uncertain all of a sudden. N:812:Pit Fiend G:U:o I:130:60d100:30:120:75 W:77:3:0:22000 E:1:1:1:2:1:1 O:0:100:0:0 B:CLAW:FIRE:8d10 B:CLAW:FIRE:8d10 B:BITE:POISON:7d10 B:BITE:LOSE_CON:7d10 F:FORCE_SLEEP | FORCE_MAXHP | REGENERATE | NONLIVING | F:ONLY_ITEM | DROP_GOOD | DROP_4D2 | DROP_2D2 | BASEANGBAND | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | POWERFUL | CAN_FLY | F:EVIL | DEMON | IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP S:1_IN_5 | S:S_HI_DEMON | S_HI_DRAGON | BR_FIRE | BR_POIS | BR_CHAO | BA_CHAO | S:SCARE | BA_FIRE | CAUSE_4 D:Appearing as a giant, clawed and winged humanoid with a scaly red body D:and massive fangs dripping a foul green liquid, the Pit Fiend is a D:dreadful enemy from the lowest depths of the hells. They are often the D:commanders of vast demon armies. N:813:The Serpent of Chaos G:J:v I:130:66d100:30:180:150 W:75:2:0:25000 E:0:0:0:0:1:0 O:40:40:20:0 B:CRUSH:POISON:15d10 B:CRUSH:CONFUSE:15d10 B:CRUSH:UN_BONUS:10d15 B:CRUSH:UN_POWER:10d15 F:UNIQUE | ATTR_MULTI | ATTR_ANY | AURA_FIRE | AURA_COLD | F:FORCE_SLEEP | FORCE_MAXHP | POWERFUL | REGENERATE | F:DROP_2D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:OPEN_DOOR | BASH_DOOR | ANIMAL | EVIL | CAN_FLY | F:KILL_ITEM | KILL_BODY | F:NO_CONF | NO_SLEEP | NO_STUN | NO_FEAR | ZANGBAND | F:IM_COLD | IM_FIRE | IM_POIS S:1_IN_3 | S:BR_CHAO | BR_DISI | BA_CHAO | BR_NETH | BR_MANA | S:S_MONSTERS | S_HI_DEMON | S_HI_DRAGON D:Writhing coil upon coil, this mighty spawn of Chaos constantly disintegrates D:and reforms before your dazzled eyes. It gazes balefully upon you with its D:one remaining eye, and seeks to destroy you utterly. N:814:Yig, Father of Serpents G:J:b I:130:111d60:100:100:15 W:76:1:2300:37500 E:0:0:0:0:1:0 O:80:0:20:0 B:CLAW:POISON:8d10 B:CLAW:POISON:8d10 B:CRUSH:HURT:8d15 B:BITE:HURT:100d1 F:UNIQUE | MALE | CAN_SPEAK | SMART | RES_TELE | ANIMAL | F:ESCORT | ESCORTS | CAN_SWIM | ELDRITCH_HORROR | F:OPEN_DOOR | BASH_DOOR | F:FORCE_SLEEP | FORCE_MAXHP | F:DROP_4D2 | DROP_1D2 | DROP_GOOD | DROP_60 | DROP_90 | ONLY_ITEM | F:EVIL | IM_POIS | IM_ACID | IM_ELEC | REGENERATE | ZANGBAND S:1_IN_4 | S:BR_POIS | BR_NUKE | BR_ACID | S_HYDRA | S_KIN | S_DEMON | D:"The half-human father of serpents... the snake-god of the central D:plains tribes -- presumably the primal source of the more D:southerly Quetzalcoatl or Kukulcan -- was odd, half-anthropomorphic D:devil." N:815:Unmaker G:E:v I:120:6d66:60:50:60 W:77:4:0:10000 E:0:0:0:0:0:0 O:20:50:20:0 B:TOUCH:LOSE_ALL:10d10 B:TOUCH:UN_BONUS:10d10 B:TOUCH:UN_POWER:10d10 F:KILL_WALL | KILL_ITEM | KILL_BODY | NO_FEAR | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ATTR_MULTI | SHAPECHANGER | ATTR_ANY | F:DROP_60 | DROP_GOOD | POWERFUL | AURA_ELEC | AURA_FIRE | AURA_COLD | F:BASH_DOOR | IM_ELEC | IM_FIRE | RES_NEXU | IM_COLD | ZANGBAND | F:IM_POIS | IM_ACID | RES_PLAS | RES_DISE | COLD_BLOOD | NONLIVING | RAND_50 F:NO_CUT S:MULTIPLY | S:1_IN_5 | S:BR_CHAO D:Spawned from the Pits of the Abyss, it is a mass of sentient Chaos, D:spreading uncontrollably and destroying everything in its path. N:816:Cyberdemon G:U:u I:120:70d101:90:90:90 W:77:4:15000:30000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d50 B:HIT:HURT:1d50 B:HIT:HURT:1d50 B:HIT:HURT:1d50 F:RAND_25 | EVIL | DEMON | F:DROP_2D2 | DROP_GOOD | ONLY_ITEM | RES_TELE | SUSCEP_ACID | F:IM_POIS | IM_FIRE | FORCE_SLEEP | FORCE_MAXHP | NONLIVING F:MORTAL | ZANGBAND | HAS_LITE S:1_IN_4 | S:ROCKET D:Reverbrant metal steps announce the arrival of this huge creature, D:half demon half machine. It has an unsurpassable firepower. N:817:Hela, Queen of the Dead G:p:G I:130:74d100:60:110:10 W:74:3:8000:45000 E:1:1:1:2:1:1 O:0:0:100:0 B:TOUCH:LOSE_ALL:50d1 B:TOUCH:EXP_80:50d1 B:TOUCH:UN_BONUS:50d1 F:UNIQUE | FEMALE | CAN_SPEAK | POWERFUL | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_1D2 | DROP_GREAT | DROP_GOOD | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | CAN_FLY | F:EVIL | RES_NETH | IM_COLD | IM_POIS | F:IM_FIRE | NO_CONF | NO_SLEEP | ZANGBAND | HAS_LITE S:1_IN_3 | S:CAUSE_3 | CAUSE_4 | HAND_DOOM | TELE_TO | HOLD | S:S_UNDEAD | S_HI_UNDEAD | S_HI_DRAGON | FORGET | SCARE | BLIND | S:BA_DARK | BA_NETH | HEAL | ANIM_DEAD D:The Norse ruler of Hel is a merciless queen, who ever hunts for more D:souls to add to her collection of tortured spirits. She arrives in D:an ominous green robe, a certain sign of impending doom, to claim D:as her own those who die an ignoble death. N:818:The Mouth of Sauron G:p:v I:130:90d100:60:100:10 W:78:3:1900:38000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:UN_BONUS:6d8 B:HIT:UN_BONUS:6d8 B:TOUCH:UN_POWER B:TOUCH:UN_POWER F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_1D2 | DROP_4D2 | DROP_GOOD | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_FIRE | IM_COLD | F:IM_ELEC | BASEANGBAND | HAS_LITE S:1_IN_2 | S:TELE_TO | HOLD | CAUSE_3 | TRAPS | ANIM_DEAD | S:BO_PLAS | BA_DARK | BA_MANA | BA_FIRE | BA_WATE | BA_NETH S:S_HI_DEMON | S_HI_UNDEAD D:The Mouth of Sauron is a mighty spell caster. So old that even he cannot D:remember his own name, his power and evil are undeniable. He believes D:unshakeably that he is unbeatable and laughs as he weaves his awesome D:spells. N:819:The Necromancer of Dol Guldur G:p:v I:130:82d100:60:100:10 W:75:3:1900:40000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:UN_BONUS:6d8 B:HIT:UN_POWER:6d8 B:HIT:BLIND:6d8 B:HIT:CONFUSE:6d8 F:UNIQUE | MALE | CAN_SPEAK | POWERFUL | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_1D2 | DROP_GREAT | DROP_GOOD | SPECIAL_GENE | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_FIRE | IM_COLD | F:IM_ELEC | NO_CONF | NO_SLEEP | BASEANGBAND S:1_IN_2 | S:CAUSE_3 | TELE_TO | BA_FIRE | DRAIN_MANA | HOLD | S:TRAPS | BA_WATE | BO_PLAS | BA_NETH | S:BA_MANA | BA_DARK | S_HI_UNDEAD | BA_CHAO | HAND_DOOM | ANIM_DEAD D:The dark master of the terrible fortress of southern Mirkwood. It is D:rumoured that this is in fact none other than Sauron in disguise: D:although if this is so, he has yet to reveal his full power - and perhaps D:will not do so while his deception lasts, in the hope of keeping it going. N:820:Lisa, rider of gold Romth G:B:y I:130:65d100:100:100:15 W:78:6:420000:35500 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:10d15 B:HIT:HURT:10d15 B:HIT:HURT:10d15 B:HIT:HURT:10d15 F:UNIQUE | FEMALE | THUNDERLORD | RES_TELE | CAN_FLY | GOOD | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | DROP_SKELETON | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | PET | F:DROP_4D2 | DROP_1D2 | DROP_GOOD | DROP_60 | DROP_90 | ONLY_ITEM | F:IM_COLD | IM_POIS | IM_ACID | IM_ELEC | REGENERATE | F:MORTAL | HAS_LITE S:1_IN_4 | S:TPORT | TELE_TO | BR_FIRE | S_THUNDERLORD | S:TELE_AWAY | HEAL | BA_NETH | BO_NETH | BA_FIRE | BO_FIRE D:She came to help you. N:821:Master quylthulg G:Q:B I:120:30d100:20:1:0 W:76:2:7000:15000 E:0:0:0:0:0:0 O:0:0:0:0 F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:INVISIBLE | EMPTY_MIND | ANIMAL | RES_TELE | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_2 | S:S_MONSTERS | S_HI_UNDEAD | S_HI_DRAGON | S_HI_DEMON | S_ANIMALS | BLINK | TELE_TO D:A giant seething mass of flesh, overwhelming you with monster after monster. N:822:Qlzqqlzuup, the Lord of Flesh G:Q:v I:130:50d100:30:1:0 W:79:3:10000:20000 E:0:0:0:0:0:0 O:20:20:20:20 F:UNIQUE | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | NEVER_MOVE | NEVER_BLOW | F:ONLY_ITEM | DROP_4D2 | F:INVISIBLE | ATTR_MULTI | EMPTY_MIND | ANIMAL | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND S:1_IN_1 | S:S_MONSTERS | S_ANGEL | S_HOUND | S_HYDRA | S_SPIDER | S_ANT | S_ANIMALS | S:S_HI_UNDEAD | S_HI_DRAGON | S_HI_DEMON | S_WRAITH | S_UNIQUE | S_KIN D:A gigantic seething mass of flesh, Qlzqqlzuup changes colours in front D:of your eyes. Pulsating first one colour then the next, it knows only it D:must bring help to protect itself. N:823:Cthugha, the Living Flame G:E:R I:133:50d100:30:1:20 W:78:3:0:17500 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:BLIND B:TOUCH:FIRE:12d10 B:TOUCH:FIRE:12d10 B:TOUCH:FIRE:12d10 F:UNIQUE | RES_TELE | AURA_FIRE | IM_FIRE | CAN_FLY | RES_PLAS | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | SMART | ELDRITCH_HORROR | F:EVIL | KILL_ITEM | KILL_BODY | F:NO_CONF | NO_SLEEP | NO_FEAR | CTHANGBAND | HAS_LITE | NO_CUT S:1_IN_4 | S:BR_FIRE | S_KIN D:"But even though we had shielded our eyes, it was impossible not D:to see the great amorphous shapes streaming skyward from the D:accursed place, nor the equally great being hovering like a cloud D:of living fire above the trees." N:824:Flare, rider of bronze Moonth G:B:U I:130:70d100:100:100:15 W:79:5:400000:38500 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:15d15 B:HIT:HURT:15d15 B:HIT:HURT:15d15 B:HIT:HURT:15d15 F:UNIQUE | MALE | THUNDERLORD | RES_TELE | CAN_FLY | CAN_SPEAK | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | DROP_SKELETON | F:FORCE_SLEEP | FORCE_MAXHP | PET | GOOD | F:DROP_4D2 | DROP_1D2 | DROP_GOOD | DROP_60 | DROP_90 | ONLY_ITEM | F:IM_COLD | IM_POIS | IM_ACID | IM_ELEC | IM_FIRE | REGENERATE | F:MORTAL | HAS_LITE S:1_IN_4 | S:SCARE | TPORT | TELE_TO | S_THUNDERLORD | S:TELE_LEVEL | HEAL | BR_FIRE | BR_TIME | ROCKET D:A leader from afar, he has come with his eagle to help you in D:your battle. Having already saved his home, he now wants to save Arda! N:825:Maeglin, the Traitor of Gondolin G:h:D I:130:60d100:220:120:20 W:81:2:1400:35000 E:1:1:1:2:1:1 O:30:70:0:0 B:HIT:HURT:8d8 B:HIT:HURT:8d8 B:HIT:HURT:8d8 B:HIT:HURT:8d8 F:UNIQUE | MALE | F:FORCE_MAXHP | CAN_SPEAK | SMART | EVIL | AI_SPECIAL | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:OPEN_DOOR | BASH_DOOR | KILL_WALL | MOVE_BODY | TAKE_ITEM | F:IM_FIRE | IM_COLD | IM_POIS | SPECIAL_GENE | F:REGENERATE | REFLECTING | DROP_SKELETON | DROP_CORPSE | BASEANGBAND F:HAS_LITE S:1_IN_6 | S:S_MONSTERS | S_WRAITH | S_HI_UNDEAD | S:S_HI_DRAGON | S_HI_DEMON | S_UNIQUE | S_ANIMALS D:The son of Eol the Dark Elf, Maeglin is every bit as evil as his father D:and more. His greed for gold led him to betray the Hidden Kingdom of D:Gondolin to Morgoth's forces. He is a mighty warrior himself, and some D:of Morgoth's greatest servants answer to his call. N:826:Cyaegha G:e:G I:130:64d100:90:120:10 W:80:3:0:44444 E:0:0:0:0:0:0 O:20:50:30:0 B:CRUSH:HURT:15d15 B:CRUSH:HURT:15d15 B:CRUSH:HURT:15d15 B:CRUSH:HURT:15d15 F:UNIQUE | CAN_SPEAK | RES_TELE | ELDRITCH_HORROR | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | DEMON | IM_ACID | IM_ELEC | F:IM_COLD | IM_POIS | CTHANGBAND | HAS_LITE S:1_IN_3 | S:TELE_AWAY | BLIND | HOLD | SCARE | BRAIN_SMASH | S:BR_DARK | BA_DARK | BR_NETH | HAND_DOOM | S:S_HI_UNDEAD | S_DEMON | S_MONSTERS | S_HYDRA D:"...it was a gigantic eye staring down at them. Around the eye, D:the sky split; deep clefts opened through which the darkness D:began to ooze, a darkness blacker than the night, which crawled D:down as a set of slimy tentacles, taking on more form, more D:definite shape... something was standing, outlined against D:the black sky, something which had tentacles of darkness D:and a green-glowing eye." N:827:Pazuzu, Lord of Air G:U:b I:140:55d100:40:125:10 W:82:2:0:30000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:ELEC:12d12 B:HIT:ELEC:12d12 B:HIT:ELEC:12d12 B:HIT:ELEC:12d12 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:EVIL | DEMON | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | F:IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND S:1_IN_3 | S:MIND_BLAST | BO_ELEC | BO_MANA | BA_ELEC | S_HI_DEMON D:A winged humanoid demon from the Planes of Hell, Pazuzu grins inhumanely at you D:as he decides your fate. N:828:Ithaqua the Windwalker G:Y:B I:140:55d100:40:125:10 W:82:2:0:32500 E:1:1:1:2:1:1 O:0:0:100:0 B:CLAW:COLD:12d12 B:CLAW:COLD:12d12 B:CRUSH:ELEC:12d12 B:CRUSH:ELEC:12d12 F:UNIQUE | CAN_SPEAK | ESCORT | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | AURA_COLD | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | AURA_ELEC | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | NONLIVING | F:EVIL | DEMON | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | F:IM_POIS | NO_CONF | NO_SLEEP | CTHANGBAND S:1_IN_3 | S:BO_MANA | SCARE | BR_COLD | S_DEMON | BO_ELEC | BA_ELEC | S:MIND_BLAST | CAUSE_4 | BA_CHAO | BA_WATE | S_HI_UNDEAD | S_KIN D:The Wendigo, moving so fast that you can see little except two D:glowing eyes burning with hatred. N:829:Greater Hellhound G:C:r I:120:48d30:25:80:30 W:78:2:600:600 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:FIRE:5d12 B:BITE:FIRE:5d12 B:BITE:FIRE:5d12 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE F:RAND_25 | FRIENDS | AURA_FIRE | SUSCEP_COLD | F:BASH_DOOR | MOVE_BODY | F:ANIMAL | EVIL | IM_FIRE | BASEANGBAND | HAS_LITE | S:1_IN_5 | BR_FIRE D:It is a giant dog that glows with heat. Flames pour from its nostrils. N:830:Cantoras, the Skeletal Lord G:s:v I:140:75d100:20:120:80 W:84:2:0:45000 E:1:1:1:2:1:1 O:50:0:50:0 B:GAZE:EXP_80:5d5 B:GAZE:EXP_80:5d5 B:TOUCH:POISON:5d5 B:TOUCH:POISON:5d5 F:UNIQUE | MALE | CAN_SPEAK | RES_TELE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_2 | S:TELE_TO | SLOW | SCARE | CAUSE_4 | BRAIN_SMASH | S:BO_ICEE | BO_MANA | BA_WATE | BA_NETH | S:S_HI_UNDEAD | ANIM_DEAD D:A legion of evil undead druj animating the skeleton of a once mighty D:sorcerer. His power is devastating and his speed unmatched in the D:underworld. Flee his wrath! N:831:Mephistopheles, Lord of Hell G:U:r I:140:30d222:20:150:50 W:84:2:0:42500 E:1:1:1:2:1:1 O:0:100:0:0 B:GAZE:EXP_80:10d5 B:GAZE:TERRIFY:10d5 B:TOUCH:FIRE:4d15 B:TOUCH:UN_POWER:4d15 F:MALE | UNIQUE | CAN_SPEAK | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:IM_FIRE | RES_PLAS | RES_NETH | AURA_FIRE | F:NO_CONF | NO_SLEEP | NONLIVING | EVIL | DEMON | F:ESCORTS | IM_COLD | IM_POIS | ZANGBAND | HAS_LITE S:1_IN_3 | S:TELE_TO | SCARE | HOLD | BRAIN_SMASH | S:S_DEMON | S_HI_UNDEAD | S_UNDEAD | S:BR_FIRE | BR_NETH | S_HI_DEMON | HAND_DOOM | ANIM_DEAD D:A duke of hell, in the flesh. N:832:Godzilla G:R:v I:130:85d100:50:185:20 W:84:2:900000:35000 E:0:1:0:2:1:0 O:100:0:0:0 B:CLAW:POISON:5d10 B:CLAW:POISON:5d10 B:BITE:HURT:20d10 B:CRUSH:UN_BONUS:5d12 F:UNIQUE | CAN_SWIM | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | RES_PLAS | RES_DISE | RES_TELE F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | IM_FIRE | IM_COLD | IM_POIS F:MORTAL | JOKEANGBAND S:1_IN_2 | S:BR_DISE | BR_PLAS | BR_NUKE | BR_POIS | BR_ACID D:Godzilla rose from the contaminated sea. This terrible creature could D:level whole cities in anger. N:833:Abhoth, Source of Uncleanness G:j:G I:130:80d105:50:150:0 W:85:3:0:40000 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:ACID:11d11 B:TOUCH:DISEASE:11d11 B:TOUCH:ACID:11d11 B:TOUCH:POISON:11d11 F:ONLY_ITEM | DROP_1D2 | CAN_SWIM | F:DROP_GOOD | DROP_GREAT | F:CAN_SPEAK | EVIL | UNIQUE | NEVER_MOVE | FORCE_MAXHP | FORCE_SLEEP | F:IM_ACID | IM_POIS | IM_COLD | IM_ELEC | RES_NETH | RES_WATE | RES_NEXU | F:NO_FEAR | NO_CONF | NO_SLEEP | DEMON | SMART | ELDRITCH_HORROR | F:COLD_BLOOD | RES_DISE | NO_STUN | CTHANGBAND | NO_CUT S:1_IN_6 | S:S_MONSTERS | S_DEMON | S_HI_DRAGON | S_HI_UNDEAD | HEAL | S:TELE_AWAY | TPORT | CAUSE_4 | BRAIN_SMASH | DRAIN_MANA | S:BR_NUKE | BR_POIS | BR_CHAO | BR_NEXU | ANIM_DEAD D:"...in the pool [there was] a grayish, horrid mass that nearly choked D:it from rim to rim. Here, it seemed, was the ultimate source of all D:miscreation and abomination. For the gray mass quobbed and quivered, D:and swelled perpetually; and from it, in manifold fission, were D:spawned the anatomies that crept away on every side through the D:grotto." N:834:Ymir, the Ice Giant G:P:w I:130:86d110:50:160:20 W:71:2:0:32500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:COLD:9d11 B:HIT:HURT:9d11 B:HIT:COLD:9d11 B:HIT:HURT:9d11 F:UNIQUE | CAN_SPEAK | SUSCEP_FIRE | F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | RES_NETH | RES_WATE | MALE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | EVIL | ESCORT | GIANT | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | TAKE_ITEM | RES_DISE | F:EVIL | IM_COLD | IM_POIS | SUSCEP_FIRE | F:COLD_BLOOD | AURA_COLD | DROP_CORPSE | ZANGBAND | HAS_LITE | NO_CUT S:1_IN_5 | S:BR_COLD | BO_ICEE | DARKNESS | TELE_TO | S_KIN | S_HI_UNDEAD | S:TELE_AWAY | HAND_DOOM D:Ymir is one of the oldest beings in existence. He looks like a giant D:humanoid made of ice. N:835:Loki, the Trickster G:P:D I:130:110d100:50:160:20 W:85:2:0:75000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:BLIND:6d11 B:HIT:UN_BONUS:6d11 B:HIT:UN_POWER:6d11 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | RES_NETH | RES_PLAS | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_GREAT | EVIL | AURA_FIRE | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | TAKE_ITEM | CAN_SPEAK | F:EVIL | IM_FIRE | NO_CONF | NO_SLEEP | IM_POIS | SUSCEP_COLD | GIANT | F:REGENERATE | ZANGBAND | HAS_LITE S:1_IN_5 | S:SHRIEK | HASTE | HEAL | DRAIN_MANA | TPORT | TELE_TO | TELE_AWAY | S:TELE_LEVEL | FORGET | S_HI_DEMON | HAND_DOOM | S_HI_UNDEAD | S:S_UNIQUE | S_HI_DRAGON | BA_DARK | BA_MANA | ANIM_DEAD D:Loki, the god of mischief, is a nasty person. He will use every D:dirty trick in the book, and then some. In the end, his half-giant D:heritage is bound to show, as he will defect to the side of the D:giants and fight against the other gods of Asgard. N:836:Star-spawn of Cthulhu G:U:G I:130:75d100:90:90:90 W:86:2:0:44000 E:0:0:0:0:0:0 O:0:0:100:0 B:CLAW:POISON:1d30 B:CLAW:ACID:1d30 B:TOUCH:UN_POWER:1d10 B:CRUSH:UN_BONUS:2d33 F:RAND_25 | KILL_ITEM | OPEN_DOOR | BASH_DOOR | RES_NETH | ELDRITCH_HORROR | F:DROP_1D2 | DROP_2D2 | DROP_90 | ONLY_ITEM | FORCE_SLEEP | FORCE_MAXHP | F:EVIL | DEMON | IM_POIS | IM_COLD | IM_ACID | IM_ELEC | RES_TELE | NONLIVING | F:POWERFUL | IM_FIRE | CAN_SWIM | CTHANGBAND S:1_IN_3 S:SCARE | CONF | S_DEMON | S_UNDEAD | DRAIN_MANA | BR_ACID | S:BR_FIRE | TPORT | S_MONSTERS | BRAIN_SMASH | BR_NETH | S:HEAL | MIND_BLAST | BA_NUKE | ANIM_DEAD D:The last remnants of sanity threaten to leave your brain as you D:behold this titanic bat-winged, octopus-headed unholy abomination. D:"They all lay in stone houses in their great city of R'lyeh, D:preserved by the spells of mighty Cthulhu for a glorious D:resurrection when the stars and the earth might once more D:be ready..." N:837:Surtur, the Fire Giant G:P:r I:130:86d110:50:160:20 W:71:2:0:32500 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:FIRE:9d11 B:HIT:HURT:9d11 B:HIT:FIRE:9d11 B:HIT:HURT:9d11 F:UNIQUE | SUSCEP_COLD | F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | RES_NETH | RES_PLAS | MALE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | EVIL | AURA_FIRE | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | TAKE_ITEM | CAN_SPEAK | F:EVIL | IM_FIRE | NO_CONF | NO_SLEEP | IM_POIS | SUSCEP_COLD | GIANT | F:ZANGBAND | HAS_LITE S:1_IN_5 | S:BR_FIRE | BR_PLAS | BLIND | TELE_TO | S_KIN | S:HAND_DOOM | TELE_AWAY | S_HI_DEMON D:Surtur is another of the most ancient of all creatures. He is a demonic D:giant of fire, who is destined to set the nine worlds afire with his D:accursed sword of doom on the day of Ragnarok. N:838:The Tarrasque G:R:v I:130:130d100:50:185:20 W:84:2:50000:35000 E:1:1:1:2:1:1 O:20:50:25:5 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:TOUCH:UN_POWER:10d10 B:TOUCH:UN_POWER:10d10 F:UNIQUE | ATTR_MULTI | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | IM_FIRE | IM_COLD | NO_SLEEP | BASEANGBAND S:1_IN_2 | S:BR_FIRE | BR_COLD | BR_DISE D:The Tarrasque is a massive reptile of legend, rumoured to be unkillable D:and immune to magic. Fear its anger, for its devastation is unmatched! N:839:Lungorthin, the Balrog of White Fire G:U:v I:130:80d100:20:125:80 W:88:2:14000:37000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:FIRE:8d12 B:HIT:FIRE:8d12 B:CRUSH:HURT:8d12 B:TOUCH:UN_POWER F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | ESCORTS | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DEMON | IM_FIRE | F:NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_FIRE | BR_PLAS | S:S_HI_DEMON | S_UNDEAD D:A massive form cloaked in flame. Lungorthin stares balefully at you with D:eyes that smoulder red. The dungeon floor where he stands is scorched by D:the heat of his body. N:840:Draugluin, Sire of All Werewolves G:C:v I:130:80d100:80:90:90 W:83:2:1000:40000 E:0:1:0:2:1:0 O:0:0:100:0 B:CLAW:HURT:6d8 B:CLAW:HURT:6d8 B:BITE:POISON:6d6 B:BITE:POISON:6d6 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | ESCORTS | DROP_CORPSE | F:RAND_25 | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:ANIMAL | EVIL | IM_POIS | BASEANGBAND S:1_IN_3 | S:SCARE | S_MONSTERS | S_HOUND D:Draugluin provides Sauron with a fearsome personal guard. He is an D:enormous wolf inhabited by a human spirit. He is chief of all his kind. N:841:Shuma-Gorath G:e:G I:130:85d100:50:150:0 W:88:3:0:47000 E:0:0:0:0:0:0 O:0:0:100:0 B:CRUSH:HURT:12d12 B:CRUSH:HURT:12d12 B:GAZE:LOSE_INT:2d12 B:GAZE:LOSE_WIS:2d12 F:ONLY_ITEM | DROP_1D2 | CAN_SWIM | F:DROP_GOOD | DROP_GREAT | F:CAN_SPEAK | EVIL | UNIQUE | NEVER_MOVE | FORCE_MAXHP | FORCE_SLEEP | F:IM_ACID | IM_POIS | IM_COLD | IM_ELEC | RES_NETH | RES_WATE | RES_NEXU | F:NO_FEAR | NO_CONF | NO_SLEEP | DEMON | SMART | ELDRITCH_HORROR | F:COLD_BLOOD | RES_DISE | CTHANGBAND | NO_CUT S:1_IN_2 | S:FORGET | HEAL | HAND_DOOM | BA_MANA | TPORT | TELE_AWAY | S:TELE_LEVEL | CONF | BLIND | BRAIN_SMASH | DRAIN_MANA | S:S_MONSTERS | S_KIN | S_HI_DEMON | S_HOUND | S_HYDRA | S:S_UNIQUE | S_HI_UNDEAD | S_HI_DRAGON | ANIM_DEAD D:Shuma-Gorath is one of the immortal lords of chaos. The true form of D:this blasphemous horror is a huge, all-seeing eye surrounded by tentacles. N:842:Tulzscha, the Green Flame G:E:G I:130:100d100:90:100:50 W:89:4:0:45000 E:0:0:0:0:0:0 O:0:100:0:0 B:HIT:HURT:2d50 B:HIT:HURT:2d50 B:HIT:HURT:2d50 B:HIT:HURT:2d50 F:RAND_25 | EVIL | DEMON | AURA_FIRE | AURA_COLD | ELDRITCH_HORROR | F:DROP_2D2 | DROP_4D2 | DROP_GOOD | ONLY_ITEM | RES_TELE | F:IM_POIS | IM_FIRE | FORCE_SLEEP | FORCE_MAXHP | NONLIVING | F:IM_COLD | IM_ACID | IM_ELEC | RES_NEXU | RES_NETH | RES_PLAS | F:REGENERATE | UNIQUE | CTHANGBAND | HAS_LITE | NO_CUT | NO_SLEEP | NO_FEAR S:1_IN_3 | S:BR_NEXU | BR_NETH | BR_COLD | BR_FIRE D:"A belching column of sick greenish flame... spouting volcanically D:from the depths profound and inconceivable, casting no shadows as D:healthy flame should, and coating the nitrous stone with a nasty, D:venomous verdigris. For all that seething combustion no warmth D:lay, but only the clamminess of death and corruption." N:843:Oremorj, the Cyberdemon Lord G:U:u I:130:90d100:90:90:90 W:89:4:0:50000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:2d50 B:HIT:HURT:2d50 B:HIT:HURT:2d50 B:HIT:HURT:2d50 F:RAND_25 | EVIL | DEMON | SUSCEP_ACID | F:DROP_2D2 | DROP_GOOD | ONLY_ITEM | RES_TELE | DROP_GREAT | UNIQUE | NO_SLEEP | F:IM_POIS | IM_FIRE | FORCE_SLEEP | FORCE_MAXHP | NONLIVING | JOKEANGBAND | F:HAS_LITE S:1_IN_3 | S:ROCKET | S_HI_DEMON D:The mightiest of Cyberdemons, their lord and ruler. N:844:Vecna, the Emperor Lich G:L:v I:130:80d100:100:100:0 W:92:3:0:45000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:EXP_80:7d12 B:HIT:LOSE_DEX:7d12 B:HIT:UN_POWER:7d12 B:HIT:UN_POWER:7d12 F:UNIQUE | MALE | CAN_SPEAK | RES_TELE F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_SLEEP | BASEANGBAND F:NO_CUT S:1_IN_3 | S:TPORT | BLIND | SCARE | CAUSE_4 | BRAIN_SMASH | S:BA_MANA | BO_MANA | BA_FIRE | BA_NETH | S:S_MONSTERS | S_HI_DEMON | S_HI_UNDEAD | S_KIN | HAND_DOOM | ANIM_DEAD D:The greatest of all undead sorcerers, even the gods once feared him. This D:ancient shadow of death wilts every living thing it passes. N:845:Yog-Sothoth, the All-in-One G:j:v I:130:66d99:100:100:20 W:90:3:0:45000 E:0:0:0:0:0:0 O:0:0:100:0 B:TOUCH:HURT:40d5 B:TOUCH:LOSE_CON:16d2 B:TOUCH:LOSE_CON:16d2 F:UNIQUE | CAN_SPEAK | SMART | ELDRITCH_HORROR | RES_TELE F:PASS_WALL | FORCE_SLEEP | FORCE_MAXHP | AURA_ELEC | AURA_FIRE | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | ATTR_MULTI | ATTR_ANY | AURA_COLD | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | NONLIVING | CAN_FLY | F:EVIL | IM_ACID | IM_COLD | IM_ELEC | IM_POIS | IM_FIRE | NO_CONF | NO_SLEEP F:CTHANGBAND | HAS_LITE | NO_CUT S:1_IN_3 | S:BO_MANA | BRAIN_SMASH | BA_MANA | S_MONSTERS | S_HI_DEMON | S:BA_CHAO | S_DEMON | S_HI_UNDEAD | S_HOUND | BR_MANA | BR_DISI D:"Great globes of light massing towards the opening... the breaking D:apart of the nearest globes, and the protoplasmic flesh that D:flowed blackly outward to join together and form that eldritch, D:hideous horror from outer space... whose mask was a congeries D:of iridescent globes... who froths as primal slime in nuclear D:chaos forever beyond the nethermost outposts of space and time!" N:846:Fenris Wolf G:C:D I:130:70d100:80:90:40 W:90:2:0:35000 E:0:1:0:2:1:0 O:20:0:80:0 B:BITE:HURT:20d6 B:CLAW:HURT:8d8 B:CLAW:HURT:8d8 B:BITE:HURT:20d6 F:UNIQUE | CAN_SPEAK | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | F:RAND_25 | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | KILL_BODY | NO_SLEEP F:ANIMAL | EVIL | IM_POIS | IM_FIRE | IM_COLD | ZANGBAND S:1_IN_8 | S:BR_DARK | BR_POIS | BR_COLD D:The immensely huge wolf who would swallow the sun to satisfy its D:hunger - and leave the gods for dessert. N:847:Great Wyrm of Power G:D:v I:130:111d111:40:160:70 W:85:4:220000:47500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:8d12 B:CLAW:HURT:8d12 B:BITE:HURT:10d14 B:BITE:HURT:10d14 F:FORCE_SLEEP | FORCE_MAXHP | MOVE_BODY | AURA_FIRE | REFLECTING | AURA_ELEC | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | AURA_COLD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | RES_NETH | RES_DISE | F:DRAGON | GOOD | RES_TELE | DROP_CORPSE | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | F:RES_NEXU | RES_PLAS | CAN_FLY | BASEANGBAND | HAS_LITE | NO_CUT F:ATTR_MULTI S:1_IN_4 | S:S_HI_DRAGON | S_DRAGON | S_KIN | S:BR_ACID | BR_ELEC | BR_FIRE | S:BR_COLD | BR_POIS | BR_NETH | BR_LITE | BR_DARK | S:BR_CONF | BR_SOUN | BR_CHAO | BR_DISE | BR_NEXU | S:BR_TIME | BR_INER | BR_GRAV | BR_SHAR | BR_PLAS | S:BR_WALL | BR_MANA | BR_DISI D:The mightiest of all dragonkind, a great wyrm of power is seldom D:encountered in our world. It can crush stars with its might. N:848:Shub-Niggurath, Black Goat of the Woods G:U:D I:130:65d99:100:100:20 W:91:3:0:47500 E:0:0:0:0:0:0 O:0:0:100:0 B:CRUSH:LOSE_WIS:20d5 B:CRUSH:LOSE_INT:20d5 B:BITE:LOSE_STR:10d2 B:BITE:LOSE_CON:10d2 F:UNIQUE | CAN_SPEAK | FEMALE | ELDRITCH_HORROR | AURA_ELEC | RES_TELE | F:ATTR_MULTI | FORCE_SLEEP | FORCE_MAXHP | PASS_WALL | ATTR_ANY | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_90 | NONLIVING | CAN_FLY | F:SMART | OPEN_DOOR | BASH_DOOR | REGENERATE | DEMON | AURA_COLD | F:EVIL | IM_ACID | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | CTHANGBAND S:1_IN_3 | S:BO_MANA | BRAIN_SMASH | BA_DARK | S_MONSTERS | S:CAUSE_4 | HEAL | BR_CHAO | BR_CONF | BR_POIS | BR_NUKE | S:BA_CHAO | S_HI_DEMON | S_HI_UNDEAD | S_UNIQUE | ANIM_DEAD D:This horrendous outer god looks like a writhing cloudy mass filled D:with mouths and tentacles. N:849:Nodens, Lord of the Great Abyss G:P:W I:130:75d99:100:100:20 W:81:3:0:48000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:2d66 B:HIT:HURT:2d66 B:HIT:HURT:2d66 B:HIT:HURT:2d66 F:UNIQUE | CAN_SPEAK | MALE | F:FORCE_SLEEP | FORCE_MAXHP | PASS_WALL | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_90 | DROP_GREAT | F:SMART | OPEN_DOOR | BASH_DOOR | REGENERATE | CAN_FLY | F:GOOD | IM_ACID | IM_COLD | IM_POIS | IM_FIRE | IM_ELEC | F:RES_NEXU | RES_NETH | RES_WATE | ZANGBAND | HAS_LITE S:1_IN_1 | S:TELE_AWAY | TELE_TO | TELE_LEVEL | TPORT | S:BO_MANA | BA_MANA | S_MONSTERS | HEAL | S:CAUSE_4 | HASTE | HAND_DOOM | S:S_ANGEL | S_UNIQUE D:The hoary Lord of the Great Abyss seems a wizened man, D:but appearances can be deceiving. N:850:Carcharoth, the Jaws of Thirst G:C:D I:130:90d100:80:110:10 W:94:1:3400:40000 E:0:1:0:2:1:0 O:30:10:60:0 B:CLAW:POISON:9d12 B:CLAW:POISON:9d12 B:BITE:FIRE:9d12 B:BITE:FIRE:9d12 F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | AURA_FIRE | F:SMART | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:ANIMAL | EVIL | IM_FIRE | IM_POIS | BASEANGBAND S:1_IN_3 | S:BR_DARK | BR_POIS | BR_FIRE | BR_NETH | S_HOUND D:The first guard of Angband, Carcharoth, also known as 'The Red Maw', is D:the largest wolf to ever walk the earth. He is highly intelligent and a D:deadly opponent in combat. N:851:Nyarlathotep, the Crawling Chaos G:U:r I:130:90d99:100:100:20 W:93:3:0:49000 E:0:0:0:0:0:0 O:0:50:50:0 B:CRUSH:LOSE_CON:30d4 B:CRUSH:LOSE_STR:30d4 B:GAZE:LOSE_INT:1d50 B:GAZE:LOSE_WIS:1d50 F:UNIQUE | CAN_SPEAK | ELDRITCH_HORROR | RES_TELE | NONLIVING | F:FORCE_SLEEP | FORCE_MAXHP | PASS_WALL | DEMON | RES_NEXU | F:SHAPECHANGER | ATTR_MULTI | ATTR_ANY | MALE | AURA_ELEC | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_GREAT | DROP_90 | F:SMART | OPEN_DOOR | BASH_DOOR | REGENERATE | AURA_COLD | F:EVIL | IM_ACID | IM_POIS | IM_FIRE | NO_CONF | NO_SLEEP | CTHANGBAND S:1_IN_3 | S:TELE_AWAY | TELE_TO | TELE_LEVEL | TPORT | BR_NEXU | BA_CHAO | S:BA_MANA | BA_FIRE | S_MONSTERS | BRAIN_SMASH | MIND_BLAST | S:CAUSE_4 | HASTE | S_HI_UNDEAD | S_HI_DRAGON | ANIM_DEAD | S:S_ANGEL | HEAL | S_SPIDER | S_HOUND | S_HI_DEMON | HAND_DOOM D:Nyarlathothep is the messenger, the heart and the soul of the outer gods. D:He is a shapechanger capable of assuming thousands of nightmarish forms. D:One of them looks like this: "A tall, slim figure with the young face of D:an antique pharaoh, gay with prismatic robes and crowned with a D:pshent that glowed with inherent light... the fascination of a D:dark god or fallen archangel, and around whose eyes there lurked D:the languid sparkle of capricious humor." N:852:Azathoth, the Daemon Sultan G:E:B I:130:99d99:100:150:100 W:93:3:0:50000 E:0:0:0:0:0:0 O:0:50:0:50 B:CRUSH:HURT:35d5 B:CRAWL:ACID:35d5 B:CRUSH:HURT:35d5 B:CRAWL:ACID:35d5 F:UNIQUE | ELDRITCH_HORROR | RES_TELE F:FORCE_SLEEP | FORCE_MAXHP | KILL_WALL | DEMON | AURA_FIRE | AURA_ELEC | F:ATTR_MULTI | ESCORTS | ESCORT | POWERFUL | ATTR_ANY | NONLIVING | F:KILL_ITEM | KILL_WALL | CAN_SWIM | AURA_COLD F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_90 | RES_DISE | F:STUPID | OPEN_DOOR | BASH_DOOR | REGENERATE | EMPTY_MIND | F:EVIL | IM_ACID | IM_POIS | IM_FIRE | NO_CONF | NO_SLEEP | NO_STUN | CTHANGBAND F:HAS_LITE | NO_CUT S:1_IN_5 | S:S_DEMON | BR_CHAO | BR_DISE | BR_MANA | BA_WATE | BR_DISI D:"That last amorphous blight of nethermost confusion which D:blasphemes and bubbles at the centre of all infinity -- D:the boundless daemon sultan Azathoth, whose name no lips D:dare speak aloud, and who gnaws hungrily in inconceivable, D:unlighted chambers beyond time amidst the muffled, maddening D:beating of vile drums and the thin monotonous whine of D:accursed flutes." N:853:Huan, Wolfhound of the Valar G:C:W I:130:90d100:50:160:10 W:93:2:3400:40000 E:0:1:0:2:1:0 O:30:10:60:0 B:CLAW:COLD:9d12 B:CLAW:COLD:9d12 B:BITE:COLD:9d12 B:BITE:COLD:9d12 F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | AURA_COLD | F:SMART | OPEN_DOOR | BASH_DOOR | KILL_BODY | F:ANIMAL | GOOD | F:IM_COLD | IM_ACID | IM_ELEC | BASEANGBAND S:1_IN_5 | S:BR_COLD | BR_SHAR | BR_SOUN | BR_LITE | D:The wolfhound of the Valar, Huan has served many masters in his time, from D:Celegorm son of Feanor to Beren son of Barahir: but now he runs wild and D:acknowledges no master save himself, as he hunts alone for his nemesis - D:Carcharoth, the terrible wolf of Angband. N:854:Jormungand the Midgard Serpent G:J:v I:130:120d120:100:200:0 W:94:1:3000:45000 E:0:1:0:2:1:0 O:0:0:0:0 B:CRUSH:HURT:20d10 B:CRUSH:HURT:20d10 B:BITE:HURT:5d50 F:UNIQUE | FORCE_MAXHP | FORCE_SLEEP | WILD_TOO | WILD_OCEAN | WILD_SWAMP | F:MOVE_BODY | KILL_WALL | IM_FIRE | IM_POIS | IM_ACID | IM_COLD | COLD_BLOOD | F:RES_WATE | RES_PLAS | RES_NEXU | NO_STUN | REGENERATE | DROP_CORPSE | F:NO_CONF | NO_SLEEP | ZANGBAND S:1_IN_3 S:BA_WATE | BR_MANA | BR_NETH | BR_POIS | BR_DISI | S_KIN D:The Midgard Serpent is so huge that its body surrounds the world of D:mortal men. It could grind even the gods into lifeless pulp. N:855:The Destroyer G:g:v I:130:140d140:100:200:0 W:94:1:0:45000 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:30d9 B:HIT:HURT:30d9 B:HIT:HURT:30d9 B:HIT:HURT:30d9 F:UNIQUE | NONLIVING | NO_FEAR | FORCE_MAXHP | FORCE_SLEEP | REFLECTING | F:MOVE_BODY | KILL_WALL | IM_FIRE | IM_ELEC | IM_POIS | IM_ACID | IM_COLD | F:RES_NETH | RES_WATE | RES_PLAS | RES_NEXU | NO_STUN | REGENERATE | F:NO_CONF | NO_SLEEP | NO_STUN | CAN_FLY | F:EMPTY_MIND | COLD_BLOOD | BASH_DOOR | ZANGBAND | NO_CUT S:1_IN_3 | S:BR_DISI | BO_MANA D:The Destroyer was built by the Norse deities to be their ultimate weapon D:against the space gods who had arrived to judge the world. Unfortunately, D:the Destroyer has gone berserk and is destroying everything it sees. The D:mystical Destroyer is nearly indestructible, and it is said that when it D:uses its power of complete disintegration, the day of Ragnarok is near. N:856:Gothmog, the High Captain of Balrogs G:U:v I:130:120d100:100:140:0 W:95:1:17000:43000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:FIRE:9d12 B:HIT:FIRE:9d12 B:CRUSH:HURT:8d12 B:TOUCH:UN_POWER F:UNIQUE | MALE | CAN_SPEAK | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | F:ESCORT | ESCORTS | KILL_WALL | AURA_FIRE | NONLIVING | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DEMON | F:IM_FIRE | IM_ELEC | BASEANGBAND | HAS_LITE S:1_IN_3 | S:BLIND | CONF | SCARE | S:BR_FIRE | S_KIN | S:S_HI_DEMON | S_HI_UNDEAD D:Gothmog is the Chief Balrog in Morgoth's personal guard. He is renowned D:for slaying three High Kings of the Noldor Elves, and he has never been D:defeated in combat. With his whip of flame and awesome fiery breath he D:saved his master from Ungoliant's rage. N:857:Great Cthulhu G:U:g I:130:100d100:100:140:100 W:97:2:4000:62500 E:0:0:0:0:0:0 O:0:50:50:0 B:CRUSH:HURT:50d4 B:CLAW:UN_POWER:15d2 B:CLAW:UN_BONUS:15d2 B:TOUCH:DISEASE:100d1 F:UNIQUE | CAN_SPEAK | DEMON | ELDRITCH_HORROR | NONLIVING | F:FORCE_SLEEP | FORCE_MAXHP | ESCORT | ESCORTS | SMART | RES_PLAS | RES_NEXU | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | REGENERATE | RES_NETH | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_1D2 | DROP_GOOD | F:DROP_GREAT | RES_DISE | RES_TELE | CAN_SWIM | F:EVIL | DEMON | IM_FIRE | IM_POIS | IM_ELEC | IM_ACID | NO_CONF | NO_SLEEP | F:CTHANGBAND S:1_IN_3 S:TPORT | SCARE | BLIND | MIND_BLAST | BRAIN_SMASH | DRAIN_MANA | S:BR_POIS | BR_ACID | BR_FIRE | CONF | DARKNESS | FORGET | S_HI_UNDEAD | S:BR_NUKE | BR_NETH | BR_CHAO | BR_DISE | BR_DARK | BR_PLAS | BR_CONF S:BR_NEXU | S_HI_DEMON | BR_DISI | HAND_DOOM | S:ANIM_DEAD D:This creature is death incarnate. "A monster of vaguely anthropoid D:outline, but with an octopus-like head whose face was a mass of D:feelers, a scaly, rubbery-looking body, prodigious claws on hind D:fore feet, and long, narrow wings behind. This thing... was a D:somewhat bloated corpulence... It lumbered slobberingly into sight D:and gropingly squeezed its gelatinous green immensity through the D:black doorway... A mountain shambled or walked." N:858:Sarko, rider of gold Foronth G:B:y I:145:99d111:100:165:0 W:97:6:420000:65000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:12d12 B:HIT:HURT:12d12 B:HIT:FIRE:12d12 B:HIT:FIRE:12d12 F:UNIQUE | FEMALE | DROP_CORPSE | F:ATTR_MULTI | THUNDERLORD | RES_TELE | PET | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | GOOD | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:DROP_CHOSEN | REFLECTING | AURA_FIRE | AURA_ELEC | F:SMART | OPEN_DOOR | BASH_DOOR | MOVE_BODY | REGENERATE | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | POWERFUL | F:MORTAL | HAS_LITE S:1_IN_4 | S:TPORT | TELE_TO | BR_FIRE | BR_TIME | S_THUNDERLORD | TELE_AWAY | D:Foronth is the first Eagle queen, and Sarko the first to discover D:the Firebirds, the ancestor of the Thunderlord eagles. She will try to D:help you! N:859:The Unicorn of Order G:q:w I:130:66d100:30:170:150 W:75:2:0:65000 E:0:1:0:2:1:0 O:25:50:25:0 B:KICK:UN_POWER:13d13 B:KICK:UN_POWER:12d12 B:BUTT:UN_BONUS:11d11 B:BITE:TIME:10d10 F:UNIQUE | FORCE_SLEEP | FORCE_MAXHP | REFLECTING | AURA_COLD | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:SMART | KILL_BODY | POWERFUL | BASH_DOOR | REGENERATE | CAN_FLY | F:ANIMAL | GOOD | IM_ACID | IM_COLD | IM_ELEC | F:NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | RES_TELE | ZANGBAND S:1_IN_3 | S:BR_SOUN | BR_LITE | BR_TIME | BR_SHAR | BR_MANA | S:S_MONSTERS | HEAL | S_ANGEL D:The Unicorn of Order, who once stole an eye from the great Serpent D:of Chaos, regards you as a mortal meddling in the affairs of immortals, D:and thus is attempting to eliminate you. N:860:Sauron, the Sorcerer G:p:v I:130:100d225:100:160:0 W:99:1:2300:50000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:UN_BONUS:10d12 B:HIT:UN_BONUS:10d12 B:HIT:UN_POWER:8d12 B:HIT:UN_POWER:8d12 F:UNIQUE | MALE | CAN_SPEAK | REFLECTING | F:FORCE_SLEEP | FORCE_MAXHP | FORCE_DEPTH | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:SMART | OPEN_DOOR | BASH_DOOR | MOVE_BODY | REGENERATE | NO_SLEEP | NO_FEAR | NO_CONF | F:EVIL | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:RES_TELE | BASEANGBAND | HAS_LITE S:1_IN_2 | S:TPORT | TELE_LEVEL | BLIND | CONF | SCARE | CAUSE_4 | S:BRAIN_SMASH | FORGET | BO_ICEE | BO_MANA | BO_PLAS | S:BA_MANA | BA_FIRE | BA_WATE | BA_NETH | BA_DARK | BA_CHAO | S:S_MONSTERS | S_HI_DEMON | S_HI_UNDEAD | S_HI_DRAGON | S_WRAITH | S_UNIQUE | S:HAND_DOOM | ANIM_DEAD D:Mighty in spells and enchantments, he created the One Ring. D:His eyes glow with power and with his gaze he seeks to destroy D:your soul. He has many servants, and rarely fights without them. N:861:DarkGod, the Mighty Coder of Hell G:P:B I:155:180d100:111:175:0 W:127:1:1600:66666 E:2:0:2:6:1:1 O:20:20:20:20 B:GAZE:EAT_GOLD:20d10 B:HIT:SHATTER:20d10 B:BITE:LOSE_ALL:10d12 B:TOUCH:UN_POWER F:UNIQUE | CAN_SPEAK | ATTR_MULTI | ATTR_ANY | MALE | F:FORCE_MAXHP | WEIRD_MIND | DROP_CORPSE | DROP_SKELETON | F:REFLECTING | AURA_FIRE | AURA_ELEC | AURA_COLD | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_3D2 | DROP_4D2 | F:DROP_GOOD | DROP_GREAT | RES_NETH | INVISIBLE | F:SMART | KILL_WALL | KILL_BODY | POWERFUL | RES_TELE | F:REGENERATE | CAN_FLY | CAN_SWIM | DG_CURSE | WYRM_PROTECT | F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF |NO_FEAR | NO_STUN | RES_TELE F:MORTAL | JOKEANGBAND | HAS_LITE S:1_IN_2 | S:S_THUNDERLORD | BR_CHAO | BA_CHAO | ROCKET | BRAIN_SMASH | S_HI_DEMON | S:BR_NETH | HASTE | BR_MANA | S_HI_UNDEAD | S_HI_DRAGON | TRAPS | FORGET | S:BR_NUKE | BR_POIS | BR_DISI | HAND_DOOM | HEAL | TPORT | TELE_TO | S:S_BUG | S_RNG | D:He is the master of coding; none can match his skill. He created the D:Variant Maintainer, the RNGs, and the software bugs. Bull Gates is D:nothing next to him. Do not think that since he loves the novels of D:Tolkien he is to be ignored! He wishes to translate your soul into D:assembler, the one hitch being that he must kill you first. If you D:encounter him, pray your deity holds you in good stead. N:862:Morgoth, Lord of Darkness G:P:D I:140:200d150:100:150:0 W:100:1:200000:60000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:SHATTER:24d10 B:HIT:SHATTER:24d10 B:HIT:LOSE_ALL:10d12 B:TOUCH:UN_POWER F:UNIQUE | CAN_SPEAK | MALE | F:FORCE_SLEEP | FORCE_MAXHP | FORCE_DEPTH | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_3D2 | DROP_4D2 | F:DROP_GOOD | DROP_GREAT | DROP_CHOSEN | RES_NETH | F:SMART | KILL_WALL | MOVE_BODY | AURA_COLD | F:REGENERATE | POWERFUL | F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_STUN | NO_SLEEP | NO_FEAR | RES_TELE | BASEANGBAND | HAS_LITE S:1_IN_3 | S:BRAIN_SMASH | S:BA_MANA | BO_MANA | BA_NETH | BA_CHAO | BA_DARK | ANIM_DEAD | S:S_MONSTERS | S_UNIQUE | S_HI_DEMON | S_HI_UNDEAD | S_HI_DRAGON | S:ROCKET | BR_NETH | BR_DISI | HAND_DOOM | S_WRAITH D:He was the most powerful of the Valar, the equal of Manwe. D:He is the Master of the Pits of Angband. His figure is like a black D:mountain crowned with Lightning. He rages with everlasting anger, his D:body scarred by Fingolfin's eight mighty wounds. He can never rest from D:his pain, but seeks forever to dominate all that is light and good in the D:world. He is the origin of man's fear of darkness and created many foul D:creatures with his evil powers. Orcs, Dragons, and Trolls are his most D:foul corruptions, causing much pain and suffering in the world to please D:him. His disgusting visage, twisted with evil, is crowned with iron, the D:two remaining Silmarils forever burning him. Grond, the mighty Hammer of D:the Underworld, cries defiance as he strides towards you to crush you to a D:pulp! N:863:Human Warrior G:p:u I:110:9d8:10:10:0 W:0:20:1700:0 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:5d8 F:MALE | F:PET | FRIENDS | WILD_ONLY | F:ONLY_GOLD | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR F:DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE D:They are used as the main assault force of the human kings. D:They will help you in some quests. N:864:Elven archer G:h:W I:110:9d7:10:10:0 W:0:20:1400:0 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:2d8 F:MALE | F:PET | FRIENDS | WILD_ONLY | F:ONLY_GOLD | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR F:DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_1 | S:ARROW_2 | ARROW_1 | ARROW_2 | ARROW_1 | D:They are used as the main assault force of the elven kings. D:They will help you in some quests. N:865:Dwarven warrior G:h:U I:110:8d8:10:10:0 W:0:20:1500:0 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:6d8 F:MALE | F:PET | FRIENDS | WILD_ONLY | F:ONLY_GOLD | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR F:DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE D:They are used as the main assault force of the dwarven kings. D:They will help you in some quests. N:866:Elite uruk G:o:w I:110:10d10:20:50:0 W:20:1:2000:70 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:8d5 B:HIT:HURT:8d5 F:MALE | F:FORCE_MAXHP | FRIENDS | DROP_60 | F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | ORC | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_8 | S:ARROW_2 D:It is a cunning orc of power, taller than a man, and stronger. It fears D:little. N:867:The Philosophy Teacher G:p:r I:120:50d100:30:50:0 W:56:1:1900:20000 E:1:1:1:2:1:1 O:20:20:20:20 B:GAZE:CONFUSE:15d5 B:GAZE:PARALYZE:15d5 B:TOUCH:INSANITY:5d5 B:TOUCH:EXP_40:5d5 F:FEMALE | UNIQUE | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_GOOD | DROP_GREAT | F:CAN_SPEAK | WEIRD_MIND | DROP_SKELETON | DROP_CORPSE | F:EVIL | NO_CONF | NO_SLEEP | JOKEANGBAND | HAS_LITE S:1_IN_3 S:BR_CONF | BR_SOUN | BR_CHAO | BR_TIME | S:HOLD | SCARE | SLOW | CONF | FORGET D:She is a feared teacher, mistress of chaos and strangely minded. D:She wants to take your mind. Fear her and flee while you can. N:868:The Variant Maintainer G:p:B I:160:10d10:30:50:0 W:10:1:1700:3000 E:1:1:1:2:1:1 O:20:20:20:20 B:INSULT:* B:HIT:INSANITY:1d8 B:HIT:LOSE_WIS:1d8 F:ONLY_ITEM | DROP_2D2 | UNIQUE | CAN_FLY | F:DROP_GOOD | WEIRD_MIND | CAN_SPEAK | F:RAND_50 | RAND_25 | INVISIBLE | EVIL | F:MORTAL | JOKEANGBAND | HAS_LITE S:1_IN_2 S:S_BUG | S_RNG | BR_CONF D:A deranged programmer, scattering bizarre ideas and bad code everywhere. N:869:Random Number Generator G:I:b I:130:1d6:10:50:0 W:10:1:0:10 E:0:0:0:0:0:0 O:20:20:20:20 B:INSULT:* B:MOAN:* B:HIT:CONFUSE:1d6 F:DROP_1D2 | EVIL | F:EMPTY_MIND | RAND_50 | RAND_25 | JOKEANGBAND S:MULTIPLY D:A feared creation of the Variant Maintainer, it tries to generate Morgoth D:in the town and the One Ring in the magic shop. N:870:Rocket mine G:.:R I:110:20d8:20:3:10 W:50:10:0:100 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:POISON:10d5 F:NEVER_MOVE | IM_POIS | NONLIVING | IM_ACID | STUPID | F:FORCE_MAXHP | UNDEAD | EVIL | JOKEANGBAND | NO_CUT S:1_IN_4 S:ROCKET | ARROW_4 D:It was left here to be used against intruders. N:871:Bouncing mine G:.:B I:120:20d15:50:5:10 W:70:10:0:200 E:0:0:0:0:0:0 O:0:0:0:0 B:SPORE:POISON:10d5 F:NEVER_MOVE | IM_POIS | NONLIVING | IM_ACID | STUPID | F:FORCE_MAXHP | UNDEAD | EVIL | JOKEANGBAND | NO_CUT S:1_IN_3 S:ROCKET | ARROW_4 | BLINK | BR_POIS | BR_CHAO | BR_NEXU D:It was left here to be used against intruders. N:872:Durin's Bane G:U:v I:130:30d100:20:100:80 W:50:3:13000:30000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:FIRE:6d12 B:HIT:FIRE:6d12 B:CRUSH:HURT:5d12 B:TOUCH:UN_POWER F:UNIQUE | MALE | SPECIAL_GENE | DROP_RANDART F:FORCE_SLEEP | FORCE_MAXHP | KILL_WALL | F:ESCORT | ESCORTS | DROP_CORPSE | NONLIVING | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_CHOSEN | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DEMON | IM_FIRE | F:NO_CONF | BASEANGBAND | HAS_LITE S:1_IN_4 | S:CONF | SCARE | S:BR_FIRE | S:S_UNDEAD | S_DEMON D:A huge Balrog surrounded by raging pillars of fire, this is indeed a D:terrible opponent. Wielding a great whip of fire and a blazing sword, his D:fury blisters your skin and melts your flesh! N:873:The Icky Queen G:i:v I:120:40d10:20:50:10 W:20:5:3000:400 E:0:0:0:0:0:0 O:40:30:10:10 B:CRAWL:POISON:3d4 B:CRAWL:EAT_FOOD:3d4 B:TOUCH:ACID:3d5 B:HIT:HURT:3d5 F:UNIQUE | FEMALE | F:FORCE_MAXHP | CAN_SPEAK | SMART | ESCORT | ESCORTS | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | DROP_CORPSE | F:WEIRD_MIND | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_ACID | IM_ELEC | IM_FIRE | IM_COLD | IM_POIS | F:MORTAL | BASEANGBAND S:1_IN_5 | S:DRAIN_MANA | BLIND | CONF | SCARE | S_KIN D:And you thought her offspring were icky! N:874:Rot jelly G:j:u I:120:20d8:2:30:99 W:5:1:2000:15 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:EAT_FOOD:2d3 B:TOUCH:LOSE_CHR:2d3 F:NEVER_MOVE | F:STUPID | EMPTY_MIND | CAN_SWIM | F:HURT_LITE | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:It is a large pile of rotting flesh, whose touch spoils your food. The terrible D:smell it exudes is also very hard to get rid of... N:875:Death G:G:D I:130:50d100:200:120:5 W:80:6:3000:25000 E:1:1:1:2:1:1 O:10:80:20:0 B:HIT:HURT:20d5 B:HIT:HURT:20d5 B:TOUCH:EXP_80:20d5 B:TOUCH:EXP_80:20d5 F:UNIQUE | F:FORCE_MAXHP | DROP_CORPSE | F:DROP_GOOD | DROP_GREAT | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | PASS_WALL | NO_SLEEP | NO_STUN | NO_CONF | F:EVIL | UNDEAD | JOKEANGBAND | NO_CUT D:"And I looked, and behold a pale horse: and his name that sat on him was D:Death, and Hell followed with him. And power was given unto them over the D:fourth part of the earth, to kill with sword, and with hunger, and with D:death, and with the beasts of the earth." N:876:Famine G:G:U I:130:50d100:200:120:5 W:77:6:3000:25000 E:1:1:1:2:1:1 O:10:80:20:0 B:TOUCH:EAT_FOOD:20d4 B:GAZE:UN_BONUS:20d4 B:WAIL:LOSE_INT:10d5 B:WAIL:LOSE_DEX:10d5 F:UNIQUE | MALE | F:FORCE_MAXHP | DROP_CORPSE | F:DROP_GOOD | DROP_GREAT | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | PASS_WALL | NO_STUN | NO_SLEEP | NO_CONF | F:EVIL | UNDEAD | JOKEANGBAND | NO_CUT D:One of the horsemen of the apocalypse, before you lies Famine. A D:figure so gaunt that the shape of the bones beneath are revealed, D:Famine rides a pale grey mare that appears near death. N:877:Pestilence G:G:G I:130:50d100:200:120:5 W:74:6:3000:25000 E:1:1:1:2:1:1 O:10:80:20:0 B:TOUCH:POISON:20d4 B:TOUCH:POISON:20d4 B:TOUCH:DISEASE:16d5 B:TOUCH:DISEASE:16d5 F:UNIQUE | MALE | F:FORCE_MAXHP | DROP_CORPSE | F:DROP_GOOD | DROP_GREAT | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | PASS_WALL | NO_SLEEP | NO_STUN | NO_CONF | F:EVIL | UNDEAD | JOKEANGBAND | NO_CUT S:1_IN_2 | S:S_ANT | S_SPIDER D:One of the horsemen of the apocalypse, before you lies Pestilence. D:At first, it looks like a human, but then you notice ants, worms, and D:worse peeking out of the flesh. Pestilence rides a purple horse with D:skin that bulges and occasionally gives hints of the vermin within. N:878:War G:G:r I:130:50d100:200:120:5 W:71:6:3000:25000 E:1:1:1:2:1:1 O:10:80:20:0 B:TOUCH:PARALYZE:20d4 B:WAIL:CONFUSE:20d4 B:GAZE:BLIND:20d4 B:WAIL:TERRIFY:20d4 F:UNIQUE | MALE | F:FORCE_MAXHP | DROP_CORPSE | F:DROP_GOOD | DROP_GREAT | DROP_60 | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | PASS_WALL | NO_SLEEP | NO_STUN | NO_CONF | NO_FEAR | F:EVIL | UNDEAD | JOKEANGBAND | NO_CUT S:1_IN_2 | S:S_MONSTER D:One of the horsemen of the apocalypse, before you lies War. A healthy and D:hearty warrior, War grins a little too wide at you as he prepares for D:combat. War rides a large well-groomed yellow horse that leaves behind D:puddles of blood where its hooves touch the ground. ##### Some aquatic monsters. ##### N:879:Pike G:~:s I:125:2d7:80:35:0 W:2:1:100:7 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:2d3 F:ANIMAL | AQUATIC | STUPID | DROP_CORPSE | COLD_BLOOD | F:MORTAL | BASEANGBAND D:It's a common fresh-water predatory fish. N:880:Electric eel G:J:B I:110:15d15:15:40:70 W:20:2:500:145 E:0:1:0:2:1:0 O:0:0:0:0 B:TOUCH:ELEC:2d7 B:TOUCH:ELEC:2d7 B:TOUCH:ELEC:2d7 F:AQUATIC | ANIMAL | RAND_25 | IM_ELEC | RES_WATE | F:WILD_TOO | WILD_OCEAN | COLD_BLOOD | F:MORTAL | BASEANGBAND D:This serpentine creature can create a deadly voltage. Better watch out! N:881:Giant crayfish G:~:R I:90:4d10:6:100:20 W:4:1:1200:10 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d4 B:CLAW:HURT:3d4 F:ANIMAL | AQUATIC | STUPID | WEIRD_MIND | DROP_CORPSE | COLD_BLOOD | F:MORTAL | BASEANGBAND D:A man-sized, heavily armoured fresh-water relative of the lobster. N:882:Mermaid G:h:G I:110:5d8:50:30:0 W:4:1:1600:20 E:1:1:1:2:1:0 O:20:50:10:5 B:TOUCH:LOSE_WIS B:TOUCH:INSANITY:2d3 B:TOUCH:CONFUSE F:FEMALE | RAND_25 | DROP_60 | SMART | AQUATIC | NO_CONF | DROP_CORPSE | F:MORTAL | ZANGBAND D:A green-skinned humanoid with a fishtail. Beware - there are rumours D:of adventures losing their minds under the fearsome D:charms of mermaids. N:883:Box jellyfish G:~:B I:110:10d10:20:30:75 W:10:2:3000:25 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:PARALYZE:1d6 B:TOUCH:PARALYZE:1d6 F:ANIMAL | AQUATIC | IM_POIS | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:A strange water creature, whose touch can be deadly. N:884:Giant piranha G:~:g I:120:6d8:30:20:10 W:10:2:300:40 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:5d1 B:BITE:HURT:5d1 F:NO_SLEEP | WILD_TOO | COLD_BLOOD | F:FRIENDS | AQUATIC | ANIMAL | F:MORTAL | BASEANGBAND D:A very large and bloodthirsty fish. N:885:Piranha G:~:g I:120:2d6:20:8:5 W:3:1:200:8 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:1d6 F:FRIENDS | AQUATIC | ANIMAL | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:Bloodthirsty fish who can smell your blood from a great distance. N:886:Bullywug G:h:g I:110:6d10:20:15:0 W:7:1:700:25 E:1:1:1:2:1:1 O:30:40:10:10 B:HIT:HURT:2d4 B:HIT:HURT:2d4 F:MALE | ONLY_ITEM | DROP_1D2 | SMART | AQUATIC | DROP_CORPSE | FRIENDS | F:MORTAL | BASEANGBAND | HAS_LITE | COLD_BLOOD D:A vaguely humanoid creature, it looks like a cross between a hobbit and a D:frog. N:887:Bullywug warrior G:h:g I:110:8d10:20:15:0 W:8:1:750:35 E:1:1:1:2:1:1 O:15:60:10:10 B:HIT:HURT:2d5 B:HIT:HURT:2d5 F:MALE | ONLY_ITEM | DROP_1D2 | SMART | AQUATIC | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE | COLD_BLOOD D:A member of the frog-people clan. He is wielding a long, sharp shark tooth. N:888:Bullywug shaman G:h:g I:110:6d10:20:15:0 W:8:1:800:35 E:1:1:1:2:1:1 O:25:10:50:10 B:HIT:HURT:1d6 B:HIT:HURT:1d6 F:MALE | ONLY_ITEM | DROP_1D2 | SMART | AQUATIC | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE | COLD_BLOOD S:1_IN_5 | S:BLIND | CONF | DARKNESS | BO_COLD | HEAL | MISSILE | CAUSE_2 D:A leader of a clan of frog-people, he is cloaked in a cloak made of D:shark skin. N:889:Whale G:~:G I:110:22d22:15:50:70 W:20:4:9000:175 E:0:0:0:0:1:0 O:0:0:0:0 B:CRUSH:HURT:1d20 B:CRUSH:HURT:1d20 F:RAND_25 | FORCE_MAXHP | RES_WATE | F:ANIMAL | AQUATIC | WILD_TOO | F:MORTAL | BASEANGBAND D:Although it looks like a fish and lives in water, it is in fact D:a mammal. And it is huge! N:890:Sand mite G:~:B I:110:3d10:5:25:80 W:10:2:500:25 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:POISON:3d6 B:BITE:POISON:3d6 F:AQUATIC | ANIMAL | IM_POIS | FRIENDS | F:CHAR_CLEAR | ATTR_CLEAR | DROP_CORPSE | COLD_BLOOD | F:MORTAL | BASEANGBAND S:MULTIPLY D:A relative of crabs and shrimp, this is a tiny creature that inhabits sandy D:bottoms. It has a pair of dangerous-looking claws. N:891:Octopus G:~:g I:105:60d6:60:60:60 W:15:2:1200:60 E:3:0:3:6:1:0 O:0:0:0:0 B:SPIT:BLIND:1d3 B:CRUSH:HURT:6d3 B:CRUSH:HURT:6d3 B:CRUSH:HURT:6d3 F:RAND_25 | IM_COLD | RES_WATE | AQUATIC | ANIMAL | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:It doesn't move very fast, but when it does - watch out! N:892:Giant octopus G:~:g I:115:100d6:10:35:5 W:30:1:1800:180 E:3:0:3:6:1:0 O:0:0:0:0 B:SPIT:BLIND:1d4 B:CRUSH:HURT:8d4 B:CRUSH:HURT:8d4 B:CRUSH:PARALYZE:8d4 F:AQUATIC | SMART | IM_POIS | ANIMAL | NO_CONF | NO_SLEEP | F:NO_FEAR | SMART | WEIRD_MIND | DROP_CORPSE | COLD_BLOOD | F:MORTAL | BASEANGBAND S:1_IN_15 | S:DARKNESS | SLOW | CONF | SCARE D:A cunning and dangerous undersea opponent. N:893:Eye of the deep G:e:b I:120:16d100:10:20:40 W:40:3:1600:6000 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:EXP_20:2d6 B:GAZE:UN_POWER:2d6 B:GAZE:INSANITY:2d6 B:BITE:HURT:6d6 F:EVIL | IM_POIS | NO_CONF | NO_SLEEP | AQUATIC | F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | RES_TELE | F:SMART | DROP_CORPSE | BASEANGBAND S:1_IN_2 | S:BLIND | SLOW | CONF | SCARE | DRAIN_MANA | MIND_BLAST | S:FORGET | DARKNESS | BO_WATE | BO_ICEE | BO_MANA | BO_COLD D:A beholder that inhabits the depths of the sea, sleeping and pondering D:alien thoughts for centuries. Occasionally, it will float to the D:surface to wreck the lives of surface dwellers. N:894:Murk dweller G:S:s I:110:200d5:70:30:0 W:27:3:3000:800 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:5d10 B:CLAW:PARALYZE B:STING:INSANITY:5d10 B:STING:UN_BONUS F:AQUATIC | ANIMAL | WEIRD_MIND | FORCE_MAXHP | HURT_LITE | F:EVIL | SMART | NO_CONF | NO_SLEEP | DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_5 | S:BA_POIS | BR_DARK | BLIND | BR_POIS | SLOW | CONF | MIND_BLAST | S:BRAIN_SMASH | DARKNESS D:A gigantic aquatic monster, somewhat resembling a cross between a D:lobster and a spider. It is coated in poisonous slime and noxious D:parasites. This foul creature hides in the silt of the deep ocean floor, D:waiting to trap unsuspecting prey. N:895:Drowned soul G:G:B I:110:9d8:5:33:50 W:11:1:0:30 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:BLIND:3d3 B:TOUCH:POISON:2d4 B:WAIL:TERRIFY F:COLD_BLOOD | EMPTY_MIND | EVIL | AQUATIC | UNDEAD | IM_COLD | INVISIBLE | F:IM_POIS | NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_8 S:BLIND | HOLD | CONF D:A ghastly victim of drowning, forever doomed to wander the ocean waters D:looking for revenge. N:896:Tiger shark G:~:g I:120:10d5:100:32:0 W:12:1:3000:40 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:4d4 F:RAND_25 | AQUATIC | ANIMAL | STUPID | DROP_CORPSE | F:MORTAL | BASEANGBAND D:A small species of shark, although the teeth are still as deadly. N:897:Hammerhead shark G:~:g I:115:16d10:20:59:20 W:16:3:1500:40 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:3d4 B:BUTT:HURT:3d4 B:BITE:HURT:3d4 F:ANIMAL | AQUATIC | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:A hungry shark with a strange head. N:898:Great white shark G:~:w I:120:100d6:20:70:20 W:24:2:5000:250 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:4d6 B:BITE:HURT:4d6 B:BITE:HURT:4d6 F:FORCE_SLEEP | AQUATIC | COLD_BLOOD | F:ANIMAL MORTAL | BASEANGBAND D:A very large carnivorous fish. N:899:Aquatic golem G:g:b I:100:25d10:35:75:10 W:19:1:0:100 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:3d10 B:HIT:HURT:3d10 F:COLD_BLOOD | EMPTY_MIND | AQUATIC | F:IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT D:An ingenious gnomish invention -- a golem designed for underwater D:usage. N:900:Aquatic kobold G:k:B I:110:13d9:10:30:15 W:5:1:1500:35 E:1:1:1:2:1:1 O:0:50:0:30 B:HIT:HURT:1d10 F:DROP_90 | EVIL | IM_POIS | AQUATIC | DROP_CORPSE | F:MORTAL | BASEANGBAND D:Yes, your favourite denizen of evil also comes in an aquatic variety. N:901:White shark G:~:W I:120:30d10:20:50:10 W:18:1:3000:100 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:3d5 B:BITE:HURT:3d5 B:BITE:HURT:3d5 F:ANIMAL | AQUATIC | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:A fast-moving hunter of the depths. When this creature moves, D:everybody in the water is in danger! N:902:Scrag G:T:B I:110:40d10:20:50:50 W:35:1:5000:440 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d10 B:HIT:HURT:1d10 B:HIT:HURT:3d2 B:HIT:HURT:3d2 F:MALE | F:FORCE_MAXHP | AQUATIC | REGENERATE | F:FRIENDS | DROP_60 | WILD_TOO | WILD_OCEAN | F:OPEN_DOOR | BASH_DOOR | RES_WATE | F:EVIL | TROLL | IM_COLD | IM_POIS | HURT_LITE | BASEANGBAND D:A troll of the sea, he reeks of brine. N:903:Jaws G:~:w I:130:100d20:200:80:70 W:40:2:7000:2000 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:11d2 B:BITE:HURT:22d1 B:BITE:HURT:11d2 B:BITE:HURT:22d1 F:FORCE_MAXHP | UNIQUE | MOVE_BODY | F:WILD_OCEAN | WILD_TOO | COLD_BLOOD | F:BASH_DOOR | IM_COLD | IM_ELEC | IM_POIS | ANIMAL | AQUATIC | F:NO_CONF | NO_SLEEP | F:MORTAL | ZANGBAND D:The biggest white shark who has ever lived, it is hunting for you now! N:904:Aquatic elf G:h:b I:110:14d8:30:30:6 W:9:1:1400:25 E:1:1:1:2:1:0 O:20:20:50:10 B:HIT:HURT:3d4 F:MALE | AQUATIC | SMART | DROP_CORPSE | F:FRIENDS | DROP_60 | ZANGBAND | HAS_LITE D:A sleek form vaguely shaped like a dolphin, except with a humanoid D:head and arms. The facial features are decidedly elven. N:905:Aquatic elven warrior G:h:b I:110:20d8:40:35:5 W:10:1:1500:35 E:1:1:1:2:1:0 O:20:60:10:10 B:HIT:HURT:4d4 B:HIT:HURT:4d4 F:MALE | AQUATIC | FRIENDS | SMART | DROP_60 | DROP_CORPSE | ZANGBAND | F:HAS_LITE D:An aquatic elf trained in all forms of combat. N:906:Aquatic elven shaman G:h:b I:110:12d8:30:30:6 W:10:1:1400:35 E:1:1:1:2:1:0 O:10:10:70:10 B:TOUCH:UN_BONUS F:MALE | AQUATIC | SMART | DROP_2D2 | DROP_CORPSE | ZANGBAND | F:HAS_LITE S:1_IN_12 | S:BO_MANA | BO_COLD | S_MONSTERS D:A wizened aquatic elf skilled in the magical arts. You can see an D:iridescent film coating the water around him. N:907:Stargazer G:~:y I:100:15d9:10:25:30 W:21:1:800:60 E:0:0:0:0:1:0 O:0:0:0:0 B:GAZE:PARALYZE F:AQUATIC | ANIMAL | SMART | RAND_25 | DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_10 | S:S_MONSTER D:A giant fish shaped like a flounder. There are two enormous eyes D:occupying half of the creature's body. N:908:Elder stargazer G:~:y I:100:20d10:15:25:30 W:29:1:1000:75 E:0:0:0:0:1:0 O:0:0:0:0 B:GAZE:PARALYZE B:GAZE:CONFUSE F:AQUATIC | ANIMAL | SMART | DROP_CORPSE | F:MORTAL | BASEANGBAND S:1_IN_10 | S:S_MONSTERS D:A stargazer a bit larger than average, covered with barnacles. N:909:Flounder G:~:s I:100:10d5:5:25:30 W:13:1:700:55 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:2d6 F:AQUATIC | ANIMAL | RAND_25 | INVISIBLE | ATTR_CLEAR | DROP_CORPSE | F:MORTAL | BASEANGBAND D:A flattened fish which is able to change body colouring for D:camouflage. N:910:Giant turtle G:R:G I:110:5d8:10:14:30 W:7:1:3000:30 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:HURT:2d2 B:BITE:HURT:2d2 F:ANIMAL | AQUATIC | DROP_CORPSE | F:MORTAL | BASEANGBAND D:A giant turtle with flippers, adapted for life in the ocean. N:911:Baby dragon turtle G:d:W I:110:10d10:20:60:50 W:9:1:20000:35 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:1d3 B:CLAW:HURT:1d3 B:BITE:HURT:1d5 F:FORCE_MAXHP | FORCE_SLEEP | DROP_CORPSE | F:ONLY_GOLD | DROP_60 | DROP_1D2 | F:EVIL | DRAGON | AQUATIC | BASEANGBAND | ATTR_MULTI S:1_IN_12 | S:BR_SOUN D:A newly-hatched dragon turtle. It still hasn't grown a proper shell. N:912:Young dragon turtle G:d:W I:110:30d10:20:70:70 W:31:1:80000:700 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d6 B:CLAW:HURT:2d6 B:BITE:HURT:2d8 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:DROP_3D2 | F:EVIL | DRAGON | AQUATIC | BASEANGBAND | ATTR_MULTI S:1_IN_11 | S:SCARE | S:BR_SOUN D:A dragon-like creature inhabiting lightless reaches of ocean caves. It has D:a long neck with a tiny head, and four massive flippers. It has a soft and D:flexible shell. N:913:Mature dragon turtle G:d:W I:110:50d10:20:80:70 W:38:1:170000:1500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:2d10 B:CLAW:HURT:2d10 B:BITE:HURT:4d10 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:DROP_4D2 | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | AQUATIC | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_9 | S:SCARE | S:BR_SOUN D:A large dragon turtle, covered with a tough white shell. N:914:Ancient dragon turtle G:D:W I:120:70d10:20:90:80 W:41:1:220000:2500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d8 B:CLAW:HURT:4d8 B:BITE:HURT:7d8 F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | F:DROP_1D2 | DROP_4D2 | F:SMART | AQUATIC | POWERFUL | MOVE_BODY | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_9 | S:BLIND | CONF | SCARE | S:BR_SOUN D:A huge dragon turtle. You can see many barnacles covering its body. N:915:Fastitocalon G:D:g I:120:40d100:25:150:30 W:52:3:250000:16000 E:0:1:0:6:1:0 O:0:0:0:0 B:BITE:HURT:5d8 B:BITE:HURT:5d8 B:CRUSH:POISON:3d10 B:CRUSH:POISON:3d10 F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | AQUATIC | WILD_TOO | WILD_OCEAN | F:IM_FIRE | IM_ACID | IM_COLD | IM_POIS | F:DRAGON | NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | ATTR_MULTI S:1_IN_6 | S:BR_FIRE | BR_ACID | BR_SOUN | BA_WATE D:A huge aquatic dragon-turtle, its shell is as large as a small island. N:916:Undead stargazer G:~:y I:100:18d9:10:25:30 W:25:1:0:100 E:0:0:0:0:1:0 O:0:0:0:0 B:GAZE:PARALYZE B:GAZE:EXP_20 F:AQUATIC | ANIMAL | SMART | INVISIBLE | UNDEAD | BASEANGBAND | NO_CUT S:1_IN_10 | S:S_UNDEAD | S_MONSTER D:A stargazer brought back from the dead under control of some unholy D:sorceror. N:917:Killer whale G:~:w I:120:20d50:12:55:30 W:25:1:9500:85 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:HURT:7d4 B:BITE:HURT:7d4 F:AQUATIC | WILD_TOO | WILD_OCEAN | F:ANIMAL | MORTAL | BASEANGBAND D:An almost beautiful, deadly beast. N:918:Merrow G:O:B I:110:30d9:20:33:30 W:28:2:2300:80 E:1:1:1:2:1:1 O:20:70:0:10 B:HIT:HURT:3d8 B:HIT:HURT:3d8 F:FRIENDS | DROP_60 | DROP_CORPSE | AQUATIC | WILD_TOO | WILD_OCEAN | F:OPEN_DOOR | BASH_DOOR | RES_WATE | IM_COLD | IM_POIS | F:EVIL | GIANT | F:MORTAL | BASEANGBAND | HAS_LITE D:A great ogre of the sea, it is violent and stupid. N:919:Water naga G:n:B I:110:30d10:10:55:10 W:24:1:1600:60 E:0:0:0:0:1:0 O:40:0:50:10 B:CRUSH:HURT:2d8 B:CRUSH:HURT:2d8 B:BITE:POISON:1d8 B:BITE:POISON:1d8 F:FEMALE | F:AQUATIC | DROP_CORPSE | F:ONLY_ITEM | DROP_90 | DROP_2D2 | F:EVIL | NO_CONF | NO_SLEEP | SMART | F:MORTAL | BASEANGBAND S:1_IN_7 | S:DARKNESS | CAUSE_3 | BO_ICEE D:A naga adapted to underwater life. She has a fish-like tail and a pair D:of gills. N:920:Devilfish G:~:s I:105:10d5:10:10:5 W:12:1:900:60 E:0:0:0:0:1:0 O:0:0:0:0 F:NEVER_BLOW | ATTR_MULTI | AQUATIC | NO_CONF | DROP_CORPSE | F:MORTAL | ZANGBAND S:1_IN_4 | S:BR_CHAO | BR_LITE | BR_SOUN | BR_DISE | BR_TIME D:A disgusting fish, it has a large gaping mouth and a small lantern dangling D:from an outgrowth on its head. N:921:Undead devilfish G:~:D I:105:10d5:10:10:5 W:15:1:0:75 E:0:0:0:0:1:0 O:0:0:0:0 F:NEVER_BLOW | ATTR_MULTI | AQUATIC | INVISIBLE | NO_CONF | UNDEAD | F:ZANGBAND | NO_CUT S:1_IN_4 | S:BR_NETH | BR_DISE | BR_TIME | BR_NEXU | BR_POIS D:A devilfish brought back from the dead. N:922:Moby Dick, the White Whale G:~:w I:120:100d25:200:80:70 W:50:2:10000:2500 E:0:0:0:0:1:0 O:0:0:0:0 B:CRUSH:HURT:10d10 B:CRUSH:HURT:10d10 B:CRUSH:HURT:10d10 B:CRUSH:HURT:10d10 F:FORCE_MAXHP | UNIQUE | MOVE_BODY | F:WILD_OCEAN | WILD_TOO | COLD_BLOOD | F:BASH_DOOR | IM_COLD | IM_ELEC | IM_POIS | ANIMAL | AQUATIC | F:MORTAL | JOKEANGBAND S:1_IN_6 | BA_WATE D:The mightiest whale of the seas, he has sunk many ships in his time. With D:a mere flick of his tail he can create a mighty whirlpool, to the ruin D:of all who would travel the ocean. N:923:Aquatic hound G:Z:B I:110:15d5:60:60:0 W:20:1:600:200 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:CONFUSE:2d8 B:BITE:HURT:2d8 B:CLAW:POISON:2d8 F:FRIENDS | DROP_CORPSE | F:ANIMAL | AQUATIC | F:MORTAL | BASEANGBAND S:1_IN_10 | S:BO_ICEE | BO_WATE D:A dog with a finned tail and large, muscular flippers for hind legs. D:It has a rubbery skin instead of fur. N:924:Water demon G:U:B I:110:35d20:30:50:10 W:40:1:0:1000 E:0:0:0:0:1:0 O:20:60:20:0 B:HIT:HURT:3d4 B:GAZE:POISON:8d12 B:CLAW:INSANITY:8d12 F:FORCE_SLEEP | FORCE_MAXHP | F:FRIENDS | SMART | F:ONLY_ITEM | DROP_60 | F:AQUATIC | POWERFUL | F:EVIL | DEMON | IM_ACID | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE S:1_IN_8 | S:BO_ICEE | BA_WATE D:A hideous scaled demon, it is a sleek form with many fins but no visible D:arms or legs. It has a toothed gaping maw, reminiscent of a caricature D:of a shark's jaws. N:925:Ixitxachitl G:~:s I:110:12d8:20:30:20 W:12:1:1600:40 E:0:0:0:0:1:0 O:0:0:0:0 B:STING:POISON:2d5 B:STING:POISON:2d5 F:ANIMAL | EVIL | AQUATIC | IM_POIS | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND D:An intelligent devil-ray of the depths. N:926:Ixitxachitl priest G:~:s I:110:10d10:20:40:20 W:19:1:1600:80 E:0:0:0:0:1:0 O:0:0:0:0 B:STING:POISON:2d7 B:STING:POISON:2d7 F:ANIMAL | EVIL | AQUATIC | IM_POIS | WILD_TOO | COLD_BLOOD | F:MORTAL | BASEANGBAND S:1_IN_6 S:TELE_TO | HEAL | SCARE | CAUSE_2 | BLIND | S_MONSTER D:A devil-ray of the depths, with priestly magic. N:927:Vampiric ixitxachitl G:~:D I:110:15d15:20:50:20 W:26:1:1800:120 E:0:0:0:0:1:0 O:0:0:0:0 B:STING:POISON:3d8 B:STING:EXP_40:3d8 F:ANIMAL | EVIL | AQUATIC | RES_NETH | IM_POIS | WILD_TOO | F:BASEANGBAND | COLD_BLOOD S:1_IN_6 S:HEAL | SCARE | CAUSE_3 | BLIND | FORGET | HASTE D:A devil-ray of the depths, with vampiric powers. N:928:Mathilde, the Science Student G:h:y I:110:220d100:40:10:3 W:0:4:1100:0 E:0:1:1:2:1:1 O:20:20:20:20 F:UNIQUE | FEMALE | CAN_SPEAK | DROP_CORPSE | DROP_SKELETON | F:FORCE_MAXHP | WILD_TOWN | WILD_ONLY | RAND_25 F:ONLY_ITEM | DROP_90 | DROP_GOOD | F:OPEN_DOOR | DG_CURSE | F:MORTAL | JOKEANGBAND | HAS_LITE D:She loves joking, and she's constantly giggling. A very happy girl. D:Beware, it is rumoured that Dark God has put a mighty curse on her. N:929:Child spirit G:G:W I:120:5d5:8:15:10 W:5:3:0:0 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:TERRIFY B:TOUCH:HURT:3d4 F:INVISIBLE | COLD_BLOOD | PASS_WALL | UNDEAD | F:IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | SMART | PET | UNDEAD | F:BASEANGBAND | NO_CUT D:A helpful spirit from beyond the grave. N:930:Young spirit G:G:W I:120:8d8:8:15:10 W:10:3:0:0 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:TERRIFY B:TOUCH:HURT:9d4 F:INVISIBLE | COLD_BLOOD | PASS_WALL | UNDEAD | F:IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | SMART | PET | UNDEAD | F:BASEANGBAND | NO_CUT D:A helpful spirit from beyond the grave. N:931:Mature spirit G:G:W I:120:16d16:8:15:10 W:40:3:0:0 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:TERRIFY B:TOUCH:HURT:18d4 F:INVISIBLE | COLD_BLOOD | PASS_WALL | UNDEAD | F:IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | SMART | PET | UNDEAD | F:BASEANGBAND | NO_CUT D:A helpful spirit from beyond the grave. N:932:Experienced spirit G:G:W I:120:18d18:8:15:10 W:60:3:0:0 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:TERRIFY B:TOUCH:HURT:20d4 F:INVISIBLE | COLD_BLOOD | PASS_WALL | UNDEAD | F:IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | SMART | PET | UNDEAD | F:BASEANGBAND | NO_CUT D:A helpful spirit from beyond the grave. N:933:Wise spirit G:G:W I:120:25d25:8:15:10 W:90:3:0:0 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:TERRIFY B:TOUCH:HURT:30d4 F:INVISIBLE | COLD_BLOOD | PASS_WALL | UNDEAD | F:IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | SMART | PET | UNDEAD | F:BASEANGBAND | NO_CUT D:A helpful spirit from beyond the grave. N:934:Fangorn the Treebeard, Lord of the Ents G:#:G I:120:50d100:30:120:15 W:52:3:6000:15500 E:1:1:1:2:1:1 O:0:50:50:0 B:CRUSH:HURT:13d13 B:CRUSH:HURT:13d13 B:CRUSH:HURT:13d13 B:CRUSH:HURT:13d13 F:FORCE_SLEEP | FORCE_MAXHP | UNIQUE | CAN_SPEAK | SUSCEP_FIRE | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | MOVE_BODY | DROP_CORPSE | F:SMART | TAKE_ITEM | BASH_DOOR | KILL_WALL | NO_SLEEP | F:GOOD | PET | BASEANGBAND | NO_CUT D:The first being to awoke on Arda, apart from the Valar themselves. He is the D:first, oldest, greatest and most respected of all the Ents: and though he is D:slow to anger, he is a terrible foe when roused. N:935:Gandalf the Grey G:p:s I:120:49d101:101:100:0 W:60:7:1600:35000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:UN_BONUS:6d8 B:HIT:UN_BONUS:6d8 B:HIT:TERRIFY:5d5 B:HIT:TERRIFY:5d5 F:UNIQUE | MALE | CAN_SPEAK | PET | DROP_CORPSE | F:FORCE_SLEEP | FORCE_MAXHP | REFLECTING | RES_TELE | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | F:GOOD | IM_FIRE | IM_COLD | F:IM_ELEC | IM_POIS | BASEANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | HASTE | TPORT | TELE_AWAY | BLIND | CONF | SCARE | S:CAUSE_4 | BRAIN_SMASH | FORGET | TRAPS | S:BA_FIRE | BO_FIRE | BO_PLAS | BO_MANA | CAUSE_4 | S:S_MONSTERS | S_ANGEL | S_DRAGON | S_KIN D:The wizard who opposed Sauron and, in the end, was the only D:one of the Istari to succeed in his task. Gandalf is very D:wise and specialises in fire magic. N:936:Nar, the Dwarf G:h:y I:110:45d10:25:70:25 W:17:2:1400:250 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:UNIQUE | MALE | F:FORCE_MAXHP | FORCE_SLEEP | F:OPEN_DOOR | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_POIS | F:DROP_CORPSE | DROP_SKELETON | BASEANGBAND | HAS_LITE S:1_IN_6 | S:HEAL | BLIND | CONF | CAUSE_2 | MIND_BLAST D:The friend and companion of the dwarven king Thror, he went mad with D:grief after Thror's death at the hands of Azog the Orc. With torn beard D:and ragged clothes, he seems to have fixed on you as a convenient target D:to vent his anger. N:937:Novice mindcrafter G:p:y I:110:6d8:20:10:5 W:8:1:900:18 E:1:1:1:2:1:1 O:0:50:0:30 B:HIT:HURT:1d6 F:DROP_60 | WILD_TOO | FRIENDS | F:OPEN_DOOR | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE | NO_CONF | NO_SLEEP S:1_IN_12 | BLIND | SLOW | CONF | SCARE D:A novice in the arts of mind over matter. N:938:Great Swamp Wyrm G:D:g I:120:40d100:30:150:80 W:63:2:190000:20000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:POISON:6d14 B:BITE:POISON:6d14 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | DROP_CORPSE | F:EVIL | DRAGON | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_POIS D:A truly enormous dragon with great powers. The foul gases issuing D:from the beast nearly make you vomit; and while you may try to hold D:your breath as you fight it, it sees no reason to do likewise. N:939:Great Bile Wyrm G:D:s I:120:50d100:30:150:80 W:67:2:190000:23000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:ACID:6d14 B:BITE:ACID:6d14 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | DROP_CORPSE | F:EVIL | DRAGON | IM_ACID | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_ACID D:A huge and very powerful dragon. Great steaming pools of acid drip from D:its form onto the ground. You shudder when you see the acid eating away D:the very stones of the dungeon - what could it do to you? N:940:Blue Firebird G:B:B I:120:4d5:8:15:10 W:5:3:100:0 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:3d4 B:CLAW:FIRE:5d4 F:IM_COLD | IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | IMPRESED | F:CAN_FLY | SMART | PET | DROP_CORPSE | HAS_EGG | GOOD | F:MORTAL | HAS_LITE S:1_IN_10 S:TELE_TO | D:The ancestors of the Eagles of the Thunderlords, these are D:friendly funny flying creatures with power. N:941:Green Firebird G:B:G I:120:4d5:10:15:10 W:7:3:110:0 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:4d4 B:CLAW:FIRE:5d4 F:IM_COLD | IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | IMPRESED | F:CAN_FLY | SMART | PET | DROP_CORPSE | HAS_EGG | GOOD | F:MORTAL | HAS_LITE S:1_IN_10 S:TELE_TO | D:The ancestors of the Eagles of the Thunderlords, these are D:friendly funny flying creatures with power. N:942:Brown Firebird G:B:u I:120:5d5:10:15:10 W:10:3:120:0 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:5d4 B:CLAW:FIRE:7d4 F:IM_COLD | IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | IMPRESED | F:CAN_FLY | SMART | PET | DROP_CORPSE | HAS_EGG | GOOD | F:MORTAL | HAS_LITE S:1_IN_10 S:TELE_TO | D:The ancestors of the Eagles of the Thunderlords, these are D:friendly funny flying creatures with power. N:943:Bronze Firebird G:B:U I:120:6d5:15:15:10 W:13:3:130:0 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:6d4 B:CLAW:FIRE:7d4 F:IM_COLD | IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | IMPRESED | F:CAN_FLY | SMART | PET | DROP_CORPSE | HAS_EGG | GOOD | F:MORTAL | HAS_LITE S:1_IN_10 S:TELE_TO | D:The ancestors of the Eagles of the Thunderlords, these are D:friendly funny flying creatures with power. N:944:Gold Firebird G:B:y I:120:6d5:20:15:10 W:15:3:140:0 E:0:1:0:6:1:0 O:0:0:0:0 B:CLAW:HURT:6d4 B:CLAW:FIRE:8d4 F:IM_COLD | IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | IMPRESED | F:CAN_FLY | SMART | PET | DROP_CORPSE | HAS_EGG | GOOD | F:MORTAL | HAS_LITE S:1_IN_10 S:TELE_TO | D:The ancestors of the Eagles of the Thunderlords, these are D:friendly funny flying creatures with power. N:945:High-elven ranger G:h:G I:120:50d30:20:70:0 W:40:3:1400:500 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:10d8 B:HIT:HURT:10d8 F:MALE | FRIENDS | OPEN_DOOR | BASH_DOOR | F:GOOD | DROP_SKELETON | DROP_CORPSE | SMART | PET | F:IM_ACID | IM_COLD | RES_WATE | RES_NETH | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_2 | S:ARROW_4 D:An elf cloaked in green wielding a longbow. N:946:Uvatha the Horseman G:W:D I:120:24d100:90:60:10 W:40:13:0:10000 E:0:0:0:0:0:0 O:30:30:30:10 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:HIT:EXP_80:4d6 B:HIT:EXP_80:4d6 F:UNIQUE | MALE | F:FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | NAZGUL | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | DROP_CHOSEN | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | F:BASEANGBAND | SPECIAL_GENE | NO_CUT D:A tall black Ringwraith, he is a master of horsemanship. He longs D:to taste your blood. N:947:Adunaphel the Quiet G:W:D I:120:27d100:90:60:10 W:43:13:0:13000 E:1:1:1:2:1:1 O:30:30:30:10 B:HIT:HURT:6d6 B:HIT:HURT:6d6 B:TOUCH:EXP_80:5d6 B:TOUCH:EXP_80:5d6 F:UNIQUE | FEMALE | F:FORCE_SLEEP | FORCE_MAXHP | NAZGUL | DROP_CHOSEN | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:INVISIBLE | COLD_BLOOD | PASS_WALL | MOVE_BODY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | F:BASEANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | FORGET | S:BO_ACID | BO_FIRE | BO_COLD | BO_NETH | S:S_MONSTER D:A sorceress in life, Adunaphel quickly fell under Sauron's sway and the D:power of the rings. N:948:Akhorahil the Blind G:W:D I:120:30d100:90:70:10 W:45:13:0:15000 E:1:1:1:2:1:1 O:30:30:30:10 B:HIT:HURT:7d6 B:HIT:HURT:7d6 B:GAZE:EXP_80:6d6 B:WAIL:TERRIFY:6d6 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | NAZGUL | DROP_CHOSEN | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | DARKNESS | S:BO_FIRE | BO_COLD | BO_NETH | S:S_MONSTERS D:A mighty sorcerer king, Akhorahil was blind in life. With powerful D:enchantments, he created jewelled eyes that enabled him to see better than D:any ordinary man ever could. N:949:Ren the Unclean G:W:D I:120:35d100:90:70:10 W:48:13:0:18000 E:1:1:1:2:1:1 O:30:30:30:10 B:HIT:HURT:7d7 B:HIT:HURT:7d7 B:TOUCH:EXP_80:6d7 B:WAIL:TERRIFY:6d7 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | NAZGUL | DROP_CHOSEN | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:INVISIBLE | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | BO_FIRE | BO_NETH | BA_FIRE | S:S_MONSTER D:Ren was an insane eastern king who believed himself to be the son of a D:volcano god. At an early age his sanity was destroyed by a plague that D:wiped out his family, and he never recovered. N:950:Ji Indur Dawndeath G:W:D I:120:40d100:90:70:10 W:52:13:0:22000 E:0:0:0:0:0:0 O:30:30:30:10 B:HIT:HURT:8d7 B:HIT:HURT:8d7 B:TOUCH:EXP_40:6d7 B:TOUCH:EXP_40:6d7 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | NAZGUL | DROP_CHOSEN | F:INVISIBLE | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | S:BA_FIRE | BA_NETH | BA_COLD | BA_ELEC | BA_ACID | S:S_UNDEAD D:This Ringwraith was a weak-minded sorcerer-king who fell easily under D:Sauron's power. N:951:Dwar, Dog Lord of Waw G:W:D I:120:45d100:90:90:10 W:56:13:0:25000 E:0:1:0:2:1:0 O:30:30:30:10 B:HIT:HURT:8d8 B:HIT:HURT:8d8 B:BITE:EXP_40:6d7 B:WAIL:TERRIFY:6d7 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | NAZGUL | DROP_CHOSEN | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | BA_FIRE | BA_NETH | S:S_MONSTERS | S_UNDEAD | S_HOUND D:Dwar had a special affinity for dogs in life, and can still command them D:at will. He howls manically as he reaches out to destroy you. N:952:Hoarmurath of Dir G:W:D I:130:60d100:90:100:10 W:64:13:0:30000 E:0:0:0:0:0:0 O:30:30:30:10 B:HIT:HURT:9d9 B:HIT:HURT:9d9 B:TOUCH:EXP_80:6d7 B:WAIL:TERRIFY:6d7 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_COLD | IM_POIS | NAZGUL | DROP_CHOSEN | F:HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | MIND_BLAST | S:BO_COLD | BA_COLD | BA_NETH | S:S_UNDEAD D:A Ringwraith powerful in fell sorcery, he yearns for the life he has D:exchanged for an unlife of everlasting torment. N:953:Khamul, the Black Easterling G:W:D I:130:70d100:90:100:10 W:72:13:2600:40000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:9d10 B:HIT:HURT:9d10 B:TOUCH:EXP_80:7d7 B:TOUCH:EXP_80:7d7 F:UNIQUE | MALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | NAZGUL | DROP_CHOSEN | F:SMART | COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:EVIL | UNDEAD | IM_ACID | IM_FIRE | IM_COLD | IM_POIS | F:HURT_LITE | NO_CONF | NO_SLEEP | RES_TELE | BASEANGBAND | NO_CUT S:1_IN_2 | S:TELE_LEVEL | BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | BO_MANA | S:BA_FIRE | BA_COLD | BA_NETH | ANIM_DEAD | S:S_HI_UNDEAD | S_KIN D:He was the warrior-king of the East, now a Ringwraith. Khamul is a powerful opponent, his skill in D:combat awesome and his form twisted by evil cunning. N:954:The Witch-King of Angmar G:W:D I:130:90d100:90:120:10 W:80:14:1800:60000 E:1:1:1:2:1:1 O:30:30:30:10 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:HIT:EXP_80:7d7 B:HIT:EXP_80:7d7 F:UNIQUE | MALE | CAN_SPEAK | RES_TELE F:FORCE_SLEEP | FORCE_MAXHP | SMART | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | MOVE_BODY | NAZGUL | F:EVIL | UNDEAD | DROP_CHOSEN | F:IM_COLD | IM_POIS | HURT_LITE | NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_2 | S:TELE_AWAY | BLIND | HOLD | SCARE | CAUSE_3 | BRAIN_SMASH | S:BO_MANA | BA_NETH | S_WRAITH | S:S_KIN | S_HI_UNDEAD | S_HI_DRAGON | S_MONSTERS | ANIM_DEAD D:The Chief of the Ringwraiths. A fell being of devastating power, his D:spells are lethal and his combat blows crushingly hard. He moves at D:speed, and commands legions of evil to do his bidding. It is said that he D:is fated never to die by the hand of mortal man. N:955:Green Thunderlord G:B:g I:120:50d50:20:100:50 W:30:4:30000:10000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:8d6 B:HIT:HURT:8d6 F:FEMALE | F:THUNDERLORD | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:IM_FIRE | REGENERATE | OPEN_DOOR | BASH_DOOR | F:RES_TELE | NO_CONF | NO_SLEEP | CAN_FLY | HAS_LITE S:1_IN_4 | S:BR_FIRE | S:BLINK | TELE_AWAY D:A Thunderlord. Among the weaker breeds, but still dangerous. N:956:Blue Thunderlord G:B:b I:120:60d60:20:100:50 W:40:4:30000:20000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:8d7 B:HIT:HURT:8d7 F:MALE | SMART | F:THUNDERLORD | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:IM_FIRE | REGENERATE | OPEN_DOOR | BASH_DOOR | F:RES_TELE | NO_CONF | NO_SLEEP | CAN_FLY | HAS_LITE S:1_IN_4 | S:BR_FIRE | S:TPORT | BLINK D:A Thunderlord. Among the weaker breeds, but still dangerous. N:957:Brown Thunderlord G:B:u I:130:70d70:30:100:50 W:50:4:30000:20000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:8d9 B:HIT:HURT:8d9 F:MALE | SMART | F:THUNDERLORD | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:IM_FIRE | REGENERATE | OPEN_DOOR | BASH_DOOR | F:RES_TELE | NO_CONF | NO_SLEEP | CAN_FLY | HAS_LITE S:1_IN_4 | S:BR_FIRE | S:TPORT | BLINK D:A Thunderlord. Beware its flame. N:958:Bronze Thunderlord G:B:U I:130:80d80:30:100:50 W:60:5:30000:20000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:10d9 B:HIT:HURT:10d9 F:MALE | SMART | F:THUNDERLORD | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:IM_FIRE | REGENERATE | OPEN_DOOR | BASH_DOOR | F:RES_TELE | NO_CONF | NO_SLEEP | CAN_FLY | HAS_LITE S:1_IN_4 | S:BR_FIRE | BR_TIME | S:TPORT | BLINK D:A Thunderlord, mightiest among the males. N:959:Gold Thunderlord G:B:y I:130:90d90:30:100:50 W:70:5:30000:20000 E:1:1:1:2:1:1 O:50:50:0:0 B:HIT:HURT:10d9 B:HIT:HURT:10d9 B:HIT:HURT:10d9 B:HIT:HURT:10d9 F:FEMALE | SMART | F:THUNDERLORD | DROP_SKELETON | DROP_CORPSE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:IM_FIRE | REGENERATE | OPEN_DOOR | BASH_DOOR | F:RES_TELE | NO_CONF | NO_SLEEP | CAN_FLY | HAS_LITE S:1_IN_4 | S:BR_FIRE | BR_TIME | S:TPORT | BLINK | TELE_TO | TELE_AWAY | S:S_THUNDERLORD D:A Thunderlord, among the queens of their kind. N:960:Blood Sprout G:,:g I:140:3d5:10:1:0 W:50:1:50:3 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:HURT:3d15 B:TOUCH:HURT:3d15 B:TOUCH:HURT:3d15 B:TOUCH:HURT:3d15 F:STUPID | EMPTY_MIND | KILL_TREES | F:IM_POIS | IM_ELEC | IM_ACID | IM_COLD | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL S:MULTIPLY D:A kind of giant mycorrhiza, corrupted into a carnivore by Morgoth. N:961:Gorlim, Betrayer of Barahir G:p:s I:120:16d100:20:120:40 W:41:3:1800:7000 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:HURT:8d6 B:HIT:HURT:8d6 B:HIT:UN_BONUS:6d8 B:HIT:UN_BONUS:6d8 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | DROP_SKELETON | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:SMART | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | BASEANGBAND F:HAS_LITE S:1_IN_2 | S:CAUSE_3 | BO_WATE | BO_MANA D:This sad creature - once a mighty warrior - betrayed his former friends to D:Morgoth's army in return for, he thought, safety for himself and his wife. D:And so he fell under Morgoth's power and became little more than a mindless D:servant of evil, even though the other side of his "bargain" was not kept. N:962:The Blubbering idiot, agent of black market, Simon the weak G:t:W I:110:5d11:10:16:0 W:5:1:1500:50 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:2d5 B:TOUCH:EAT_ITEM B:TOUCH:INSANITY:2d5 B:TOUCH:INSANITY:2d5 F:MALE | DROP_CORPSE | DROP_SKELETON | WILD_TOO | F:RAND_25 | UNIQUE | STUPID | MALE | FORCE_MAXHP | F:TAKE_ITEM | CAN_SPEAK | CAN_SWIM | EVIL | F:MORTAL | JOKEANGBAND | HAS_LITE S:1_IN_8 S:SHRIEK D:He tends to blubber a lot, he was a simple blubbering idiot before he lost D:himself in the dungeon and fell under Morgoth's will. D:Now he is a mindless servant of Morgoth. Destroy him - if you can... N:963:Aranea G:S:r I:120:20d10:20:45:50 W:30:2:1000:250 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:POISON:2d8 B:CLAW:POISON:2d8 B:BITE:POISON:2d6 B:BITE:POISON:2d6 F:DROP_SKELETON | FORCE_MAXHP | FRIENDS | F:OPEN_DOOR | BASH_DOOR | HURT_LITE | F:ANIMAL | SPIDER | EVIL | IM_POIS | BASEANGBAND S:1_IN_4 S:BO_FIRE | SLOW | HOLD | CAUSE_3 | MISSILE D:A red arachnid with legs weaving spells in the air. N:964:Elder aranea G:S:v I:120:30d20:20:65:50 W:40:3:1800:2500 E:0:1:0:2:1:0 O:0:0:0:0 B:CLAW:POISON:5d8 B:CLAW:POISON:5d8 B:BITE:HALLU:5d6 B:BITE:HALLU:5d6 F:DROP_SKELETON | FORCE_MAXHP | F:OPEN_DOOR | BASH_DOOR | HURT_LITE | SMART | F:ANIMAL | SPIDER | EVIL | IM_FIRE | IM_POIS | BASEANGBAND S:1_IN_6 S:SLOW | HOLD | DRAIN_MANA | MIND_BLAST | HEAL | S:BA_FIRE | BO_FIRE | CAUSE_3 | S_SPIDER D:A vast, bloated arachnid, master of its brood: among the more terrible of D:Ungoliant's descendants, this is a monster such as those who haunted the dread D:valley of Nan Dungortheb long ago. N:965:Giant brown tick G:S:u I:110:16d8:12:50:20 W:25:2:400:27 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:POISON:2d6 B:STING:BLIND:1d1 F:WEIRD_MIND | BASH_DOOR | CAN_FLY | F:ANIMAL | IM_POIS | MORTAL | BASEANGBAND D:It is moving slowly towards you. N:966:Wavelord G:p:b I:120:16d100:30:120:40 W:61:3:1800:7000 E:1:1:1:2:1:1 O:20:50:10:5 B:HIT:HURT:8d9 B:HIT:COLD:8d9 B:HIT:HURT:8d9 B:HIT:COLD:8d9 F:SMART | PET | DROP_CORPSE | FRIENDS | WILD_SHORE | WILD_OCEAN | WILD_TOO | F:IM_POIS | AQUATIC | CAN_SWIM | DROP_USEFUL | F:NO_CONF | NO_SLEEP | NO_FEAR | DROP_GOOD | DROP_3D2 | F:MORTAL | REGENERATE | TAKE_ITEM | GOOD | SUSCEP_FIRE | F:RES_WATE | RES_NEXU | HAS_LITE S:1_IN_4 S:BO_WATE | BA_WATE | BO_ICEE D:The Dolphiners came with the Thunderlords from their far home. D:These friendly beings ride their sharks into combat to assist you. N:967:Novice possessor (soul) G:G:D I:110:1d1:30:1:10 W:10:3:10:0 E:0:0:0:0:0:0 O:0:0:0:0 F:SMART | POSSESSOR | F:BASEANGBAND | NO_CUT D:It does not look that powerful. N:968:Bat of Gorgoroth G:b:g I:120:20d10:20:30:30 W:28:3:150:100 E:0:1:1:0:1:0 O:0:0:0:0 B:BITE:POISON:1d10 B:CLAW:HURT:1d4 F:DROP_60 | RAND_25 | MOVE_BODY | CAN_FLY | DROP_CORPSE | F:BASH_DOOR | MOVE_BODY | FRIENDS | WEIRD_MIND | F:ANIMAL | IM_POIS | AI_ANNOY | MORTAL | BASEANGBAND S:1_IN_8 | S:SCARE | BR_POIS | BR_DARK D:Fed with horrid meats and grown to enormous size, this slavering creature D:seeks livelier prey. N:969:The Princess G:p:y I:110:1d1:40:250:3 W:0:4:730:0 E:0:1:1:2:1:1 O:0:0:1:0 F:FEMALE | CAN_SPEAK F:FORCE_MAXHP | SPECIAL_GENE | NO_TARGET F:NEVER_MOVE | NEVER_BLOW | GOOD | NO_DEATH | RES_TELE F:MORTAL | BASEANGBAND | UNIQUE | PET | D:The princess of an unknown kingdom, you need to save her! N:970:Merton Proudfoot, the lost hobbit G:h:v I:110:1d1:40:250:3 W:1:1:730:0 E:0:1:1:2:1:1 O:0:0:0:1 F:MALE | CAN_SPEAK F:FORCE_MAXHP | SPECIAL_GENE F:NEVER_MOVE | NEVER_BLOW | GOOD | NO_TARGET F:MORTAL | BASEANGBAND | UNIQUE | PET | NO_DEATH D:The poor hobbit got lost in the dreadful maze! N:971:The Wight-King of the Barrow-downs G:W:v I:120:38d22:30:45:0 W:46:3:0:22000 E:0:0:0:0:0:0 O:15:55:15:0 B:HIT:HURT:2d10 B:WAIL:PARALYZE:2d6 B:TOUCH:EXP_80:4d8 B:TOUCH:EXP_80:4d8 F:SPECIAL_GENE | FORCE_MAXHP | SMART | CAN_SPEAK | F:DROP_4D2 | DROP_2D2 | COLD_BLOOD | UNIQUE | F:CAN_SWIM | CAN_FLY | EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_4 | S:HOLD | SCARE | CAUSE_3 | BA_NETH D:He has lived in the Barrow-Downs for centuries after his first death at the D:hands of the Witch-King of Angmar. A once loyal captain under the D:Witch-King's command, he now awaits a time when his undead forces shall D:rise again to avenge their deaths. N:972:Adventurer G:@:U I:115:3d20:50:50:10 W:0:3:100:0 O:50:50:0:0 B:HIT:HURT:2d6 B:PUNCH:HURT:1d7 B:KICK:HURT:1d8 F:SPECIAL_GENE | SMART | OPEN_DOOR F:FORCE_MAXHP | CAN_SWIM | BASEANGBAND | F:NO_SLEEP | NO_CONF D:A great warrior. N:973:Experienced possessor (soul) G:G:D I:120:5d5:30:50:10 W:30:3:10:0 O:0:0:0:0 F:SMART | POSSESSOR | F:BASEANGBAND | NO_CUT S:1_IN_9 S:S_KIN D:It does not look that powerful. N:974:Old possessor (soul) G:G:D I:130:10d10:30:100:10 W:95:3:10:0 O:0:0:0:0 F:SMART | POSSESSOR | F:BASEANGBAND | NO_CUT S:1_IN_4 S:S_KIN D:It does not look that powerful. N:975:Death orb G:E:D I:130:40d100:255:75:0 W:80:5:10:5000 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:PARASITE:20d10 B:ENGULF:ACID:6d5 B:ENGULF:EXP_80:6d5 B:ENGULF:LOSE_ALL:6d5 F:FORCE_MAXHP | ZANGBAND | KILL_ITEM | KILL_WALL | KILL_BODY | F:NONLIVING | COLD_BLOOD | EMPTY_MIND | CAN_SWIM | F:NO_CONF | NO_SLEEP | NO_STUN | REGENERATE | F:IM_ACID | IM_FIRE | IM_ELEC | IM_COLD | IM_POIS | F:RES_NETH | RES_PLAS | RES_WATE | RES_DISE | RES_NEXU | F:DEATH_ORB | NO_CUT D:A small, apparently unassuming orb which spawns death and destruction. N:976:Bronze dragon worm G:w:U I:100:10d15:10:40:80 W:20:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | NO_CONF | F:MORTAL | BASEANGBAND | ATTR_MULTI S:MULTIPLY | S:1_IN_6 | BR_CONF D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. Its scales glitter in D:a multitude of perplexing and distracting ways. N:977:Gold dragon worm G:w:y I:100:10d15:10:40:80 W:20:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | NO_STUN | F:MORTAL | BASEANGBAND | ATTR_MULTI S:MULTIPLY | S:1_IN_6 | BR_SOUN D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. You can feel the air itself D:vibrating as you near it. N:978:Moldoux, the Defenceless Mold G:m:v I:100:1d1:1:1:0 W:1:1:20:3 E:0:0:0:0:0:0 O:0:0:0:0 F:NEVER_MOVE | UNIQUE | F:STUPID | EMPTY_MIND | F:IM_POIS | FORCE_DEPTH | F:NO_CONF | NO_SLEEP | NO_FEAR | F:MORTAL | WYRM_PROTECT | ONLY_DEPTH | JOKEANGBAND | NO_CUT D:A small strange growth. It seems to be defenceless... N:979:The Physics Teacher G:p:w I:120:65d100:30:120:15 W:62:3:100000:13500 E:1:1:1:2:1:1 O:20:20:20:20 B:TOUCH:LOSE_INT:13d13 B:TOUCH:LOSE_WIS:13d13 B:GAZE:PARALYZE B:WAIL:EXP_80 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | CAN_SPEAK | DROP_CORPSE | F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:PASS_WALL | MOVE_BODY | AURA_FIRE | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | ANIMAL | DEMON | UNDEAD | JOKEANGBAND | NO_CUT S:1_IN_3 S:BR_FIRE | BR_PLAS | BR_TIME | BA_WATE | ROCKET | S:FORGET D:A keeper of forbidden wisdom, this Teacher bombards you with his mastery D:over elements of matter. N:980:Ar-Pharazon the Golden G:p:y I:130:50d100:30:45:255 W:55:1:0:2500 E:1:1:1:2:1:1 O:20:70:10:0 B:HIT:HURT:8d12 B:HIT:HURT:8d12 B:HIT:HURT:8d12 B:HIT:HURT:8d12 F:FORCE_SLEEP | FORCE_MAXHP | UNIQUE | CAN_SPEAK | SPECIAL_GENE | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_GOOD | DROP_SKELETON | DROP_CORPSE | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | MOVE_BODY | BASEANGBAND | F:HAS_LITE | AQUATIC S:1_IN_6 | S:HEAL | HASTE | TELE_AWAY | S_MONSTERS | S_KIN D:Last and proudest king of ancient Numenor. Corrupted by power and D:avarice, he fell victim to Sauron's wiles, tried to fight the immortals D:themselves, and condemned Numenor to oblivion. N:981:Doppelganger G:@:w I:1:1d1:1:1:1 E:0:0:0:0:0:0 O:0:0:0:0 F:NEVER_MOVE | NEVER_BLOW | DOPPLEGANGER | BASEANGBAND | HAS_LITE D:It looks like you... N:982:Marylene, Heartbreakeress of the Netherworld G:P:W I:155:200d120:155:175:0 W:127:1:1600:66666 E:1:1:1:2:1:1 O:30:30:30:10 B:GAZE:PARALYZE:20d15 B:HIT:EXP_80:20d17 B:BITE:LOSE_ALL:10d12 B:TOUCH:INSANITY:12d9 F:UNIQUE | CAN_SPEAK | ATTR_MULTI | ATTR_ANY | FEMALE | F:FORCE_MAXHP | WEIRD_MIND | DROP_CORPSE | DROP_SKELETON | F:REFLECTING | AURA_FIRE | AURA_ELEC | AURA_COLD | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_3D2 | DROP_4D2 | F:DROP_GOOD | DROP_GREAT | RES_NETH | INVISIBLE | F:SMART | KILL_WALL | KILL_BODY | POWERFUL | RES_TELE | F:REGENERATE | CAN_FLY | CAN_SWIM | WYRM_PROTECT | F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | RES_TELE | DEMON | F:MORTAL | DG_CURSE | JOKEANGBAND | HAS_LITE S:1_IN_1 | S:BR_CHAO | BA_CHAO | BRAIN_SMASH | SHRIEK | BR_CONF | BR_SOUN | S:BR_NETH | HASTE | TRAPS | FORGET | BR_DISE | BR_TIME | MIND_BLAST | S:HEAL | TPORT | TELE_TO | CAUSE_1 | CAUSE_2 | CAUSE_3 | CAUSE_4 | BLIND | S:CONF | SLOW | HOLD | S_ANGEL | S_UNIQUE D:A woman of mind-shattering beauty, none can match her beauty. She is perfect, D:and totally evil. She loves nothing but herself and her evil is as D:great as her beauty. No one can stand against her, even DarkGod. D:As you see her approaching, you feel your heart breaking. D:She is the perfection, don't even try against her; you will surely lose D:your mind... N:983:The Greater Lag Monster G:U:v I:110:60d100:40:10:3 W:95:4:730:0 E:0:0:0:0:0:0 O:40:40:0:10 B:GAZE:PARALYZE:20d15 B:HIT:HURT:15d10 B:TOUCH:EXP_80:10d5 B:TOUCH:EAT_ITEM F:RAND_50 | TAKE_ITEM | FORCE_MAXHP | UNIQUE | F:DROP_3D2 | DROP_GOOD | DROP_GREAT | WYRM_PROTECT | F:NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | RES_TELE | DEMON | F:EVIL | WEIRD_MIND | RES_NETH | INVISIBLE | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | JOKEANGBAND | NO_CUT S:1_IN_2 S:CONF | SHRIEK | BR_CONF | BR_TIME | BR_INER | BR_GRAV | BRAIN_SMASH | S:SCARE | BLIND | SLOW | HOLD | HASTE | HEAL | TELE_TO | FORGET | S:S_HI_DEMON | S_MONSTERS | S_HYDRA | S_HI_DRAGON | S_HI_UNDEAD | S_ANGEL | S:S_HOUND | S_UNIQUE | D:It is even worse than the RNG, coming from Mangband, D:it seeks to crush you to pulp... and surely can. N:984:Hrungnir, the Stone Giant G:P:W I:130:99d110:50:160:20 W:78:2:0:45000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:SHATTER:9d11 B:HIT:SHATTER:9d11 B:HIT:HURT:9d11 B:HIT:HURT:9d11 F:UNIQUE | SUSCEP_ACID | HURT_ROCK | F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | RES_NETH | RES_PLAS | MALE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | EVIL | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | TAKE_ITEM | CAN_SPEAK | F:EVIL | IM_FIRE | IM_POIS | GIANT | F:ZANGBAND | HAS_LITE | NO_CUT S:1_IN_5 | S:BR_WALL | BR_GRAV | BR_SHAR | BLIND | TELE_TO | S_KIN | S_MONSTERS | S:HAND_DOOM | TELE_AWAY | D:Hrungnir is the strongest of all the Stone Giants: one who would even dare D:to challenge Thor himself to single combat. N:985:Bullroarer the Hobbit G:h:U I:120:6d10:16:8:10 W:5:3:1000:90 E:1:1:1:2:1:1 O:25:55:0:20 B:HIT:HURT:1d8 B:HIT:HURT:1d8 F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE | DROP_SKELETON | F:FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:MORTAL | BASEANGBAND | HAS_LITE D:He is a sturdy hobbit who is renowned for his unusual strength and D:vigour. He can prove a troublesome opponent. N:986:3-headed hydra G:M:o I:120:100d5:20:65:20 W:20:2:4500:350 E:0:1:0:2:2:0 O:0:0:0:0 B:BITE:HURT:2d6 B:BITE:HURT:2d6 B:BITE:HURT:2d6 F:FORCE_SLEEP | WILD_TOO | WILD_SHORE | WILD_SWAMP | CAN_SWIM | F:DROP_CORPSE | DROP_SKELETON | ONLY_GOLD | DROP_2D2 | F:OPEN_DOOR | BASH_DOOR | MOVE_BODY | F:ANIMAL | MORTAL | BASEANGBAND S:1_IN_9 | S:SCARE D:A strange reptilian creature with three heads, guarding its hoard. N:987:Uldor the Accursed G:p:U I:110:10d100:20:70:40 W:28:4:2000:600 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:4d6 B:HIT:HURT:4d6 B:HIT:HURT:4d6 B:HIT:HURT:4d6 F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE | DROP_SKELETON | F:FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_10 | S_KIN D:An evil and cunning man from the East. Having once sworn allegiance to the D:sons of Feanor, it was Uldor's treachery that turned the tide of the Battle D:of Unnumbered Tears in Morgoth's favour. N:988:Mystic G:p:o I:120:35d10:30:50:5 W:33:3:1400:500 E:1:1:1:2:1:1 O:30:0:60:10 B:KICK:HURT:10d2 B:KICK:HURT:10d2 B:KICK:HURT:10d2 B:KICK:HURT:10d2 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | DROP_SKELETON | F:ONLY_ITEM | DROP_1D2 | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_POIS | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_6 | S:HEAL | S:S_SPIDER | S_ANIMAL D:An adept at unarmed combat, the mystic strikes with stunning power. He D:can summon help from nature and is able to focus his power to ease any D:pain. N:989:Elder vampire G:V:r I:120:34d100:20:90:10 W:54:3:1700:4500 E:1:1:1:2:1:1 O:0:70:30:0 B:HIT:HURT:4d6 B:HIT:HURT:4d6 B:BITE:EXP_80:5d6 B:BITE:EXP_80:5d6 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:DROP_60 | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | RES_TELE | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT S:1_IN_7 | S:BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | DRAIN_MANA | S:BRAIN_SMASH | DARKNESS | BO_NETH | S_UNDEAD D:A terrible robed undead figure, this creature has existed in its D:unlife for many centuries by stealing the life of others. It can D:summon the very shades of its victims from beyond the grave to D:come enslaved to its aid. N:990:Ulfang the Black G:p:U I:120:25d100:20:90:40 W:44:5:2100:1200 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:5d8 B:HIT:HURT:5d8 B:HIT:HURT:5d8 B:HIT:HURT:5d8 F:UNIQUE | MALE | CAN_SPEAK | DROP_CORPSE | DROP_SKELETON | F:FORCE_MAXHP | IM_FIRE | IM_COLD | IM_ELEC | SPECIAL_GENE | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | DROP_RANDART F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_10 | S_KIN | S_MONSTERS D:A short and swarthy Easterling dressed in black. He and his three sons D:once openly swore allegiance to the High Elves, but were secretly in the D:pay of Morgoth. N:991:Demonologist G:p:R I:120:28d10:20:50:10 W:36:2:1100:700 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:HURT:2d6 B:HIT:HURT:2d6 B:HIT:HURT:2d6 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | DROP_SKELETON F:RES_NETH | RES_NEXU | F:ONLY_ITEM | DROP_1D2 | F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | MORTAL | BASEANGBAND | HAS_LITE S:1_IN_2 | S:TPORT | HOLD | S:S_DEMON | BO_FIRE D:A figure twisted by evil standing in robes of deepest crimson. N:992:Hezrou G:U:g I:110:52d10:20:40:80 W:41:3:2100:2500 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:FORCE_SLEEP | FORCE_MAXHP | FRIENDS F:ONLY_ITEM | DROP_2D2 | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | NONLIVING F:BASEANGBAND S:1_IN_9 | S:BO_FIRE | S:S_DEMON D:It is a demon of lizard form with cruel-looking jaws. N:993:Glabrezu G:U:U I:110:70d10:20:40:80 W:43:2:2300:3000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_90 | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | NONLIVING | F:BASEANGBAND S:1_IN_9 | S:BO_FIRE | S:S_DEMON D:It is a demon with arms and pincers, its form a true mockery of life. N:994:Nalfeshnee G:U:r I:110:90d10:20:50:80 W:45:2:6000:5000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:3d4 B:HIT:HURT:3d4 B:HIT:HURT:3d4 F:FORCE_SLEEP | FORCE_MAXHP | AURA_FIRE F:ONLY_ITEM | DROP_1D2 | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | DEMON | F:IM_FIRE | NO_CONF | NO_SLEEP | NONLIVING F:BASEANGBAND S:1_IN_9 | S:BLIND | CONF | S:BR_FIRE | S:S_DEMON D:It is a large demon with the head of a giant boar. Flames run up and down D:its length. N:995:Marilith G:U:y I:120:20d70:20:75:80 W:47:2:3000:7000 E:3:0:3:4:1:0 O:0:50:50:0 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:HIT:HURT:3d6 B:HIT:HURT:3d6 F:FEMALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_1D2 | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | NONLIVING | F:BASEANGBAND S:1_IN_9 | S:BLIND | CAUSE_2 | S:S_DEMON D:She is a demon of female form with many arms, each bearing deadly weapons. N:996:Lesser Balrog G:U:v I:120:20d100:20:50:80 W:49:2:9000:10000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:FIRE:4d12 B:HIT:FIRE:4d12 B:CRUSH:HURT:3d12 B:TOUCH:UN_POWER F:FORCE_SLEEP | FORCE_MAXHP | AURA_FIRE | KILL_WALL | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:EVIL | DEMON | IM_FIRE | NO_CONF | NO_SLEEP | NONLIVING | F:BASEANGBAND | HAS_LITE S:1_IN_4 | S:BLIND | CONF | S:BR_FIRE | S:S_DEMON D:It is a massive humanoid demon wreathed in flames. N:997:Master mystic G:p:o I:130:11d100:30:60:5 W:50:3:1600:6000 E:1:1:1:2:1:1 O:40:0:40:20 B:KICK:HURT:10d2 B:KICK:HURT:10d2 B:HIT:POISON:20d1 B:HIT:PARALYZE:15d1 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | DROP_SKELETON | F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | S:S_SPIDER | S_ANIMALS D:A lord of all that is natural, skilled in the mystic ways. He is a master D:of martial arts and is at one with nature, able to summon help from the D:wild if need be. N:998:Grand master mystic G:p:o I:130:22d100:30:80:5 W:57:3:1800:15000 E:1:1:1:2:1:1 O:40:0:40:20 B:KICK:HURT:20d2 B:KICK:HURT:10d2 B:HIT:POISON:20d1 B:HIT:PARALYZE:15d1 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | DROP_CORPSE | DROP_SKELETON | F:ONLY_ITEM | DROP_4D2 | F:INVISIBLE | OPEN_DOOR | BASH_DOOR | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | MIND_BLAST | S:S_SPIDER | S_HOUND | S_ANIMALS D:He is one of the few true masters of the art, being extremely skillful in D:all forms of unarmed combat and controlling the world's natural creatures D:with disdainful ease. N:999:Erinyes G:U:u I:110:24d10:20:50:80 W:38:2:0:1000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:HURT:3d4 B:TOUCH:LOSE_STR:1d5 F:FEMALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_60 | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:EVIL | DEMON | F:IM_FIRE | IM_POIS | NO_CONF | NO_SLEEP | F:BASEANGBAND S:1_IN_7 | S:BLIND | CONF | BO_FIRE D:It is a lesser demon of female form; however, she takes little time to D:show her true colours. N:1000:Novice mindcrafter G:p:y I:110:6d8:20:10:5 W:4:1:900:18 E:1:1:1:2:1:1 O:0:50:0:30 B:HIT:HURT:1d6 F:DROP_60 | WILD_TOO | F:OPEN_DOOR | DROP_SKELETON | DROP_CORPSE | F:MORTAL | BASEANGBAND | HAS_LITE | NO_CONF | NO_SLEEP S:1_IN_9 | BLIND | SLOW | CONF | SCARE D:A novice in the arts of mind over matter. N:1001:Polyphemus, the Blind Cyclops G:P:g I:130:65d100:40:140:40 W:69:3:40000:29000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:11d10 B:HIT:SHATTER:11d10 B:HIT:HURT:11d10 B:HIT:SHATTER:11d10 F:UNIQUE | MALE | BASEANGBAND | HAS_LITE | CAN_SWIM | F:FORCE_SLEEP | FORCE_MAXHP | RAND_25 | DROP_CORPSE | F:DROP_2D2 | DROP_3D2 | DROP_GOOD | ONLY_ITEM | KILL_ITEM | F:BASH_DOOR | KILL_BODY | F:EVIL | GIANT | IM_ACID | IM_POIS | IM_FIRE | IM_COLD | S:1_IN_5 | S:BO_WATE | BA_WATE | BO_ICEE | BA_ACID | ARROW_4 D:No ordinary cyclops, but the son of a sea-god: he wields the powers of D:elemental water as well as the considerable strength of a cyclops. His D:one eye was blinded long ago by the warrior Odysseus, but he has trained D:himself to hear so well that it nearly makes up for his disability. N:1002:Great Wyrm of Perplexity G:D:U I:120:40d100:30:150:80 W:63:2:190000:20000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:CONFUSE:6d14 B:BITE:CONFUSE:6d14 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:SMART | BASH_DOOR | POWERFUL | MOVE_BODY | DROP_CORPSE | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | BASEANGBAND | HAS_LITE | ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_CONF D:A dragon of great size and power. Its polished bronze scales reflect the D:light in strange and confusing patterns, and you find it hard to keep your D:mind on the job of fighting for your life. N:1003:Hound of Tindalos G:Z:s I:120:60d15:30:100:0 W:59:3:600:8000 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:TIME:2d12 B:BITE:TIME:2d12 B:CLAW:HURT:2d12 B:CLAW:HURT:2d12 F:FORCE_SLEEP | FRIENDS | RES_NETH | F:INVISIBLE | PASS_WALL | EVIL | CAN_FLY | F:ANIMAL | NO_CONF | NO_SLEEP | CTHANGBAND S:1_IN_5 | BLINK | TELE_TO | S:BR_NETH | BR_TIME D:"They are lean and athirst!... All the evil in the universe D:was concentrated in their lean, hungry bodies. Or had they D:bodies? I saw them only for a moment, I cannot be certain." N:1004:Great Wyrm of Thunder G:D:y I:120:50d100:30:150:80 W:67:2:190000:23000 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:4d12 B:CLAW:HURT:4d12 B:BITE:HURT:6d14 B:BITE:HURT:6d14 F:FORCE_SLEEP | FORCE_MAXHP | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:BASH_DOOR | POWERFUL | MOVE_BODY | DROP_CORPSE | F:EVIL | DRAGON | NO_CONF | NO_SLEEP | NO_STUN | BASEANGBAND | HAS_LITE F:ATTR_MULTI S:1_IN_4 | S:BLIND | CONF | SCARE | S:BR_SOUN D:A dragon of gigantic proportions, with destructive abilities to match. The D:sheer loudness of its roar leaves you stunned and unable to think clearly D:enough to defend yourself adequately. N:1005:Silver mouse G:r:W I:110:1d3:8:4:20 W:4:1:200:1 E:0:1:0:2:1:0 O:0:0:0:0 B:BITE:EAT_LITE:1d2 F:RAND_25 | CAN_SWIM | ANIMAL | F:DROP_CORPSE | MORTAL | BASEANGBAND S:MULTIPLY D:It is about three feet long with large teeth. As the light of your lamp falls D:on it, it seems to grow stronger. N:1006:The Rat King G:r:v I:120:20d12:30:30:0 W:18:1:950:32 E:1:1:1:2:1:1 O:0:0:0:0 B:CLAW:HURT:3d2 B:CLAW:HURT:3d2 B:BITE:DISEASE:4d2 B:BITE:DISEASE:4d2 F:UNIQUE | ESCORT | ESCORTS | FORCE_MAXHP | F:BASH_DOOR | ANIMAL | NO_CONF | NO_SLEEP F:MORTAL | BASEANGBAND D:A massive rat. He's the leader of the pack. N:1007:Vort the Kobold Queen G:k:v I:110:12d10:20:20:20 W:7:3:1000:100 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:HURT:1d10 B:HIT:HURT:1d10 F:UNIQUE | FEMALE | CAN_SPEAK | F:FORCE_MAXHP | F:ESCORT | ESCORTS | DROP_SKELETON | DROP_CORPSE F:ONLY_ITEM | DROP_1D2 | DROP_GOOD | F:OPEN_DOOR | BASH_DOOR | F:EVIL | IM_POIS | F:MORTAL | BASEANGBAND | HAS_LITE S:1_IN_6 | MISSILE | HEAL | CAUSE_1 | CONF D:Where Mughash is the strongest of his kind, his consort Vort is the D:wisest: she is her tribe's chief shamaness. N:1008:Giant black louse G:I:D I:120:1d2:6:7:10 W:14:1:100:3 E:0:0:0:0:0:0 O:0:0:0:0 B:BITE:HURT:1d2 F:RAND_50 | RAND_25 | CAN_FLY | WEIRD_MIND | F:ANIMAL | MORTAL | BASEANGBAND S:MULTIPLY D:It is six inches long. N:1009:Fire Phantom G:G:r I:120:10d100:20:90:40 W:34:5:0:1200 E:0:0:0:0:0:0 O:0:0:100:0 B:HIT:HURT:5d5 F:UNIQUE | MALE | CAN_SPEAK F:FORCE_MAXHP | UNDEAD | NO_CONF | NO_SLEEP | REGENERATE | NO_STUN | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | PASS_WALL | F:MORTAL | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_6 S:BR_FIRE | HOLD | CONF | SCARE | MIND_BLAST D:He's back from the grave for vengeance on those who D:burnt him. He has no mercy for those in his way. N:1010:The Insane Player G:p:v I:120:18d100:25:100:10 W:36:2:1500:1200 E:1:1:1:2:1:1 O:20:20:20:20 B:HIT:HURT:3d8 F:UNIQUE | MALE | CAN_SPEAK | ATTR_MULTI | F:FORCE_MAXHP | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | DROP_SKELETON | DROP_CORPSE F:OPEN_DOOR | BASH_DOOR | RAND_25 | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR F:JOKEANGBAND | HAS_LITE S:1_IN_4 | S:TELE_TO | SHRIEK | SCARE D:Once a powerful adventurer, this poor fighter has seen a few too many D:software bugs in his time. Any shred of lucidity is long gone, but D:he still remains dangerous. He wanders aimlessly through the dungeon D:randomly striking at foes both real and imagined, all the while screaming D:out at the world that caused his condition. N:1011:Glaryssa, Succubus Queen G:U:W I:120:12d100:90:60:10 W:41:3:3000:8000 E:1:1:1:2:1:1 O:0:50:50:0 B:CLAW:HURT:5d5 B:HIT:LOSE_STR:4d4 B:TOUCH:EXP_80:8d3 F:UNIQUE | FEMALE | CAN_SPEAK | F:FORCE_SLEEP | FORCE_MAXHP | NO_SLEEP | NO_CONF F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | F:COLD_BLOOD | PASS_WALL | MOVE_BODY | NONLIVING | F:OPEN_DOOR | BASH_DOOR | IM_POIS | IM_COLD | DEMON | EVIL | F:ZANGBAND S:1_IN_3 | S:CAUSE_3 | HOLD | BLIND | BO_ACID | S_DEMON | S:FORGET | BO_NETH | MIND_BLAST | DARKNESS D:Drop dead gorgeous - literally. N:1012:Vermicious Knid G:j:s I:110:90d10:20:55:100 W:44:2:1400:2100 E:0:0:0:0:0:0 O:40:30:20:10 B:TOUCH:TERRIFY:4d6 B:CRAWL:HURT:4d6 B:ENGULF:HURT:4d6 F:FRIENDS | EVIL | IM_COLD | SMART | F:COLD_BLOOD | NO_FEAR | WEIRD_MIND | F:OPEN_DOOR | ONLY_ITEM | DROP_2D2 | HURT_ROCK | F:NONLIVING | F:JOKEANGBAND | NO_CUT D:An amorphous shape that looks like wet grey clay with two pale eyes. D:It is totally silent as it oozes towards you. N:1013:Bone golem G:g:w I:120:35d100:20:170:50 W:61:3:5000:23000 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:UN_BONUS:8d8 B:HIT:UN_BONUS:8d8 B:HIT:LOSE_STR:6d6 B:HIT:LOSE_STR:6d6 F:FORCE_SLEEP | FORCE_MAXHP | EMPTY_MIND | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | F:EVIL | UNDEAD | IM_COLD | IM_POIS | IM_FIRE | IM_ELEC | RES_TELE | F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_3 | S:TELE_TO | CAUSE_4 | DRAIN_MANA | S:BRAIN_SMASH | BA_NETH | S_HI_UNDEAD D:A skeletal form, black as night, constructed from the bones of its D:previous victims. N:1014:Snake of Yig G:J:b I:120:48d10:25:80:30 W:38:4:2000:600 E:0:0:0:0:1:0 O:0:0:0:0 B:BITE:POISON:3d12 F:FORCE_SLEEP | FORCE_MAXHP | F:RAND_25 | FRIENDS | AURA_FIRE | F:BASH_DOOR | MOVE_BODY | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | HAS_EGG | EVIL | IM_FIRE | IM_POIS | F:MORTAL | ZANGBAND S:1_IN_5 | S:BR_POIS D:It is a giant snake that drips with poison. N:1015:Bronze golem G:g:o E:2:1:2:4:1:1 O:0:0:0:0 I:120:40d100:25:170:50 W:65:3:5500:26000 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:HIT:HURT:10d10 F:FORCE_MAXHP | FORCE_SLEEP | EMPTY_MIND | COLD_BLOOD | F:OPEN_DOOR | BASH_DOOR | IM_FIRE | IM_ELEC | IM_POIS | RES_TELE | F:NO_CONF | NO_SLEEP | NO_STUN | NO_FEAR | NONLIVING | BASEANGBAND | NO_CUT S:1_IN_3 | S:BO_PLAS | BA_FIRE | BR_FIRE | BA_ELEC | S_HI_DEMON | TELE_TO D:A gigantic four-armed animated bronze statue, glowing with great heat. N:1016:Dimensional shambler G:h:B I:120:40d10:30:68:255 W:29:6:1100:400 E:0:0:0:0:0:0 O:20:40:40:0 B:HIT:HURT:3d5 B:HIT:HURT:3d5 B:HIT:HURT:3d5 F:FORCE_MAXHP | FORCE_SLEEP | NO_FEAR | GOOD | F:ONLY_ITEM | DROP_2D2 | NONLIVING | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | F:IM_FIRE | IM_COLD | IM_POIS | NO_CONF | NO_SLEEP | RES_TELE | F:CTHANGBAND S:1_IN_3 | S:HEAL | HASTE | BLIND | CONF | SCARE | TPORT | BLINK D:A shabby humanoid with a wrinkled skin. It seems to shift D:in and out of existence as you watch. N:1017:Cultist G:p:G I:110:14d8:20:22:40 W:17:1:1500:36 E:1:1:1:2:1:1 O:10:0:90:0 B:HIT:HURT:4d3 F:MALE | F:FORCE_SLEEP | F:DROP_1D2 | EVIL | F:DROP_SKELETON | DROP_CORPSE | F:SMART | OPEN_DOOR | BASH_DOOR | F:MORTAL | CTHANGBAND | HAS_LITE S:1_IN_3 | S:HEAL | SCARE | CAUSE_2 | S:S_MONSTER | MIND_BLAST D:A robed humanoid dedicated to a demonic outer god. N:1018:Cult leader G:p:G I:120:52d14:20:60:10 W:47:2:1800:1800 E:1:1:1:2:1:1 O:20:0:80:0 B:HIT:HURT:6d4 B:HIT:HURT:6d4 F:MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_90 | DROP_2D2 | F:SMART | OPEN_DOOR | BASH_DOOR | F:DROP_SKELETON | DROP_CORPSE | F:EVIL | NO_CONF | NO_SLEEP | F:MORTAL | CTHANGBAND | HAS_LITE S:1_IN_2 | S:HEAL | BLIND | HOLD | CONF | CAUSE_3 | S:S_MONSTER | S_UNDEAD | S_DEMON | BA_CHAO | BRAIN_SMASH D:An evil priest, dressed all in black and devoted to one of the netherworld D:demons that call themselves "the outer gods". N:1019:Servitor of the outer gods G:H:y I:130:100d35:30:140:255 W:41:6:2100:15000 E:0:0:0:0:0:0 O:10:20:70:0 B:GAZE:TERRIFY:4d4 B:HIT:HURT:8d6 F:FORCE_SLEEP | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | NO_FEAR | REFLECTING | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NONLIVING | F:RES_TELE | ELDRITCH_HORROR | SHAPECHANGER | ATTR_MULTI | F:CTHANGBAND S:1_IN_3 | S:TELE_TO | BLIND | SCARE | CAUSE_2 | CAUSE_4 | BO_MANA | S:S_UNDEAD D:"Toad-like creatures which seemed constantly to be changing shape and D:appearance, and from whom emanated, by some means I could not distinguish, D:a ghostly ululation, a piping." August Derleth - "The Lurker at The D:Threshold". N:1020:Avatar of Nyarlathotep G:p:R I:120:25d25:20:70:20 W:45:2:0:500 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:HURT:5d5 F:IM_POIS | IM_FIRE | IM_ELEC | IM_ACID | IM_COLD | F:NO_SLEEP | NO_FEAR | SHAPECHANGER | ELDRITCH_HORROR | NONLIVING | F:MALE | OPEN_DOOR | BASH_DOOR | F:CTHANGBAND | HAS_LITE D:The Crawling Chaos with a thousand forms. Nyarlathotep is amused at your D:puny attempts to kill him, and will keep coming back for another go D:until he gets bored with the game. N:1021:Thiazi, the Storm Giant G:P:B I:130:99d110:50:160:20 W:78:2:0:45000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:ELEC:9d11 B:HIT:HURT:9d11 B:HIT:ELEC:9d11 B:HIT:HURT:9d11 F:UNIQUE | SUSCEP_COLD | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | RES_TELE | RES_NETH | RES_PLAS | MALE | F:ONLY_ITEM | DROP_2D2 | DROP_4D2 | DROP_GOOD | EVIL | AURA_ELEC | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | TAKE_ITEM | CAN_SPEAK | F:EVIL | IM_FIRE | IM_POIS | SUSCEP_COLD | GIANT | DEMON F:ZANGBAND | HAS_LITE S:1_IN_5 | S:BR_ELEC | BR_PLAS | BR_MANA | BLIND | TELE_TO | S_KIN | S_HI_DRAGON | S:HAND_DOOM | TELE_AWAY D:Thiazi is the greatest of all the Storm Giants: when travelling, he takes D:the form of a giant eagle. It was he who succeeded in kidnapping Iduna and D:her apples of youth from Asgard itself. N:1022:Hypnos, Lord of Sleep G:p:G I:130:51d99:20:150:10 W:67:2:5000:36000 E:1:1:1:2:1:1 O:0:0:100:0 B:TOUCH:LOSE_ALL:2d25 B:GAZE:PARALYZE:1d20 B:GAZE:TERRIFY:1d20 B:GAZE:BLIND:1d20 F:UNIQUE | MALE | CAN_SPEAK | ATTR_MULTI | F:NO_STUN | RES_DISE | RES_NEXU | CAN_FLY | F:FORCE_SLEEP | FORCE_MAXHP | EVIL | SMART | DROP_CORPSE F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | F:NO_SLEEP | NO_CONF | NO_STUN | IM_POIS | IM_COLD | IM_FIRE | IM_ACID F:ZANGBAND | HAS_LITE S:1_IN_3 S:BR_NEXU | BR_CHAO | HOLD | SLOW | BR_INER | BA_NUKE | S:MIND_BLAST | BRAIN_SMASH | CONF | BLIND | TELE_TO | HEAL | S:TELE_AWAY | TELE_LEVEL | TPORT | S_UNDEAD | S_DEMON | DRAIN_MANA D:"Young with the youth that is outside time, and with a handsome D:bearded face, curved, smiling lips, Olympian brow; and dense locks D:waving and poppy-crowned." N:1023:Blue dragon worm G:w:B I:100:10d15:10:40:80 W:20:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_ELEC | F:MORTAL | BASEANGBAND | ATTR_MULTI S:MULTIPLY | S:1_IN_6 | BR_ELEC D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. Sparks fly from its jaws. N:1024:White dragon worm G:w:W I:100:10d15:10:40:80 W:20:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_COLD | F:MORTAL | BASEANGBAND | ATTR_MULTI S:MULTIPLY | S:1_IN_6 | BR_COLD D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. Its breath condenses in the air. N:1025:Green dragon worm G:w:G I:100:10d15:10:40:80 W:20:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_POIS | F:MORTAL | BASEANGBAND | ATTR_MULTI S:MULTIPLY | S:1_IN_6 | BR_POIS D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. You can smell foul gases D:on its breath. N:1026:Black dragon worm G:w:s I:100:10d15:10:40:80 W:20:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_ACID | F:MORTAL | BASEANGBAND | ATTR_MULTI S:MULTIPLY | S:1_IN_6 | BR_ACID D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. Acidic drool drips from its jaws. N:1027:Red dragon worm G:w:R I:100:10d15:10:40:80 W:20:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_FIRE | F:MORTAL | BASEANGBAND | ATTR_MULTI S:MULTIPLY | S:1_IN_6 | BR_FIRE D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. Smoke comes from its mouth. N:1028:Multi-hued dragon worm G:w:v I:100:10d20:10:40:80 W:23:3:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:HURT:3d3 B:CLAW:HURT:3d3 B:BITE:HURT:3d5 F:RAND_50 | RAND_25 | ATTR_MULTI | F:DROP_60 | ONLY_GOLD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | F:EVIL | DRAGON | IM_ELEC | IM_FIRE | IM_ACID | IM_COLD | IM_POIS | F:MORTAL | BASEANGBAND S:MULTIPLY | S:1_IN_6 | BR_ELEC | BR_COLD | BR_FIRE | BR_ACID | BR_POIS D:You thought dragons used eggs, but this worm has the scales, and the bad D:breath, and the fiery eyes, of a real dragon. Its scales shimmer different D:colours as you watch. N:1029:The Minotaur of the Labyrinth G:H:s I:130:150d10:13:25:10 W:40:2:17500:3100 E:1:1:1:2:1:1 O:0:0:0:0 B:BUTT:HURT:4d6 B:BUTT:HURT:4d6 B:BUTT:HURT:3d6 B:BUTT:HURT:3d6 F:BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:EVIL | UNIQUE | SPECIAL_GENE | F:MORTAL | BASEANGBAND D:It is a cross between a human and a bull. N:1030:The Sandworm Queen G:w:v I:120:30d20:10:40:80 W:30:3:4500:12 E:0:0:0:0:1:0 O:30:60:0:10 B:CLAW:ACID:5d4 B:CLAW:POISON:5d4 B:BITE:FIRE:5d4 B:BITE:ELEC:5d4 F:FORCE_MAXHP | DROP_60 | ONLY_ITEM | DROP_GREAT | DROP_GOOD | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | FEMALE | POWERFUL | SPECIAL_GENE | REFLECTING | F:EVIL | ANIMAL | IM_ELEC | IM_FIRE | IM_ACID | IM_POIS | ESCORT | F:MORTAL | BASEANGBAND | EMPTY_MIND | UNIQUE | NO_CONF S:1_IN_2 | BR_POIS | S_KIN D:Queen and mother of the sandworms, fear her and her prolific children. N:1031:Sandworm G:w:y I:115:10d15:10:40:80 W:27:6:4500:12 E:0:0:0:0:1:0 O:0:0:0:0 B:CLAW:POISON:4d4 B:CLAW:POISON:4d4 B:CLAW:POISON:4d4 B:BITE:HURT:5d5 F:RAND_25 | F:FORCE_MAXHP | DROP_CORPSE | POWERFUL | F:EVIL | IM_ELEC | IM_FIRE | IM_POIS | EMPTY_MIND | F:MORTAL | BASEANGBAND S:MULTIPLY D:Offbreed of the Sandworm Queen, they are harmless alone... N:1032:Tik'srvzllat G:G:v I:142:180d100:200:170:0 W:127:2:1000:350000 E:1:1:1:2:1:1 O:50:0:50:0 B:GAZE:UN_BONUS:10d10 B:GAZE:TIME:10d10 B:GAZE:INSANITY:10d10 B:GAZE:INSANITY:10d5 F:UNIQUE | SPECIAL_GENE | F:FORCE_MAXHP | POWERFUL | F:ONLY_ITEM | DROP_3D2 | DROP_4D2 | DROP_GOOD | DROP_GREAT | F:INVISIBLE | COLD_BLOOD | PASS_WALL | WEIRD_MIND | F:EVIL | UNDEAD | IM_COLD | IM_FIRE | IM_ACID | IM_ELEC | AURA_COLD | F:IM_POIS | RES_NETH | BASEANGBAND | NO_CUT S:1_IN_2 | S:S_UNDEAD | S_DEMON | S_DRAGON | S:S_UNIQUE | S_WRAITH | S_HI_DEMON | S:S_HI_UNDEAD | S_HI_DRAGON | S_KIN | S:BR_DISE | BA_NETH D:A disembodied and barely sentient mind, Tik'srvzllat floated D:through the void for eons before being awakened by sorcery, pulled D:into the nether realm, and shaped into the being you see before you. D:A flickering purple outline of a sphere, with eerie yellow-purple D:mist circling rapidly around it, Tik'srvzllat threatens your sanity D:with its appearance alone. N:1033:The Glass Golem G:g:W I:130:100d15:200:170:0 W:52:4:0:2000 E:0:0:0:0:0:0 O:0:0:0:0 B:HIT:INSANITY:5d6 B:HIT:INSANITY:6d6 B:HIT:INSANITY:7d6 B:HIT:INSANITY:6d6 F:COLD_BLOOD | EMPTY_MIND | KILL_WALL | FORCE_MAXHP | POWERFUL | SPECIAL_GENE | F:BASH_DOOR | IM_COLD | IM_ACID | IM_FIRE | IM_ELEC | IM_POIS | NONLIVING | F:ESCORTS | ESCORT | UNIQUE | NO_SLEEP | NO_CONF | NO_FEAR | NO_STUN F:CHAR_MULTI | CAN_FLY | BASEANGBAND | NO_CUT S:1_IN_4 S:BR_CONF | BR_LITE | BR_DARK | BR_WALL S:S_KIN | TELE_LEVEL | SHRIEK D:One of the last creations of the petty dwarves of Ludarin, its existence D:explains their destruction. A creation of finest glass, the body of this D:creature bends and amplifies light in a way that makes you unsure of its D:position. You feel somewhat dizzy as the radiant light reflects off the D:walls, the ceiling and your gear. N:1034:The White Balrog G:U:W I:120:25d100:20:100:100 W:50:3:12000:25000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:COLD:4d12 B:HIT:COLD:4d12 B:CRUSH:HURT:3d12 B:TOUCH:UN_POWER F:UNIQUE | FORCE_SLEEP | FORCE_MAXHP | AURA_COLD | CAN_FLY | F:ONLY_ITEM | DROP_2D2 | DROP_GOOD | NONLIVING | DROP_RANDART F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | SMART | F:EVIL | DEMON | IM_COLD | NO_CONF | KILL_WALL | BASEANGBAND | F:HAS_LITE | SPECIAL_GENE S:1_IN_4 | S:BLIND | CONF | BRAIN_SMASH | S:BR_COLD | BO_COLD | BA_NETH | S_UNDEAD | S_DEMON D:It is a massive humanoid demon wreathed in frost, wielding a cruel looking D:pike in its hands. N:1035:Golgarach, the Living Rock G:#:W I:120:50d30:20:100:40 W:45:2:0:1500 E:0:0:0:0:0:0 O:60:0:40:0 B:HIT:HURT:4d6 B:HIT:HURT:4d6 B:HIT:HURT:4d6 F:FORCE_SLEEP | COLD_BLOOD | EMPTY_MIND | PASS_WALL | KILL_BODY | ESCORT | F:BASH_DOOR | IM_COLD | IM_ACID | IM_ELEC | IM_POIS | NONLIVING | UNIQUE F:HURT_ROCK | NO_CONF | NO_SLEEP | NO_CUT | CHAR_MULTI | BASEANGBAND | SPECIAL_GENE F:NO_CUT | DROP_RANDART S:1_IN_10 | S_KIN | BO_ACID | BA_FIRE D:Deep in the heart of the earth, even the rock itself is sentient D:and has learned to despise intruders. N:1036:Atlas, the Titan G:P:s I:130:100d100:30:160:15 W:76:3:70000:37000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:SHATTER:13d13 B:HIT:CONFUSE:13d13 B:HIT:SHATTER:13d13 B:HIT:CONFUSE:13d13 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | F:ONLY_ITEM | DROP_GOOD | DROP_4D2 | KILL_BODY | KILL_WALL | F:SMART | TAKE_ITEM | OPEN_DOOR | BASH_DOOR | DROP_CORPSE | F:EVIL | GIANT | HURT_ROCK | BASEANGBAND | HAS_LITE | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS D:The strongest of all the Titans. Legend has it that he once held the sky D:on his shoulders; and the mountain range that now does so is named after him. N:1037:Kronos, Lord of the Titans G:P:v I:130:130d100:30:150:15 W:87:3:80000:42000 B:HIT:CONFUSE:12d12 B:HIT:CONFUSE:12d12 B:HIT:CONFUSE:12d12 B:HIT:CONFUSE:12d12 E:1:1:1:2:1:1 O:0:100:0:0 F:UNIQUE | MALE | F:FORCE_SLEEP | FORCE_MAXHP | MOVE_BODY | F:ONLY_ITEM | DROP_4D2 | DROP_3D2 | DROP_GOOD | F:SMART | TAKE_ITEM | BASH_DOOR | HAS_LITE | F:EVIL | GIANT | ESCORT | BASEANGBAND | DROP_CORPSE | F:IM_FIRE | IM_COLD | IM_ACID | IM_POIS | IM_ELEC S:1_IN_3 | S:BR_FIRE | BR_COLD | BR_SHAR | BR_SOUN | ROCKET | S:S_MONSTERS | S_KIN | TELE_TO | HEAL D:The lord of the Titans, he has broken loose from his confinement in D:the nether hells to seek revenge on the world. N:1038:Water hound G:Z:r I:110:12d6:30:30:0 W:43:1:600:150 B:BITE:HURT:1d6 B:CLAW:HURT:1d4 B:CLAW:HURT:1d4 E:0:1:0:2:1:0 O:0:0:0:0 F:FORCE_SLEEP | BASH_DOOR | DROP_CORPSE | FRIENDS F:ANIMAL | IM_COLD | MORTAL | BASEANGBAND | RES_WATE | NO_CUT S:1_IN_5 | BA_WATE D:The sound of a hundred waterfalls rushes through your ears as D:a huge wave of water, vaguely hound-shaped, rushes towards you. N:1039:Improv, the mighty MoLD G:m:v I:150:170d100:40:140:0 W:127:2:3000:50000 E:3:0:3:6:1:0 O:20:20:20:20 B:SPORE:UN_BONUS:10d10 B:SPORE:EXP_80:10d10 B:SPORE:TIME:10d10 B:SPORE:TIME:10d10 F:UNIQUE | NEVER_MOVE | CAN_SWIM | F:FORCE_MAXHP | WEIRD_MIND | DROP_CORPSE | F:REFLECTING | AURA_ELEC | ONLY_ITEM | DROP_4D2 | F:DROP_GOOD | DROP_GREAT | FORCE_SLEEP | RES_NETH | F:SMART | POWERFUL | RES_TELE | REGENERATE | CAN_FLY | F:DG_CURSE | WYRM_PROTECT | EVIL | F:IM_ACID | IM_FIRE | IM_ELEC | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | F:JOKEANGBAND | HAS_LITE | RES_WATE | NO_CUT S:1_IN_2 | S:S_HI_DRAGON | S_KIN | BR_DISI | HEAL | TPORT | S:TELE_LEVEL | TELE_TO D:An assistant to DarkGod, Improv has chosen the form of a dense D:purple smog for his incarnation into Middle-earth. It travels the D:dungeons, killing software bugs and creating random artifacts for D:guests to find. N:1040:Emperor Mimic G:m:y I:120:50d50:30:60:100 W:40:3:100:200 E:0:0:0:0:0:0 O:25:25:25:25 B:HIT:POISON:5d5 B:HIT:POISON:5d5 B:HIT:POISON:5d5 B:HIT:POISON:5d5 F:MIMIC | UNIQUE F:FORCE_SLEEP | F:EMPTY_MIND | COLD_BLOOD | F:IM_ACID | IM_FIRE | IM_ELEC | IM_COLD | IM_POIS | F:NO_CONF | NO_SLEEP | NO_FEAR | BASEANGBAND | NO_CUT S:1_IN_1 | S:BLIND | CONF | SCARE | CAUSE_4 | CAUSE_3 | FORGET | S:BA_ACID | BA_FIRE | BA_COLD | BA_ELEC | S:S_MONSTER | S_KIN | SHRIEK | BRAIN_SMASH | TRAPS D:A strange creature that disguises itself as an object to lure D:unsuspecting adventurers within reach of its venomous claws. N:1041:Melinda Proudfoot G:h:v I:110:1d1:40:250:3 W:1:1:730:0 E:0:1:1:2:1:1 O:0:0:0:1 F:FEMALE | CAN_SPEAK F:FORCE_MAXHP | SPECIAL_GENE F:NEVER_MOVE | NEVER_BLOW | GOOD | NO_TARGET F:MORTAL | BASEANGBAND | UNIQUE | NEUTRAL | NO_DEATH D:She seems to seek someone, you may help... N:1042:Thrain, the King Under the Mountain G:h:B I:110:1d1:40:250:3 W:60:1:730:0 E:0:1:1:2:1:1 O:0:0:0:1 F:MALE | CAN_SPEAK F:FORCE_MAXHP | SPECIAL_GENE F:NEVER_MOVE | NEVER_BLOW | GOOD | NO_TARGET F:MORTAL | BASEANGBAND | UNIQUE | NEUTRAL | NO_DEATH D:He must have suffered horrible tortures... N:1043:Fire golem G:g:r I:115:3d20:50:50:10 W:0:3:100:0 E:1:1:1:2:1:1 O:0:0:0:0 B:HIT:HURT:2d6 B:HIT:HURT:2d6 B:HIT:FIRE:3d6 B:HIT:FIRE:3d6 F:BASH_DOOR | AURA_FIRE | HAS_LITE F:IM_FIRE | SPECIAL_GENE F:NO_CONF | NO_SLEEP | NO_FEAR | NONLIVING | NO_STUN F:MORTAL | BASEANGBAND | NO_CUT | AI_PLAYER S:1_IN_10 | S:BR_FIRE D:A sentient mass of pure fire. N:1044:Melkor, Lord of Darkness G:G:v I:150:300d300:100:150:0 W:150:1:200000:60000 E:1:1:1:2:1:1 O:25:25:25:25 B:HIT:ABOMINATION:3d10 B:HIT:TIME:24d10 B:HIT:INSANITY:24d10 B:HIT:LOSE_ALL:24d10 F:UNIQUE | CAN_SPEAK | MALE | F:FORCE_MAXHP | SPIRIT F:ONLY_ITEM | DROP_1D2 | DROP_2D2 | DROP_3D2 | DROP_4D2 | F:DROP_GOOD | DROP_GREAT | DROP_CHOSEN | RES_NETH | F:SMART | KILL_WALL | MOVE_BODY | AURA_FIRE | F:REGENERATE | POWERFUL | SPECIAL_GENE | CAN_FLY | KILL_TREES F:EVIL | IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | F:NO_CONF | NO_STUN | NO_SLEEP | NO_FEAR | RES_TELE | BASEANGBAND | S:1_IN_4 | S:BRAIN_SMASH | S:BA_MANA | BO_MANA | BA_NETH | BA_CHAO | BA_DARK | ANIM_DEAD | S_KIN | S:S_MONSTERS | S_UNIQUE | S_HI_DEMON | S_HI_UNDEAD | S_HI_DRAGON | S:BR_NETH | BR_DISI | HAND_DOOM | S_WRAITH | HEAL | BRAIN_SMASH | S:DRAIN_MANA | TELE_TO | DARKNESS | SHRIEK D:He was the most powerful of the Valar, the equal of Manwe. D:You banned him here, in the Void, and now you must destroy him D:forever. However here in the Void, his spirit gained much power D:for he is closer to the Flame Imperishable. He is coming to you in pure D:madness, which makes him even more dangerous. You are on the verge D:of dying! ## Here are the Spirits, inhabitants of the Void, all called "Spirit" making it hard to know what we are up against ## ## Note: I am nasty heheh :) # Spirit of nether N:1045:Spirit G:G:v I:120:40d80:30:50:20 W:128:2:0:5000 E:0:1:1:2:0:0 O:25:0:75:0 B:TOUCH:EXP_80:10d10 B:TOUCH:EXP_80:10d10 F:SPIRIT | BASEANGBAND | NEVER_MOVE | EMPTY_MIND | NO_CUT | F:COLD_BLOOD | INVISIBLE S:1_IN_1 | S:BA_NETH D:This strange, almost intangible spirit keeps assaulting you! # Spirit of annoyance (hahaha AI_ANNOY and MULTIPLY) N:1046:Spirit G:G:B I:130:40d20:30:70:70 W:144:4:0:500 E:0:0:0:0:0:0 O:5:5:5:0 B:TOUCH:POISON:10d10 B:CRAWL:POISON:10d10 B:CRAWL:EAT_ITEM:10d9 B:BITE:UN_BONUS:9d9 F:SPIRIT | BASEANGBAND | WEIRD_MIND | FRIENDS | F:AI_ANNOY | PASS_WALL S:MULTIPLY D:These things multiply at an apparently unstoppable rate! # Spirit of movement N:1047:Spirit G:G:B I:130:10d80:50:65:10 W:132:1:10:5500 E:0:0:0:0:0:0 O:0:0:0:0 B:TOUCH:LOSE_DEX:2d3 B:TOUCH:PARALYZE:1d12 B:TOUCH:PARALYZE:1d12 F:SPIRIT | BASEANGBAND | NO_SLEEP | PASS_WALL | WEIRD_MIND S:1_IN_2 | S:SLOW | BLINK | HOLD | HASTE D:Coming towards you quickly, it seems intent on moving faster than you. # Spirit of confusion N:1048:Spirit G:G:v I:120:40d80:80:85:0 W:135:2:0:5500 E:0:0:0:0:0:0 O:0:0:0:0 B:ENGULF:HALLU:16d8 B:ENGULF:HALLU:16d8 B:ENGULF:CONFUSE:16d8 B:ENGULF:CONFUSE:16d8 F:SPIRIT | BASEANGBAND | RES_NEXU | AURA_ELEC | IM_FIRE | IM_ELEC | F:EMPTY_MIND | BASH_DOOR | POWERFUL | CAN_FLY | ATTR_MULTI | F:NO_CONF | NO_SLEEP | NO_FEAR | NO_CUT S:1_IN_3 | S:BR_CHAO | BR_NEXU | BR_CONF D:A swirling mass, constantly changing its appearance. # Spirit of brawn N:1049:Spirit G:G:U I:130:140d100:50:180:30 W:145:3:10000:8000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:SHATTER:18d18 B:HIT:CONFUSE:18d18 B:HIT:SHATTER:18d18 B:HIT:CONFUSE:18d18 F:SPIRIT | BASEANGBAND | DROP_4D2 | KILL_BODY | KILL_WALL | F:OPEN_DOOR | BASH_DOOR | DROP_CORPSE | KILL_TREES | F:EVIL | GIANT | HURT_ROCK | BASEANGBAND | HAS_LITE | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS D:Strong and swarthy, this spirit could bend metal with his bare hands. # Spirit of Wyrms N:1050:Spirit G:G:v I:130:151d151:50:190:50 W:147:8:10000:87500 E:0:1:0:6:1:0 O:50:50:0:0 B:CLAW:HURT:10d15 B:CLAW:HURT:10d15 B:BITE:HURT:14d18 B:BITE:HURT:14d18 F:SPIRIT | FORCE_MAXHP | MOVE_BODY | AURA_FIRE | REFLECTING | AURA_ELEC | F:ONLY_ITEM | DROP_2D2 | DROP_3D2 | DROP_4D2 | DROP_GOOD | AURA_COLD | F:OPEN_DOOR | BASH_DOOR | POWERFUL | RES_NETH | RES_DISE | F:DRAGON | GOOD | RES_TELE | DROP_CORPSE | KILL_TREES | F:IM_ACID | IM_FIRE | IM_COLD | IM_ELEC | IM_POIS | NO_CONF | NO_SLEEP | F:RES_NEXU | RES_PLAS | CAN_FLY | BASEANGBAND | HAS_LITE | NO_CUT S:1_IN_3 | S:S_HI_DRAGON | S_DRAGON | S_KIN | S:BR_ACID | BR_ELEC | BR_FIRE | S:BR_COLD | BR_POIS | BR_NETH | BR_LITE | BR_DARK | S:BR_CONF | BR_SOUN | BR_CHAO | BR_DISE | BR_NEXU | S:BR_TIME | BR_INER | BR_GRAV | BR_SHAR | BR_PLAS | S:BR_WALL | BR_MANA | BR_DISI D:This spirit bears a remarkable similarity to some of the most powerful D:types of dragonkind found in Middle-earth. It appears to be even more D:fearsome though! # Spirit of snakes N:1051:Spirit G:G:g I:130:150d100:40:80:20 W:133:3:90:750 E:1:1:1:2:1:1 O:25:20:25:20 B:BITE:POISON:15d15 B:BITE:POISON:15d15 B:BITE:LOSE_ALL:10d12 F:SPIRIT | CAN_SWIM | IM_POIS | IM_ACID | F:DROP_60 | DROP_2D2 | FRIENDS | DROP_CORPSE | F:OPEN_DOOR | BASH_DOOR | EVIL | BASEANGBAND S:1_IN_4 | S:BA_POIS | S_MONSTER | SCARE | HOLD D:It slides towards you, a horrible scaly, slidy thing. # Spirit of seeing N:1052:Spirit G:G:v I:130:95d110:60:130:10 W:141:3:60:50000 E:0:0:0:0:0:0 O:0:0:0:0 B:GAZE:UN_BONUS:12d12 B:GAZE:UN_POWER:12d10 B:GAZE:INSANITY:12d14 B:GAZE:LOSE_ALL:6d6 F:SPIRIT | BASH_DOOR | EVIL | IM_POIS | F:CAN_FLY | BASEANGBAND S:1_IN_2 | S:BLIND | CONF | FORGET | SCARE | DRAIN_MANA | BRAIN_SMASH | S:BA_DARK | BO_MANA | BA_NETH | BA_ACID | BA_FIRE | BA_COLD D:You will find it difficult to avoid being seen by this spirit! And D:once it has you in its sight, beware! # Spirit of unseeing N:1053:Spirit G:.:W I:120:55d50:20:130:80 W:142:6:60:4000 E:0:0:0:0:0:0 O:10:0:90:0 B:TOUCH:UN_BONUS:12d12 B:TOUCH:UN_POWER:12d10 B:TOUCH:INSANITY:12d14 B:TOUCH:LOSE_ALL:6d6 F:SPIRIT | CAN_FLY | REFLECTING | F:SMART | BASH_DOOR | COLD_BLOOD | INVISIBLE | EMPTY_MIND | F:EVIL | BASEANGBAND | CHAR_MULTI | CHAR_CLEAR | ATTR_CLEAR S:1_IN_3 | S:DRAIN_MANA | BLINK | BLIND | SCARE | CONF | S:HEAL | TELE_AWAY | DARKNESS | TRAPS | FORGET | SHRIEK D:Hopefully you will kill this spirit before you realise it exists. # Spirit of ickyness N:1054:Spirit G:G:g I:130:80d80:30:60:10 W:138:4:300:40000 E:0:0:0:0:0:0 O:40:30:10:10 B:CRAWL:POISON:12d14 B:CRAWL:EAT_FOOD:12d14 B:TOUCH:ACID:13d15 B:HIT:HURT:13d15 F:SPIRIT | BASEANGBAND | F:EMPTY_MIND | OPEN_DOOR | BASH_DOOR | F:EVIL | IM_ACID | IM_ELEC | IM_FIRE | IM_COLD | IM_POIS | F:EMPTY_MIND S:1_IN_4 | S:DRAIN_MANA | BLIND | CONF | SCARE | S_KIN D:A horrible slimy spirit, that seems to ooze evilness. I wouldn't get D:too close to it if I were you. # Spirit of friendship N:1055:Spirit G:G:W I:130:35d100:40:150:100 W:136:3:200:10000 E:0:1:0:2:1:0 O:50:50:0:0 B:BITE:HURT:12d12 B:BITE:HURT:12d12 B:BITE:HURT:12d8 B:BITE:HURT:12d8 F:SPIRIT | BASEANGBAND | F:ESCORT | ESCORTS | F:OPEN_DOOR | BASH_DOOR S:1_IN_2 | S:S_KIN D:This spirit appears to have lots of friends! # Spirit of abomination N:1056:Spirit G:G:d I:130:40d80:30:125:125 W:134:2:200:5000 E:0:0:0:0:0:0 O:50:0:50:0 B:WAIL:TERRIFY:8d9 B:HIT:HURT:10d10 B:HIT:ABOMINATION:6d10 B:HIT:ABOMINATION:6d10 F:SPIRIT | BASEANGBAND | F:EVIL | UNDEAD | IM_POIS | IM_COLD | NO_CONF | NO_SLEEP | F:COLD_BLOOD | HURT_LITE | NO_CUT S:1_IN_3 | S:SCARE | HOLD | DARKNESS | SCARE D:It seems to have been woken from the dead, this spirit. It lumbers D:towards you, seeking to turn you into a form as hideous as its own! ### Here come the spirits of ### # # Spirit of strength N:1057:Spirit G:G:u I:120:140d100:50:180:170 W:129:2:10000:8000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:LOSE_STR:4d8 B:HIT:LOSE_STR:4d8 B:HIT:LOSE_STR:4d8 F:SPIRIT | BASEANGBAND | DROP_2D2 | KILL_BODY | KILL_WALL | F:BASH_DOOR | EVIL | GIANT | HURT_ROCK | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS D:It is coming for you, this massive imposing tower of strength. D:It appears almost unstoppable! # Spirit of intelligence N:1058:Spirit G:G:r I:140:80d100:50:100:10 W:131:2:10000:8000 E:1:1:1:2:1:1 O:0:0:100:0 B:HIT:LOSE_INT:4d8 B:HIT:LOSE_INT:4d8 B:HIT:LOSE_INT:4d8 F:EVIL | SPIRIT | BASEANGBAND | DROP_2D2 | F:OPEN_DOOR | SMART | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS S:1_IN_2 | S:HASTE | TPORT | TELE_TO | BLIND | CONF | S:BO_MANA | BO_FIRE | BO_COLD | BO_ELEC | D:This spirit looks very clever, cunning almost. # Spirit of wisdom N:1059:Spirit G:G:G I:130:120d100:50:200:130 W:137:2:10000:8000 E:1:1:1:2:1:1 O:0:50:50:0 B:HIT:LOSE_WIS:4d8 B:HIT:LOSE_WIS:4d8 B:HIT:LOSE_WIS:4d8 F:EVIL | SPIRIT | BASEANGBAND | DROP_2D2 | F:OPEN_DOOR | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS S:1_IN_2 | S:HEAL | MIND_BLAST | CAUSE_4 | SCARE | S:DRAIN_MANA | BRAIN_SMASH | FORGET | D:This spirit has something of a priestly look about it. # Spirit of dexterity N:1060:Spirit G:G:W I:160:120d100:50:160:50 W:139:2:10000:8000 E:1:1:1:2:1:1 O:0:50:25:25 B:HIT:LOSE_DEX:4d8 B:HIT:LOSE_DEX:4d8 B:HIT:LOSE_DEX:4d8 F:EVIL | SPIRIT | BASEANGBAND | DROP_2D2 | F:OPEN_DOOR | SMART | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS S:1_IN_1 | S:ARROW_4 D:This spirit moves almost too quickly for you to see him. # Spirit of constitution N:1061:Spirit G:G:s I:120:140d100:50:180:50 W:143:2:10000:8000 E:1:1:1:2:1:1 O:0:50:0:50 B:HIT:LOSE_CON:4d8 B:HIT:LOSE_CON:4d8 B:HIT:LOSE_CON:4d8 F:EVIL | SPIRIT | BASEANGBAND | DROP_2D2 | BASH_DOOR | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS D:This spirit moves slower than most, but thunders on and on D:towards you. # Spirit of charisma N:1062:Spirit G:G:b I:140:80d100:50:120:90 W:146:2:10000:8000 E:1:1:1:2:1:1 O:70:10:10:10 B:HIT:LOSE_CHR:4d8 B:HIT:LOSE_CHR:4d8 B:HIT:LOSE_CHR:4d8 F:SPIRIT | BASEANGBAND | DROP_2D2 | F:OPEN_DOOR | EVIL | TAKE_ITEM | F:IM_FIRE | IM_COLD | IM_ACID | IM_ELEC | IM_POIS S:1_IN_2 | S:TRAPS | ARROW_3 | BLINK | TELE_TO | CONF D:There is something attractive about this spirit, and it seems D:to have a full purse. ### Here come some elemental spirits ### # # Spirit of flickering fire N:1063:Spirit G:G:r I:120:60d100:50:65:80 W:130:1:5:6000 E:1:1:1:2:1:1 O:25:60:0:15 B:HIT:FIRE:10d8 B:HIT:FIRE:10d8 B:HIT:FIRE:10d8 F:SPIRIT | BASEANGBAND | AI_ANNOY | IM_FIRE | AURA_FIRE | HAS_LITE S:1_IN_2 | S:BO_FIRE | BA_FIRE D:Flickering towards you, and then away, this spirit will burn you badly! # Spirit of icy cold N:1064:Spirit G:G:w I:120:60d100:50:65:80 W:148:1:5:6000 E:1:1:1:2:1:1 O:25:60:0:15 B:HIT:COLD:10d8 B:HIT:COLD:10d8 B:HIT:COLD:10d8 F:SPIRIT | BASEANGBAND | IM_COLD | AURA_COLD | F:COLD_BLOOD | BASH_DOOR S:1_IN_2 | S:BO_COLD | BA_COLD D:The temperature around you drops as soon as you set eyes on this spirit. # Spirit of corrosion (acid) N:1065:Spirit G:G:s I:120:60d100:50:65:80 W:146:1:5:6000 E:1:1:1:2:1:1 O:25:60:0:15 B:HIT:ACID:10d8 B:HIT:ACID:10d8 B:HIT:ACID:10d8 F:SPIRIT | BASEANGBAND | IM_ACID | BASH_DOOR | KILL_TREES S:1_IN_2 | S:BO_ACID | BA_ACID D:The very fabric of the void heals itself where this spirit walks. # Spirit of shocking (electricity) N:1066:Spirit G:G:b I:120:60d100:50:65:80 W:149:1:5:6000 E:1:1:1:2:1:1 O:25:60:0:15 B:HIT:ELEC:10d8 B:HIT:ELEC:10d8 B:HIT:ELEC:10d8 F:SPIRIT | BASEANGBAND | IM_ELEC | AURA_ELEC | BASH_DOOR S:1_IN_2 | S:BO_ELEC | BA_ELEC D:The air crackles as this spirit approaches, and you smell singed flesh. # Spirit of Valaraukar (Balrogs) N:1067:Spirit G:G:v I:130:130d100:100:140:10 W:149:1:170:43000 E:1:1:1:2:1:1 O:0:100:0:0 B:HIT:FIRE:11d12 B:HIT:FIRE:11d12 B:CRUSH:HURT:10d12 B:TOUCH:UN_POWER F:SPIRIT | CAN_FLY | KILL_WALL | AURA_FIRE | NONLIVING | F:ONLY_ITEM | DROP_2D2 | EVIL | DEMON | F:OPEN_DOOR | BASH_DOOR | POWERFUL | MOVE_BODY | F:IM_FIRE | IM_ELEC | BASEANGBAND | HAS_LITE S:1_IN_3 | S:BLIND | CONF | SCARE | BR_FIRE D:Carrying a whip of fire, this spirit looks not dissimilar to a certain D:Balrog. # Spirit of shadows N:1068:Spirit G:G:d I:130:30d100:70:150:4 W:140:4:2300:10000 E:1:1:1:2:1:1 O:20:80:0:0 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:TOUCH:EXP_80:20d8 B:TOUCH:EXP_40:20d8 F:SPIRIT | BASEANGBAND | REFLECTING | REGENERATE | F:IM_ACID | IM_ELEC | IM_COLD | IM_FIRE | IM_POIS | RES_TELE | F:TAKE_ITEM | OPEN_DOOR | BASH_DOOR | SMART | POWERFUL S:1_IN_3 | S:BLIND | HEAL | BA_DARK | HASTE | CONF D:Deriving his strength from the shadows, this spirit D:steals only for the challenge. # Spirit of vampire or something N:1069:Spirit G:G:W I:130:50d50:30:90:10 W:143:2:1700:18000 E:1:1:1:2:1:1 O:0:70:30:0 B:HIT:HURT:10d9 B:HIT:HURT:9d9 B:BITE:EXP_80:9d9 B:BITE:EXP_80:9d9 F:SPIRIT | FORCE_SLEEP | CAN_FLY | F:DROP_60 | DROP_4D2 | F:COLD_BLOOD | OPEN_DOOR | BASH_DOOR | REGENERATE | RES_TELE | F:EVIL | UNDEAD | IM_COLD | IM_POIS | HURT_LITE | F:NO_CONF | NO_SLEEP | BASEANGBAND | NO_CUT | SPIRIT S:1_IN_3 | S:BLIND | HOLD | SCARE | CAUSE_3 | CAUSE_4 | DRAIN_MANA | S:BRAIN_SMASH | DARKNESS | BO_NETH D:Your blood curdles and your bones chill as this spirit approaches. # Spirit of unresistability (hehehehe) N:1070:Spirit G:G:v I:140:40d100:40:70:20 W:149:4:1200:20000 E:1:1:1:2:1:1: O:0:0:0:100 B:HIT:SHATTER:18d10 B:HIT:SHATTER:18d10 B:HIT:LOSE_ALL:8d8 B:TOUCH:UN_POWER F:BASEANGBAND | SPIRIT | SMART | F:OPEN_DOOR | BASH_DOOR | POWERFUL | F:RES_NEXU | RES_NETH | F:NO_CONF | NO_SLEEP | NO_FEAR | F:IM_POIS | IM_ELEC | IM_ACID | IM_COLD | S:1_IN_2 | S:BA_MANA | BR_PLAS | BR_TIME | ROCKET | HAND_DOOM | FORGET | BA_WATE D:This spirit appears to be afraid of very little, and confident in its D:ability to destroy you. # Spirit of time N:1071:Spirit G:G:G I:130:80d100:40:110:0 W:150:3:800:50000 E:0:1:0:2:1:0 O:0:0:0:0 B:TOUCH:TIME:6d12 B:TOUCH:TIME:6d12 B:TOUCH:TIME:6d12 B:TOUCH:TIME:6d12 F:OPEN_DOOR | BASH_DOOR | DROP_SKELETON | DROP_CORPSE | F:ANIMAL | NO_CONF | NO_SLEEP | F:SPIRIT | BASEANGBAND S:1_IN_2 | S:BR_TIME | SLOW | HASTE | HOLD D:All at once you see that which is to come and that which has gone before. # Spirit of Gold N:1072:Spirit G:G:y I:130:50d80:20:110:100 W:130:4:80:8000 E:0:1:0:2:1:0 O:100:0:0:0 B:TOUCH:EAT_GOLD:7d15 B:TOUCH:EAT_GOLD:7d15 B:HIT:POISON:6d12 B:HIT:POISON:6d12 F:ONLY_GOLD | SPIRIT | BASEANGBAND | F:DROP_4D2 | DROP_4D2 | DROP_4D2 | REFLECTING | COLD_BLOOD | REGENERATE | F:BASH_DOOR | MOVE_BODY | IM_ELEC | IM_COLD | IM_POIS | F:RES_TELE | NO_FEAR | NO_STUN | NO_CONF | NO_SLEEP S:1_IN_4 | S:ARROW_4 | HEAL | FORGET D:It is the very essence of financial greed... # Spirit of doom N:1073:Spirit G:G:D I:136:60d70:40:70:30 W:134:2:60:8000 E:1:1:1:2:1:1 O:0:10:90:0 B:HIT:HURT:14d14 B:HIT:HURT:14d14 B:HIT:HURT:14d14 F:SMART | OPEN_DOOR | BASH_DOOR | F:EVIL | NO_CONF | NO_SLEEP | F:SPIRIT | BASEANGBAND | HAS_LITE S:1_IN_2 | S:HAND_DOOM | CAUSE_4 | DARKNESS D:The very presence of this creature fills the air with an aura of doom. D:You feel waves of depression descending on you as it approaches. # Spirit of etherealism (?) N:1074:Spirit G:G:o I:120:40d100:30:120:40 W:141:3:1700:10000 E:0:1:0:6:1:0 B:CLAW:HURT:14d10 B:CLAW:HURT:14d10 B:BITE:HURT:17d10 F:INVISIBLE | CAN_FLY | SPIRIT | WEIRD_MIND | F:PASS_WALL | POWERFUL | MOVE_BODY | F:EVIL | NO_CONF | NO_SLEEP | BASEANGBAND | SPIRIT S:1_IN_2 | S:BLIND | CONF | S:BR_LITE | BR_DARK | BR_CONF D:This sprit seems to flicker in and out of this plane, and is a master D:of light and dark. # Spirit of orc (boring huh) N:1075:Spirit G:G:v I:120:90d10:30:160:100 W:142:3:2700:11111 E:1:1:1:2:1:1 O:10:90:0:0 B:HIT:HURT:10d10 B:HIT:HURT:10d10 B:HIT:HURT:10d10 F:OPEN_DOOR | BASH_DOOR | F:EVIL | ORC | IM_POIS | ONLY_ITEM | F:MORTAL | BASEANGBAND | HAS_LITE | SPIRIT D:Stupid but strong, this spirit has an orcish aura about him. ### Here endeth the Spirits ### N:1076:Neil, the Sorceror G:h:v # *Not* enough hitpoints I:110:50d100:20:30:30 # Bottom of Erebor W:72:100:330:50000 E:1:1:1:2:1:1 O:0:5:90:5 # Sorceror, not warrior B:HIT:HURT:1d1 B:HIT:HURT:1d1 F:OPEN_DOOR | SMART | MALE | DROP_SKELETON | DROP_CORPSE F:MORTAL | HAS_LITE | JOKEANGBAND | UNIQUE # Trone, of course F:CAN_FLY | REFLECTING | IM_FIRE # Thorin F:IM_ACID | FORCE_MAXHP # No cold or random gen... waiting on elven rings only at bottom of Erebor F:SPECIAL_GENE # Dig F:KILL_WALL # Obvious resistances F:NO_CONF | NO_SLEEP | NO_STUN | NO_FEAR # Well, he's been there a while F:ONLY_ITEM | DROP_4D2 | DROP_GOOD | DROP_GREAT # Essence of speed, Manathrust, Noxious Cloud, and Fireflash S:1_IN_1 | S:HASTE | BO_MANA | BA_POIS | BA_FIRE D:He looks like he is looking for something, and the flecks of dragon D:blood on his face tell you he means business! tome-235-src/lib/edit/t_lorien.txt0000644000076400017500000003515211012107760014740 0ustar dgdg# Town Name: Lothlorien # by Akhronath (zzhou22876@aol.com) # # Created for PernAngband # Default for Mage/Fireproof Quest = entrance is tree F:z:96:3 # Default for Quest 10 = entrance is tree F:y:96:3 # Default for Quest 11 = entrance is tree F:x:96:3 # Default for entrance to the Void, entrance is dirt F:v:88:3 # Default for Quest 22 = entrance is quest entrance F:w:8:3:0:0:0:0:0:22 ############### Quest 22 - Wolves hut finished = house ############### ?:[EQU $QUEST22 2] F:w:74:3:0:0:0:0:0:7 ?:[EQU $QUEST22 5] F:w:74:3:0:0:0:0:0:7 ?:1 ############### Entrance to the Void ############### ?:[EQU $QUEST20 1] F:v:7:3:0:0:0:0:0:11 ?:1 ############### Quest 10 - Spiders of Mirkwood ############### # Quest 10 taken, entrance is quest entrance ?:[EQU $QUEST10 1] F:y:8:3:0:0:0:0:0:10 ?:1 ############### Quest - Mage/Fireroof quest ############### # Mage/Fireproof Quest taken, entrance is quest entrance ?:[EQU $QUEST"Old Mages quest" 1] F:z:8:3:0:0:0:0:0:"Old Mages quest" ?:1 ###################### Buildings ######################## # The Mirror F:a:74:3:0:0:0:0:0:23 # Castle: Plot Lorien F:B:75:3:0:0:0:0:0:2 # Seat of Ruling F:b:74:3:0:0:0:0:0:24 # Inn F:c:74:3:0:0:0:0:0:11 # Beastmaster Shanty F:d:74:3:0:0:0:0:0:16 # Fighters Hall F:f:74:3:0:0:0:0:0:17 # Wizards Spire F:g:74:3:0:0:0:0:0:25 # Priests Circle F:h:74:3:0:0:0:0:0:26 # Rangers Guild allows Ranger F:i:74:3:0:0:0:0:0:21 # Nest F:j:74:3:0:0:0:0:0:22 # Altars F:k:161:3 F:l:162:3 F:m:163:3 F:n:165:3 # Force elven monsters f:ELVEN # Town Layout D:###################################################################################################################################################################################################### D:# , , , . , , ,, , , , # D:# , , . , # D:# , , . # D:# , , ,, , . , , , # D:# ,, , , , ,, , , , , , # D:# , , , , , , , , # D:# , , , ,x , , # D:# , , , , # D:# ,, , , , ,, , , , # D:# , , , , # D:# , , , , , , ,, , , , # D:# , , , , # D:# , , z,,,, ## , ## # D:# , , , #### , #### , # D:# , , , ### ###1,,,,,h### # D:# , , ### , #####, ####, , #### , , , # D:# ,, , ##### , ##### ## , ## , ,, , , , , , # D:# , , , ##### , ,##.## ### ## , ## , , # D:# , , # #, ##### , ##.## ######### , #### , , # D:# ,, , ### ### #g# , . ########c,,,,,4### ,, , , , # D:# , #### , #### , , , ,, ######### , #### , , , # D:# ,, , ############## ,,,,, , #9# ## , ## , ,, , , , , , # D:# , , , ############## , , , , , ## , , # D:# , , ###########j,,,,,,,,,,,,,, , , , #### , , # D:# , , #####B######## , ,,,,,,,,,,,,,,,,,,,,,,,,d### y , # D:# , , ############## , , , #### ,, , , ,, , , , # D:# , ,#### #### , , ## , , # D:# , , ### ### #6# ### ### , , ### ### # D:# , , # #, ##### ### ### , ,,, ########## , , # D:# ##### #7# #i# ,,,,,,,, ########## , , , # D:# ,, , ### , , , , , , #3# ### , , , # D:# , , , , ,, , , , , ## , # D:# , , ,,, ,,,,,,,,,,,,, ,,, , , , , #### ,, , , , # D:# , , , ,,,, ,,,,b,,,,,,,,,,,,,,,,,,,w### , # D:# , , v, ,,, , #### # D:# , , --,-- ,, , VVV , ## , , , # D:# ,, , l----,----m , VWWWV #2# ,, , , , , , # D:# , , , ---VV,VV--- , VWWVV , ##### , # D:# , , ---VVW,WVV--- , VVVV ##### , # D:# , , , ---VWWaWVV--- ,, ### , ,, , , , # D:# ---VVWWWVV--- ,,, , , , # D:# ,, , ---VVVVV--- ,,,,,,,,,,,,,,, , ,, , , , # D:# n---------k , , , , , # D:# , , --- , #5# , # D:# , , , ### # D:# , , , , ### , , , # D:# ,, , #0# , ,, , , , , , # D:# , , , , , ##### , , # D:# , , , ##### , , # D:# ### , , , # D:# ,, , , ,, , , , # D:# , , , # D:# , , , , , ,, , , , # D:# , , ,, , , , , # D:# ,, , , ,, , , , , , # D:# , , , , , , , # D:# , , , , , # D:# , , , # D:# ,, , , ,, , , , # D:# , , , # D:# , , # D:# , , ,, , , , , # D:# ,, , , ,, , , , , , # D:# # D:###################################################################################################################################################################################################### # Default starting position ?:[EQU $LEAVING_QUES 0] P:13:99 # Starting position when coming from quest 12 ?:[EQU $LEAVING_QUES 12] P:26:109 tome-235-src/lib/edit/haunted.map0000644000076400017500000000201511012107760014503 0ustar dgdg# permanent wall F:X:61:0 # granite F:#:57:0 # up staircase F:<:6:0 # Floor F:.:1:0 # Locked Door F:D:38:0 # Secret Door F:S:48:0 # Great item F:g:1:0:0:*:* # Dungeon layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XXX...D.........................X D:XXX...XXXXXXXXXXXXXXXXXXXXXXXXX.X D:XXX...X....X....X....X....X...X.X D:XXX...X....X....X....X....X...X.X D:XXX...X....X....X....X....X...X.X D:XXXDXXXDXXXXDXXXXDXXXXDXXXXDXXX.X D:XXX.............................X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.X D:X.S.....X.....X.....X.....X...X.X D:X.X.....X.....X.....X.....X...X.X D:X.X.....X.....X.....X.....X...X.X D:X.X.....X.....X.....X.....X...X.X D:XgX.....X.....X.....X.....X...X.X D:XXXDXXXXXDXXXXXDXXXXXDXXXXXDXXX.X D:XXX.............................X D:XXXXXXXDXXXXXDXXXXXDXXXXXDXXXXXDX D:XgX<....X.....X.....X.....X.....X D:X.X.....X.....X.....X.....X.....X D:X.X.....X.....X.....X.....X.....X D:X.X.....X.....X.....X.....X.....X D:X.S.....X.....X.....X.....X.....X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Starting position P:3:5 tome-235-src/lib/edit/al_info.txt0000644000076400017500000012471311012107760014536 0ustar dgdg# File: al_info.txt # This file is used to initialize the "lib/raw/al_info.raw" file, which is # used as the alchemist recipes in ToME # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes. # Version stamp (required) V:2.0.0 #Note: when you add anything to this file, you also need to change the M:a #line of misc.txt. Unlike other files, there is no 'count' entry. The #easiest and fastest way to find out what to say in misc.txt is: # # grep '^[Ia]:' :tval:sval:::level:xp # tval and sval describe the required item, they can be left unspecified # for no object, or specify starting with tval for increasingly specific # objects. #F:object flag to be set #D:Description of flag #x:Description of activation (instead of description of flag) #d:Description of required item #p:Description of required item (plural, not used for activations) #a:qty:object_flag_to_be_set Essence_name #define ACT_PET_SUMMON 150 #define ACT_CURE_PARA 151 #define ACT_CURE_HALLU 152 #define ACT_CURE_POIS 153 #define ACT_CURE_HUNGER 154 #define ACT_CURE_STUN 155 #define ACT_CURE_CUTS 156 #define ACT_CURE_FEAR 157 #define ACT_CURE_CONF 158 #define ACT_CURE_BLIND 159 #define ACT_CURING 160 #define ACT_ACQUIREMENT 163 #define ACT_MUT 166 #define ACT_CURE_INSANITY 167 #define ACT_CURE_MUT 168 #define ACT_REST_LIFE 84 #define ACT_REST_ALL 85 #define ACT_CURE_LW 81 #define ACT_CURE_MW 82 #define ACT_CURE_POISON 83 #define ACT_CURE_700 86 #define ACT_CURE_1000 87 #define ACT_LIGHT 111 #define ACT_SUNLIGHT 1 A:0:70:15:0:0:40:40000 x:SUNLIGHT D:Sunlight d:Brass Lantern #define ACT_MAP_LIGHT 112 #define ACT_DETECT_ALL 113 #define ACT_DETECT_XTRA 114 #define ACT_ID_FULL 115 #define ACT_ID_PLAIN 116 #define ACT_GROW_MOLD 197 #define ACT_BO_MISS_1 2 A:0:0:0:0:0:20:4000 x:BO_MISS_1 D:Magic Missile (1) #define ACT_BO_MISS_2 15 A:0:0:0:0:0:30:300000 x:BO_MISS_2 D:Magic Missile (2) #define ACT_BA_MISS_3 24 A:0:0:0:0:0:40:400000 x:BA_MISS_3 D:Ball of Missiles #define ACT_BO_ELEC_1 4 A:0:0:0:0:0:30:300000 x:BO_ELEC_1 D:Bolt of Lightning #define ACT_BA_ELEC_2 12 A:0:0:0:0:0:30:300000 x:BA_ELEC_2 D:Ball of Lightning #define ACT_BA_ELEC_3 18 A:0:0:0:0:0:35:350000 x:BA_ELEC_3 D:Ball of Lightning(2) #define ACT_BA_ELEC_H 172 A:0:0:0:0:0:40:400000 x:BA_ELEC_H D:Ball of Lightning(3) #define ACT_BA_ELEC_4 183 A:0:0:0:0:0:40:400000 x:BA_ELEC_4 D:Ball of Lightning(4) #define ACT_BR_ELEC 184 A:0:0:0:0:0:45:450000 x:BR_ELEC D:Breathe Lightning #define ACT_BO_ACID_1 5 #define ACT_BA_COLD_1 8 #define ACT_BA_ACID_H 173 #define ACT_BA_ACID_4 182 #define ACT_BR_ACID 187 #define ACT_BO_COLD_1 6 #define ACT_BA_COLD_2 11 #define ACT_BA_COLD_3 17 #define ACT_BA_COLD_H 171 #define ACT_BA_COLD_4 180 #define ACT_BR_COLD 185 #define ACT_BO_FIRE_1 7 #define ACT_BA_FIRE_1 9 #define ACT_BA_FIRE_2 16 #define ACT_BA_FIRE_H 170 #define ACT_BA_FIRE_4 181 #define ACT_BR_FIRE 186 #define ACT_BA_POIS_1 3 #define ACT_BA_POIS_4 179 #define ACT_BR_POIS 188 #define ACT_BR_MANY 189 #define ACT_BR_CONF 190 #define ACT_BR_SOUND 191 #define ACT_BR_CHAOS 192 #define ACT_BR_SHARD 193 #define ACT_BR_BALANCE 194 #define ACT_BR_LIGHT 195 #define ACT_BR_POWER 196 #define ACT_ROCKET 22 A:0:0:0:0:0:50:40000 x:ROCKET D:Fire a Rocket #define ACT_JUMP 177 #define ACT_WHIRLWIND 19 #define ACT_CALL_CHAOS 21 #define ACT_DISP_EVIL 23 #define ACT_DISP_GOOD 25 #define ACT_DAWN 61 #define ACT_CHARM_ANIMAL 65 #define ACT_CHARM_UNDEAD 66 #define ACT_CHARM_OTHER 67 #define ACT_CHARM_ANIMALS 68 #define ACT_CHARM_OTHERS 69 #define ACT_SUMMON_ANIMAL 70 #define ACT_SUMMON_PHANTOM 71 #define ACT_SUMMON_ELEMENTAL 72 #define ACT_SUMMON_DEMON 73 #define ACT_SUMMON_UNDEAD 74 #define ACT_RUNE_EXPLO 117 #define ACT_RUNE_PROT 118 #define ACT_SATIATE 119 #define ACT_DEST_DOOR 120 #define ACT_STONE_MUD 121 #define ACT_RECHARGE 122 #define ACT_ALCHEMY 123 #define ACT_DIM_DOOR 124 #define ACT_TELEPORT 125 #define ACT_RECALL 126 #define ACT_SPIN 174 #define ACT_NOLDOR 175 #define ACT_SPECTRAL 176 #define ACT_DEST_TELE 178 #define ACT_DRAIN_1 10 #define ACT_DRAIN_2 13 #define ACT_VAMPIRE_1 14 #define ACT_VAMPIRE_2 20 #define ACT_GILGALAD 26 #define ACT_CELEBRIMBOR 27 #define ACT_SKULLCLEAVER 28 #define ACT_HARADRIM 29 #define ACT_FUNDIN 30 #define ACT_EOL 31 #define ACT_UMBAR 32 #define ACT_NUMENOR 33 #define ACT_KNOWLEDGE 34 #define ACT_UNDEATH 35 #define ACT_THRAIN 36 #define ACT_BARAHIR 37 #define ACT_TULKAS 38 #define ACT_NARYA 39 #define ACT_NENYA 40 #define ACT_VILYA 41 #define ACT_POWER 42 #define ACT_STONE_LORE 43 #define ACT_RAZORBACK 44 #define ACT_BLADETURNER 45 #define ACT_MEDIATOR 46 #define ACT_BELEGENNON 47 #define ACT_GORLIM 48 #define ACT_COLLUIN 49 #define ACT_BELANGIL 50 #define ACT_CONFUSE 51 #define ACT_SLEEP 52 #define ACT_QUAKE 53 #define ACT_TERROR 54 #define ACT_TELE_AWAY 55 #define ACT_BANISH_EVIL 56 #define ACT_GENOCIDE 57 #define ACT_MASS_GENO 58 #define ACT_ANGUIREL 59 #define ACT_ERU 60 #define ACT_FIRESTAR 62 #define ACT_TURMIL 63 #define ACT_CUBRAGOL 64 #define ACT_ELESSAR 75 #define ACT_GANDALF 76 #define ACT_MARDA 77 #define ACT_PALANTIR 78 #define ACT_ROBINTON 79 #define ACT_PIEMUR 80 #define ACT_MENOLLY 88 #define ACT_EREBOR 89 #define ACT_DRUEDAIN 90 #define ACT_ESP 91 #define ACT_BERSERK 92 #define ACT_PROT_EVIL 93 #define ACT_RESIST_ALL 94 #define ACT_SPEED 95 #define ACT_XTRA_SPEED 96 #define ACT_WRAITH 97 #define ACT_INVULN 98 #define ACT_ROHAN 99 #define ACT_HELM 100 #define ACT_BOROMIR 101 #define ACT_HURIN 102 #define ACT_AXE_GOTHMOG 103 #define ACT_MELKOR 104 #define ACT_GROND 105 #define ACT_NATUREBANE 106 #define ACT_NIGHT 107 #define ACT_ORCHAST 108 #define ACT_DEATH 127 #define ACT_RUINATION 128 #define ACT_DESTRUC 129 #define ACT_UNINT 130 #define ACT_UNSTR 131 #define ACT_UNCON 132 #define ACT_UNCHR 133 #define ACT_UNDEX 134 #define ACT_UNWIS 135 #define ACT_STATLOSS 136 #define ACT_HISTATLOSS 137 #define ACT_EXPLOSS 138 #define ACT_HIEXPLOSS 139 #define ACT_SUMMON_MONST 140 #define ACT_PARALYZE 141 #define ACT_HALLU 142 #define ACT_POISON 143 #define ACT_HUNGER 144 #define ACT_STUN 145 #define ACT_CUTS 146 #define ACT_PARANO 147 #define ACT_CONFUSION 148 #define ACT_BLIND 149 #define ACT_DARKNESS 161 #define ACT_LEV_TELE 162 #define ACT_WEIRD 164 #define ACT_AGGRAVATE 165 #define ACT_LIGHT_ABSORBTION 169 #define ACT_MUSIC 200 #***************************Amulets*********************** #SV_AMULET_ADORNMENT I:40:2:4:DARKNESS #SV_AMULET_BRILLANCE I:40:6:1:KNOWLEDGE I:40:6:2:CONFUSION #SV_AMULET_CHARISMA I:40:7:4:DARKNESS #SV_AMULET_DEVOTION I:40:25:1:MAGIC I:40:25:2:CONFUSION I:40:25:8:KNOWLEDGE #SV_AMULET_ESP I:40:22:4:KNOWLEDGE #SV_AMULET_INFRA I:40:26:1:LITE #SV_AMULET_NO_MAGIC I:40:13:4:MAGIC #SV_AMULET_NO_TELE I:40:14:8:TELEPORT #SV_AMULET_REFLECTION I:40:9:10:FORCE I:40:9:10:MANA #SV_AMULET_REGENERATION I:40:30:4:LIFE #SV_AMULET_RESISTANCE I:40:15:4:ACID I:40:15:4:COLD I:40:15:4:FIRE I:40:15:4:LIGHTNING #SV_AMULET_RESIST_ACID I:40:4:4:ACID #SV_AMULET_RESIST_ELEC I:40:29:4:LIGHTNING #SV_AMULET_SEARCHING I:40:5:4:KNOWLEDGE I:40:5:4:LITE #SV_AMULET_SERPENT I:40:17:1:MANA I:40:17:4:ACID #SV_AMULET_SLOW_DIGEST I:40:3:4:LIFE #SV_AMULET_SUSTENANCE I:40:21:8:LIFE #SV_AMULET_TELEPORT I:40:1:8:TELEPORT #SV_AMULET_THE_MAGI I:40:8:1:MAGIC I:40:8:4:KNOWLEDGE #SV_AMULET_TRICKERY #I:40:23:1:MAGIC I:40:23:8:CONFUSION #SV_AMULET_WEAPONMASTERY I:40:24:12:EXPLOSION I:40:24:1:MAGIC #SV_AMULET_WISDOM I:40:28:1:KNOWLEDGE I:40:28:2:CONFUSION #*********Potions****************************** #Note that these first few potions are the ones which #can be thrown for much damage, and are thus an integral part of #the alchemist's arsenal. #SV_POTION_DETONATIONS I:71:22:6:EXPLOSION #SV_POTION_DEATH I:71:23:10:LIFE #SV_POTION_RUINATION I:71:15:5:DARKNESS #SV_POTION_APPLE_JUICE I:71:1:1:LIFE #SV_POTION_AUGMENTATION I:71:55:16:POISON I:71:55:24:CONFUSION I:71:55:6:MAGIC I:71:55:8:EXPLOSION I:71:55:16:LIFE I:71:55:8:LIGHTNING I:71:55:16:DARKNESS #SV_POTION_BESERK_STRENGTH I:71:33:1:FIRE #SV_POTION_BLINDNESS I:71:7:1:DARKNESS #SV_POTION_BOLDNESS I:71:28:1:LITE #SV_POTION_CONFUSION I:71:9:1:CONFUSION #SV_POTION_CURE_CRITICAL I:71:36:4:LIFE #SV_POTION_CURE_LIGHT I:71:34:1:LIFE #SV_POTION_CURE_SERIOUS I:71:35:2:LIFE #SV_POTION_CURING I:71:61:1:LIFE #SV_POTION_DEC_CHR I:71:21:1:MANA I:71:21:8:DARKNESS I:71:21:8:CONFUSION #SV_POTION_DEC_CON I:71:20:1:MANA I:71:20:8:LIFE I:71:20:8:POISON #SV_POTION_DEC_DEX I:71:19:1:MANA I:71:19:8:LIGHTNING I:71:19:8:DARKNESS #SV_POTION_DEC_INT I:71:17:1:MANA I:71:17:8:CONFUSION I:71:17:8:KNOWLEDGE #SV_POTION_DEC_STR I:71:16:1:MANA I:71:16:8:EXPLOSION I:71:16:8:POISON #SV_POTION_DEC_WIS I:71:18:1:MANA I:71:18:8:CONFUSION I:71:18:8:LIFE #SV_POTION_DETECT_INVIS I:71:25:1:DARKNESS I:71:25:1:LITE #SV_POTION_ENLIGHTENMENT I:71:56:8:KNOWLEDGE #SV_POTION_EXPERIENCE I:71:59:30:EXTRALIFE #SV_POTION_HEALING I:71:37:1:EXTRALIFE #SV_POTION_HEROISM I:71:32:1:COLD #SV_POTION_INC_CHR I:71:53:1:MAGIC I:71:53:8:DARKNESS I:71:53:8:CONFUSION #SV_POTION_INC_CON I:71:52:1:MAGIC I:71:52:8:LIFE I:71:52:8:POISON #Potion of Slow Poison I:71:26:1:POISON #Potion of Cure Poison I:71:27:2:POISON #Potion of Poison I:71:6:1:POISON #SV_POTION_INC_DEX I:71:51:1:MAGIC I:71:51:8:LIGHTNING I:71:51:8:DARKNESS #SV_POTION_INC_INT I:71:49:1:MAGIC I:71:49:8:KNOWLEDGE I:71:49:8:CONFUSION #SV_POTION_INC_STR I:71:48:1:MAGIC I:71:48:8:EXPLOSION I:71:48:8:POISON #SV_POTION_INC_WIS I:71:50:1:MAGIC I:71:50:8:CONFUSION I:71:50:8:LIFE #SV_POTION_INFRAVISION I:71:24:1:LITE #SV_POTION_INVIS I:71:8:4:DARKNESS #SV_POTION_INVULNERABILITY I:71:62:10:FORCE I:71:62:4:MAGIC #SV_POTION_LIFE I:71:39:8:EXTRALIFE #SV_POTION_LOSE_MEMORIES I:71:13:20:DARKNESS #SV_POTION_MUTATION I:71:10:12:CHAOS #SV_POTION_NEW_LIFE I:71:63:16:EXTRALIFE #SV_POTION_RESISTANCE I:71:60:2:ACID I:71:60:2:COLD I:71:60:2:FIRE I:71:60:2:LIGHTNING #SV_POTION_RESIST_COLD I:71:31:1:COLD #SV_POTION_RESIST_HEAT I:71:30:1:FIRE #SV_POTION_RESTORE_EXP I:71:41:8:LIFE I:71:41:3:KNOWLEDGE #SV_POTION_RESTORE_MANA I:71:40:12:MANA #SV_POTION_RES_CHR I:71:47:12:LIFE #SV_POTION_RES_CON I:71:46:12:LIFE #SV_POTION_RES_DEX I:71:45:12:LIFE #SV_POTION_RES_INT I:71:43:12:LIFE #SV_POTION_RES_STR I:71:42:12:LIFE #SV_POTION_RES_WIS I:71:44:12:LIFE #SV_POTION_SALT_WATER I:71:5:1:LIGHTNING #SV_POTION_SELF_KNOWLEDGE I:71:58:2:KNOWLEDGE #SV_POTION_SLEEP I:71:11:1:MANA #SV_POTION_SLIME_MOLD I:71:2:1:LIFE #SV_POTION_SLOWNESS I:71:4:1:MANA #SV_POTION_SPEED I:71:29:1:TIME #SV_POTION_STAR_ENLIGHTENMENT I:71:57:12:KNOWLEDGE #SV_POTION_STAR_HEALING I:71:38:4:EXTRALIFE #SV_POTION_WATER I:71:0:1:LIFE #********************************Potion 2********************************* #SV_POTION2_MIMIC 1 I:72:1:2:LIFE #SV_POTION2_CURE_LIGHT_SANITY 14 I:72:14:1:CONFUSION I:72:14:1:DARKNESS #SV_POTION2_CURE_SERIOUS_SANITY 15 I:72:15:2:CONFUSION I:72:15:2:DARKNESS #SV_POTION2_CURE_CRITICAL_SANITY 16 I:72:16:4:CONFUSION I:72:16:4:DARKNESS #SV_POTION2_CURE_SANITY 17 I:72:17:8:CONFUSION I:72:17:8:DARKNESS #SV_POTION2_CURE_WATER 18 #I:72:18:4:EXPLOSION #I:72:18:4:POISON #I:72:18:2:EXTRALIFE #************Rod Tips.**************************** #SV_ROD_ACID_BALL I:66:24:1:MAGIC I:66:24:8:ACID #SV_ROD_ACID_BOLT I:66:20:4:ACID #SV_ROD_COLD_BALL I:66:27:1:MAGIC I:66:27:8:COLD #SV_ROD_COLD_BOLT I:66:23:4:COLD #SV_ROD_CURING I:66:8:3:LIFE #SV_ROD_DETECTION I:66:6:8:KNOWLEDGE #SV_ROD_DETECT_DOOR I:66:1:1:KNOWLEDGE #SV_ROD_DETECT_TRAP I:66:29:1:KNOWLEDGE #SV_ROD_DISARMING I:66:14:4:TELEPORT #SV_ROD_DRAIN_LIFE I:66:18:10:LIFE #SV_ROD_ELEC_BALL I:66:25:1:MAGIC I:66:25:8:LIGHTNING #SV_ROD_ELEC_BOLT I:66:21:4:LIGHTNING #SV_ROD_FIRE_BALL I:66:26:1:MAGIC I:66:26:8:FIRE #SV_ROD_FIRE_BOLT I:66:22:4:FIRE #SV_ROD_HAVOC I:66:28:5:CHAOS #SV_ROD_HEALING I:66:9:4:EXTRALIFE #SV_ROD_IDENTIFY I:66:2:4:MANA I:66:2:4:KNOWLEDGE #SV_ROD_ILLUMINATION I:66:4:4:LITE #SV_ROD_LITE I:66:15:1:LITE #SV_ROD_MAPPING I:66:5:1:KNOWLEDGE I:66:5:8:LITE #SV_ROD_POLYMORPH I:66:19:1:CHAOS #SV_ROD_PROBING I:66:7:20:KNOWLEDGE I:66:7:3:MANA #SV_ROD_RECALL I:66:3:3:FORCE I:66:3:9:TELEPORT #SV_ROD_RESTORATION I:66:10:30:LIFE #SV_ROD_SLEEP_MONSTER I:66:16:1:MANA #SV_ROD_SLOW_MONSTER I:66:17:1:TIME #SV_ROD_SPEED I:66:11:10:TIME #SV_ROD_TELEPORT_AWAY I:66:13:8:TELEPORT #**************************Scrolls ******************** #SV_SCROLL_ACQUIREMENT I:70:46:10:MAGIC #SV_SCROLL_ARTIFACT I:70:52:99:MAGIC #SV_SCROLL_BLESSING I:70:33:1:LIFE #SV_SCROLL_CHAOS I:70:50:2:CHAOS #SV_SCROLL_DARKNESS I:70:0:1:DARKNESS #SV_SCROLL_DETECT_DOOR I:70:29:1:KNOWLEDGE #SV_SCROLL_DETECT_GOLD I:70:26:1:KNOWLEDGE #SV_SCROLL_DETECT_INVIS I:70:30:1:DARKNESS I:70:30:1:KNOWLEDGE #SV_SCROLL_DETECT_ITEM I:70:27:2:KNOWLEDGE #SV_SCROLL_DETECT_TRAP I:70:28:1:KNOWLEDGE #SV_SCROLL_DISPEL_UNDEAD I:70:42:1:EXTRALIFE #SV_SCROLL_ENCHANT_ARMOR I:70:16:3:EXPLOSION #SV_SCROLL_ENCHANT_WEAPON_PVAL I:70:19:10:MAGIC #SV_SCROLL_ENCHANT_WEAPON_TO_DAM I:70:18:3:EXPLOSION #SV_SCROLL_ENCHANT_WEAPON_TO_HIT I:70:17:3:LITE #SV_SCROLL_FIRE I:70:48:1:FIRE #SV_SCROLL_GENOCIDE I:70:44:1:FORCE I:70:44:5:DARKNESS #SV_SCROLL_HOLY_CHANT I:70:34:2:LIFE #SV_SCROLL_HOLY_PRAYER I:70:35:3:LIFE #SV_SCROLL_ICE I:70:49:1:COLD #SV_SCROLL_IDENTIFY I:70:12:1:KNOWLEDGE #SV_SCROLL_LIGHT I:70:24:1:LITE #SV_SCROLL_MAPPING I:70:25:2:KNOWLEDGE I:70:25:5:LITE #SV_SCROLL_MASS_GENOCIDE I:70:45:1:FORCE I:70:45:30:DARKNESS #SV_SCROLL_MONSTER_CONFUSION I:70:36:1:CONFUSION #SV_SCROLL_PHASE_DOOR I:70:8:1:TELEPORT #SV_SCROLL_PROTECTION_FROM_EVIL I:70:37:1:MANA I:70:37:9:LIFE #SV_SCROLL_RECHARGING I:70:22:4:LIGHTNING #SV_SCROLL_REMOVE_CURSE I:70:14:1:LIFE #SV_SCROLL_RESET_RECALL I:70:23:1:FORCE #SV_SCROLL_RUMOR I:70:51:1:LIGHTNING #SV_SCROLL_RUNE_OF_PROTECTION I:70:38:1:EXTRALIFE I:70:38:6:FORCE #SV_SCROLL_SATISFY_HUNGER I:70:32:1:LIFE #SV_SCROLL_STAR_ACQUIREMENT I:70:47:20:MAGIC #SV_SCROLL_STAR_DESTRUCTION I:70:41:12:FORCE #SV_SCROLL_STAR_ENCHANT_ARMOR I:70:20:9:EXPLOSION #SV_SCROLL_STAR_ENCHANT_WEAPON I:70:21:9:EXPLOSION I:70:21:9:LITE #SV_SCROLL_STAR_IDENTIFY I:70:13:1:MAGIC I:70:13:20:KNOWLEDGE #SV_SCROLL_STAR_REMOVE_CURSE I:70:15:1:EXTRALIFE #SV_SCROLL_TELEPORT I:70:9:1:TELEPORT #SV_SCROLL_TELEPORT_LEVEL I:70:10:5:TELEPORT #SV_SCROLL_TRAP_CREATION I:70:7:1:CONFUSION I:70:7:1:TELEPORT #SV_SCROLL_TRAP_DOOR_DESTRUCTION I:70:39:1:FORCE #SV_SCROLL_WORD_OF_RECALL I:70:11:1:FORCE I:70:11:3:TELEPORT #***************************Staves************************ #Globe of Light I:55:3:1:LITE #Fiery Shield I:55:4:2:FIRE I:55:4:1:MANA #Remove Curse I:55:5:2:LIFE #Wings of Winds I:55:6:1:FORCE #Shake I:55:7:4:FORCE #Disarm I:55:8:1:FORCE I:55:8:1:KNOWLEDGE #Teleportation I:55:9:1:TELEPORT #Probability Travel I:55:10:1:MANA I:55:10:1:TELEPORT #11 Recovery I:55:11:1:LIFE #12 Healing I:55:12:1:EXTRALIFE #13 Vision I:55:13:1:LITE #Identify I:55:14:1:KNOWLEDGE I:55:14:1:MANA #Sense Hidden I:55:15:1:KNOWLEDGE #Reveal Ways I:55:16:1:KNOWLEDGE #Sense Monsters I:55:17:1:KNOWLEDGE #Genocide I:55:18:1:FORCE I:55:18:5:DARKNESS #19 Summon I:55:19:1:LIFE I:55:19:1:TELEPORT #Wish I:55:20:99:MAGIC #Mana I:55:21:1:MANA #Sterilize I:55:24:1:POISON I:55:24:1:MANA #********************Wands***************** #MannaThrust I:65:3:4:MANA #FireFlash I:65:4:1:FIRE #FireWall I:65:5:4:FIRE I:65:5:1:MANA #Tidal Wave I:65:6:1:POISON I:65:6:1:ACID I:65:6:1:COLD #Ice Storm I:65:7:4:COLD I:65:7:1:MANA #Wand of Noxious Cloud I:65:8:1:POISON #Poison Blood I:65:9:2:POISON I:65:9:1:LIFE #Thunderstorm I:65:10:4:LIGHTNING #DIG I:65:11:1:FORCE #Stone Prison I:65:12:3:FORCE I:65:12:1:MANA #Strike I:65:13:1:FORCE #Teleport Away I:65:14:1:TELEPORT #Summon Animal I:65:15:4:LIFE I:65:15:1:MANA #MageLock I:65:16:1:FORCE #Slow Monster I:65:17:1:MANA #Essence of Speed I:65:18:1:TIME #Banishment I:65:19:2:TELEPORT #20 Disperse Magic I:65:20:4:LIFE I:65:20:4:MANA #Charm I:65:21:1:MANA I:65:21:1:LIFE #Confuse I:65:22:1:CONFUSION #Deamon Blade I:65:23:1:FORCE I:65:23:1:FIRE #Heal Monster I:65:24:1:LIFE #25 Haste Monster I:65:25:1:MANA #RINGS********************************************************* #ring of poison resistance I:45:20:8:POISON #Ring of Critical Hits I:45:59:8:MANA #Damage I:45:29:1:EXPLOSION #Slaying I:45:30:8:EXPLOSION I:45:30:8:LITE #Sound Resistance I:45:42:4:EXPLOSION I:45:42:4:LITE #Shard Resistance I:45:44:4:EXPLOSION I:45:44:4:TELEPORT #Flying I:45:54:12:TELEPORT #Extra Attacks I:45:49:8:TELEPORT I:45:49:4:TIME #Teleportation I:45:4:8:TELEPORT #Lordly Protection I:45:48:4:TELEPORT I:45:48:12:LITE I:45:48:1:EXTRALIFE #Ring of Ice I:45:19:8:COLD #Ring of Cold Resistance I:45:9:4:COLD #Ring of Flames I:45:18:8:FIRE #Ring of Fire Resistance I:45:8:4:FIRE #Ring of Acid I:45:17:8:ACID #Ring of Disenchantment Resistance I:45:45:8:ACID I:45:45:2:CHAOS #Ring of slow digestion I:45:6:4:LIFE I:45:6:1:TIME #ring of confusion resistance I:45:43:8:CONFUSION #Ring of Stupidity I:45:3:1:CONFUSION #Ring of Blindness Resistance I:45:47:8:LITE #Ring of Accuracy I:45:28:1:LITE #Ring of Searching I:45:23:4:LITE I:45:23:3:KNOWLEDGE #Ring of Chaos I:45:46:8:LITE #Ring of Light and Darkness Resistance I:45:39:8:LITE I:45:39:8:DARKNESS #Ring of Speed I:45:31:12:TIME #ring of Weakness I:45:2:1:POISON #ring of Constitution I:45:27:2:POISON I:45:27:8:LIFE #ring of Strength I:45:24:1:POISON I:45:24:1:EXPLOSION #Ring of Dexterity I:45:26:1:KNOWLEDGE I:45:26:1:LIGHTNING #ring of Sustain Constitution I:45:13:1:POISON I:45:13:4:LIFE I:45:13:1:MANA #ring of Sustain Strength I:45:10:1:POISON I:45:10:1:EXPLOSION I:45:10:1:MANA #ring of Sustain Intelligence I:45:11:1:CONFUSION I:45:11:1:MANA #ring of Intelligence I:45:25:1:CONFUSION I:45:25:12:KNOWLEDGE #Ring of Sustain Wisdom I:45:12:1:MANA I:45:12:4:CONFUSION #Ring of Sustain Dexterity I:45:14:1:MANA I:45:14:1:LIGHTNING #Ring of Sustain Charisma I:45:15:1:MANA I:45:15:1:DARKNESS #Ring of See Invisible I:45:22:8:DARKNESS #Ring of Invisibility I:45:53:8:DARKNESS #Ring of Fear resistance I:45:38:1:MAGIC #Ring of Levitation I:45:7:1:MANA #Ring of Nether Resistance I:45:40:1:MANA I:45:40:12:LIFE #Ring of Nexus Resistance I:45:41:1:MANA #Ring of Free Action I:45:21:1:FORCE #Ring of Protection I:45:16:10:FORCE #Ring of Lightning I:45:56:12:LIGHTNING #EGO ITEMS, in order by e_idx I:1:1:1:MAGIC },/*of Mana*/ I:1:2:2:MAGIC },/*of Power*/ I:1:3:3:MAGIC },/*of Wizardry*/ I:1:4:2:MAGIC },/*of Spell*/ I:1:5:4:ACID },/*of Resist Acid*/ I:1:6:4:LIGHTNING },/*of Resist Lightning*/ I:1:7:4:FIRE },/*of Resist Fire*/ I:1:8:4:COLD },/*of Resist Cold*/ I:1:9:4:ACID },/*of Resistance*/ I:1:9:4:COLD },/*of Resistance*/ I:1:9:4:FIRE },/*of Resistance*/ I:1:9:4:LIGHTNING },/*of Resistance*/ I:1:10:5:ACID },/*Elven*/ I:1:10:5:COLD },/*Elven*/ I:1:10:5:FIRE },/*Elven*/ I:1:10:5:LIGHTNING },/*Elven*/ I:1:11:1:MAGIC },/*of Permanence*/ I:1:11:6:ACID },/*of Permanence*/ I:1:11:6:COLD },/*of Permanence*/ I:1:11:6:FIRE },/*of Permanence*/ I:1:11:6:LIGHTNING },/*of Permanence*/ I:1:12:1:POISON },/*of Leprousness*/ I:1:13:3:MAGIC },/*of Immunity*/ I:1:14:5:MAGIC },/*of Defense*/ I:1:15:4:TELEPORT },/*of Jumping*/ I:1:16:4:ACID },/*of Resist Acid*/ I:1:17:4:LIGHTNING },/*of Resist Lightning*/ I:1:18:4:FIRE },/*of Resist Fire*/ I:1:19:4:COLD },/*of Resist Cold*/ I:1:20:4:ACID },/*of Resistance*/ I:1:20:4:COLD },/*of Resistance*/ I:1:20:4:FIRE },/*of Resistance*/ I:1:20:4:LIGHTNING },/*of Resistance*/ I:1:21:12:FORCE },/*of Reflection*/ I:1:22:8:LIGHTNING },/*of Electricity*/ I:1:23:4:DARKNESS },/*of the Noldor*/ I:1:24:4:KNOWLEDGE },/*of Intelligence*/ I:1:25:4:KNOWLEDGE },/*of Wisdom*/ I:1:26:4:KNOWLEDGE },/*of Beauty*/ I:1:27:12:KNOWLEDGE },/*of the Magi*/ I:1:28:12:EXPLOSION },/*of Might*/ I:1:29:4:MANA },/*of Lordliness*/ I:1:30:8:KNOWLEDGE },/*of Seeing*/ I:1:31:1:LITE },/*of Infravision*/ I:1:32:1:LITE },/*of Light*/ I:1:33:8:KNOWLEDGE },/*of Telepathy*/ I:1:34:4:LIFE },/*of Regeneration*/ I:1:35:4:TELEPORT },/*of Teleportation*/ I:1:40:8:EXPLOSION },/*Dwarven*/ I:1:40:8:FIRE },/*Dwarven*/ I:1:40:8:LIFE },/*Dwarven*/ I:1:40:8:LITE },/*Dwarven*/ I:1:40:8:MANA },/*Dwarven*/ I:1:41:4:FORCE },/*of Protection*/ I:1:42:4:DARKNESS },/*of Stealth*/ I:1:43:4:ACID },/*of Aman*/ I:1:43:4:COLD },/*of Aman*/ I:1:43:4:DARKNESS },/*of Aman*/ I:1:43:4:FIRE },/*of Aman*/ I:1:43:4:LIGHTNING },/*of Aman*/ I:1:44:8:FIRE },/*of Immolation*/ I:1:48:8:LIGHTNING },/*of Electricity*/ I:1:49:1:FORCE },/*of Free Action*/ I:1:50:4:FORCE },/*of Slaying*/ I:1:50:4:LITE },/*of Slaying*/ I:1:51:4:LIGHTNING },/*of Agility*/ I:1:52:4:EXPLOSION },/*of Power*/ I:1:54:2:DARKNESS },/*of Charming*/ I:1:57:3:DARKNESS },/*of Levitation*/ I:1:58:3:DARKNESS },/*of Stealth*/ I:1:59:3:DARKNESS },/*of Free Action*/ I:1:60:5:TIME },/*of Speed*/ I:1:61:2:DARKNESS },/*of Dwarvish Endurance*/ I:1:61:2:EXPLOSION },/*of Dwarvish Endurance*/ I:1:65:4:ACID },/*of Aman*/ I:1:65:4:COLD },/*of Aman*/ I:1:65:4:DARKNESS },/*of Aman*/ I:1:65:4:FIRE },/*of Aman*/ I:1:65:4:LIGHTNING },/*of Aman*/ I:1:66:1:MAGIC },/*(Defender)*/ I:1:66:4:ACID },/*(Defender)*/ I:1:66:4:COLD },/*(Defender)*/ I:1:66:4:FIRE },/*(Defender)*/ I:1:66:4:LIGHTNING },/*(Defender)*/ I:1:67:8:KNOWLEDGE },/*Blessed*/ I:1:68:12:LIFE },/*of Greater Life*/ I:1:68:2:MAGIC },/*of Greater Life*/ I:1:69:4:DARKNESS },/*of Westernesse*/ I:1:69:4:EXPLOSION },/*of Westernesse*/ I:1:69:4:LIGHTNING },/*of Westernesse*/ I:1:69:4:LITE },/*of Westernesse*/ I:1:70:2:TIME },/*of Extra Attacks*/ I:1:71:4:FORCE },/*of Slaying*/ I:1:71:4:LITE },/*of Slaying*/ I:1:72:4:EXPLOSION },/*of Spinning*/ I:1:72:4:LIGHTNING },/*of Spinning*/ I:1:73:4:ACID },/*Acidic*/ I:1:74:4:LIGHTNING },/*Shocking*/ I:1:75:4:FIRE },/*Fiery*/ I:1:76:4:COLD },/*Frozen*/ I:1:77:4:POISON },/*Venomous*/ I:1:78:4:CHAOS },/*Chaotic*/ I:1:79:4:FORCE },/*Sharp*/ I:1:80:4:FORCE },/*of Earthquakes*/ I:1:81:8:CHAOS },/*of Slay Animal*/ I:1:82:8:CHAOS },/*of Slay Evil*/ I:1:83:8:CHAOS },/*of Slay Undead*/ I:1:84:8:CHAOS },/*of Slay Demon*/ I:1:85:8:CHAOS },/*of Slay Orc*/ I:1:86:8:CHAOS },/*of Slay Troll*/ I:1:87:8:CHAOS },/*of Slay Giant*/ I:1:88:8:CHAOS },/*of Slay Dragon*/ I:1:89:12:CHAOS },/*of *Slay Animal**/ I:1:90:12:CHAOS },/*of *Slay Evil**/ I:1:91:12:CHAOS },/*of *Slay Undead**/ I:1:92:12:CHAOS },/*of *Slay Demon**/ I:1:93:12:CHAOS },/*of *Slay Orc**/ I:1:94:12:CHAOS },/*of *Slay Troll**/ I:1:95:12:CHAOS },/*of *Slay Giant**/ I:1:96:12:CHAOS },/*of *Slay Dragon**/ I:1:97:8:LIFE },/*Vampiric*/ I:1:98:4:MAGIC },/*(*Defender*)*/ I:1:98:8:ACID },/*(*Defender*)*/ I:1:98:8:COLD },/*(*Defender*)*/ I:1:98:8:FIRE },/*(*Defender*)*/ I:1:98:8:LIGHTNING },/*(*Defender*)*/ I:1:98:8:POISON },/*(*Defender*)*/ I:1:99:12:TELEPORT },/*of the Thunderlords*/ I:1:100:12:KNOWLEDGE },/*of Gondolin*/ I:1:100:1:MAGIC },/*of Gondolin*/ I:1:101:1:FORCE },/*of Digging*/ I:1:102:12:LIFE },/*Spectral*/ I:1:102:4:MANA },/*Spectral*/ I:1:105:1:LITE },/*of Accuracy*/ I:1:106:2:FORCE },/*of Power*/ I:1:107:2:FORCE },/*of Extra Might*/ I:1:108:1:FORCE },/*of Extra Shots*/ I:1:108:1:LITE },/*of Extra Shots*/ I:1:108:1:TIME },/*of Extra Shots*/ I:1:109:2:FORCE },/*of Lothlorien*/ I:1:109:2:LITE },/*of Lothlorien*/ I:1:110:2:FORCE },/*of the Haradrim*/ I:1:110:2:LITE },/*of the Haradrim*/ I:1:111:2:FORCE },/*of Buckland*/ I:1:111:2:LITE },/*of Buckland*/ I:1:112:1:CHAOS },/*of Slay Animal*/ I:1:113:1:CHAOS },/*of Slay Evil*/ I:1:114:1:CHAOS },/*of Slay Undead*/ I:1:115:1:POISON },/*of Venom*/ I:1:116:1:ACID },/*of Acid*/ I:1:117:12:ACID },/*Elemental*/ I:1:117:12:COLD },/*Elemental*/ I:1:117:12:FIRE },/*Elemental*/ I:1:117:12:LIGHTNING },/*Elemental*/ I:1:117:12:POISON },/*Elemental*/ I:1:118:1:CHAOS },/*of Slay Demon*/ I:1:119:1:CHAOS },/*of Slay Dragon*/ I:1:120:1:FORCE },/*of Slaying*/ I:1:120:1:LITE },/*of Slaying*/ I:1:121:1:LIGHTNING },/*of Lightning*/ I:1:121:1:LITE },/*of Lightning*/ I:1:122:1:FIRE },/*of Flame*/ I:1:122:1:LITE },/*of Flame*/ I:1:123:1:COLD },/*of Frost*/ I:1:123:1:LITE },/*of Frost*/ I:1:124:1:LIFE },/*of Wounding*/ I:1:128:2:ACID },/*of the Eldar*/ I:1:128:2:DARKNESS },/*of the Eldar*/ I:1:129:2:ACID },/*of Power*/ I:1:129:2:COLD },/*of Power*/ I:1:129:2:DARKNESS },/*of Power*/ I:1:129:2:FIRE },/*of Power*/ I:1:129:2:LIGHTNING },/*of Power*/ I:1:130:1:MANA },/*Dragon*/ I:1:131:1:MANA },/*Capacity of */ I:1:132:1:LIFE },/*Cheapness of */ I:1:133:1:TIME },/*Quickness of */ I:1:134:1:TIME },/*Charging of */ I:1:135:3:LIFE },/*the Istari of */ I:1:135:3:MANA },/*the Istari of */ I:1:135:3:TIME },/*the Istari of */ I:1:136:1:LITE },/*of Boldness*/ I:1:137:1:LITE },/*of Fearlessness*/ I:1:138:2:LITE },/*of Illumination*/ I:1:139:2:LITE },/*of Brightness*/ I:1:140:4:LITE },/*of *Brightness**/ I:1:141:4:DARKNESS },/*of the Shadows*/ I:1:141:4:LITE },/*of the Shadows*/ I:1:142:4:DARKNESS },/*of Infravision*/ I:1:142:4:LITE },/*of Infravision*/ I:1:143:8:DARKNESS },/*of the Eternal Eye*/ I:1:144:4:MANA },/*of the Ethereal Eye*/ I:1:146:4:DARKNESS },/*Dwarven*/ I:1:146:4:EXPLOSION },/*Dwarven*/ I:1:146:4:LITE },/*Dwarven*/ I:1:147:1:MAGIC },/*Indestructible*/ I:1:147:4:ACID },/*Indestructible*/ I:1:147:4:COLD },/*Indestructible*/ I:1:147:4:FIRE },/*Indestructible*/ I:1:147:4:LIGHTNING },/*Indestructible*/ I:1:147:4:MANA },/*Indestructible*/ I:1:149:1:FIRE },/*Fireproof*/ I:1:163:3:DARKNESS },/*of the Magi*/ I:1:163:3:KNOWLEDGE },/*of the Magi*/ I:1:163:3:MANA },/*of the Magi*/ I:1:166:4:MAGIC },/*of Preservation*/ I:1:166:4:MANA },/*of Preservation*/ I:1:167:12:MANA },/*of Serenity*/ I:1:168:4:DARKNESS },/*of Night and Day*/ I:1:168:4:LITE },/*of Night and Day*/ I:1:169:1:TIME },/*of the Magi*/ I:1:169:8:KNOWLEDGE },/*of the Magi*/ I:1:170:4:DARKNESS },/*of Invisibility*/ I:1:171:8:DARKNESS },/*of the Bat*/ I:1:171:8:TELEPORT },/*of the Bat*/ I:1:172:4:LIGHTNING },/*of Thievery*/ I:1:173:4:FORCE },/*of Combat*/ I:1:174:4:TELEPORT },/*of Stability*/ I:1:175:4:ACID },/*of Elvenkind*/ I:1:175:4:COLD },/*of Elvenkind*/ I:1:175:4:FIRE },/*of Elvenkind*/ I:1:175:4:LIGHTNING },/*of Elvenkind*/ I:1:176:1:MAGIC },/*of Fury*/ I:1:176:4:CHAOS },/*of Fury*/ I:1:176:4:EXPLOSION },/*of Fury*/ I:1:176:4:MANA },/*of Fury*/ I:1:178:8:FORCE },/*Magical*/ I:1:179:4:KNOWLEDGE },/*Simplicity of */ I:1:180:1:FIRE },/*of Warmth*/ I:1:185:12:LIFE },/*of Life*/ I:1:185:2:MAGIC },/*of Life*/ tome-235-src/lib/edit/ba_info.txt0000644000076400017500000000647411012107760014527 0ustar dgdg# File: ba_info.txt # This file is used to initialize the "lib/raw/ba_info.raw" file, which is # used to initialize the "store/building actions type" information for # the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # N:: # C::: # I::: # Restriction: # 0 = No restrictions # 1 = Restrict to normal & liked # 2 = Restrict to liked # Version stamp (required) V:2.0.0 N:0:Nothing C:0:0:0 I:0:0:. N:1:Sell an item C:0:0:0 I:43:0:s:d N:2:Purchase an item C:0:0:0 I:44:0:p:g N:3:Examine an item C:0:0:0 I:45:0:x N:4:Steal an item C:0:0:0 I:46:0:Z N:5:Rest for the night C:25:20:15 I:17:0:r N:6:Buy food and drink C:3:2:1 I:18:0:f N:7:Listen for rumours C:0:0:0 I:19:0:u N:8:Presage fate C:600:500:480 I:42:0:l N:9:In-Between C:0:0:0 I:12:0:b N:10:Play craps C:0:0:0 I:14:0:c N:11:Spin the wheel C:0:0:0 I:15:0:s N:12:Play dice slots C:0:0:0 I:16:0:d N:13:Game rules C:0:0:0 I:13:0:r N:14:Research item C:1400:1300:1200 I:1:0:a N:15:Town history C:0:0:0 I:2:0:h N:16:Race legends C:0:0:0 I:3:0:l N:17:Look at busts of Kings C:0:0:0 I:5:0:l N:18:Research monster C:1600:1500:1400 I:20:0:r N:19:View bounties C:0:0:0 I:38:0:v N:20:Receive bounty money C:0:0:0 I:39:0:b N:21:Get quest monster C:0:0:0 I:54:0:q N:22:Turn in quest corpse C:0:0:0 I:55:0:m N:23:Compare weapons C:220:200:180 I:21:0:c N:24:Enchant weapon C:750:700:150 I:23:0:w N:25:Enchant armour C:750:700:150 I:24:0:a N:26:Recharge item C:350:300:75 I:25:0:r N:27:Identify possessions C:900:800:100 I:26:0:i N:28:Healing prayer C:600:400:0 I:28:0:h N:29:Restoration C:600:500:100 I:29:0:r N:30:Get share of stolen gold C:0:0:0 I:7:2:g N:31:Enchant arrows C:550:500:100 I:30:0:a N:32:Enchant bow C:550:500:100 I:31:0:b N:33:Recall to dungeon C:300:200:100 I:33:0:r N:34:Teleport to dungeon-level C:15000:10000:1000 I:34:0:t N:35:Get a quest C:0:0:0 I:6:0:q # Restrict to liked/normal N:36:Get a quest C:0:0:0 I:46:1:q N:37:Get a quest C:0:0:0 I:47:0:q N:38:Get a quest C:0:0:0 I:49:0:q N:39:Herbal Healing C:32000:10000:0 I:50:0:h N:40:Song of Lore C:2000:800:50 I:26:0:s N:41:Distribute earnings C:0:0:0 I:7:2:d N:42:Morph restoration C:3000:1500:750 I:37:0:r #for The Mirror N:43:View fate C:500:500:500 I:42:0:v #for The Mirror N:44:Research item C:1500:1500:1500 I:1:0:a #for library in gondol N:45:Research item C:2000:2000:2000 I:1:0:a #for Star-Dome N:46:Identify possessions C:1200:1000:250 I:26:0:i #for Star-Dome N:47:Recharge item C:1200:1000:150 I:25:0:r #for Valarin Temple N:48:Restoration C:1200:1000:200 I:29:0:r #for Sea-Dome N:49:Morph restoration C:1500:1500:1500 I:37:0:r #for The Golden Flower N:50:Enchant arrows C:1100:1000:200 I:30:0:a #for The Golden Flower N:51:Enchant bow C:1100:1000:200 I:31:0:b #for The Fountain N:52:Enchant armour C:1100:1000:200 I:24:0:a #for The Fountain N:53:See Healers C:1100:1000:0 I:28:0:h N:54:Drop an item C:0:0:0 I:43:0:d:s N:55:Get an item C:0:0:0 I:44:0:g:p N:56:Request an item C:0:0:0 I:51:2:r N:57:Ask for loan C:0:0:0 I:52:2:a N:58:Pay back loan C:0:0:0 I:53:2:p N:59:Donate an item C:0:0:0 I:43:0:d # Mage Tower quest in Lothlorien N:60:Get a quest C:0:0:0 I:56:0:q N:61:Get a quest C:0:0:0 I:61:0:q tome-235-src/lib/edit/t_d_gond.txt0000644000076400017500000003335211012107760014702 0ustar dgdg# File: t_d_gond.txt # Destroyed Gondolin: Your failure has left the city in ruins. # Created by Mynstral (mynstral@thehelm.com) # Extra terrain features that aren't commonly used # Dead/burnt tree F:D:92:3 # Ash F:A:93:3 # Fire F:F:205:3 # Permanent rubble F:R:206:3 # Tainted water F:w:174:3 # Decoration = Straight Road (B) F:":66:3 # Decoration = Straight Road (W) F:$:70:3 # Town Layout D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:######################################^^^^^^^^^^^^R #### D:####################################^^^^^^^^^^^R #### D:##################################^^^^^^^ R R R ### D:#################################^^^^^^^^R C C R CCR CC CC C CCRC CR R ### D:################################^^^R^^^^^^^ C RCRCR#R######R#R#####R#####CCR CCR R R ### D:###############################^^^^^^^^^^^^ CRRR C# ###### DD D ####RDRD D D ###R###CC C R ^^^^^ ### D:##############################^^^^^^R^^^R C R####R##RD DDD R.R## R.DD DDD#RR#####C R R^^^^^^^ R ### D:#############################^^^^^^^^^^ # R##########D R######### .D##########R R ^^^^^^^^^^^^ ### D:############################^^RR^^ R ############ ..R###########R ..D############C R ^^^^^^^^^^^^^^R ### D:############################ C #############DR .###ww#####ww### .D#############CR ^^^^^^^^^^^^^ ### D:########################### RR R #############DD .#wwww#R###wwRw# R.RR############# R ^^^^^^^^^^^ ### D:########################### R . R RR C#R###########DR .ww###R###ww .DR############C R R ^^^^^^^ R R ### D:########################## R ##### RR R #### R R C######wwww### ..w## R##R ..D####wwww#####CR ####### # R ^^^^ ### D:########################## R #R##### R ##R## ####### C#R####D DDww#DR # .R# DRRwD DD######C R## ##R#RR ### D:####R#################R#w# ### ###R ### R ####### ###### DDw#R D#wDD D####R ##R#### ### D:####wR#w###R#R#####R#Rwww# R####R### #R##R ####### R######D R RR..R######R ### D:#####wR##w#w##R##wRwww#w## #####R### # ### #########R ######D R .. DD DD ..RRD######CR R ### D:#####RwRwRwww##RwRwww#RR## R######R# R ##R R##R#### RR R RC#######Rw ..DD D####### DD ..ww#R##### C # R ### D:######w##ww#ww#wwwww#R#### . R R R# R# #######R## D ##### R###### DD ########## R ## ## ### R RR ### D:######www#wwwRwRwRwwRw#### .. R CR####### .. D###### R# # ##### .. ########R #R#######R###R#### ### D:#######RwwwwRwwwRwwR#ww### R #####D DD .. D###R.R#R# #R## .###D ..DDDR#####CR R #### # #######R ### D:########RwwRwwRwwwR#w###### # ###### R R## #####R C# D ..D## ..## RR ..# R .. D DD# R RR#R#######R## ### D:#########R#wwwwRww########## #R#R####R ############ R#D R .R#R ## R ..R R.. ..## D R# # ..D#C R R ###R### R## ### D:##########R#################### # ####### ############ R #D R R####R D## R# R ..# @ @ ## .#R##R R RD# ## #R#R#R## @ @ ### D:#### R#################### ####R# ##R #####R####### RC#D # #R R. D## @@@ @ .##D ..R## R .D #RC #### R @@@@@@ ### D:#### ####RRRC##w#LL#""## #######R ## R##R#R ## C### R ###R . D ### R @w@@..###D D .#### ###R @ @ @@@@wwww@@@ ### D:#### R####R##RC# R#LL#""# # . R R ###D R##R D###.### .#####w@ @###.## R###R R### R @@ @@wwwwwww@ ### D:##### ################### . R C### ## #R D## ..##.R##wRww#..## ..# D ## R D###C @@@@wwwwwwwww@ ### D:# R#### D# .#..#ww#Rw#..# .#D R## .. @wwwwwwwwwwww@@ ### D:#.. ..#w#w#w# R @wwwwwwwwwwww@ @ ### D:# .##R# D# .#.R#ww#wR#..# .#D ####R .. @@wwwwwwwwwww@@ @ R ### D:############ ########## # . . . R###D ..#R###R ## ..##..##www##..## ..## #R # R R##C @wwwwwwwwww@@@@ ^^### D:#### #### K# C# #LL# "# R . R . . ### ##R# DD###.### .##### R###.###D R### . D#R# @@@wwwwwww@@@@@@ R ^^### D:#### ### K CC ww# L# "## ##### # R ## #### # # #### CR##D .. DD### ..###DD .###R DD####RC @@wwwww@@ @ @ ^^^^### D:#### ####KK#CC#ww#L # "### ## ###### ###R ###R# R# ##### R#DD D## R .##D ..R# # D #####CR @@wwww@ R R^^^^^^### D:######## ###################### ######### R####R#R### # ## R# CRD ..D## R#R .RR ## .#R##R .D##### R DD @@@@@@@ ^^^^^^^### D:####### #####R$R$#R#### #### ### ###R# R ## ########R# # # # ww ww .DD## R R.##RR ## RR## D #R# R###### DD DD DD DD DD ^^^^^^^^^### D:########$R$$R#R$RR$##### ## R##R###### ##R# ### R### R## R CRR..ww# R #Rw D####.#########R#R####D ..######C D DD DDD D D DD DDD ^^^^^^^^^### D:######$$R#$R$$#$#$##$#$### R C D..w#R .###w . DD#################D D .DR#####R DD DDD########DDD DDDD ^^^^^^^### D:#######R#$##$$$#$#$$R$#### C#D .w###.R# R D D### #########DD D #R###R DDD###DD D D### D DD R ^^^^^^### D:######R$R$$$#$#R#$R$$R$$# R R RR RC##D.w##R # Rw ..D D ####### D D ### DDD##DD D ##DDDDDD ^^^^### D:#####$$$$#$$R#$$$$$R$$R### ###### # RR### R###RR RC#D.ww#####ww R RR DD#C DD#DD D DD## D DD R ^^^^### D:#####R$$#$$R#####$R$$$R### ## ####R R #R## ##### ##R R ..ww###wwR ..D DR RDDDR R R .DD R R D DR R. DR R D ##D DDD ^^^^### D:####R$$###R########R#R$$$# ###R#####R ## ####### # C wwwRw .DDR######R#RDRD RDDD#R###R#R#DDD RR R R D#DD D DD##D ^^^^^^### D:###R$#################R### # ## ## # ###########R# CRDD .DD###wwwwww####R . R#R##wwwwww### D .DD#C R DDD##DDD D D##DD D ^^^^^^^### D:#######################R## R#### #R ############# R# .D##www .wRw###DDD###www .www#RDR .D#R DDDD D D D###DD D R ^^^^^^^### D:########################### R # R R CR# .D#ww ..ww#######ww R.ww#D D#R DD D DD# ## ## DDD DD ^^^^^### D:########################### R R# C#D R ..####### R ..DD#R DD D DDD DDD DD D ^^^^### D:############################ ##R #R R#D ..D#ww R R..ww#######wR R ..ww#D .. DR# R DDDD DD D D R R ^^^^^^### D:############################ ######### C ##DD .D##www .www#########www R.www##D . R## DDD D DD D ^^^^^^^^^### D:############################# #####R# R#D DD DD ##wwwwww## #### #####wwwwww###D DD D##RC ^^^^^^^^^^^^### D:############################## R ###R #### DD DDD ##### # ######R # ########DDDD RDRD ###RC R ^^^^^^^^^^^^^^### D:############################### ### RR CR R#R#R##DDD RDR DD##############D DRRD D D## #R#CCRR R^^^^^^^^^^^^^^^^^### D:################################ R # CC R ##R# #R#####R###R#R#R#####R###R###RCRC CR R ^^^^^^^^^^^^^^^^^### D:################################# R R R # R CRCR CCCRCC CRRCRCCC C R #C C CR RC C R ^^^^^^^^^^^^^^^^^^#### D:################################## #### R R R # R ^^^^^^^^^^^^^^^^^^^^^#### D:#################################### R ##### R ^^^^^^^^^^^^^^^^^^^###### D:###################################### #### ######## R ^^^^^^^^^^^^^^^^^^######## D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### # Default starting position ?:[EQU $LEAVING_QUEST 0] P:33:50 # Starting position when coming from quest 19 ?:[EQU $LEAVING_QUEST 19] P:51:190 # Starting position when coming from quest 20 ?:[EQU $LEAVING_QUEST 20] P:33:13 # Starting position when coming from quest 21 ?:[EQU $LEAVING_QUEST 21] P:27:168 # Starting position when coming from quest 22 ?:[EQU $LEAVING_QUEST 22] P:6:42 tome-235-src/lib/edit/wights.map0000644000076400017500000000251511012107760014365 0ustar dgdg# Permanent wall F:X:63:3 # up stairs F:<:6:3 # Floor with mountain F:^:97:3 # Floor F:.:1:3 # Floor with dirt F:;:88:3 # Floor with forest wight F:f:88:3:381 # Floor with grave wight F:g:88:3:470 # Floor with barrow wight F:b:88:3:499 # Floor with Emperor Wight F:e:88:3:604 # Floor with a Human Skeleton F:k:88:8:0:395 # Marker F:,:172:6 # between gate 1 F:1:160:6:0:0:0:0:0:2057 # between gate 2 F:2:160:6:0:0:0:0:0:1036 # between gate 3 F:3:160:6:0:0:0:0:0:3847 # between gate 4 F:4:160:6:0:0:0:0:0:2321 # between gate 5 F:5:160:6:0:0:0:0:0:1043 # between gate 6 F:6:160:6:0:0:0:0:0:3599 # between gate 7 F:7:160:6:0:0:0:0:0:2071 # between gate 8 F:8:160:6:0:0:0:0:0:3350 # between gate 9 F:9:160:6:0:0:0:0:0:771 # Dungeon layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X..k^^^^^^^^^^^^^^^^^^^^^^^XX D:Xfkff^^^^^...^^^^..ff^^^^^^XX D:X^f1^^^^^^.ffg^^^^.fgg^^^^^XX D:X^^^^^^^^^^^fg4^^^^f6^^^^^^XX D:X^^^^^^^^^^^^f^^^^^^^^^fg8^XX D:X^^^^^^.f^^^^^^^^^^^^.ffg^^XX D:X^^^^.ff2^^^^^^.^^^^^^.f^^^XX D:X^^^^^3.^^^^^^^.^^^^^^^^^^^XX D:X^^^^^^^^^^^^ff.^^^^^^^^^^^XX D:X^^^^^^^^^^^7gfg^^^^^^^^f^^XX D:X^^^^^^^^^^^^^^^^^^^..^..^^XX D:X^^^^^^^^^^^^.^^^^^^....ff^XX D:X^^^^...^^^^^ff^^^^^^..fg^^XX D:X^^^.fff^^^^gfg^^^^...fgee^^X D:X^^^^g5^^^^..8^^^^^f^fgfe,9^X D:X^^^^^^^^^^^^^^^^^^^^^^^^^^^X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Starting position P:3:3 tome-235-src/lib/edit/t_d_lori.txt0000644000076400017500000003270611012107760014722 0ustar dgdg# Town Name: Lothlorien (destroyed) # # original town by Akhronath (zzhou22876@aol.com) # destruction by fearoffours (fearoffours@moppy.co.uk) # # Created for ToME # Dead/burnt tree F:D:92:3 # Ash F:A:93:3 # Fire F:F:205:3 # Permanent rubble F:R:206:3 # Town Layout D:###################################################################################################################################################################################################### D:#DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD .DDDDDDDDDDDDDD,DDDD,DDDDDDDDDDDDDD ,,DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDDDDDD ,DDDDDDDD DDDDAAA# D:#DDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD .DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDD , # D:#DDDDAADDDDDDDD ,DDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDAAADDDDD.DDDDD DD DDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAADDDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDD ,,DDDDDDDDDDD, .DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD,DDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, # D:#DDDDDDDDDDDDDDDDDD ,,DDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAADDDDDD.AAADDDDDDDDDDD ,DDDDDDDDDDDDDD ,,DDDDDDDAAA,DDDDDDDDDDDDDD,DDDDDDDDDDDDDD , ,DDDDDDDDDDDDDD,DDDD# D:#DDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDD,DDDDDDDDDDDDDDDDDDDDDDDD ,DDDD ,DDDDDDDDDDDDDDDDDD ,DDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDD,DDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDAADDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDD DDDDDDDDDDDDDDDDDDD ,DDDDDDAADDDDDDDDDD # D:#DDDDDDDDDD DDDDDDDDDDDDDDDDDDDDAADDDDDDDDDDDDDDDDDDDDDAAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA,DDDDDDDDDDDDDD ,DDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DDDDDDDDDDDDDD ,,DDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDDDDDDFDDDDDDDDDDDDDD ,DDDD ,DDDD,,DDDDDDDDD DDDDDDDDDDDDDDDD ,DDDDDDDDDDAADDDDDDDDDDDDDDDAAA,DDDDDDDDDDDDDD ,DDDDDDD # D:#DDDDDDDAAA,DDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD AADDDDDDDDDDDDDD AAAAFDDDDDDD ,DDDDDDDDDDDDDDDDDDDDAAA,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDD ADDDDDDDDDDDDDDDDDDDDDDDDDDDAAA,DDDDDDDDDDDDDD FDDDD FFDDDD ,DDDDDDDDDDDDDD,DDDD,DDDDDDDDDDDDDD ,,DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDDDDDD ,DDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDDDDDAAADDD ,DDDDDDDDDAAADDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDD AADDDDDDDDDDD FDDDD F F F ,DDDDDDDDDDDDDDDDDDDDDDDDDDDAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD , # D:#DDDD DDDDDDDDD ,DDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD AADDDDDDDAA ADDDDDDDADDDDDDD## F,AAA##DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDDD DDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDAADDDDDDDDDDDDDD #### , # ##DDDDDDDDDDDDDDDDDDD DDAAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD , # D:#DDDDDDDDDDDDDD ,DDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDD AFDDDDDDD ADDDDDDD RDDDDDDD##DDDD FDDDD##R,,F,, ##DDDD ADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDDDD DDDDDDDDDDDDDDDDDD,DDDDDDADDDDDDDDDDDDDDDDD A ,DDDDDDDDDDDDDD## #DDDD#####, AADDDD## , , ###DDDD F ADDDDDDDDDDDDDDDDDDDDDDDD , DDAAA,DDDDDDDDDDDDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, # D:#DDDADDDDDDDDDDDDDD ,,DDDD ,DDDDDDDDDDDDDD AAAAADDDDDDDDDDDFFDDDDDDD A # #A# A ### #DDDDDDD ##AAA,AAAA#DDDD AAAAAADDDDDDDDDDDADD ,,DDDDDDDAAA,DDDDDDDDDDDDDD,DDDDDDDDDDDDDD , ,DDDDDDDDDDDDDD,DDDD# D:#DDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDA, A ,DDDDDDDDDDDDDDDDDDDDDDDD## ##AAA, #A##DDDD##AAAR#AAA,AAA##AAA, FAADDDDDDDDDDDDDDDDDDDDDDDDDDD AA ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDD,DDDDDDDDDDDDDDDDDD,AADDDDD AAAADDDDDDD###AADDDD FDDDDA,AAA#####DDDD##.##AAA####RR ## , ##DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDADDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDD # D:#DDDDDDDDDDDDDD ,,DDDD ,DDDDDDDDDDDDDD A ADDDD FFF##DDDDDDD # ## #DDDDA #DDDDDDD.DDDD ##########,,,, # #AAAF,,DDDDDDDDD DDDDDDDDDDDDDDDD ,DAADDDDDDDDDDDADDDDDDDDDDDDAAA,DDDDDDDDDDDDDD ,DDDDDDD # D:#DDDDDDDDD DDDDDDDDDDDDDDDD,DDDDDDD AA ADDDDDDD #### ,A R ####DDDD ,DDDDDDD , ,, ##F#####AAAA ####DDDDFDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, # D:#DD DDDDDDDDDDDDDD ,,DDDD ,DDDDDDDDDDD ADDDDDDDDDDD###R# # ######DDDDDDD,DDDDDDD ,DDDD #R#AAA#AAA,AAA##DDDD FAAA,DDDDDDDDDDDDDD ,,DDDDDDD A,DDDDDDDDDDDDDD,DDDDDDDDDDDDDD , ,DDDDDDDDDDDDDD,DDDD# D:#DDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDA,DDDD,DDDD #### ##A###F##DAADDDD, F , , AAAAF ,DDDDDDD ,AAA##AAA, F FDDDDDDD DDDDDDDDDDDD ADDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDD,DDDDDDDDDDDDDDDDDD,DDDDDDDAADDDDDDDDDDD ############,,,,AA,,,AAA,,AAA,DDDD F ,DDDD A , ###DDDDDDDDDDD ADDDDDDDDDDDDDDDDDDDD A ,DDDDDDDDDADDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDD # D:#DDDDDDDAAA,DDD DDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD##### #######DDDDDDD ,DDDD,,,,,,,,,,,A,,,F,,,,,,,,R###DDDDDDDDD AAAA ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDD ADDDDDDDDDDD ######## #####AAA,AAA,DDDDDDDDDDDDDD FDDDD AA , ###AAA,,DDDD, F ,ADDDDDDDDDDDDDD ,,DDDDDDDDDDDDDDDDDDDDAAAAA, ,DDDDDDDDDDD ,DDDDDDDDDDDDDDAAA# D:#DD DDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDAAADDDDFDDDD,## # RRAAA######DDDD ,DDDDDDDDDDDDDDDDDD FDDDD ,DDDD# ,DDDDRDDDDDDDDDDDAAADDDDDDDDDDDDDDDAADDDDDDDDDDDDDDDDDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD , # D:#DDDDDDDDDDDDDD ,DDDDDDDDDDDDDD,DDDDDDDDDDD FFAAA###DDDDDDD # R #DDDD ##DDDD A ## #AAA## A FF ,DDDD ,AAA### ###DDDDDDDDDDDDDDDDDDDDDDDDADDDDDDDDDDDDDDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDDDDDDD ,DDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDD #DDDDDDDDDDDDDD#,AAA#R###DDDD F ##DDDD####AAAA ,AAA,,,AAA##### ####DDDDDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDD # D:#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA## ## AAAA###DDDD #FAAAF,,,,,,,,DDDD ##########DDDDAADDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDD ,DDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DDDD DDDDDDDDD ,,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ### # AAA ,#DDDD ,DDDD ,F ,AAA, ,DDDD### ###DDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDADDDDAAA,DDDDDDDDDDDDDD ,DDDDDDD # D:#DDDDDDDAAA,DDDDDDDAAAAAADDDDDDDDDDDDDDDDDDDDDDDDDDD ADDDDDDDDDDDDDDDDDDDDDDDD A ,DDDD ,DDDD,, ,AAA,DDDD AA,DDDD### ## ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDDDD DDDDDDDDDAAAAAFDDDDDDDDDDDDDDDDDDDD ,,AA ,,,,,,,,,,,,, ,F, ,DDDDDDD, , , # ##DDDDDDDDDDD ,,DDDDDDDDDDDDDDDDDDDDAAADDD ,DDDDDDDDDDD ,DDDDDDDDDDDDDDAAA# D:#DDDD DDD DDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDD ,FDDDDDDDDDDDDDDDDDDDD AA , ,,A,DDDDDDDDDDD,AA,F,F,,,,,,,,,,,,,AA,,R###DDDDDDD AADDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDAADDDDDAADDDDDDDDDDDAAA, # D:#DDDDDDDDDDDDDD ,DDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDD AADDDDDDDDDDD AA A ADDDD,,DDDDDDDDDDD ADDDD ,,, FDDDDDDDAA A,DDDD# ##DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DDDDDDDDDDDDDDD DDDDDDDDDAA,DDDDDDDDDDDDDDDDDDDD AADDDD ,DDDD AAAAADDDD --,--AAAA,AADDDDDDDDDDD ,AAAVVV@DDDD F#,DDDD # #DDDDDDDDDDADDDAAA,DDDD ,DDDDDDAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, # D:#DDDDDDDDDDDDDDDDDD ,,DDDD ,DDDDDDDDDDDDDDDDDDDDDDDD F FDDDDDDDAAAF AAAA----,---- AADDDDDDDDDDD AA VWWWV@DDDD #R#DDDDDDDDDDDDDD ,,DDDDDDD DD,DDDDDDDDDDDDDD,DDDDDDDDDDDDDD , ,DDDDDDDDDDDDDD,DDDD# D:#DDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDD,DDDDDDDDDDD AAAAADADDDD ---VV,@@---ADDDDDDDDDDDDDD , @WWV@@ ,AAAF###DDDDDDDDDDDDDDDDDDDDDDDDDDD A ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDDDDDDDDD D ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDA AA A ---VVW,WV@---DDDDDDD A AAAA, V@VVDDDDDDD#F####DDDDF,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADADDDDDDD # D:#DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDDDDDDDDDDDDDDDDDDD FFAADDDDDDD A ,F---VWW@WV@---DDDDDDDDDDDAAAA,, @@DDDDDDDR###AAA,AAAFDDDDDDDDDDD ,,DDDDDDDDDDDDDDDDDDDDDDAAA, ,DDDDDDDAAADDD,DDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDFDDDDAADDDDADDDD---V@WWW@V---DDDDDDD ADDDDDDD,,ADDDDADDDD #DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DD DDDDDDDDDD ,,AAAD ,DDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDD AADDDDDDDAAA---V@VVV@--AAA,A,,,,,,,AA,,,, ,DDDDDDD,,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDAAA,DDDDDDDDDDDDDD ,DDDDDDD # D:#DDDDDDDDDAAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ------@@-DDDD,DDDDDDD ADDDD ,DDDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDD DDD ,DDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDD FDDDDDDD ---DDDDDDD,DDDDDDD ADDDD #R#DDDD FDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD , # D:#DDDDDDDDDDDDDD ,DDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ADDDD F FDDDDDDD ,DDDDADDDDDDD R##DDDDAAADDDD FAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DDDD DDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDAADDDDAADDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDAAA,AAA#F##DDDDDDDF AADDDDDDDAAADDDDDDDDDD ,DDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD , # D:#DDDDDDDDDDDDDDDDDD ,, AAAAADDDDDDDDDDDDDD AAAAAAADDDDDDDDDDDDDDDDDD AADDDDDDDDDDD #R#DDDD ADDDDDDD #DDDD AAA ,ADDDDDDDDDDDDDD ,,DDDDDDDAAA,DDDDDDDDDDDDDD,DDDDDDDDDDDDDD , ,DDDDDDDDDDDDDD,DDDD# D:#DDD ADA AA,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDD,DDDDDDDDDDDDDDDDDDADDDDDDD,DDDD ,DDDD ##R#DDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDD,DDDDDDDDDDDDDDAAAAADDDDDDDDDDDDDDAA AAAADDDDDDDDDDDAFAADDDDDDDAAAFDDDD####RAAAFDDDDDDD AADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDD # D:#DDDDDDDAADDDDDDDDDDDDDDDDDDDDDDDDDDAAADDDDDD AADDDDDDDDDDDDDD ADDDD FDDDDAA FDDDD#F#DDDD FDDDDDDD AADDDDDDDDDDDDDDDDDDDDDDDDDAAADDDDDDDDDD ,DDDDDDDDDDDDDD ,DDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DDDDDDDDDDDDDD ,, AA ,DDDDDDDDDDDDDDDDDDDD AADDDDDDDDDDDDDDDDDDDDDDDD FDDDDDDDDDDD #DDDDDDDDDDDDDD A ,DDDD,,DDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA,DDDDDDDDDDADDD ,DDDDDDD # D:#DDDDDDDAAA,DDDDDDDAAAAAAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAADDDD AADDDDDDDAADDDDDDDDDDDDDDDDDDDDDDDD AAADDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDDDDDDDDDDDDDDDDDAAAAA, ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDD AADDDDDDDDDDDDDDDDDDAADDDDDDDDDDD ,DDDD,DDDDDDDDDDDDDD ,,DDDDDDDDDDDDDDDDDDDDDDDD , ,DDDDDDDDDDD ,DDDDDDDDDDDDDDAAA# D:#DDDDDDDDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDD ADDDD ,,DDDDDDDDDDDAADDDDDDDDDDDDDDDDDDDDDDDAADDDDDDDDDDDDDDD ,AAAAAA,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, # D:#DDDDDDD DDDDDDDDDD ,, AAA,DAADDDDDDDDDDDDDDDDDDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDD ,,DDDDDDD A ,DDDDDDDDDDDDDD,DDDDDDDDDDDDDD , ,DDDDDDDDDDDDDD,DDDD# D:#DDDDDDAA A ,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,AAAAADDDDDDDD DDDDDDDDDDDDDD ,DDDD ,DDDDDDDDDDDDDAAADDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD AA,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDAAA# D:#DDDDDDD A ,DDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDDDDDDDDDDD # D:#DDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDDDDDDDDDDDDDADDDDDDDDDDDDDDDDDDDDAADDDDDDDDDDDDDDDD ,DDDDDDDD DDDDD ,DDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDD# D:#DDDDDDDDDDDDDD ,, AA ,DDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD , AAA,DDDDDDDDDDDDDDDDDAADDDDDDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDAAA,DDDDDDDDDDDAAAA ,DDDDDDD # D:#DDDDDDDDDDDDDDDDDDDDAA,DDDDDDDDDDDDDDDDDDDDAAAD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, # D:#DDDDDDDDDDDDDD ,DDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:#DDDDD DDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDDDDDDD DDDDDDDDDDDDDD ,,DDDDDDDDDDD,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ,DDDD ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD, # D:#DDDDDD D DDDDDDDD ,,AAA ,DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD,DDDDDDDDDDDDDD ,,DDDDDDDAAA,DDDDDDDDDDDDDD,DDDDDDDDDDDDDD , ,DDDDDDDDDDDDDD,DDDD# D:#DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD # D:###################################################################################################################################################################################################### # Default starting position ?:[EQU $LEAVING_QUES 0] P:13:99 # Starting position when coming from quest 12 ?:[EQU $LEAVING_QUES 12] P:26:109 # Starting position when coming from quest 13 ?:[EQU $LEAVING_QUES 13] P:7:99 tome-235-src/lib/edit/k_info.txt0000644000076400017500000037353711012107760014406 0ustar dgdg# File: k_info.txt # This file is used to initialize the "lib/data/k_info.raw" file, which is # used to initialize the "object kind" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/data/k_info.raw" file. # Available slots are marked with # XXX: 294, 299, 444-464, ... # XXX XXX Add some "IGNORE_XXX" flags to Rings, Amulets, etc. # The old "MULTI_HUED" objects are now "violet", and no other object # is violet, so all six violet objects can be made "multi-hued", though # this would be a heinous hack. XXX XXX # Note that object zero is used for the "stack" picture (unused). # Version stamp (required) V:2.0.0 ##### Something special ##### N:0:something G:&:w ##### Mushrooms ##### N:1:Blindness G:,:d I:80:1:500 W:5:0:1:0 A:5/1 D:'E'ating this mushrooms will blind you. You cannot cast magic D:or see monsters when you are blinded. You can still use magic items or D:quaff potions. N:2:Paranoia G:,:d I:80:2:500 W:5:0:1:0 A:5/1 D:'E'ating this mushroom will make you scared. D:You will not be able to hit your enemies in combat if you're scared. N:3:Confusion G:,:d I:80:3:500 W:5:0:1:0 A:5/1 D:'E'ating this mushroom will confuse you. You will not be able to cast spells, D:use wands, staves or scrolls. You can still quaff potions, though. N:4:Hallucination G:,:d I:80:4:500 W:10:0:1:0 A:10/1 D:'E'ating this mushroom will make you hallucinate. D:You will not be able to recognise any monster or item. N:5:Cure Poison G:,:d I:80:12:500 W:10:0:1:60 A:10/1 D:'E'ating this mushroom will cure you from poison. N:6:Cure Blindness G:,:d I:80:13:500 W:10:0:1:50 A:10/1 D:'E'ating this mushroom will cure you from blindness. N:7:Cure Paranoia G:,:d I:80:14:500 W:10:0:1:25 A:10/1 D:'E'ating this mushroom will cure your paranoia. Paranoia is the state when you are D:too afraid to attack monsters. N:8:Cure Confusion G:,:d I:80:15:500 W:10:0:1:50 A:10/1 D:'E'ating this mushroom will cure your confusion. Confusion is when you are too confused D:to cast spells, zap staves, aim wands or read scrolls. N:9:Weakness G:,:d I:80:6:500 W:10:0:1:0 A:10/1 P:0:5d5:0:0:0 D:'E'ating this mushroom will reduce your strength by one point. N:10:Unhealth G:,:d I:80:10:500 W:15:0:1:50 A:15/1 P:0:10d10:0:0:0 D:'E'ating this mushroom will reduce your constitution by one point. N:11:Restore Constitution G:,:d I:80:18:500 W:20:0:1:350 A:20/1 D:'E'ating this mushroom will restore your constitution. Your constitution D:needs restoring when it is displayed in yellow. N:12:Restoring G:,:d I:80:19:500 W:20:0:1:1000 A:20/8:30/4:40/1 D:'E'ating this mushroom will restore your strength, dexterity, constitution, D:intelligence, wisdom and charisma. These need restoring when they D:are displayed in yellow. N:13:Stupidity G:,:d I:80:8:500 W:15:0:1:0 A:15/1 D:'E'ating this mushroom will reduce your intelligence by one point. D:That's a bad thing. N:14:Naivety G:,:d I:80:9:500 W:15:0:1:0 A:15/1 D:'E'ating this mushroom will reduce your wisdom by one point. D:That's a bad thing. N:15:Poison G:,:d I:80:0:500 W:5:0:1:0 A:5/1:5/1 P:0:4d4:0:0:0 D:'E'ating this mushroom will poison you. Poisoning makes you lose one hitpoint D:per turn until you magically stop the poison or until your body has D:fought off the poison. D:That's a bad thing. N:16:Sickness G:,:d I:80:7:500 W:10:0:1:0 A:10/1 P:0:4d4:0:0:0 D:'E'ating this mushroom will reduce your constitution by one point. D:It will also damage you quite severely in the process. D:That's a bad thing. N:17:Paralysis G:,:d I:80:5:500 W:20:0:1:0 A:20/1 D:'E'ating this mushroom will paralyse you for a certain time. D:Any nearby monsters will take this opportunity to kill you. D:That's a bad thing. N:18:Restore Strength G:,:d I:80:17:500 W:20:0:1:350 A:20/1 D:'E'ating this mushroom will restore your strength. Your strength D:needs restoring when it is displayed in yellow. N:19:Disease G:,:d I:80:11:500 W:20:0:1:50 A:20/1 P:0:10d10:0:0:0 D:'E'ating this mushroom will reduce your strength by one point. D:It will also damage you quite severely in the process. D:That's a bad thing. N:20:Cure Serious Wounds G:,:d I:80:16:500 W:15:0:1:75 A:15/1 D:'E'ating this mushroom will heal several hit points. Your hit points D:need healing when they are displayed in yellow or red. ##### Normal Food ##### N:21:& Ration~ of Food G:,:U I:80:35:5000 W:0:0:10:3 A:0/1:5/1:10/1 D:Lightweight and filling. Not an incredible taste experience, but that'd be asking a bit much. D:You can 'E'at it. N:22:& Hard Biscuit~ G:,:U I:80:32:500 W:0:0:2:1 D:It doesn't look great, and 'E'ating it will only fill your stomach a bit, D:for a short time. N:23:& Strip~ of Venison G:,:u I:80:33:1500 W:0:0:2:2 D:It looks great, and 'E'ating it will fill your stomach well. N:24:& Slime Mold~ G:,:g I:80:36:3000 W:1:0:5:2 A:1/1 D:It looks disgusting, but if you really want to you can 'E'at it. D:Not an incredible taste experience, but that'd be asking a bit much. # New - now Lembas works as a scroll of Satisfy Hunger N:25:& Lembas~ G:,:B I:80:37:0 W:5:0:3:10 A:5/1:10/1:20/1 D:A sort of cake, tasty and sustaining. It even helps to overcome weariness. Its fabrication D:is a secret of the elves. If you 'E'at it, you will be full. N:26:& Pint~ of Fine Ale G:,:y I:80:38:500 W:0:0:5:1 D:A bottle of a dark beer-like beverage. You can drink it by pressing 'E'. N:27:& Pint~ of Fine Wine G:,:r I:80:39:1000 W:0:0:10:2 D:A bottle of fine wine. You can drink it by pressing 'E'. ##### Extra digger ##### N:28:& Mattock~ G:\:D I:20:7:3 W:50:0:250:700 A:50/2 P:0:1d8:0:0:0 F:TUNNEL f:TUNNEL D:This is a digging tool. Use it to dig in walls, destroy doors, or cut wood. # The Blue Stone 'Toris Mejistos' -- see artifact list N:29:& Blue Stone~ G:":B I:40:18:0 W:60:0:3:90000 F:INSTA_ART | SPECIAL_GENE ##### Edged Weapons ##### N:30:& Broken Dagger~ G:|:D I:23:1:0 W:0:0:5:1 A:0/2:5/2 P:0:1d1:-2:-4:0 F:SHOW_MODS D:The blade itself is a foot long and broken off not far above the hilt. N:31:& Bastard Sword~ G:|:W I:23:21:0 W:15:0:140:350 A:15/1 P:0:3d4:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:This is a long, double-edged sword with a plain hilt that could D:be wielded in one or two hands. It's called a "bastard sword" because in D:size, it falls between the broad sword and the two-handed sword, thus not D:having a family of its own. It's typically around 51 inches long. D:It is effective for cutting through tougher armours. It could be used for D:thrusting, but most wielders swing it like a bat. N:32:& Scimitar~ G:|:W I:23:18:0 W:10:0:130:250 A:10/1 P:0:2d5:0:0:0 F:SHOW_MODS D:This oriental blade has 2 edges and is deeply curved. It has a wide D:and very sharp end. It is the forefather of the sabre. N:33:& Tulwar~ G:|:W I:23:15:0 W:5:0:100:200 A:5/1 P:0:2d4:0:0:0 F:SHOW_MODS D:This vicious sword is half sword and half club, with a slight hook on the tip. N:34:& Broad Sword~ G:|:W I:23:16:0 W:10:0:150:255 A:10/1:15/1 P:0:2d5:0:0:0 F:SHOW_MODS D:This broader version of the long sword is a standard weapon in the army D:of Gondolin. N:35:& Short Sword~ G:|:W I:23:10:0 W:5:0:80:90 A:5/1 P:0:1d7:0:0:0 F:SHOW_MODS D:This shorter version of the long sword is a common weapon for rogues D:and mages. N:36:& Blade~ of Chaos G:|:v I:23:30:0 W:70:0:180:4000 A:70/8 P:0:6d5:0:0:0 F:ATTR_MULTI F:RES_CHAOS | CHAOTIC | SHOW_MODS f:RES_CHAOS | CHAOTIC D:A mighty sword which seems to be completely blunt. However, it is a conduit D:into the realms of pure chaos and strikes its victims with the devastating D:might of chaos itself whenever it connects. It gives you resistance to chaos D:and it can polymorph, teleport, confuse or drain hit points from the monster D:you hit. It occasionally causes earthquakes as well. N:37:& Two-Handed Sword~ G:|:W I:23:25:0 W:30:0:200:775 A:30/1:40/1 P:0:3d6:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This blade is lot longer, wider and heavier than a long sword. You have to D:wield it with two hands. This means that wielding a shield makes fighting D:very difficult. N:38:& Main Gauche~ G:|:W I:23:5:0 W:3:0:30:25 A:3/1 P:0:1d5:0:0:0 F:SHOW_MODS D:This blade is sinuously curved and tipped with a harpoon-like end. D:This blade has a large handguard and was designed as an off-hand weapon. D:This short but cruel blade is a favourite among orcs. N:39:& Cutlass~ G:|:W I:23:12:0 W:5:0:110:85 A:5/1 P:0:1d7:0:0:0 F:SHOW_MODS D:This oriental weapon is a short, thick, curving sword D:with a single cutting edge. This simple slashing weapon D:is typically carried by buccaneers, pirates, and sailors. N:40:& Executioner's Sword~ G:|:r I:23:28:0 W:40:0:260:850 A:40/1 P:0:4d5:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:These weapons have been built in all sizes. They are custom-made D:for warriors that want to set out and kill their archenemy. These D:blades are rare, costly and very deadly. N:41:& Katana~ G:|:W I:23:20:0 W:20:0:120:400 A:20/1 P:0:3d4:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:The katana is a long blade with only a small disk for a guard. D:Its hilt is long enough for two hands, though it could be used D:with only one hand, and is usually wrapped in cloth or leather. D:The art of forging such swords is largely unknown in this part D:of Middle-earth, and such weapons are typically imported from D:distant lands. N:42:& Long Sword~ G:|:W I:23:17:0 W:10:0:130:300 A:10/1:20/1 P:0:2d5:0:0:0 F:SHOW_MODS D:A long straight sword, tapering to a pronounced point. Mainly good for D:piercing attacks, but it can be used for slashing, too. It is a very D:popular design and has become standard issue in many armies. N:43:& Dagger~ G:|:W I:23:4:0 W:0:0:12:10 A:0/1:5/1:10/1:20/1 P:0:1d4:0:0:0 F:SHOW_MODS D:It's the standard weapon of rogues and thieves. The blade is D:a foot long. N:44:& Rapier~ G:|:W I:23:7:0 W:5:0:40:42 A:5/1 P:0:1d6:0:0:0 F:SHOW_MODS D:The rapier's hilt consisted of a pair of oval guards pierced with holes, D:recurved quillions, and a knuckle guard. The guard is very intricate D:and very effective as protection. N:45:& Sabre~ G:|:W I:23:11:0 W:5:0:50:50 A:5/1 P:0:1d7:0:0:0 F:SHOW_MODS D:A long, one-edged, slightly curved sword with a knuckle guard and short D:hilt. It is two-edged in its lower part. N:46:& Small Sword~ G:|:W I:23:8:0 W:5:0:75:48 A:5/1 P:0:1d6:0:0:0 F:SHOW_MODS D:It's the favourite weapon of strong mages and thieves. The blade is D:about twenty inches long. It's very easy to handle, although it is a lot less D:efficient than the longer and heavier designs. N:47:& Broken Sword~ G:|:D I:23:2:0 W:0:0:30:2 A:0/2:5/2 P:0:1d2:-2:-4:0 F:SHOW_MODS D:Just a hilt and a few inches of blade, broken off in a jagged stump. D:Probably worthless. ##### Hafted Weapons ##### N:48:& Ball-and-Chain~ G:\:D I:21:6:0 W:20:0:150:200 A:20/1 P:0:2d4:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:This weapon has a ball linked with a chain to a wooden handle. D:Preferred tactic is smashing the brains of your opponent. N:49:& Whip~ G:\:D I:21:2:0 W:3:0:30:30 A:3/1 P:0:1d6:0:0:0 F:SHOW_MODS D:Think Doctor Jones. This weapon is light and easy to fight with. D:It has nasty barbs and hooks fixed to the thong to make it useful D:in combat. Whips give easily multiple attacks. N:50:& Flail~ G:\:D I:21:13:0 W:10:0:150:353 A:10/1 P:0:2d6:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:This weapon was originally used to cut corn. More warlike versions D:sport a large blade stuck on a wooden handle. The hinge allows it to get D:past enemy defences or to strike with added momentum when used skillfully. N:51:& Two-Handed Flail~ G:\:y I:21:18:0 W:45:0:280:590 A:45/1 P:0:3d6:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This two-handed version of the flail gives the fighter a fearsome D:weapon that can do a fair amount of damage. It typically has several D:spiked metal lumps on chains. N:52:& Morning Star~ G:\:D I:21:12:0 W:10:0:150:396 A:10/1 P:0:2d6:0:0:0 F:SHOW_MODS D:This weapon consists of a large club with chains that have wooden balls D:with metal spikes on the end. N:53:& Mace~ G:\:D I:21:5:0 W:5:0:120:130 A:5/1 P:0:2d4:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:This weapon is a club ending in a sphere. The sphere is studded D:with metal shards, and thus can both crush and cut your adversary. N:54:& Quarterstaff~ G:\:U I:21:3:0 W:10:0:150:200 A:10/1 P:0:1d9:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A long, wooden pole, usually the height of the wielder. Four of them can be D:made out of the trunk of one young tree, hence the name. The quarterstaff D:is an excellent weapon for travellers as it doubles both as a walking staff D:and as a deterrent against brigands. The quarterstaff is used more in D:fencing and brawling than melee combat. N:55:& War Hammer~ G:\:D8 I:21:8:0 W:5:0:120:225 A:5/1 P:0:3d3:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A large hammer, designed to crush skulls with mighty strikes. N:56:& Lead-Filled Mace~ G:\:D I:21:15:0 W:15:0:180:502 A:15/1 P:0:3d4:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A large, mean mace filled with lead in order to wreak a maximum of havoc. N:57:& Mace~ of Disruption G:\:v I:21:20:0 W:80:0:400:4300 A:80/5 P:0:5d8:0:0:0 F:SLAY_UNDEAD | SHOW_MODS | MUST2H f:MUST2H | SLAY_UNDEAD D:This mace is custom-made for priests that go out to destroy evil. D:It is deadly, especially for undead. N:58:& Lucerne Hammer~ G:\:B I:21:10:0 W:10:0:120:376 A:10/1 P:0:2d5:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A war hammer combined with a spearpoint, mounted on a long pole. ##### Polearms ##### N:59:& Beaked Axe~ G:/:s I:22:10:0 W:15:0:180:408 A:15/1 P:0:2d6:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This polearm has a beak mounted opposite the blade. N:60:& Glaive~ G:/:s I:22:13:0 W:20:0:190:363 A:20/1 P:0:2d6:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A polearm with a long, slightly curved knife-like blade. It has spurs on D:the dull side of the blade. It's primarily a slashing and chopping weapon. Glaives D:are often used to protect archers, crossbowmen, and gunners while they reload. D:Outside of combat they are a popular processional weapon and therefore many D:have ornately carved blades. N:61:& Halberd~ G:/:s I:22:15:0 W:25:0:190:430 A:25/1 P:0:3d5:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:The halberd has a broad, short axe blade on a 5 - 6ft long haft, with a D:spearpoint at the top, often a back-spike and occasionally a butt-spike. Used to D:combat heavier armour. It's usually used for cutting and stabbing. It's the most D:versatile polearm in Middle-earth. The axe is used in general melee. The top D:pike is used to pierce armour, or is set against a cavalry charge. The back D:hook could unseat horses, trip opponents, parry a blow, or be a general D:piercing weapon. N:62:& Awl-Pike~ G:/:s I:22:4:0 W:10:0:160:340 A:10/1 P:0:1d8:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:This is a polearm with a long square-sectioned spike on the end. N:63:& Pike~ G:/:s I:22:8:0 W:15:0:160:358 A:15/1 P:0:2d5:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A staff, 16-18 feet long, that has a small piercing head about 10 inches D:long. The pike is often used by infantry to fend off cavalry. It is very D:effective against mounted troops. N:64:& Spear~ G:/:s I:22:2:0 W:5:0:50:36 A:5/1 P:0:1d6:0:0:0 F:SHOW_MODS D:Spears tend to have a strong, wide, leaf-shaped head with a ridge down the D:middle. The spearhead is attached to the wooden shaft by a socket. The D:sockets are usually riveted to the shaft and some have two small lugs near D:the base of the socket to allow the head to be possibly bound on as well. D:This spear is 7 feet long. N:65:& Trident~ G:/:y I:22:5:0 W:5:0:70:120 A:5/1 P:0:1d8:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:The trident is based on the pitchfork. In fact, when not used as a weapon, D:it is often employed as a pitchfork. It is famous for its uses in D:gladiatorial arenas. It is used much like a spear and could even be thrown D:like one in desperate situations. N:66:& Lance~ G:/:s I:22:20:0 W:10:0:300:230 A:10/1 P:0:2d8:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This is the original polearm. It is shaped like a spear but is bigger. It's D:meant to fend off enemies, not to be thrown. N:67:& Great Axe~ G:/:s I:24:25:0 W:40:0:230:500 A:40/1 P:0:4d4:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:A huge and heavy two-headed axe. N:68:& Battle Axe~ G:/:s I:22:22:0 W:15:0:170:334 A:15/1 P:0:2d8:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:Nordic polearm with a broad blade and a hook mounted on the end of the shaft. D:The Nordics' take on the halberd. The polearm of choice for many Nordics, D:ideally suited for slashing, thrusting, and unseating cavalry. N:69:& Lochaber Axe~ G:/:D I:22:28:0 W:45:0:250:750 A:45/1 P:0:3d8:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:Nordic polearm with a broad blade and a hook mounted on the end of the shaft. D:A Nordic version of the halberd. The polearm of choice for many Nordics, D:this weapon is ideally suited for slashing, thrusting, and unseating cavalry. N:70:& Broad Axe~ G:/:s I:24:11:0 W:15:0:160:304 A:15/1 P:0:2d6:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A one-headed axe made for combat, with an elongated moon-shaped blade. N:71:& Scythe~ G:/:s I:22:17:0 W:45:0:250:800 A:45/1 P:0:5d3:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:A simple farm implement, converted into a weapon by slightly straightening D:its blade and putting it in line with its pole, instead of the typical D:right angle. N:72:& Scythe~ of Slicing G:/:r I:22:30:0 W:80:0:250:10000 A:80/20 P:0:8d4:0:0:0 F:SHOW_MODS | MUST2H | WOUNDING | VORPAL f:MUST2H | VORPAL | WOUNDING D:The simple design of the war scythe, but this one uses a finely crafted and D:incredibly sharp steel blade which causes terrible wounds when it hits. ##### Bows, Crossbows, Slings ##### N:73:& Short Bow~ G:}:U I:19:12:0 W:3:0:30:50 A:3/1:50/2 F:SHOW_MODS D:A piece of bent wood, fitted with a string. Easy to transport and use, but D:its effect is not very impressive. You can 'f'ire it after you 'w'ield it. N:74:& Long Bow~ G:}:U I:19:13:0 W:10:0:40:120 A:10/1:70/2 F:SHOW_MODS D:A bow almost as long as a human. It takes considerable strength and skill to D:use and is rather awkward to carry around inside buildings. Nevertheless, it D:shoots arrows with astonishing force. You can 'f'ire it after you 'w'ield it. N:75:& Light Crossbow~ G:}:s I:19:23:0 W:15:0:110:140 A:15/1:60/2 F:SHOW_MODS D:A metal bow mounted on a wooden stock. It is used for shooting bolts. This D:design is relatively light and not too difficult to cock, but also shoots its D:quarrels with less force. You can 'f'ire with it after you 'w'ield it. N:76:& Heavy Crossbow~ G:}:s I:19:24:0 W:30:0:200:300 A:30/1:80/2 F:SHOW_MODS D:A metal bow mounted on a wooden stock, with attached cocking mechanism. It D:takes considerable time and strength to cock it and it's rather heavy. D:However, it hurls its ammunition with incredible force. You can 'f'ire with D:it after you 'w'ield it. N:77:& Sling~ G:}:u I:19:2:0 W:1:0:5:5 A:1/1:40/2 F:SHOW_MODS D:A simple cloth or leather pouch with two strings attached. It is used to hurl D:pebbles or iron shots. You can 'f'ire with it after you 'w'ield it. ##### Missiles ##### N:78:& Arrow~ G:{:U I:17:1:0 W:3:0:2:1 A:3/1:15/1:50/1 P:0:1d4:0:0:0 F:SHOW_MODS D:A simple metal head on a piece of wood or bamboo, fitted with some feathers. D:You can use it for 'f'iring a bow. N:79:& Seeker Arrow~ G:{:G I:17:2:0 W:55:0:2:20 A:55/2:80/2 P:0:4d4:0:0:0 F:SHOW_MODS D:A precision-made arrow, which allows you to hit precisely the most vulnerable D:place of an opponent. You can use it for 'f'iring a bow. N:80:& Bolt~ G:{:s I:18:1:0 W:3:0:3:2 A:3/1:25/1:60/1 P:0:1d5:0:0:0 F:SHOW_MODS D:A short metal arrow, to be 'f'ired with a crossbow. N:81:& Seeker Bolt~ G:{:B I:18:2:0 W:65:0:3:25 A:65/2:90/2 P:0:4d5:0:0:0 F:SHOW_MODS D:A precision-made bolt, which allows you to hit exactly the most vulnerable D:place of an opponent. You can use it for 'f'iring a crossbow. N:82:& Rounded Pebble~ G:{:s I:16:0:0 W:0:0:4:1 A:0/1:10/2 P:0:1d2:0:0:0 F:SHOW_MODS D:Small round stones. When fired with a sling, they could even hurt a giant. D:You can use them for 'f'iring a sling. N:83:& Iron Shot~ G:{:s I:16:1:0 W:3:0:5:2 A:3/1:40/2 P:0:1d4:0:0:0 F:SHOW_MODS D:Metal balls, made for shooting with slings. You can use them for 'f'iring a D:sling. ##### Shovels and Picks ##### N:84:& Shovel~ G:\:s I:20:1:1 W:1:0:60:10 A:5/2 P:0:1d2:0:0:0 F:TUNNEL f:TUNNEL D:A simple digging tool for shovelling away rubble and maybe even soft rock. N:85:& Gnomish Shovel~ G:\:G I:20:2:2 W:20:0:60:100 A:20/3 P:0:1d2:0:0:0 F:TUNNEL f:TUNNEL D:Crafted by the gnomes, its design profits greatly from the gnomes' expertise D:honed in the burrowing of their hovels. N:86:& Dwarven Shovel~ G:\:B I:20:3:3 W:40:0:120:200 A:40/4 P:0:1d3:0:0:0 F:TUNNEL f:TUNNEL D:The lighter digging tool used by dwarves to remove debris, but also good D:enough to clear away bits of rock when no pick is easily available. N:87:& Pick~ G:\:s I:20:4:1 W:5:0:150:50 A:10/2 P:0:1d3:0:0:0 F:TUNNEL f:TUNNEL D:A heavy digging tool, primarily for earthworking, but also good for tunnelling D:through stone, if one is willing to perform the time-consuming labour. N:88:& Orcish Pick~ G:\:g I:20:5:2 W:30:0:180:300 A:30/3 P:0:1d3:0:0:0 F:TUNNEL f:TUNNEL D:Although orcs tend to dig rather untidy mines and overcome difficulties in D:this work less by skill than mere stubbornness, they have amassed D:quite some expertise in mining, which has gone into this digging tool. N:89:& Dwarven Pick~ G:\:b I:20:6:3 W:50:0:200:600 A:50/4 P:0:1d4:0:0:0 F:TUNNEL f:TUNNEL D:The dwarves, miners of legend, have made this pick, which is so expertly D:crafted that even weaklings can bore through solid rock with it. ##### Armour ##### N:90:& Elven Cloak~ G:(:G I:35:2:0 W:30:0:5:1500 A:30/4 P:4:0d0:0:0:4 F:IGNORE_ACID | IGNORE_COLD | IGNORE_FIRE | IGNORE_ELEC F:STEALTH | SEARCH | LUCK f:STEALTH D:A wonderfully light cloak coloured in brown and green hues. Its colouring D:greatly helps the wearer to avoid undesired attention. Wearing it makes you D:feel lucky and somehow you seem to see what was meant to stay unseen. N:91:& Pair~ of Soft Leather Boots G:]:U I:30:2:0 W:3:0:20:7 A:3/1 P:2:1d1:0:0:0 D:A pair of low boots, comfortable to wear. N:92:& Pair~ of Hard Leather Boots G:]:U I:30:3:0 W:5:0:40:12 A:5/1 P:3:1d1:0:0:0 D:A pair of boots, with hardened leather at the caps, offering a little D:extra protection for the feet. N:93:& Pair~ of Metal Shod Boots G:]:s I:30:6:0 W:20:0:80:50 A:20/1 P:6:1d1:0:0:0 D:Heavy boots, with metal strips at the toes, heels and other vulnerable parts, D:to better protect the wearer's feet from harm. N:94:& Hard Leather Cap~ G:]:u I:32:2:0 W:3:0:15:12 A:3/1 P:2:0d0:0:0:0 D:A piece of protective headgear made from hardened leather, just covering the D:skull. N:95:& Metal Cap~ G:]:s I:32:3:0 W:10:0:20:30 A:10/1 P:3:1d1:0:0:0 D:A metal skullcap with nose and cheekguards. N:96:& Iron Helm~ G:]:s I:32:5:0 W:20:0:75:75 A:20/1 P:5:1d3:0:0:0 D:A large helmet that can protect the entire head. Ventilation and bad vision D:can be a problem, however. N:97:& Steel Helm~ G:]:W I:32:6:0 W:40:0:60:200 A:40/1 P:6:1d3:0:0:0 D:A helmet which protects the entire head. The expensive steel as base material D:allows it to offer very good protection while being fairly light. N:98:& Iron Crown~ G:]:s I:33:10:0 W:45:0:20:500 A:45/1 P:0:1d1:0:0:0 D:An iron circlet which might be worn, but which is purely ornamental unless it D:has special powers. N:99:& Golden Crown~ G:]:y I:33:11:0 W:45:0:30:1000 A:45/1 P:0:1d1:0:0:0 F:IGNORE_ACID D:A gilded crown, which just looks good. Sometimes such headgear also has D:additional properties which might make it worth wearing. N:100:& Jewel Encrusted Crown~ G:]:v I:33:12:0 W:50:0:40:2000 A:50/1 P:0:1d1:0:0:0 F:IGNORE_ACID D:A gorgeous-looking silver crown, adorned with several gems. You might wear it D:on your head, if you really think you're worthy. N:101:& Robe~ G:(:b I:36:2:0 W:1:0:20:4 A:1/1:50/1 P:2:0d0:0:0:0 D:A full-length garment which can be worn on the body. It is not really D:armour, but mages often wear them as they are very light and don't hinder D:movement much. N:102:& Filthy Rag~ G:(:D I:36:1:0 W:0:0:20:1 A:0/1 P:1:0d0:0:0:-1 D:A piece of discarded cloth, smelly and dirty. Eurgh. You're not going to D:wear this, are you? N:103:& Soft Leather Armour~ G:(:U I:36:4:0 W:3:0:80:18 A:3/1 P:4:0d0:0:0:0 D:A leather jerkin, light and unencumbering, but not very protective. N:104:& Soft Studded Leather~ G:(:U I:36:5:0 W:3:0:90:35 A:3/1 P:5:1d1:0:0:0 D:A leather jerkin with metal studs in critical places offering slightly better D:protection. N:105:& Hard Leather Armour~ G:(:U I:36:6:0 W:5:0:100:150 A:5/1 P:6:1d1:-1:0:0 D:A leather armour covering only the body. It is made of hardened leather to D:make it harder to penetrate. It's also a bit harder to move in, as it is D:rather stiff. N:106:& Hard Studded Leather~ G:(:U I:36:7:0 W:10:0:110:200 A:10/1 P:7:1d2:-1:0:0 D:A suit of hardened leather armour, reinforced with metal studs. N:107:& Leather Scale Mail~ G:(:U I:36:11:0 W:15:0:140:450 A:15/1 P:11:1d1:-1:0:0 D:A suit of armour made of overlapping hardened leather scales. It offers good D:protection while still being rather lightweight. N:108:& Metal Scale Mail~ G:[:s I:37:3:0 W:25:0:250:550 A:25/1 P:13:1d4:-2:0:0 D:A suit of overlapping metal scales, sewn onto a leather or cloth jerkin. N:109:& Chain Mail~ G:[:s I:37:4:0 W:25:0:220:750 A:25/1 P:14:1d4:-2:0:0 D:A suit of interlinked metal rings, to be worn over a woollen garment. N:110:& Rusty Chain Mail~ G:[:r I:37:1:0 W:25:0:200:550 A:25/1 P:14:1d4:-5:0:-8 D:This chain mail has rusted beyond repair. It can still be worn, but some of D:the rings have gone missing and the rust has made the suit inflexible. D:Consequently, it offers very poor protection and is cumbersome to move in. N:111:& Augmented Chain Mail~ G:[:s I:37:6:0 W:30:0:270:900 A:30/1 P:16:1d4:-2:0:0 D:A suit of interlinked metal rings, with additional metal plates or scales D:covering vulnerable parts of the wearer. N:112:& Bar Chain Mail~ G:[:s I:37:8:0 W:35:0:280:950 A:35/1 P:18:1d4:-2:0:0 D:A suit of interlinked metal rings, with additional short metal bars added in D:many places to prevent penetration of the armour by piercing attacks. N:113:& Metal Brigandine Armour~ G:[:s I:37:9:0 W:35:0:290:1100 A:35/1 P:19:1d4:-3:0:0 D:This is a leather armour with many small metal plates fixed to it, covering D:it entirely. N:114:& Partial Plate Armour~ G:[:W I:37:12:0 W:45:0:260:1200 A:45/1 P:22:1d6:-3:0:0 D:An armour made of steel plates, covering only the body of the wearer. N:115:& Metal Lamellar Armour~ G:[:W I:37:13:0 W:45:0:340:1250 A:45/1 P:23:1d6:-3:0:0 D:Lamellar consists of small rectangular plates (lames) attached to each other D:at each edge or corner with leather lacings through small holes in the plates. N:116:& Full Plate Armour~ G:[:W I:37:15:0 W:45:0:380:1350 A:45/1 P:25:2d4:-3:0:0 D:A suit of armour made of metal plates, covering the body, arms and upper legs. D:A very effective but very heavy armour. N:117:& Ribbed Plate Armour~ G:[:W I:37:18:0 W:50:0:380:1500 A:50/1 P:28:2d4:-3:0:0 D:This full suit of armour has been strengthened in places to better deflect or D:absorb blows. N:118:& Adamantite Plate Mail~ G:[:G I:37:30:0 W:75:0:420:20000 A:75/4 P:40:2d4:-4:0:0 F:IGNORE_ACID D:A suit of plate armour fashioned from an unbreakable crystal by mage-smiths. N:119:& Mithril Plate Mail~ G:[:B I:37:25:0 W:60:0:300:15000 A:60/3 P:35:2d4:-3:0:0 F:IGNORE_ACID D:A full suit of plate armour, fashioned from the rare true-silver. Only the D:dwarves know the secret of making armour or weapons of this metal. N:120:& Mithril Chain Mail~ G:[:B I:37:20:0 W:55:0:150:7000 A:55/3 P:28:1d4:-1:0:0 F:IGNORE_ACID D:A suit of chain mail, made by dwarven smiths from the rare and precious metal D:also called true-silver. N:121:& Double Chain Mail~ G:[:s I:37:7:0 W:30:0:250:850 A:30/1 P:16:1d4:-2:0:0 D:A suit of chain mail, with an additional layer of mail in some places. # This shield does not belong here N:122:& Shield~ of Deflection G:[:B I:34:10:0 W:70:0:100:10000 A:70/3 P:10:1d1:0:0:10 F:IGNORE_ACID D:A large shield fashioned from a metal alloy that is not subject to corrosion. D:It was especially crafted to better deflect attacks. ### The Cloaks ### N:123:& Cloak~ G:(:g I:35:1:0 W:1:0:10:3 A:1/1:20/1 P:1:0d0:0:0:0 D:A cloth coat typically worn as a loose outer garment. It is spacious enough D:to be worn even over bulky metal armour. N:124:& Shadow Cloak~ G:(:D I:35:6:1 W:60:0:5:7500 A:75/4 P:6:0d0:0:0:4 F:RES_DARK | RES_LITE | STEALTH f:STEALTH D:A rare cloak imbued with magic to radiate a strange twilight, absorbing both D:extreme brightness and darkness. ### The Gloves ### N:125:& Set~ of Leather Gloves G:]:U I:31:1:0 W:1:0:5:3 A:1/1 P:1:0d0:0:0:0 D:Light gloves which do not seriously hinder finger movements, while still D:protecting the hands somewhat. N:126:& Set~ of Gauntlets G:]:U I:31:2:0 W:10:0:25:35 A:10/1 P:2:1d1:0:0:0 D:Metal gloves protecting the hands up to the middle of the lower arm. N:127:& Set~ of Cesti G:]:W I:31:5:0 W:50:0:40:100 A:50/1 P:5:1d1:0:0:0 D:A set of metal gloves with nasty spikes and barbs. Though originally made to D:help in combat, the additional metal on the backs of the hands also offers a D:lot more protection. ### The shields ### N:128:& Small Leather Shield~ G:):U I:34:2:0 W:3:0:50:30 A:3/1 P:2:1d1:0:0:0 D:A small disc of lindenwood, with a leather covering on one side. N:129:& Large Leather Shield~ G:):U I:34:4:0 W:15:0:100:120 A:15/1 P:4:1d2:0:0:0 D:A large oval or rectangular shield. It is made of wood, typically linden, and D:covered with a layer of hardened leather to offer better protection. N:130:& Small Metal Shield~ G:):s I:34:3:0 W:10:0:65:50 A:10/1 P:3:1d2:0:0:0 D:A small shield strengthened with a layer of metal. N:131:& Large Metal Shield~ G:):s I:34:5:0 W:30:0:120:200 A:30/1 P:5:1d3:0:0:0 D:A large piece of wood, rectangular or oval in shape, and covered with metal D:to strengthen it. It's to be worn strapped to the arm not occupied by the D:weapon when fighting. ##### Rings ##### N:132:Strength G:=:d I:45:24:0 W:30:0:2:500 A:30/1 F:STR | HIDE_TYPE f:STR D:This bauble magically improves your strength. N:133:Dexterity G:=:d I:45:26:0 W:30:0:2:500 A:30/1 F:DEX | HIDE_TYPE f:DEX D:This piece of jewellery magically improves your agility. N:134:Constitution G:=:d I:45:27:0 W:30:0:2:500 A:30/1 F:CON | HIDE_TYPE f:CON D:This ring magically grants you health, improving your constitution. N:135:Intelligence G:=:d I:45:25:0 W:30:0:2:500 A:30/1 F:INT | HIDE_TYPE f:INT D:This magical piece of jewellery makes you smarter. N:136:Speed G:=:d I:45:31:0 W:75:0:2:100000 A:75/1 F:SPEED | HIDE_TYPE f:SPEED D:This wonderful ring grants you additional energy, allowing you to act faster. N:137:Searching G:=:d I:45:23:0 W:5:0:2:250 A:5/1 F:SEARCH | HIDE_TYPE f:SEARCH D:This ring magically improves your attention, so you can detect hidden things better. # New : It can be activated but at the cost of its destruction N:138:Teleportation G:=:d I:45:4:0 W:5:0:2:250 A:5/1 a:HARDCORE=DEST_TELE F:CURSED | TELEPORT | EASY_KNOW | ACTIVATE f:TELEPORT D:This ring will uncontrollably send you to different places at its whim. D:You can use its power once at your will, but it will destroy the ring. N:139:Slow Digestion G:=:d I:45:6:0 W:5:0:2:250 A:5/1 F:SLOW_DIGEST | EASY_KNOW f:SLOW_DIGEST D:This magical bauble grants you some sustenance, allowing you to subsist on less food. N:140:Fire Resistance G:=:d I:45:8:0 W:10:0:2:250 A:10/1 F:RES_FIRE | IGNORE_FIRE | EASY_KNOW f:RES_FIRE D:This piece of jewellery grants you some protection from the burning heat of fire. N:141:Cold Resistance G:=:d I:45:9:0 W:10:0:2:250 A:10/1 F:RES_COLD | IGNORE_COLD | EASY_KNOW f:RES_COLD D:This piece of jewellery grants you some protection from the chilling forces of cold. N:142:Levitation G:=:d I:45:7:0 W:5:0:2:200 A:5/1 F:FEATHER | EASY_KNOW f:FEATHER D:When you put on this ring, you will be able to float just above the floor. D:It prevents you from drowning, and all your falls will be painless. N:143:Poison Resistance G:=:d I:45:20:0 W:60:0:2:16000 A:60/2 F:RES_POIS | EASY_KNOW f:RES_POIS D:This magical ring grants protection from poison. D:It is rumoured that in deep dungeons monsters can kill you at once if you D:don't have poison resistance. N:144:Free Action G:=:d I:45:21:0 W:20:0:2:1500 A:20/1 F:FREE_ACT | EASY_KNOW f:FREE_ACT D:This magical bauble prevents you from being held. D:Some monsters will paralyse you and then kill you if you lack free action. N:145:Weakness G:=:d I:45:2:-5 W:5:0:2:0 A:5/1 F:CURSED | STR | HIDE_TYPE f:STR D:This accursed ring will sap your strength, rendering you much weaker as long as you wear it. N:146:Flames G:=:d I:45:18:0 W:50:0:2:3000 A:50/1 P:0:0d0:0:0:15 a:HARDCORE=BA_FIRE_4 F:RES_FIRE | IGNORE_FIRE | ACTIVATE f:RES_FIRE D:This fiery circlet grants you protection, makes fire less dangerous and even D:allows you to call forth a ball of flame. N:147:Acid G:=:d I:45:17:0 W:50:0:2:3000 A:50/1 P:0:0d0:0:0:15 a:HARDCORE=BA_ACID_4 F:RES_ACID | IGNORE_ACID | ACTIVATE f:RES_ACID D:This magical ring is imbued with spells of devouring acid, granting protection against such D:assaults and the ability to shoot acid at your foes. N:148:Ice G:=:d I:45:19:0 W:50:0:2:3000 A:50/1 a:HARDCORE=BA_COLD_4 P:0:0d0:0:0:15 F:RES_COLD | IGNORE_COLD | ACTIVATE f:RES_COLD D:This ring is imbued with supernatural cold, which makes you less vulnerable to such effects D:and occasionally allows you to throw balls of ice at your foes. N:149:Woe G:=:d I:45:0:-5 W:50:0:2:0 A:50/1 F:CURSED | TELEPORT | WIS | CHR | HIDE_TYPE | AUTO_CURSE D:This accursed ring will turn you into a bumbling fool and, in addition, magically D:transports you to places you never wanted to see. It can recurse itself if D:you leave it on too long. N:150:Stupidity G:=:d I:45:3:-5 W:5:0:2:0 A:5/1 F:CURSED | INT | HIDE_TYPE f:INT D:This wicked ring feeds off your intellect, magically making you stupid. N:151:Damage G:=:d I:45:29:0 W:20:0:2:500 A:20/1 F:HIDE_TYPE D:This ring makes your hands magically strong in combat, allowing you to inflict D:greater pain with your hand-to-hand attacks. N:152:Accuracy G:=:d I:45:28:0 W:20:0:2:500 A:20/1 F:HIDE_TYPE D:This ring magically improves your control in combat, allowing you to hit more often. N:153:Protection G:=:d I:45:16:0 W:10:0:2:500 A:10/1 D:This ring creates a magical aura around you, protecting you against the blows of your enemies. N:154:Aggravate Monster G:=:d I:45:1:0 W:5:0:2:0 A:5/1 F:CURSED | AGGRAVATE | EASY_KNOW | AUTO_CURSE f:AGGRAVATE D:This faithless ring will draw opponents' attention towards its hapless owner. N:155:See Invisible G:=:d I:45:22:0 W:30:0:2:340 A:30/1 F:SEE_INVIS | EASY_KNOW f:SEE_INVIS D:This magical piece of jewellery allows your eyes to perceive beings otherwise unseen. N:156:Sustain Strength G:=:d I:45:10:0 W:20:0:2:400 A:20/1 F:SUST_STR | EASY_KNOW f:SUST_STR D:This magical bauble protects your physical force against attacks attempting to drain it. N:157:Sustain Intelligence G:=:d I:45:11:0 W:20:0:2:400 A:20/1 F:SUST_INT | EASY_KNOW f:SUST_INT D:This magical ring protects your intellect against attempts to lower it. N:158:Sustain Wisdom G:=:d I:45:12:0 W:20:0:2:400 A:20/1 F:SUST_WIS | EASY_KNOW f:SUST_WIS D:This magical ring protects you from attempts to make you more foolish. N:159:Sustain Constitution G:=:d I:45:13:0 W:20:0:2:400 A:20/1 F:SUST_CON | EASY_KNOW f:SUST_CON D:This magical ring protects your health, making it impossible for your opponents to lower it. N:160:Sustain Dexterity G:=:d I:45:14:0 W:20:0:2:400 A:20/1 F:SUST_DEX | EASY_KNOW f:SUST_DEX D:This magical ring protects your nerves, so that you will never become clumsy. N:161:Sustain Charisma G:=:d I:45:15:0 W:20:0:2:400 A:20/1 F:SUST_CHR | EASY_KNOW f:SUST_CHR D:This ring magically protects your beauty and charm from attempts to make you ugly. N:162:Slaying G:=:d I:45:30:0 W:40:0:2:1000 A:40/1 F:SHOW_MODS D:This ring magically improves your fighting prowess, allowing to hit more often and harder. ##### Amulets ##### N:163:Brilliance G:":d I:40:6:0 W:50:0:3:1000 A:50/4 F:INT | WIS | HIDE_TYPE | LITE1 D:This talisman grants a sharper wit, greater insight and brightness to light dark places. N:164:Charisma G:":d I:40:7:0 W:30:0:3:500 A:30/1 F:CHR | HIDE_TYPE f:CHR D:This amulet grants beauty beyond mere looks. N:165:Searching G:":d I:40:5:0 W:15:0:3:600 A:15/1 F:SEARCH | HIDE_TYPE f:SEARCH D:This amulet grants keen sight, finding things that are hidden. N:166:Teleportation G:":d I:40:1:0 W:10:0:3:250 A:10/1 F:CURSED | TELEPORT | EASY_KNOW f:TELEPORT D:This amulet nastily throws you all over the place. N:167:Slow Digestion G:":d I:40:3:0 W:15:0:3:200 A:15/1 F:SLOW_DIGEST | EASY_KNOW f:SLOW_DIGEST D:This talisman will make you hungry less quickly when worn. N:168:Acid Resistance G:":d I:40:4:0 W:10:0:3:250 A:10/1 F:RES_ACID | IGNORE_ACID | EASY_KNOW f:RES_ACID D:This magical talisman will make the corroding forces of acid less threatening to your health. N:169:Adornment G:":d I:40:2:0 W:10:0:3:20 A:10/1 F:EASY_KNOW D:This amulet is not magical. It just looks good. ##### Extra armour ##### N:170:& Double Ring Mail~ G:[:s I:37:5:0 W:25:0:230:700 A:25/1 P:15:1d4:-2:0:0 D:A suit of leather armour with metal rings sewn onto it. In addition, in important parts it is D:reinforced with mail. ##### Additional amulets ##### N:171:the Magi G:":d I:40:8:0 W:70:0:3:30000 A:70/8 P:0:0d0:-4:-4:0 F:INT | SUST_INT | SEARCH | SPELL_CONTAIN | WIELD_CAST F:FREE_ACT | RES_BLIND | RES_CONF | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This rare amulet is highly desirable for mages, as it makes its wearer smarter, more attentive D:and impervious to magics which would make their own magic-use impossible. N:172:Doom G:":d I:40:0:-5 W:50:0:3:0 A:50/1 F:CURSED | STR | INT | WIS | DEX | CON | CHR | HIDE_TYPE F:AUTO_CURSE | CURSE_NO_DROP D:This wicked amulet will drain all your abilities, turning you into a mere shadow of yourself. It D:is exceedingly hard to get rid of. ##### Scrolls ##### N:173:Enchant Weapon To-Hit G:?:d I:70:17:0 W:15:0:5:125 A:15/1 D:This magical scroll will allow you to improve the accuracy of a weapon in your possession. D:However, weapons which are already very highly enchanted are more difficult to improve D:further. N:174:Enchant Weapon To-Dam G:?:d I:70:18:0 W:15:0:5:125 A:15/1 D:Upon reading this scroll, a magical enchantment will be placed on a weapon in your D:possession, increasing the pain it inflicts when hitting. On very highly enchanted weapons this D:enchantment may fail, wasting the scroll. N:175:Enchant Armour G:?:d I:70:16:0 W:15:0:5:125 A:15/1 D:This scroll will try to enchant a piece of armour in your possession, making it more effective D:in protecting you. Highly enchanted armour is likely not to accept this enchantment, however. N:176:Identify G:?:d I:70:12:0 W:1:0:5:50 A:1/1:5/1:10/1:30/1 D:If you read this scroll, the identity of an item you specify will be laid open to you. N:177:*Identify* G:?:d I:70:13:0 W:30:0:5:1000 A:30/1:50/2:80/1:100/1 D:This scroll will allow you to gain insight into an object's special properties. D:Only the highly magical objects, like rare rings and amulets or very unusual weapons D:and armour possess abilities which warrant the use of this magic. N:178:Rumour G:?:d I:70:51:0 W:1:0:5:10 A:1/1 D:A piece of paper inscribed with a little text. You may meditate over it or ignore it at your D:leisure. N:179:Chaos G:?:d I:70:50:0 W:100:0:5:10000 A:100/8 F:IGNORE_FIRE | IGNORE_ACID | IGNORE_COLD | IGNORE_ELEC D:A piece of paper inscribed with strange shifting runes. Upon reading them, they will release D:a blast of chaotic forces. N:180:Remove Curse G:?:d I:70:14:0 W:10:0:5:100 A:10/1:20/2:40/2 D:A scroll inscribed with a beneficial formula. Upon reading it, evil magics will be removed D:from your possessions. N:181:Light G:?:d I:70:24:0 W:0:0:5:15 A:0/1:3/1:10/1 D:A scroll which will create a permanent magical light, illuminating the surroundings. N:182:Fire G:?:d I:70:48:0 W:50:0:5:1000 A:50/4 F:IGNORE_FIRE D:A piece of paper inscribed with runes glowing brightly red. Upon reading them, a large blast D:of fire will be released. N:183:Ice G:?:d I:70:49:0 W:75:0:5:5000 A:75/6 F:IGNORE_COLD D:A piece of paper inscribed with light-blue runes that radiate a strange cold. Upon reading them, D:a large icy blast will be released. N:184:Summon Monsters G:?:d I:70:4:0 W:1:0:5:0 A:1/1 D:This scroll was made by mischievous sorcerers. If it is read, a few creatures will appear to fight D:you. N:185:Phase Door G:?:d I:70:8:0 W:1:0:5:15 A:1/1 D:Upon reading this scroll, you will be translocated over a short distance. N:186:Teleportation G:?:d I:70:9:0 W:10:0:5:40 A:10/1 D:If you read this scroll, you will immediately be transported to another place on the level. N:187:Teleport Level G:?:d I:70:10:0 W:20:0:5:50 A:20/1 D:This scroll will magically transport you to the level directly above or below, when read. N:188:Monster Confusion G:?:d I:70:36:0 W:5:0:5:30 A:5/1 D:Reading this scroll will cause your hands to glow with a strange mesmerising light that will D:attempt to confuse the next creature you hit with a hand or weapon attack. N:189:Magic Mapping G:?:d I:70:25:0 W:5:0:5:40 A:5/1 D:Reading this scroll will reveal the layout of your immediate surroundings to you. N:190:Rune of Protection G:?:d I:70:38:0 W:50:0:5:500 A:50/2:90/4 D:This scroll is inscribed with a powerful protective incantation. When read, this will erect a D:strong magical ward around the location you currently stand on. Be aware that this magic is D:easily disturbed by already present structures and thus cannot work where an object is lying, or D:on a trap. N:191:*Remove Curse* G:?:d I:70:15:0 W:50:0:5:8000 A:50/2:75/2:85/2:95/1 D:This valuable scroll is inscribed with a powerful blessing capable of dispelling all but the D:mightiest curses which may have been laid on your possessions. N:192:Treasure Detection G:?:d I:70:26:0 W:0:0:5:15 A:0/1 D:This scroll magically reveals the locations of nearby loose change to you. N:193:Object Detection G:?:d I:70:27:0 W:0:0:5:15 A:0/1 D:This scroll shows nearby objects to you. It only makes you aware of items on the floor, D:however, not those carried by creatures. N:194:Trap Detection G:?:d I:70:28:0 W:5:0:5:35 A:5/1:10/1 D:This scroll is very helpful, because it reveals the locations of nearby snares and traps which you D:might otherwise blunder into. ##### Extra ammunition ##### N:195:& Sheaf Arrow~ G:{:o I:17:1:0 W:10:0:4:3 A:15/2:50/2 P:0:1d5:0:0:0 F:SHOW_MODS D:These arrows have bigger arrowheads and bigger feathers. D:They also make bigger holes. N:196:& Mithril Shot~ G:{:B I:16:2:0 W:40:0:4:20 A:40/2:65/1 P:0:3d4:5:5:0 F:SHOW_MODS | IGNORE_ACID D:Sling bullets made from the slags of mithril smelting. They are unusually heavy, hitting D:with great force, and are almost imperishable. ##### Additional scrolls ##### N:197:Door/Stair Location G:?:d I:70:29:0 W:5:0:5:35 A:5/1:10/1:15/1 D:This scroll will reveal nearby passages. N:198:Acquirement G:?:d I:70:46:0 W:20:0:5:100000 A:20/8 D:A great treasure is magically stored within the shimmering runes of this scroll. Reading the D:words will release it. N:199:*Acquirement* G:?:d I:70:47:0 W:60:0:5:200000 A:60/16 D:Several great treasures have been hidden in a magical compartment. This scroll serves as the D:key and will release them when read. N:200:Mass Genocide G:?:d I:70:45:0 W:50:0:5:1000 A:50/4:100/4 D:An astoundingly powerful death spell is stored in the runes of this spell. Reading D:it will annihilate all nearby creatures. Only a few beings of legendary stature D:can withstand it. N:201:Detect Invisible G:?:d I:70:30:0 W:1:0:5:15 A:1/1 D:A minor detection spell is stored in this scroll, showing you the locations of otherwise D:unseen beings for a brief moment. N:202:Aggravate Monster G:?:d I:70:1:0 W:5:0:5:0 A:5/1 D:This nasty scroll will make a loud noise, waking up foes in your vicinity. N:203:Trap Creation G:?:d I:70:7:0 W:10:0:5:0 A:10/1 D:If you read this rather annoying scroll, snares and pitfalls will magically be planted all around D:you, ready to do nasty things to you once you walk onto them. N:204:Trap/Door Destruction G:?:d I:70:39:0 W:10:0:5:50 A:10/1 D:A very specifically destructive spell is written on this scroll. It will smash all traps and all D:doors immediately next to you. N:205:Artifact Creation G:?:d I:70:52:0 W:70:0:5:200000 A:70/16 D:The mighty magic on this scroll will imbue a mundane item you possess with supernatural powers, D:also rendering the object indestructible. N:206:Recharging G:?:d I:70:22:0 W:40:0:5:200 A:40/1 D:This scroll is inscribed with a spell releasing the enchantments used to give wands and D:staves their power, allowing you to replenish their spent charges. N:207:Genocide G:?:d I:70:44:0 W:40:0:5:750 A:40/4:80/4 D:This rare and powerful scroll will annihilate all members of a specified race of monsters in D:your current location, but this will also exact a price of pain from you. N:208:Darkness G:?:d I:70:0:0 W:1:0:5:0 A:1/1 D:This scroll will create a blast of utter darkness, which then fades to leave the immediate D:surroundings in a lasting gloom. The extreme darkness can blind those who are not used to D:it. N:209:Protection from Evil G:?:d I:70:37:0 W:30:0:5:250 A:30/1 D:Upon reading the runes on this piece of paper, a faint aura of holiness will spring into existence D:around you, protecting you from blows of evil creatures, unless they are more powerful than you. N:210:Satisfy Hunger G:?:d I:70:32:0 W:5:0:5:10 A:5/1:20/1:50/1:75/1 D:Reading this scroll will transport a good portion of nourishing gruel directly into your D:stomach. Some people say that this is a ploy of a food producer whose food nobody wants to eat. N:211:Dispel Undead G:?:d I:70:42:0 W:40:0:5:200 A:40/1 D:A powerful exorcism is inscribed on this scroll. When read it will hurt undead abominations D:nearby, possibly even destroying them. N:212:*Enchant Weapon* G:?:d I:70:21:0 W:50:0:5:500 A:50/1 D:Reading this scroll will magically infuse a weapon of your choice, making it more effective D:in combat. N:213:Curse Weapon G:?:d I:70:3:0 W:50:0:5:0 A:50/1 D:This scroll will ruin your weapon beyond repair. Only weapons of legend have a hope of D:escaping destruction, but even they will often be shattered. N:214:*Enchant Armour* G:?:d I:70:20:0 W:50:0:5:500 A:50/1:50/1 D:This scroll will place a great enchantment on a piece of armour of your choice, making it much D:better at protecting you. Mark that improving armours which are already highly enchanted is very D:difficult and will often fail. N:215:Curse Armour G:?:d I:70:2:0 W:50:0:5:0 A:50/1 D:This scroll bears a curse that will tear your armour to shreds. Don't read it! N:216:Summon Undead G:?:d I:70:5:0 W:15:0:5:0 A:15/1 D:These spells scribed by ancient necromancers will call their horrible creatures to haunt you. N:217:Blessing G:?:d I:70:33:0 W:1:0:5:15 A:1/1 D:The recitation of this scroll will grant you a blessing of the Valar, making you more confident D:in attack and defence for a few moments. N:218:Holy Chant G:?:d I:70:34:0 W:10:0:5:40 A:10/1 D:This blessing will give you a holy warrior's prowess in battle for a while. N:219:Holy Prayer G:?:d I:70:35:0 W:25:0:5:80 A:25/1 D:This incantation lets you fight as a warrior of Valinor for quite a while, supreme in attack and D:defence. N:220:Word of Recall G:?:d I:70:11:0 W:5:0:5:150 A:5/1 D:The spell on this scroll will slowly build an ethereal conduit to the town for you if you are in D:a dungeon, and into the dungeon if you are above ground. Upon completion, which takes a while, you D:will suddenly be translocated to the other place. N:221:*Destruction* G:?:d I:70:41:0 W:40:0:5:250 A:40/1 D:This scroll is inscribed with a mighty conjuration which wrecks the dungeon all around you. D:Monsters and objects will be annihilated by this blast; only completely indestructible things can D:withstand it. ##### Potions ##### N:222:Slime Mold Juice G:!:d I:71:2:400 W:0:0:4:2 A:0/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A strange sort of yellowish-green slime, too viscous to even slosh in the bottle. And as I know D:you, you're going to slurp it down. N:223:Apple Juice G:!:d I:71:1:250 W:0:0:4:1 A:0/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A healthy fruit beverage. N:224:Water G:!:d I:71:0:200 W:0:0:4:1 A:0/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A small bottle filled with pure water. N:225:Strength G:!:d I:71:48:0 W:20:0:4:8000 A:20/6:25/3:30/1 P:0:1d1:0:0:0 D:This beneficial potion will magically improve your physical strength. N:226:Weakness G:!:d I:71:16:0 W:3:0:4:0 A:3/1 P:0:3d12:0:0:0 F:FOUNTAIN D:This nasty potion will sap your strength, making you weaker. N:227:Restore Strength G:!:d I:71:42:0 W:25:0:4:300 A:25/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This magical potion will bring back your physical power to its full extent, should it be drained. N:228:Intelligence G:!:d I:71:49:0 W:20:0:4:8000 A:20/6:25/3:30/1 P:0:1d1:0:0:0 D:This nice potion will magically enhance your wit, permanently improving your intellect. N:229:Stupidity G:!:d I:71:17:0 W:20:0:4:0 A:20/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This accursed potion will cloud your intellect, making you stupid. N:230:Restore Intelligence G:!:d I:71:43:0 W:25:0:4:300 A:25/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This beneficial potion will magically heal your brain, restoring drained intelligence. N:231:Wisdom G:!:d I:71:50:0 W:20:0:4:8000 A:20/6:25/3:30/1 P:0:1d1:0:0:0 D:This potion grants great insight, making you wiser. N:232:Naivety G:!:d I:71:18:0 W:20:0:4:0 A:20/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This potion casts a shadow on your knowledge, making you foolish. N:233:Restore Wisdom G:!:d I:71:44:0 W:25:0:4:300 A:25/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This potion benefits the naive, bringing back their wisdom to what it once was. N:234:Charisma G:!:d I:71:53:0 W:20:0:4:1000 A:20/1:25/1 P:0:1d1:0:0:0 D:This potion infuses you with beauty and charm. N:235:Ugliness G:!:d I:71:21:0 W:20:0:4:0 A:20/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This wicked potion slightly twists your features, making you appear less fair. N:236:Restore Charisma G:!:d I:71:47:0 W:20:0:4:300 A:20/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This useful potion restores drained charm. N:237:Curing G:!:d I:71:61:100 W:18:0:4:250 A:18/1:40/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This blessed potion helps to recover from a wide variety of ailments. ### Note! Invulnerability decreases your food... ### N:238:Invulnerability G:!:d I:71:62:-2500 W:90:0:4:100000 A:90/9 P:0:1d1:0:0:0 D:This immensely powerful potion makes your physique almost indestructible for a very short D:time. Very rarely, an attempt to hurt you will still succeed, so don't be too confident. N:239:New Life G:!:d I:71:63:100 W:50:0:4:750000 A:50/20:100/10:120/5 P:0:1d1:0:0:0 D:This potion fundamentally twists your physical features, as if you were another mother's child. D:Your physique will be shaped anew. N:240:Cure Serious Wounds G:!:d I:71:35:100 W:3:0:4:40 A:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This beneficial potion will cure some wounds and other inhibiting ailments. N:241:Cure Critical Wounds G:!:d I:71:36:100 W:5:0:4:100 A:5/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This nice potion will cure a good bit of hurt you have suffered and also allows you to recover D:from unhealthy conditions like blood poisoning, confusion or blindness. N:242:Healing G:!:d I:71:37:200 W:15:0:4:300 A:15/1:30/1:60/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This blessed potion greatly heals you and also cures many other ailments from D:which you might suffer. N:243:Constitution G:!:d I:71:52:0 W:20:0:4:8000 A:20/6:25/3:30/1 P:0:1d1:0:0:0 D:This magical concoction greatly improves your health, making you permanently tougher. N:244:Experience G:!:d I:71:59:0 W:65:0:4:25000 A:65/1 P:0:1d1:0:0:0 D:This exceptional drink instills into you knowledge, allowing you to advance further in your trade. N:245:Sleep G:!:d I:71:11:100 W:0:0:4:0 A:0/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This potion was made to help people with bad sleeping disorders to find rest. Surely you don't D:want to take a nap while nasty goblins are searching for you? N:246:Blindness G:!:d I:71:7:0 W:0:0:4:0 A:0/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This slightly poisonous potion temporarily impedes your eyesight, making you unable to see D:a thing. N:247:Booze G:!:d I:71:9:50 W:0:0:4:0 A:0/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A small bottle of a dark brown distilled beverage. By its look and smell, it contains a fair D:amount of still muck and wood alcohol. N:248:Poison G:!:d I:71:6:0 W:3:0:4:0 A:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This bottle is filled with a mild but still dangerous liquid poison. Drinking it would be highly D:unwise. N:249:Speed G:!:d I:71:29:0 W:1:0:4:75 A:1/1:40/1:60/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A magical drink which temporarily allows you to act much faster when imbibed. N:250:Slowness G:!:d I:71:4:50 W:1:0:4:0 A:1/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A magical concoction which drains force from you, forcing you to move and act a lot slower, D:until it wears off. N:251:Dexterity G:!:d I:71:51:0 W:20:0:4:8000 A:20/6:25/3:30/1 P:0:1d1:0:0:0 D:A strange magical drink which greatly improves your agility and nimbleness. N:252:Restore Dexterity G:!:d I:71:45:0 W:25:0:4:300 A:25/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This magical brew brings your agility back to its former glory should it have been reduced. N:253:Restore Constitution G:!:d I:71:46:0 W:25:0:4:300 A:25/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A beneficial magical concoction, restoring your damaged health. N:254:Lose Memories G:!:d I:71:13:0 W:10:0:4:0 A:10/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A wicked potion, making you less of an adventurer than by right you should be. N:255:Salt Water G:!:d I:71:5:0 W:0:0:4:0 A:0/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A solution of salt in water, made for curing meat. Drinking it would cause violent nausea. N:256:Enlightenment G:!:d I:71:56:0 W:25:0:4:800 A:25/1:50/1:100/1 P:0:1d1:0:0:0 F:FOUNTAIN D:An exceptional magical drink which lets you "remember" your current location as if you had D:already seen all of it. N:257:Heroism G:!:d I:71:32:0 W:1:0:4:35 A:1/1 P:0:1d1:0:0:0 F:FOUNTAIN D:Quaffing this drink will temporarily make you fight like a hero of great might. N:258:Berserk Strength G:!:d I:71:33:0 W:3:0:4:100 A:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This strange drink will instill in you a wild battle rage for a while. N:259:Boldness G:!:d I:71:28:0 W:1:0:4:10 A:1/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This drink will improve your courage, dispelling all fear. N:260:Restore Life Levels G:!:d I:71:41:0 W:40:0:4:400 A:40/1 P:0:1d1:0:0:0 F:FOUNTAIN D:If your life force has been drained, this blessed brew will bring it back. N:261:Resist Heat G:!:d I:71:30:0 W:1:0:4:30 A:1/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This magical potion will make fire flow in your veins, rendering you less vulnerable to outward D:heat. N:262:Resist Cold G:!:d I:71:31:0 W:1:0:4:30 A:1/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This magical potion will for a short while grant you a familiarity with frost, so that you take D:less harm from extreme cold. N:263:Detect Invisible G:!:d I:71:25:0 W:3:0:4:50 A:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This magical concoction will temporarily improve your eyesight so that you can see creatures D:otherwise unseen. N:264:Slow Poison G:!:d I:71:26:0 W:1:0:4:25 A:1/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This healthy potion will dilute poisons in your blood. N:265:Neutralise Poison G:!:d I:71:27:0 W:5:0:4:75 A:5/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This powerful antidote will completely negate the effect of poisons currently affecting you. N:266:Restore Mana G:!:d I:71:40:0 W:25:0:4:350 A:25/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This potion infuses the drinker with pure magic force, bringing their magical potential back to D:its full extent. N:267:Infra-vision G:!:d I:71:24:0 W:3:0:4:20 A:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This potion temporarily grants or improves the ability to optically perceive heat sources. N:268:Resistance G:!:d I:71:60:100 W:20:0:4:250 A:20/1:45/1:80/1:100/1 P:0:1d1:0:0:0 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:FOUNTAIN D:This great potion infuses you with the power of the elements, so that you can better D:withstand their ravages. ##### Wands ##### # Wand of school spells N:269:Spell G:-:d I:65:1:0 W:3:0:10:100 A:3/1:13/1:23/1:43/1:63/1:83/1 P:0:1d1:0:0:0 F:SPECIAL_GENE N:270:Manathrust G:-:d I:65:3:-1:SPELL=Manathrust W:3:0:10:100 A:3/1 P:0:1d1:0:0:0 N:271:Fireflash G:-:d I:65:4:-1:SPELL=Fireflash W:10:0:10:100 A:10/2 P:0:1d1:0:0:0 N:272:Firewall G:-:d I:65:5:-1:SPELL=Firewall W:20:0:10:100 A:20/1 P:0:1d1:0:0:0 N:273:Tidal Wave G:-:d I:65:6:-1:SPELL=Tidal Wave W:20:0:10:100 A:20/1 P:0:1d1:0:0:0 N:274:Ice Storm G:-:d I:65:7:-1:SPELL=Ice Storm W:15:0:10:100 A:15/1 P:0:1d1:0:0:0 N:275:Noxious Cloud G:-:d I:65:8:-1:SPELL=Noxious Cloud W:5:0:10:100 A:5/2 P:0:1d1:0:0:0 N:276:Poison Blood G:-:d I:65:9:-1:SPELL=Poison Blood W:30:0:10:100 A:30/2 P:0:1d1:0:0:0 N:277:Thunderstorm G:-:d I:65:10:-1:SPELL=Thunderstorm W:40:0:10:100 A:40/2 P:0:1d1:0:0:0 N:278:Dig G:-:d I:65:11:-1:SPELL=Dig W:15:0:10:100 A:15/1 P:0:1d1:0:0:0 N:279:Stone Prison G:-:d I:65:12:-1:SPELL=Stone Prison W:50:0:10:100 A:50/3 P:0:1d1:0:0:0 N:280:Strike G:-:d I:65:13:-1:SPELL=Strike W:30:0:10:100 A:30/1 P:0:1d1:0:0:0 N:281:Teleport Away G:-:d I:65:14:-1:SPELL=Teleport Away W:20:0:10:100 A:20/1 P:0:1d1:0:0:0 N:282:Summon Animal G:-:d I:65:15:-1:SPELL=Summon Animal W:60:0:10:100 A:60/1 P:0:1d1:0:0:0 N:283:Magelock G:-:d I:65:16:-1:SPELL=Magelock W:1:0:10:100 A:3/2 P:0:1d1:0:0:0 N:284:Slow Monster G:-:d I:65:17:-1:SPELL=Slow Monster W:3:0:10:100 A:3/2 P:0:1d1:0:0:0 N:285:Essence of Speed G:-:d I:65:18:-1:SPELL=Essence of Speed W:25:0:10:100 A:25/2 P:0:1d1:0:0:0 N:286:Banishment G:-:d I:65:19:-1:SPELL=Banishment W:45:0:10:100 A:45/2 P:0:1d1:0:0:0 N:287:Disperse Magic G:-:d I:65:20:-1:SPELL=Disperse Magic W:10:0:10:100 A:10/2 P:0:1d1:0:0:0 N:288:Charm G:-:d I:65:21:-1:SPELL=Charm W:15:0:10:100 A:15/1 P:0:1d1:0:0:0 N:289:Confuse G:-:d I:65:22:-1:SPELL=Confuse W:7:0:10:100 A:7/2 P:0:1d1:0:0:0 N:290:Demon Blade G:-:d I:65:23:-1:SPELL=Demon Blade W:60:0:10:100 A:60/1 P:0:1d1:0:0:0 N:291:Heal Monster G:-:d I:65:24:-1:SPELL=Heal Monster W:1:0:10:0 A:1/4 P:0:1d1:0:0:0 N:292:Haste Monster G:-:d I:65:25:-1:SPELL=Haste Monster W:1:0:10:0 A:1/4 P:0:1d1:0:0:0 ##### Extra ammunition ##### N:293:& Flight Arrow~ G:{:y I:17:1:0 W:3:0:1:1 A:3/2 P:0:1d3:0:0:0 F:SHOW_MODS D:An arrow designed for longer flight. Consequently, it is lighter and hits with less force. # XXX N:295:& Boulder~ G:*:W I:11:1:0 W:3:0:50:1 A:3/200 P:0:5d5:0:0:0 F:SPECIAL_GENE D:A big nasty-looking piece of rock. # Used for a quest N:296:& Flame~ Imperishable G:~:v I:11:255:0 W:127:0:4:0 A:127/255 P:0:1d1:0:0:0 T:39:2 F:NORM_ART | FULL_NAME | SPECIAL_GENE F:ACTIVATE | ACTIVATE_NO_WIELD a:SPELL=Artifact Eternal Flame D:An impossibly bright, flickering living flame. It can be used D:once to imbue an object with the power of Eru Iluvatar himself. N:297:& Necromantic Teeth~ G:|:D I:23:34:0 W:0:0:7:10 A:0/1:5/1:10/1:20/1 P:0:1d4:0:0:0 F:SHOW_MODS | VAMPIRIC | SPECIAL_GENE D:This looks like some animal's teeth or at least you think D:it comes from an animal... # The Horn of the Thunderlords N:298:& Golden Horn~ of the Thunderlords G:_:d I:55:23:-1:SPELL=Artifact Thunderlords W:50:10:10:12000 P:0:1d4:0:0:0 A:50/200 T:55:8 F:NO_RECHARGE | EASY_USE | RECHARGED | NORM_ART | FULL_NAME | SPECIAL_GENE D:This horn was given to you as a reward. Blow it if you are in dire need D:of leaving your current location fast. # XXX ##### Staves ##### N:300:Spell G:_:d I:55:1:0 W:5:0:50:100 A:5/1:15/1:35/1:45/1:65/1:75/1:85/1:95/1 P:0:1d2:0:0:0 F:SPECIAL_GENE N:301:Nothing G:_:d I:55:2:-1:SPELL=Nothing W:5:0:50:100 A:5/1 P:0:1d2:0:0:0 N:302:Globe of Light G:_:d I:55:3:-1:SPELL=Globe of Light W:7:0:50:100 A:7/1 P:0:1d2:0:0:0 N:303:Fiery Shield G:_:d I:55:4:-1:SPELL=Fiery Shield W:15:0:50:100 A:15/2 P:0:1d2:0:0:0 N:304:Remove Curses G:_:d I:55:5:-1:SPELL=Remove Curses W:10:0:50:100 A:10/1 P:0:1d2:0:0:0 N:305:Wings of Winds G:_:d I:55:6:-1:SPELL=Wings of Winds W:25:0:50:100 A:25/2 P:0:1d2:0:0:0 N:306:Shake G:_:d I:55:7:-1:SPELL=Shake W:30:0:50:100 A:30/1 P:0:1d2:0:0:0 N:307:Disarm G:_:d I:55:8:-1:SPELL=Disarm W:2:0:50:100 A:2/1 P:0:1d2:0:0:0 N:308:Teleportation G:_:d I:55:9:-1:SPELL=Teleportation W:20:0:50:100 A:20/1 P:0:1d2:0:0:0 N:309:Probability Travel G:_:d I:55:10:-1:SPELL=Probability Travel W:50:0:50:100 A:50/3 P:0:1d2:0:0:0 N:310:Recovery G:_:d I:55:11:-1:SPELL=Recovery W:20:0:50:100 A:20/1 P:0:1d2:0:0:0 N:311:Healing G:_:d I:55:12:-1:SPELL=Healing W:25:0:50:100 A:25/2 P:0:1d2:0:0:0 N:312:Vision G:_:d I:55:13:-1:SPELL=Vision W:30:0:50:100 A:30/1 P:0:1d2:0:0:0 N:313:Identify G:_:d I:55:14:-1:SPELL=Identify W:10:0:50:100 A:10/1 P:0:1d2:0:0:0 N:314:Sense Hidden G:_:d I:55:15:-1:SPELL=Sense Hidden W:10:0:50:100 A:10/1 P:0:1d2:0:0:0 N:315:Reveal Ways G:_:d I:55:16:-1:SPELL=Reveal Ways W:5:0:50:100 A:5/1 P:0:1d2:0:0:0 N:316:Sense Monsters G:_:d I:55:17:-1:SPELL=Sense Monsters W:5:0:50:100 A:5/1 P:0:1d2:0:0:0 N:317:Genocide G:_:d I:55:18:-1:SPELL=Genocide W:55:0:50:100 A:55/2 P:0:1d2:0:0:0 N:318:Summon G:_:d I:55:19:-1:SPELL=Summon W:5:0:50:100 A:5/1 P:0:1d2:0:0:0 N:319:Sterilization G:_:d I:55:24:-1:SPELL=Sterilize W:20:0:50:100 A:20/3 P:0:1d2:0:0:0 N:320:Wish G:_:d I:55:20:-1:SPELL=Wish W:95:0:50:10000 A:95/40 P:0:1d2:0:0:0 F:NO_RECHARGE N:321:Mana G:_:d I:55:21:-1:SPELL=Mana W:60:0:50:100 A:60/2 P:0:1d2:0:0:0 # XXX # ... # XXX ##### School Books ##### N:330:& Tome~ of Magical Energy G:?:B I:111:0:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:The bright blue cover of this tome seems to glow D:with an inner violet light. You feel more attuned D:to raw magic as you hold it. N:331:& Tome~ of the Eternal Flame G:?:R I:111:1:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW | IGNORE_FIRE D:The cover of this tome is bright red, with flickering D:flames dancing across it once in a while. As you hold D:it, you begin to gain a much closer knowledge of all D:that is fiery. N:332:& Tome~ of the Blowing Wind G:?:b I:111:2:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW | IGNORE_ELEC D:The pages of this tome have a tendency to turn themselves, D:as though flipped by an errant wind. As you hold it, D:you start feeling wind at your fingertips. N:333:& Tome~ of the Impenetrable Earth G:?:U I:111:3:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW | IGNORE_ACID D:The solid leather cover of this tome seems permanently D:stained with caked mud and grass. Heavy it is to lift, D:yet strangely comforting to hold - you feel stronger D:and better supported. N:334:& Tome~ of the Everrunning Wave G:?:B I:111:4:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:The cover and pages of this tome seem to be perpetually D:wet, though they are not wet to the touch. As you hold D:it, you begin to understand ocean storms better. N:335:& Tome~ of Translocation G:?:B I:111:5:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:This book seems to flicker strangely. It's one of those books D:with an annoying tendency to disappear when you need it and D:reappear in the unlikeliest places. As you hold it, you start D:to understand what conveyance really means. N:336:& Tome~ of the Tree G:?:G I:111:6:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:The cover of this tome is a bright shade of green, and it gives off D:a healthy, zesty scent that makes your thoughts clearer. As you D:hold it, your heart goes out to all living things upon Arda. N:337:& Tome~ of Knowledge G:?:D I:111:7:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:A thick book with solid leather binding. It looks entirely D:unremarkable, but as you hold it, you feel strangely able D:to learn the inner workings of things and creatures. ##### Chests ##### N:338:& Small wooden chest~ G:~:s I:7:1:0 W:5:0:250:20 A:5/1 P:0:2d3:0:0:0 D:A small wooden box, locked and possibly trapped. You wonder what might be inside. N:339:& Large wooden chest~ G:~:s I:7:5:0 W:15:0:500:60 A:15/1 P:0:2d5:0:0:0 D:A large wooden box. It doesn't seem to be locked - why not risk a look inside? N:340:& Small iron chest~ G:~:s I:7:2:0 W:25:0:300:100 A:25/1 P:0:2d4:0:0:0 D:A small rectangular container made of wood and reinforced with iron corners and latches. N:341:& Large iron chest~ G:~:s I:7:6:0 W:35:0:1000:150 A:35/1 P:0:2d6:0:0:0 D:A big container made of wood, with a heavy iron lock. N:342:& Small steel chest~ G:~:s I:7:3:0 W:45:0:500:200 A:45/1 P:0:2d4:0:0:0 D:A small wooden box with strong steel locks and reinforcements. N:343:& Large steel chest~ G:~:s I:7:7:0 W:55:0:1000:250 A:55/1 P:0:2d6:0:0:0 D:A nearly indestructible chest of wood and steel. The lock doesn't look impenetrable, but it D:might be trapped. N:344:& Ruined chest~ G:~:s I:7:0:0 W:0:0:250:0 A:75/1 D:A broken, empty chest. ##### Various Stuff ##### N:345:& Iron Spike~ G:~:W I:5:0:0 W:1:0:10:1 A:1/1 P:0:1d1:0:0:0 D:A small spur of iron. Ramming one between a door and its frame might jam it. N:346:& Wooden Torch~ G:~:u I:39:0:0:4000 W:1:0:30:2 A:1/1 P:0:1d1:0:0:0 F:EASY_KNOW | LITE1 | FUEL_LITE f:LITE1 | FUEL_LITE D:A piece of wood with an oily rag wrapped around it. When lit, it will give off a little light and D:much smoke. N:347:& Brass Lantern~ G:~:U I:39:1:0:7500 W:3:0:50:35 A:3/1 P:0:1d1:0:0:0 F:EASY_KNOW | IGNORE_FIRE | LITE2 | FUEL_LITE f:LITE2 | FUEL_LITE D:A brass container with a wick emerging from it, protected from draughts by a sheet of greased D:paper. It can be carried by a handle. N:348:& Flask~ of oil G:!:y I:77:0:7500 W:1:0:10:3 A:1/1 P:0:2d6:0:0:0 D:A small clay container, filled with thick oil. The oil is flammable and can be used as lantern D:fuel. N:349:& Empty Bottle~ G:!:w I:2:1:0 W:0:0:2:1 A:0/1 P:0:1d1:0:0:0 D:A small glass bottle. It's empty. ##### Here are the Rod Tips ##### N:350:Havoc G:-:d I:66:28:90 W:95:0:15:150000 A:100/16 P:0:1d1:0:0:0 D:This powerful rod will release great blasts of destructive energy, but there's no knowing what D:this effect will concentrate on. N:351:Door/Stair Location G:-:d I:66:1:10 W:15:0:15:1000 A:15/1 P:0:1d1:0:0:0 D:When fuelled with enough ambient mana, this rod can detect nearby passages. N:352:Trap Location G:-:d I:66:29:8 W:5:0:15:100 A:5/1:10/1:20/1 P:0:1d1:0:0:0 D:Zapping this rod will release a minor detection magic, alerting you of nearby pits and snares. N:353:Probing G:-:d I:66:7:50 W:40:0:15:4000 A:40/4 P:0:1d1:0:0:0 D:A rod of knowledge which will tell you about nearby creatures' health. N:354:Recall G:-:d I:66:3:80 W:30:0:15:4500 A:30/4 P:0:1d1:0:0:0 D:A rod which can transport you from the depths to your home and back. N:355:Illumination G:-:d I:66:4:8 W:20:0:15:1000 A:20/1 P:0:1d1:0:0:0 D:This rod carries a minor spell of brightness, lighting your immediate surroundings whenever D:activated. N:356:Light G:-:d I:66:15:15 W:10:0:15:500 A:10/1 P:0:1d1:0:0:0 D:This rod can shoot a lance of bright light, hurting creatures which lurk in the dark. N:357:Lightning Bolts G:-:d I:66:21:30 W:20:0:15:2000 A:20/1 P:0:1d1:0:0:0 D:This rod shoots a small spark of lightning, zapping the creature it hits. N:358:Frost Bolts G:-:d I:66:23:35 W:25:0:15:2500 A:25/1 P:0:1d1:0:0:0 D:A small but extremely cold shard of ice will fly from this rod to your enemy. N:359:Fire Bolts G:-:d I:66:22:40 W:30:0:15:3000 A:30/1 P:0:1d1:0:0:0 D:This rod fires a magical flaming arrow at your foe, burning it. N:360:Polymorph G:-:d I:66:19:25 W:35:0:15:1200 A:35/1 P:0:1d1:0:0:0 D:This rod of change will cause its target creature to mutate into something else. N:361:Slow Monster G:-:d I:66:17:25 W:30:0:15:1500 A:30/1 P:0:1d1:0:0:0 D:This obstructive rod emits an energy bolt which will slow the creature it hits. N:362:Sleep Monster G:-:d I:66:16:25 W:30:0:15:1500 A:30/1 P:0:1d1:0:0:0 D:This sorcerous rod will cause its target to stop in its tracks. N:363:Drain Life G:-:d I:66:18:30 W:75:0:15:3600 A:75/4 P:0:1d1:0:0:0 D:This necromantic magical rod will hurt a living creature struck by its spell. N:364:Teleport Other G:-:d I:66:13:60 W:45:0:15:1400 A:45/2 P:0:1d1:0:0:0 D:This rod of movement will displace its target to another location. N:365:Disarming G:-:d I:66:14:50 W:35:0:15:2100 A:35/1 P:0:1d1:0:0:0 D:This rod will clear a path for you, triggering and thus rendering harmless all traps on the way. N:366:Lightning Balls G:-:d I:66:25:50 W:55:0:15:4000 A:55/1 P:0:1d1:0:0:0 D:This rod will hurl a large ball of lightning at its target, electrifying all it engulfs. N:367:Cold Balls G:-:d I:66:27:55 W:60:0:15:4500 A:60/1 P:0:1d1:0:0:0 D:This rod will call forth a minor storm of ice which freezes everything in the area of its blast. N:368:Fire Balls G:-:d I:66:26:60 W:75:0:15:5000 A:75/1 P:0:1d1:0:0:0 D:This rod will cause a small storm of flame to rage in a small circular area of your choice. N:369:Acid Balls G:-:d I:66:24:60 W:70:0:15:5500 A:70/1 P:0:1d1:0:0:0 D:This destructive rod will drown its target and its immediate surroundings in caustic acid. N:370:Acid Bolts G:-:d I:66:20:40 W:40:0:15:3500 A:40/1 P:0:1d1:0:0:0 D:This rod will shoot a small glob of powerful acid at its target. N:371:Enlightenment G:-:d I:66:5:40 W:65:0:15:10000 A:65/4 P:0:1d1:0:0:0 D:This rod grants you knowledge of your surroundings. N:372:Perception G:-:d I:66:2:20 W:50:0:15:13000 A:50/8:100/8 P:0:1d1:0:0:0 D:This rod makes you insightful, laying open the identity of your possessions. N:373:Curing G:-:d I:66:8:35 W:65:0:15:15000 A:65/8 P:0:1d1:0:0:0 D:This is a rod with minor healing powers, alleviating many disabling conditions. N:374:Healing G:-:d I:66:9:120 W:80:0:15:20000 A:80/8 P:0:1d1:0:0:0 D:This rod has major healing powers and can restore your health if you have been wounded. N:375:Detection G:-:d I:66:6:80 W:30:0:15:5000 A:30/8 P:0:1d1:0:0:0 D:This rod grants knowledge about all things worthy of notice in your vicinity. N:376:Restoration G:-:d I:66:10:140 W:80:0:15:25000 A:80/16 P:0:1d1:0:0:0 D:This rod lets you remember your previous abilities and gain them back, should they have been D:reduced. N:377:Speed G:-:d I:66:11:100 W:95:0:15:50000 A:95/16 P:0:1d1:0:0:0 D:This energising rod will allow you to act a lot faster for some time. # Ring of Spell N:378:Spell G:=:d I:45:58:0 W:10:0:2:1000 A:10/1 F:SPELL_CONTAIN | WIELD_CAST f:SPELL_CONTAIN D:This ring is a container for spells. Those that are skilled in copying spells can inscribe a D:spell into it. # Amulet of Spell N:379:Spell G:":d I:40:27:0 W:10:0:2:1000 A:10/1 F:SPELL_CONTAIN | WIELD_CAST f:SPELL_CONTAIN D:This amulet is a container for spells. Those that are skilled in copying spells can inscribe a D:spell into it. # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX ##### Skeletons ##### N:391:& Broken Skull~ G:~:w I:1:1:0 W:0:0:1:0 A:0/1 P:0:1d1:0:0:0 D:Good old Yorick. So that's where he ended up. N:392:& Broken Bone~ G:~:w I:1:2:0 W:0:0:2:0 A:0/1 P:0:1d1:0:0:0 D:A yellowish bone, broken off. Obviously, its owner no longer has a use for it. N:393:& Canine Skeleton~ G:~:w I:1:4:0 W:1:0:10:0 A:1/1 P:0:1d1:0:0:0 D:Lassie? N:394:& Rodent Skeleton~ G:~:w I:1:3:0 W:1:0:10:0 A:1/1 P:0:1d1:0:0:0 D:The remains of a cat's meal. N:395:& Human Skeleton~ G:~:w I:1:8:0 W:5:0:60:0 A:5/1 P:0:1d2:0:0:0 D:It's dead, Jim. N:396:& Dwarf Skeleton~ G:~:w I:1:7:0 W:5:0:50:0 A:5/1 P:0:1d2:0:0:0 D:The remains of a dwarf who met his or her demise here. N:397:& Elf Skeleton~ G:~:w I:1:6:0 W:5:0:40:0 A:5/1 P:0:1d2:0:0:0 D:A person of about human shape, but considerably more slightly built, has died here long ago. N:398:& Gnome Skeleton~ G:~:w I:1:5:0 W:5:0:30:0 A:5/1 P:0:1d2:0:0:0 D:This was once a gnome. Looks very dead now. ##### Additional weapon ##### N:399:& Great Hammer~ G:\:D I:21:19:0 W:45:0:300:350 A:45/3 P:0:4d6:0:0:0 F:SHOW_MODS D:A massive smith's hammer, so large and heavy it can be used as a weapon. ##### Dragon Scale Mail ##### N:400:& Black Dragon Scale Mail~ G:[:s I:38:1:0 W:60:0:200:50000 A:60/8 P:30:2d4:-2:0:10 a:HARDCORE=BR_ACID F:RES_ACID | FLY | f:RES_ACID | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:An armour made of a black dragon's hide, containing some of this beast's powers. N:401:& Blue Dragon Scale Mail~ G:[:b I:38:2:0 W:50:0:200:40000 A:50/8 P:30:2d4:-2:0:10 a:HARDCORE=BR_ELEC F:RES_ELEC | FLY | f:RES_ELEC | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A piece of dragon hide fashioned into an armour, shimmering bright blue. N:402:& White Dragon Scale Mail~ G:[:w I:38:3:0 W:50:0:200:40000 A:50/8 a:HARDCORE=BR_COLD P:30:2d4:-2:0:10 F:RES_COLD | FLY | f:RES_COLD | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:An armour fashioned from dragon hide, glistening the white of snow. N:403:& Red Dragon Scale Mail~ G:[:r I:38:4:0 W:60:0:200:50000 A:60/8 P:30:2d4:-2:0:10 a:HARDCORE=BR_FIRE F:RES_FIRE | FLY | f:RES_FIRE | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:The skin of a dragon made into a suit of armour. It glows a bright red and radiates heat. N:404:& Green Dragon Scale Mail~ G:[:g I:38:5:0 W:50:0:200:40000 A:50/8 P:30:2d4:-2:0:10 a:HARDCORE=BR_POIS F:RES_POIS | FLY | f:RES_POIS | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A suit of armour fashioned of dragon hide. It is dirty green and smells awful. N:405:& Multi-Hued Dragon Scale Mail~ G:[:v I:38:6:0 W:90:0:200:150000 A:90/32 P:30:2d4:-2:0:10 a:HARDCORE=BR_MANY F:ATTR_MULTI F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | FLY | f:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A powerful armour made of dragonhide. It glows red, blue, green, black and white. N:406:& Pseudo Dragon Scale Mail~ G:[:v I:38:10:0 W:70:0:200:70000 A:70/16 P:30:2d4:-2:0:10 a:HARDCORE=BR_LIGHT F:RES_LITE | RES_DARK | FLY | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A suit of armour made of dragon hide, glowing with a strange light, or is it darkness? N:407:& Law Dragon Scale Mail~ G:[:B I:38:12:0 W:80:0:200:80000 A:80/16 P:30:2d4:-2:0:10 a:HARDCORE=BR_SHARD F:RES_SOUND | RES_SHARDS | FLY | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A piece of dragonhide cut and shaped so it can be worn as armour. The scales are very sharp, D:and the roaring of a storm seems to come from it, but you're not afraid of either. N:408:& Bronze Dragon Scale Mail~ G:[:U I:38:14:0 W:50:0:200:40000 A:50/8 P:30:2d4:-2:0:10 a:HARDCORE=BR_CONF F:RES_CONF | FLY | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A suit of armour made from dragon skin. Its brownish scales glitter in a dazzling light. N:409:& Gold Dragon Scale Mail~ G:[:y I:38:16:0 W:60:0:200:50000 A:60/8 P:30:2d4:-2:0:10 a:HARDCORE=BR_SOUND F:RES_SOUND | FLY | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A suit of golden-hued armour made of dragonhide. The rustle of its scales occasionally D:increases to a loud boom. N:410:& Chaos Dragon Scale Mail~ G:[:v I:38:18:0 W:80:0:200:80000 A:80/16 P:30:2d4:-2:0:10 a:HARDCORE=BR_CHAOS F:ATTR_MULTI F:RES_CHAOS | RES_DISEN | FLY | f:RES_CHAOS | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A suit of armour made of dragon hide. It glows in colours you have never seen before. As you D:put it on, you feel like you could change the world and are no longer afraid of your equipment D:losing its magic. N:411:& Balance Dragon Scale Mail~ G:[:v I:38:20:0 W:95:0:200:100000 A:95/32 P:30:2d4:-2:0:10 a:HARDCORE=BR_BALANCE F:RES_CHAOS | RES_DISEN | RES_SOUND | RES_SHARDS | FLY | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A suit of armour made of the hide of a dead dragon. When wearing it, you feel like you D:understand the principles of law and chaos, and no longer fear either. N:412:& Power Dragon Scale Mail~ G:[:v I:38:30:0 W:100:0:250:350000 A:100/64 P:40:2d4:-3:0:15 a:HARDCORE=BR_POWER F:ATTR_MULTI F:RES_ACID | RES_FIRE | RES_COLD | RES_ELEC | RES_POIS | FLY | F:RES_NETHER | RES_NEXUS | RES_CHAOS | RES_LITE | RES_DARK | F:RES_SHARDS | RES_SOUND | RES_DISEN | RES_CONF | F:ACTIVATE | IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:A suit of armour made of a very thick richly coloured dragonhide. You think you'll never have D:to fear dragons if you put it on. #### PDSM has been restored to (almost) its former glory in Zangband N:413:& Dragon Helm~ G:]:G I:32:7:0 W:45:0:50:10000 A:80/4 P:8:1d3:0:0:10 F:IGNORE_ACID | IGNORE_FIRE | IGNORE_ELEC | IGNORE_COLD D:An iron helmet, covered with a layer of dragonhide. It offers great protection and may grant D:protection against some dragon's attacks, based on the dragon the hide was taken from. N:414:& Dragon Shield~ G:[:G I:34:6:0 W:70:0:100:10000 A:80/4 P:8:1d3:0:0:10 F:IGNORE_ACID | IGNORE_FIRE | IGNORE_ELEC | IGNORE_COLD D:A large shield, with a dragonskin cover. Depending on which dragon the hide came from, it D:might grant protection against some sorts of dragon breath. ##### Extra potions ##### N:415:Death G:!:d I:71:23:0 W:55:0:4:0 A:55/4 P:0:20d20:0:0:0 F:FOUNTAIN D:A potent and very quickly working poison, sometimes utilised by those who wish to end their D:lives. It is immensely toxic and will seriously hurt you even if you just get some of it on your D:hands. N:416:Ruination G:!:d I:71:15:0 W:40:0:4:0 A:40/8 P:0:20d20:0:0:0 F:FOUNTAIN D:This wicked potion will seriously damage your abilities beyond the powers of magical D:restoration. N:417:Detonations G:!:d I:71:22:0 W:60:0:4:10000 A:60/8 P:0:25d25:0:0:0 F:FOUNTAIN D:This bottle is filled with a strange substance which will violently explode if strongly agitated. D:You don't want to know what it might do to your intestines. N:418:Augmentation G:!:d I:71:55:0 W:40:0:4:60000 A:40/16 P:0:1d1:0:0:0 F:FOUNTAIN D:This blessed potions will greatly improve all your abilities, if they can still be improved. N:419:*Healing* G:!:d I:71:38:0 W:40:0:4:1500 A:40/4:60/2:80/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This highly desirable potion will greatly help recovering from wounds, typically healing you D:fully. N:420:Life G:!:d I:71:39:0 W:60:0:4:5000 A:60/4:100/2 P:0:1d1:0:0:0 D:This wonderful potion will fully heal you no matter how badly you're hurt, allow drained D:abilities to recover and remove various other ailments. N:421:Self Knowledge G:!:d I:71:58:0 W:40:0:4:2000 A:40/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A drink of insight, letting you know yourself better. N:422:*Enlightenment* G:!:d I:71:57:0 W:70:0:4:80000 A:70/4 P:0:1d1:0:0:0 F:FOUNTAIN D:This magical concoction will grant you great insight, magically improving your wits and D:wisdom, letting you know precisely who and where you are and what you possess. # XXX # XXX N:425:Fear Resistance G:=:d I:45:38:0 W:10:0:2:300 A:10/2 F:RES_FEAR | EASY_KNOW f:RES_FEAR | D:This ring grants courage, so that you can never become afraid. N:426:Light and Darkness Resistance G:=:d I:45:39:0 W:30:0:2:3000 A:30/2 F:RES_LITE | RES_DARK | EASY_KNOW f:RES_LITE | RES_DARK | D:This ring protects against fluctuations of the light. N:427:Nether Resistance G:=:d I:45:40:0 W:34:0:2:14500 A:34/2 F:RES_NETHER | HOLD_LIFE | EASY_KNOW f:RES_NETHER | D:This blessed ring improves your life force, protecting you from the draining forces of nether D:and other attempts to suck your lifeblood. N:428:Nexus Resistance G:=:d I:45:41:0 W:24:0:2:3000 A:24/2 F:RES_NEXUS | EASY_KNOW f:RES_NEXUS | D:This ring of stability protects you from the warping forces of nexus. N:429:Sound Resistance G:=:d I:45:42:0 W:26:0:2:3000 A:26/2 F:RES_SOUND | EASY_KNOW f:RES_SOUND | D:This ring projects an aura of quiet around you, protecting you from loud noise. N:430:Confusion Resistance G:=:d I:45:43:0 W:22:0:2:3000 A:22/2 F:RES_CONF | EASY_KNOW f:RES_CONF | D:This ring stabilises your mind, protecting you from all kinds of befuddlement. N:431:Shard Resistance G:=:d I:45:44:0 W:25:0:2:3000 A:25/2 F:RES_SHARDS | EASY_KNOW f:RES_SHARDS | D:This piece of jewellery magically toughens your skin, protecting you from flying shrapnel. N:432:Disenchantment Resistance G:=:d I:45:45:0 W:90:0:2:15000 A:90/10 F:RES_DISEN | EASY_KNOW f:RES_DISEN | D:This rare ring of preservation protects your equipment from attempts to sap its magic, also D:causing you to suffer less pain from such attacks. N:433:Chaos Resistance G:=:d I:45:46:0 W:50:0:2:13000 A:50/2 F:RES_CHAOS | RES_CONF | EASY_KNOW f:RES_CHAOS | D:This ring protects you from the horribly warping forces of chaos. N:434:Blindness Resistance G:=:d I:45:47:0 W:60:0:2:7500 A:60/2 F:RES_BLIND | EASY_KNOW f:RES_BLIND | D:This ring magically preserves your eyesight, making you impervious to any attempt to blind D:you. N:435:Lordly Protection G:=:d I:45:48:0 W:100:0:2:100000 A:100/5 F:RES_DISEN | RES_POIS | HOLD_LIFE | FREE_ACT f:RES_DISEN | RES_POIS | HOLD_LIFE | FREE_ACT D:This blessed ring will protect you from disenchantment, poison, attempts to drain your life D:force and holding magic. N:436:Extra Attacks G:=:d I:45:49:0 W:50:0:2:100000 A:50/2 F:BLOWS f:BLOWS D:This powerful ring of fighters greatly enhances your fighting speed, allowing you to attack D:more often in a round of combat. N:437:Cure Light Wounds G:!:d I:71:34:50 W:0:0:4:15 A:0/1:1/1:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This healthy drink heals a little damage you have taken. N:438:Clumsiness G:!:d I:71:19:0 W:5:0:4:0 A:5/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This nasty concoction will numb your nerves, making you clumsier. N:439:Sickliness G:!:d I:71:20:0 W:10:0:4:0 A:10/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This unhealthy drink damages your health, reducing your physical constitution. ###### Here start the maps ##### # Map of Bree N:440:Map of Bree G:?:s I:8:200:0 W:3:100:5:100 A:3/3 D:A map, showing the town of Bree and the landscape around it. # Map of Gondolin N:441:Map of Gondolin G:?:s I:8:201:0 W:70:100:5:50000 A:70/3 D:A map detailing the place of the hidden city of Gondolin. Consider yourself lucky someone D:lost a map here, since the location is yet unknown even to Morgoth. # Map of Lothlorien N:442:Map of Lothlorien G:?:s I:8:202:0 W:6:100:5:1000 A:6/3 D:A map vaguely describing the forest of Lothlorien and the elven settlements therein. # Map of Minas Anor N:443:Map of Minas Anor G:?:s I:8:203:0 W:36:100:5:10000 A:36/3 D:A map of the great city of Gondor. # XXX Numbers 444-464 unused # N:465:& Silver Arrow~ G:{:W I:17:3:0 W:55:0:2:35 A:50/4:90/2 P:0:3d4:0:0:0 F:SHOW_MODS | SLAY_EVIL | IGNORE_ACID | IGNORE_FIRE D:An arrow to be shot with a bow, its iron head coated with hallowed silver, D:a material that sears the flesh of all evil creatures. N:466:& Silver Bolt~ G:{:w I:18:3:0 W:50:0:2:40 A:60/4:95/2 P:0:3d5:0:0:0 F:SHOW_MODS | SLAY_EVIL | IGNORE_ACID | IGNORE_FIRE D:This crossbow bolt has a silver tip, blessed by the Valar for fighting evil. N:467:Lightning Resistance G:":d I:40:29:0 W:10:0:3:250 A:10/1 F:RES_ELEC | IGNORE_ELEC | EASY_KNOW f:RES_ELEC | D:This amulet will protect you from electrical discharges and storms. N:468:Wisdom G:":d I:40:28:0 W:30:0:3:500 A:30/1 F:WIS | SUST_WIS | HIDE_TYPE f:WIS | D:This magical amulet will magically make you wiser, and fend off D:attacks that would reduce your wisdom. Beware: if cursed, the D:amulet will do the opposite. N:469:Regeneration G:":d I:40:30:0 W:30:0:3:600 A:30/3 F:REGEN | EASY_KNOW f:REGEN | D:Wearing this amulet will trigger your body's regenerational D:processes quicker and make them proceed faster. N:470:Infravision G:":d I:40:26:0 W:10:0:3:200 A:10/1 F:INFRA | HIDE_TYPE f:INFRA | D:This amulet will increase your ability to sense warm-blooded D:creatures in your vicinity. Beware: if cursed, it will do D:just the opposite. N:471:Devotion G:":d I:40:25:0 W:70:0:3:30000 A:70/8 F:WIS | CHR | SUST_WIS | SUST_CHR | LITE1 | HIDE_TYPE | F:RES_DARK | RES_LITE | RES_FIRE | HOLD_LIFE | D:This blessed amulet will protect your wisdom and charms from D:diminishing, often adding to them as well. It also grants D:some extra protective magics by the grace of the Valar. N:472:Weaponmastery G:":d I:40:24:0 W:70:0:3:30000 A:70/8 F:STR | CON | SUST_STR | SUST_CON | FREE_ACT | HIDE_TYPE | F:RES_FEAR | RES_DISEN | D:The ultimate amulet for a warrior, it will grant protection D:in the face of some evil magics, protect your strength and health, D:also increasing them. Beware: if cursed, the amulet will D:sap your strength and health instead. N:473:Trickery G:":d I:40:23:0 W:70:0:3:30000 A:70/8 F:DEX | SUST_DEX | STEALTH | SPEED | INFRA | HIDE_TYPE | F:RES_NEXUS | RES_POIS D:The ultimate amulet for a rogue or assassin, it protects the D:wearer against some evil magics, granting improvements in D:the abilities vital to these adventurers. Beware: if cursed, D:the amulet will do just the opposite. N:474:Telepathy G:":d I:40:22:0 W:50:0:3:25000 A:50/6 F:ESP_ALL | f:ESP_ALL | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This rare and powerful amulet lays bare the minds of monsters D:before the wearer. N:475:Sustenance G:":d I:40:21:0 W:60:0:3:20000 A:60/4 F:SUST_STR | SUST_INT | SUST_WIS | SUST_DEX | SUST_CON | SUST_CHR | F:HOLD_LIFE | SLOW_DIGEST | EASY_KNOW | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This blessed amulet will make the wearer impervious to evil magics D:that would sap innate abilities. It also slows down the digestive D:system, making food less necessary on long journeys. # The Palantir of Minas Ithil -- see artifact list N:476:& Palantir~ G:~:y I:39:107:0 W:75:0:200:0 P:0:10d10:0:0:0 F:INSTA_ART # The Elfstone 'Elessar' -- see artifact list N:477:& Elfstone~ G:":g I:40:19:0 W:60:0:3:50000 F:INSTA_ART # The Jewel 'Evenstar' -- see artifact list N:478:& Jewel~ G:":w I:40:20:0 W:50:0:3:35000 F:INSTA_ART # The Ring of Durin -- see artifact list N:479:& Ring~ G:=:d I:45:57:0 W:70:0:2:65000 F:INSTA_ART | SPECIAL_GENE ##### And here starts the gold/gems ##### N:480:copper G:$:u I:100:1:0 W:1:0:0:3 N:481:copper G:$:u I:100:2:0 W:1:0:0:4 N:482:copper G:$:u I:100:3:0 W:1:0:0:5 N:483:silver G:$:s I:100:4:0 W:1:0:0:6 N:484:silver G:$:s I:100:5:0 W:1:0:0:7 N:485:silver G:$:s I:100:6:0 W:1:0:0:8 N:486:garnets G:$:r I:100:7:0 W:1:0:0:9 N:487:garnets G:$:r I:100:8:0 W:1:0:0:10 N:488:gold G:$:y I:100:9:0 W:1:0:0:12 N:489:gold G:$:y I:100:10:0 W:1:0:0:14 N:490:gold G:$:y I:100:11:0 W:1:0:0:16 N:491:opals G:$:W I:100:12:0 W:1:0:0:18 N:492:sapphires G:$:b I:100:13:0 W:1:0:0:20 N:493:rubies G:$:r I:100:14:0 W:1:0:0:24 N:494:diamonds G:$:w I:100:15:0 W:1:0:0:28 N:495:emeralds G:$:g I:100:16:0 W:1:0:0:32 N:496:mithril G:$:B I:100:17:0 W:1:0:0:40 N:497:adamantite G:$:G I:100:18:0 W:1:0:0:80 ##### Objects 498 and 499 are the "Morgoth Artifacts" ##### # These objects, like objects 500 to 511, are never created # without being turned into artifacts. This simplifies the # code for "killing the winner monster". N:498:& Mighty Hammer~ G:\:D I:21:50:0 W:15:0:200:1000 P:0:3d9:0:0:0 F:SHOW_MODS | INSTA_ART | MUST2H | SPECIAL_GENE f:MUST2H N:499:& Massive Iron Crown~ G:]:D I:33:50:0 W:44:0:20:1000 P:0:1d1:0:0:0 F:INSTA_ART | SPECIAL_GENE ##### Objects 500 to 511 are "Special Artifacts" ##### # These objects do not specify "full names" because the artifact name # is added in "obj-desc.c" based on the artifact index ("i_ptr->name1"). # # These objects do specify a "base name", which is used when the object # is "aware" (always true for lites) # # The Lites (and the One Ring) specify "physical colors", which # over-ride the "flavor" colors, if any. Note that the "One Ring" # also has a specific check for "unknown" in which it changes its # name to "a plain gold ring". See "object1.c" # # Note that ALL artifacts are given "IGNORE_ACID/ELEC/FIRE/COLD", # so we do not need to specify that here. # # Note that the "INSTA_ART" flag is used to prevent these objects from # being created without also turning them into artifacts. This flag # must be specified both here and in the artifact template. # # The only reason for having six different "ring" templates and three # different "amulet" templates is to allow each "special artifact" to # have a different "color" and "flavor", and also to allow the use of # special "base names" (such as "Necklace"). # The Phial of Galadriel -- see artifact list N:500:& Phial~ G:~:y I:39:100:0 W:20:0:10:10000 P:0:1d1:0:0:0 F:INSTA_ART # The Star of Elendil -- see artifact list N:501:& Star~ G:~:B I:39:101:0 W:30:0:5:25000 P:0:1d1:0:0:0 F:INSTA_ART # The Arkenstone of Thrain -- see artifact list N:502:& Arkenstone~ G:~:R I:39:102:0 W:60:0:5:60000 P:0:1d1:0:0:0 F:INSTA_ART # The Amulet of Carlammas -- see artifact list N:503:& Amulet~ G:":d I:40:10:0 W:50:0:3:60000 F:INSTA_ART # The Amulet of Ingwe -- see artifact list N:504:& Amulet~ G:":d I:40:11:0 W:60:0:3:90000 F:INSTA_ART # The Necklace 'Nauglamir' -- see artifact list N:505:& Necklace~ G:":d I:40:12:0 W:70:0:3:75000 F:INSTA_ART # The Ring of Barahir -- see artifact list N:506:& Ring~ G:=:d I:45:32:0 W:50:0:2:65000 F:INSTA_ART # The Ring of Tulkas -- see artifact list N:507:& Ring~ G:=:d I:45:33:0 W:90:0:2:150000 F:INSTA_ART # The Ring of Power 'Narya' -- see artifact list N:508:& Ring~ G:=:d I:45:34:0 W:80:0:2:100000 F:INSTA_ART | SPECIAL_GENE # The Ring of Power 'Nenya' -- see artifact list N:509:& Ring~ G:=:d I:45:35:0 W:90:0:2:200000 F:INSTA_ART # The Ring of Power 'Vilya' -- see artifact list N:510:& Ring~ G:=:d I:45:36:0 W:100:0:2:300000 F:INSTA_ART # The Ring of Power 'The One Ring' -- see artifact list N:511:& Ring~ G:=:y I:45:37:0 W:110:0:2:5000000 F:INSTA_ART ### Room for new objects added after 511 (Zangband 2.1.0): 512-575 # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX N:520:Reflection G:":d I:40:9:0 W:60:0:3:30000 A:60/4 F:REFLECT | EASY_KNOW f:REFLECT | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This wondrous amulet will magically make the wearer D:reflect arrows and bolts launched by adversaries. #521 and 522 cannot have EASY_KNOW because they may be cursed N:521:Anti-Magic G:":d I:40:13:0 W:40:0:3:30000 A:40/4 F:NO_MAGIC f:NO_MAGIC F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This amulet wards off magic of any kind, good or bad. N:522:Anti-Teleportation G:":d I:40:14:0 W:30:0:3:15000 A:30/4 F:NO_TELE f:NO_TELE F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This amulet will prevent the space-time continuum from D:being disrupted around the wearer. #523 cannot have EASY_KNOW because it can get random resistances N:523:Resistance G:":d I:40:15:0 W:50:0:3:25000 A:50/4 F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD f:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This amulet will make the wearer resist the elements. ##### New arms ##### N:524:& Zweihander~ G:|:w I:23:29:0 W:40:0:280:580 A:40/3 P:0:4d6:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This great sword of foreign origin is approximately 6 feet long. The hilt is D:long enough for even four hands to grip. A mighty weapon for a warrior. # Dwarven lantern N:525:& Dwarven Lantern~ G:~:b I:39:3:0 W:15:0:50:5000 A:15/2 P:0:1d1:0:0:0 F:EASY_KNOW | IGNORE_FIRE | LITE2 f:LITE2 D:Made by the dwarves, this lantern provides light in the D:darkest recesses of the earth. N:526:& Splint Mail~ G:[:D I:37:10:0 W:35:0:250:950 A:35/1 P:19:1d4:-2:0:0 D:A suit of metal armour that consists of metal strips applied vertically D:to the backing of chain, leather, or cloth. # Everburning torch N:527:& Everburning Torch~ G:~:R I:39:2:0 W:5:0:50:2500 A:5/1 P:0:1d1:0:0:0 F:EASY_KNOW | IGNORE_FIRE | LITE1 f:LITE1 D:This enchanted torch never needs to be fuelled. N:528:& Trifurcate Spear~ G:/:o I:22:26:0 W:35:0:140:400 A:35/3 P:0:2d9:0:0:0 F:SHOW_MODS D:This deadly spear's point has three branches, suited for inflicting D:greater damage than a regular spear. N:529:& Three Piece Rod~ G:\:u I:21:11:0 W:20:0:120:350 A:20/3 P:0:3d3:0:0:0 F:SHOW_MODS D:A descendant of the threshing flail, consisting of three short wooden D:pieces linked by chain or rope. # Feanorian Lamp N:530:& Feanorian Lamp~ G:~:B I:39:4:0 W:25:0:50:15000 A:25/3 P:0:1d1:0:0:0 F:EASY_KNOW | IGNORE_FIRE | LITE3 f:LITE3 D:Made by the descendants of the Noldo craftsman, this lamp D:contains a part of the flame which burned inside Feanor. N:531:& Fur Cloak~ G:(:W I:35:3:0 W:20:0:30:100 A:20/2:30/2 P:3:0d0:0:0:0 D:A coat made from the fur of various wild animals - it is D:somewhat bulky, but still spacious enough to wear over armour. N:532:Water Curing G:!:d I:72:18:80 W:0:0:4:0 A:0/1 P:0:1d1:0:0:0 F:SPECIAL_GENE D:It is a magical component that can purify water. N:533:& Hatchet~ G:/:s I:24:1:0 W:10:0:60:120 A:10/2 P:0:1d5:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:This is a large axe that could be wielded in one or two hands. It has D:a single blade with a pick on the reverse, designed for armour piercing. ##### New armour ##### N:535:& Rhino Hide Armour~ G:(:s I:36:8:0 W:15:0:110:400 A:15/1 P:8:1d1:-1:0:0 D:A hard leather armour made from the thick hide of a rhinoceros. N:536:& Leather Jacket~ G:(:U I:36:12:0 W:20:0:130:550 A:20/3 P:12:1d2:-1:0:0 D:A garment fashioned from animal hide, resembling a robe that has been D:shortened to waist-length, with straight-cut sleeves and a bit of decorative D:fringe around the collar. ##### New weapons ##### N:537:& Sickle~ G:/:s I:22:3:0 W:10:0:70:110 A:10/3 P:0:2d3:0:0:0 F:SHOW_MODS D:A semicircular blade attached to a short handle, good for chopping D:things up into pieces. # XXX # XXX # XXX # XXX N:542:& Club~ G:\:u I:21:1:0 W:0:0:100:3 A:0/1 P:0:1d4:0:0:0 F:SHOW_MODS D:A stout heavy stick, thicker at one end. Useful for D:shattering and smashing things. N:543:& Broad Spear~ G:/:w I:22:7:0 W:14:0:100:240 A:14/3 P:0:1d9:0:0:0 F:SHOW_MODS D:Designed specifically for foot soldiers combatting cavalry, this spear D:is too heavy to be effective when thrown. N:544:& Khopesh~ G:|:W I:23:14:0 W:10:0:130:190 A:10/2 P:0:2d4:0:0:0 F:SHOW_MODS D:This sword comes from the regions of Far Harad. The blade is straight D:for 18 inches, and then it curves for another 2 feet. N:545:& Flamberge~ G:|:W I:23:26:0 W:40:0:230:600 A:40/2 P:0:3d7:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:A large, two-handed sword with a blade that weaves D:left and right until it reaches the hilt. N:546:& Claymore~ G:|:W I:23:23:0 W:40:0:200:600 A:40/2 P:0:2d8:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:Also known as a Claidhmore, or Greatsword, this weapon is favoured D:by powerful mercenaries. The blade is large, straight, and broad, D:almost as large as a two-handed sword. N:547:& Espadon~ G:|:W I:23:24:0 W:40:0:200:600 A:40/3 P:0:2d9:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This is the strictly two-handed version of the bastard sword. D:The blade is of medium length, double-edged, and considerably D:heavy to wield. N:548:& Great Scimitar~ G:|:W I:23:22:0 W:40:0:240:500 A:40/3 P:0:4d5:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This is a larger version of the curved oriental blade. D:Runes of war decorate its golden hilt. ### Trapping Kits N:549:Arrow G:`:r I:46:2:0 W:10:0:60:150 A:10/2:50/2 F:SHOW_MODS D:It must be loaded with arrows, which will be D:fired at the monster who triggers the trap. N:550:Bolt G:`:o I:46:3:0 W:20:0:220:300 A:20/2:50/2 F:SHOW_MODS D:It must be loaded with crossbow bolts, which will D:be fired at the monster who triggers the trap. N:551:& Fauchard~ G:/:s I:22:6:0 W:18:0:155:301 A:18/2 P:0:1d10:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:It is a type of glaive with two ornate hooks on the back D:of the blade. It is typically 8 to 9 feet long. N:552:& Guisarme~ G:/:s I:22:16:0 W:21:0:165:320 A:21/1 P:0:2d5:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:Mounted on a long shaft for maximum reach, this weapon is D:effective at repelling both cavalry and infantry. N:553:& Heavy Lance~ G:/:s I:22:29:0 W:43:0:400:700 A:43/2 P:0:4d8:0:0:0 F:SHOW_MODS | MUST2H f:MUST2H D:This is a shock weapon. Its purpose is to unhorse a rider D:in single combat, or smash through the armour of opposing lines. N:554:& Basilard~ G:|:w I:23:9:0 W:15:0:80:220 A:15/3 P:0:1d8:0:0:0 F:SHOW_MODS D:This is a two-edged dagger with a long blade. A favourite among travellers D:and warriors alike, it can be worn comfortably with plain clothes D:as well as armour. ### Trapping Kits N:555:Catapult G:`:R I:46:1:0 W:1:0:50:40 A:1/2:20/2 F:SHOW_MODS D:It must be loaded with sling bullets, which will D:be fired at the monster who triggers the trap. N:556:& Ring Mail~ G:[:s I:37:2:0 W:20:0:200:500 A:20/1 P:12:1d4:-2:0:0 D:A suit of non-overlapping metal rings sewn onto a D:heavy leather backing. N:557:& Cord Armour~ G:(:y I:36:9:0 W:5:0:80:40 A:5/1 P:6:1d1:0:0:0 D:Fibres of hemp or other natural material woven and knotted D:into a thick, tough fabric. N:558:& Paper Armour~ G:(:w I:36:3:0 W:5:0:30:40 A:5/2 P:4:1d1:0:0:0 D:Thickly pleated sheets of paper assembled together into D:a suit of armour. N:559:& Padded Armour~ G:(:y I:36:10:0 W:2:0:60:40 A:2/1 P:4:1d1:0:0:0 D:Heavy, multi-layered cloth sewn together to cover the body, D:with extra padding between layers. ### Trapping Kits N:560:Fumes G:`:G I:46:4:0 W:2:0:20:50 A:2/2:30/2 D:It must be loaded with potions, which will splatter D:over the monster who triggers the trap. N:561:& Stone and Hide Armour~ G:(:U I:36:15:0 W:35:0:200:500 A:35/7 P:15:1d1:-1:0:0 D:A primitive armour made from a thick hide reinforced by stone shards. ### Trapping Kits N:562:Magic G:`:g I:46:5:0 W:5:0:20:50 A:5/2:40/2 F:IGNORE_ACID | IGNORE_FIRE | IGNORE_COLD | IGNORE_ELEC D:It must be loaded with scrolls, which will release D:their spells at the monster who triggers the trap. N:563:Device G:`:v I:46:6:0 W:20:0:20:50 A:20/2:40/2:60/2 F:IGNORE_ACID | IGNORE_FIRE | IGNORE_COLD | IGNORE_ELEC D:It must be loaded with a magic device (wand, staff, or rod), which D:will fire its spell at the monster who triggers the trap. N:564:Nothing G:?:d I:70:53:0 W:1:0:5:2 A:1/1 P:0:1d1:0:0:0 N:565:Poison G:*:G I:4:1:5 W:0:0:4:2 A:0/1 P:0:1d1:0:0:0 # wand N:566:Nothing G:-:d I:65:2:-1:SPELL=Nothing W:2:0:10:20 A:2/1 P:0:1d1:0:0:0 F:NO_RECHARGE | SPECIAL_GENE N:567:Nothing G:=:d I:45:50:0 W:5:0:2:20 A:5/1 P:0:1d1:0:0:0 N:568:Nothing G:_:d I:55:30:0 W:5:0:50:50 A:5/1 P:0:1d1:0:0:0 F:NO_RECHARGE | SPECIAL_GENE N:569:Nothing G:-:d I:66:0:1 W:5:0:10:50 A:5/1 P:0:1d1:0:0:0 # Here comes the Essences (randomly interspersed with other stuff...) N:570:Explosion G:*:G I:4:2:50 W:0:0:4:2 A:0/1:20/1:40/1:60/1 P:0:1d1:0:0:0 N:571:Teleport G:*:G I:4:3:190 W:0:0:4:2 A:5/1:20/1:40/1:60/1 P:0:1d1:0:0:0 # Amulet of Nothing N:572:Nothing G:":d I:40:16:0 W:10:0:3:20 A:10/1 P:0:1d1:0:0:0 # An artifact potion! The Blood of Life... N:573:& Blood~ of Life G:!:d I:71:3:200 W:70:0:4:10000 A:70/16 P:0:1d1:0:0:0 T:71:2 F:NORM_ART | FULL_NAME D:Quaffing this measure of living blood will imbue your body and soul D:with the power to escape death one time. N:574:Cold G:*:G I:4:4:200 W:0:0:4:2 A:5/1:20/1:40/1:60/1 P:0:1d1:0:0:0 N:575:Fire G:*:G I:4:5:200 W:0:0:4:2 A:5/1:20/1:40/1:60/1 P:0:1d1:0:0:0 N:576:Acid G:*:G I:4:6:200 W:0:0:4:2 A:6/1:20/1:40/1:60/1 P:0:1d1:0:0:0 # Mage staffs (for Sorcerers to wield.) N:577:& Mage Staff~ G:\:B I:6:1:0 W:5:0:12:300 A:5/1:20/1:50/1:80/1 P:0:1d4:0:0:0 F:SHOW_MODS | COULD2H f:COULD2H D:It looks like a simple walking stick, plain and nondescript. D:In the hands of a spellcaster, it can be a deadly weapon. # An extra ring, out of place N:578:Lightning G:=:d I:45:56:0 W:50:0:2:3000 A:50/1 P:0:0d0:0:0:15 a:HARDCORE=BA_ELEC_4 F:RES_ELEC | IGNORE_ELEC | ACTIVATE f:RES_ELEC | D:This sparkling circlet grants you protection, makes electricity less D:dangerous and even allows you to call forth a ball of lightning. # More essences N:579:Life G:*:G I:4:7:300 W:0:0:4:2 A:0/1:20/1:40/1:60/1 P:0:1d1:0:0:0 N:580:Confusion G:*:G I:4:8:100 W:0:0:4:2 A:0/1:20/1:40/1:60/1 P:0:1d1:0:0:0 N:581:Light G:*:G I:4:9:60 W:0:0:4:2 A:0/1:20/1:40/1:60/1 P:0:1d1:0:0:0 # The Ring of Flare -- see artifact list N:582:& Ring~ G:=:y I:45:52:5 W:50:25:2:75000 F:INSTA_ART # Potion of Invisibility N:583:Invisibility G:!:d I:71:8:0 W:3:0:4:50 A:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This magical brew will temporarily hide you from sight, and also attunes you D:to this state so that your eyes can still perceive your hidden form. N:584:Chaos G:*:G I:4:10:200 W:20:0:4:2 A:20/1 P:0:1d1:0:0:0 F:ATTR_MULTI # Potion of Corruption N:585:Corruption G:!:d I:71:10:0 W:3:0:4:0 A:20/1:30/1:40/1 P:0:1d1:0:0:0 F:FOUNTAIN D:This concoction of toxic wastes will strangely warp your shape. # Ring of Invisibility N:586:Invisibility G:=:d I:45:53:4 W:50:0:2:10000 A:50/1 F:INVIS | HIDE_TYPE f:INVIS | D:This magical bauble will hide you from sight. ### Just another essence, to confuse the edit file hackers ;) ### N:587:Time G:*:G I:4:11:600 W:20:0:4:2 A:20/1:40/1:60/1 P:0:1d1:0:0:0 ######### Here are the parchments ######## N:588:Deep Thoughts G:?:o I:8:0:0 W:3:0:5:50 A:3/1 D:This parchment contains the thoughts of a powerful D:wizard who departed Middle-earth long ago. N:589:More Deep Thoughts G:?:o I:8:1:0 W:4:0:5:50 A:4/1 D:This parchment contains the thoughts of a powerful D:wizard who departed Middle-earth long ago. N:590:Compendium of Deep Thoughts G:?:o I:8:2:0 W:5:0:5:50 A:5/1 D:This parchment contains the thoughts of a powerful D:wizard who departed Middle-earth long ago. N:591:Artifact Lore Vol. I G:?:o I:8:6:0 W:40:0:5:50 A:40/3 D:This parchment contains information about unique D:artifacts that are rumoured to exist upon Arda. N:592:Artifact Lore Vol. II G:?:o I:8:7:0 W:40:0:5:50 A:40/3 D:This parchment contains information about unique D:artifacts that are rumoured to exist upon Arda. N:593:Artifact Lore Vol. III G:?:o I:8:8:0 W:40:0:5:50 A:40/3 D:This parchment contains information about unique D:artifacts that are rumoured to exist upon Arda. N:594:Monstrous Compendium 1 G:?:o I:8:9:0 W:10:0:5:50 A:10/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:595:Monstrous Compendium 2 G:?:o I:8:10:0 W:11:0:5:50 A:11/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:596:Monstrous Compendium 3 G:?:o I:8:11:0 W:12:0:5:50 A:12/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:597:Monstrous Compendium 4 G:?:o I:8:12:0 W:13:0:5:50 A:13/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:598:Monstrous Compendium 5 G:?:o I:8:13:0 W:14:0:5:50 A:14/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:599:Monstrous Compendium 6 G:?:o I:8:14:0 W:15:0:5:50 A:15/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:600:Monstrous Compendium 7 G:?:o I:8:15:0 W:16:0:5:50 A:16/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:601:Monstrous Compendium 8 G:?:o I:8:16:0 W:17:0:5:50 A:17/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:602:Monstrous Compendium 9 G:?:o I:8:17:0 W:18:0:5:50 A:18/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:603:Monstrous Compendium 10 G:?:o I:8:18:0 W:19:0:5:50 A:19/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. N:604:Monstrous Compendium 11 G:?:o I:8:19:0 W:20:0:5:50 A:20/2 D:This parchment contains a small part of the collected D:lore concerning monsters inhabiting Arda. #### Here come the shape-shifting potions. #### N:605:& Morphic Oil~ of # G:!:d I:72:1:0 W:5:0:4:100 A:1/3:5/1:10/1 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:This concoction can transform your body for a short period of time. # XXX 606 -> 617 # The Mimic's cloaks N:618:& #~ G:(:y I:35:100:0:50 W:5:130:30:100 A:5/1:15/1:35/1:55/1:75/1 P:1:1d1:0:0:0 D:Combined with proper skill, this cloak can make you seem D:like a different creature. Otherwise, it just provides some D:extra protection. # XXX 619 -> 639 # One more essence... N:640:Magic G:*:G I:4:12:700 W:20:0:4:2 A:30/1:50/1:80/1 P:0:1d1:0:0:0 # Here are the corpses N:641:corpse G:~:U I:9:1:3000 W:20:0:80:0 A:30/1 P:0:1d1:0:0:0 F:DECAY D:Whatever happened with this one, it wasn't pretty. N:642:skeleton G:~:U I:9:2:800 W:20:0:2:0 A:30/1 P:0:1d1:0:0:0 D:The sorry, bony remains of some hapless creature. N:643:head G:~:U I:9:3:600 W:20:0:10:0 A:30/1 P:0:1d1:0:0:0 F:DECAY D:2 eyes, 2 ears, a mouth, some hair -- yep, that's a head. N:644:skull G:~:U I:9:4:1000 W:20:0:20:0 A:30/1 P:0:1d1:0:0:0 D:It's a white bony skull, smiling to you without teeth. N:645:raw meat G:~:U I:9:5:1200 W:20:0:10:2 A:30/1 P:0:1d1:0:0:0 F:DECAY D:Yuck, just looking at it makes your stomach upset. # New armour: Thunderlord Coat. (With two low resists, it shouldn't be # at only 5th level. Make it 25th. -JLE...) N:646:& Thunderlord Coat~ G:(:y I:36:16:0 W:5:0:60:400 A:25/1 P:9:1d1:0:0:0 F:RES_FIRE | RES_COLD | D:This suit of thick impregnated cloth is worn by the riders of flying steeds, D:and protects them from extremes of temperatures. # The Stone of Lore -- see artifact list N:647:& Stone~ G:~:g I:39:106:0 W:15:0:15:20000 F:INSTA_ART | SPECIAL_GENE # Here are the boomerangs N:648:& Small Wooden Boomerang~ G:{:y I:15:1:0 W:1:0:60:10 A:1/1:5/2:10/2:20/2 P:0:1d4:0:0:0 D:A small curved piece of wood. N:649:& Wooden Boomerang~ G:{:y I:15:2:0 W:10:0:60:100 A:10/1:20/2 P:0:1d8:0:0:0 D:A strange, curved leaf-shaped piece of wood. N:650:& Small Metal Boomerang~ G:{:y I:15:3:0 W:20:0:60:400 A:20/1:30/2 P:0:3d4:0:0:0 D:A short boomerang with metal blades on the "forward" edges. N:651:& Metal Boomerang~ G:{:y I:15:4:0 W:30:0:60:800 A:30/1:50/2 P:0:4d5:0:0:0 D:A strange curved leaf-shaped piece of wood, its "forward" edges enhanced with metal blades. # The Space-Time Anchor -- see artifact list N:652:& Anchor~ G:~:v I:39:105:0 W:30:0:15:50000 F:INSTA_ART # To convert monsters into objects for wielding them ! ! ! :) # Funny, funny, funny :) # pval the monster idx, pval2 for the monster hp N:653:& ~ G:~:y I:99:1:0 W:127:200:60:0 A:127/255 P:0:0d0:0:0:0 N:654:Summon Never-Moving Pet G:?:d I:70:6:0 W:5:0:5:125 A:5/1:15/1:25/1:35/1:65/1:85/1:95/1 D:A piece of paper, inscribed with runes which will summon an immobile creature to your aid. # XXX # XXX ###The potions of cure insanity, in light, medium, regular, and full ###versions. Cure light's W:x entry reduced to 1, so it doesn't boost level rating when appearing ###at 50' - nyra N:657:Cure Light Insanity G:!:d I:72:14:0 W:1:5:4:15 A:5/1:1/1:3/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A magical potion which drives away irrational quirks of behaviour. N:658:Cure Serious Insanity G:!:d I:72:15:0 W:10:5:4:40 A:10/1 P:0:1d1:0:0:0 F:FOUNTAIN D:A magical brew which will lift shadows that have been cast on your soul. N:659:Cure Critical Insanity G:!:d I:72:16:0 W:15:5:4:100 A:15/3 P:0:1d1:0:0:0 F:FOUNTAIN D:This drink will cure you even of serious mental disorders. N:660:Cure Insanity G:!:d I:72:17:0 W:25:5:4:300 A:25/3 P:0:1d1:0:0:0 F:FOUNTAIN D:This blessed potion can make you completely sane and healthy, even if you have only the D:faintest shred of sanity left. # The Phial of Undeath -- see artifact list. He he he he... N:661:& Phial~ G:~:y I:39:103:0 W:1:0:10:0 P:0:1d1:0:0:0 F:INSTA_ART # Here is the random artifact type. # This is used as a template -- the sval will be chosen later # on in the game to be an index to the random_artifacts array, # which in turn determines: # # Name # Color # Level # Cost N:662:Random Artifact G:~:o I:102:0:0 W:1:0:50:0 A:1/1:10/1:20/1:30/1 F:INSTA_ART | ACTIVATE | ACTIVATE_NO_WIELD N:663:Craftsmanship G:?:d I:70:19:0 W:80:0:5:200000 A:80/16 D:A powerful scroll, desired by many, as it can magically improve the special powers of magical D:weaponry. # A Parchment, not the Artifact N:664:The One Ring G:?:s I:8:4:0 W:10:100:5:50 A:10/2 D:This parchment contains words in the Black Speech and Westron, D:and they seem to speak of a powerful Ring... could it be true? # XXX 665 - 668 were the old music books ### Musical Instruments ### N:669:& Horn~ G:/:W I:14:60:1 W:7:0:30:400 A:7/2:20/1:40/1:80/1 P:0:1d1:0:0:0 F:CON | ACTIVATE | WIELD_CAST D:A simple wind instrument made from brass. If used by inexperienced musicians it sounds D:like somebody making "prbbt!" noises down a drainpipe. N:670:& Drum~ G:/:W I:14:58:1 W:7:0:30:400 A:7/2:20/1:40/1:80/1 P:0:1d1:0:0:0 F:STR | WIELD_CAST D:A sort of clay pot with a bit of skin stretched over its mouth. N:671:& Harp~ G:/:W I:14:59:1 W:7:0:30:400 A:7/2:20/1:40/1:80/1 P:0:1d1:0:0:0 F:CHR | WIELD_CAST D:A number of strings held by a wooden frame. #N:672:& Banjo~ #G:/:W #I:14:2:0 #W:15:0:30:200 #A:15/1 #P:0:1d1:0:0:0 #D:A combination of kithara and tambourine. It looks strange and sounds bad. #N:673:& Lute~ #G:/:W #I:14:3:0 #W:20:0:30:200 #A:20/1 #P:0:1d1:0:0:0 #D:A string instrument, to be plucked with your fingers. #N:674:& Mandolin~ #G:/:W #I:14:4:0 #W:25:0:30:300 #A:25/1 #P:0:1d1:0:0:0 #D:A small string instrument, typically strummed with your fingers or a plectron. # The Palantir of Orthanc -- see artifact list N:675:& Palantir~ G:~:y I:39:104:0 W:75:0:200:100000 P:0:10d10:0:0:0 F:INSTA_ART ### The Monster Egg template; note the theoretical weight of 3 lbs ### N:676:Egg G:,:W I:10:1:0 W:5:0:30:100 A:5/1:15/1:25/1:35/1 P:0:1d1:0:0:0 F:ACTIVATE | ACTIVATE_NO_WIELD ### Two more scrolls ### N:677:Reset Recall G:?:d I:70:23:0 W:20:0:5:125 A:20/1:25/1:35/1 D:A strange formula is inscribed on this scroll, which allows you to define another place as the D:location to which recalls shall move you. N:678:Divination G:?:d I:70:31:0 W:20:0:5:600 A:30/1:45/1:55/1 D:This scroll is inscribed with a ritual which allows you to discern what fate holds in store for D:you. ### Here comes the Runes ### N:679:Self G:?:b I:105:0:0 W:3:5:2:40 A:3/1 P:0:1d1:0:0:0 N:680:Ray G:?:b I:105:2:0 W:10:5:2:300 A:10/1 P:0:1d1:0:0:0 F:IGNORE_COLD | IGNORE_ELEC N:681:Sphere G:?:b I:105:3:0 W:15:5:2:1000 A:15/1 P:0:1d1:0:0:0 F:IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD N:682:Knowledge G:?:b I:104:91:0 W:6:5:2:200 A:6/1 P:0:1d1:0:0:0 N:683:Life G:?:D I:104:53:0 W:3:5:2:200 A:3/1 P:0:1d1:0:0:0 N:684:Fire G:?:r I:104:5:0 W:10:5:2:300 A:10/1 P:0:1d1:0:0:0 F:IGNORE_FIRE N:685:Cold G:?:b I:104:4:0 W:12:5:2:300 A:12/1 P:0:1d1:0:0:0 F:IGNORE_COLD N:686:Lightning G:?:W I:104:1:0 W:13:5:2:300 A:13/1 P:0:1d1:0:0:0 F:IGNORE_ELEC N:687:Acid G:?:B I:104:3:0 W:16:5:2:300 A:16/1 P:0:1d1:0:0:0 F:IGNORE_ACID N:688:Element G:?:g I:104:10:0 W:23:5:2:1000 A:23/1 P:0:1d1:0:0:0 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD N:689:Chaos G:?:v I:104:30:0 W:26:5:2:2000 A:26/1 P:0:1d1:0:0:0 F:ATTR_MULTI F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD N:690:Mind G:?:D I:104:85:0 W:19:5:2:3000 A:19/1 P:0:1d1:0:0:0 F:IGNORE_ELEC N:691:Holding G:?:B I:104:75:0 W:5:5:2:500 A:5/1 P:0:1d1:0:0:0 F:IGNORE_ACID N:692:Arrow G:?:b I:105:1:0 W:6:5:2:100 A:6/1 P:0:1d1:0:0:0 F:IGNORE_ELEC N:693:Power Surge G:?:b I:105:4:0 W:50:5:2:5000 A:50/1 P:0:1d1:0:0:0 F:IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | IGNORE_ACID N:694:Armageddon G:?:b I:105:5:0 W:30:5:2:4000 A:30/1 P:0:1d1:0:0:0 F:IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | IGNORE_ACID N:695:Gravity G:?:G I:104:35:0 W:16:5:2:300 A:16/1 P:0:1d1:0:0:0 F:IGNORE_ACID # And, among the runes, one more essence... N:696:Extra Life G:*:G I:4:13:900 W:50:0:4:2 A:50/1:70/1:90/1 P:0:1d1:0:0:0 # Now, the rest of the runes... N:697:Undeath G:?:G I:104:92:0 W:35:5:2:1000 A:35/1 P:0:1d1:0:0:0 F:IGNORE_ACID N:698:Protection G:?:G I:104:74:0 W:45:5:2:1500 A:45/1 P:0:1d1:0:0:0 F:IGNORE_ACID # XXX # The Ring of Precognition (now a k_info.txt artifact) N:700:& Ring~ of Precognition G:=:d I:45:51:0 W:90:0:2:300000 A:90/100 T:45:23 F:PRECOGNITION | f:PRECOGNITION | F:NORM_ART | FULL_NAME F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:This magical ring allows you to know what you will encounter in the near future. # Athelas, cures Black Breath N:701:& Sprig~ of Athelas G:,:g I:80:40:0 W:25:5:2:450 A:25/2:55/1:85/1 D:'When the black breath blows / And death's shadow grows / D:And all lights pass / Come Athelas! Come Athelas! / D:Life to the dying / In the King's hands lying.' # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # The Scroll of Deincarnation (now an artifact) N:720:& Old Scroll~ of Deincarnation G:?:d I:70:40:0 W:90:0:5:160000 A:90/140 T:70:51 F:NORM_ART | FULL_NAME F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD D:It allows you to leave your body to reincarnate into D:another one, however, your current body is lost in the process. N:721:& Dark Sword~ G:|:D I:23:33:0 W:25:0:70:500 A:25/1:80/2 P:0:3d7:0:0:0 F:SHOW_MODS | ANTIMAGIC_50 f:ANTIMAGIC_50 D:A strange, very sharp long sword, which seems to drain light from its surroundings. As you D:wield it, you feel much less attuned to magic. N:722:Numenorean for Beginners (I) G:?:s I:8:101:0 W:10:100:5:50 A:10/2 D:These ancient words still contain magic. N:723:Numenorean for Beginners (II) G:?:s I:8:102:0 W:5:100:5:50 A:5/2 D:These ancient words still contain magic. N:724:Advanced Lessons of Numenorean G:?:s I:8:103:0 W:20:100:5:50 A:20/2 D:These ancient words still contain magic. N:725:Advanced Lessons of Sindarin G:?:s I:8:104:0 W:20:100:5:50 A:20/2 D:These ancient words still contain magic. ##### Junk ##### N:726:& Shard~ of Pottery G:~:r I:11:3:0 W:0:0:5:0 A:0/1 P:0:1d1:0:0:0 F:EASY_KNOW D:Half a clay jar -- how many failed artists have taken refuge in these dungeons? N:727:& Broken Stick~ G:~:r I:11:6:0 W:0:0:3:0 A:0/1 P:0:1d1:0:0:0 F:EASY_KNOW D:A piece of rotten wood. # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX # XXX N:738:& Book~ of Beginner Cantrips G:?:w I:111:50:0 W:5:0:30:100 A:5/1 P:0:1d1:0:0:0 D:The blood smudged on the cover makes you wonder how many people had it before you... N:739:& Book~ of Teleportation G:?:w I:111:51:0 W:10:0:30:1000 A:10/1 P:0:1d1:0:0:0 D:A standard spellbook with a few spells. # XXX N:741:& Book~ of Summoning G:?:w I:111:52:0 W:7:0:30:700 A:7/1 P:0:1d1:0:0:0 D:A standard spellbook with a few spells. D:It smells like camel. # XXX # The Potion of Learning - another artifact! N:743:& Potion~ of Learning G:!:d I:71:12:200 W:90:0:4:100000 A:90/25 P:0:1d1:0:0:0 T:71:49 F:NORM_ART | FULL_NAME F:IGNORE_ACID | IGNORE_FIRE | IGNORE_COLD | IGNORE_ELEC D:This old potion is supposed to grant more learning power D:to its user. # XXX # XXX # XXX # XXX # XXX # XXX # XXX N:751:Khuzdul - The Hidden Tongue of the Dwarves G:?:s I:8:105:0 W:2:100:5:50 A:2/2 D:These ancient words still contain magic. N:752:Nandorin for Dummies G:?:s I:8:106:0 W:20:100:5:50 A:20/2 D:These ancient words still contain magic. N:753:Advanced Lessons of Orcish G:?:s I:8:107:0 W:30:100:5:50 A:30/2 D:These ancient words still contain magic. # Here's the Ring of Flying N:755:Flying G:=:d I:45:54:0 W:20:0:2:16000 A:20/3 F:FLY | EASY_KNOW f:FLY | D:This ring is imbued with the power of eagles. It grants you the power of flight. N:756:& Tome~ of the Time G:?:b I:111:8:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:This tome seems to have trouble deciding whether it really exists now. Its flickering pages D:contain all that is known about the currents of time. N:757:& Spellbook~ of # G:?:w I:111:255:0 W:10:0:30:200 A:10/1:20/1:30/1:40/1:50/1:60/1:70/1 P:0:1d1:0:0:0 D:This book contains a single spell within its pages. N:758:& Tome~ of Meta Spells G:?:v I:111:9:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW | IGNORE_FIRE | ATTR_MULTI D:This tome gives you deeper insights on the works of magic. N:759:& Tome~ of the Mind G:?:B I:111:10:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:This tome has no pages; knowledge is transferred to you if you simply D:hold it. N:760:& Holy Tome~ of Eru Iluvatar G:?:G I:111:20:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:This dusty tome is filled with ancient rituals, D:designed to uncover all that is hidden. N:761:& Holy Tome~ of Manwe Sulimo G:?:B I:111:21:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:A large jewel-encrusted tome that transfers D:wisdom and understanding to its wearer. N:762:& War Tome~ of Tulkas G:?:R I:111:22:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:This tome fills you with glorious visions of total devastation. D:Anyone in your way shall be destroyed. N:763:& Unholy Tome~ of the Hellflame G:?:v I:111:11:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW | ATTR_MULTI D:This singed book smells like burned flesh. Its power is as evident D:as its thirst for your blood. N:764:& Corrupted Tome~ of Melkor G:?:D I:111:23:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW D:A black and scarlet flame springs from this tome, issuing D:a thunderous roar under which you think you hear the screams of tormented souls. N:768:& Forest Tome~ of Yavanna G:?:G I:111:24:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW # for the Library Quest # Tome of PLAYER N:769:Tome of# G:?:v I:111:61:0 W:50:0:30:25000 A:50/4 P:0:1d1:0:0:0 F:FULL_NAME | EASY_KNOW | ATTR_MULTI | SPECIAL_GENE F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | NORM_ART D:This book has some of your favourite spells inside. # The Ring of Phasing -- see artifact list N:770:& Ring~ G:=:d I:45:55:0 W:110:0:2:300000 A:110/5 F:INSTA_ART | SPECIAL_GENE N:771:[Earth] G:?:R I:114:0:0 W:10:0:30:100 A:10/1 P:0:1d1:0:0:0 F:SPECIAL_GENE D:A heavy lump of rock. As you touch it, you think you can see into the earth and perceive its D:secrets. N:772:[Fire] G:?:R I:114:1:0 W:20:0:30:1000 A:20/1 P:0:1d1:0:0:0 F:SPECIAL_GENE D:A bright red crystal, filled with a liquid flame that scorches you even though the surface of D:the gem is cool to the touch. N:773:[Air] G:?:r I:114:2:0 W:50:0:30:2500 A:50/1 P:0:1d1:0:0:0 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:SPECIAL_GENE D:A completely translucent gem; as you behold it, you hear a great wind and feel like you're D:about to take off and fly away. N:774:[Water] G:?:r I:114:3:0 W:70:0:30:50000 A:70/3 P:0:1d1:0:0:0 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:SPECIAL_GENE D:A large gem, filled with dark blue water. It feels strangely heavy and cold. N:775:[Mana] G:?:r I:114:4:0 W:100:0:30:100000 A:100/3 P:0:1d1:0:0:0 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:SPECIAL_GENE D:A large gem that seems somehow immaterial and is filled with a strange insubstantial... power? # Rod Tip of Home Summoning: now an artifact #N:776:& Great Rod Tip~ of Home Summoning N:776:Home Summoning G:-:d I:66:30:75 W:90:0:15:150000 A:100/14 P:0:1d1:0:0:0 T:66:1 F:NORM_ART | FULL_NAME F:IGNORE_FIRE | IGNORE_ACID | IGNORE_COLD | IGNORE_ELEC D:This rod creates a little hatch, allowing access to your home, no matter how far away the abode D:is. # Additional swords N:777:& Shadow Blade~ G:|:D I:23:32:1 W:50:900:45:2000 A:48/4:60/2:80/1 P:0:4d4:-2:2:0 F:IGNORE_ACID | RES_DARK | STEALTH f:STEALTH D:A thin long sword made of a completely black metal, which reflects no light. N:778:& Bluesteel Blade~ G:|:b I:23:31:0 W:60:1800:50:6000 A:60/20 P:0:1d6:4:0:0 F:SHOW_MODS | VORPAL D:A small sword made of a blueish metal with a strangely rough surface. As anything is hurt D:with it, the weapon will stick inside the wound and cause horrible wounds when torn away. # Amulet N:779:the Serpents G:":G I:40:17:0 W:25:0:3:10000 A:25/1 a:HARDCORE=BA_POIS_4 F:RES_POIS | DEX | ACTIVATE D:A petrified serpent's tongue, hung on a thin chain to be clasped around your neck. It makes you D:like unto snakes, able to wriggle out of tight corners, impervious to poisons and poisonous D:yourself. # Here comes the new Essences N:780:Darkness G:*:G I:4:14:20 W:0:0:4:1 A:0/1:20/1:40/1 P:0:1d1:0:0:0 D:It's a gem that eats all light that reaches it. It's perfectly black. N:781:Knowledge G:*:G I:4:15:100 W:0:0:4:1 A:20/1:30/1:70/1 P:0:1d1:0:0:0 D:It's a blue gem with countless formulae scribbled on it. N:782:Force G:*:G I:4:16:180 W:0:0:4:1 A:10/1:40/1 P:0:1d1:0:0:0 D:It's a green gem that can barely contain the forces in it. N:783:Lightning G:*:G I:4:17:200 W:0:0:4:1 A:28/1 P:0:1d1:0:0:0 D:It's a white gem. Inside you see lightning rage. N:784:Mana G:*:G I:4:18:400 W:0:0:4:1 A:45/2 P:0:1d1:0:0:0 D:It's an everchanging gem. You feel the magic throbbing through it. # The Nine Rings for mortal men doomed to die! When a Nazgul is # destroyed, it drops a Ring of Power with random powers. N:785:Ring~ of Power G:=:d I:45:5:0 W:100:0:2:1 A:100/100 F:INVIS | DRAIN_EXP | CURSED | HEAVY_CURSE | CURSE_NO_DROP f:INVIS F:SPECIAL_GENE | FULL_NAME # To help people climb mountains... N:786:& Climbing Set~ G:`:B I:12:0:0 W:40:0:2:50000 A:40/3 F:CLIMB f:CLIMB D:A bunch of screws and hooks, a small pick and a very long rope. As long as a wall or rock face D:isn't really high, this collection of tools should help you across it. # Parchment to help beginners N:787:Adventurer's Guide to Middle-earth G:?:o I:8:20:0 W:0:0:5:1 A:0/1 D:Read it! ### Demonblades ### N:788:& Demonblade~ G:|:R I:115:55:0 W:10:0:150:500 A:10/1 P:0:4d6:0:0:0 F:SHOW_MODS | SLAY_DEMON | WIELD_CAST D:This blade has been taken from the corpse of a demon. D:Some demonic energy is still coursing through it, helping D:you slay other demons. N:789:& Demonshield~ G:]:R I:115:56:0 W:15:0:70:500 A:15/1 P:5:1d1:0:0:0 F:REGEN | WIELD_CAST D:This shield has been taken from the corpse of a demon. D:Some demonic energy is still coursing through it, giving D:life to any that wield it. N:790:& Demonhorn~ G:[:R I:115:57:0 W:20:0:30:500 A:20/1 P:2:1d1:0:0:0 F:LITE2 | WIELD_CAST D:This horn is about six feet long. Just looking at it makes you nervous. # XXX # XXX ### Rods ### N:793:& Wooden Rod~ of# G:-:u I:67:10:0 W:10:0:15:100 A:5/1:10/1 P:0:1d1:0:0:0 D:The most common rod of all. It's the wood of oak, cut at midnight by a fair maiden. N:794:& Copper Rod~ of# G:-:s I:67:20:0 W:15:0:15:200 A:15/1 P:0:1d1:0:0:0 D:This is the common rod of the dwarves. It is created by chanting incessantly for 48 hours. N:795:& Iron Rod~ of# G:-:D I:67:50:0 W:20:0:15:500 A:20/1 P:0:1d1:0:0:0 D:This is the better version of the copper rod. It has been forged with iron that comes from D:the greatest deeps, where even the dwarves fear to go. # Aluminium only exists since 30 years N:796:& Moonstone Rod~ of# G:-:U I:67:75:0 W:25:0:15:750 A:25/1 P:0:1d1:0:0:0 D:This rod has been fashioned from moonrock. Its alien nature gives it quite a bit of capacity. N:797:& Silver Rod~ of# G:-:s I:67:100:0 W:30:0:15:1000 A:30/1 P:0:1d1:0:0:0 D:This rod is used often used by court mages. Its creation costs an insane amount D:of gold but it is still lesser than a Golden Rod. N:798:& Golden Rod~ of# G:-:y I:67:125:0 W:40:0:15:1250 A:40/2 P:0:1d1:0:0:0 D:These rods are rare, since finding gold that can withstand the great magic D:capacity that this rod holds is very difficult. N:799:& Mithril Rod~ of# G:-:B I:67:160:0 W:50:0:15:1600 A:50/5 P:0:1d1:0:0:0 D:The mithril of this rod comes from very deep, too deep. Unknown powers have been D:infused in this rod, making it the second most powerful type of rod on Middle-earth. N:800:& Adamantite Rod~ of# G:-:v I:67:200:0 W:60:0:15:2000 A:60/10 P:0:1d1:0:0:0 D:This is the rarest and most powerful kind of rod there is. Treasure it! # Greater Ration of Health - artifact food item (!) N:801:& Greater Ration~ of Health G:,:g I:80:41:0 W:90:5:2:60000 A:90/50 T:80:40 F:NORM_ART | FULL_NAME D:This food will, once eaten, permanently add 70 HP. # Scroll of Mass Resurrection - artifact scroll N:802:& Crumpled Scroll~ of Mass Resurrection G:?:d I:70:43:0 W:55:0:5:0 A:55/1 T:70:1 F:NORM_ART | FULL_NAME F:IGNORE_FIRE | IGNORE_ACID | IGNORE_COLD | IGNORE_ELEC D:This magical scroll sends a call to the halls of Mandos, issuing forth all those who have been D:slain by the reader. ### Axes ### N:803:& Cleaver~ G:/:s I:24:2:0 W:13:0:110:175 A:13/1 P:0:2d4:0:0:0 F:SHOW_MODS D:A small axe with a heavy rectangular blade. N:804:& Light War Axe~ G:/:s I:24:8:0 W:16:0:140:300 A:16/1 P:0:2d5:0:0:0 F:SHOW_MODS D:A broad-bladed axe, suited for battle. N:805:& Slaughter Axe~ G:/:G I:24:30:0 W:70:0:300:6000 A:70/8 P:0:5d7:0:0:0 F:SLAY_ANIMAL | SHOW_MODS D:A huge axe, the sort used for slaughtering animals, this weapon is unusually deadly against D:natural creatures. N:806:& Runestone~ G:?:v I:105:255:0 W:10:5:2:300 A:10/3:20/2:30/1:60/1 P:0:1d1:0:0:0 F:IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | IGNORE_ACID D:A small oval stone. One surface is flat, as if something ought to be scratched or inscribed into D:it. N:807:& Fortune cookie~ G:,:U I:80:42:500 W:0:0:2:10 A:0/1:5/1:10/1 D:A small, sweet bakery product, with a scrap of paper inside. # XXX was the Portable Hole N:809:Critical Hits G:=:d I:45:59:0 W:50:0:2:10000 A:50/3 F:CRIT f:CRIT D:A magical ring to make it likelier for the wearer to hit exceptionally heavily. # The Wand of Stone to Mud of Thrain N:810:& Wand~ of Digging of Thrain G:-:d I:65:26:-1:SPELL=Dig W:10:10:10:3200 A:10/200 P:0:10d10:0:0:0 T:65:6 F:RECHARGE | SPECIAL_GENE | EASY_USE | RECHARGED | NORM_ART | FULL_NAME D:The miner's friend. This wand was used by Thrain to dig into the D:walls of the dungeon. Its indestructible nature makes it quite useful. # The Staff of Holy Fire of Mithrandir N:811:& Gnarled Staff~ of Holy Fire of Mithrandir G:_:d I:55:22:-1:SPELL=Holy Fire of Mithrandir W:50:10:10:12000 P:0:10d4:0:0:0 A:50/200 T:55:8 F:RECHARGE | EASY_USE | RECHARGED | NORM_ART | FULL_NAME D:Mithrandir's staff that throws powerful fire attacks at all enemies. It D:can be recharged without blowing up, for it is built to hold D:much magical energy. ### Summoner totems ### N:812:Partial Totem G:":v I:54:1:0 W:10:10:10:120 P:0:1d1:0:0:0 A:10/200 F:SPECIAL_GENE D:An item which a Summoner can use to animate a copy of a creature that D:only exists by the will of its master. N:813:True Totem G:":v I:54:2:0 W:10:10:10:120 P:0:1d1:0:0:0 A:10/200 F:SPECIAL_GENE D:An item which a Summoner can use to revive a true copy of a creature. ### Holy relics for God Quests ### N:814:& Piece~ of the Relic of Eru G:~:v I:11:7:0 W:0:0:0:1000 A:0/1 P:0:1d1:0:0:0 F:SPECIAL_GENE | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | IGNORE_ACID D:Although it looks like a piece of junk, it is actually part of an ancient D:relic belonging to Priests of Eru. The relic now lies in pieces, hidden D:from all but but his most dedicated followers. N:815:& Piece~ of the Relic of Manwe G:~:v I:11:8:0 W:0:0:0:1000 A:0/1 P:0:1d1:0:0:0 F:SPECIAL_GENE | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | IGNORE_ACID D:Although it looks like a piece of junk, it is actually part of an ancient D:relic belonging to Priests of Manwe. The relic now lies in pieces, hidden D:from all but his most dedicated followers. N:816:& Piece~ of the Relic of Tulkas G:~:v I:11:9:0 W:0:0:0:1000 A:0/1 P:0:1d1:0:0:0 F:SPECIAL_GENE | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | IGNORE_ACID D:Although it looks like a piece of junk, it is actually part of an ancient D:relic belonging to worshippers of Tulkas. The relic now lies in pieces, D:hidden from all but his most dedicated followers. N:817:& Piece~ of the Relic of Melkor G:~:v I:11:10:0 W:0:0:0:1000 A:0/1 P:0:1d1:0:0:0 F:SPECIAL_GENE | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | IGNORE_ACID D:Although it looks like a piece of junk, it is actually part of an ancient D:relic belonging to Dark Priests. The relic now lies in pieces, hidden D:from all but the most faithful followers of Melkor. N:818:& Piece~ of the Relic of Yavanna G:~:v I:11:11:0 W:0:0:0:1000 A:0/1 P:0:1d1:0:0:0 F:SPECIAL_GENE | IGNORE_COLD | IGNORE_ELEC | IGNORE_FIRE | IGNORE_ACID D:Although it looks like a piece of junk, it is actually part of an ancient D:relic belonging to Druids. The relic now lies in pieces, hidden D:from all but the most faithful followers of Yavanna. tome-235-src/lib/edit/dragons.map0000644000076400017500000000173411012107760014517 0ustar dgdg# permanent wall F:X:61:0 # Mountain Chain F:^:97:0 # granite F:#:57:0 # up staircase F:<:6:0 # Dirt F:.:88:0 # Dungeon layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^X D:X^^^^^.....................^^^^^X D:X^^^.........................^^^X D:X^^...........................^^X D:X^^...........................^^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^.............................^X D:X^^...........................^^X D:X^^...........................^^X D:X^^^........................<^^^X D:X^^^^^.....................^^^^^X D:X^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Starting position P:6:6 tome-235-src/lib/edit/w_info.txt0000644000076400017500000001722111012107760014403 0ustar dgdg# PernAngband wilderness definition file by DarkGod (darkgod@pernangband.org) # with the help form Gwidon S. Naskrent (naskrent@artemida.amu.edu.pl) # Designed to "look like" Middle-earth map W:D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX W:D:XgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggX W:D:XgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggX W:D:Xggggggggggg=========g=========gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggX W:D:Xgggggg========t===ggg==========gggggtggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggX W:D:Xggggg=========gtgg^g======ggg=gggggggggggtggtggggggggggggggggggggggggggggggggggggggggggggggggggggggX W:D:Xggg=========gg^t^^g========ggggt^g^ttggtgtgggggggggggggggggggggggggggggggggggggggggggggggggggggggggX W:D:X==========,,,,&__ttgg=ggg=ggggt^^%t^^^tg&ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggX W:D:X========..tt&&&^__,ttttttttttttt,gttttt&&&&ggtggggggggggtgggggtgggggggggggggggggtggggggggggggggtgggX W:D:X===^===....,&&&,t__,,,,,,g,t,,,,,,,,tttgt&^^&g&g&ggtggggggggggggggggtttggtgggggggtgggtgggggtgggggggX W:D:X=========.,.&&,,,,__t,,,,,t,,,,t,t,,,,,tttt&t&^MMM&ggggg&g&&&gggttttttgtttgttttttttttttttttttttttttX W:D:X=========.,.&&,,_,__,,,,,,,,,,,,,,,,,,,,,tttg...2Mt&&&&&&&t&t&&&&tgttttttttttttgtttttttttttttttttttX ?:[EQU $TOWN_DESTROY2 1] W:M:0:1 W:D:X=========.,.&&,,_,__,,,,,,,,,,,,,,,,,,,,,tttg...PMt&&&&&&&t&t&&&&tgttttttttttttgtttttttttttttttttttX ?:1 W:D:X========..T.&___.___,,^,,,,,,,,,,,,,,,,,,tttt.&MMM^^__t^&&&,t^^ttttt,t,t,ttttttttttttttttttttttttttX W:D:X======.,..__&&,,,,__,,^^,,,,,,,,,,,,,,,,,t....t&&t^^__^__&.&,&&&^^,,t,,,,,,,,t,t,t,ttttttttttttttttX W:D:X=====,..__.T&&..,,__,,^^,,,,.,,,^^,,,,,,,,^^^t^&&&&,__^__tTTT,,,,,,,,,,,,t,,,,,,,,,,,,,t,ttttttttttX W:D:X===....__.,.&&,.,,__,,_^,,,,,,,,^^,,,,,,,,^^,^^^_&_^^__TT__T_TT,,&_,,,,,,,,,,,,,^,^,t,,,,,,t,ttttttX W:D:X===..,.__.TT&&..,__,__^^==,,.,^^,,.,,.,,,,^^____^&&___,TTTT_T__,,__,,,,^^,^^^^^^^^,,,,,t,,,,,,,,,,tX W:D:X===....__..T&&....__,^^=,__....,.....,,.,,^__^^,^&&,__,TTTTT__T_==,,,,,,,^_,,^,,,,,,,,,,,,,,t,t,,,,X W:D:X===...__..TT&&...__,.^^^..__.........,,,,,__^^^^^&&,__,TTTTTT_TT_=,,,,,,,__,,,,,,,,,,,,,,,,,,,,,,t,X W:D:X===...__..TT&&&..__..^..,.__...,..^..,,,,__^.^^^^&&,__,TTTTT&T&T__,,,,,,,,,__,,,,,,,,,,,,,,,,,,,,,,X W:D:X===....==..T.&..__..,.....__TTT....^^...__..TTT._&&..__,TTT&T&T&T__,,,,,,,,,__,,,,,,,,,,,,,,,,,,,,,X W:D:X====...==.....==......^...__TTTT.1.^^..,__...T__&&...__.TTTTTTTTT__,,,,,,,,__,,,,,,,,,,,,,,,,,,,,,,X W:D:X=====..========...^.^......__TTT._.^....__..,__._&...__.TTTTTTTTTT,__,,,,,,,__,,,,,,,,,,,,,,,,,,,,,X W:D:X==============..............__TT........__..__^_&&..,.__.TTTTTTTTT,__,,,,,,,,__,,,,,,,,,,,,,,,,,,,,X W:D:X======..==....&&............__..^^^....__...__^&&.....__.*TTTTTTT,,,__,,,,,,__,,,,,,,,,,,,,,,,,,,,,X W:D:X======........&&......,.....__...^.^...__.__.^^&&..._.__.TTTTTTTT..,,______,__,,,,,,,,,,,,,,,,,,,,,X W:D:X======........&&............__.,......__..__.^^&&___.___.TTTTTTTT....,,.,,,__,,,,,,,,,,,,,,,,,,,,,,X W:D:X======........&&....^......__..........___...^^&&.....__.TTTTT.T.,.....,,,,,__,,,,,,,,,,,,,,,,,,,,,X W:D:X=======.....T&&&..^^^^....__..........__....^^&&^...,__...TTTT......,....,,,__,,,,,,,,,,,,,,,,,,,,,X W:D:X==========..T&&&T.......__..........__......^^&&&&^..__...TTTT...........,,,,__,,,_,,,,,,,T,T,,,,,,X W:D:X==========..TTT&&T&&...__........,___......^)^&&.&^.__.....TTTTTT....,.....,,__,__,_=,,,TTTTTT,,,,,X W:D:X==========...TT&TT..___.__.......__.@__..._^^^&&....__..TTTTTTTTTT...........,,_,.,,==...T=_TT,,,,,X W:D:X==========.....T.T.__.._........__..._____^___&__...__,TTTTTTTTTT...,..,..,....,,,,,========TT,,,,,X W:D:X===========.=......__.........__.........^^^&&&_T,T__,.TT&TTTTTTT..........,.,.....=========T,,,,,,X W:D:X================..__..........__,.......^.^M&&._T4T__..TTTTTTTTT......,......,.....=====..==,,,,,,,X W:D:X=================.==T....,...__.........^^^MM&,.TTT.__...TTTTT..........,..........========,,.,,,,,X W:D:X===================TT........__.........^^MMMTT.T.^.^__^^........,......,,......^^..=======,,,.,.,,X W:D:X===================T==......__......,...^^M)MTTTT^___^.__^.,....................^,..==...==..,,.,.,X W:D:X===================T==.....__...........^&MgMMTTTTT..___^^................,..,..^^.......=.....,.,,X W:D:X=====================.....__...,........^&M5MTTTTTT.^^^__.....,..,......,,,.....^^...,......,......X W:D:X=====================.....=_............&&MMMTTTTT..^^..__.,.........,.........,^^.......,.........X W:D:X======================...==........,....&&&&&T.._......__..,..................................,..,.X W:D:X=======================.===.............._&^.....__..,...__.....,.........,..,,,...,...,...........X W:D:X===========================..............__.......__....__......,.......,...........,..............X W:D:X==========================.........._._..__.......__...__^..^,..............................,..,...X W:D:X==========================...._.,.__._.___........__...^^_^^@.....,..,.....,.,,....,,....,.,.,.....X W:D:X==========================..__.__.___._..&&^^.....__...^^_^^_@..&.&.....,.......,....,.............X W:D:X============================....._..._.__.&&&.....__....__.@...&&DD&&....,..................,.,..,.X W:D:X===========================.............._&&&^^....__...___....&&D^^D&&.&.&.&.&.&.&.&.&^^^,,,,,,,,,X W:D:X===========================.......^.&.^^&&&&&&&......______.....&&DDD&^&^&D&D&D&,&,&,&,,,,,,,,,,,,,X W:D:X===========================.....^^.&.&_&^&.&^&_&&&^...._.___....&&^DDD&^DDDDDD^&_,,,,,,,,,,,,,D,D,,X W:D:X===========================....^....__^^...^^^__^&&........__...&&^D&DDDDDDD^^,_,__,,,,,,,,,,,,,,,,X W:D:X===========================..^^^_..__......^^.__^^&&&........__.&&^DDDDDDDDD^^,,,,__,,,,,D,,,,,,,,,X W:D:X============================.^__.__.__......__&^^^.&&&&&&&&&..__&&^DDDDDDD^__,,,,,,__,,,,,,,DDDD,,,X W:D:X============================.&^__.._....^^.__&&&^^.._&&&&&&&.^__&^^DDDDD^^,,__,,,,,,__,,,,,,,,,,,,,X W:D:X============================^&^__.^^^^^^^^...__...__^&^&&&&&.__^&&^DDD^^^,,,,__,,,D,,__,,,,,,,D,,D,X W:D:X===========================.^^.__..^.^.........___..^&^^.^^3.__.&&^D^D^^,,,,__,,D,,,D,__,,,D,,,,,,,X W:D:X==========================.^^^..__....===.====__..&^...._^...__.&&,^,^,,,,,,,____,,,,,__,,,,,,,,,,,X W:D:X==========================^^....__..===========.&&^....__....__.$&,,,,,,,,D,,,,,=_,,__,,,,,D,,D,D,,X W:D:X========================..^^=...=_.==========&^^^^.._.__....__..&&,,,,,,,,,,,,,,==__,,&,,,,,,,,,,,,X W:D:X======================^^.^=====.==============^^^._=._......__.._&&,,,,,,,,,======,,,,&&,,D,D,D,D,,X W:D:X==============================================.^^^==...._.__..__.&&,,,___,_======,D,,&&,D,,,D,,,DD,X W:D:X===============================================..====___.__.__...&&,__,,D_,,D,,=_,,,D&&,D,DD,DDD,DDX W:D:X===============================================.==^==_@@..._.....&&_,,,,,,,,,,,__,&&&&DDDDDDDDD,,DDX W:D:X=================================================^^===...........&&,&,&,&,&,&,&__&&&DD,DD,DDD,D,,DDX W:D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Definition of all the entrances to the dungeons # W:E::: # Numenor W:E:7:25:1 # Path of the Dead W:E:16:49:38 # Illusory Castle W:E:17:34:42 # Maze W:E:18:25:35 # Orc Cave W:E:19:15:32 # Erebor W:E:20:17:77 # Old Forest W:E:21:21:31 # The Sacred Land Of Mountains W:E:25:37:80 # The Wild Land Of Rhun W:E:26:30:75 # The Sandworm Lair W:E:27:28:10 # The Grinding Ice W:E:29:3:3 # Dol Guldur W:E:23:30:60 # Cirith Ungol W:E:9:56:65 # Starting position W:P:34:21 tome-235-src/lib/edit/s_info.txt0000644000076400017500000002621711012107760014404 0ustar dgdg# File: s_info.txt # This file is used to initialize the "lib/data/s_info.raw" file, which is # used to initialize the "skills" information for the PernAngband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/data/s_info.raw" file. # The skill indexes are defined in "defines.h", and must not be changed. # N:idx:name # D:desc # A:action mkey:action desc # I:rate # E:exclusive skill:exclusive skill # O:skill:opposing skill%percent # A:skill:friendly skill%percent # T:father:child # Version stamp (required) V:2.0.0 ################################## MAGIC ################################## N:56:Magic-Device D:Eases the use of magical devices, such as wands, staves and rods D:It also helps pseudo-id of magic objects I:1000 F:RANDOM_GAIN N:54:Spell-learning D:You should not see that ! that is a BUG! #A:18:Learn a spell from a realm I:1000 F:HIDDEN N:41:Sorcery D:Ability to use all the magic schools as if their skill was sorcery D:But the price to channel that much magic is your health A:17:Cast a spell I:1000 N:1:Conveyance D:Ability to learn and use spells from the Conveyance school D:Spells use the intelligence stat A:17:Cast a spell I:1000 F:RANDOM_GAIN N:2:Mana D:Ability to learn and use spells from the Mana school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:3:Fire D:Ability to learn and use spells from the Fire school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:4:Air D:Ability to learn and use spells from the Air school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:5:Water D:Ability to learn and use spells from the Water school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:6:Nature D:Ability to learn and use spells from the Nature school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:7:Earth D:Ability to learn and use spells from the Earth school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:10:Divination D:Ability to learn and use spells from the Divination school D:Spells use the intelligence stat A:17:Cast a spell I:1000 F:RANDOM_GAIN N:11:Temporal D:Ability to learn and use spells from the Temporal school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:14:Meta D:Ability to learn and use spells from the Meta school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:51:Mind D:Ability to learn and use spells from the Mind school D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:55:Udun D:Ability to learn and use spells from the Udun school D:Spells use the intelligence stat A:17:Cast a spell I:1000 F:HIDDEN N:13:Demonology D:Ability to use incantations from the Demonblades D:Spells use the intelligence stat A:17:Cast a spell I:1000 N:31:Necromancy D:Ability to harness the powers of the dead D:Spells use the intelligence stat A:7:Use Necromancy I:1000 F:RANDOM_GAIN G:60 N:34:Runecraft D:Ability to combine magic runes to create your own spells D:Runespells use the dexterity stat A:9:Use Runespells I:1000 N:43:Thaumaturgy D:Ability to gain and cast innate spells D:Spells use the intelligence stat A:8:Cast a thaumaturgy spell I:1000 F:RANDOM_GAIN N:15:Magic D:General ability to do magic, also affects mana reserves and D:magic device ability. Helps pseudo-id of magic objects A:19:Copy a spell I:1000 F:RANDOM_GAIN N:45:Spell-power D:Ability to increase the power of spells I:1000 N:59:Geomancy D:Ability to understand the raw elemental forces of nature and use D:them to your advantage. Most spells need Fire/Water/Earth/Air skills A:101:Use Geomancy I:1000 # All magic skills affect magic skill f:Magic-Device:Magic%7 f:Spell-power:Magic%20 f:Sorcery:Magic%20 f:Mana:Magic%10 f:Fire:Magic%10 f:Air:Magic%10 f:Water:Magic%10 f:Earth:Magic%10 f:Geomancy:Fire%45 f:Geomancy:Earth%45 f:Geomancy:Air%45 f:Geomancy:Water%45 f:Conveyance:Magic%10 f:Divination:Magic%10 f:Nature:Magic%10 f:Temporal:Magic%10 f:Meta:Magic%10 f:Mind:Magic%10 f:Udun:Magic%10 f:Demonology:Magic%10 f:Necromancy:Magic%4 f:Runecraft:Magic%12 f:Thaumaturgy:Magic%6 ################################## COMBAT ################################## N:16:Combat D:General ability to fight and to pseudo-id armour and weapons D:It also allows the use of heavier armour without penalties I:1000 F:RANDOM_GAIN N:17:Weaponmastery D:General ability to use melee weapons I:1000 F:RANDOM_GAIN N:18:Sword-mastery D:Ability to use swords I:1000 N:19:Axe-mastery D:Ability to use axes I:1000 N:20:Polearm-mastery D:Ability to use polearms I:1000 N:21:Hafted-mastery D:Ability to use hafted weapons I:1000 N:22:Backstab D:Ability to backstab fleeing and sleeping monsters to increase damage I:1000 N:23:Archery D:General ability to use ranged weapons I:1000 F:RANDOM_GAIN N:24:Sling-mastery D:Ability to use slings A:23:Fire piercing shots I:1000 N:25:Bow-mastery D:Ability to use bows A:23:Fire piercing shots I:1000 N:26:Crossbow-mastery D:Ability to use crossbows A:23:Fire piercing shots I:1000 N:27:Boomerang-mastery D:Ability to use boomerangs I:1000 N:58:Boulder-throwing D:Ability to make and throw boulders A:21:Tear down a wall to create boulders I:1000 N:42:Barehand-combat D:Ability to fight barehanded I:1000 F:RANDOM_GAIN G:70 N:47:Bearform-combat D:Ability to fight in bear form I:1000 F:HIDDEN | AUTO_HIDE N:52:Critical-hits D:Ability to deal critical hits with swords < 5lb I:1000 N:57:Stunning-blows D:Ability to stun opponents when doing critical hits with hafted weapons > 5 lb I:1000 # List of combat friendly skills # Melee: Specific masteries improve generic mastery f:Critical-hits:Sword-mastery%5 f:Sword-mastery:Weaponmastery%25 f:Axe-mastery:Weaponmastery%25 f:Polearm-mastery:Weaponmastery%25 f:Stunning-blows:Hafted-mastery%5 f:Hafted-mastery:Weaponmastery%25 # Ranged: Specific masteries improve generic mastery f:Sling-mastery:Archery%25 f:Bow-mastery:Archery%25 f:Crossbow-mastery:Archery%25 f:Boomerang-mastery:Archery%25 # All combat skills improve Combat f:Weaponmastery:Combat%50 f:Sword-mastery:Combat%7 f:Axe-mastery:Combat%7 f:Polearm-mastery:Combat%7 f:Hafted-mastery:Combat%7 f:Archery:Combat%50 f:Sling-mastery:Combat%7 f:Bow-mastery:Combat%7 f:Crossbow-mastery:Combat%7 f:Boomerang-mastery:Combat%7 f:Barehand-combat:Combat%50 f:Boulder-throwing:Combat%40 # No more, let's see how it turns out # Sorcery and Weaponmastery aren't exactly friendly to each other #O:Sorcery:Weaponmastery%100 #O:Sorcery:Archery%100 #O:Sorcery:Barehand-combat%100 #O:Weaponmastery:Sorcery%100 #O:Archery:Sorcery%100 #O:Barehand-combat:Sorcery%100 ############################### SPIRITUALITY SKILLS ########################### N:28:Spirituality D:General ability to use spiritual skills and also influence your Saving Throw I:1000 F:RANDOM_GAIN N:53:Prayer D:Ability to learn and use spells from the gods' schools D:Spells use the wisdom stat and cost piety instead of mana A:17:Cast a spell I:1000 N:12:Druidistic D:Ability to learn and use prayers from the Druidistic realm D:Nature powers use the wisdom stat A:1:Cast a druidistic spell I:1000 N:29:Mindcraft D:Ability to focus the powers of the mind D:Mindpowers use the wisdom stat A:2:Use Mindcraft I:1000 F:RANDOM_GAIN G:50 N:9:Music D:Ability to learn and sing songs D:Songs use the charisma stat A:17:Cast a spell I:1000 f:Prayer:Spirituality%10 f:Druidistic:Spirituality%10 f:Mindcraft:Spirituality%10 f:Music:Spirituality%10 f:Prayer:Magic%10 f:Druidistic:Magic%10 f:Mindcraft:Magic%10 f:Music:Magic%10 ################################## MISC SKILLS ############################### N:30:Misc D:Not a real skill, it is only used to regroup some skills I:0 N:33:Antimagic D:Ability to generate an antimagic field A:3:Use antimagic I:1000 F:RANDOM_GAIN G:80 N:39:Alchemy D:Ability to use essences to modify/create magic items A:5:Use Alchemy I:1000 # Antimagic exclude all magic E:Magic-Device:Antimagic E:Mana:Antimagic E:Geomancy:Antimagic E:Fire:Antimagic E:Air:Antimagic E:Water:Antimagic E:Earth:Antimagic E:Conveyance:Antimagic E:Divination:Antimagic E:Temporal:Antimagic E:Meta:Antimagic E:Mind:Antimagic E:Nature:Antimagic E:Udun:Antimagic E:Sorcery:Antimagic E:Demonology:Antimagic E:Runecraft:Antimagic E:Necromancy:Antimagic E:Mindcraft:Antimagic E:Music:Antimagic E:Prayer:Antimagic E:Druidistic:Antimagic E:Thaumaturgy:Antimagic ################################## SNEAKINESS SKILLS ############################### N:35:Sneakiness D:General ability at the sneakiness skills. D:It also affects the searching abilities I:0 F:RANDOM_GAIN N:36:Stealth D:Ability to move unnoticed, silently I:0 F:RANDOM_GAIN N:37:Disarming D:Ability to disarm the various traps I:0 F:RANDOM_GAIN N:40:Stealing D:Ability to steal objects A:15:Steal object I:0 N:46:Dodging D:Ability to dodge blows and bolts A:16:Check dodge chance I:0 f:Stealth:Sneakiness%15 f:Disarming:Sneakiness%10 f:Backstab:Sneakiness%5 f:Stealing:Sneakiness%15 f:Dodging:Sneakiness%10 ################################## MONSTER SKILLS ################################ N:48:Monster-lore D:General ability at the monster related skills, ability to gain experience D:from friendly kills. It also affects the number of companions you can have I:0 A:22:Turn pet into companion F:RANDOM_GAIN N:44:Summoning D:Ability to create totems from monsters and use them to summon monsters A:13:Manipulate totems I:1000 F:RANDOM_GAIN G:60 N:49:Corpse-preservation D:Ability not to destroy the monsters' corpses when killing them I:0 N:50:Possession D:Ability to incarnate into monsters A:11:Use the possession skill I:0 N:8:Symbiosis D:Ability to enter in symbiosis with monsters unable to move by themselves D:Spells use the intelligence stat A:20:Use symbiotic powers I:1000 F:RANDOM_GAIN G:70 N:32:Mimicry D:Ability to use cloaks of mimicry to change form A:6:Use Mimicry I:1000 F:RANDOM_GAIN G:80 f:Possession:Monster-lore%10 f:Corpse-preservation:Monster-lore%10 f:Summoning:Monster-lore%10 f:Symbiosis:Monster-lore%10 f:Mimicry:Monster-lore%10 ################################## SKILL TREE ################################ T:Main:Combat T:Combat:Weaponmastery T:Weaponmastery:Sword-mastery T:Sword-mastery:Critical-hits T:Weaponmastery:Axe-mastery T:Weaponmastery:Hafted-mastery T:Hafted-mastery:Stunning-blows T:Weaponmastery:Polearm-mastery T:Combat:Archery T:Archery:Sling-mastery T:Archery:Bow-mastery T:Archery:Crossbow-mastery T:Archery:Boomerang-mastery T:Combat:Barehand-combat T:Combat:Bearform-combat T:Combat:Boulder-throwing T:Combat:Antimagic T:Main:Sneakiness T:Sneakiness:Stealth T:Sneakiness:Disarming T:Sneakiness:Backstab T:Sneakiness:Stealing T:Sneakiness:Dodging T:Main:Magic T:Magic:Magic-Device T:Magic:Spell-power T:Magic:Sorcery T:Magic:Mana T:Magic:Geomancy T:Magic:Meta T:Magic:Conveyance T:Magic:Divination T:Magic:Temporal T:Magic:Mind T:Magic:Nature T:Magic:Udun T:Magic:Demonology T:Magic:Necromancy T:Magic:Runecraft T:Magic:Thaumaturgy T:Magic:Alchemy T:Geomancy:Fire T:Geomancy:Water T:Geomancy:Air T:Geomancy:Earth T:Main:Spirituality T:Spirituality:Prayer T:Spirituality:Mindcraft T:Spirituality:Music T:Main:Monster-lore T:Monster-lore:Summoning T:Monster-lore:Corpse-preservation T:Monster-lore:Possession T:Monster-lore:Symbiosis T:Monster-lore:Mimicry tome-235-src/lib/edit/ow_info.txt0000644000076400017500000002332711012107760014566 0ustar dgdg# File: ow_info.txt # This file is used to initialize the "lib/raw/ow_info.raw" file, which is # used to initialize the "owner info type" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # N:: # I::::: # C::: # L:liked races # H:hated races # Version stamp (required) V:2.0.0 N:0:Bilbo the Friendly(Hobbit) I:20000:170:108:5:15 C:120:100:80 L:Elf | Half-Elf | High-Elf | Dunadan | Hobbit | Dwarf | RohanKnight H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold N:1:Uldrik(Human) I:20000:170:108:1:1 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:2:Otick(Human) I:100:170:108:4:10 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:3:Merana(Human) I:0:170:108:1:1 C:200:100:95 L:Human H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:4:Mirimbar(High-Elf) I:0:170:108:1:1 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:5:Raistlin the Chicken(Human) I:20000:175:108:4:12 C:120:100:80 L:Human H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:6:Sultan the Midget(Gnome) I:30000:170:107:5:15 C:120:100:80 L:Gnome | Dwarf | Petty-Dwarf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:7:Lyar-el the Comely(Elf) I:30000:165:107:6:18 C:120:100:80 L:Elf | Half-Elf | Dark-Elf | High-Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:8:Kon-Dar the Ugly(Half-Orc) I:5000:210:115:5:7 C:120:100:80 L:Orc | Troll | Half-Ogre | Beorning | Kobold H:Gnome | Dwarf | Human | RohanKnight | Elf | Half-Elf | High-Elf N:9:Darg-Low the Grim(Human) I:10000:190:111:4:9 C:120:100:80 L:Human H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:10:Decado the Handsome(Dunadan) I:25000:200:112:4:10 C:120:100:80 L:Human | Dunadan | RohanKnight H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:11:Wieland the Smith(Dwarf) I:30000:200:112:4:5 C:120:100:80 L:Gnome | Dwarf | Petty-Dwarf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:12:Arnold the Beastly(Barbarian) I:5000:210:115:6:6 C:120:100:80 N:13:Arndal Beast-Slayer(Half-Elf) I:10000:185:110:5:9 C:120:100:80 L:Elf | Half-Elf | Dark-Elf | High-Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:14:Eddie Beast-Master(Half-Orc) I:25000:190:115:5:7 C:120:100:80 L:Orc | Troll | Half-Ogre | Beorning | Kobold H:Gnome | Dwarf | Human | RohanKnight | Elf | Half-Elf | High-Elf N:15:Oglign Dragon-Slayer(Dwarf) I:30000:195:112:4:8 C:120:100:80 L:Gnome | Dwarf | Petty-Dwarf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:16:Aragorn(Dunadan) I:20000:200:112:4:10 C:120:100:80 L:Human | Dunadan | RohanKnight H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:17:Sondar(Human) I:0:200:112:4:10 C:120:100:80 N:18:Celebor(Half-Elf) I:100:170:108:4:10 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:19:Sharra(Human) I:25000:200:112:4:10 C:120:100:80 L:Human | Dunadan | RohanKnight H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:20:Hjolgar(Barbarian) I:5000:210:115:6:6 C:120:100:80 #L:Warrior | N:21:Tanistil(Elf) I:5000:210:115:6:6 C:120:100:80 #L:Mage | Sorceror | Thaumaturgist #H:Warrior | N:22:Eldore(Human) I:5000:210:115:6:6 C:120:100:80 #L:Priest #H:Necromancer N:23:Vilios(Human) I:5000:210:115:6:6 C:120:100:80 #L:Paladin #H:Necromancer N:24:Angros(Elf) I:5000:210:115:6:6 C:120:100:80 #L:Ranger N:25:Palano(Thunderlord) I:0:210:115:6:6 C:120:100:80 L:Thunderlord N:26:Ludwig the Humble(Dwarf) I:5000:175:109:6:15 C:120:100:80 L:Gnome | Dwarf | Petty-Dwarf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:27:Gunnar the Paladin(Half-Troll) I:10000:185:110:5:23 C:120:100:80 L:Orc | Troll | Half-Ogre | Beorning | Kobold H:Gnome | Dwarf | Human | RohanKnight | Elf | Half-Elf | High-Elf N:28:Torin the Chosen(High-Elf) I:25000:180:107:6:20 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:29:Sarastro the Wise(Human) I:30000:185:109:5:15 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:30:Mauser the Chemist(Half-Elf) I:10000:190:111:5:8 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:31:Wizzle the Chaotic(Hobbit) I:10000:190:110:6:8 C:120:100:80 L:Elf | Half-Elf | High-Elf | Dunadan | Hobbit | Dwarf | RohanKnight H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:32:Midas the Greedy(Gnome) I:15000:200:116:6:9 C:120:100:80 L:Gnome | Dwarf | Petty-Dwarf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:33:Ja-Far the Alchemist(Elf) I:15000:220:111:4:9 C:120:100:80 L:Elf | Half-Elf | Dark-Elf | High-Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:34:Ariel the Sorceress(Half-Elf) I:20000:200:110:7:8 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:35:Buggerby the Great(Gnome) I:20000:215:113:6:10 C:120:100:80 L:Gnome | Dwarf | Petty-Dwarf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:36:Inglorian the Mage(Human) I:30000:200:110:7:10 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:37:Luthien Starshine(High-Elf) I:30000:175:110:5:11 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:38:Gary Gygaz(Half-Troll) I:20000:250:150:10:5 C:120:100:80 #L:Rogue H:Gnome | Dwarf | Human | RohanKnight | Elf | Half-Elf | High-Elf N:39:Histor the Goblin(Half-Orc) I:20000:250:150:10:5 C:120:100:80 #L:Rogue H:Gnome | Dwarf | Human | RohanKnight | Elf | Half-Elf | High-Elf N:40:Zorak the Smart(Dwarf) I:30000:250:150:10:5 C:120:100:80 #L:Rogue H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:41:Tipo the Fair(Human) I:30000:250:150:10:5 C:120:100:80 #L:Rogue H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:42:Dolaf the Greedy(Human) I:10000:175:108:4:12 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | N:43:Odnar the Sage(High-Elf) I:15000:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:44:Gandar the Neutral(Dark-Elf) I:25000:120:110:7:19 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold N:45:Ro-sha the Patient(Elf) I:30000:140:105:6:12 C:120:100:80 L:Elf | Half-Elf | Dark-Elf | High-Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:46:N'rak the Summoner(Human) I:10000:175:108:4:12 C:120:100:80 L:Human | Dunadan | RohanKnight H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:47:Esperion the Beastlover(High-Elf) I:15000:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:48:Flarim the Shopkeeper(Dunadan) I:25000:120:110:7:19 C:120:100:80 L:Human | Dunadan | RohanKnight H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:49:Tril-akheb the Supreme(Elf) I:30000:140:105:6:12 C:120:100:80 L:Elf | Half-Elf | Dark-Elf | High-Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:50:Dorchel(Elf) I:30000:140:105:6:12 C:120:100:80 L:Elf | Half-Elf | Dark-Elf | High-Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:51:Galadriel(High-Elf) I:15000:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:52:Celeborn(High-Elf) I:15000:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:53:Aulendil(Elf) I:30000:140:105:6:12 C:120:100:80 #L:Warrior | H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:54:Valceronwe(Elf) I:30000:140:105:6:12 C:120:100:80 #L:Mage | Thaumaturgist | Sorceror H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:55:Voronwe(Elf) I:30000:140:105:6:12 C:120:100:80 #L:Priest | Paladin H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:56:Celegail(Elf) I:30000:140:105:6:12 C:120:100:80 #L:Ranger H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:57:Turgon(High-Elf) I:30000:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:58:Pengolodh(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:59:Aerandir(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:60:Celebrimbor(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf #L:Warrior | H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:61:Lomelosse(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf | H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:62:Arlindel(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf #L:Harper | Ranger H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:63:Sulraen(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf #L:Mage | Sorceror H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:64:Firiel(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf | H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:65:Earendur(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf | Elf H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:66:Glorfindel(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf #L:Ranger H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:67:Ecthelion(High-Elf) I:0:120:105:6:16 C:120:100:80 L:High-Elf | Half-Elf #L:Paladin H:Orc | Troll | Half-Ogre | Beorning | Kobold | N:68:Kanris(Human) I:5000:210:115:6:6 C:120:100:80 #L:Merchant #H:Rogue N:69:Barliman Butterbur(Human) I:100:170:108:4:10 C:120:100:80 L:Dunadan | Hobbit | Human | H:Orc | Troll | DeathMold | Half-Ogre | Beorning | Kobold | tome-235-src/lib/edit/maeglin.map0000644000076400017500000000412411012107760014472 0ustar dgdg# Created by Mynstral (mynstral@thehelm.com) # Made for PernAngband on 26/07/2001 # Monsters starts awake N:0 # Permanent wall F:X:63:3 # Marker F:<:172:3 # up stairs with maeglin F:{:6:3:825 # Floor with dirt F:.:88:5 # Floor with dirt with an Ettin F:e:88:5:621 # Floor with dirt with a War Troll F:w:88:5:631 # Floor with dirt with a Troll Chieftan F:t:88:5:799 # Floor with dirt with a Snagga sapper F:s:88:5:251 # Floor with dirt with an Orc Captain F:o:88:5:285 # Floor with dirt with an Elite Uruk F:u:88:5:866 # Floor with dirt with an Ancient blue dragon F:L:88:5:601 # Floor with dirt with an Ancient bronze dragon F:Z:88:5:602 # Floor with dirt with an Ancient white dragon F:W:88:5:617 # Floor with dirt with an Ancient green dragon F:G:88:5:618 # Floor with dirt with an Ancient black dragon F:B:88:5:624 # Floor with dirt with an Ancient red dragon F:R:88:5:644 # Floor with dirt with an Ancient gold dragon F:O:88:5:645 # Floor with dirt with a Lesser Balrog F:U:88:5:996 # Granite wall F:#:56:5 D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X##..#########...#........###..R.....###.e...{X D:X#.wt.######..O....#s..#..##w.#..###.....#.t..X D:X#wBLe.####.U.###....##.U.#...##..u####.#####.X D:X#eRe.####..#..######.B...w...#.U#uuu##.#U...eX D:X##...#...G###s...##....##..####..##uu#B..##..X D:X####...e...#####.t...####...####.###u#####.w#X D:X###....##.w.######.e.#..##...###..##uu#e...##X D:X##..W#####...###.....#...##.e####.L##...#####X D:X##...######e.##Z..w.###.......####.###t.#####X D:X....########s....#s...##R..#.U.##..####..####X D:Xs..####....##.tU####...#####t...#.######..###X D:X#...##..##..#..######.t..e..##.w...#####w.###X D:X##.....####s..######.e.#.#t...#.#U.####..####X D:X#...####uu##.t..#####...e####s#........w.####X D:X...####uou...##...#####.....###..#####...####X D:X..#####uu##...###s.##........##..#####..#####X D:X.o.#######...e.###.....o.###s.##..###s...#..#X D:X#s..o#......#s.......u...####..#s.##...o.G...X D:Xsss##o....u###....u..o.o.#####........###.OZ.X D:X: # I:: # T::: # G:char:attr # W:max number of items in the store # proba is the chance(out of 100) of the item being generated # Version stamp (required) V:2.0.0 N:0:General Store I:100:& Wooden Torch~ I:95:& Brass Lantern~ I:95:& Flask~ of oil I:100:& Ration~ of Food I:100:& Hard Biscuit~ I:90:& Strip~ of Venison I:70:& Pint~ of Fine Wine I:80:& Pint~ of Fine Ale I:60:& Shovel~ I:50:& Pick~ I:100:& Iron Spike~ I:70:& Iron Shot~ I:70:& Bolt~ I:70:& Arrow~ I:98:& Cloak~ I:46:& Fur Cloak~ A:0:0:1:2:3:4 O:0:5:6:7 G:1:U W:24 N:1:Armoury I:70:& Pair~ of Soft Leather Boots I:60:& Pair~ of Hard Leather Boots I:80:& Hard Leather Cap~ I:70:& Metal Cap~ I:65:& Iron Helm~ I:100:& Robe~ I:90:& Soft Leather Armour~ I:90:& Soft Studded Leather~ I:90:& Hard Leather Armour~ I:85:& Hard Studded Leather~ I:90:& Leather Scale Mail~ I:80:& Metal Scale Mail~ I:75:& Chain Mail~ I:80:& Augmented Chain Mail~ I:75:& Metal Brigandine Armour~ I:68:& Bar Chain Mail~ I:100:& Set~ of Leather Gloves I:80:& Set~ of Gauntlets I:100:& Small Leather Shield~ I:90:& Large Leather Shield~ I:80:& Small Metal Shield~ A:0:0:1:2:3:4 O:8:9:10:11 G:2:s W:24 N:2:Weaponsmith I:100:& Dagger~ I:100:& Main Gauche~ I:100:& Rapier~ I:100:& Small Sword~ I:100:& Short Sword~ I:100:& Sabre~ I:100:& Cutlass~ I:100:& Tulwar~ I:100:& Broad Sword~ I:100:& Long Sword~ I:100:& Scimitar~ I:100:& Katana~ I:100:& Bastard Sword~ I:100:& Spear~ I:100:& Awl-Pike~ I:100:& Trident~ I:100:& Pike~ I:100:& Beaked Axe~ I:100:& Broad Axe~ I:100:& Lance~ I:100:& Battle Axe~ I:100:& Hatchet~ I:100:& Sling~ I:100:& Short Bow~ I:100:& Long Bow~ I:100:& Light Crossbow~ I:100:& Iron Shot~ I:100:& Arrow~ I:100:& Bolt~ I:100:& Whip~ I:100:& Small Wooden Boomerang~ A:23:0:1:2:3:4 O:12:13:14:15 G:3:w W:24 N:3:Temple I:100:& Nunchaku~ I:100:& Quarterstaff~ I:100:& Mace~ I:100:& Bo Staff~ I:100:& War Hammer~ I:100:& Lucerne Hammer~ I:100:& Morning Star~ I:100:& Flail~ I:100:& Lead-Filled Mace~ I:100:Remove Curse I:100:Blessing I:100:Holy Chant I:100:Heroism I:100:Word of Recall I:100:Word of Recall I:100:Word of Recall #I:100:Cure Light Wounds T:100:71:34 #I:100:Cure Serious Wounds #I:100:Cure Serious Wounds T:100:71:35 T:100:71:35 I:100:Cure Critical Wounds I:100:Cure Critical Wounds I:100:Restore Life Levels I:100:Restore Life Levels I:100:Restore Life Levels I:100:& Whip~ I:100:& Mace~ I:100:& Ball-and-Chain~ I:100:& War Hammer~ I:100:Word of Recall I:100:Word of Recall I:100:Word of Recall I:100:Cure Critical Wounds I:100:Cure Critical Wounds I:100:Restore Life Levels I:100:Restore Life Levels I:100:Restore Life Levels I:100:Remove Curse I:100:Remove Curse I:100:*Remove Curse* I:100:*Remove Curse* A:0:0:1:2:3:4 O:26:27:28:29 G:4:g W:24 N:4:Alchemy shop I:100:Enchant Weapon To-Hit I:100:Enchant Weapon To-Dam I:100:Enchant Armour I:100:Identify I:100:Identify I:100:Identify I:100:Identify I:100:Light I:100:Phase Door I:100:Phase Door T:100:70:9 I:100:Monster Confusion I:100:Magic Mapping I:100:Treasure Detection I:100:Object Detection I:100:Trap Detection I:100:Detect Invisible I:100:Recharging I:100:Satisfy Hunger I:100:Word of Recall I:100:Word of Recall I:100:Word of Recall I:100:Word of Recall T:100:70:9 T:100:70:9 #I:100:Restore Strength T:100:71:42 I:100:Restore Intelligence I:100:Restore Wisdom I:100:Restore Dexterity #I:100:Restore Constitution T:100:71:46 I:100:Restore Charisma I:100:Identify I:100:*Identify* I:100:*Identify* I:100:*Identify* I:100:*Identify* I:100:*Identify* I:100:*Identify* I:100:Light #I:100:Restore Strength T:100:71:42 I:100:Restore Intelligence I:100:Restore Wisdom I:100:Restore Dexterity #I:100:Restore Constitution T:100:71:46 I:100:Restore Charisma I:100:Enchant Armour I:100:Enchant Armour I:100:Recharging I:100:Satisfy Hunger I:100:Satisfy Hunger I:100:Satisfy Hunger A:0:0:1:2:3:4 O:30:31:32:33 G:5:b W:24 N:5:Magic shop I:100:Protection I:100:Levitation I:100:Protection I:100:Fire Resistance I:100:Cold Resistance I:100:Charisma I:100:Slow Digestion T:100:40:3 I:100:Acid Resistance I:100:Lightning Resistance I:100:Searching I:100:Cure Light Wounds # Rods I:100:Probing I:25:& Wooden Rod~ of# # Book T:100:111:50 # Wands T:100:65:3 T:100:65:8 T:100:65:11 T:100:65:16 T:100:65:22 # Staves T:100:55:3 T:100:55:5 T:100:55:8 T:100:55:9 T:100:55:14 T:60:55:15 T:60:55:16 T:60:55:17 A:0:0:1:2:3:4 O:34:35:36:37 G:6:r W:24 N:6:Black Market A:30:0:1:2:3:4 O:38:39:40:41 G:7:D F:ALL_ITEM | MEDIUM_LEVEL W:24 N:7:Home A:0:0:54:55:3:0 O:0:0:0:0 G:8:y W:24 N:8:Book Store # & Book~ of Beginner Cantrips T:100:111:50 T:100:111:50 T:100:111:255 T:100:111:255 T:100:111:255 T:100:111:255 T:100:111:255 T:100:111:255 A:0:0:1:2:3:4 O:42:43:44:45 G:9:o W:24 N:9:Pet Shop I:100:Egg T:100:70:6 I:100:& Hard Biscuit~ A:0:0:1:2:3:4 O:46:47:48:49 G:+:b F:MEDIUM_LEVEL W:12 N:10:Mayor's Office A:0:0:16:15:35:0 O:1:1:1:1 G:+:o W:0 N:11:Inn I:100:& Ration~ of Food I:100:& Hard Biscuit~ I:100:& Strip~ of Venison I:100:& Pint~ of Fine Wine I:100:& Pint~ of Fine Ale A:2:4:5:6:7:0 O:2:2:18:18 G:+:w W:8 N:12:The Soothsayer I:20:Divination I:20:Divination I:20:Divination I:20:Divination I:20:Divination I:20:Divination A:0:0:2:0:8:0 O:3:3:3:3 G:+:B F:RANDOM W:2 N:13:Library I:100:Identify A:0:0:14:15:16:2 O:4:4:4:4 G:+:U W:2 N:14:Castle A:0:0:16:35:0:0 O:16:16:16:16 G:+:o W:0 N:15:Casino A:13:0:9:10:0:12 O:17:17:17:17 G:+:s W:0 N:16:Beastmaster Shanty # Disabled the bounty list for the time being to not confuse people # with the bounty quest # A:18:0:19:20:21:22 A:18:0:21:22:0:0 O:19:19:19:19 G:+:g W:0 N:17:Fighters Hall A:0:0:24:25:0:0 O:20:20:20:20 G:+:s W:0 N:18:Tower of Magery A:0:0:26:27:0:0 O:21:21:21:21 G:+:b W:0 N:19:Inner Temple A:0:0:28:29:0:0 O:22:22:22:22 G:+:G W:0 N:20:Paladins Guild A:0:0:28:25:0:0 O:23:23:23:23 G:+:g W:0 N:21:Rangers Guild A:0:0:31:32:0:0 O:24:24:24:24 G:+:u W:0 N:22:Thunderlords' Nest A:0:0:33:2:34:0 O:25:25:25:25 G:+:U W:0 N:23:The Mirror A:0:0:44:15:16:43 O:51:51:51:51 G:+:U W:0 N:24:Seat of Ruling A:0:0:17:35:0:0 O:52:52:52:52 G:+:U W:0 N:25:Wizards Spire A:60:0:26:27:0:0 O:54:54:54:54 G:+:U W:0 N:26:Priests Circle A:0:0:28:29:0:0 O:55:55:55:55 G:+:o W:0 N:27:Tower of the King A:0:0:17:35:0:0 O:57:57:57:57 G:+:U W:0 N:28:Library I:100:Identify A:0:0:14:15:16:2 O:58:58:58:58 G:+:U W:2 N:29:The White Tree I:100:& Ration~ of Food I:100:& Hard Biscuit~ I:100:& Strip~ of Venison I:100:& Pint~ of Fine Wine I:100:& Pint~ of Fine Ale A:2:4:5:6:7:0 O:59:59:59:59 G:+:w W:8 N:30:Craftsmaster A:0:0:24:25:0:0 O:60:60:60:60 G:+:s W:0 N:31:Earth-Dome (Nature) A:0:0:39:0:0:0 O:61:61:61:61 G:+:U W:0 N:32:Minstrels Haven A:0:0:40:41:0:0 O:62:62:62:62 G:+:U W:0 N:33:Star-Dome A:0:0:46:47:0:0 O:63:63:63:63 G:+:U W:0 N:34:Valarin Temple A:0:0:28:48:0:0 O:64:64:64:64 G:+:U W:0 N:35:Sea-Dome A:0:0:49:35:0:0 O:65:65:65:65 G:+:U W:0 N:36:The Golden Flower A:0:0:50:51:0:0 O:66:66:66:66 G:+:U W:0 N:37:The Fountain A:0:0:52:53:0:0 O:67:67:67:67 G:+:U W:0 # Here begins the random shops, for the random towns N:38:Axe Smith T:100:24:256 A:0:0:1:2:3:4 O:12:13:14:15 G:3:w F:RANDOM | MEDIUM_LEVEL W:12 N:39:Hafted Smith T:100:21:256 A:0:0:1:2:3:4 O:12:13:14:15 G:3:w F:RANDOM | MEDIUM_LEVEL W:12 N:40:Polearm Smith T:100:22:256 A:0:0:1:2:3:4 O:12:13:14:15 G:3:w F:RANDOM | MEDIUM_LEVEL W:12 N:41:Sword Smith T:100:23:256 A:0:0:1:2:3:4 O:12:13:14:15 G:3:w F:RANDOM | MEDIUM_LEVEL W:12 N:42:Rare Jewelry Shop T:100:40:256 T:100:45:256 A:0:0:1:2:3:4 O:34:35:36:37 G:6:v F:RANDOM | DEPEND_LEVEL | DEEP_LEVEL | FORCE_LEVEL F:VERY_RARE W:10 N:43:Jewelry Shop T:100:40:256 T:100:45:256 A:0:0:1:2:3:4 O:34:35:36:37 G:6:y F:RANDOM | DEPEND_LEVEL | MEDIUM_LEVEL | FORCE_LEVEL F:RARE W:20 N:44:Footwear Shop T:100:30:256 A:0:0:1:2:3:4 O:8:9:10:11 G:2:r F:RANDOM | MEDIUM_LEVEL F:COMMON W:12 N:45:Rare Footwear Shop T:100:30:256 A:0:0:1:2:3:4 O:8:9:10:11 G:2:r F:RANDOM | DEEP_LEVEL | MEDIUM_LEVEL F:VERY_RARE W:8 N:46:Library T:100:110:256 T:100:111:256 T:100:112:256 T:100:113:256 T:100:114:256 T:100:115:256 T:100:116:256 T:100:117:256 T:100:118:256 T:100:119:256 T:100:120:256 T:100:121:256 T:100:122:256 T:100:123:256 T:100:124:256 T:100:125:256 A:27:0:1:2:3:4 O:8:9:10:11 G:9:y F:RANDOM | DEPEND_LEVEL | MEDIUM_LEVEL W:24 N:47:Forbidden Library T:100:110:256 T:100:111:256 T:100:112:256 T:100:113:256 T:100:114:256 T:100:115:256 T:100:116:256 T:100:117:256 T:100:118:256 T:100:119:256 T:100:120:256 T:100:121:256 T:100:122:256 T:100:123:256 T:100:124:256 T:100:125:256 A:27:0:1:2:3:4 O:8:9:10:11 G:9:v F:RANDOM | DEPEND_LEVEL | DEEP_LEVEL F:RARE W:12 N:48:Expensive Black Market A:0:0:1:2:3:4 O:38:39:40:41 G:7:v F:RANDOM | ALL_ITEM | DEEP_LEVEL | DEPEND_LEVEL | MEDIUM_LEVEL W:12 N:49:Common Shop I:95:& Brass Lantern~ I:100:& Flask~ of oil I:100:& Ration~ of Food I:60:& Shovel~ I:50:& Pick~ I:100:& Iron Spike~ I:70:& Iron Shot~ I:70:& Bolt~ I:70:& Arrow~ I:98:& Cloak~ I:46:& Fur Cloak~ I:100:Word of Recall I:100:Cure Critical Wounds A:0:0:1:2:3:4 O:0:5:6:7 G:1:U W:12 F:RANDOM N:50:Dragon Hunter T:100:38:256 A:0:0:1:2:3:4 O:8:9:10:11 G:2:v F:RANDOM | DEEP_LEVEL | DEPEND_LEVEL F:VERY_RARE W:12 N:51:Speed Ring Market T:100:45:31 A:0:0:1:2:3:4 O:34:35:36:37 G:6:G F:RANDOM | SHALLOW_LEVEL | DEPEND_LEVEL F:VERY_RARE W:6 N:52:Scribe T:100:70:256 A:0:0:1:2:3:4 O:8:9:10:11 G:5:B F:RANDOM | MEDIUM_LEVEL | DEPEND_LEVEL W:12 N:53:Potion Store T:100:71:256 T:100:72:256 A:0:0:1:2:3:4 O:8:9:10:11 G:5:B F:RANDOM | MEDIUM_LEVEL | DEPEND_LEVEL W:12 N:54:Recaller I:100:Word of Recall A:33:0:1:2:3:0 O:8:9:10:11 G:+:b F:RANDOM | COMMON W:2 N:55:Master Archer T:100:19:2 T:100:19:12 T:20:19:13 T:100:19:23 T:20:19:24 T:50:16:256 T:50:17:256 T:50:18:256 A:0:0:1:2:3:4 O:12:13:14:15 G:3:g F:RANDOM | MEDIUM_LEVEL | DEPEND_LEVEL F:RARE W:24 N:56:Merchants Guild A:0:0:56:57:58:0 O:68:68:68:68 G:+:g W:0 N:57:The Mathom-house A:0:0:59:0:3:0 O:0:0:0:0 G:+:g F:MUSEUM W:255 N:58:The Prancing Pony I:100:& Ration~ of Food I:100:& Hard Biscuit~ I:100:& Strip~ of Venison I:100:& Pint~ of Fine Wine I:100:& Pint~ of Fine Ale A:2:4:5:6:7:0 O:69:69:69:69 G:+:w W:8 ##### Mining equipment for Khazad-Dum ##### N:59:Mining Supply store T:100:20:256 I:100:& Wooden Torch~ I:95:& Brass Lantern~ I:95:& Flask~ of oil I:75:& Dwarven Lantern~ I:60:& Feanorian Lamp~ T:60:65:6 T:70:71:22 A:0:0:1:2:3:4 O:11:15:26:40 F:MEDIUM_LEVEL G:+:s W:24 ## Library quest in Minas Anor N:60:Library I:100:Identify A:61:0:14:15:16:2 O:4:4:4:4 G:+:U W:2 tome-235-src/lib/edit/thrain.map0000644000076400017500000000070711012107760014346 0ustar dgdg# Floor F:.:1:0:0:0:0:0:0:0:61 # Some Nazguls F:1:1:0:951:0:0:0:0:0:61 F:2:1:0:952:0:0:0:0:0:61 F:o:1:0:866:0:0:0:0:0:61 # Marker F:,:172:6:0:0:0:0:0:0:61 # Lit permanent wall F:x:61:6 # Door F:D:48:0:0:0:0:0:0:0:61 # Floor with Trap F:t:1:8:0:0:0:0:* # Deep lava F:l:85:0:0:0:0:0:0:0:61 # Dungeon layout D: D: xxxxxxxx D: xoooo..x D: xo2oo..x D: xlloo..x D: x,loo..D D: xlloo..x D: xo1oo..x D: xoooo..x D: xxxxxxxx D: tome-235-src/lib/edit/volcano.txt0000644000076400017500000003237611012107760014573 0ustar dgdg# File: volcano.txt # Stairway to the Hell F:$:7:3:0:0:0:0:0:6 # Hole to the center of the Volcano F:>:7:3:0:0:0:0:0:5 ############### Town Layout ############### D:###################################################################################################################################################################################################### D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL$LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^^^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^>^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^^K^^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^^K^^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^^K^^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:#LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL^K^LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL# D:###################################################################################################################################################################################################### ############### SLarting positions ############### # Standard starting position for normal races ?:[EQU $LEAVING_QUEST 0] P:64:80 tome-235-src/lib/edit/s_factory.map0000755000076400017500000001353511012107760015060 0ustar dgdg# Map "s_factory.map" # # Special Level "Foul Factory" in the Illusory Castle # # Created for ToME 3.x on 11/11/2003 # Written by Lord Dimwit (lorddimwit@hotmail.com) # # Middle-game dungeon # Comments: This level isn't designed to kill the player, really, just # induce such severe aggravation that their head explodes. There are # two parts of it, the "abusive trickery" part that leads the player # through a horrendous maze of strategically placed glass walls, permanent # walls, and ethereal walls (like permanent walls only invisible, very awful), # followed by a "Factory" stage that follows more traditional patterns of # throwing monsters systematically at the player. # Backported to ToME 2.x by Massimiliano Marangio on 02/07/2004 # Replaced the letter : by R for Rubble # Changed the starting position to 21:51 # Corrected the exits of the jumpgates ### F:::::::::: ### Terrain Features # Permanent wall F:X:61:4 # Fake wall F:I:189:0 # Ethereal wall F:#:214:0 # Copper Pillar F:;:213:0 # Mountains F:M:97:0 # granite F:G:57:4 # Floor F:.:1:0 # Deep Water F:~:187:4 # Ash F:,:93:4 # Fire F:%:205:0 # Deep lava F:L:85:0 # Shallow lava F:l:86:0 # Glass Wall F:_:188:0 # Rubble F:R:49:0 # Trees F:T:96:0 # Tainted water F:t:174:0 # Chasm F:C:87:0 # up staircase F:<:6:0 # down staircase F:>:7:0 # between gate 1 F:1:160:6:0:0:0:0:0:845 # between gate 2 F:2:160:6:0:0:0:0:0:846 # between gate 3 F:3:160:6:0:0:0:0:0:4370 # between gate 4 F:4:160:6:0:0:0:0:0:3339 # between gate 5 F:5:160:6:0:0:0:0:0:4119 # between gate 6 F:6:160:6:0:0:0:0:0:6659 # between gate 7 F:7:160:6:0:0:0:0:0:9257 # between gate 8 F:8:160:6:0:0:0:0:0:8018 # between gate 9 F:9:160:6:0:0:0:0:0:9298 # between gate A F:A:160:6:0:0:0:0:0:805 # between gate B F:B:160:6:0:0:0:0:0:831 # between gate D F:D:160:6:0:0:0:0:0:809 # between gate E F:E:160:6:0:0:0:0:0:2826 # between gate F F:F:160:6:0:0:0:0:0:2831 # between gate H F:H:160:6:0:0:0:0:0:4631 # between gate J F:J:160:6:0:0:0:0:0:7198 # between gate K F:K:160:6:0:0:0:0:0:7990 # between gate N F:N:160:6:0:0:0:0:0:9253 # Treasure on floor F:$:1:0:0:*65 # Trap (random) on floor F:^:1:0:0:0:0:0:* ### Monsters # Eog Golem on floor F:g:1:0:530 # Clay Golem on floor F:a:1:0:261 # Aquatic Golem in water (OK, just for show) F:?:187:0:899 # Stone Golem on floor F:b:1:0:323 # Iron Golem on floor F:c:1:0:367 # Colbran on floor F:d:1:0:435 # Mithril golem on floor F:e:1:0:464 # Colossus on floor F:f:1:0:558 # Drolem on floor F:h:1:0:691 # Demonic Q on shallow lava F:Q:86:0:727 # Livingstone on floor F:i:1:0:336 # Random monster (upto 8 levels ood) on normal floor F:&:1:0:*58 ### Items # Broken Stick F:s:1:0:0:727 ### Guaranteed Items # The Boots of the Machine F:*:205:0:0:0:0:218 ### Level layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X..e.e...I.......Xe..c.a..ca.c.....1X..3..XQQX,llllllllllllll2XX#Gi.X.X..XLABLX..X D:X.XXX...XXX.....XXXe.c..XXX__XX__XXXX.;.;.XllX,ll,ll,XXXXXXXXXXi.X#.XiXXXXL%%LXXXX D:X&XXXe.XX~XXeeeXX~XXe..XX~~~~~~ttttXX.....X,,,,Ll,ll,X..XII.X.X.i.XXG_XXXXL%%LXXXX D:X..&..XX~~~XXeXX~?~XX.&X~~~~t~ttttttX.;.;.X,lllll,ll,XX_..XX.XX#X..X#XXf.X_GG_X.fX D:XGXGXGX?~~~~_c_~~~~~X.&XX~~~~t~ttttXX.....X,L,,,,,lL,.X.#XXi..G.XXiX..XX.........X D:X.....XX~~?XXcXX~~~XXa..XXX__XX__XXXX.;.;.X,L,.XXX%L%XXXXcXX.XXX.X.X.X.XX.X.ff.X.X D:XXgXgXgXX~XXcccXX?XXXXX.a^^a.^^a...bXXXGXXX%L%XX.XX%XXa.aXIX.Xi#.XiXI.X.X........X D:XgXgXgXgXXX^^^^^XXX,ccXXXXXXXXXXXb.XX#...#XX%XX.XI_XX....X.X.#XXXIX.#GX.X.X....X.X D:X.......4X.^^5^^.X.c.c..c..c.c..c.XX.#...#.XXXIXX.X.a.c..XXi..I.X._.X.XXX...&&...X D:X..&&...XXXXXXXXXXc,c,c.XX_XX..ccXX..#...#..XX#iiX.X.a..a.XX.#XX._X.XX.XX.X....X.X D:X......XXEX,,,c,c,cc,ccXXMRMXXc.XX...#...#...XXX#iXXXXXc..IXGX.XXiX.....X........X D:XXXXXXXX..X,,,,,,,,,,,XXM..RMXXXX$$XXX...XXX$$XX..XX_GXXXXXX.Ii.X_X.X#XXX.X....X.X D:XT.T._.g.gXX,C,,,.,C,c_M.R.R.MXX$$$XXX...XXX$$$XX..XIXIXII.i.XX_.X.XX.XXXXGGGGGGXX D:X.T.T_.....XXlXXXXXlXFXXM..RMXX$$XXXXX...XXXXX$$XX.#.XX.X_X_XXI#.XXIIX.Xeee...eeeX D:X..T._.g..g.XlX_D_XlXXXXXM.MXX$$$#....%%%....#$$$X.X..XX_G.#.X.XXIXX..cXXXX...XXXX D:XMMMMX...&..XlX_._XlX6..XXXXXX$$$#....%*%....#$$$X._X#iX.XX..G_Xi.XXd..XLl#_._#lLX D:Xs.s._..&.&.XlX_._XlX..gg....X$$$#....%%%....#$$$X.IIX.X..XIXX.X.G#X..dXLl#_._#lLX D:X.s.s_g....XXlXXGXXlXX.g..d&.XX$$XXXXX...XXXXX$$XXXX._XG#X.XX.X_X.XX.c.XXXX...XXXX D:XXXXXXXXXXIXLLLXGXLLLXgg.g.d..XX$$$XXX...XXX$$$XX<...XiXX.X.Xi.X.X.Xd..X.........X D:Xgg.gXg.gXIXL%LXGXL%LXGXXX__XXXXX$$XXX...XXX$$XXXXXXIXXiX#XX#XX#X_XX...XXXXXXXIXXX D:X^^X^X^X^X^XX_XXGXX_XXGXXg..g.%.XX...X...X...XX.GI.X._iXXG...I..I.GX..dIX#I#I#I#IX D:X^^X^X^X^X^Xhl,&c.a&g.l.XX.g.g%RRXX..X###X..XX..#_X..XXX_iXXIXiXi_.Xc..X.IX.XXXIXX D:X^^X^X^X^X^X&,,,l&,lac.&.__.g.%.R.XX...>...XX#X.X..XX#.._X.X.X.#.XGX.X.XX_XX.X#i.X D:XH.Xg.gXg.gXla,ca&,f.fl.leXX..%R.RRXX.....XX.G.XX#XXI.XX.#.XGXXXiX.#X.XX.i._X.XGX# D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXGXXXXXXXG.X..X#XXX.XX.XXI._XIX.XIXXI#.XXX.X D:X,.,G,&&,ee,ff,hgg,&&,,,.,,I7XXXc..aX.;.;.X&..XXXG#XX.G.XXX..XG######.G.#..##..iXX D:X^X,G.&&.ee,ff..gg,&&,.,,,,XXX..MRM.X.....X.....XXX.IIX.XGI.XX..IXXXXXXXXXXX._.X._ D:X^X,XXXXXXXXXXX.XXXXXX,,.XXX..$.....X.;.;.Xh..&...GXXXGXi#IXX.IXX..#.....#.XX##XXX D:X^X,llL,LlLL,LXXXlll,XXXXX..aMR..$.cX.....X.....XXXX8XXXXXXXX#IX###..##.#..#XI.XKX D:X^XlLCCCCCCCCLllll%%l.R.R.R.R..M.R..X.;.;.X&..XXX.#X#.i.#.XXX#X...###.#.##.#.X#IXX D:X^X,lL,llL,Ll,XXX,lllXXXXXc.M..R.c..X.....XXXXX#.#.XIX#Xi.X...X###.#####.#...X#XXX D:X^X,XXXXXXXXXXX.XXXXXX,.,XXX...$.M..X.;.;.Xh.##i#.#XX_IX.#X.##I....#.#.###.##X#I.X D:X^X.G,&&,,gg.&.,ee,ff,,.,.,XXXa..R..X.....X..#.###.XIXX.X.X.##XX####..#..###II.X.X D:X,,,G,&&,,gg.&h.ee,ff,..,.,I^XXXM..9X.;J;.Xh.##.###..iiX#.X....II.....#....IX..XNX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ### Starting location P:21:51 tome-235-src/lib/edit/t_pref.txt0000644000076400017500000000241211012107760014375 0ustar dgdg# File: t_pref.txt # Defines the preferences for the town features # letter:feature:cave_info:monster:object:ego:artifact:trap:special # Barrow-Downs entrance F:{:7:3:0:0:0:0:0:4 # Mirkwood Forest entrance F:~:7:3:0:0:0:0:0:1 # Land of Mordor entrance F:|:7:3:0:0:0:0:0:2 # Angband Dungeon entrance F:>:7:3:0:0:0:0:0:3 # Mountain chain F:^:97:3 # Floor F:.:1:3 # Trees F:T:96:3 # Deep water F:W:187:3 # Shallow water F:V:84:3 # Deep Lava F:L:85:3 # Shallow Lava F:K:86:3 # Chasm F:C:87:3 # Dirt F:,:88:3 # Mud F:@:94:3 # Rubble F:;:49:3 # Grass F:-:89:3 # Permanent wall F:#:63:3 # Brick Roof F:s:193:3 # Brick Roof Top F:S:194:3 # Brick Roof Chimney F:t:195:3 # Grass Roof F:X:190:3 # Grass Roof Top F:U:191:3 # Grass Roof Chimney F:Y:192:3 # Cobblestone Road F:O:200:3 # General Store F:1:74:3:0:0:0:0:0:0 # Armoury F:2:74:3:0:0:0:0:0:1 # Weapons Smith F:3:74:3:0:0:0:0:0:2 # Temple F:4:74:3:0:0:0:0:0:3 # Alchemy Shop F:5:74:3:0:0:0:0:0:4 # Magic Shop F:6:74:3:0:0:0:0:0:5 # Black Market F:7:74:3:0:0:0:0:0:6 # Home F:8:74:3:0:0:0:0:0:7 # Bookstore F:9:74:3:0:0:0:0:0:8 # Pet Shop F:0:74:3:0:0:0:0:0:9 # Underground Tunnels -- used for tunnels in towns F:I:173:3 # Underground Tunnels -- used for tunnels in towns F:M:204:3 # Fake blank feature F: :0:3 tome-235-src/lib/edit/qrand10.map0000644000076400017500000000071311012107760014324 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Door F:D:38:6 # Floor with Trap F:t:1:2056:0:0:0:0:* # Deep lava F:F:85:12 # Dungeon layout D: D: xxxxxxx D: xFFFFFx D: xxxxxx,t.ttxxxx D: xFFG,t....t,,,xxx D: xFpG.......t.t.DD D: xFFG,t....t,,,xxx D: xxxxxx,t.ttxxxx D: xFFFFFx D: xxxxxxx D: tome-235-src/lib/edit/qrand11.map0000644000076400017500000000057611012107760014334 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Door F:D:38:6 # Floor with Trap F:t:1:8:0:0:0:0:* # Deep lava F:L:85:6 # Shallow lava F:l:86:6 # Dungeon layout D: ,llllllll , D:, llLLLLLllll, D:llLLLGGGLLLlll, D:llLLLGpGLLLLlll D:lllLLGGGLLLllll D:lllllLLLLlllll, D:,lllllllllll, D: , ,llllll, tome-235-src/lib/edit/qrand12.map0000644000076400017500000000060111012107760014322 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Door F:D:38:6 # Floor with Trap F:t:1:8:0:0:0:0:* # Deep water F:W:187:6 # Shallow water F:w:84:6 # Dungeon wayout D: ,wwwwwwww , D:,,wwWWWWWwwww, D:wwWWWGGGWWWwww, D:wwWWWGpGWWWWwww D:wwwWWGGGWWWwwww D:wwwwwWWWWwwwww, D:,wwwwwwwwwww, D: , ,wwwwww, tome-235-src/lib/edit/qrand14.map0000644000076400017500000000062311012107760014330 0ustar dgdg# Floor F:.:1:6 # Marker F:,:172:6 # Princess F:p:1:6:969 # Lit permanent wall F:x:61:6 # Lit glass wall F:G:188:6 # Door F:D:38:6 # Floor with Trap F:t:1:8:0:0:0:0:* # Deep water F:W:84:6 # Shallow water F:w:187:6 # Dungeon wayout D: D: xxxx xxxx D: x,,x x,,x D: xxDxxxxxxxDxx D: D,,,GpG,,,D D: xxDxxxxxxxDxx D: x,,x x,,x D: xxxx xxxx D: tome-235-src/lib/edit/readme.txt0000644000076400017500000001063111012107760014355 0ustar dgdg# File: a_info.txt # This file is used to initialize the "artifact" information for the Angband game. # This is were you find Cubragol, The Phial , Ringil etc. # File: ba_info.txt # This file is used used to initialize the "store/building actions type" information for the Angband game. # This is where you find the ID numbers for 'Presage fate', 'Play craps' , 'Sell an item' etc. # File: d_info.txt # This file is used to used to set the dungeons for the Angband game. # This is where you find 'Barrow Downs', 'The Maze' , 'Mordor' etc. # File: e_info.txt # This file is used to initialize the "ego-item" information for the Angband game. # This is where you find 'Helms of the Noldor' , 'Filthy rags of leprousness' , 'Boots of Jumping' etc. # File: f_info.txt # This file is used to used to initialize the "terrain feature" information for the Angband game. # This is where you find the ID numbers for 'Underground tunnel' , 'grass with flowers' , 'open floor' etc. # File: k_info.txt # This file is used to initialize the "object kind" information for the Angband game. # This is where you find 'Katanas' , 'Mushrooms of Sickness' , 'Jewel Encrusted Crowns' etc. # File: misc.txt # This file contains a lot of 'maximums ' for the Angband game. # This is where you find 'Maximum number of skills in s_info.txt' , #'Maximum number of items in k_info.txt' , 'Maximum number of artifacts in a_info.txt' etc. # File: ow_info.txt # This file is used to initialize the "owner info type" information for the Angband game. # This is where you find 'Bilbo the Friendly(Hobbit)' , 'Raistlin the Chicken(Human)' , # Inglorian the Mage(Human) etc. # File: p_info.txt # This file is used to initialize the "player race/race mod/class" information for the Angband game. # You will find here races like 'Humans' , subraces like 'Vampire', classes like 'Monk' # File: r_info.txt # This file is used to initialize the "monster race" information for the Angband game. # You will find here monsters like 'Marylene, Heartbreakeress of the Netherworld', # 'The Minotaur of the Labyrinth' , 'Morgoth, Lord of Darkness' etc. # File: ra_info.txt # This file is used to initialize the "randart parts" information for the Angband game. # Here you will find info for random artefacts made of 'Mage Staves' , 'Lights' , 'Gloves' etc. # File: re_info.txt # This file is used to initialize the "monster ego race" information for the Angband game. # Here you will find ego monster types like 'Spectral','Skeleton','Archer' etc. # File: s_info.txt # This file is used to initialize the "skills" information for the ToME game. # Here you will find player & monster skills, 8you can use their IDs in other files(?), # You will find skills like 'Bearform-combat' , 'Necromancy' , 'Spell-power' etc. # File: set_info.txt # This file is used to initialize the "lib/raw/set_info.raw" file, which is # used to initialize the "item set" information for the Angband game. # You find linked Items like 'The bow of Bard' & 'The arrow of Bard' # It is like totally unclear to me what this does, especially because # the big spider doesnt drop Sting, hint hint ! # File: special.txt # Contains terrain parsings for the special levels now being kept in seperate map files # You will find there entries as in f_info.txt # File: st_info.txt # This file is used to initialize the "store info type" information for the Angband game. # You will find there stores like 'Armoury' , 'Temple' , 'The Mathom-house' etc. # File: t_info.txt # Includes the town definitions of the game Angband # You will find here the towns like 'Gondor' , 'Bree' , 'Lothlorien' etc. # File: t_pref.txt # Defines the preferences for the town features # You will find there entries as in f_info.txt # File: tr_info.txt # This file comes from Angband64 written by Jurriaan Kalkman # and describes the traps items can have # You will find traps like 'Summon Fast Quylthulgs Trap' , 'Wisdom Trap' etc. # File: v_info.txt # This file is used to initialize the "vault template" information for the Angband game. # You will find vaults like 'The I in the Storm' , 'Greater vault (mortuary temple of sety)' , # 'Lesser vault (amenhotep I)' etc. # File: W_info.txt # This is the wilderness # Change the dimensions at your perils, most likely the game will crash !!! # File: wf_info.txt # This file is used to initialize the "wilderness feats" information for the Angband game. # You will stuff like 'Ekkaia, the Encircling Sea' , 'mountain' , 'Minas Anor' etc. tome-235-src/lib/edit/t_d_khaz.txt0000644000076400017500000003232011012107760014702 0ustar dgdg# Town Name: Destroyed Khazad-Dum # by fearoffours (fearoffours@moppy.co.uk) # # Created for ToME F:o:207:3 # Ash F:A:93:3 # Fire F:F:205:3 # Permanent rubble F:R:206:3 # Town Layout D:###################################################################################################################################################################################################### D:#ooooooooooooo####^^^^^^^^^#######^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#####oooo#######oo######^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^##########oooooooooo CCCCCCC # D:#ooo##ooooooooo#####^^^^^##########^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^########ooo########ooo##########^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^################oooooooooooo CCCCCCCC # D:##oo###oo####oo##############################^^^^^^^^^^^^^^^^^########################oooo#########oo#### ###########^^^^^^^^^^^^^^^^^^^^^^^^####### #######oooo########## CCCCCCCC # D:##############o#########oo###oo###################^^^^^^^############################oooo#########oo###### ################################# #####ooooooooo############# CCCCCCCC ; # D:#^^^^########oooooooooooooo##ooooooooo############################# #################oooo########oo########### ########################## ######ooooooooo################ CCCCCCCC ; # D:#############ooooooooooooooooooooooooooo###### ########### ###### ############## ####oooo#######o##o############# ################### ###########ooo######################## CCCCCCCC ; # D:#^#############ooooo##################oo### # #### # ##### #### ############### ###ooo########ooo## ## ###### # ## ## ## # #######ooooo########################### CCCCCCCC # D:#^^################oo#################ooooo#### ## ; ## ;; o ; o ## # ooooooooo############################ CCCCCCCC # D:#^^^^################o##########o#####oooooooooooooooooooooo AAAAAAAA # o ; oooooooooooooooooooooooo##ooo############################ CCCCCCC # D:#^^^^^^################################# ## ; o ; AAFFFFFAA A o ; o R#o################################### CCCCCCC# D:#^^^^^^################################ ### o ### AAFFFFAAAA ## o ###; o ##A ######################################## CCCCCC# D:#^^^^^################################# ### o ### ### ## AAFFFFFAAo ### o ### o #AAFFA RR###################################### CCCCCC# D:#^^^^^^^################################ ###### ;; o ######### AAAFFFFFAo ###### o ## ### o ## #AFA #R##################################### ; CCCCCC# D:#^^^^^^^^################################ # ## #### o ; ## # # AAAAAAAAA ####### # #### # o ## ###FF# ###R#R################################## CCCCCC # D:#^^^^^^^################################### ## ## o ; ;### # AAAAo # # ##o # ## ; o # ##FF ;#R##RR################################# CCCCCCC # D:#^^^^^^^^^################################ ## AAAAAAAA ### o ### o # # o ## # #R################################## CCCCCC ; # D:#^^^^^^^^^################################# AAFFFFFFAA o o o #R ################################## CCCCCC # D:#^^^^^^^^^^################################ ; AAFFFFFFFAAoooooooo o o oooooooooooo AAAA R################################# CCCCCC ; # D:#^^^^^^^^^^^^^########################### AAAFFFFFAA o o o o FFFFF A ################################# CCCCCCC # D:#^^^^^^^^^^^^^^^########################## AAAAAAAAAAAAAAFF o ### # o o ;### o ### # AF FAA #R############################## CCCCCCC ; # D:#^^^^^^^^^^^^############################# AFFFAA #####; o # ## o o # ### o # # # FF ; ###############################; CCCCCCC ; # D:#^^^^^^^^^############################### AAFFFA; ## ## # o #### ## o ; o ####### o ### #A AAA ############################ CCCCCCC # D:#^######################################### AFAA; ## ### oooooooo #### # #o o ###### oooooo ###AAFF o ; R#############################; CCCCCCC # D:#################ooo###################### AA ; ### # o # ## o o ##### o ## AFFA# RR#############oo############## CCCCC; # D:####oo##ooo#####o#######o###ooo########### ## ; o ## o o ### o ; ###FFAA ;; R########oo###oooooo#####oo###### CCCCC ; # D:#ooooooooooooooooooooooooooooooo##oooooooo ; o ; o o o ; # ;; ; oooooooooooo##oooooooo##oooooooooo CCCCC ; # D:#ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooAAAFooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo CCCCCC # D:#oooooooooooooooooo##oooooo##oooooo##ooooo AA ; o o AA FFA ; Roooooooo#oooooooooooooooooooooooo CCCCC # D:#^#######################oo####ooooo####### ##### FFAFA # # o o AFFF### # ######o####oo####oo######oo######; CCCCC # D:#^^#######################o########### #### AAFFFAA# oA o A FA## # ## ## ## RR####o####################oo#### CCCCC # D:#^####################################### ## ### ;; ; AAFFAA##### oA FFFAA ### ### ## #### R####oo######################### CCCCCC # D:#^^######################################## ####### ; #A##### oA o # #### # # ### RRR###o############oo########## CCCCCCC # D:#^^^###############ooo################### ### # ; ;# ## oA AA o FA ##### ; ### ## ;; R#####oo########ooooo####### CCCCCCCC # D:#####oo##oo#####oooooooo##############oo## ### ; #### o AA o F A ### ### R#######oooo##oooooo####### CCCCCCCCC ; # D:#ooooooooooo###ooooooooooooooooooooooooooo # o A oF # ooooooooooooooooooooooooooo CCCCCCCC # D:#ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooFoooFooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo CCCCCCCC ; # D:#^ooooooooooooooooo###oooooooooo##oooooooo o #o A o o AA # ooooooo####ooooooooooooo CCCCCCCC # D:#^^#o###ooo#####ooo#####ooooo########oo# # # ; o ### o A Fo ;### o A ### oR#########ooooo###oo# CCCCCCCC ; # D:#^^^^^###o################oo############# # # # ; o ###### # AF o ## # o #### ; R###########oo######## CCCCCCCC ; # D:#^^^^^^^##################################R ; #### ooooooo ##### o ; A o ###### ooooo A ####### ######################## CCCCCCCCC # D:#^^^^^^^^^^##############################RR AA; ## ##### o ; ####### o Ao ### # o FFF # ## # o ; #R######################## CCCCCCCC # D:#^^^^^^^^^^^^^^^######################### R AA FF A ; ## ## o #### o A ##### o AFF ### # ############################ CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^^###################RR AAAFFFAA ## ; o ### o o # # o ; A ### ; ;; RR########################## CCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^#################### R AAAFFFAA ; o ;; o ; o o A ; R########################### CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^######################R AAFFA A ooooooooooo o o oooooooooooo ;; ;R ############################ CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^^^^^#################RRR ; AFFA o ; ; o o ; A o R############################ CCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^##############R ### o # # o ### o ###; FF A o #### RR############################ CCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^############RRR ### # o AAA A # ### o ## # o # # # AAFF Ao # ## R ######################## CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^^##########R R ### # #;; ; o AAAA ## #### o ## #### o ### ### FFAo ####### R########################### CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^^##########RR ## ### o ;A A #### ## A A o ### # # o # ## ### AAF AA ####### ############################ CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^^^########### ### o ; ;## ## AAA o # ### o ##### ; FFAA #### ; ############################## CCCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^^^^^^############## R ### ; o ## AAAA o # # o A ## A oFA ### R############################## CCCCCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^^^^^^#################R o A AoAA A Ao A A AAAAA FFF R#########oo###oo################# CCCCCCCCCC # D:#^^^^^^^^^^^^^^^^^^#############o#######oooooooooooooooooooooo ## AA A o A A A AR AAFFFAFA oooooooooooooooooRoooooooooooooooooo################## CCCCCCCC ; # D:#^^^^^^^^^^^^^^^^^############ooooooooooo# ### RRR RR # ### RR R o RR## AAR F FFA#FF A AA FFFFRR R ## R oooooo##oooooooooo################### CCCCCCC # D:#^^^^^^^^^^^#################ooooooooooo####R######R ## RR### ######### ###RR####o RR##### #ooo# ### R#F#F#RRRR A FF##R#R ##### ####################ooo##################### CCCCCCC # D:#^^^^^^^^^^###################oo######oo### ########### ######## ## #### ###########oooo########ooo ##########R#A##A A ######R# ###### ####################oo###################### CCCCCCC # D:#^^^^^^^##########oo####oo####ooo######### ############ ######### ###^^^ #########ooooo########oo##################A################### #########^######oooo##ooo################## CCCCCCC # D:##^^^^^#########oooooooooooooooo#################^^####### ###########^^^^^###########ooooo######ooo####################################### #####^^^#######ooooooooooooo############# ; CCCCCCC# D:#^^^##########ooooooooooo##ooooo######^#########^^^^##################^^^^^^^^^^^######ooo#######oooo#########^^^^^^^^^^^^^^^^^^^########### #####^^^#######oo##oooooooo############# CCCCCC# D:##############ooooo##########oo######^^^#####^^^^^^^^###############^^^^^^^^^^^^^^#####oooo#######ooo######^^^^^^^^^^^^^^^^^^^^^^^^^^^^###### ####^^^^^###############ooo############## CCCCC# D:########ooo#####oo##################^^^^^^^^^^^^^^^^^#############^^^^^^^^^^^^^^^^^####oo########oooo#####^^^^^^^^^^^^^^^^^^^^^^^^^^^########### #######^^^^^#############ooo#ooo######## CCCCCC# D:#o##oooooooooooooooo##############^^^^^^^^^^^^^^^^^^^^^^#########^^^^^^^^^^^^^^^^^^#####oo########oo######^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^####### # ######^^^^^^^^^^^^########oooooooooooooo CCCCC # D:#oooooooooooooooooo########^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^########oooo#######ooooo###^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^##############^^^^^^^^^^^^^^^#######ooooooooooo CCCCC # D:###################################################################################################################################################################################################### # Default starting position # ?:[EQU $LEAVING_QUES 0] # P:31:32 tome-235-src/lib/edit/wolves.map0000644000076400017500000000207311012107760014376 0ustar dgdg# permanent wall F:X:61:0 # granite F:#:57:0 # up staircase F:<:6:0 # Grass F:-:89:0 # Dirt F:.:88:0 # Trees F:t:96:0 # Open door F:D:4:0 # Broken door F:d:5:0 # Grass with elf skeleton F:z:89:0:0:397 # Dungeon layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X...t.---.......-.-.....-...#.--X D:X-..#..-......-.....--......t...X D:X...t.--.tt#ddt##t#dd#t#....#...X D:Xz-.t....#.--...#...-..#.--.t...X D:X#d##....#.z.z..t---...t....#tD#X D:X....---.t......t..-.z.#..z.....X D:X...--.-.#...z..#.--...t........X D:X##t#-z-.#####dd#dd##tt#....#t#tX D:X..-t.--.t....-.t...--.#.---t...X D:X.--t---.t......#..--z-#----#-..X D:X...D....#.--z...---.--t--.-d--.X D:X...#....#........---..#--..#z-.X D:X#t#t....t..-...t-z-...t....#tt#X D:X..-.....#-..-..#......#.....--.X D:X...-.--.#dd#ttt##t##Dd#.....--.X D:X#Dt#....#-.....#......#....##t#X D:X...#...-t----..#......t...-tz--X D:X.z.t...-#--.-..t......#.---#-..X D:X.--t.---#-z.--.#.....zt--..d-..X D:X---#....###dd#tt##dd###--..t...X D:X.z-t..-...-....-..-.--.....#X D:X.LLL...........LLLXX...G=-&.=-G^........1.X D:X.L9L.LLLLLLLLLLLLX%...EGE.=&.FG^..........X D:X.L99.L&..........X%....G..&-..G^....j.....X D:X.LLLLL&LLLLLLLLL.LXX...G=-=&-=G^..........X D:X....&&&L.......L.L*XXX.G-=&&-=G^^^^^^^^^^^X D:XLLLLLLLL.LLLLL..&L**XXXXXXXGGGG%XXXXXXXXXXX D:XXXXXXLL..L***LLLLLLLX^^^^8Xi....%@@^^.^^@@X D:X5..8X.&.XXXXXX......D^^^^8XIIIIIXbb^^.^^ccX D:X...8X...XA...X.LLLLLX^^^^8X.....X..^^.^^..X D:X...8X.XXXC...X.LL...XXXIXXX^^^^^X..^^.^^..X D:XGXXXX.LfX7...X&LL.L.Xa^^^aXf...fX..^^.^^..X D:X.X5XL.L*XB...X&&..L.X^b^b^X^^^^^X..^^.^^..X D:X.X^XL.L*XXXXXXLLLLL.X^^7^^X.....X..^^.^^..X D:X.X^XL.L***fXL.....&&X^b^b^XIIIIIX..^^.^^..X D:X.X^XL.LLLLLXL.LLLLLLXa^^^aXi....X..^^.^^..X D:X.X^XL.........XXXXXXXXX%XXXXXXXXX..^^.^^..X D:X.X^XXXXXXXXXXLX^...^Xe-^=dX^^..&X..^^.^^..X D:X.X^^^^^^^^^^XLX.^^^.X-^^^=X^^..&X..^^.^^..X D:X.XXXXXXXXXX^X8Xf^B^.%^^6^^%^^C.&X..^^.^^..X D:X.LLLLLLLLL+^XXX.^^^.X-^^^=X^^..&X..^^.^^..X D:X.XXXXXXXXXXXXXX^...^Xd-^=eX^^..&X..^^.^^..X D:X.Xbbbbb......XXXXXXXXXX%XXXXXXXXX..^^.^^..X D:X.XbbbbXXXX^^^^XX....X^^^^^X...h.X..^^.^^..X D:X.XbbbXX^^XXX^^^XX...X^ccc^X....0X..^^.^^..X D:X.XbbXX.^X%bXX^^^XX..X^.A.^X.....X..^^0^^..X D:X.IbXX..XXbbbXX^^^XX.X^ccc^XIXXXXXXXXXXXXXXX D:X.XXX..XX.....X%^^^XXX^^^^^XlllllllllllllllX D:X.X99.XXW......XX^^^XXXXXXXXlllllllllllllllX D:X.X99XXWWW...a..XX^^.XXllllllLLLLLlXXXX%XXXX D:X.XXXX..WWW.....cXX^.XXXXXlllllllllXVVVVVVVX D:X.X8.....WWW....ccX^.X^^^XLLLlLLLLLXVVVVVVVX D:X.X%XXXXXXXWW...cXXX.X+X^XlllllllllXV%%%%%VX D:X.X.......XWWW..X%^X.XLX^XlLLLLLLLLXV%8^8%VX D:X.XXXXXX%.X.WWWXX^^X.XLX^XlllllllllXV%^a^%VX D:X.X.IIIIX.X..WXX..XXcXLX^XLLLlLLLLlXV%^^^%VX D:X.X%XXXIX.X..XX..XXccXLX^XlglllLgllXV%^^^%VX D:X.Xa.6XIX.X.XX..XXcccXLX^XlllllXXXXXV%^a^%VX D:X+XXX.XIX.X.X99XXccccXLX^XXXXXXX888XV%8^8%VX D:X%%%Xa%.X.%8X99XcccccXLX^^^^^^4X...XV%%%%%VX D:X%.%XXXXXXXXXXXXIXXXXXLXXXXXXXXX...XVVVVVVVX D:X.%%+..........................G..4X...F...X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ### Starting Location P:43:4 tome-235-src/lib/edit/d_info.txt0000644000076400017500000002540011012107760014356 0ustar dgdg# File: d_info.txt # This file is used to initialize the "lib/raw/d_info.raw" file, which is # used to initialize the "dungeon type" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # Some store indexes are defined in "defines.h", and must not be # changed. # N:: # D:<3 letter short name>: # W:::::: # L::<%1>::<%2>::<%3> # A::<%1>::<%2>::<%3>:: # O:<%treasure>:<%combat>:<%magic>:<%tools> # E:d:: # F: # R:: # M: # S: # Note for : # 0 = No restriction # 1 = AND # 2 = NAND # 3 = OR # 4 = NOR # Version stamp (required) V:2.0.0 ### Wilderness(purely cosmetic, never used) ### N:0:Wilderness D:Wil:a way to the Wilderness W:0:0:0:0:14:500 L:89:80:199:20:1:0 A:96:100:56:0:56:0:57:58 O:20:20:20:20 F:PRINCIPAL | FLAT | NO_RECALL R:100:0 ### The principal dungeons, they were created by spliting the vanilla dungeon ### N:1:Mirkwood D:Mkw:a way to the Mirkwood Forest. W:11:33:5:0:14:160 L:89:95:199:5:88:0 A:96:100:97:0:56:0:202:96 O:20:20:20:20 F:PRINCIPAL | NO_DOORS | NO_DESTROY | FLAT F:FILL_METHOD_0 R:100:0 N:2:Mordor D:Mdr:a door to the Land of Mordor. W:34:66:15:0:14:160 L:88:67:93:33:1:0 L:0:100:0 A:97:50:56:50:56:0:57:97 A:0:100:0 O:20:20:20:20 F:PRINCIPAL | LAVA_RIVER | CAVERN | NO_STREAMERS F:FILL_METHOD_2 R:100:0 N:3:Angband D:Ang:an entrance to the Pits of Angband. W:67:127:30:0:14:160 L:1:100:1:0:1:0 A:56:100:56:0:56:0:57:58 O:20:20:20:20 F:PRINCIPAL | CAVERN | NO_EASY_MOVE | NO_RECALL F:ADJUST_LEVEL_1_2 | ADJUST_LEVEL_1 F:FILL_METHOD_0 R:100:0 N:4:Barrow-Downs D:BDw:a way to the Barrow-Downs. W:1:10:1:0:14:160 L:88:78:89:18:199:4 L:0:95:5 A:96:34:97:66:56:0:57:97 A:100:0:0 O:20:20:20:20 F:PRINCIPAL | FLAT F:FILL_METHOD_3 R:25:1 M:UNDEAD R:75:0 # The Additional dungeons # Mount Doom # Levels 85-99 N:5:Mount Doom D:MDm:a way to the top of the Mount Doom. W:85:99:18:0:14:160 L:86:90:205:10:1:0 A:177:100:0:0:0:0:85:87 O:10:10:30:30 E:2d10:10:FIRE F:CAVE | LAVA_RIVER | NO_RECALL | NO_STREAMERS F:FILL_METHOD_0 | NO_EASY_MOVE R:100:1 M:IM_FIRE # Nether Realm # Levels 666-696 (!!!) # guarded by Tik'srvzllat, who has the Ring of Phasing N:6:Nether Realm D:Nth:a magical portal to the Nether Realm. W:666:696:40:0:14:160 L:102:80:86:15:85:5 A:85:80:87:20:87:0:57:85 A:50:50:0 O:25:25:25:25 E:10d10:3:NETHER F:EMPTY | FORGET | NO_BREATH | NO_EASY_MOVE | NO_SHAFT F:RANDOM_TOWNS | ADJUST_LEVEL_2 | NO_RECALL | NO_STREAMERS F:LAVA_RIVER | FINAL_GUARDIAN_1032 | FINAL_ARTIFACT_203 F:FILL_METHOD_2 | NO_RECALL_OUT R:5:0 R:95:3 M:RES_NETH | R_CHAR_G | R_CHAR_W | R_CHAR_U # The Lost Land of Numenor # levels 35-50 # guarded by Ar-Pharazon the Golden, who has the stone "Toris Mejistos". N:7:Submerged Ruins D:Num:a submerged way to the lost land of Numenor. W:35:50:25:0:14:160 L:84:95:187:5:1:0 A:187:80:84:10:56:10:57:187 A:60:0:40 O:30:30:10:10 E:1d1:1:ACID F:NO_STREAMERS F:FINAL_GUARDIAN_980 | FINAL_ARTIFACT_204 F:FILL_METHOD_3 | WATER_BREATH R:20:0 R:80:3 M:AQUATIC | CAN_SWIM | CAN_FLY # Used for astral mode N:8:Halls of Mandos D:HMa:*A BUG*YOU should see this message!* W:1:98:1:0:14:160 L:1:100:1:0:1:0 O:20:20:20:20 A:56:100:56:0:56:0:57:58 F:RANDOM_TOWNS | NO_RECALL | NO_SHAFT F:FILL_METHOD_0 R:100:2 M:UNIQUE # Cirith Ungol # levels 25-50 # guarded by Shelob. N:9:Cirith Ungol D:CUg:an entrance to Cirith Ungol. W:25:50:10:0:14:160 L:87:5:88:65:16:30 A:97:90:16:10:56:0:16:58 O:30:30:30:10 E:4d4:20:POISON F:FINAL_GUARDIAN_481 F:CIRCULAR_ROOMS F:FILL_METHOD_2 R:2:0 R:49:3 M:SPIDER | R_CHAR_c | R_CHAR_a | R_CHAR_I | R:49:3 M:ORC | R_CHAR_w | R_CHAR_m | R_CHAR_j # The Heart of the Earth # levels 25-36 # guarded by Golgarach, the Living Rock N:10:Heart of the Earth D:HoE:a passage leading into the very heart of the world. W:25:36:10:0:14:160 L:1:100:1:0:1:0 A:56:100:56:0:56:0:57:58 O:40:10:10:20 G:life F:EVOLVE | FINAL_GUARDIAN_1035 | NO_RECALL | NO_SHAFT R:40:3 M:R_CHAR_# | R_CHAR_X | R_CHAR_g | R_CHAR_E | R:30:3 M:PASS_WALL | KILL_WALL | HURT_ROCK R:30:0 # The Void # Levels 128-150 # Where Melkor lurks for the final battle! N:11:The Void D:Vod:a jumpgate to the Void W:128:150:40:0:20:160 L:183:97:102:3:0:0 A:183:90:102:10:0:0:102:102 A:40:60:0 O:25:25:25:25 E:20d6:100:DARK F:EMPTY | FORGET | NO_BREATH | NO_EASY_MOVE | NO_RECALL_OUT | NO_RECALL | F:ADJUST_LEVEL_1_2 | ADJUST_LEVEL_1 | NO_STREAMERS | NO_SHAFT F:FILL_METHOD_2 F:FINAL_GUARDIAN_1044 | R:1:0 R:99:3 M:UNDEAD | DEMON | DRAGON | NONLIVING | SPIRIT # TEST dungeon N:12:Test D:Tst:a way to test dungeon gen W:1:10:1:0:14:160 L:88:78:89:18:199:4 L:0:95:5 A:177:100:0:0:0:0:85:87 A:100:0:0 O:20:20:20:20 F:FILL_METHOD_3 | SMALL R:100:0 G:dungeon2 # The Paths of the Dead # levels 40-70 # Feagwath is there, guarding Doomcaller N:16:Paths of the Dead D:PoD:the entrance to the Paths of the Dead. W:40:70:18:0:24:100 L:88:85:84:15:1:0 A:56:75:87:25:56:0:57:58 O:30:30:30:2 E:1d1:20:RAISE F:FINAL_GUARDIAN_804 | FINAL_ARTIFACT_91 F:FILL_METHOD_3 R:5:0 R:10:3 M:R_CHAR_p R:85:3 M:UNDEAD | NONLIVING # The Illusory Castle # levels 35-52 # Guarded by The Glass Golem guarding The Helm of Knowledge N:17:Illusory Castle D:Ill:an entrance to the Illusory Castle. W:35:52:10:0:24:100 L:1:98:188:2:1:0 A:56:50:189:50:56:0:57:58 O:50:10:20:20 E:6d2:6:CONFUSION F:RANDOM_TOWNS | NO_STREAMERS F:FINAL_GUARDIAN_1033 | FINAL_ARTIFACT_160 F:FILL_METHOD_1 R:30:0 R:70:3 M:STUPID | WEIRD_MIND | SHAPECHANGER | ATTR_MULTI | CHAR_MULTI | RAND_25 | M:RAND_50 | EMPTY_MIND | INVISIBLE | PASS_WALL | KILL_WALL S:BR_CONF | BR_CHAO | BA_CHAO | CONF | FORGET | TRAPS | MULTIPLY # The Maze # Levels 25-37 # Guarded by The Minotaur of the Labyrinth with the Steel Helm of Hammerhand N:18:Maze D:Maz:a small tunnel leading to a maze of twisty little passages, all alike. W:25:37:15:0:20:160 L:1:100:1:0:1:0 A:56:98:48:2:56:0:57:58 O:2:40:10:40 G:maze F:SMALLEST | FORGET F:FINAL_GUARDIAN_1029 | FINAL_ARTIFACT_38 R:80:0 R:20:3 M:R_CHAR_p # The Orc Cave # levels 10-22 # There is Azog with the Wand of Thrain at the bottom N:19:Orc Cave D:Orc:a dark tunnel leading to an Orc Cave. W:10:22:8:0:35:200 L:88:100:1:0:1:0 A:97:100:56:0:56:0:57:97 O:5:50:10:25 F:RANDOM_TOWNS | F:FINAL_OBJECT_810 | FINAL_GUARDIAN_373 | CAVE | F:FILL_METHOD_0 R:30:3 M:TROLL R:20:0 R:50:3 M:ORC | R_CHAR_k | R_CHAR_o | R_CHAR_O # Erebor # levels 60-72 # There is Glaurung N:20:Erebor D:Ere:a tunnel leading into depths of the Lonely Mountain. W:60:72:35:0:20:140 L:88:100:1:0:1:0 A:97:90:87:10:56:0:57:97 O:40:40:40:40 F:BIG | LAVA_RIVER | CAVERN | NO_RECALL | NO_STREAMERS F:CAVE | DOUBLE | FINAL_GUARDIAN_715 | F:FILL_METHOD_2 R:10:0 R:60:1 M:DRAGON | R_CHAR_D R:30:1 M:DRAGON | R_CHAR_d # The Old Forest # levels 13-25 # Old Man Willow protects it N:21:The Old Forest D:OFr:a path into the Old Forest. W:13:25:5:0:15:100 L:88:76:84:16:199:8 L:68:16:16 A:96:100:56:0:56:0:202:96 O:20:5:15:30 F:WATER_RIVERS | NO_DOORS | NO_DESTROY | FLAT | NO_STREAMERS F:RANDOM_TOWNS | FINAL_GUARDIAN_206 F:FILL_METHOD_3 R:30:0 R:40:3 M:ANIMAL R:30:3 M:UNDEAD | R_CHAR_h # The Mines of Moria # levels 30-50 # There is Durin's Bane N:22:Moria D:MoM:a stone door leading to the Mines of Moria. W:30:50:20:0:40:40 L:88:100:1:0:1:0 A:97:100:56:0:56:0:57:97 O:30:50:10:5 F:FINAL_GUARDIAN_872 | WATER_RIVER | BIG | NO_STREAMERS F:FORCE_DOWN F:RANDOM_TOWNS F:WILD_45_30__44_37 F:FILL_METHOD_0 R:40:3 M:ORC R:30:3 M:TROLL | GIANT R:20:3 M:DEMON R:10:0 # The tower of Dol Guldur # Levels 57-70 # The Necromancer (weak Sauron) at the bottom, with the Ring of Durin N:23:Dol Guldur D:TDG:a gate leading to the tower of Dol Guldur. W:57:70:34:0:24:160 L:1:80:174:20:1:0 A:56:100:56:0:56:0:57:58 O:20:1:70:9 F:SMALL | FINAL_GUARDIAN_819 | FINAL_ARTIFACT_205 F:FILL_METHOD_3 R:30:3 M:R_CHAR_p | R_CHAR_P R:10:3 M:ORC | TROLL R:20:3 M:UNDEAD R:30:3 M:DEMON | DRAGON R:10:0 # Dungeons from Variaz # The Small Water Cave # levels 32-34 # The Watcher in the Water is at the bottom N:24:The Small Water Cave D:SWC:the entrance to a small water cave. W:32:34:20:0:14:160 L:84:100:84:0:84:0 A:97:100:56:0:56:0:57:58 O:10:10:30:30 E:1d1:20:ACID F:FINAL_GUARDIAN_517 | NO_RECALL F:FILL_METHOD_0 R:10:0 R:10:3 M:AQUATIC R:40:1 M:IM_COLD S:BA_WATE R:40:3 M:IM_COLD # The Land of Mountains # Trone the rebel Thunderlord is hiding here, with his suit of # thunderlord armour. # Levels 45-70 N:25:The Sacred Land Of Mountains D:LoM:the way to the Sacred Land of Mountains. W:45:70:20:0:14:160 L:89:100:89:0:89:0 A:97:100:56:0:56:0:97:97 O:20:20:20:20 F:RANDOM_TOWNS | FLAT | NO_STREAMERS F:FINAL_GUARDIAN_789 | FINAL_ARTIFACT_27 F:FILL_METHOD_0 R:60:3 M:CAN_FLY R:40:0 # The Land of Rhun # levels 26-40 # Guarded by Ulfang the Black, Morgoth's first Easterling follower. N:26:The Land Of Rhun D:LoR:a way to the Land of Rhun. W:26:40:15:0:14:160 L:89:100:1:0:1:0 A:89:50:96:25:84:25:57:58 O:20:20:20:20 F:RANDOM_TOWNS | FLAT | NO_STREAMERS | FINAL_GUARDIAN_990 F:FILL_METHOD_1 R:30:3 M:R_CHAR_p | R_CHAR_h R:30:3 M:ANIMAL R:40:0 # The Sandworm's Lair # level 22-30 # guarded by the Sandworm Queen (and her children), who will drop her armour N:27:The Sandworm lair D:SwL:a sandhole. W:22:30:12:0:5:200 L:91:85:94:10:93:5 A:98:100:96:0:84:0:94:94 O:15:5:60:20 F:NO_DOORS | SAND_VEIN | F:FINAL_GUARDIAN_1030 | FINAL_ARTIFACT_153 F:FILL_METHOD_0 R:90:3 M:R_CHAR_w R:10:3 S:MULTIPLY # Used by the death fate N:28:Death fate D:Dth:a fated death. W:1:1:1:0:30:255 L:1:100:1:0:1:0 A:1:100:1:0:1:0:1:1 O:1:1:1:1 F:EMPTY | SMALLEST | NO_RECALL | NO_STREAMERS F:FILL_METHOD_0 R:100:0 # The Grinding Ice # levels 20-40 # Guarded by the White Balrog N:29:The Helcaraxe D:Ice:the entrance to the Grinding Ice of the Helcaraxe. W:20:40:10:0:14:160 L:90:0:88:70:84:30 L:90:0:10 A:95:0:56:100:56:0:57:58 A:100:0:0 O:20:20:20:20 E:1d4:15:COLD F:DOUBLE | WATER_RIVER | CAVERN | NO_STREAMERS F:FINAL_GUARDIAN_1034 | F:FILL_METHOD_2 R:100:1 M:IM_COLD # The Lost Temple of "..player.pgod.." # Generated in god quest. # Most dungeon attributes altered during the quest. # See god.lua for details N:30:A lost temple D:LTm:the entrance to a lost temple. W:1:50:1:0:14:160 L:1:100:1:0:1:0 A:56:100:56:0:56:0:57:58 O:20:20:20:20 F:FILL_METHOD_4 | NO_RECALL R:100:0 # N:: # D:<3 letter short name>: # W:::::: # L::<%1>::<%2>::<%3> # A::<%1>::<%2>::<%3>:: # O:<%treasure>:<%combat>:<%magic>:<%tools> # E:d:: # F: # R:: # M: # S: # 0 = No restriction # 1 = AND # 2 = NAND # 3 = OR # 4 = NOR tome-235-src/lib/edit/evil.map0000644000076400017500000000206311012107760014015 0ustar dgdg# permanent wall F:X:61:0 # granite F:#:57:0 # Mountain Chain F:^:97:0 # up staircase F:<:6:0 # Dirt F:.:88:0 # Lesser Balrog F:b:88:0:996 # Greater Balrog F:B:88:0:807 # Pit Fiend F:P:88:0:812 # Dungeon layout D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X^..^^^^^^^^^^^^^^^^^^^^^^^^^^^^X D:X^..^^^^^^^^^..^^^^^^^^^^^^^^^^^X D:X^...^^^^^^.........^^^^^^^^^^^^X D:X^^..^^^^^..^^^^..^B^^^^^^^^^^^^X D:X^...^^^^...^^^^^..^^^^^^^^^^^^^X D:X^^..^^^..^^.^^^^^^^^^^^^^^^^^^^X D:X^..^^^^^.....^^^^^.^^^^^^^^^^^^X D:X^^..^^^^..^^.^^^.^......^^^^^^^X D:X^..^^^^..^^...^^...^..^.^^^^^^^X D:X^^..^^^..^^^..^...^^^....^^^^^^X D:X^^^...^.^^^.....^^^^P...<^^^^^^X D:X^^^.....^^^^..^^^^^^^^..^^^^^^^X D:X^^^^^^.^^^^..^^^^^^^^^^^^^^^^^^X D:X^^^^^^^^^^^...^^^^^^^^^^^^^^^^^X D:X^^^^^.^^^^.^..^^^^^^^^^^^^^^^^^X D:X^^^^...^^...^^^...^^^^^^...^^^^X D:X^^^^.^....^^^^.^.....^..^..^^^^X D:X^^^^..^^^^^.....^...^..^^^B^^^^X D:X^^^P........^.....^^^^^^^^^^^^^X D:X^^^^^^...^^^^^^^^^^^^^^^^^^^^^^X D:X^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Starting position P:3:4 tome-235-src/lib/edit/misc.txt0000644000076400017500000000323411012107760014054 0ustar dgdg# File: misc.txt # Maximum number of towns M:T:100 # Maximum number of non random towns(must be < 20) M:t:5 # Maximum x size of the wilderness M:X:101 # Maximum y size of the wilderness M:Y:66 # Maximum number of randart parts in ra_info.txt M:Z:516 # Maximum number of monsters in r_info.txt # WARNING ! add one more to the real count for the player ghost !! M:R:1078 # Maximum number of monsters in re_info.txt # WARNING ! Use the exact amount of ego types used, if not you # will get weird results ! M:r:14 # Maximum number of items in k_info.txt M:K:819 # Maximum number of vaults in v_info.txt M:V:108 # Maximum number of terrain features in f_info.txt M:F:256 # Maximum number of alchemist recipes M:a:1000 # Maximum number of artifacts in a_info.txt M:A:219 # Maximum number of sets types in set_info.txt M:s:10 # Maximum number of ego-items in e_info.txt M:E:200 # Maximum number of dungeon types in d_info.txt M:D:31 # Maximum number of trap types in tr_info.txt M:U:176 # Maximum number of terrain types in wf_info.txt M:W:30 # Maximum number of owners types in ow_info.txt M:N:70 # Maximum number of building actions in ba_info.txt M:B:62 # Maximum number of store types in st_info.txt M:S:61 # Maximum size for "o_list[]" M:O:1024 # Maximum size for "m_list[]" M:M:768 # Maximum number of race types in p_info.txt M:P:R:22 # Maximum number of subrace types in p_info.txt M:P:S:10 # Maximum number of class types in p_info.txt M:P:C:32 # Maximum number of meta class types in p_info.txt M:P:M:1 # Maximum number of histories types in p_info.txt M:P:H:266 # Maximum number of skills in s_info.txt M:k:60 # Maximum number of traits in ab_info.txt M:b:50 tome-235-src/lib/edit/special.txt0000644000076400017500000000156111012107760014542 0ustar dgdg# Contains terrain parsings for the special levels now being kept in seperate map files # # Created for PernAngband 5.0.1 on 18/8/01 # Written by Mynstral (mynstral@thehelm.com) # Permanent Wall F:X:63:0 F: :63:0 # Granite Wall F:#:57:0 F:%:57:0 # Hidden Door F:+:48:0 # Normal Door F:D:32:0 # Floor F:.:1:0 # Tree F:T:96:0 # Mountain F:M:97:0 # Shallow Water F:w:84:0 F:V:84:0 # Deep Water F:W:187:0 # Shallow Lava F:l:86:0 # Deep Lava F:L:85:0 # Glass Wall F:G:188:0 # Illusion Wall F:I:189:0 # Treasure (random) on normal floor F:*:1:0:0:* # Trap (random) on normal floor F:^:1:0:0:0:0:0:* # down staircase F:>:7:0 # between gates F:4:160:0:0:0:0:0:0:-1 F:5:160:0:0:0:0:0:0:-1 F:6:160:0:0:0:0:0:0:-1 F:7:160:0:0:0:0:0:0:-1 F:A:160:0:0:0:0:0:0:-1 F:B:160:0:0:0:0:0:0:-1 F:C:160:0:0:0:0:0:0:-1 F:E:160:0:0:0:0:0:0:-1 F:F:160:0:0:0:0:0:0:-1 F:0:160:0:0:0:0:0:0:-1 tome-235-src/lib/edit/nirnaeth.map0000644000076400017500000000226711012107760014674 0ustar dgdg# Permanent wall F:X:63:3 # up stairs F:<:6:3 # Floor with dirt F:.:1:5 # Dirt (no-tele) F:s:88:5 # Shallow water F:V:84:5 # Dirt with Olog F:a:88:5:538 # Dirt with Cave Troll F:b:88:5:496 # Dirt with with Eldrak F:c:88:1:620 # Dirt with with Ettin F:e:88:1:621 # Dirt with with War troll F:f:88:1:631 # Dirt with with Hru F:g:88:1:709 # Dirt with Ulik the Troll F:h:88:5:729 # Dirt with Ancient green dragon F:i:88:5:618 # Dungeon D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X...a.bab....f.....f.XXXXXXXXXXX D:X..ab...b..ff..aa..b..XXXXXXXXXX D:X.aa..b..fff...a..g.f.b.XXXXXXXX D:Xab.....b....f.......f..bf..XXXX D:X..b.f......ff.f..aa...f..b.XXXX D:X...ff..f..ff.c.a..f.g.a..fXXXXX D:Xb.f....fff.ff...aaa....f..XXXXX D:X...ff...ff...f......aa..a..XXXX D:Xb.ff.a...f...bbb..a..aa.....XXX D:X.f.a...a....bbebb......f.fa.XXX D:X.....a.....bbecebb..g.a.a....XX D:X.a.a....aa.beccceb....f.a..c.XX D:X......a..f.bbecebba.f....ea...X D:XX.b.aa.f..f.bbebb...a.aa...g.aX D:XX..bb...a..f.bbb..a..a..aae..iX D:XXX....aa.aa.f...aa...e..b..h..X D:XXXXXX........bb...g....aa...gcX D:XXXXXXXX.g..aa...a...a.e...ac.:7:0 # Permanent wall F:X:61:4 # Glacial Wall F:#:215:4 # Ice Wall F:M:95:4 # Deep Water F: :187:4 # Fog F:*:210:4 # Shallow water F:~:84:4 # Ice F:.:90:4 # Hidden Door F:+:48:0 # Normal Door F:=:32:0 # Ash F:,:93:4 # Fake wall F:I:189:4 ### Monsters # Leviathan in deep water F:L:187:0:782 # Greater Kraken in deep water F:K:187:0:775 # Lesser Kraken in deep water F:k:187:0:740 # Giant Squid in deep water F:s:187:0:482 # Killer Whale in deep water F:w:187:0:917 # Drowned Soul in shallow water F:G:84:0:895 # Ancient White Dragon on ice F:D:90:0:617 # Mature White Dragon on ice F:d:90:0:549 # Ice Troll on ice F:T:90:0:454 # Headless Ghost on ice F:H:90:0:533 # Shadow on ice F:g:90:0:665 # Young White Dragon on ice F:b:90:0:460 # Zombified Human on ice F:z:90:0:229 # Greater mummy on ice F:m:90:0:522 # Cold Hound on ice F:Z:90:0:308 # Giant White Dragon Fly on ice F:F:90:0:250 # Ice Elemental on ice F:E:90:0:570 # Yeti on ice F:Y:90:0:154 # Ice skeleton on ice F:i:90:0:379 # Skeleton human on ice F:h:90:0:228 # Ghost on ice (apologies to Eldridge Cleever) F:W:90:0:477 # Hand druj on ice F:S:90:0:748 # Eye druj on ice F:J:90:0:749 # Dread on ice F:o:90:0:534 # Dreadmaster on ice F:O:90:0:690 # Night mare on ice F:q:90:0:622 # Random monster (upto 5 levels ood) on ice F:&:90:0:*40 # Random monster (upto 9 levels ood) and # Random object (upto 7 levels ood) on ice F:8:90:0:*44:*42 # Treasure (random) on ice F:$:90:0:0:*47 # Treasure (good) on ice F:%:90:0:0:*60 # Trap (random) on ice F:^:90:0:0:0:0:0:* # Trap (random) on shallow water F:t:84:0:0:0:0:0:* # Trap (random) on fog F:@:210:0:0:0:0:0:* # Human skeleton on ice F:x:90:0:0:395 ### Between Gates # between gate 3: was 711 F:3:160:6:0:0:0:0:0:1136 # between gate A: was 6247 F:A:160:6:0:0:0:0:0:6761 # between gate 4: was 3339 F:4:160:6:0:0:0:0:0:3853 # between gate B: was 3085 F:B:160:6:0:0:0:0:0:3599 ### Guaranteed Items # The Mage Staff of Forochel F:!:90:0:0:0:0:213 ### Level Design D:XXXXXXXXXXXXXXXX XXXXXXXXXXXX XXXXXXX XXXXXXXXXXXXXXX XXXX D:X###############..~ .#. k w ~.#XX######### .~~ s G..#####.. w .###.######X##~~ .GX.### D:X####%####...~ ~.~ s .#.X#~~.##### .~ s w G..#.##.#.XGG~XXk~.####A####.~X ~~.X... D:X##%#$#######...~ w wXXXXXX#XXXX###XXX #~XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..XX....~.XX X#xX.#..#.#G. w ~X G~~ D:X##$#########.... s XXXTT^...~.~#####w~###~~~~8....**.tE.&E ^^.M^.xx.....x..ZZ..^XTTTT M...GG.~.. w G.###~XX~~#XX . s X D:X#########...~ w XXXTTTT.^..x~.H#### ###~~D....8**.~M~.E..M^.MM^..xh.h...ZZZZ^~M.,.,.,.~~ .G...~~ ~###. w . w M.d. D:X#####.x.x~~~ XXXTTTXXXMxx.H.####### ~##~~~8...#.**.~tE&EE^^~%M^.h.x.E.xh.ZZ..^X.,.^....~ ...G.~ s ~# XX ~~ w X D:X######...~~ MM~ w XXX^^XXX.MMMxx...G#####w ~#~.~..&...**E.MEt.^^.MM^~..i.....ZZZZ^~M.,.,,.gM.~.,~.,G.G~~ G~. G~.MM XX..~ D:X##.....~~ XXX^E=^XX$b.MMMMxH..HG#.## w ~#~##~8....*E~.&EM^^.M^h..i..x.x..ZZ..^XTTTTX.,.,~........~.G~~..w . G~...G~X D:X...~~~ K XXX^^EXXXX$$$..MMXXXXXXX#### #####XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX..,.X..M~.........~G..G ~~.G...G~ D: ~~~ w XXX^^EXXXdX%d$$b$$XXd~~~~##### s ###.,.W.**,.x.,.,.,.,.,.***,,....,x....,,.SX.,.,.,..,o.,.,.~~.G..~.G..G..~X k D: w MMM. w XXX^E^XXX.,*XDDd$$$XXd$..~~~~#### ###.,.,.,.**..,.,i.,.,W,.,**..z.,.,.q...g.,......~.,.,.,.,.~.~..F.~M~......~ D: MM. XXX4EEXXXi^**.XX%%$dXX$d$.H#####~G~~####.~.,~..,.h*,,~,.,.,.,~,.,.,.H.,.~.,..~,.,,,.~,.,.~.,.,.X.~,g.~~..~.~..,..,X D: s XXXBXXXXX^.**.W.,XDD%XXb$$b####..G~~~G###~.,,.,.,.,...,,.x,.~.,.,~..,.~.,.,~,.,.,,.,.,~,.,.,.~,.,..,X.,.***.~***,W.,X D: XXX.o..X.g***i.*.,.XX%XX######^^^^t ##ttt^^^^^t^^^^^^t^^^^^t^^^^^^^t^^^^^^t^^^^t^^tt^^^tt^^^^t^tXo..x************X D: k XXX^E..o.XX8.****,.g..XXX..#........~~~~~ttt###~~.,.G~.......XXXXX..~,..,,..,,.~.,..,.,..,,..,.,x..,.ooX******W***g.*.g*X D: XXX%S^^E..ooX,*****,..,.X.....h........XXX~~~tt#tt w ~~G~...XXXXXXX.,**.,..D.**.G.,~,..XXX...~~~.....o8X***.~.,.****$$..X D: XX%%%^mm.E..oXH**.^.*i.....#.....i..*..XXXXX~~ G~~.XXXXXXXXX~.*..,.,*..~,..,.,XXXXX...~..,.XXXXXo.W.$$.g.x....o.X D: XXX%S^^E..ooX8.*~~...,~~##...,..,.***,.XXX~G~ k ~~~~XXXXXXX.,.*. g...*..x..W.~.XXX.***.,,o..oO8X.o.,.o.xx$$$XXXXX D: XXX^E..o.XXH.###....###~~~.,h..,.*.,..~~.~~ s ~~.XXXXX.~..**...i~**.....~.,,.,,.***~,,,.oXXXXXXXXXXXXXXXX.!.X D: s XXX.o..X&..w~##..##~~~X~^^^^^^^^^^t^ttt^tt w tt^tttt^^tt^^^^^ttt^^^^ttt@@^^^^ttt^^^^^ttt@^^ttXXXW ^^.M*.t^oo.^^...X s D: ~~~ XXX>XXH~G..#####~G~~Gt..,.,..,.,xx..x ~~~ i~~xx.~...x....~.~..~..,~..***..~..~...,~.~*.~.XXXE.^^H..SM.~^.oo....JX D: ~~....~~ XXX$8w~.^####G~G ~i.XX.,,.,...........G~~~s~~ iiF~...........~.......x.,.**~....,~....~.*XXX.EE.W.^^.M*.~^^^o^O^..X D: ~.#..#..~~ XXX8##t..##~#.G.t..XX..,H...,.W...,...,~~...,...*,,.x...,.i.....g.....**.........XXXXXXX...EE.^^H..SM.~.^oo...^JX D: ~.##.##..~ XXX###GG~~~*h~.^..XX.....,....,.W...,.G....W.***...,...,...,....,...,**..q....SX3tttW#...EE.W.^^.M*.t.oo.^.^.XX D: ~~.###..~~ X##.##~~G^~~~~i*^XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX~~ D: ~~...###.~ k ~###X.G~~@Gh~x*~^..^i.zX8~i.~..h....zzzXiX..^$.T.t$......F.t..XX..^TTT*..M..Y....^.Y.^*.^..~....X.x..x~. 2 -> 3 -> 50 -> 51 -> 52 -> 53. # RohanKnight: 84 -> 85 -> 50 -> 51 -> 52 -> 53. # Half-Ogre: 74 -> 20 -> 2 -> 3 -> 50 -> 51 -> 52 -> 53. # Beorning: 75 -> 76 -> 20 -> 2 -> 3 -> 50 -> 51 -> 52 -> 53. # Half-elf: 4 -> 1 -> 2 -> 3 -> 50 -> 51 -> 52 -> 53. # Elf, Wood-elf: 5 -> 6 -> 9 -> 54 -> 55 -> 56. # High-elf: 7 -> 8 -> 9 -> 54 -> 55 -> 56. # Dark-elf: 69 -> 70 -> 71 -> 72 -> 73. # Hobbit: 10 -> 11 -> 3 -> 50 -> 51 -> 52 -> 53. # Gnome: 13 -> 14 -> 3 -> 50 -> 51 -> 52 -> 53. # Dwarf: 16 -> 17 -> 18 -> 57 -> 58 -> 59 -> 60 -> 61. # Petty-Dwarf: 87 -> 88 -> 18 -> 57 -> 58 -> 59 -> 60 -> 61. # Thunderlord: 89 -> 90 -> 93 -> 94. # Maia: 91 -> 92 -> 93 -> 94. # Ent: 95 -> 96. # Troll: 22 -> 23 -> 24 -> 62 -> 63 -> 64 -> 65 -> 66. # Orc 25 -> 26 -> 27 -> 28 -> 80 -> 81 -> 65 -> 66. # Yeek: 29 -> 3 -> 50 -> 51 -> 52 -> 53. # (not used: 78 -> 79 -> 80 -> 81 -> 65 -> 66.) # Kobold: 82 -> 83 -> 80 -> 81 -> 65 -> 66. # Deathmold: 100 -> 101 -> 102 -> 103 -> 104. H:0:10:1:2:25:You are the illegitimate and unacknowledged child H:1:20:1:2:35:You are the illegitimate but acknowledged child H:2:95:1:2:45:You are one of several children H:3:100:1:2:50:You are the first child H:4:40:2:3:65:of a Serf. H:5:65:2:3:80:of a Yeoman. H:6:80:2:3:90:of a Townsman. H:7:90:2:3:105:of a Guildsman. H:8:96:2:3:120:of a Landed Knight. H:9:99:2:3:130:of a Noble Lord. H:10:100:2:3:140:of the Royal Blood Line. H:11:20:3:50:20:You are the black sheep of the family. H:12:80:3:50:55:You are a credit to the family. H:13:100:3:50:60:You are a well-liked child. H:14:25:4:1:40:Your mother was of the Avari. H:15:40:4:1:50:Your father was of the Avari. H:16:65:4:1:60:Your mother was of the Nandor. H:17:80:4:1:60:Your father was of the Nandor. H:18:96:4:1:70:Your mother was of the Sindar. H:19:99:4:1:70:Your father was of the Sindar. H:20:100:4:1:100:Your ancestry traces to Elrond. H:21:60:5:6:50:You are one of several children H:22:100:5:6:55:You are the only child H:23:40:6:9:40:of an Avarin H:24:70:6:9:50:of a Nandorin H:25:100:6:9:60:of a Sindarin H:26:60:7:8:50:You are one of several children H:27:100:7:8:55:You are the only child H:28:75:8:9:50:of a Telerin H:29:95:8:9:55:of a Noldorin H:30:100:8:9:60:of a Vanyarin H:31:40:9:54:80:Ranger. H:32:70:9:54:90:Archer. H:33:87:9:54:110:Warrior. H:34:95:9:54:125:Mage. H:35:99:9:54:140:Prince. H:36:100:9:54:145:King. H:37:85:10:11:45:You are one of several children of a Hobbit H:38:100:10:11:55:You are the only child of a Hobbit H:39:20:11:3:55:Bum. H:40:30:11:3:80:Tavern Owner. H:41:40:11:3:90:Miller. H:42:50:11:3:100:Home Owner. H:43:80:11:3:110:Burglar. H:44:95:11:3:115:Warrior. H:45:99:11:3:125:Mage. H:46:100:11:3:140:Clan Elder. H:47:85:13:14:45:You are one of several children of a Gnome H:48:100:13:14:55:You are the only child of a Gnome H:49:20:14:3:55:Beggar. H:50:50:14:3:70:Braggart. H:51:75:14:3:85:Prankster. H:52:95:14:3:100:Warrior. H:53:100:14:3:125:Mage. H:54:25:16:17:40:You are one of two children of a Dwarven H:55:100:16:17:50:You are the only child of a Dwarven H:56:10:17:18:60:Thief. H:57:35:17:18:80:Smith. H:58:75:17:18:90:Miner. H:59:90:17:18:110:Warrior. H:60:99:17:18:130:Priest. H:61:100:17:18:150:King. H:62:15:18:57:10:You are the black sheep of the family. H:63:85:18:57:50:You are a credit to the family. H:64:100:18:57:55:You are a well liked child. H:65:100:20:2:50:You are the adopted child H:66:100:22:23:50:You are the offspring of a H:67:30:23:24:20:Forest-Troll H:68:60:23:24:25:Cave-Troll H:69:75:23:24:30:Hill-Troll H:70:90:23:24:35:Stone-Troll H:71:95:23:24:40:Snow-Troll H:72:100:23:24:45:Water-Troll H:73:25:24:62:50:Worker. H:74:95:24:62:55:Warrior. H:75:99:24:62:65:Shaman. H:76:100:24:62:80:Clan Chief. H:77:100:25:26:50:You are one of several children of H:78:40:26:27:40:a Snaga H:79:80:26:27:50:an Orc H:80:100:26:27:60:an Uruk H:81:30:27:28:20:Slave H:82:60:27:28:50:Archer H:83:90:27:28:60:Warrior H:84:95:27:28:80:Shaman H:85:100:27:28:100:Chieftain H:86:30:28:80:50:from the Misty Mountains. H:87:60:28:80:50:from the Grey Mountains. H:88:90:28:80:70:from the orc-hold of Mount Gundabad. H:89:100:28:80:80:from the Pits of Angband. H:90:25:29:3:50:You are one of five children of a blue Yeek. H:91:75:29:3:75:You are one of five children of a brown Yeek. H:92:100:29:3:100:You are one of five children of a master Yeek. H:93:20:50:51:50:You have dark brown eyes, H:94:60:50:51:50:You have brown eyes, H:95:70:50:51:50:You have hazel eyes, H:96:80:50:51:50:You have green eyes, H:97:90:50:51:50:You have blue eyes, H:98:100:50:51:50:You have blue-gray eyes, H:99:70:51:52:50:straight H:100:90:51:52:50:wavy H:101:100:51:52:50:curly H:102:30:52:53:50:black hair, H:103:70:52:53:50:brown hair, H:104:80:52:53:50:auburn hair, H:105:90:52:53:50:red hair, H:106:100:52:53:50:blond hair, H:107:10:53:0:50:and a very dark complexion. H:108:30:53:0:50:and a dark complexion. H:109:80:53:0:50:and an average complexion. H:110:90:53:0:50:and a fair complexion. H:111:100:53:0:50:and a very fair complexion. H:112:85:54:55:50:You have light grey eyes, H:113:95:54:55:50:You have light blue eyes, H:114:100:54:55:50:You have light green eyes, H:115:75:55:56:50:straight H:116:100:55:56:50:wavy H:117:75:56:0:50:black hair, and a fair complexion. H:118:85:56:0:50:brown hair, and a fair complexion. H:119:95:56:0:50:blond hair, and a fair complexion. H:120:100:56:0:50:silver hair, and a fair complexion. H:121:99:57:58:50:You have dark brown eyes, H:122:100:57:58:60:You have glowing red eyes, H:123:90:58:59:50:straight H:124:100:58:59:50:wavy H:125:75:59:60:50:black hair, H:126:100:59:60:50:brown hair, H:127:25:60:61:50:a one foot beard, H:128:60:60:61:51:a two foot beard, H:129:90:60:61:53:a three foot beard, H:130:100:60:61:55:a four foot beard, H:131:100:61:0:50:and a dark complexion. H:132:60:62:63:50:You have slime green eyes, H:133:85:62:63:50:You have puke yellow eyes, H:134:99:62:63:50:You have blue-bloodshot eyes, H:135:100:62:63:55:You have glowing red eyes, H:136:33:63:64:50:dirty H:137:66:63:64:50:mangy H:138:100:63:64:50:oily H:139:33:64:65:50:sea-weed green hair, H:140:66:64:65:50:bright red hair, H:141:100:64:65:50:dark purple hair, H:142:25:65:66:50:and green H:143:50:65:66:50:and blue H:144:75:65:66:50:and white H:145:100:65:66:50:and black H:146:33:66:0:50:ulcerous skin. H:147:66:66:0:50:scabby skin. H:148:100:66:0:50:leprous skin. H:149:85:69:70:45:You are one of several children of a Dark Elven H:150:100:69:70:55:You are the only child of a Dark Elven H:151:50:70:71:60:Warrior. H:152:80:70:71:75:Warlock. H:153:100:70:71:95:Noble. H:154:100:71:72:50:You have black eyes, H:155:70:72:73:50:straight H:156:90:72:73:50:wavy H:157:100:72:73:50:curly H:158:100:73:0:50:black hair and a very dark complexion. H:159:25:74:20:25:Your mother was an Ogre, but it is unacknowledged. H:160:100:74:20:25:Your father was an Ogre, but it is unacknowledged. H:161:90:75:76:50:You are a descendant of Beorn to the H:162:100:75:20:100:Your father was Beorn. H:163:13:76:20:55:9th degree. H:164:25:76:20:60:8th degree. H:165:38:76:20:65:7th degree. H:166:50:76:20:70:6th degree. H:167:63:76:20:75:5th degree. H:168:75:76:20:80:4th degree. H:169:88:76:20:85:3rd degree. H:170:100:76:20:90:2nd degree. H:171:100:78:79:50:You are one of several children of H:172:50:79:80:50:a Brown Yeek. H:173:75:79:80:50:a Blue Yeek. H:174:95:79:80:85:a Master Yeek. H:175:100:79:80:120:Boldor, the King of the Yeeks. H:176:25:80:81:50:You have pale eyes, H:177:50:80:81:50:You have glowing eyes, H:178:75:80:81:50:You have tiny black eyes, H:179:100:80:81:50:You have shining black eyes, H:180:20:81:65:50:no hair at all, H:181:40:81:65:50:short black hair, H:182:60:81:65:50:long black hair, H:183:80:81:65:50:bright red hair, H:184:100:81:65:50:colourless albino hair, H:185:100:82:83:50:You are one of several children of H:186:40:83:80:50:a Small Kobold. H:187:75:83:80:55:a Kobold. H:188:95:83:80:65:a Large Kobold. H:189:100:83:80:100:Mughash, the Kobold Lord. H:190:85:84:85:45:You are one of several children H:191:100:84:85:50:You are the first child H:192:60:85:50:40:of a Serf. H:193:85:85:50:55:of a Devoted Mercenary. H:194:96:85:50:60:of a Landed Knight. H:195:99:85:50:100:of a Marshal of the Riddermark. H:196:100:85:50:120:of a King of the Rohirrim. H:197:100:87:88:89:You are one of several children of H:198:30:88:18:20:a Petty-Dwarf Slave. H:199:50:88:18:40:a Petty-Dwarf Thief. H:200:70:88:18:60:a Petty-Dwarf Smith. H:201:90:88:18:75:a Petty-Dwarf Miner. H:202:95:88:18:100:a Petty-Dwarf Shaman. H:203:100:88:18:100:Mim, Betrayer of Turin. H:204:85:89:90:50:You are one of many Manwe Maia. H:205:100:89:90:60:You are the one of the most famous Manwe Maia. H:206:90:90:93:100:Your eagle looks very good. H:207:100:90:93:120:Your eagle is splendid. H:208:10:91:92:20:You are a unnoticed minion of H:209:25:91:92:30:You are a minor servant of H:210:45:91:92:40:You are a subject of H:211:65:91:92:50:You have attached yourself to H:212:85:91:92:65:You are associated with H:213:95:91:92:80:You are a notable follower of H:214:100:91:92:100:You are a celebrated assistant to H:215:20:92:93:55:Nessa. H:216:40:92:93:60:Vana. H:217:50:92:93:65:Tulkas. H:218:80:92:93:75:Mandos. H:219:90:92:93:80:Nienna. H:220:95:92:93:90:Varda. H:221:100:92:93:95:Manwe. H:222:100:93:94:50:In the past you dwelt on earth in the form of H:223:25:94:0:50:various animals. H:224:55:94:0:55:a spirit of forest and river. H:225:70:94:0:60:a beneficent but unseen force. H:226:96:94:0:70:a wise and ancient counsellor. H:227:100:94:0:80:a Wizard of legend. H:228:30:95:96:30:You are of an unknown generation of the Ents. H:229:40:95:96:50:You are of the third generation of the Ents. H:230:60:95:96:60:You are of the second generation of the Ents. H:231:100:95:96:80:You are one of the first beings who awoke on Arda. H:232:50:96:0:50:You have green skin and inflexible members. H:233:100:96:0:50:You have brown skin and inflexible members. H:234:10:100:101:30:You were born in dirty bilge-water, H:235:20:100:101:35:You were born in dirty straw, H:236:30:100:101:40:You were born in wet mud, H:237:40:100:101:45:You were born in a pile of dust, H:238:50:100:101:50:You were born in sand, H:239:60:100:101:50:You were born in pebbles, H:240:70:100:101:55:You were born in a kobold corpse, H:241:80:100:101:60:You were born in dragon droppings, H:242:90:100:101:65:You were born in a pile of bones, H:243:100:100:101:70:You were born in a corpse of a mighty hero, H:244:10:101:102:30:created by rotting flesh. H:245:20:101:102:35:created by a kobold magician. H:246:30:101:102:40:created by a corrupted apprentice. H:247:40:101:102:45:created by a curious mage apprentice. H:248:50:101:102:50:created by an evil Symbiant. H:249:60:101:102:50:created by a practicing Necromancer. H:250:70:101:102:55:created by the Mutant Breeders. H:251:80:101:102:60:created by a curious adventurer. H:252:90:101:102:65:called to life by the Witch-King of Angmar. H:253:100:101:102:70:called to life by Sauron himself. H:254:100:102:103:50:Since then you have given life to H:255:10:103:104:30:no H:256:20:103:104:35:one weak-willed H:257:30:103:104:40:two H:258:40:103:104:45:three H:259:50:103:104:50:four H:260:60:103:104:50:five H:261:70:103:104:55:about twenty H:262:80:103:104:60:dozens of H:263:90:103:104:65:hundreds of H:264:100:103:104:70:uncounted multitudes of H:265:100:104:0:50:foul offspring. ############################################################################## ############################################################################## ############################################################################## ############################################################################## # M:N:idx:color:Meta class name # M:C:class name I: M:N:0:U:Classes -- The Classes of Middle-earth M:C:Warrior M:C:Archer M:C:Rogue M:C:Mage M:C:Priest M:C:Loremaster #M:C:Test #M:C:Chaos-Warrior #M:N:1:B:Spellcasters -- Magic is The One True Way #M:N:2:y:Priests -- Hail the powers of the Ainur #M:C:Mindcrafter #M:N:3:G:Beastfriends -- Monsters are fun #M:C:BeastMaster #M:N:4:v:Others -- The way to your independence #M:C:Harper #M:C:Merchant #M:N:5:o:Tests -- Test is you dare ! #M:C:Test #M:C:Blade #M:C:Black-Knight tome-235-src/lib/edit/s_doom.map0000644000076400017500000001360111012107760014336 0ustar dgdg# Mount Doom ### Terrain Features # Permanent Wall F:X:177:0 # Lava Wall F:#:177:0 F: :177:0 # Great Fire F:$:178:0 # Fire F:%:205:0 # Hidden Door F:+:48:0:0:0:0:0:0:0:177 # Normal Door F:D:32:0 # Shallow Lava F:.:86:0 # Deep Lava F:L:85:0 # Treasure (random) on shallow lava F:*:86:0:0:* # Trap (random) on deep lava F:^:85:0:0:0:0:0:* # Trap (random) on shallow lava F:t:86:0:0:0:0:0:* # up staircase F:<:6:0 ### Guaranteed Monsters # Greater Balrog on deep lava F:A:85:0:807 # Greater Balrog on shallow lava F:a:86:0:807 # Lesser Balrog on deep lava F:B:85:0:996 # Lesser Balrog on shallow lava F:b:86:0:996 # Pit Fiend on deep lava F:C:85:0:812 # Pit Fiend on shallow lava F:c:86:0:812 # Great Wyrm of Power on deep lava F:E:85:0:847 # Great Wyrm of Power on shallow lava F:e:86:0:847 # Bone Golem on deep lava F:F:85:0:1013 # Bone Golem on shallow lava F:f:86:0:1013 # Dracolisk on deep lava F:G:85:0:703 # Dracolisk on shallow lava F:g:86:0:703 # Nycadaemon on deep lava F:H:85:0:719 # Nycadaemon on shallow lava F:h:86:0:719 # Barbazu on deep lava F:I:85:0:720 # Barbazu on shallow lava F:i:86:0:720 # Plasma Hounds on deep lava F:J:85:0:726 # Plasma Hounds on shallow lava F:j:86:0:726 # Hell knight on deep lava F:K:85:0:731 # Hell knight on shallow lava F:k:86:0:731 # Nightcrawler on deep lava F:M:85:0:744 # Nightcrawler on shallow lava F:m:86:0:744 # Aether Hound on deep lava F:N:85:0:811 # Aether Hound on shallow lava F:n:86:0:811 # Eye druj on deep lava F:O:85:0:749 # Eye druj on shallow lava F:o:86:0:749 # Skull druj on deep lava F:P:85:0:750 # Skull druj on shallow lava F:p:86:0:750 # Great Hell Wyrm on deep lava F:Q:85:0:756 # Great Hell Wyrm on shallow lava F:q:86:0:756 # Nightwalker on deep lava F:R:85:0:768 # Nightwalker on shallow lava F:r:86:0:768 # Osyluth on deep lava F:S:85:0:773 # Osyluth on shallow lava F:s:86:0:773 # Great Wyrm of Many Colours on deep lava F:U:85:0:790 # Great Wyrm of Many Colours on shallow lava F:u:86:0:790 # Horned Reaper on deep lava F:V:85:0:811 # Horned Reaper on shallow lava F:v:86:0:811 # Bronze Golem on deep lava F:W:85:0:1015 # Bronze Golem on shallow lava F:w:86:0:1015 ### Random Monsters and/or Items # Random monster on deep lava F:!:85:0:*99 # Random monster on shallow lava F:1:86:0:*99 # Random monster (upto 10 levels ood) on deep lava F:@:85:0:*109 # Random monster (upto 10 levels ood) on shallow lava F:2:86:0:*109 # Random monster and # Random object on deep lava F:&:85:0:*99:*99 # Random monster and # Random object on shallow lava F:7:86:0:*99:*99 # Random monster (upto 10 levels ood) and # Random object (upto 5 levels ood) on deep lava F:(:85:0:*109:*104 # Random monster (upto 10 levels ood) and # Random object (upto 5 levels ood) on shallow lava F:9:86:0:*109:*104 D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X #%%NNLL...JJJ....LL# ############## X D:X ##### #NNNN...Ljjjjj..LLL# #############################################..1!!!!...L### X D:X##.LL## #nNNN...LLJJj.LLLLL# #L....&!&!&....L%%%%%%%L..mRR%R%%M%MML%LL...DL...!1&..@L%%# X D:X#LL<..# #nn.LL.LLLL...%%%LL# #..##########################################LLL....LLL%%%# X D:X##%LL## #....LLL%%LLL..^LLL# #.L# #LL2.t..q.LLL## X D:X ###+# #D##############+#######.L# ##%%.LLLL&L...# X D:X #!# #.# #.......L%%# ##%%LL..2...t.## X D:X #^# #.############ ##########+# XXXXXXXXXX ##.9.t.LLLLL## X D:X #.# #LL%%%%LL...p# #11111# X########X ###############.2..LQ#+# X D:X ##.# ############D## #11211# X#9....9#X #o.....t...# ###^L..#(# X D:X #L## ##%%V## #12221# XXXXXX#..$$..#XXXXXX#LLLLKkk...# ###D#### X D:X ##!# ##.VH^%## #12221# X######t....m######X#LLLLkkk.LL# #.# X D:X #.# ##.iH%%hv## #11211### X#sSSSrrt%.mVVVLLe#X#.LL.kkk...# ##.# X D:X ###D######### #tiI%HHhvL# #11111+9# X#rRssRr.%.mVvvm..#X#%...LLL...# ##Lo###### X D:X #.^t^LLL...L## #.LIH%Hc..# ######### X#.MmmM..%..MMLLL.#X#%%......L&# ##.L##EBBB# X D:X #.jJ%%%L....L# ##..ICCL.## X#.L..L..%ttL.....#X########D### #.####LAAB## X D:X #JJJJL%LLL&..# ##..L.L## X#9LLL...%..LL(LLq#X #..L..# #.LL..LB%%L# X D:X #J%J..LLL%%LL## ##.t.## X######......######X #L.#### ###..LL%%%L## X D:X #jJJ^..bL%LL..## ##D################# XXXXXX#.LUUL.#XXXXXX #.L# #.PL%%%@(L# X D:X ##....BABLL..L.## #.uLL^L..L%^^..L%%# X#.L%%LL#X #L.#### ###.L%LL..##X D:X ##....B%%L.....## #################L# X#LLL..t#X #..twW# #L..LL...+pX D:X ###....LLL...LLL####################.# X#%L..7.#X #####L# ###LL...1###oX D:X #9+L%%L...LLL....D.+..%%oF.%%^..%%LL.# X#LLLLt.#X #p# #%%%!@..## #tX D:X ##################L###.L###..###.L#### X#7tt.LL#X #.# ######### #EX D:X ##################.# ############## X#.LLLL.#X ######D###################LX D:X ##11!!!&LL.+(#L# X#LL%%LL#X #G..LLL.LL...D..LL....^LLL%X D:X ##1!!!%%%%Lp###L# X#L%%%%Q#X #..LF....K...##############X D:X ##!!%%%%%LLL..#.# XXXXDDXXXX########.LLLL..KKK..#### X D:X ##.LLLLLLL...+.# #%%%%%%%%%%%%%+LL7..LL.k..L+o7# X D:X ############### ############################### X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ### Starting location P:6:6 tome-235-src/lib/edit/s_crypt.map0000644000076400017500000000723611012107760014550 0ustar dgdg# Special level "The Forgotten Crypt" in The Pits of Angband # # Created for PernAngband 5.0.1 on 18/8/01 # Written by Mynstral (mynstral@thehelm.com) %:special.txt ### Guaranteed Monsters # Vampire on normal floor F:a:1:0:432 # Ghoul on normal floor F:b:1:0:418 # Rotting Quylthulg on normal floor F:c:1:0:633 # Master Vampire on normal floor F:d:1:0:520 # Vampire Lord on normal floor F:e:1:0:623 # Greater Rotting Quylthulg on normal floor F:f:1:0:802 # Ghast on normal floor F:g:1:0:327 # Undead Beholder on normal floor F:h:1:0:664 # Thuringwethil, the Vampire Messenger on normal floor F:i:1:0:755 # Black Reaver on normal floor F:j:1:0:798 ### Random Monsters and/or Items # Random monster (upto 5 levels ood) on normal floor F:&:1:0:*75 # Random monster (upto 11 levels ood) on normal floor F:@:1:0:*81 # Random monster (upto 9 levels ood) and # Random object (upto 7 levels ood) on normal floor F:8:1:0:*79:*77 # Random monster (upto 40 levels ood) and # Random object (upto 20 levels ood F:9:1:0:*110:*90 # Random monster (upto 3 levels ood) F:-:1:0:*73 # Random object (upto 7 levels ood) F:=:1:0:0:*77 ### Guaranteed Items # The Shadow Cloak of Luthien on normal floor F:1:1:0:0:0:0:49 D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XA.%@=-=-X8XX6...XX.XXLLL..c..LLLXX.XX...7XX8X=-=-...5X D:X.%%@=-=-X99X.....X..XLL..X%X..LLX..XhVV..X99X=-=-..GGX D:X%%@@...XXX9XX....XX.XX...X.X...XX.XXVVVVXX9XXX=-=.XGGX D:X@@@....X8X-=XgggggX..X..dX4Xd..X..XWWWWWX-=X8X-=-.XGGX D:X......XX%XX=XXgddgXX.XX8GXXXG8XX.XXWWWWXX-XX%XX...XGGX D:XIXIXXIX*X=X-=XgddggX..X8G^.^G8X..XWWWWWX-=X.X.X&&&XGGX D:XXXIXIXX*X-XX=XXggggXX.XXG^.^GXX.XXWWWWXX-XX.X.XX&&XGGX D:XXXXXIX**X=-X=-XIIXXXX..XG^.^GX..XVWWWVX=-XX.XddX@@XGGX D:X^^^^XX**X=-XX=XXIXIIXX.XX^.^XX.XXVVVVXX-XX%.XedXX@XGGX D:X^^f^Xe**X%%.X=-XXIXXIXbbX^.^XbbX.VV.XX=-XbX.XXXIX@IIGX D:X^^^XXe..X...XX=-XXXIXXXbXX.XXbXX...XX=-XXbX.XaaaXXXIGX D:X^^XXbbb.XGGG.XX=-XXIIXXbbXDXbbX...XX=-XXbbX.XaaaaXXIGX D:X^XXcbab.XVdG.cXX=-XXXIXXabXbaXX.XXX=-XXbbbX.XaaaaaXXfX D:X%XbbbbbbXVWG.%.XX.DbXDXXXbXbXXXDXbD.XX....G.XGGGGGGX%X D:XX.bababa%eWG.%.BXXXbcbbbbX.XbbbbcbXXXC...fX.%.......XX D:X%XbbbbbbXVWG.%.XX.DbXDXXXbXbXXXDXbD.XX....G.XGGGGGGX%X D:X8XXcbab.XVdG.cXX=-XXX.XXabXbaXXLXXX=-XXbbbX.XaaaaaXX.X D:X88XXbbb.XGGG.XX=-XX...XbbXDXbbXLLLXX=-XXbbX.XaaaaXXX.X D:XXXIXXe..X...XX=-XX.GGXXbXX.XXbXXILIXX=-XXbX.XaaaXXXX.X D:X9889Xe**X%%.X=-XXG.GdXbbX^.^XbbXILLIXX=-XbX.XXXIXhGG.X D:XXIXXXX**X=-XX=XXdG.GXX.XX^.^XX.XXILIIXX-XX%.XedXXXXX.X D:X99999X**X=-X=-XGGG..X..XI^a^IX..XILLIIX=-XX.XddX..eeeX D:XXXXIXXX*X=XX-XX....XX.XXI^a^IXX.XXILLIXX=XX.X.XX.GGGGX D:X^^^^^cX*X-X=-X.....X..X.I^a^I.X..XIILLIX=-X.X.Xdddd..X D:XllllX^XX%XX=XXG.GGXX.XX.IXXXI.XX.XXIILIXX-XX%XXXXXXX.X D:X^^^cl^=X8X-=XeG.GeX..X...X4X...X..XILLLIX-=X8X.aaaaaaX D:XLLX^l^-XXX9XXGG.GXX.XX...X.X...XX.XXLLLLXX9XXX.GGGGGGX D:X..L^l^=-X99X.....X..XWW..X%X..WWX..XLLLL.X99XXbbbbb..X D:X7.L^l^=-X8XX5...XX.XXWWW..c..WWWXX.XXLL.AXX8XXbbbbb.6X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XXXXXXXIIIIXIIIIXXIIIXIIIIXXIIIXXXXggggXc..cXaaaaXbb.CX D:XIIIIIXIXXIIIXXIIXIXIXIXXIXXIXIXXXXgddg%....%aaaa%bb..X D:XIXXXIXIXXXXXXXXIIIXIXIIXIXXIXIXXXXggggXc..cXaaaaXbbbbX D:XIXXXIIIXIIIIIIXXXXXIXXIXIXIIXIXXXXXXXXXXIIXXXXXXXXXXXX D:X..XXXXXXIXXXXIXIIIXIXIIXIXIXXIXXXXVVVjXddddXe..eX....X D:XB.IIIIIXIIIXIIXIXIXIIIXXIXIXIIXIIIVVVEX....%.ee.%.hh.X D:X..XXXXIXXXIXIXXIXIXXXXXIIXIXIXXIXXVVVjXddddXe..eX....X D:XIXXXIXIIIXIXIIIIXIIIIXIIXXIXIXXIXXXXXXXXXXXXXXXXXXDDXX D:XIXXXIXXXIIIXXXXXXXXXIXIXXIIXIIIIXXGGGGXgggdddeIVX....X D:XIIXXIXXXXXXXIIIIXXIXXXIIIIXXXXXXXXE.heDgggaaaiG1X....X D:XXIIIIIIIIIIIIXXIIIIXIIIXXXXXXXXXXXGGGGXgggdddeIVX..j>X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ### Starting location P:17:29 tome-235-src/lib/edit/thieves.map0000644000076400017500000000244311012107760014527 0ustar dgdg# Floor F:.:1:6 # Dark floor F:,:1:4 # Permanent wall F:X:61:4 # Lit permanent wall F:x:61:6 # Magically looked door F:M:38:22 # Looked door F:D:38:6 # Open door F:d:4:6 # up staircase F:<:6:8 # Floor with Novice rogue F:a:1:6:44 # Floor with Bandit F:b:1:6:150:43:* # Floor with novice warrior F:c:1:6:43 # Floor with novice mage F:e:1:6:46 # Dark floor with novice warrior F:f:1:4:43 # Floor with human skeleton F:z:1:6:0:395 # Dungeon layout D:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx D:x.....x....zx.....x.............x D:x.....x.....x.....x.............x D:x.....x.....x.....x.............x D:xxxMxxxxxdxxxxxdxxxxxxxxxDxxxxxxx D:XXx..........................xXXX D:XXx.xxxxx.xxxxx.xxxxxxxxx.xx,xXXX D:XXxxxXXXxxxXXXxxxXXXXXXXxxx,,,XXX D:XXXXxxxxxxxxxxxxxxxxxXXXXX,,,,,XX D:XXXXxe..xb..x...x...xXXXX,,,,,,,X D:XXXXx...x...xa..x...xXXXX,,,,,,,X D:XXXXx...x...x...x.a.xXXXX,,,,,,,X D:xxxxxxDxxxDxxxDxxxDxxXXXXX,,,,,XX D:x,,,x...............xXXXXXX,,,XXX D:x,,,x..x.........x..xXXXXXXX,XXXX D:x,,,D.....x...x.....D,,,,,,,,XXXX D:x,,,x..x.........x..xXXXXXXXXXXXX D:x,,,x...............xXXXXXXXXXXXX D:x,,,xxDxxxDxxxDxxxDxxXXXXXXXXXXXX D:x,,,x...x...x.a.xa..xXXXXXXXXXXXX D:x,,,xc..x.a.x...x...xXXXXXXXXXXXX D:xf,fx...x...x...x...xXXXXXXXXXXXX D:xxxxxxxxxxxxxxxxxxxxxXXXXXXXXXXXX # Starting position P:4:4 tome-235-src/lib/edit/tr_info.txt0000644000076400017500000004425511012107760014571 0ustar dgdg# This file comes from Angband64 written by Jurriaan Kalkman # and describes the traps items can have # # byte type; /* this goes into sval */ # s16b probability; /* probability of existence in 1000 */ # s16b another; /* does this trap easily combine in 1000 */ # s16b pvalinc; /* how much does this trap attribute to pval */ # byte difficulty; /* how difficult to disarm */ # byte level; /* minimum level - disenchantment trap at 200' is */ # /* not so nice */ # byte color; # cptr name; /* what name does this trap have */ # # d TERM_DARK |r TERM_RED |D TERM_L_DARK |R TERM_L_RED # w TERM_WHITE |g TERM_GREEN|W TERM_L_WHITE|G TERM_L_GREEN # s TERM_SLATE |b TERM_BLUE |v TERM_VIOLET |B TERM_L_BLUE # o TERM_ORANGE|u TERM_UMBER|y TERM_YELLOW |U TERM_L_UMBER # # b blue for stat traps # w white for teleport traps # o orange for dungeon rearrangement traps # v violet for summoning traps # y yellow for stealing/equipment traps # r red for other character affecting traps # g green for elemental bolt trap # B umber for elemental ball trap # R l red for arrow/dagger traps # W for compound trap!!! # don't use U or you'll get trapped doors that are indistinguishable from untrapped doors! # # an unknown character is multi-hued! # # N:type:name # I:diff:prob:another:pval:minlevel:damage:color # I:diff:prob: :minlevel: :color # D:description V:2.0.0 # # stat traps # N:1:Weakness Trap I:2:100:5:5:2:0d0:b D:A poisoned needle weakens you! F:FLOOR | CHEST | DOOR N:2:Weakness Trap I:5:100:5:5:20:0d0:b D:A poisoned needle seriously weakens you! F:FLOOR | CHEST | DOOR N:3:Weakness Trap I:7:100:5:8:40:0d0:b D:A poisoned needle permanently weakens you! F:FLOOR | CHEST | DOOR N:4:Intelligence Trap I:2:100:5:2:2:0d0:b D:A poisoned needle makes you feel stupid! F:FLOOR | CHEST | DOOR N:5:Intelligence Trap I:5:100:5:5:20:0d0:b D:A poisoned needle makes you feel very stupid! F:FLOOR | CHEST | DOOR N:6:Intelligence Trap I:7:100:5:8:40:0d0:b D:A poisoned needle makes you feel permanently stupid! F:FLOOR | CHEST | DOOR N:7:Wisdom Trap I:2:100:5:2:2:0d0:b D:A poisoned needle makes you feel naive! F:FLOOR | CHEST | DOOR N:8:Wisdom Trap I:5:100:5:5:20:0d0:b D:A poisoned needle makes you feel very naive! F:FLOOR | CHEST | DOOR N:9:Wisdom Trap I:7:100:5:8:40:0d0:b D:A poisoned needle makes you feel permanently naive! F:FLOOR | CHEST | DOOR N:10:Fumbling Fingers Trap I:2:100:5:2:2:0d0:b D:A poisoned needle makes you feel clumsy! F:FLOOR | CHEST | DOOR N:11:Fumbling Fingers Trap I:5:100:5:5:20:0d0:b D:A poisoned needle makes you feel very clumsy! F:FLOOR | CHEST | DOOR N:12:Fumbling Fingers Trap I:7:100:5:8:40:0d0:b D:A poisoned needle makes you feel permanently clumsy! F:FLOOR | CHEST | DOOR N:13:Wasting Trap I:2:100:5:2:2:0d0:b D:A poisoned needle makes you feel sickly! F:FLOOR | CHEST | DOOR N:14:Wasting Trap I:5:100:5:5:20:0d0:b D:A poisoned needle makes you feel very sickly! F:FLOOR | CHEST | DOOR N:15:Wasting Trap I:7:100:5:8:40:0d0:b D:A poisoned needle makes you feel permanently sickly! F:FLOOR | CHEST | DOOR N:16:Beauty Trap I:2:100:5:2:2:0d0:b D:A poisoned needle scars you! F:FLOOR | CHEST | DOOR N:17:Beauty Trap I:5:100:5:5:20:0d0:b D:A poisoned needle scars you horribly! F:FLOOR | CHEST | DOOR N:18:Beauty Trap I:7:100:5:8:40:0d0:b D:A poisoned needle scars you permanently! F:FLOOR | CHEST | DOOR # # miscellaneous traps # N:20:Trap of Curse Weapon I:5:10:0:12:20:0d0:y D:Your weapon will never be the same... F:FLOOR | CHEST | DOOR N:21:Trap of Curse Armour I:5:15:0:12:20:0d0:y D:Your armour doesn't exactly get better by setting off this trap... F:FLOOR | CHEST | DOOR N:22:Earthquake Trap I:5:20:0:10:10:0d0:o D:The ceiling collapses around you! F:FLOOR | CHEST | DOOR N:23:Poison Needle Trap I:1:50:50:3:2:0d0:r D:A poisoned needle pricks you! F:FLOOR | CHEST | DOOR N:24:Summon Monster Trap I:2:50:40:4:2:0d0:v D:Monsters defend the memory of the owner... F:FLOOR | CHEST | DOOR N:25:Summon Undead Trap I:4:25:40:6:10:0d0:v D:Undead rise from the grave to defend this! F:FLOOR | CHEST | DOOR N:26:Summon Greater Undead Trap I:8:10:50:20:20:0d0:v D:Greater undead defend this! F:FLOOR | CHEST | DOOR N:27:Teleport Trap I:3:100:50:3:2:0d0:w D:Now you know why nobody ever got close enough to disarm this trap... F:FLOOR | CHEST | DOOR N:28:Paralysing Trap I:1:100:20:2:2:0d0:r D:You suddenly cannot move! F:FLOOR | CHEST | DOOR N:29:Explosive Device I:3:100:80:0:3:3d8:r D:Ha! It explodes before your hands can illegally touch it! F:FLOOR | CHEST | DOOR N:30:Teleport Item Trap I:3:50:50:3:5:0d0:w D:The item magically disappears from your greedy hands! F:FLOOR | CHEST N:31:Lose Memory Trap I:6:30:30:6:10:0d0:r D:You suddenly can't remember what you were doing here... F:FLOOR | CHEST | DOOR N:32:Bitter Regret Trap I:9:15:20:9:20:0d0:r D:You already regret trying this... F:FLOOR | CHEST | DOOR N:33:Bowel Cramps Trap I:1:90:20:1:6:0d0:r D:Your stomach twists with a sharp pang! F:FLOOR | CHEST | DOOR N:34:Blindness/Confusion Trap I:4:100:50:4:6:0d0:r D:You suddenly can't see, and thinking is difficult too.... F:FLOOR | CHEST | DOOR N:35:Aggravation Trap I:2:100:50:2:3:0d0:o D:Your hear a high-pitched humming noise... F:FLOOR | CHEST | DOOR N:36:Multiplication Trap I:3:90:0:3:5:0d0:o D:The floor around you doesn't seem the same... F:FLOOR | CHEST | DOOR N:37:Steal Item Trap I:3:100:50:3:6:0d0:y D:The chest seems to swell, while your backpack feels lighter.. F:FLOOR | CHEST N:38:Summon Fast Quylthulgs Trap I:8:50:10:10:25:0d0:v D:Parts of the owner seem to return from somewhere else, as you slow in awe. F:FLOOR | CHEST | DOOR N:39:Trap of Sinking I:2:50:0:0:3:0d0:w D:A trapdoor opens up under you! F:FLOOR | DOOR N:40:Trap of Mana Drain I:4:100:50:3:4:0d0:r D:You suddenly can't think so clearly any more... F:FLOOR | CHEST | DOOR N:41:Trap of Missing Money I:2:100:50:2:2:0d0:y D:Money isn't everything, they say... F:FLOOR | CHEST | DOOR N:42:Trap of No Return I:5:20:10:4:8:0d0:y D:Do stay a while! F:FLOOR | CHEST | DOOR N:43:Trap of Silent Switching I:4:100:50:3:6:0d0:y D:You suddenly are a different person! F:FLOOR | CHEST | DOOR N:44:Trap of Walls I:6:100:50:2:10:0d0:o D:The room seems to shrink! F:FLOOR | CHEST | DOOR N:45:Trap of Calling Out I:10:100:100:5:15:0d0:v D:You hear something coming closer, much closer. F:FLOOR | CHEST | DOOR N:46:Trap of Sliding I:8:50:50:4:8:0d0:r D:Your feet seem to have a life of their own! F:FLOOR | CHEST | DOOR N:47:Trap of Charges Drain I:6:100:70:2:3:0d0:y D:You feel as if you've just lost something... F:FLOOR | CHEST | DOOR N:48:Trap of Stair Movement I:6:0:50:3:4:0d0:o D:The dungeon seems different... F:FLOOR | CHEST | DOOR N:49:Trap of New Trap I:5:100:5:0:4:0d0:o D:Somehow, disarming isn't over, you feel... F:FLOOR | CHEST | DOOR N:50:Trap of Scatter Items I:10:50:50:6:12:0d0:w D:You hear crashing sounds from all over the dungeon! F:FLOOR | CHEST | DOOR N:51:Trap of Decay I:4:100:50:4:4:0d0:r D:Your stomach isn't empty, but suddenly you think of food. F:FLOOR | CHEST | DOOR N:52:Trap of Wasting Wands I:6:100:40:4:5:0d0:y D:Your wands seem different... F:FLOOR | CHEST | DOOR N:53:Trap of Filling I:10:100:0:10:25:0d0:o D:The whole room vibrates in a strange way... F:FLOOR | CHEST | DOOR N:54:Trap of Drain Speed I:8:50:10:25:80:0d0:y D:You suddenly seem to have more time to self-reflect... F:FLOOR | CHEST | DOOR # # bolt traps # N:60:Lightning Bolt Trap I:2:80:5:3:2:2d8:g D:You are jolted with electricity! F:FLOOR | CHEST | DOOR | LEVEL1 N:61:Poison Bolt Trap I:2:80:5:3:2:2d8:g D:A blast of poison gas hits you! F:FLOOR | CHEST | DOOR | LEVEL1 N:62:Acid Bolt Trap I:2:80:5:3:2:2d8:g D:A jet of acid shoots out at you! F:FLOOR | CHEST | DOOR | LEVEL1 N:63:Cold Bolt Trap I:2:80:5:3:2:2d8:g D:You are suddenly very cold! F:FLOOR | CHEST | DOOR | LEVEL1 N:64:Fire Bolt Trap I:2:80:5:3:2:2d8:g D:You are suddenly very hot! F:FLOOR | CHEST | DOOR | LEVEL1 N:65:Plasma Bolt Trap I:6:80:5:6:15:10d12:g D:A bolt of plasma hits you! F:FLOOR | CHEST | DOOR | LEVEL3 N:66:Water Bolt Trap I:4:80:5:5:8:5d10:g D:A gush of water hits you! F:FLOOR | CHEST | DOOR | LEVEL2 N:67:Light Bolt Trap I:4:80:5:5:8:5d10:g D:There is a sudden flash of light around you! F:FLOOR | CHEST | DOOR | LEVEL2 N:68:Dark Bolt Trap I:4:80:5:5:8:5d10:g D:A bolt of pure elemental darkness hits you! F:FLOOR | CHEST | DOOR | LEVEL2 N:69:Shards Bolt Trap I:6:80:5:6:15:6d10:g D:A blast of crystal shards hits you! F:FLOOR | CHEST | DOOR | LEVEL3 N:70:Sound Bolt Trap I:6:80:5:6:15:10d12:g D:A sudden roar of sound hurts your eardrums! F:FLOOR | CHEST | DOOR | LEVEL3 N:71:Confusion Bolt Trap I:4:80:5:5:8:6d10:g D:A blast of confusion gas engulfs you! F:FLOOR | CHEST | DOOR | LEVEL2 N:72:Force Bolt Trap I:6:80:5:6:15:10d12:g D:A bolt of pure force hits you! F:FLOOR | CHEST | DOOR | LEVEL3 N:73:Inertia Bolt Trap I:6:80:5:6:15:10d12:g D:Your feet feel like lead! F:FLOOR | CHEST | DOOR | LEVEL3 N:74:Mana Bolt Trap I:8:80:5:9:25:15d16:g D:A bolt of pure magic hits you! F:FLOOR | CHEST | DOOR | LEVEL4 N:75:Ice Bolt Trap I:4:80:5:5:8:5d10:g D:A bolt of ice hits you! F:FLOOR | CHEST | DOOR | LEVEL2 N:76:Chaos Bolt Trap I:6:80:5:6:15:10d12:g D:A blast of raw chaos hits you! F:FLOOR | CHEST | DOOR | LEVEL3 N:77:Nether Bolt Trap I:8:80:5:9:25:15d16:g D:A bolt of negative energy hits you! F:FLOOR | CHEST | DOOR | LEVEL4 N:78:Disenchantment Bolt Trap I:8:80:5:9:25:15d16:g D:There is a static feeling in the air... F:FLOOR | CHEST | DOOR | LEVEL4 N:79:Nexus Bolt Trap I:6:80:5:6:15:10d12:g D:A bolt of nexus hits you! F:FLOOR | CHEST | DOOR | LEVEL3 N:80:Time Bolt Trap I:8:80:5:9:25:15d16:g D:Suddenly, several months pass by in a second! F:FLOOR | CHEST | DOOR | LEVEL4 N:81:Gravity Bolt Trap I:6:80:5:6:15:10d12:g D:Gravity suddenly warps around you! F:FLOOR | CHEST | DOOR | LEVEL3 # # ball traps # N:82:Lightning Ball Trap I:3:60:5:5:8:3d10:B D:A massive electrical charge shoots through you! F:FLOOR | CHEST | DOOR | LEVEL1 N:83:Poison Ball Trap I:3:60:5:5:8:3d10:B D:A large cloud of poison gas envelops you! F:FLOOR | CHEST | DOOR | LEVEL1 N:84:Acid Ball Trap I:3:60:5:5:8:3d10:B D:You are suddenly drenched in acid! F:FLOOR | CHEST | DOOR | LEVEL1 N:85:Cold Ball Trap I:3:60:5:5:8:3d10:B D:A blast of hideously cold air envelops you! F:FLOOR | CHEST | DOOR | LEVEL1 N:86:Fire Ball Trap I:3:60:5:5:8:3d10:B D:You are suddenly in the centre of a raging inferno! F:FLOOR | CHEST | DOOR | LEVEL1 N:87:Plasma Ball Trap I:8:60:5:8:20:12d18:B D:You are engulfed in plasma! F:FLOOR | CHEST | DOOR | LEVEL3 N:88:Water Ball Trap I:5:60:5:6:15:8d12:B D:A whirlpool engulfs you! F:FLOOR | CHEST | DOOR | LEVEL2 N:89:Light Ball Trap I:5:60:5:6:15:8d12:B D:A massive flash of light erupts around you! F:FLOOR | CHEST | DOOR | LEVEL2 N:90:Darkness Ball Trap I:5:60:5:6:15:8d12:B D:A large patch of darkness erupts around you! F:FLOOR | CHEST | DOOR | LEVEL2 N:91:Shards Ball Trap I:8:60:5:8:20:12d18:B D:A violent blast of crystal shards hits you! F:FLOOR | CHEST | DOOR | LEVEL3 N:92:Sound Ball Trap I:8:60:5:8:20:12d18:B D:BOOM! Your eardrums nearly explode! F:FLOOR | CHEST | DOOR | LEVEL3 N:93:Confusion Ball Trap I:5:60:5:6:15:8d12:B D:You are enveloped in a cloud of confusion gas! F:FLOOR | CHEST | DOOR | LEVEL2 N:94:Force Ball Trap I:8:60:5:8:20:12d18:B D:A violent blast of pure force smashes down around you! F:FLOOR | CHEST | DOOR | LEVEL3 N:95:Inertia Ball Trap I:8:60:5:8:20:12d18:B D:Suddenly, your entire body feels like lead! F:FLOOR | CHEST | DOOR | LEVEL3 N:96:Mana Ball Trap I:10:60:5:10:30:16d20:B D:You are hit by a blast of pure magic! F:FLOOR | CHEST | DOOR | LEVEL4 N:97:Ice Ball Trap I:5:60:5:6:15:8d12:B D:A massive blast of ice crystals engulfs you! F:FLOOR | CHEST | DOOR | LEVEL2 N:98:Chaos Ball Trap I:8:60:5:8:20:12d18:B D:A violent blast of raw chaos engulfs you! F:FLOOR | CHEST | DOOR | LEVEL3 N:99:Nether Ball Trap I:10:60:5:10:30:16d20:g D:A blast of energy from the netherworld engulfs you! F:FLOOR | CHEST | DOOR | LEVEL4 # N:type:name # I:diff:prob:another:pval:minlevel:color # D:description N:100:Disenchantment Ball Trap I:10:60:5:10:30:16d20:B D:You are hit by a blast of pure anti-magic! F:FLOOR | CHEST | DOOR | LEVEL4 N:101:Nexus Ball Trap I:8:60:5:8:20:12d18:B D:A ball of nexus hits you! F:FLOOR | CHEST | DOOR | LEVEL3 N:102:Time Ball Trap I:10:60:5:10:30:16d20:B D:Suddenly, several years pass by in a second! F:FLOOR | CHEST | DOOR | LEVEL4 N:103:Gravity Ball Trap I:8:60:5:8:20:12d18:B D:You suddenly feel gravity warp violently around you! F:FLOOR | CHEST | DOOR | LEVEL3 N:110:Arrow Trap I:2:100:0:5:2:0d0:R D:An arrow shoots out at you. F:FLOOR | CHEST | DOOR N:111:Bolt Trap I:2:100:0:5:5:0d0:R D:A bolt shoots out at you. F:FLOOR | CHEST | DOOR N:112:Seeker Arrow Trap I:2:100:0:6:10:0d0:R D:A seeker arrow shoots out at you. F:FLOOR | CHEST | DOOR N:113:Seeker Bolt Trap I:2:100:0:6:12:0d0:R D:A seeker bolt shoots out at you. F:FLOOR | CHEST | DOOR N:114:Poison Arrow Trap I:2:100:0:5:4:0d0:R D:A poisoned arrow shoots out at you. F:FLOOR | CHEST | DOOR N:115:Poison Bolt Trap I:2:100:0:6:6:0d0:R D:A poisoned bolt shoots out at you. F:FLOOR | CHEST | DOOR N:116:Poison Seeker Arrow Trap I:2:100:0:7:12:0d0:R D:A poisoned seeker arrow shoots out at you. F:FLOOR | CHEST | DOOR N:117:Poison Seeker Bolt Trap I:2:100:0:7:15:0d0:R D:A poisoned seeker bolt shoots out at you. F:FLOOR | CHEST | DOOR N:118:Broken Dagger Trap I:2:100:0:5:2:0d0:R D:An broken dagger shoots out at you. F:FLOOR | CHEST | DOOR N:119:Dagger Trap I:2:100:0:5:5:0d0:R D:A dagger shoots out at you. F:FLOOR | CHEST | DOOR N:120:Poison Broken Dagger Trap I:2:100:0:5:4:0d0:R D:A poisoned broken dagger shoots out at you. F:FLOOR | CHEST | DOOR N:121:Poison Dagger Trap I:2:100:0:6:6:0d0:R D:A poisoned dagger shoots out at you. F:FLOOR | CHEST | DOOR # # multiple arrows/daggers traps # N:122:Arrows Trap I:4:100:0:7:16:0d0:R D:Some arrows shoot out at you. F:FLOOR | CHEST | DOOR N:123:Bolts Trap I:4:100:0:7:18:0d0:R D:Some bolts shoot out at you. F:FLOOR | CHEST | DOOR N:124:Seeker Arrow Trap I:5:100:0:8:20:0d0:R D:Some seeker arrows shoot out at you. F:FLOOR | CHEST | DOOR N:125:Seeker Bolt Trap I:5:100:0:8:24:0d0:R D:Some seeker bolts shoot out at you. F:FLOOR | CHEST | DOOR N:126:Poison Arrows Trap I:5:100:0:8:18:0d0:R D:Some poisoned arrows shoot out at you. F:FLOOR | CHEST | DOOR N:127:Poison Bolt Trap I:6:100:0:8:20:0d0:R D:Some poisoned bolts shoot out at you. F:FLOOR | CHEST | DOOR N:128:Poison Seeker Arrows Trap I:7:100:0:9:27:0d0:R D:Some poisoned seeker arrows shoot out at you. F:FLOOR | CHEST | DOOR N:129:Poison Seeker Bolts Trap I:9:100:0:9:30:0d0:R D:Some poisoned seeker bolts shoot out at you. F:FLOOR | CHEST | DOOR N:130:Broken Daggers Trap I:4:100:0:6:12:0d0:R D:Some broken daggers shoot out at you. F:FLOOR | CHEST | DOOR N:131:Dagger Trap I:4:100:0:6:15:0d0:R D:Some daggers shoot out at you. F:FLOOR | CHEST | DOOR N:132:Poison Broken Daggers Trap I:5:100:0:7:18:0d0:R D:Some poisoned broken daggers shoot out at you. F:FLOOR | CHEST | DOOR N:133:Poison Daggers Trap I:6:100:0:7:23:0d0:R D:Some poisoned daggers shoot out at you. F:FLOOR | CHEST | DOOR N:140:Trap of Drop Item I:3:50:0:2:5:0d0:y D:A sudden sound startles you and you drop something! F:FLOOR | CHEST | DOOR N:141:Trap of Drop Items I:5:50:0:5:12:0d0:y D:A sudden sound startles you and you drop several things! F:FLOOR | CHEST | DOOR N:142:Trap of Drop Everything I:8:50:0:8:20:0d0:y D:A sudden sound startles you and you drop everything! F:FLOOR | CHEST | DOOR #-SC- N:150:Trap of Femininity I:4:30:5:0:10:2d8:r D:You feel like a new woman! F:FLOOR | CHEST | DOOR N:151:Trap of Masculinity I:4:30:5:0:10:2d8:r D:You feel like a new man! F:FLOOR | CHEST | DOOR N:152:Trap of Neutrality I:4:30:5:0:10:2d8:r D:You feel like a new woman... erm, a new man... er, WHAT did you say??? F:FLOOR | CHEST | DOOR N:153:Trap of Aging I:5:50:5:0:15:1d8:r D:You suddenly age very fast! F:CHEST | DOOR N:154:Trap of Growing I:3:75:5:0:5:1d8:r D:You begin to grow! F:FLOOR | CHEST | DOOR N:155:Trap of Shrinking I:3:75:5:0:5:1d8:r D:You begin to shrink! F:FLOOR | CHEST | DOOR #N:156: UNUSED #N:157: UNUSED N:158:Trap of Divine Anger I:6:100:5:0:15:0d0:G D:A voice booms out "Have a care, mortal!" F:FLOOR | CHEST | DOOR N:159:Trap of Divine Wrath I:9:50:5:0:30:0d0:G D:A voice booms out "Sacrilege!" F:FLOOR | CHEST | DOOR N:160:Hallucination Trap I:3:100:10:0:4:0d0:r D:Your vision is clouded by a blast of kaleidoscopic light! F:FLOOR | CHEST | DOOR # Bolt traps N:161:Greater Magic Missile Trap I:6:80:5:6:75:25d20:g D:A greater magic missile hits you! F:FLOOR | CHEST | DOOR | LEVEL3 #N:162:Foulness Trap #I:6:80:5:6:15:10d12:g #D:You feel foul! #F:FLOOR | CHEST | DOOR | LEVEL3 #N:163:Trap of Death Ray #I:8:80:5:9:25:15d16:g #D:A Ray of Death hits you! #F:FLOOR | CHEST | DOOR | LEVEL4 N:164:Trap of Holy Fire I:6:80:5:6:15:10d12:g D:Holy fire rises around you! F:FLOOR | CHEST | DOOR | LEVEL3 N:165:Trap of Hell Fire I:6:80:5:6:15:10d12:g D:Hellfire rises around you! F:FLOOR | CHEST | DOOR | LEVEL3 N:166:Psi Bolt Trap I:6:80:5:6:15:10d12:g D:Your mind is suddenly blasted! F:FLOOR | CHEST | DOOR | LEVEL3 N:167:Psi Drain Trap I:6:80:5:6:15:8d10:r D:You suddenly can't think clearly any more... F:FLOOR | CHEST | DOOR | LEVEL3 # Ball Traps ### this one *ought* to be a Nuke Ball trap, not plasma ball, as trap 87 ### is also plasma ball. I've put the description right in advance. #N:168:Plasma Ball Trap #I:8:60:5:8:20:12d18:B #D:A blast of radiation engulfs you! #F:FLOOR | CHEST | DOOR | LEVEL3 N:169:Psi Ball Trap I:8:60:5:8:20:12d18:B D:Your brain is suddenly blasted! F:FLOOR | CHEST | DOOR | LEVEL3 # Useful traps N:170:Acquirement Trap I:1:40:5:5:18:0d0:v D:Woah! F:FLOOR | DOOR # More bolt traps N:171:Greater Lightning Bolt Trap I:3:60:5:3:6:6d6:g D:You are jolted with electricity! F:FLOOR | CHEST | DOOR | LEVEL1 N:172:Greater Poison Bolt Trap I:3:60:5:3:6:6d6:g D:A blast of deadly poison gas hits you! F:FLOOR | CHEST | DOOR | LEVEL1 N:173:Greater Acid Bolt Trap I:3:60:5:3:6:6d6:g D:A jet of acid shoots out at you! It burns severely! F:FLOOR | CHEST | DOOR | LEVEL1 N:174:Greater Cold Bolt Trap I:3:60:5:3:6:6d6:g D:You are suddenly extremely cold! F:FLOOR | CHEST | DOOR | LEVEL1 N:175:Greater Fire Bolt Trap I:3:60:5:3:6:6d6:g D:You are suddenly extremely hot! F:FLOOR | CHEST | DOOR | LEVEL1 tome-235-src/lib/edit/ab_info.txt0000644000076400017500000000531211012107760014515 0ustar dgdg# File: ab_info.txt # This file is used to initialize the "lib/data/ab_info.raw" file, which is # used to initialize the "abilities" information for the ToME game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # The ToME abilities indexes are defined in "defines.h", and must not be changed. # If you want to add new ones, add them after the tome ones # N:idx:name # D:desc # I:cost(in skill points) # A:action mkey:action desc # Prerequisites # k:level:skill # S:level(linear mode):stats # a:needed ability # E:excluding ability:excluding ability # If you need more sophisticated prereqs use the HOOK_LEARN_ABILITY # Version stamp (required) # Do not forget to update misc.txt with an entry like the following : # Maximum number of traits in ab_info.txt # M:b:50 V:2.2.0 N:0:Spread blows D:If a monster dies to your attack but you still have blows left D:you won't lose the full turn, allowing you to attack some other D:monster in the same turn D:Prereq: Weaponmastery skill@30, Dex@17 I:5 k:30:Weaponmastery S:17:DEX N:1:Tree walking D:Allows you to walk in dense forest D:Prereq: Nature skill@20 I:7 k:20:Nature N:2:Perfect casting D:Allows you to reach 0% failure rate on spells D:Prereq: Magic skill@35 I:6 k:35:Magic N:3:Extra Max Blow(1) D:Increases your max possible blows number by 1 D:Prereq: Combat@10 I:7 k:10:Combat N:4:Extra Max Blow(2) D:Increases your max possible blows number by 1 D:Prereq: Combat@20, Extra Max Blow(1) I:7 k:20:Combat a:Extra Max Blow(1) N:5:Ammo creation D:Allows you to create shots, arrows and bolts from various materials D:Prereq: Archery@10 A:10:Forge ammo I:8 k:10:Archery N:6:Touch of death D:Your melee blows can insta-kill, but you only receive 1/3 of the experience D:Prereq: Necromancy@50, Combat@40, DEX@30, STR@30 A:100:Activate touch of death I:15 k:50:Necromancy k:40:Combat S:30:DEX S:30:STR N:7:Artifact Creation D:In combination with a high alchemy skill this ability will let you D:design your very own artifacts D:Prereq: Alchemy@40, INT@35, WIS@35 I:70 k:40:Alchemy S:35:INT S:35:WIS N:8:Far reaching attack D:You can attack an enemy one square far using a long polearm. D:At high levels of Polearm-mastery skill, you can even hit two enemies at once. D:Prereq: Combat@15, Polearm-mastery@15 I:10 A:102:Far reaching attack k:15:Combat k:15:Polearm-mastery N:9:Trapping D:Ability to set monster traps D:Prereq: Disarming@15 I:10 A:14:Set trap k:15:Disarming N:10:Undead Form D:Ability to turn into a weak undead being when you "die". D:You must then kill enough monsters to absorb enough life energy D:to come back to life. D:Prereq: Necromancy@30, INT@25 I:15 k:30:Necromancy S:25:INT tome-235-src/lib/edit/t_gondol.txt0000644000076400017500000003727011012107760014735 0ustar dgdg# File: Gondolin.txt # Gondolin: The Hidden Kingdom of the Noldor # Created by Akhronath (zzhou22876@aol.com) ############### Additional default terrain settings ############### # Default for Quest 13 = entrance is mountain F:z:97:3 # Default for Quest 14 = entrance is floor F:y:1:3 # Default for Quest 15 = entrance is floor F:x:1:3 # Default for Quest 23 = entrance is quest entrance F:w:8:3:0:0:0:0:0:23 # Decoration = Straight Road (B) F:":66:3 # Decoration = Straight Road (W) F:$:70:3 # Rare jewelry shop -- unusable yet, need finish quest F:!:63:3 # Between gate to minas anor -- unusable yet, need finish quest F:Z:63:3 #################### Quest 13 - Eol the Dark Elf #################### # Quest 13 assigned, entrance is quest entrance ?:[EQU $QUEST13 1] F:z:8:3:0:0:0:0:0:13 ?:1 #################### Quest 14 - Nirnaeth Arnoediad #################### # Quest 14 assigned, entrance is quest entrance ?:[EQU $QUEST14 1] F:y:8:3:0:0:0:0:0:14 # Quest 14 finished, reward is a rare jewelry shop ?:[EQU $QUEST14 5] F:!:74:3:0:0:0:0:0:42 ?:1 #################### Quest 15 - Invasion of Gondolin #################### # Quest 15 assigned, entrance is quest entrance ?:[EQU $QUEST15 1] F:x:8:3:0:0:0:0:0:15 ?:1 #################### Quest 16 - The last Alliance #################### # Quest 16 finished, reward is a between gate ?:[EQU $QUEST16 5] F:Z:176:3:0:0:0:0:0:1 ?:1 ############### Quest 23 - Wolves hut finished = house ############### ?:[EQU $QUEST23 2] F:w:74:3:0:0:0:0:0:7 ?:[EQU $QUEST23 5] F:w:74:3:0:0:0:0:0:7 ?:1 #################### Buildings #################### # h: Orange (Minstrel) # i: Red (Sorcery) # j: Green (Temple) # k: Violet (Chaos) # l: Dark Brown (Ranger) # m: White (Paladin) # Tower of the King F:a:74:3:0:0:0:0:0:27 # Library F:b:74:3:0:0:0:0:0:28 # Castle: Gondolin Plot F:B:75:3:0:0:0:0:0:4 # The White Tree:Aerandir:High-Elf F:c:74:3:0:0:0:0:0:29 # Craftsmaster F:d:74:3:0:0:0:0:0:30 # Earth-Dome F:e:74:3:0:0:0:0:0:31 # Prophet F:f:74:3:0:0:0:0:0:12 # Minstrels Haven F:h:74:3:0:0:0:0:0:32 # Star-Dome:Sulraen:High-Elf F:i:74:3:0:0:0:0:0:33 # Valarin Temple F:j:74:3:0:0:0:0:0:34 # Sea-Dome F:k:74:3:0:0:0:0:0:35 # The Golden Flower F:l:74:3:0:0:0:0:0:36 # The Fountain F:m:74:3:0:0:0:0:0:37 # Thunderlord's Hide F:n:74:3:0:0:0:0:0:22 # Merchant guild F:o:74:3:0:0:0:0:0:56 # Force elven monsters f:ELVEN # Town Layout D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:######################################^^^^^^^^^^^^^,,, #### D:####################################^^^^^^^^^^^^,,,, #### D:##################################^^^^^^^^,,,,,,,, #### D:###########B#####################^^^^^^^^^,,,,,, CCCCCCCCCCCCCCCCCCCCCCCCC ,,,,,,, ,,,,### D:################################^^^^^^^^^^^,,, CCCCCCCC#######################CCCCCCCC ,,,,,,,,,,, ,,,,,### D:###############################^^^^^^^^^^^^,, CCCCCCC########TTTTTTTT#####TTTTTTTT########CCCCCC ,,,,,^^^^^,,,, ,,,,### D:##############################^^^^^^^^^^^,,, CCCC########TTTTTT........###........TTTTTT########CCCC ,,,,^^^^^^^,,,,,, ,,,,,### D:#############################^^^^^^^n^^,,, CC###########T..........#########..........T###########CC ,,,,^^^^^^^^^^^^,,,,,,,,,,,### D:############################^^^^^^,,,,,, ......................... CC############T........#############........T############CC ,,,,^^^^^^^^^^^^^^,,,,,,,,,### D:############################,,,,,,,,, ......................... CC#############T.......###WW#####WW###.......T#############CC ,,,,^^^^^^^^^^^^^,,,,,,,,,### D:###########################,,,,,, ... . ... C#############TT.......#WWWW##h##WWWW#.......TT#############C ,,,,,^^^^^^^^^^^,,,,,,,,,### D:########################### ... . #### ... #### C#############T..........VV###.###VV..........T#############C ,,,,,,^^^^^^^,,, ,,,,,### D:########################## ... ##### ####5#### CC######WWWW###T...........V##...##V...........T####WWWW#####CC ######### ,,,,,,^^^^,,, ,,,,### D:########################## ######### ... ##### ####### C######TTTTWW#TT............#.....#............TT#WWTTTT######C ######### ,,,,,,,,,, ,,,,### D:####W###################W# ######### ... ##### ####### C#####l...TTW#T.................................T#WTT...T#####C ######### ,,,,,,,, ,,,,,,### D:####WWWW#############WWWW# ######### ... ##### ####### C######T...............................................T######C ,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,### D:#####WWWWWWW#####WWWWWWW## ######### ... ##### ######### C######TTT.................TTTTTTTTT.................TTT######C , ,,,,,,,,,, ,,,,,,,,,### D:#####WWWWWWWWWWWWWWWWWWW## ####w#### ... ##### ######5###### CC#######WW..............TTTT#######TTTT..............WW#######CC , ### ,,,,,,,,,,,,,,,,### D:######WWWWWWWWWWWWWWWWW### . ... ##...## C##########............TTT#############TTT............##########C , ########## ,,, ,,,,,,,,### D:######WWWWWWWWWWWWWWWWW### ........... ... C########TT...........TT#################TT...........TT########C , ################### ,,,,,### D:######WWWWWWWWWWWWWWWWW### ... ... C#####TTTT...........TT###..###aaa###..###TT...........TTTT#####C , ############### ,,,,,,### D:########WWWWWWWWWWWWW###### ######### ... ############# ... C#TTTTT..............T##.....#!...Z#.....##T..............TTTTT#C , ############## ,,,,### D:###########WWWWWWW########## ######### ... ############# ... C#T...........###...TT##.....#.....#.....##TT...###...........T#C , ############## ,,,### D:############################### ######### ... ############# ... C#T.........####....T##......#.....#......##T....####.........T#C , ########### ,,,,### D:####--####KK#CC#VV#LL#""## ######### ... ############# ... CC#TT.......####.....T##...................##T.....####.......TT#CC , #### , ## ,,,### D:####--####KK#CC#VV#LL#""## ######### ... ######1###### ... C###T......####....TTT###.................###TTT....####......T###C , , VVVVV ,,,,### D:####--####KK#CC#VV#LL#""# ... . ... C###T......d###...TT###.###....#####....###.###TT...###b......T###C ,,,,,,,,,,,,,,, VVWWWVV ,,,### D:######################### ... . ... C###T......d###...T##.....##..##WWW##..##.....##T...###b......T###C , VVVWWWWWV ,,,,### D:#..............................................................................................####...T#.......#..#WV#VW#..#.......#T...####........... , VVVVWWWWWWWV ,,,,,### D:#.x.........y.....................................................................................................#W#V#W#..............................,,,, VWWWWWWWWWWV ,,,,### D:#..............................................................................................####...T#.......#..#WV#VW#..#.......#T...####........... , VVWWWWWWWVVV ,,,,,### D:######################### . ... . . C###T......c###...T##.....##..##WWW##..##.....##T...####......T###C , VWWWWWVVVV ,,,,,^^### D:####--####KK#CC#VV#LL#""# . ... . . C###T......####...TT###.###....#####....###.###TT...####....TTT###C , VVWWWVV ,,,,,,^^### D:####--####KK#CC#VV#LL#""## ####1#### ... ######2###### ##3## C###T..............TTT###.................###TTT....####...TT#####C , VVWWV ,,,,,,^^^^### D:####--####KK#CC#VV#LL#""### ######### ... ############# ##### CC#TT................T##...................##T.....####...TT#####CC , VVVV ,,,,,,^^^^^^### D:############################### ########1...... ############# ##### C#T.................T##......#.....#......##T....####....T######C , ------TT------------ ,,,,,^^^^^^^### D:###########$$$$$$$########## ######### ... ############# ##### C#T...VV...VV.......TT##.....##...##.....##TT...###.......f#####C ,------TT-TTT--TT-TT-TT---- ,,,,^^^^^^^^^### D:########$$$$$$$$$$$$$###### ######### ... ############# ##### C#T..VV#...#VV.......T####.#####m#####.####T..............f#####C -,--TTTTTTTTTTTTTTT-TT-TTT---,,,,^^^^^^^^^### D:######$$$$$$$$$$$$$$$$$### ... C#T..V###.###V.......TTT#################TTT.............T######C ---,--TT-TTT########TTT-TTTT----,,,,,^^^^^^^### D:######$$$$$$$$$$$$$$$$$### ... C#TT.V##4.j##V.........TTT#############TTT...............TT#####C----,---TTT###TTTTTT###TT-T-TT----,,,,,^^^^^^### D:######$$$$$$$$$$$$$$$$$$## ... C##T.V#######V...........TTTT#######TTTT..................TT####C----,--TTT##TTT----TTT##TTTTTT------,,,,,^^^^### D:#####$$$$$$$$$$$$$$$$$$$## ######### ... ############# CC#T.VV#####VV.............................................TTT#CC----,---TT#TT--------TT##T-T-TT------,,,,^^^^### D:#####$$$$$$$#####$$$$$$$## ######### ... ############# C#T..VV###VV.....TTTTTTTTTTT.......TTTTTTTTTTT..............T#C-----,,,,,,,,,,,,,,,,,,,e#TT-TTT------,,,,^^^^### D:####$$$$#############$$$$# ########o.........7############ C#T...VVVVV....TTT#########TTT...TTT#########TTT............T#C----------T#TT--------TT##TTT-------,,,,^^^^^^### D:####$###################$# ######### ... ############# C#TT..........TT###VVVVVV####TT.TT####WWWWWW###TT..........TT#C--------TTT##TTT----TTT##TTTTT-----,,,,^^^^^^^### D:########################## ######### ... ############# C##T..........T##VVV....VVV###TTT###WWW....WWW##T..........T##C-------TTTTT###TTTTTT###TTTTT-----,,,,,^^^^^^^### D:########################### ... CC#T..........T#VV........VV#######WW........WW#T..........T#CC -----TTTT-TTT########TTTTTT------,,,,,,,^^^^^### D:########################### #...# C#TT.......................i#####k.......................TT#C -T---TTTTT-TTTTTTTTTT-TT------ ,,,,,,,z^^^### D:############################ ##...## C##TT........T#VV........VV#######WW........WW#T........TT##C ------TTTT-TT--TT---T----- ,,,,,,,^^^^^^### D:############################ ####6#### CC##TT.......T##VVV....VVV#########WWW....WWW##T.......TT##CC ------TTT-TTTT--T----- ,,,,,,,^^^^^^^^^### D:############################# ####### CC##TTTT...TTT###VVVVVV#############WWWWWW###TTT...TTTT##CC ------T-------- ,,,,,,^^^^^^^^^^^^### D:############################## ##### CC####TTTTTTTTT###########################TTTTTTTTT####CC ,,,,,,^^^^^^^^^^^^^^### D:############################### ##### CCCC######TTTTTTTTTTT##############TTTTTTTTTT######CCCC ,,,,,,^^^^^^^^^^^^^^^^^### D:################################ ##### CCCCCC#####################################CCCCCC ,,,,,,,,,,^^^^^^^^^^^^^^^^^### D:################################# ##### CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC ,,,,,,,,,,^^^^^^^^^^^^^^^^^^#### D:################################## ####### ,,,,,,,,,,,^^^^^^^^^^^^^^^^^^^^^#### D:#################################### ######### ,,,,,,,,,,,,,^^^^^^^^^^^^^^^^^^^###### D:###################################### ############# ,,,,,,,,,,,,,,,^^^^^^^^^^^^^^^^^^######## D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### D:###################################################################################################################################################################################################### # Default starting position ?:[EQU $LEAVING_QUEST 0] P:33:50 # Starting position when coming from quest 19 ?:[EQU $LEAVING_QUEST 19] P:51:190 # Starting position when coming from quest 20 ?:[EQU $LEAVING_QUEST 20] P:33:13 # Starting position when coming from quest 21 ?:[EQU $LEAVING_QUEST 21] P:27:168 # Starting position when coming from quest 22 ?:[EQU $LEAVING_QUEST 22] P:6:42 tome-235-src/lib/edit/t_minas.txt0000644000076400017500000003432611012107760014561 0ustar dgdg# File: t_minas.txt # Minas Anor: The Royal City of Gondor # Created by Mynstral (mynstral@thehelm.com) # Completed: 22/06/01 # Between gate to gondolin -- need to finish the quest F:Z:63:3 # Default for Quest 24 = entrance is quest entrance F:w:8:3:0:0:0:0:0:24 #################### Quest 16 - The last Alliance #################### # Quest 16 finished, reward is a between gate ?:[EQU $QUEST16 5] F:Z:176:3:0:0:0:0:0:0 ?:1 ############### Quest 24 - Haunted House finished = house ############### ?:[EQU $QUEST24 2] F:w:74:3:0:0:0:0:0:7 ?:[EQU $QUEST24 5] F:w:74:3:0:0:0:0:0:7 ?:1 #################### Buildings #################### # Library F:a:74:3:0:0:0:0:0:60 # Castle F:b:74:3:0:0:0:0:0:14 # Casino F:d:74:3:0:0:0:0:0:15 # Inn F:e:74:3:0:0:0:0:0:11 # Beastmaster Shanty F:f:74:3:0:0:0:0:0:16 # Fighters hall F:g:74:3:0:0:0:0:0:17 # Tower of Magery F:h:74:3:0:0:0:0:0:18 # Inner temple F:i:74:3:0:0:0:0:0:19 # Paladin guild F:j:74:3:0:0:0:0:0:20 # Ranger guild F:k:74:3:0:0:0:0:0:21 # Thunderlord's Hide F:l:74:3:0:0:0:0:0:22 # Castle: Plot Minas Anor F:B:75:3:0:0:0:0:0:5 # Merchant guild F:m:74:3:0:0:0:0:0:56 # Library Quest F:x:63:3 ?:[EQU $QUEST"Library quest" 1] F:x:8:3:0:0:0:0:0:"Library quest" ?:1 ############### Town Layout ############### D:###################################################################################################################################################################################################### D:#^^########------------------ @@@@@@@ @@@@@@@@@ # D:#^^^------############---------- ^ @@VVVVV@@ @@VVVVVVV@@@@@@@ ,,, # D:#^^^----------###----#######------- ^^^^^ @VVVVVVV@@@@@ @@VV@@@@@@VVVVVV@@@@ ,, # D:#^^----ssss-----###--------####------ ^^^^^^ @VVVVVV@@VVV@@@ @VV@@ @@@@@@VVVV@@ ,, # D:#^^^---StSS-------###--#ssss--###------- ^^^^^^^^ @@VVVVVVVV@VVV@@@@@@@@ @@@V@@ @@@@VV@@@@ , # D:#^^----ssss----OO---##--#StSS---####------ ^^^^^^^^ @@V@V,@@@@@@VVVVVVVV@@@VVV@ @@VVVV@@ ,, # D:#^^----x#a#-----OOO--##--#sssss----###------ ^^^^^^^^ @@@@@ @@@@@@@@VVVVV@@@ @@@@VV@@@ ,,, # D:#^ ---------------OO--###-#m#7#------###----- ^^^^^^^^^^ @VVV@@ @@VVV@@ ,O, # D:#^ StSSSS-----ss---OO---##-----OOOOO---###---- ^^^^^^^^^^^ @@@ @@VVV@@ OO # D:#^^ssssss----Ssss---OOO--##---OOOOOOOO---##---- ^l^^^^^^^ @@VVV@ OO # D:#^ ####9#---sstSss---OOO--##-OOOOOOOOOOO--##---- ^^^^^ @@VVV@@ OO # D:#^^^-------##sssSss---OOO--#OOO--s--OOOOO--###--- @@@@@@@@@@ @@VVV@@ OO # D:#^^^######---##ssh--s--OOO-OOO--StS--OOOOO---##--- @@VVVVVVVV@@@@@@@V@@@@ OO # D:#^^^^----###---##--ssS--OOOOO#--ssss--OOOOOO--##--- @VVVVVVVVVVVV@@VV@@ OOO OO # D:#^^--------###----ssSs#--OOO-##-#####--OOOOOO--##--- ---- @VVVV@@@@VVVVVVV@@ OOOOO OOOOO # D:#^ ----------##--#stsi--OOOO--#---------OOOOOO--#------ -------- @@VVV@@ @@VVV@@@@ OO OO OO # D:#^^-----------###-#s#--OOOOOO-##-#sssss--OOOOOO,#####--- ----------- @@VVV@@ @@@@@ OO- OOOOOOOOO # D:#^^-------------##-#--OOO-OOO--#--ssssss--OOOOO,,,,,#---- ---ssssssss--- @VVV@@ -OO # D:#^^--------------#---OOO-t-OOO-##-#SStSS--OOOOOO,##,#---------ssssssss---- @VV@@ --OO- # D:#^^^--#----------##-OOO-sssOOO--#--ssssss-OOOOOO--#,#####-----SStSSSSS----- @@VV@ --OO- # D:#^^^--#-----------#OOO-##4##OOO-##-ssssss--OOOOOO-#,,######---ssssssss--O--- @@VVV@ -OO-- # D:#^^--###----------OOO-------OOO--#-####2#--OOOOOO-##,#k#,,##--ssssssss--O---- @VVV@@ --O-- # D:#^^^-###---------OOO#--SSStS-OOO-#---------OOOOO---#,,,,,,,#--ssssssss--O----- @@VV@@ --OO- # D:#^^-#####-------OOO-#--sssss-OOO-#--ssss--OOOOO--T-#,-----,#--#####d##--O------ @VVV@ --OO-- # D:#^^#######------OOO-##-###j#-OOO-##-ssss--OOOOO-TT-#------,#-------,,,,,O------ @@VV@@ --OO-- # D:#^^^########----OOO--#-------OOO--#-StSS--OOOOO-TT-#-----,,#------------O------- @VVV@@ --OO-- # D:#^^############-OOO--##-StSSS-OOO-#-ssss--OOOOO--T-#----,,##---ssssssss-O-------- @@VV@@ --OOO-- # D:#^^^#########---OOO---#-sssss-OOO-#-ssss--OOOOOO---#,,,,,##----SSSSStSS-O--------- @@@VVV@ --OOO-- # D:#^^#####B###----OOO---#-###6#-OOO-#-##g#---OOOOOO--#######-----ssssssss-O---------- @VVVV@@ ---OOO-- # D:#^^^#######-----OOO---#-------OOO-#---------OOOOOOOOOOOOOOOOO--###e####-O----------- @@VVV@@ ------OO-- # D:#^^#######bOOOOOOOO-^^^^^^^^^^MMM^^^^^^^^^^^^OOOOOOOOOOOOOOOOOOOOOOOOOOOO----------- @@@VVV@@ ---OOOOOO-- # D:#^^#######bOOOOOOO############III############^OOOOOOOOOOOOOOOOOOOOOOOOOOOOO--------- @@VVVV@@ ---OOOOOO-- # D:#^ #######bOOOOOOO############III############^OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO--------- @VVVV@@ ----OOOOOO---- # D:#^ #######bOOOOOOOO-^^^^^^^^^^MMM^^^^^^^^^^^^OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO------- @VVV@@ ------OOOO------ # D:#^^^######Z-----OOO---#-sSss--OOO-#---------OOOOOOOOOOOOOOOOO-----------OOOOOOO------ ---------##@VVV@## --------OOOOO----- # D:#^^#########----OOO---#-sSss--OOO-#-sssss--OOOOOO--#######--------sssss-O-OOOOO----- --OOOO-----#######--------OOOOOO----- # D:#^^##########---OOO---#-stss--OOO-#-SStSS-OOOOOO---####,,##-------SStSS-O-OOOOO---- --OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO----- # D:#^^############-OOO--##-sSss--OOO-#-sssss-OOOOO--T-##k#,,,##------sssss-O--OOOOO--- --OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO----- # D:#^^#########----OOO--#--####-OOO--#-sssss-OOOOO-TT-#,,,,-,,#------sssss-O---OOOO--- --OOOOO-OOOOOOOOOOOOOOOOOOOOOOO------- # D:#^^#######------OOO-##-------OOO-##-###3#-OOOOO-TT-#,-----,#------###0#-O---OOOOO--- --OOOO---------#######--------------- # D:#^^-#####-------OOO-#--Ssss--OOO-#--------OOOOO--T-#,-----,#------------O----OOOO---- --OOOO---------##@VVV@##----------- # D:#^^^-###---------OOO#-#stss--OOO-#-ssssss--OOOOO---#,----,,#----ssssss--O-----OOOO---- ---OOOO--- @VVV@@ # D:#^^--###----------OOO--#sSs-OOO--#-StSSSS--OOOOOO-##,-,,,,##----SStSSS--O------OOOO---- --OOOOO---- @VVV@@ # D:#^^---#-----------#OOO--###-OOO-##-ssssss--OOOOOO-#,,,,####-----ssssss--O-------OOOO---- --OOOOO---- @VVVV@ # D:#^^^--#----------##-OOO----OOO--#--###5##-OOOOOO--#,#####-------ssssss-OO--------OOOO--------OOOOO---- @@VVV@@@ @@@@ # D:#^^^-------------#---OOO---OOO-##---------OOOOOO,##,#-----------####1#-O----------OOOO----OOOOOO----- @@VVVV@@@ @@@@@@ # D:#^^-------------##----OOO-OOO--#--ss------OOOOO,,,,,#------------------O-----------OOOOOOOOOOO----- @@@VVVV@@ @@@@@@@@@V@@@ # D:#^^^----------###--ss--OOOOOO-##-ssSs----OOOOOO,#####------------------O-------- ---OOOOOOOOO--- @@VVVV@@ @@@@@ @@@@@@@@@@@@@ # D:#^^^---------##---ssSs--OOOO--#--ssts#--OOOOOO--#------ ------ssssss--OO------ ---OOOOO----- @@VVVV@@@ @@@VVV@@@ @@@V@@@@@@@@ # D:#^^--------###---sstss#--OOO-##-ssSs#--OOOOOO--##----- ----StSSSS--O------ ----------- @@@VVVV@@@@@ @@@@VVVVVVV@@ @@@@@V@@V@@@V@@ # D:#^^------###-----#Sss#--OOOOO#--sSsf--OOOOOO--##----- ---ssssss--O----- ------- @@@VVVVVV@@@@@@@@@@@VVVVV@@@VVV@@@@@VVVV@@@@ @@@@ # D:#^^^######---ss---#s#--OOO-OOO--Ss#--OOOOO---##----- --###w##-OO----- @@VVVVVVVVVVVVVVVVV@@@@@ @@@VVVVVVV@@@@ # D:#^^^-------ssssS---#--OOO--#OOO--#--OOOOO--###----- --------O----- @@@@@@@@@@@@@@@@@@@ @@@@@@@@@ # D:#^^-sssss-#ssstss----OOO--##-OOO---OOOOO--##------ ------OO---- # D:#^^-SSStS--#sSsss#--OOO--##---OOOOOOOO---##------ ----O---- # D:#^^-sssss---#ss##--OO---##--X--OOOOO---###------ ---O--- # D:#^^^#####----##---OO--###--XXX-OOO---###------ --- # D:#^^^------------OOO--##---XXX#-----###----- # D:#^^--SStSS-----OO---##--XX###---####----- # D:#^^^-sssss--------###--###----###------ # D:#^^--#####------###--------####------ # D:#^^^----------###----#######------ # D:#^^^------############---------- # D:#^^########----------------- # D:###################################################################################################################################################################################################### tome-235-src/lib/edit/e_info.txt0000644000076400017500000007376111012107760014374 0ustar dgdg# File: e_info.txt # This file is used to initialize the "lib/data/e_info.raw" file, which is # used to initialize the "ego-item" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/data/e_info.raw" file. # The ego-item indexes are defined in "defines.h", and must not be changed. # Note that every "ego-item" type has a different "index", and can only be # created from items that belong to a certain "slot" in the equipment, if # one assumes that "ammo" belongs to an imaginary slot (23). However, it # is possible for several "ego-item" types to have the same "textual name", # such as with "Armor of Resistance" and "Shield of Resistance". # === Understanding e_info.txt === # N: serial number : ego type # D: description # T: tval : min sval : max sval # R: rarity # X: position : slot : rating # W: depth : rarity1 : rarity2 : cost # C: to-hit : to-dam : to-ac : pval # r:N:needed flags on the base object # r:F:forbidden flags on the base object # Z: granted_power # F: flags # 'N' indicated the beginning of an entry. The serial number must increase # for each new item. # 'D' contains description. This field is currently not supported. # 'T' is for possible tval and sval value of the base item. # Up to 5 entries are possible. # 'R' stands for rarity, or randomness. It specifies percentual chance # of generated item to have following 'F' flags. I.e. 'R:40' followed # by 'F:SPEED' means, that 40% of item of this ego type will boost speed. # 'X' is for extra information. Position value 'A' means that ego-type name # will appear after base-item name ('Robe of Permanence'), value 'B' means # that ego-type name will appear before base-item name ('Elven Plate Mail'). # Slot is determining in which equipment slots item could be equipped. This # value is currently ignored. Rating determines how level feeling will be # affected. # 'W' is for extra information. Depth is the depth the object is normally # found at, rarity determines how common the object is and cost is the items # value. # 'C' stands for 'creation'. It determines maximal to-hit, to-damage, AC and # stats (pval) values item can get. # 'Z' is granted power. See tables.c, array powers_type_init (lines 4511-4943). # 'F' contains flags. Most are self explaining, rest could be found in source. # Version stamp (required) V:2.0.0 ### Mage Staff ### N:1:of Mana X:A:24:20 T:6:0:255 W:5:3:8:10000 C:-30:-30:0:3 R:100 F:MANA f:MANA R:70 F:PVAL_M2 N:2:of Power X:A:24:30 T:6:0:255 W:5:5:8:20000 C:-30:-30:0:10 R:100 F:SPELL f:SPELL R:70 F:PVAL_M2 N:3:of Wizardry X:A:24:60 T:6:0:255 W:10:1:8:50000 C:-40:-40:0:3 R:100 F:MANA | SPELL R:50 F:PVAL_M2 N:4:of Spell T:6:0:255 X:A:24:60 W:0:2:8:40000 C:0:0:0:0 R:100 F:ACTIVATE F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD ### Body Armor ### N:5:of Resist Acid T:36:0:255 T:37:0:255 X:A:30:16 W:0:4:20:1000 R:100 F:RES_ACID | IGNORE_ACID f:RES_ACID | IGNORE_ACID N:6:of Resist Lightning T:36:0:255 T:37:0:255 X:A:30:10 W:0:4:20:400 R:100 F:RES_ELEC | IGNORE_ELEC f:RES_ELEC | IGNORE_ELEC N:7:of Resist Fire T:36:0:15 T:36:17:255 T:37:0:255 X:A:30:14 W:0:4:20:800 R:100 F:RES_FIRE | IGNORE_FIRE f:RES_FIRE | IGNORE_FIRE N:8:of Resist Cold T:36:0:15 T:36:17:255 T:37:0:255 X:A:30:12 W:0:4:20:600 R:100 F:RES_COLD | IGNORE_COLD f:RES_COLD | IGNORE_COLD N:9:of Resistance T:36:0:255 T:37:0:255 X:A:30:20 W:0:2:20:12500 C:0:0:10:0 R:100 F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD f:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | R:25 F:R_HIGH N:10:Elven T:36:0:255 T:37:0:255 X:B:30:25 W:0:2:20:15000 C:0:0:10:3 R:100 F:STEALTH | ESP_ORC f:STEALTH F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:OLD_RESIST R:25 F:RES_POIS # Robe N:11:of Permanence T:36:2:2 X:A:30:30 W:0:1:10:30000 C:0:0:10:0 R:100 F:SUST_STR | SUST_DEX | SUST_CON | SUST_INT | SUST_WIS | SUST_CHR | F:HOLD_LIFE | RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:OLD_RESIST R:2 F:R_IMMUNITY # Filthy rags of leprousness N:12:of Leprousness T:36:1:1 X:A:30:0 W:0:1:10:0 C:0:0:0:-6 R:100 F:CON | STR | R_STAT | CURSED # No CURSE_NO_DROP here, players seems to unlike surprises # Mithirl & Adamantite mails & PDSM N:13:of Immunity T:37:25:25 T:37:30:30 T:38:30:30 X:A:30:40 W:60:10:100:30000 C:0:0:5:0 R:100 F:R_IMMUNITY # Ego DSM N:14:of Defense T:38:0:255 X:A:30:5 W:20:40:100:1000 C:0:0:8:0 R:100 F:SUSTAIN # Boots of Jumping N:15:of Jumping T:30:0:255 X:A:35:16 W:0:3:27:500 C:0:0:0:3 Z:blink R:100 F:ACTIVATE a:HARDCORE=JUMP ### Shields ### N:16:of Resist Acid T:115:56:56 T:34:0:5 T:34:7:255 X:A:32:16 W:0:6:22:1000 R:100 F:RES_ACID | IGNORE_ACID f:RES_ACID | IGNORE_ACID N:17:of Resist Lightning T:34:0:5 T:34:7:255 T:115:56:56 X:A:32:10 W:0:6:22:400 R:100 F:RES_ELEC | IGNORE_ELEC f:RES_ELEC | IGNORE_ELEC N:18:of Resist Fire T:34:0:5 T:34:7:255 T:115:56:56 X:A:32:14 W:0:6:22:800 R:100 F:RES_FIRE | IGNORE_FIRE f:RES_FIRE | IGNORE_FIRE N:19:of Resist Cold T:115:56:56 T:34:0:5 T:34:7:255 X:A:32:12 W:0:6:22:600 R:100 F:RES_COLD | IGNORE_COLD f:RES_COLD | IGNORE_COLD N:20:of Resistance T:115:56:56 T:34:0:5 T:34:7:255 X:A:32:20 W:0:2:22:12500 C:0:0:10:0 R:100 F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | f:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD N:21:of Reflection T:115:56:56 T:34:0:5 T:34:7:255 X:A:32:20 W:0:2:22:15000 C:0:0:5:0 R:100 F:REFLECT f:REFLECT F:IGNORE_ELEC | IGNORE_ACID | IGNORE_COLD | IGNORE_FIRE # Metal shields only N:22:of Electricity T:34:3:3 T:34:5:5 T:34:10:10 X:A:32:10 W:0:2:22:400 R:100 F:RES_ELEC | IGNORE_ELEC | SH_ELEC f:SH_ELEC ### Crowns and Helms ### N:23:of the Noldor T:115:57:57 T:32:0:6 T:32:8:99 X:A:33:13 C:0:0:0:2 W:0:1:8:500 R:100 F:DEX | SUST_DEX | ACTIVATE | ESP_ORC a:HARDCORE=NOLDOR N:24:of Intelligence X:A:33:13 C:0:0:0:2 W:0:2:15:500 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:INT | SUST_INT f:INT N:25:of Wisdom X:A:33:13 W:0:2:15:500 C:0:0:0:2 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:WIS | SUST_WIS f:WIS N:26:of Beauty X:A:33:8 W:0:2:15:1000 C:0:0:0:4 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:CHR | SUST_CHR f:CHR # 40% chance of increase spell power N:27:of the Magi X:A:33:15 W:0:1:8:7500 C:0:0:0:3 T:33:0:99 R:100 F:INT | SUST_INT | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:ABILITY | R_HIGH R:40 F:SPELL R:50 F:SPELL_CONTAIN | WIELD_CAST N:28:of Might X:A:33:19 W:0:1:8:2000 C:0:0:0:3 T:33:0:99 R:100 F:STR | DEX | CON | SUST_STR | SUST_DEX | SUST_CON | FREE_ACT F:R_HIGH N:29:of Lordliness X:A:33:17 W:0:1:8:2000 C:0:0:0:3 T:33:0:99 R:100 F:WIS | CHR | SUST_WIS | SUST_CHR F:R_HIGH N:30:of Seeing X:A:33:8 W:0:1:8:1000 C:0:0:0:5 T:32:0:6 T:32:8:99 T:33:0:99 T:115:57:57 R:100 F:SEARCH | RES_BLIND | SEE_INVIS f:SEARCH R:20 F:ESP_ALL N:31:of Infravision X:A:33:11 W:0:1:15:500 C:0:0:0:5 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:INFRA | HIDE_TYPE f:INFRA N:32:of Light X:A:33:6 W:0:2:15:500 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:LITE1 | RES_LITE f:LITE1 N:33:of Telepathy X:A:33:20 W:0:1:8:50000 T:33:0:99 R:100 F:ESP_ALL f:ESP_ALL N:34:of Regeneration X:A:33:10 W:0:1:8:1500 T:32:0:6 T:32:8:99 T:33:0:99 T:115:57:57 R:100 F:REGEN f:REGEN N:35:of Teleportation X:A:33:0 W:0:1:7:50 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:TELEPORT f:TELEPORT R:90 F:CURSED N:36:of Stupidity X:A:33:0 C:0:0:0:-5 W:0:2:7:0 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:INT | CURSED f:INT # No CURSE_NO_DROP here, players seems to unlike surprises N:37:of Naivety X:A:33:0 C:0:0:0:-5 W:0:2:7:0 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:WIS f:WIS N:38:of Ugliness X:A:33:0 C:0:0:0:-5 W:0:1:7:0 T:32:0:6 T:32:8:99 T:115:57:57 R:100 F:CHR f:CHR N:39:of Sickliness X:A:33:0 C:0:0:0:-5 W:0:1:7:0 T:33:0:99 R:100 F:STR | DEX | CON N:40:Dwarven T:32:0:6 T:32:8:99 X:B:33:13 C:0:0:0:2 W:0:1:8:500 R:100 F:INFRA | CON | RES_FIRE | ESP_TROLL | ESP_DRAGON ### Cloaks ### N:41:of Protection X:A:31:10 W:0:4:19:1500 C:0:0:10:0 T:35:0:255 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | RES_SHARDS N:42:of Stealth X:A:31:10 W:0:8:18:500 C:0:0:0:3 T:35:0:99 R:100 F:STEALTH f:STEALTH N:43:of Aman X:A:31:20 W:0:1:28:4000 C:0:0:20:3 T:35:0:255 R:100 F:STEALTH | f:STEALTH | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:OLD_RESIST # Aura, Fire N:44:of Immolation X:A:31:16 W:0:1:18:4000 C:0:0:4:0 T:35:0:255 R:100 F:IGNORE_ACID | IGNORE_FIRE | SH_FIRE | RES_FIRE f:SH_FIRE N:45:of Enveloping X:A:31:0 W:0:1:3:0 C:-10:-10:0:0 T:35:0:255 R:100 F:SHOW_MODS N:46:of Vulnerability X:A:31:0 W:0:1:3:0 C:0:0:-50:0 T:35:0:255 R:100 F:AGGRAVATE N:47:of Irritation X:A:31:0 W:0:1:3:0 C:-15:-15:0:0 T:35:0:255 R:100 F:AGGRAVATE | SHOW_MODS # Aura, Electricity N:48:of Electricity X:A:31:16 W:0:1:18:4000 C:0:0:4:0 T:35:0:255 R:100 F:IGNORE_ACID | IGNORE_ELEC | SH_ELEC | RES_ELEC ### Gloves ### N:49:of Free Action X:A:34:11 W:0:4:10:1000 T:31:0:99 R:100 F:FREE_ACT f:FREE_ACT N:50:of Slaying X:A:34:17 W:0:3:10:1500 C:6:6:0:0 T:31:0:99 R:100 F:SHOW_MODS N:51:of Agility X:A:34:14 W:0:2:10:1000 C:0:0:0:5 T:31:0:99 R:100 F:DEX | HIDE_TYPE f:DEX N:52:of Power T:31:0:99 X:A:34:22 W:0:1:10:2500 C:5:5:0:5 R:100 F:STR | SHOW_MODS | HIDE_TYPE f:STR F:R_HIGH # 53 Gauntlets only N:53:of Peace X:A:34:0 W:0:1:3:0 C:-10:-10:0:0 T:31:2:2 R:100 F:HEAVY_CURSE | CURSED # 54 Gloves only N:54:of Charming X:A:34:5 T:31:1:1 W:0:1:11:400 C:0:0:0:6 R:100 F:CHR R:33 F:STEALTH f:STEALTH N:55:of Weakness T:31:0:99 X:A:34:0 W:0:1:3:0 C:0:0:0:-10 R:100 F:STR N:56:of Clumsiness X:A:34:0 W:0:1:3:0 C:0:0:0:-10 R:100 F:DEX T:31:0:99 ### Boots ### N:57:of Levitation X:A:35:7 W:0:8:27:250 T:30:0:99 R:100 F:FEATHER f:FEATHER R:40 F:R_HIGH N:58:of Stealth X:A:35:16 W:0:8:27:500 C:0:0:0:3 T:30:0:99 R:100 F:STEALTH f:STEALTH N:59:of Free Action X:A:35:15 W:0:5:27:1000 T:30:0:99 R:100 F:FREE_ACT f:FREE_ACT N:60:of Speed X:A:35:25 W:0:1:27:200000 C:0:0:0:10 T:30:0:99 R:100 F:SPEED | HIDE_TYPE f:SPEED R:10 F:PVAL_M3 # 61 Metal boots only N:61:of Dwarvish Endurance X:A:35:15 W:0:1:20:5000 C:0:0:0:6 T:30:6:6 R:100 F:CON | INFRA | RES_DARK R:33 F:STR N:62:of Noise X:A:35:0 W:0:1:3:0 T:30:0:99 R:100 F:AGGRAVATE f:AGGRAVATE N:63:of Slowness X:A:35:0 W:0:1:3:0 C:0:0:0:-5 T:30:0:99 R:100 F:SPEED f:SPEED N:64:of Annoyance X:A:35:0 W:0:1:3:0 C:0:0:0:-10 T:30:0:99 R:100 F:SPEED | AGGRAVATE ### Weapons ### N:65:of Aman T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:A:24:30 W:0:2:44:20000 C:6:6:4:3 R:100 F:WIS | F:SLAY_EVIL | SLAY_UNDEAD | SLAY_DEMON | F:SEE_INVIS | BLESSED | RES_FEAR | ESP_EVIL F:SUSTAIN | LIMIT_BLOWS R:10 F:BLOWS R:1 F:PVAL_M1 N:66:(Defender) T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:A:24:25 W:0:2:44:15000 C:4:4:8:4 R:100 F:STEALTH | f:STEALTH | F:FREE_ACT | SEE_INVIS | FEATHER | REGEN | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:SUSTAIN | R_HIGH R:33 F:RES_POIS N:67:Blessed T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:B:24:20 W:0:1:44:5000 C:0:0:0:3 R:100 F:WIS | ESP_GOOD F:BLESSED | ABILITY f:BLESSED N:68:of Greater Life T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:20 W:0:1:50:30000 C:5:5:0:3 r:N:MUST2H R:100 F:LIFE | HOLD_LIFE f:LIFE N:69:of Westernesse T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:A:24:20 W:0:2:44:20000 C:5:5:0:2 R:100 F:STR | DEX | CON | F:SLAY_ORC | SLAY_TROLL | SLAY_GIANT | F:FREE_ACT | SEE_INVIS | ESP_ORC | ESP_TROLL | ESP_GIANT R:33 F:RES_FEAR R:50 F:RES_MORGUL N:70:of Extra Attacks T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:20 W:0:1:44:10000 C:0:0:0:3 R:100 F:BLOWS f:BLOWS N:71:of Slaying T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:15 W:0:2:44:2500 C:0:0:0:0 R:100 F:SLAY_WEAP | WOUNDING N:72:of Spinning T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:18 W:0:1:44:9000 C:8:8:0:2 R:100 F:DEX | STR | VORPAL | ACTIVATE a:HARDCORE=SPIN # The "Elemental" brands (4) (6) N:73:Acidic T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:B:24:15 W:0:4:44:5000 R:100 F:BRAND_ACID | RES_ACID | IGNORE_ACID f:BRAND_ACID N:74:Shocking T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:B:24:20 W:0:4:44:4500 R:100 F:BRAND_ELEC | RES_ELEC | IGNORE_ELEC f:BRAND_ELEC N:75:Fiery T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:B:24:20 W:0:4:44:3500 R:100 F:BRAND_FIRE | RES_FIRE | IGNORE_FIRE | LITE1 f:BRAND_FIRE | N:76:Frozen T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:B:24:15 W:0:4:44:3000 R:100 F:BRAND_COLD | RES_COLD | IGNORE_COLD f:BRAND_COLD | N:77:Venomous T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:B:24:20 W:0:4:44:4000 R:100 F:BRAND_POIS | RES_POIS f:BRAND_POIS | N:78:Chaotic T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:29 T:23:31:255 T:24:0:255 T:115:55:55 X:B:24:28 W:0:1:44:10000 R:100 F:CHAOTIC | RES_CHAOS | IGNORE_ELEC | IGNORE_ACID | IGNORE_FIRE f:CHAOTIC F:R_ANY N:79:Sharp T:125:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:B:24:20 W:0:2:44:5000 R:100 F:VORPAL f:VORPAL N:80:of Earthquakes T:125:0:255 T:21:0:255 T:115:55:55 X:A:24:20 W:0:1:44:4000 C:10:10:0:6 R:100 F:IMPACT | STR | TUNNEL | HIDE_TYPE f:IMPACT # The "Slay" brands (8) N:81:of Slay Animal T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:18 W:0:6:44:3500 R:100 F:SLAY_ANIMAL f:SLAY_ANIMAL N:82:of Slay Evil T:15:0:255 T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:18 W:0:6:44:3500 R:100 F:SLAY_EVIL f:SLAY_EVIL N:83:of Slay Undead T:15:0:255 T:21:0:19 T:21:21:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:18 W:0:6:44:3500 R:100 F:SLAY_UNDEAD f:SLAY_UNDEAD N:84:of Slay Demon T:15:0:255 T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:14 W:0:6:44:2500 R:100 F:SLAY_DEMON f:SLAY_DEMON N:85:of Slay Orc T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:10 W:0:6:44:2500 R:100 F:SLAY_ORC f:SLAY_ORC N:86:of Slay Troll T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:10 W:0:6:44:2500 R:100 F:SLAY_TROLL f:SLAY_TROLL N:87:of Slay Giant T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:14 W:0:6:44:2500 R:100 F:SLAY_GIANT f:SLAY_GIANT N:88:of Slay Dragon T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:18 W:0:6:44:3500 R:100 F:SLAY_DRAGON f:SLAY_DRAGON # The "Kill" brands (8) N:89:of *Slay Animal* T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:20 W:0:2:44:6000 C:0:0:0:2 R:100 F:INT | SLAY_ANIMAL | SLOW_DIGEST | STEALTH | ESP_ANIMAL f:SLAY_ANIMAL | STEALTH N:90:of *Slay Evil* T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:20 W:0:2:44:6000 C:0:0:0:2 R:100 F:WIS | SLAY_EVIL | BLESSED | ESP_EVIL | RES_FEAR | ABILITY f:SLAY_EVIL | N:91:of *Slay Undead* T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:24 W:0:2:44:8000 C:0:0:0:2 R:100 F:WIS | KILL_UNDEAD | SEE_INVIS | ESP_UNDEAD | RES_NETHER f:KILL_UNDEAD | N:92:of *Slay Demon* T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:16 W:0:2:44:8000 C:0:0:0:2 R:100 F:INT | KILL_DEMON | ESP_DEMON | RES_FIRE | RES_CHAOS f:KILL_DEMON | N:93:of *Slay Orc* T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:14 W:0:2:44:4000 C:0:0:0:2 R:100 F:DEX | SLAY_ORC | ESP_ORC | SUST_DEX | f:SLAY_ORC | N:94:of *Slay Troll* T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:14 W:0:2:44:4000 C:0:0:0:2 R:100 F:STR | SLAY_TROLL | ESP_TROLL | REGEN | SUST_STR f:SLAY_TROLL | N:95:of *Slay Giant* T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:16 W:0:2:44:4000 C:0:0:0:2 R:100 F:STR | SLAY_GIANT | ESP_GIANT | RES_SHARDS | SUST_STR f:SLAY_GIANT | N:96:of *Slay Dragon* T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:24 W:0:2:44:8000 C:0:0:0:2 R:100 F:CON | KILL_DRAGON | ESP_DRAGON | RES_FEAR | f:KILL_DRAGON F:R_LOW | R_ELEM R:20 F:RES_POIS N:97:Vampiric T:125:0:255 T:23:0:255 T:115:55:55 X:B:24:25 W:0:2:44:10000 C:0:0:0:-2 R:100 F:LIFE | VAMPIRIC | HOLD_LIFE f:LIFE | VAMPIRIC N:98:(*Defender*) T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:A:24:35 W:0:1:100:50000 C:-15:-15:20:4 R:100 F:STEALTH | RES_POIS | DEX | CON | WIS | HOLD_LIFE | f:STEALTH F:FREE_ACT | SEE_INVIS | FEATHER | REGEN | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD F:R_ANY | R_LOW | SUSTAIN R:30 F:R_ANY | R_LOW | SUSTAIN R:20 F:R_ANY | R_LOW | SUSTAIN | R_HIGH R:10 F:R_IMMUNITY | R_ANY N:99:of the Thunderlords T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:A:24:22 W:0:1:100:7000 C:4:4:0:2 a:HARDCORE=TELEPORT R:100 F:SLAY_EVIL | KILL_DRAGON | TELEPORT | FREE_ACT | SEARCH | BRAND_ELEC F:REGEN | SLOW_DIGEST | RES_NEXUS | ACTIVATE | FLY | ESP_DRAGON F:R_HIGH R:12 F:ABILITY R:2 F:R_P_ABILITY | PVAL_M3 | LIMIT_BLOWS N:100:of Gondolin T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:A:24:26 W:0:1:44:25000 C:7:7:0:3 R:100 F:STR | CON | ESP_EVIL | RES_FEAR | F:SLAY_EVIL | SLAY_TROLL | SLAY_DRAGON | SLAY_DEMON | F:FREE_ACT | SEE_INVIS | LITE1 | RES_DARK | ABILITY | F:IGNORE_ACID | IGNORE_FIRE R:33 F:R_HIGH R:33 F:HOLD_LIFE R:22 F:DEX # Diggers only N:101:of Digging T:20:0:255 X:A:24:4 W:0:1:2:500 C:0:0:0:5 R:100 F:TUNNEL | f:TUNNEL | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD # More weapons N:102:Spectral T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:B:24:30 W:0:1:5:5000 R:100 F:SLAY_UNDEAD | SEE_INVIS | HOLD_LIFE | DRAIN_HP F:ACTIVATE a:HARDCORE=SPECTRAL N:103:of Morgul T:125:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:0 W:0:1:1:0 C:-20:-20:-10:-10 R:100 F:LUCK F:SEE_INVIS | AGGRAVATE | HEAVY_CURSE | CURSED | BLACK_BREATH | DRAIN_EXP | F:AUTO_CURSE | WOUNDING # No CURSE_NO_DROP here, players seems to unlike surprises N:104:of Nothingness T:125:0:255 T:15:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 X:A:24:0 W:0:1:2:0 C:-100:-100:0:0 R:100 F:NEVER_BLOW | HEAVY_CURSE | CURSED | AUTO_CURSE ### Missile Launchers ### N:105:of Accuracy T:19:0:255 T:15:0:255 X:A:25:10 W:0:8:21:1000 C:15:5:0:0 N:106:of Power T:19:0:255 T:15:0:255 X:A:25:10 W:0:8:21:1000 C:5:15:0:0 N:107:of Extra Might T:19:0:255 X:A:25:20 W:0:4:21:10000 C:5:10:0:1 R:100 F:XTRA_MIGHT | PVAL_M3 | R_ANY f:XTRA_MIGHT | N:108:of Extra Shots T:19:0:255 X:A:25:20 C:10:5:0:1 W:0:4:21:10000 R:100 F:XTRA_SHOTS | PVAL_M2 f:XTRA_SHOTS | # Bows only N:109:of Lothlorien T:19:12:13 X:A:25:20 W:50:2:21:30000 C:10:10:0:2 R:100 F:DEX | XTRA_MIGHT | FREE_ACT | IGNORE_ACID | IGNORE_FIRE | HIDE_TYPE | F:BLESSED | ABILITY # Crossbows only N:110:of the Haradrim T:19:23:24 X:A:25:30 W:50:2:21:20000 C:5:15:0:1 R:100 F:XTRA_MIGHT | XTRA_SHOTS | IGNORE_ACID | IGNORE_FIRE | HIDE_TYPE # Slings only N:111:of Buckland X:A:25:25 W:40:2:21:20000 C:8:8:0:2 T:19:2:2 R:100 F:DEX | XTRA_SHOTS | XTRA_MIGHT | IGNORE_ACID | IGNORE_FIRE | HIDE_TYPE ### Ammo ### N:112:of Slay Animal T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 W:0:2:12:25 R:100 F:SLAY_ANIMAL f:SLAY_ANIMAL N:113:of Slay Evil T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 W:0:2:12:25 R:100 F:SLAY_EVIL f:SLAY_EVIL N:114:of Slay Undead T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 W:0:1:12:35 R:100 F:SLAY_UNDEAD f:SLAY_UNDEAD N:115:of Venom T:16:0:99 T:17:0:2 T:18:0:2 X:A:23:10 R:100 F:BRAND_POIS f:BRAND_POIS W:0:2:12:25 N:116:of Acid T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 R:100 F:BRAND_ACID | IGNORE_ACID f:BRAND_ACID | W:0:1:12:30 # 117 All Elements at once - melee weapon N:117:Elemental X:B:24:30 W:10:1:50:26000 T:21:0:99 T:22:0:99 T:23:0:99 T:24:0:99 R:100 F:BRAND_ACID | RES_ACID | IGNORE_ACID F:BRAND_ELEC | RES_ELEC | IGNORE_ELEC F:BRAND_FIRE | RES_FIRE | IGNORE_FIRE F:BRAND_COLD | RES_COLD | IGNORE_COLD F:BRAND_POIS | RES_POIS | DRAIN_MANA f:BRAND_ACID | f:BRAND_ELEC | f:BRAND_FIRE | f:BRAND_COLD | f:BRAND_POIS | N:118:of Slay Demon T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 W:0:1:12:35 R:100 F:SLAY_DEMON f:SLAY_DEMON N:119:of Slay Dragon T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 R:100 F:SLAY_DRAGON f:SLAY_DRAGON W:0:1:12:35 N:120:of Slaying X:A:23:15 W:0:1:12:20 C:12:12:0:0 R:100 F:DAM_DIE N:121:of Lightning T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 R:100 F:BRAND_ELEC | IGNORE_ELEC f:BRAND_ELEC | W:0:1:12:30 N:122:of Flame T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 R:100 F:BRAND_FIRE | IGNORE_FIRE f:BRAND_FIRE | W:0:2:12:25 N:123:of Frost T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:10 R:100 F:BRAND_COLD | IGNORE_COLD f:BRAND_COLD | W:0:2:12:25 N:124:of Wounding T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:5 W:0:3:12:20 C:6:6:0:0 N:125:of Backbiting T:16:0:99 T:17:0:99 T:18:0:99 X:A:23:0 W:0:1:2:0 C:-50:-50:0:0 ### Special Broken Items ### # Destroyed Weapon N:126:Shattered T:16:0:99 T:17:0:99 T:18:0:99 X:B:24:0 W:0:1:2:0 C:-5:-5:0:0 # Destroyed Body Armor N:127:Blasted T:16:0:99 T:17:0:99 T:18:0:99 X:B:30:0 W:0:1:2:0 C:0:0:-10:0 # Instruments N:128:of the Eldar T:14:0:59 T:14:61:255 X:A:25:20 W:0:2:3:1000 C:0:0:0:0 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | F:RES_ACID | CHR | SEE_INVIS F:R_ANY | PVAL_M2 R:25 F:PVAL_M1 N:129:of Power T:14:0:59 T:14:61:255 X:A:25:20 W:0:1:3:2000 C:0:0:0:0 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | SUST_CHR | F:RES_FIRE | RES_COLD | RES_ELEC | RES_ACID | CHR | SEE_INVIS F:R_ANY | PVAL_M3 R:50 F:PVAL_M1 R:35 F:PVAL_M1 # Horn, now four different ego items (for different GF_ values) # see items 181, 182 & 183. N:130:Dragon T:14:60:60 X:B:25:20 W:0:1:2:2000 C:0:0:0:0 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | ACTIVATE F:R_ANY | PVAL_M2 R:50 F:PVAL_M1 R:25 F:PVAL_M1 a:HARDCORE=BA_ACID_H # Rods ego N:131:Capacity of T:67:0:255 X:A:51:10 W:0:2:10:1000 C:0:0:0:0 R:100 F:CAPACITY f:CAPACITY N:132:Cheapness of T:67:0:255 X:A:51:10 W:0:2:10:700 C:0:0:0:0 R:100 F:CHEAPNESS f:CHEAPNESS N:133:Quickness of T:67:0:255 X:A:51:15 W:0:3:10:1100 C:0:0:0:0 R:100 F:FAST_CAST f:FAST_CAST N:134:Charging of T:67:0:255 X:A:51:15 W:0:2:10:1500 C:0:0:0:0 R:100 F:CHARGING f:CHARGING N:135:the Istari of T:67:0:255 X:A:51:10 W:0:1:10:10000 C:0:0:0:0 R:100 F:CAPACITY | CHARGING | CHEAPNESS | FAST_CAST | ### Lights ### N:136:of Boldness X:A:0:5 T:39:0:99 W:0:1:5:1000 Z:remove fear N:137:of Fearlessness X:A:0:5 T:39:0:99 W:0:1:10:1500 R:100 F:RES_FEAR N:138:of Illumination X:A:0:5 T:39:0:99 W:0:3:10:1000 Z:illuminate R:10 F:LITE1 R:5 F:LITE2 R:2 F:LITE3 N:139:of Brightness X:A:0:5 T:39:0:99 W:0:3:10:1000 R:100 F:LITE1 f:LITE1 R:60 F:LITE2 R:30 F:LITE3 R:30 F:RES_DARK N:140:of *Brightness* X:A:0:9 T:39:0:99 W:0:1:40:5000 R:100 F:LITE1 F:LITE2 F:LITE3 f:LITE1 f:LITE2 f:LITE3 F:RES_DARK N:141:of the Shadows X:A:0:6 T:39:0:99 W:0:1:20:3000 C:0:0:0:2 R:100 F:INVIS R:70 F:RES_DARK R:50 F:RES_LITE N:142:of Infravision X:A:0:3 T:39:0:99 W:0:1:10:700 C:0:0:0:3 R:100 F:INFRA f:INFRA N:143:of the Eternal Eye X:A:0:7 T:39:0:99 W:0:3:40:4000 C:0:0:0:0 R:100 F:RES_BLIND | SEE_INVIS N:144:of the Ethereal Eye X:A:0:7 T:39:0:99 W:0:3:40:4000 C:0:0:0:0 Z:magic map N:145:of Fading X:A:0:0 T:39:2:99 W:0:1:1:0 C:0:0:0:0 R:100 F:FUEL_LITE # Armor (dwarven): must be heavy metal, and not rusty chain mail N:146:Dwarven T:37:2:255 X:B:30:18 W:0:2:20:5000 C:0:0:15:2 R:100 F:STR | CON | INFRA | FREE_ACT | HIDE_TYPE | F:RES_FEAR | RES_DARK | SUST_STR | SUST_CON | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD # Ring and Amulet egos N:147:Indestructible X:B:0:2 T:40:0:255 T:45:0:255 W:0:1:10:1000 C:0:0:0:0 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD f:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD N:148:Cursed X:B:0:0 T:40:0:255 T:45:0:255 W:0:1:10:0 C:0:0:0:0 R:100 F:AUTO_CURSE f:AUTO_CURSE # Scrolls & school spellbooks & staves N:149:Fireproof X:B:0:1 T:70:0:255 T:111:0:255 T:55:0:255 W:0:1:10:1000 C:0:0:0:0 R:100 F:IGNORE_FIRE f:IGNORE_FIRE # Wands & Staffs(NOT wishing nor nothing) N:150:of Plenty X:A:0:1 T:55:0:29 T:55:32:255 T:65:0:29 T:65:31:255 W:0:1:20:1000 C:0:0:0:3 R:100 F:PVAL_M5 | PVAL_M3 R:50 F:PVAL_M5 | PVAL_M3 R:10 F:PVAL_M5 | PVAL_M3 R:1 F:PVAL_M5 | PVAL_M3 ### Trapping Kits ### N:151:of Extra Might X:A:0:5 T:46:1:3 W:0:1:10:1000 C:20:20:0:2 R:100 F:XTRA_MIGHT f:XTRA_MIGHT N:152:of Extra Shots X:A:0:10 T:46:0:99 W:0:1:10:2000 C:20:20:0:3 R:100 F:XTRA_SHOTS f:XTRA_SHOTS N:153:Automatic X:B:0:15 T:46:0:99 W:0:1:10:3000 C:10:10:0:0 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_COLD | IGNORE_FIRE | F:AUTOMATIC_5 f:AUTOMATIC_5 N:154:Fully Automatic X:B:0:15 T:46:0:99 W:0:1:15:5000 C:10:10:0:0 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_COLD | IGNORE_FIRE | F:AUTOMATIC_99 f:AUTOMATIC_99 N:155:Well-hidden X:B:0:5 T:46:0:99 W:0:1:8:1000 C:15:15:5:12 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_COLD | IGNORE_FIRE | F:STEALTH | HIDE_TYPE f:STEALTH N:156:Complicated X:B:0:10 T:46:0:99 W:0:1:12:2000 C:15:15:30:0 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_COLD | IGNORE_FIRE N:157:Obvious X:B:0:0 T:46:0:99 W:0:1:1:0 C:-20:-20:-20:-20 R:100 F:STEALTH | CURSED | HIDE_TYPE f:STEALTH N:158:for Dragons X:A:0:5 T:46:0:99 W:0:3:10:500 C:20:20:10:4 R:100 F:STEALTH | ONLY_DRAGON | HIDE_TYPE | XTRA_SHOTS | F:IGNORE_ACID | IGNORE_FIRE N:159:for Demons X:A:0:5 T:46:0:99 W:0:3:10:500 C:20:20:10:4 R:100 F:STEALTH | ONLY_DEMON | HIDE_TYPE | XTRA_SHOTS F:IGNORE_ACID | IGNORE_FIRE N:160:for Animals X:A:0:5 T:46:0:99 W:0:3:10:500 C:20:20:10:4 R:100 F:STEALTH | ONLY_ANIMAL | HIDE_TYPE | XTRA_SHOTS N:161:for Undead X:A:0:5 T:46:0:99 W:0:3:10:500 C:20:20:10:4 R:100 F:STEALTH | ONLY_UNDEAD | HIDE_TYPE | XTRA_SHOTS | KILL_GHOST N:162:for Evil X:A:0:5 T:46:0:99 W:0:3:10:500 C:20:20:10:4 R:100 F:STEALTH | ONLY_EVIL | HIDE_TYPE | XTRA_SHOTS | KILL_GHOST # Lite ego N:163:of the Magi X:A:0:0 T:39:1:99 W:0:1:150:2000 C:0:0:0:3 Z:magic map R:100 F:INT | WIS | CHR R:60 F:INVIS | RES_BLIND R:30 F:R_HIGH R:30 F:PVAL_M2 R:50: F:SPELL_CONTAIN | WIELD_CAST ### New ego-items added by JLE # Armor of Vulnerability (the only cursed armor) N:164:of Vulnerability X:A:30:0 W:0:2:20:0 C:0:0:-50:0 T:36:0:99 T:37:0:99 R:100 F:AGGRAVATE | CURSED # Shield of Vulnerability (the only cursed shield) N:165:of Vulnerability X:A:32:0 W:0:2:22:0 C:0:0:-50:0 T:115:56:56 T:34:0:99 R:100 F:AGGRAVATE | CURSED # Shield of Preservation - N:166:of Preservation X:A:32:25 W:40:2:44:20000 C:-10:-10:20:0 T:115:56:56 T:34:0:99 R:100 F:RES_DISEN | SUST_STR | SUST_CON | SUST_DEX | HOLD_LIFE | R_HIGH | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD R:33 F:R_LOW R:33 F:R_LOW # Helm/Crown of Serenity N:167:of Serenity X:A:33:20 W:35:1:15:4000 T:32:0:6 T:32:8:99 T:33:0:99 R:100 F:RES_SOUND | RES_CONF | RES_FEAR # Crown of Night and Day N:168:of Night and Day X:A:33:18 W:35:1:15:4000 T:33:0:99 R:100 F:RES_LITE | RES_DARK | LITE1 | SEE_INVIS | RES_BLIND | IGNORE_ACID # Cloak of the Magi N:169:of the Magi X:A:31:15 W:30:1:18:2000 C:-5:-5:5:3 T:35:0:99 R:100 F:INT | SPEED | SUST_INT | FREE_ACT | STEALTH | HIDE_TYPE | IGNORE_ACID R:30 F:SPELL_CONTAIN | WIELD_CAST # Cloak of Invisibility N:170:of Invisibility X:A:31:20 W:40:1:18:3000 C:0:0:10:5 T:35:0:99 R:100 F:STEALTH | HIDE_TYPE | INVIS f:INVIS # Cloak of the Bat N:171:of the Bat X:A:31:15 W:50:1:35:3000 C:-10:-10:10:3 T:35:0:99 R:100 F:SPEED | FLY | RES_DARK | SEE_INVIS | INFRA | HIDE_TYPE | STEALTH # Leather Gloves of Thievery N:172:of Thievery X:A:34:22 W:40:1:15:5000 C:8:3:0:5 T:31:1:1 R:100 F:DEX | SEARCH | SHOW_MODS | FEATHER | FREE_ACT | HIDE_TYPE | IGNORE_ACID R:10 F:SPEED # Gauntlets and Cesti of Combat N:173:of Combat X:A:34:22 W:50:1:15:7000 C:6:8:-20:2 T:31:2:99 R:100 F:STR | CON | SHOW_MODS | AGGRAVATE | HIDE_TYPE | IGNORE_ACID | RES_FEAR | F:DRAIN_HP R:25 F:BLOWS # Boots of Stability N:174:of Stability X:A:35:20 W:0:3:27:5000 T:30:0:99 R:100 F:RES_NEXUS | FEATHER # Boots of Elvenkind (leather boots only) N:175:of Elvenkind X:A:35:30 W:60:1:36:200000 C:0:0:0:5 T:30:2:3 R:100 F:STEALTH | SPEED | HIDE_TYPE | FEATHER | IGNORE_ACID | IGNORE_FIRE | ABILITY # Weapon of Fury (must be big heavy type of weapon, no daggers or whips) N:176:of Fury X:A:24:30 W:40:1:66:20000 T:21:12:99 T:22:10:99 T:23:16:99 T:24:8:99 T:125:0:99 C:10:10:-20:2 R:100 F:STR | BLOWS | AGGRAVATE | RES_FEAR | HIDE_TYPE | F:IGNORE_ACID | IGNORE_FIRE | DRAIN_MANA # Staffs of wishing N:177:of Plenty X:A:0:1 T:55:31:31 W:0:1:20:1000 C:0:0:0:2 R:100 F:PVAL_M2 # Diggers only N:178:Magical T:20:0:255 X:B:24:4 W:0:1:10:500 C:0:0:0:0 Z:stone to mud R:100 # Rod N:179:Simplicity of T:67:0:255 X:A:51:8 W:3:2:8:1000 C:0:0:0:0 R:100 F:EASY_USE f:EASY_USE # Lite ego N:180:of Warmth X:A:0:0 T:39:1:99 W:0:1:10:500 C:0:0:0:0 R:100 F:RES_COLD #Three more horn types, for different activation types... N:181:Dragon T:14:7:7 X:B:25:20 W:0:1:2:2000 C:0:0:0:0 a:HARDCORE=BA_COLD_3 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | N:182:Dragon T:14:7:7 X:B:25:20 W:0:1:2:2000 C:0:0:0:0 a:HARDCORE=BA_ELEC_3 R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | N:183:Dragon T:14:7:7 X:B:25:20 W:0:1:2:2000 C:0:0:0:0 a:HARDCORE=BA_FIRE_H R:100 F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | # Helm of water breathing N:184:of Water Breathing X:A:33:13 C:0:0:0:2 W:15:1:25:1000 T:32:5:10 R:100 F:WATER_BREATH | IGNORE_ACID f:WATER_BREATH # A second of life for non MUST2H weapons, much lower value tho N:185:of Life T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 X:A:24:20 W:0:1:50:30000 C:5:5:0:1 r:F:MUST2H R:100 F:LIFE | HOLD_LIFE f:LIFE # Cloak of Air N:186:of Air X:A:31:10 W:30:1:35:1500 C:0:0:0:0 T:35:0:255 R:100 F:MAGIC_BREATH # Ego DSM N:187:Polished T:38:0:255 X:B:30:5 W:40:25:100:25000 C:0:0:0:0 R:100 F:REFLECT # Ego Heavy Crossbow N:188:of Siegecraft T:19:24:24 X:A:25:30 W:60:5:30:30000 C:10:15:20:2 R:120 F:XTRA_MIGHT | XTRA_SHOTS | REFLECT | IMMOVABLE # N: serial number : ego type # D: description # T: tval : min sval : max sval # R: rarity # X: position : slot : rating # W: depth : rarity1 : rarity2 : cost # C: to-hit : to-dam : to-ac : pval # r:N:needed flags on the base object # r:F:forbidden flags on the base object # Z: granted_power # F: flags tome-235-src/lib/edit/s_gates.map0000644000076400017500000001221311012107760014501 0ustar dgdg# Special Level "The Dimensional Gates" in the Pits of Angband # # Created for PernAngband 5.0.1 on 18/8/01 # Written by Mynstral (mynstral@thehelm.com) %:special.txt ### Gauranteed monsters # Quylthulg on normal floor F:a:1:0:342 # Demonic Quylthulg on normal floor F:b:1:0:727 # Draconic Quylthulg on normal floor F:c:1:0:759 # Rotting Quylthulg on normal floor F:d:1:0:633 # Greater Draconic Quylthulg on normal floor F:e:1:0:801 # Greater Rotting Quylthulg on normal floor F:f:1:0:802 # Great Hell Wyrm on normal floor F:g:1:0:756 # Master Quythulg on normal floor F:h:1:0:821 ### Random monsters and/or items # Random monster (upto 5 levels ood) on normal floor F:&:1:0:*90 # Random monster (upto 11 levels ood) on normal floor F:@:1:0:*96 # Random monster (upto 9 levels ood) and # Random object (upto 7 levels ood) on normal floor F:8:1:0:*94:*92 # Random monster (upto 40 levels ood) and # Random object (upto 20 levels ood F:9:1:0:*125:*105 ### Guaranteed items # The Ring of Power 'Narya' on normal floor F:1:1:0:0:0:0:10 ### Level design D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X*****...@%...aX.X9@********%%%%%%X9.VV....Xd.............A^^.......dX D:X*****...@%...aX.X@@********%%%%%%X.VVVV.X.XX.............B^^........X D:X*****...@%...aX.X99*XXX****%%88%%XVVWWVVX..XX.............^^.......9X D:X*****...@%...aX.X@@XXdXX***%%88%%XVVWWVVX...XX............^^.......CX D:X*****...@%...aX.X@XX...XX**%%%%%%X.VVVV.X.X..XX..........5^^........X D:X........@%...aX.XXX.....XX*%%%%%%X9.VV..X.XX..XX.........F^^.......dX D:X%X......@%...aX.X........XIXXXXXXXXXXX..X..XX..XXXXIXXXXXXXXXXXXXXXXX D:X.XXX....@%...aX.X..........XXX..>X...X..X...XX..XXXaXaXaXaXaXaXaXaXaX D:X...XXX..@%...aI.X..........XXX7..X...D..X.X..XX..XX.................X D:X.....XXX@%...aX.X..........XXXXXXXXXXX..X.XX..XX..XX................X D:X.......XXX...aX.X..........XXXXXXXaG....X..XX..XX..XX...............X D:X..X......XXX.XX%XX^^^^^X...XXXXXXXaG....X...XX..XX..XX..............X D:X^^XX.......XXX***X^^^^^X...XIIII7XXXXXXXXXX..XX..XX..XXXXXXXXXXXX+X8X D:X^^XX.........X.6.X^^^^^X...XIXXXXX&&&&&&&&XX..XX..XX...........cX.XXX D:X..XXX........X***X^^^^^X...XIXXXXX.........XX..XX..XXXXXXXXXXXXXX..XX D:X^^X8X........XXXXX^^^^^X...XIIIIIXVVV.......XX..XX.............bXX..X D:X..X8XX................XX...XXXXXIXVVVV.......XX..XXXXXXXXXXXXXXXXXX+X D:X^^X88X................XX...XIIIIIXVVVVVV..@...XX.^^^^^^^^^^^^^a.....X D:X^^X99XX...............XX...XIXXXXX4..VVVV......XXXXXXXXXXXXXXXXXXXXXX D:X..X999X...............XX...XIXXXXXXXXX.VVVV....***********.........bX D:X^^XIIIXX..............XX...XIX...5..fX...VVVVV.@....................X D:X..X....X........d.....XX...XIXf......X...VVVVVVV...............@....X D:X^^X....XX............XXX...XIXXXXXXXXX.......VVVVVVV................X D:X^^X&&&&&X............XXX...XIIIIIXe...........VVVVVVVVVVVV..........X D:X..X%%%.%XX..........XXX....XXXXXIX.............@VVVVVVVVVVVV@.......X D:X^^X88%.%8X.........XXX.....XXXXXIX...................VVVVVVVVVV.....X D:X..X%%%.%%XX........XX......XXXXXIX@.....................VVVVVVVVVVVVX D:X^^X......cX......XXXX......XXXXXIX........@..........@....VVVVVVVVVVX D:X^^^......cXX888XXXXX......dIIIIIIX.........................b.VVV...6X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXgLLLLLgXXXXXXXXXXXXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXLLLLXXLLLLLLXXXXXXXXXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXgLLLLLXXXXXgLLLLLLLXXgXXXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXLLLLgXXXXXXXXXXXXXXLLLLLLLXXXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXLLXXXXXXXXXXXXXXXXXXgXXXLLLgXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXLgXXXXXXXXXXXXXXXXXXXXXXXXLLLLXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXfXXXXXXXXLXXXXXXXXXXXXXXXXXXXXXXXXXgLLLLXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXX.XXXXXXXghgXXXXbXXXXXXXXaXXXXXXXXXXXXXXLLLLgXXXXXXX D:XXXXXXXXXXXXXXXXXXX.XXXXXXXg1gXXXX.XXXXXXXX.XXXXXXXXXXXXXXXXgLLXXXXXXX D:XXXXXXXXXXXXXXXXXXX^XXXXXXXXXXXXXX^XXXXXXXX^XXXXXXXXXXXXXXXXXXLXXXXXXX D:XXXXXXXXXXXXXXX4..^^^..^^^.......^^^......^^^.........EXXXXXXXLXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXX^XXXXXXXXX^XXXXXXXX^XXXXXXXXXXXXXXXXXLLXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXX.XXXXXXXX.XXXXXXXXXXXXXXXXLLLXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXcXXXXXXXXaXXXXXXXXXXXXXXXLLXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXgLLLXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXLLLXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXLLXgXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXLLXXXXXXXXXXXXXX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXLLXXXXXXXXXXXXXXX D:X...dXXXXXXXXXXe..0XXXXXXXXXXXXXXXD..EXXXXXXXXXXXXXXLLXXXXXXXXXXXcc..X D:X...dXXXXXXXXXX....XXXXXXXXXXXXXXX....XXXXXXXXXXXXXX.XXXXXXXXXXXX....X D:XA...XXXXXXXXXXF..eXXXXXXXXXXXXXXXC...XXXXXXXXXXXXXX0XXXXXXXXXXXX...BX D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # Starting location P:11:37 tome-235-src/lib/edit/a_info.txt0000644000076400017500000023405211012107760014360 0ustar dgdg# File: a_info.txt # This file is used to initialize the "lib/raw/a_info.raw" file, which is # used to initialize the "artifact" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/raw/a_info.raw" file. # The artifact indexes are defined in "defines.h", and must not be changed. # Artifacts 1-15 are "special", 16-63 are "armor", and 64-127 are "weapons". # Hack -- "Grond" and "Morgoth" MUST have a rarity of one, or they might # not be dropped when Morgoth is killed. Note that they, like the "special" # artifacts, are never created "accidentally". # Artifacts now have descriptions. Special thanks to J.R.R Tolkien, # without whom the words would be unwritten, the images unconceived, # the deed undone. # -Leon Marrick # Contributors: Jeff Butler, Neal Hackler, Ethan Sicotte, Pat Tracy, Divia # Version stamp (required) V:2.0.0 # The Phial of Galadriel N:1:of Galadriel I:39:100:4 W:20:10:10:10000 P:0:1d1:0:0:0 F:ACTIVATE | SEARCH | LITE3 | LUCK F:INSTA_ART | HIDE_TYPE a:HARDCORE=LIGHT D:A small crystal phial, with the light of Earendil's Star contained inside. D:Its light is imperishable, and near it darkness cannot endure. # The Star of Elendil N:2:of Elendil I:39:101:1 W:30:25:5:32500 P:0:1d1:0:0:0 F:ACTIVATE | SEE_INVIS | HOLD_LIFE | F:INSTA_ART | SPEED | LITE3 | LITE1 | HIDE_TYPE a:HARDCORE=MAP_LIGHT Z:detect curses D:The shining Star of the West, a famed heirloom of Elendil's house. # The Arkenstone of Thrain # Was +2 WIS/DEX N:3:of Thrain I:39:102:3 W:50:50:5:50000 P:0:1d1:0:0:0 F:ACTIVATE | SEE_INVIS | HOLD_LIFE | RES_CHAOS | HIDE_TYPE | LUCK F:INSTA_ART | SPEED | RES_LITE | RES_DARK | ESP_ORC | LITE3 a:HARDCORE=THRAIN D:A great globe seemingly filled with moonlight, the famed Heart of the D:Mountain, which splinters the light that falls upon it into a thousand D:glowing shards. # The Amulet of Carlammas N:4:of Carlammas I:40:10:2 W:50:10:3:60000 F:CON | HIDE_TYPE | F:ACTIVATE | RES_FIRE | F:INSTA_ART a:HARDCORE=PROT_EVIL D:A fiery circle of bronze, with mighty spells to ward off evil. # The Amulet of Ingwe N:5:of Ingwe I:40:11:3 W:65:30:3:90000 F:INT | WIS | CHR | SEARCH | INFRA | HIDE_TYPE | F:SEE_INVIS | FREE_ACT | ACTIVATE | F:RES_ACID | RES_COLD | RES_ELEC | F:INSTA_ART a:HARDCORE=DISP_EVIL D:The ancient heirloom of Ingwe, high lord of the Vanyar, against whom nothing D:of evil could stand. # The Necklace 'Nauglamir' N:6:'Nauglamir' I:40:12:3 W:70:50:3:75000 F:STR | CON | DEX | INFRA | HIDE_TYPE | RES_FEAR | F:SEE_INVIS | FREE_ACT | REGEN | LITE3 | SPEED | F:INSTA_ART D:A carencet of gold, set with a multitude of shining gems of D:Valinor. Despite its size, its weight seems as that of gossamer. # The Ring of Flare # (note: pval reduced to 3, otherwise it would probably be preferable # even to The One Ring!) N:7:of Flare I:45:52:3 W:50:35:2:75000 F:STR | CON | CHR | HIDE_TYPE | F:IM_FIRE | ACTIVATE | SEARCH | F:ESP_THUNDERLORD | SEE_INVIS | FLY | F:INSTA_ART a:HARDCORE=DIM_DOOR Z:swap position D:The mighty ring of the Thunderlord Flare that makes the wearer D:strong and healthy. Once a ring of power, it was D:given to Flare by Celegorm when he arrived on Middle-earth with a full nest D:of Thunderlords. # The Ring of Barahir N:8:of Barahir I:45:32:1 W:50:25:2:75000 F:STR | INT | WIS | DEX | CON | CHR | STEALTH | HIDE_TYPE | F:RES_POIS | RES_DARK | ACTIVATE | SEE_INVIS | SEARCH | F:INSTA_ART a:HARDCORE=BARAHIR D:A ring shaped into twinned serpents with eyes of emerald meeting beneath D:a crown of flowers, an ancient treasure of Isildur's house. # The Ring of Tulkas N:9:of Tulkas I:45:33:4 W:70:50:2:175000 F:STR | DEX | CON | HIDE_TYPE | F:ACTIVATE | SPEED | ESP_EVIL | F:INSTA_ART a:HARDCORE=TULKAS D:The treasure of Tulkas, most fleet and wrathful of the Valar. # The Ring of Power 'Narya' N:10:of Power 'Narya' I:45:34:1 W:70:30:2:100000 P:0:1d1:6:6:0 F:STR | INT | WIS | DEX | CON | CHR | SPEED | HIDE_TYPE | LUCK F:ACTIVATE | FREE_ACT | SEE_INVIS | F:SUST_STR | SUST_CON | SUST_WIS | SUST_CHR | SPECIAL_GENE | F:IM_FIRE | RES_NETHER | RES_FEAR | REGEN | F:INSTA_ART a:HARDCORE=NARYA D:The Ring of Fire, set with a ruby that glows like flame. Narya is one D:of the three Rings of Power created by the Elves and hidden by them from D:Sauron. # The Ring of Power 'Nenya' N:11:of Power 'Nenya' I:45:35:2 W:80:40:2:200000 P:0:1d1:9:9:0 F:STR | INT | WIS | DEX | CON | CHR | SPEED | HIDE_TYPE | LUCK F:ACTIVATE | HOLD_LIFE | FREE_ACT | SEE_INVIS | F:SUST_INT | SUST_WIS | SUST_CHR | F:IM_COLD | RES_BLIND | STEALTH | ESP_ALL | F:INSTA_ART a:HARDCORE=NENYA D:The Ring of Adamant, with a pure white stone as centrepiece. Nenya is one D:of the three Rings of Power created by the Elves and hidden by them from D:Sauron. # The Ring of Power 'Vilya' N:12:of Power 'Vilya' I:45:36:3 W:90:50:2:300000 P:0:1d1:12:12:0 F:STR | INT | WIS | DEX | CON | CHR | SPEED | HIDE_TYPE | LUCK F:ACTIVATE | HOLD_LIFE | FREE_ACT | SEE_INVIS | F:FEATHER | SLOW_DIGEST | REGEN | F:SUST_STR | SUST_DEX | SUST_CON | F:IM_ELEC | RES_POIS | RES_DISEN | F:INSTA_ART a:HARDCORE=VILYA D:The Ring of Sapphire, with clear blue gems that shine like stars, D:glittering untouchable despite all that Sauron ever wrought. Vilya is D:one of the three Rings of Power created by the Elves and hidden by them D:from Sauron. # The Ring of Power 'The One Ring' N:13:of Power 'The One Ring' I:45:37:5 W:100:100:2:5000000 P:0:1d1:15:15:0 F:STR | INT | WIS | DEX | CON | CHR | SPEED | HIDE_TYPE | F:ACTIVATE | AUTO_CURSE | HEAVY_CURSE | INVIS | SPELL | MANA | F:SEE_INVIS | REGEN | FREE_ACT | CURSED | CURSE_NO_DROP | F:IM_FIRE | IM_COLD | IM_ELEC | IM_ACID | PERMA_CURSE | F:SUST_STR | SUST_DEX | SUST_CON | F:SUST_INT | SUST_WIS | SUST_CHR | F:RES_BLIND | RES_POIS | RES_DISEN | RES_NETHER | ESP_ALL | F:DRAIN_MANA | DRAIN_HP | DRAIN_EXP | F:INSTA_ART a:HARDCORE=POWER Z:change the world D:"Ash nazg durbatuluk, ash nazg gimbatul, ash nazg thrakatuluk agh D:burzum-ishi krimpatul". Unadorned, made of massive gold, D:set with runes in the foul speech of Mordor, with power so great that it D:inevitably twists and masters any earthly being who wears it. # The Anchor of Space-Time N:14:of Space-Time I:39:105:0 W:30:12:15:50000 P:0:1d1:0:0:0 F:INSTA_ART | LITE1 D:A powerful stone that provides a strong light for any who D:wields it. It is rumoured that it may even protect the wearer from D:the passing of time. # This artifact has a low artifact level to prevent it being worthless for # chars with poor magic skills. # The Stone of Lore N:15:of Lore I:39:106:0 W:15:12:15:20000 P:0:1d1:0:0:0 F:ACTIVATE | SPECIAL_GENE | EASY_USE | LITE1 | F:INSTA_ART a:HARDCORE=STONE_LORE D:A great emerald that fills your mind with images of knowledge and dreadful D:understanding as you stare into its depths. # The Multi-Hued Dragon Scale Mail 'Razorback' N:16:'Razorback' I:38:6:0 W:90:9:500:400000 P:30:2d4:-4:0:25 F:FREE_ACT | IM_ELEC | SPECIAL_GENE | F:RES_FIRE | RES_COLD | RES_POIS | RES_LITE | RES_DARK | F:LITE1 | SEE_INVIS | AGGRAVATE | ESP_DRAGON F:ACTIVATE a:HARDCORE=RAZORBACK D:A massive suit of heavy dragon scales deeply saturated with many colours. D:It throbs with angry energies, and you feel the raw elemental might of D:untamed Lightning as you put it on. # The Power Dragon Scale Mail of Eternity # The ULTIMATE armour N:17:of Eternity I:38:30:0 W:100:16:600:500000 P:50:2d4:-8:0:35 F:HOLD_LIFE | REGEN | ESP_DRAGON | F:RES_ACID | RES_FIRE | RES_COLD | RES_ELEC | RES_POIS | FEATHER | FLY | F:RES_NETHER | RES_NEXUS | RES_CHAOS | RES_LITE | RES_DARK | ULTIMATE | F:RES_SHARDS | RES_SOUND | RES_DISEN | RES_BLIND | RES_CONF | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | SPECIAL_GENE F:ACTIVATE a:HARDCORE=BLADETURNER D:A suit of adamant, set with scales of every colour, surrounded in a nimbus D:of perfectly untramelled yet inextricably intermingled and utterly mastered D:powers elemental and ethereal. # The Spear of Melkor N:18:of Melkor I:22:2:-4 W:65:45:200:100000 P:0:4d6:12:24:0 F:STEALTH | WIS | CURSED | HEAVY_CURSE | TY_CURSE | ESP_GOOD | F:DRAIN_MANA | DRAIN_HP | F:RES_DARK | RES_BLIND | RES_LITE | RES_NETHER | BRAND_POIS | RES_CONF D:The mighty spear used once by Melkor to slay the trees of Valinor. # The Adamantite Plate Mail 'Soulkeeper' N:19:'Soulkeeper' I:37:30:2 W:75:9:420:300000 P:40:2d4:-4:0:20 F:CON | F:HOLD_LIFE | SUST_CON | ESP_UNDEAD | RES_CONF | RES_FEAR | F:RES_ACID | RES_COLD | RES_DARK | RES_NETHER | RES_NEXUS | RES_CHAOS | F:ACTIVATE a:HARDCORE=CURE_1000 D:A suit of imperishable adamant, with unconquerable strength to endure evil D:and disruptive magics, that protects the life force of its wearer as D:nothing else can. # The Full Plate Armour of Isildur N:20:of Isildur I:37:15:1 W:30:3:300:50000 P:25:2d4:0:0:25 F:CON | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:RES_SOUND | RES_CONF | RES_NEXUS D:A gleaming steel suit covering the wearer from neck to foot, with runes of D:warding and stability deeply engraved into its surface. # The Metal Brigandine Armour of the Rohirrim N:21:of the Rohirrim I:37:9:2 W:30:3:200:30000 P:19:1d4:0:0:15 F:STR | DEX | SPEED | HIDE_TYPE | RES_FEAR | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_CONF | RES_SOUND D:A stiff suit of armour composed of small metal plates sewn to an D:inner layer of heavy canvas, and covered with a second layer of D:cloth. Within it is the spirit of Eorl the Young, matchless in combat. # The Mithril Chain Mail 'Belegennon' N:22:'Belegennon' I:37:20:4 W:40:10:150:135000 P:28:1d4:-1:0:20 F:STEALTH | WIS | INT | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | F:HOLD_LIFE | RES_DARK | RES_FEAR | F:SEE_INVIS | F:ACTIVATE a:HARDCORE=BELEGENNON D:This wondrous suit of fine-linked chain shimmers as though of pure silver. D:It stands untouched amidst the fury of the elements, and a power of D:concealment rests within. # The Mithril Plate Mail of Celeborn N:23:of Celeborn I:37:25:4 W:40:3:250:150000 P:35:2d4:-3:0:25 F:STR | CHR | HIDE_TYPE | ESP_ORC F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_DARK | F:RES_DISEN | ACTIVATE a:HARDCORE=GENOCIDE D:A shimmering suit of true-silver, forged long ago by dwarven smiths of D:legend. It gleams with purest white as you gaze upon it, and mighty are D:its powers to protect and banish. # The Chain Mail of Arvedui N:24:of Arvedui I:37:4:2 W:20:3:220:32000 P:14:1d4:-2:0:15 F:STR | CHR | HIDE_TYPE | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_SHARDS | RES_NEXUS D:A hauberk, leggings, and sleeves of interlocking steel rings, well padded D:with leather. You feel strong and tall as Arvedui, last king of Arnor, D:as you put it on. # The Augmented Chain Mail of Caspanion N:25:of Caspanion I:37:6:3 W:25:9:270:40000 P:16:1d4:-2:0:20 F:INT | WIS | CON | HIDE_TYPE | F:RES_ACID | RES_POIS | RES_CONF | ACTIVATE a:HARDCORE=DEST_DOOR D:A hauberk, leggings, and sleeves of interlocking steel rings, strategically D:reinforced at vital locations with a second layer of chain. Magics to D:enhance body and mind lie within, and no door can hope to resist the wearer. # The Thunderlord Coat of Marda N:26:of Marda I:36:16:5 W:70:3:80:80000 P:9:0d0:0:0:25 F:FREE_ACT | RES_BLIND | RES_CONF | RES_FEAR | DRAIN_MANA | F:REFLECT | RES_NEXUS | SH_FIRE | SUST_INT | SUST_CON | SUST_CHR | F:ESP_THUNDERLORD | CON | CHR | INT | F:RES_ACID | RES_ELEC | IM_COLD | RES_COLD | AGGRAVATE | HEAVY_CURSE | F:CURSED D:The flying suit of Marda, very powerful armour that protects D:the wearer from cold. Wonderful as this mighty D:armour is, beware wearing it, for it has been cursed by a D:powerful wizard since Marda had it and is said to have gained D:a couple of undesirable side-effects... # The Thunderlord Coat of Trone N:27:of Trone I:36:16:4 W:30:3:80:65000 P:9:0d0:0:0:20 F:REFLECT | RES_NEXUS | SH_FIRE | FLY | SPECIAL_GENE | F:STEALTH | ESP_THUNDERLORD | CON | INT | SPEED | F:RES_ACID | RES_ELEC | IM_FIRE | RES_COLD D:The flying suit of Trone. It protects the user from fire and D:imps are said to be less annoying with this on. # The Leather Scale Mail 'Thalkettoth' N:28:'Thalkettoth' I:36:11:3 W:20:3:60:25000 P:11:1d1:-1:0:25 F:DEX | SPEED | HIDE_TYPE | SPECIAL_GENE | F:RES_ACID | RES_SHARDS D:A tunic and skirt sewn with thick, overlapping scales of hardened D:leather whose wearer moves with agility and assurance. # The Pair of Soft Leather Boots of Wormtongue N:29:of Wormtongue I:30:2:3 W:40:20:20:50000 P:2:1d1:-10:-10:10 F:INT | DEX | CHR | STEALTH | SEARCH | SPEED | HIDE_TYPE | F:FREE_ACT | FEATHER | RES_DARK | RES_LITE | ESP_GOOD | ESP_UNIQUE Z:panic hit D:The pair of boots used by Grima son of Galmod, also named the Wormtongue: D:a treacherous but persuasive counsellor, ever ready to betray, sneak, D:lie, cheat and steal - but never ready to actually fight. # The Small Metal Shield of Thorin N:30:of Thorin I:34:3:4 W:30:6:65:60000 P:3:1d2:0:0:25 F:STR | CON | HIDE_TYPE | F:FREE_ACT | IM_ACID | RES_SOUND | F:RES_CHAOS | ESP_ORC D:Invoking the strength and endurance of Thorin, King under the Mountain, D:this little metal shield is proof against the Element of Earth. # The Large Leather Shield of Celegorm N:31:of Celegorm I:34:4:0 W:30:3:60:12000 P:4:1d2:0:0:20 F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_LITE | RES_DARK D:This shield emblazoned with a multitude of creatures not seen for ages D:once protected Celegorm, lord of Himlad; around it lies a mystic balance D:that contains the conflicts of the elements. # The Large Metal Shield of Anarion N:32:of Anarion I:34:5:0 W:40:9:120:160000 P:5:1d3:0:0:20 F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | SUST_STR | SUST_INT | F:SUST_WIS | SUST_DEX | SUST_CON | SUST_CHR | ESP_EVIL D:The great metal-bound shield of Anarion, son of Elendil, who Sauron found D:himself powerless to wither or diminish. # The Beaked Axe of Hurin N:33:of Hurin I:22:10:3 W:20:15:180:90000 P:0:2d6:12:20:0 F:STR | CON | HIDE_TYPE | BRAND_ACID | RES_ACID | LITE1 | DRAIN_MANA | F:SLAY_ORC | KILL_DEMON | SLAY_TROLL | ACTIVATE | SHOW_MODS F:MUST2H f:MUST2H a:HARDCORE=HURIN D:Wielded by Hurin Thalion in the Fifth Battle of Beleriand, this D:troll-bane smoked in the black blood of Gothmog's guards. # The Massive Iron Crown of Morgoth N:34:of Morgoth I:33:50:125 W:100:1:20:10000000 P:0:1d1:0:0:0 F:STR | INT | WIS | DEX | CON | CHR | INFRA | HIDE_TYPE | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | F:RES_LITE | RES_DARK | RES_CONF | RES_NEXUS | RES_NETHER | F:LITE1 | SEE_INVIS | ESP_ALL | F:CURSED | HEAVY_CURSE | PERMA_CURSE | F:INSTA_ART | SPECIAL_GENE D:Two Silmarils of Feanor blaze from the thunderous crown of twisted D:iron. The corrupted metal feels at once as infernal as hellfire D:and as chilling as the Outer Darkness. One protrusion from the D:crown is abruptly ended where a third jewel might have shone. # The Iron Crown of Beruthiel N:35:of Beruthiel I:33:10:-5 W:40:12:20:0 P:0:1d1:0:0:20 F:STR | DEX | CON | HIDE_TYPE | F:FREE_ACT | SEE_INVIS | ESP_ANIMAL | ESP_EVIL | ESP_NONLIVING | ESP_ALL | F:CURSED | AUTO_CURSE D:The midnight-hued steel circlet of the sorceress-queen Beruthiel, which D:grants extraordinary powers of sight and awareness at a terrible physical D:cost. # The Hard Leather Cap of Thranduil N:36:of Thranduil I:32:2:2 W:20:2:15:50000 P:2:0d0:0:0:10 F:INT | WIS | HIDE_TYPE | F:RES_BLIND | ESP_ORC | ESP_EVIL | ESP_TROLL D:The hunting cap of King Thranduil, to whose ears come all the secrets of D:his forest domain. # The Metal Cap of Thengel N:37:of Thengel I:32:3:3 W:10:2:20:22000 P:3:1d1:0:0:12 F:WIS | CHR | RES_CONF | HIDE_TYPE | LUCK D:A ridged helmet made of steel, and embossed with scenes of valour in fine- D:engraved silver. It grants the wearer nobility, clarity of thought and D:understanding. # The Steel Helm of Hammerhand N:38:of Hammerhand I:32:6:3 W:20:2:60:45000 P:6:1d3:0:0:20 F:STR | DEX | CON | HIDE_TYPE | SPECIAL_GENE | RES_FEAR | F:SUST_STR | SUST_DEX | SUST_CON | F:RES_ACID | RES_NEXUS | RES_COLD | RES_DARK | SLOW_DIGEST | Z:berserk D:A great helm as steady as the heroes of the Westdike. Mighty were the D:blows of Helm, the Hammerhand! # The Dragon Helm of Dor-Lomin N:39:of Dor-Lomin I:32:7:4 W:40:12:75:300000 P:8:1d3:0:0:20 F:STR | DEX | CON | HIDE_TYPE | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_LITE | RES_BLIND | F:LITE1 | SEE_INVIS | ESP_DRAGON | ESP_THUNDERLORD | ACTIVATE a:HARDCORE=GORLIM D:The legendary dragon helm of Turin Turambar, an object of dread to the D:servants of Morgoth. # The Iron Helm 'Holhenneth' N:40:'Holhenneth' I:32:5:2 W:20:5:75:100000 P:5:1d3:0:0:10 F:INT | WIS | SEARCH | HIDE_TYPE | F:RES_BLIND | SEE_INVIS | ACTIVATE a:HARDCORE=DETECT_ALL D:A famous helm of forged iron granting extraordinary powers of mind and D:awareness. # The Iron Helm of Gorlim N:41:of Gorlim I:32:5:-5 W:20:5:75:0 P:5:1d3:25:25:10 F:INT | WIS | SEARCH | HIDE_TYPE | SHOW_MODS | F:SEE_INVIS | NO_MAGIC | HEAVY_CURSE | TY_CURSE F:RES_DISEN | RES_FEAR | FREE_ACT | RES_ACID | RES_FIRE | RES_POIS | F:IM_COLD | ACTIVATE | DRAIN_HP | F:TELEPORT | CURSED a:HARDCORE=GORLIM D:A headpiece, gaudy and barbaric, that betrayed a warrior when he most D:needed succor. # The Golden Crown of Gondor N:42:of Gondor I:33:11:3 W:40:40:30:125000 P:0:1d1:0:0:15 F:STR | WIS | CON | HIDE_TYPE | SPEED | RES_CONF | RES_SOUND | F:RES_COLD | RES_FIRE | RES_LITE | RES_BLIND | RES_ELEC | RES_CHAOS | F:LITE1 | SEE_INVIS | REGEN | ACTIVATE a:HARDCORE=CURE_700 D:The shining winged circlet brought by Elendil from dying Numenor, emblem of D:Gondor through an age of the world. # The Jewel Encrusted Crown of Numenor # Stolen from Oangband N:43:of Numenor I:33:12:3 W:60:30:40:50000 P:0:1d1:0:0:18 F:INT | DEX | CHR | SEARCH | SPEED | HIDE_TYPE | F:SEE_INVIS | FREE_ACT | RES_DARK | RES_BLIND | F:RES_SHARDS | RES_SOUND | RES_LITE | RES_COLD | F:LITE1 | ACTIVATE | DRAIN_MANA a:HARDCORE=NUMENOR D:A crown of massive gold, set with wondrous jewels of thought and warding, D:worn by the kings of ancient Numenor. Its wearer may go into battle D:always knowing what he faces - unless his own folly blinds him to the D:nature and magnitude of the task. # The Cloak 'Colluin' N:44:'Colluin' I:35:1:0 W:5:45:10:40000 P:1:0d0:0:0:20 F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS | ACTIVATE | ESP_GOOD a:HARDCORE=COLLUIN D:A cape worn by a hero from Valinor, a land utterly beyond the strife D:of Elements. # The Cloak 'Holcolleth' N:45:'Holcolleth' I:35:1:2 W:5:25:10:13000 P:1:0d0:0:0:4 F:INT | WIS | SPEED | STEALTH | HIDE_TYPE | F:RES_ACID | ACTIVATE a:HARDCORE=SLEEP D:This elven-grey mantle possesses great powers of tranquility and of D:concealment, and grants the wearer the knowledge and understanding of D:the Sindar. # The Cloak of Thingol N:46:of Thingol I:35:1:3 W:10:50:10:35000 P:1:0d0:0:0:18 F:DEX | CHR | HIDE_TYPE | F:FREE_ACT | RES_ACID | RES_FIRE | RES_COLD | ACTIVATE a:HARDCORE=RECHARGE D:A sable-hued cloak, with glowing elven-runes to restore magic showing calm D:and clear as moonlight on still water. # The Cloak of Thorongil N:47:of Thorongil I:35:1:0 W:5:10:10:8000 P:1:0d0:0:0:10 F:FREE_ACT | RES_ACID | SEE_INVIS | RES_FEAR D:A cloak of shimmering green and brown that grants sight beyond sight and D:shakes off holding magics, worn by Aragorn son of Arathorn in his youth D:as he adventured under the name of Thorongil. # The Cloak 'Colannon' N:48:'Colannon' I:35:1:3 W:5:20:10:11000 P:1:0d0:0:0:15 F:STEALTH | SPEED | RES_NEXUS | F:RES_ACID | ACTIVATE a:HARDCORE=TELEPORT D:A crystal-blue cape of fine silk worn by a silent messenger of D:the forces of Law. Somehow, its wearer is always able to escape D:trouble. # The Shadow Cloak of Luthien N:49:of Luthien I:35:6:2 W:40:40:5:55000 P:6:0d0:0:0:20 F:INT | WIS | CHR | HIDE_TYPE | SPEED | STEALTH | INVIS | LUCK F:RES_ACID | RES_FIRE | RES_COLD | SPECIAL_GENE | ACTIVATE | SPELL_CONTAIN | WIELD_CAST a:HARDCORE=REST_LIFE D:The opaque midnight folds, inset with a multitude of tiny diamonds, of D:this cloak swirl around you and you feel a hint, a fragment of the D:knowledge and power to restore that lay in Luthien, the most beautiful D:being that ever knew death. # The Shadow Cloak of Tuor N:50:of Tuor I:35:6:4 W:40:40:5:35000 P:6:0d0:0:0:12 F:STEALTH | DEX | HIDE_TYPE | INVIS | WATER_BREATH F:FREE_ACT | IM_ACID | SEE_INVIS | CLIMB D:From the ruin of Gondolin did Tuor escape, through secret ways and travail, D:shielded by his cloak from a multitude of hostile eyes. # The Main Gauche of Azaghal, which wounded Glaurung N:51:of Azaghal I:23:5:0 W:15:30:30:40000 P:0:2d5:12:14:0 F:KILL_DRAGON | IM_FIRE | ESP_DRAGON | RES_FEAR D:The weapon of Azaghal when he wounded Glaurung. It is deadly D:when fighting dragons and is said to make the breaths of fire D:completely harmless. # The Set of Leather Gloves 'Cambeleg' N:52:'Cambeleg' I:31:1:2 W:10:6:5:36000 P:1:0d0:8:8:15 F:STR | CON | HIDE_TYPE | F:FREE_ACT | SHOW_MODS D:A hero's handgear that lends great prowess in battle. # The Set of Leather Gloves 'Cammithrim' N:53:'Cammithrim' I:31:1:0 W:10:3:5:30000 P:1:0d0:0:0:10 F:FREE_ACT | RES_LITE | SUST_CON | LITE1 | ACTIVATE F:SPECIAL_GENE a:HARDCORE=BO_MISS_1 D:These gloves glow so brightly as to light the way for their owner and cast D:magical bolts with great frequency. # The Set of Gauntlets 'Paurhach' N:54:'Paurhach' I:31:2:0 W:10:5:25:15000 P:2:1d1:0:0:15 F:RES_FIRE | ACTIVATE | SPELL_CONTAIN | WIELD_CAST a:HARDCORE=BO_FIRE_1 D:A fiery set of gauntlets that can even shoot fire from the user's D:hands. # The Set of Gauntlets 'Paurnimmen' N:55:'Paurnimmen' I:31:2:4 W:10:5:25:33000 P:2:1d1:0:0:15 F:RES_COLD | ACTIVATE F:SUST_CON | CON | REGEN | SPELL_CONTAIN | WIELD_CAST a:HARDCORE=BO_COLD_1 D:A set of handgear so icy as to be able to fire frost bolts. # The Set of Gauntlets 'Pauraegen' N:56:'Pauraegen' I:31:2:0 W:10:5:25:11000 P:2:1d1:0:0:15 F:RES_ELEC | ACTIVATE | SPELL_CONTAIN | WIELD_CAST a:HARDCORE=BO_ELEC_1 D:A set of handgear with sparks surrounding it, able to fire D:bolts of electricity. # The Set of Gauntlets 'Paurnen' N:57:'Paurnen' I:31:2:0 W:10:5:25:12000 P:2:1d1:0:0:15 F:RES_ACID | ACTIVATE | SPELL_CONTAIN | WIELD_CAST a:HARDCORE=BO_ACID_1 D:A set of handgear so corrosive that it may fire bolts of acid. # The Set of Gauntlets 'Camlost' N:58:'Camlost' I:31:2:-3 W:10:20:25:0 P:2:1d1:-11:-12:0 F:STR | DEX | HIDE_TYPE | DRAIN_MANA | F:RES_POIS | IM_FIRE | IM_COLD | RES_DISEN | RES_NETHER | FREE_ACT | F:AGGRAVATE | SHOW_MODS | HEAVY_CURSE | TY_CURSE | TELEPORT | CURSED D:A pair of gauntlets that sap combat ability, named after the empty hand D:of Beren that once clasped a Silmaril. # The Set of Cesti of Fingolfin N:59:of Fingolfin I:31:5:4 W:40:15:40:110000 P:5:1d1:10:10:20 F:DEX | HIDE_TYPE | LUCK F:FREE_ACT | RES_ACID | ACTIVATE | SHOW_MODS a:HARDCORE=BO_MISS_2 Z:magic missile D:The hand-sheathing of Fingolfin, warrior-king of Elves and Men, who gave D:Morgoth seven mighty wounds and pain that will last forever. # The Pair of Hard Leather Boots of Feanor N:60:of Feanor I:30:3:15 W:40:120:40:300000 P:3:1d1:0:0:20 F:SPEED | HIDE_TYPE | F:RES_NEXUS | ACTIVATE a:HARDCORE=SPEED D:This wondrous pair of leather boots once sped Feanor, creator of the D:Silmarils and the mightiest of the Eldar, along the Grinding Ice and to D:Middle-earth at last. # The Pair of Soft Leather Boots 'Dal-i-thalion' N:61:'Dal-i-thalion' I:30:2:5 W:10:25:20:40000 P:2:1d1:0:0:15 F:DEX | HIDE_TYPE | CHR | SUST_CHR | F:ACTIVATE | FREE_ACT | F:RES_NETHER | RES_CHAOS | RES_CONF | SUST_CON a:HARDCORE=CURE_POISON D:A pair of high-laced shoes, strong against the powers of corruption and D:withering, that grant the wearer extraordinary agility. # The Pair of Metal Shod Boots of Thror N:62:of Thror I:30:6:3 W:30:25:80:15000 P:6:1d1:0:0:20 F:STR | CON | HIDE_TYPE | SPEED | RES_FEAR | CLIMB D:Sturdy footwear of leather and steel as enduring as the long-suffering D:Dwarven King-in-exile who wore them. Of dwarven make, these boots will D:make their wearer completely at home in the mountains. # The Seeker Arrow of Bard # This is, of course, from my 'Artifact Ammo' thread and doesn't need much # explanation. It's rather nasty and deals 1000 or more damage on a # normal hit to a dragon. :) Doesn't put a dent in Sky Drakes and Power # Dragons, tho it's still good for helping to take down Smaug, Tiamat and # the other dragon uniques. # P+ changed name, rarity to 30 N:63:of Bard I:17:2:0 W:55:30:2:50000 P:0:8d4:20:15:0 F:SLAY_ANIMAL | SLAY_EVIL | SLAY_UNDEAD | SLAY_DEMON | F:SLAY_ORC | SLAY_TROLL | SLAY_GIANT | SLAY_DRAGON | KILL_DRAGON | F:BRAND_ACID | BRAND_ELEC | BRAND_FIRE | BRAND_COLD | BRAND_POIS D:Deadliest of arrows, imbued with elemental strength, this shaft is D:feared especially by the wyrmkin. # The Main Gauche of Maedhros N:64:of Maedhros I:23:5:3 W:15:30:30:22500 P:0:2d5:12:15:0 F:INT | DEX | HIDE_TYPE | SPEED | SPECIAL_GENE F:SLAY_TROLL | SLAY_GIANT | FREE_ACT | SEE_INVIS | SHOW_MODS D:A short thrusting blade with a large guard worn by Maedhros the Tall, D:eldest son of Feanor, and wielded with his left hand after the loss of D:his right hand in the pits of Thangorodrim. # The Dagger 'Angrist' N:65:'Angrist' I:23:4:4 W:20:80:12:125000 P:0:2d4:10:15:5 F:DEX | HIDE_TYPE | STEALTH | SEARCH | BRAND_POIS | F:SLAY_EVIL | SLAY_TROLL | SLAY_ORC | BRAND_ACID | F:FREE_ACT | RES_DARK | SUST_DEX | SEE_INVIS | F:SHOW_MODS D:Forged from meteoric iron, this long chopping dagger slices through D:ordinary metal as easily as its title, "Iron Cleaver", suggests. # The Dagger 'Narthanc' N:66:'Narthanc' I:23:4:0 W:4:100:12:12000 P:0:1d4:4:6:0 F:BRAND_FIRE | RES_FIRE | ACTIVATE | SHOW_MODS | LITE1 | LEVELS a:HARDCORE=BO_FIRE_1 D:A fiery dagger finely balanced for deadly throws. # The Dagger 'Nimthanc' N:67:'Nimthanc' I:23:4:0 W:3:100:12:11000 P:0:1d4:4:6:0 F:BRAND_COLD | RES_COLD | ACTIVATE | SHOW_MODS | LEVELS a:HARDCORE=BO_COLD_1 D:A frosty dagger finely balanced for deadly throws. # The Dagger 'Dethanc' N:68:'Dethanc' I:23:4:0 W:5:100:12:13000 P:0:1d4:4:6:0 F:BRAND_ELEC | RES_ELEC | ACTIVATE | SHOW_MODS | LEVELS a:HARDCORE=BO_ELEC_1 D:A dagger covered in sparks and finely balanced for deadly throws. # The Dagger of Rilia N:69:of Rilia I:23:4:0 W:5:40:12:35000 P:0:2d4:4:3:0 F:SLAY_ORC | RES_POIS | RES_DISEN | ACTIVATE | SHOW_MODS | BRAND_POIS a:HARDCORE=BA_POIS_1 D:A large stiletto dagger that glistens with odourless poison, to which the D:wearer seems oddly immune. # The Dagger 'Belangil' N:70:'Belangil' I:23:4:2 W:10:40:12:50000 P:0:2d4:6:9:0 F:DEX | HIDE_TYPE | SPEED | BLOWS | F:BRAND_COLD | RES_COLD | F:SEE_INVIS | SLOW_DIGEST | REGEN | F:ACTIVATE | SHOW_MODS | BRAND_POIS a:HARDCORE=BELANGIL D:A frosty dagger surrounded in a nimbus of ice with a hilt of elk horn and D:an edge to wound the wind. # The Bastard Sword 'Calris' N:71:'Calris' I:23:21:5 W:30:15:140:100000 P:0:5d4:-20:20:0 F:CON | HIDE_TYPE | DRAIN_HP | F:KILL_DRAGON | SLAY_EVIL | SLAY_DEMON | SLAY_TROLL | RES_DISEN | F:AGGRAVATE | CURSED | HEAVY_CURSE | SHOW_MODS | ESP_DRAGON | ESP_DEMON F:AUTO_CURSE F:COULD2H f:COULD2H D:This sword has runes of power incised on its ornate hilt and a single D:blood channel that gleams coldly blue as you grasp this mighty weapon of D:peril. # The Broad Sword 'Aranruth' N:72:'Aranruth' I:23:16:4 W:20:45:150:125000 P:0:3d5:20:12:0 F:STR | DEX | CON | SUST_CON | SUST_STR F:REGEN | FREE_ACT | SEE_INVIS | F:RES_CHAOS | RES_NETHER | HOLD_LIFE | RES_FEAR | F:RES_COLD | F:SLAY_DEMON | SLAY_EVIL | SLAY_DRAGON | SLAY_UNDEAD | F:BRAND_COLD | F:SLOW_DIGEST | SHOW_MODS | HIDE_TYPE | BLESSED D:The beautiful sword of Thingol with a hilt of gold and silver inlay, D:glistening icily enough to freeze the hearts of demons. You feel supple D:and lightfooted as you hold it. # The Broad Sword 'Glamdring' N:73:'Glamdring' I:23:16:1 W:20:20:150:40000 P:0:2d5:10:15:0 F:SEARCH | HIDE_TYPE | BLESSED | SLAY_DEMON | F:SLAY_EVIL | BRAND_FIRE | SLAY_ORC | RES_FIRE | RES_LITE | LITE1 | F:SLOW_DIGEST | SHOW_MODS | ESP_ORC | SPECIAL_GENE | D:This fiery, shining blade earned its sobriquet "Foe-Hammer" from dying orcs D:who dared to come near hidden Gondolin. # The Broad Sword 'Aeglin' N:74:'Aeglin' I:23:16:4 W:20:90:150:95000 P:0:2d5:12:16:0 F:SEARCH | BLESSED | LITE1 | HIDE_TYPE | F:BRAND_ELEC | SLAY_ORC | SLAY_GIANT | SLAY_TROLL | RES_FEAR | F:RES_ELEC | RES_FIRE | RES_BLIND | ESP_ORC | ESP_GIANT | ESP_TROLL | F:SLOW_DIGEST | SHOW_MODS D:Like unto Orcrist and Glamdring, and like them long lost, this sword is D:continually coved in tiny arcs of captive lightning that flash and dance D:eerily in the globe of light they create. # The Broad Sword 'Orcrist' N:75:'Orcrist' I:23:16:3 W:20:20:150:40000 P:0:2d5:10:15:0 F:SEARCH | ESP_ORC | SLAY_DRAGON | ESP_DRAGON | RES_COLD | HIDE_TYPE | F:SLAY_EVIL | BRAND_COLD | SLAY_ORC | RES_COLD | LITE1 | RES_DARK | F:SLOW_DIGEST | SHOW_MODS D:This coldly gleaming blade is called simply "Biter", by orcs who came to D:know its power all too well. # The Two-Handed Sword 'Gurthang' N:76:'Gurthang' I:23:25:2 W:30:30:200:100000 P:0:3d6:13:17:0 F:STR | HIDE_TYPE | VORPAL | ESP_DRAGON | DRAIN_HP | F:RES_FIRE | RES_POIS | BRAND_FIRE | BRAND_POIS | F:KILL_DRAGON | SLAY_TROLL | FREE_ACT | SLOW_DIGEST | REGEN | SHOW_MODS F:MUST2H f:MUST2H D:A giant sword once wielded by mighty Turin, and a great dragonbane which D:bathed in Glaurung's blood: but beware, it will drink the blood of those D:who wield it eventually. # The Two-Handed Sword 'Zarcuthra' N:77:'Zarcuthra' I:23:25:4 W:30:180:250:205000 P:0:4d6:19:21:0 F:STR | CHR | INFRA | HIDE_TYPE | VORPAL | DRAIN_MANA | F:KILL_DRAGON | SLAY_ANIMAL | SLAY_EVIL | BRAND_FIRE | F:SLAY_UNDEAD | SLAY_DEMON | SLAY_TROLL | SLAY_GIANT | SLAY_ORC | F:RES_FIRE | RES_CHAOS | FREE_ACT | SEE_INVIS | AGGRAVATE | SHOW_MODS F:MUST2H f:MUST2H D:Dark and deadly runes stand stark against the naked steel of this awesome D:weapon, and you feel a stunning power of slaying and rending as you D:slowly approach. # The Dark Sword 'Mormegil' N:78:'Mormegil' I:23:33:2 W:30:15:250:0 P:0:6d7:0:0:-20 F:SPEED | IM_FIRE | RES_FIRE | BRAND_FIRE | RES_DISEN | RES_FEAR | F:AGGRAVATE | CURSED | HEAVY_CURSE | SHOW_MODS | LEVELS | TY_CURSE | F:BLOWS | SLAY_DRAGON | RES_CHAOS | ANTIMAGIC_50 | F:DRAIN_MANA | DRAIN_HP | DRAIN_EXP D:A foul, twisted sword with blackened spines and knobs, whose very name is a D:curse upon the lips of Elves and Men. # The Cutlass 'Gondricam' N:79:'Gondricam' I:23:12:3 W:20:8:110:28000 P:0:1d7:10:11:0 F:DEX | STEALTH | HIDE_TYPE | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | FEATHER | F:SEE_INVIS | REGEN | SHOW_MODS D:Famed sea-defender of Lebennin. A short, slightly curved chopping blade D:with a perfect edge shining cleanly in the sun, an object of hate to the D:men of Umbar who met it in combat. # The Executioner's Sword 'Crisdurian' N:80:'Crisdurian' I:23:28:0 W:40:15:260:111000 P:0:4d5:18:19:0 F:SLAY_DRAGON | SLAY_EVIL | SLAY_UNDEAD | SLAY_TROLL | SLAY_GIANT | F:SLAY_ORC | SEE_INVIS | SHOW_MODS | VORPAL | BRAND_POIS | WOUNDING F:MUST2H f:MUST2H D:A giant's weapon, with a long blade tall and straight thrusting out from a D:massive double-pronged hilt. On its blade are written doomspells against D:both the living and undead. # The Katana 'Aglarang' N:81:'Aglarang' I:23:20:5 W:35:25:50:40000 P:0:8d4:0:0:0 F:DEX | TUNNEL | SPEED | HIDE_TYPE | F:SUST_DEX | SHOW_MODS F:COULD2H f:COULD2H D:An utterly perfect, cleanly chiselled sword, with a edge that effortlessly D:slices rock and bone, and spells to render the wearer lithe and nimble. It D:is combat incarnate. # The Long Sword 'Ringil' N:82:'Ringil' I:23:17:10 W:20:120:130:300000 P:0:4d5:22:25:0 F:SPEED | HIDE_TYPE | RES_FEAR | BLESSED | F:SLAY_EVIL | BRAND_COLD | SLAY_UNDEAD | KILL_DEMON | SLAY_TROLL | F:FREE_ACT | RES_COLD | RES_LITE | LITE1 | SEE_INVIS | SLOW_DIGEST | REGEN | F:ACTIVATE | SHOW_MODS a:HARDCORE=BA_COLD_2 D:The weapon of Fingolfin, High King of the Noldor; it shines like a column D:of ice lit by light unquenchable. Morgoth came but unwillingly to meet it D:of old; his lame foot will remind him of its might should he meet it again. # The Long Sword 'Anduril' N:83:'Anduril' I:23:17:4 W:20:40:130:100000 P:0:3d5:10:15:5 F:STR | DEX | HIDE_TYPE | RES_FEAR | FREE_ACT | BLESSED | LUCK F:SLAY_EVIL | BRAND_FIRE | SLAY_TROLL | SLAY_ORC | FREE_ACT | F:RES_FIRE | SUST_DEX | SEE_INVIS | ACTIVATE | SHOW_MODS | LITE1 F:RES_DISEN | SPECIAL_GENE a:HARDCORE=BA_FIRE_1 D:The famed "Flame of the West", the sword that was broken and is forged D:again. It glows with the essence of fire, its wearer is mighty in combat, D:and no creature of Sauron can withstand it. It will never be stained or D:broken even in defeat. # The Long Sword 'Anguirel' N:84:'Anguirel' I:23:17:2 W:20:30:130:40000 P:0:2d5:8:12:0 F:STR | CON | SPEED | HIDE_TYPE | F:SLAY_EVIL | BRAND_ELEC | SLAY_DEMON | FREE_ACT | RES_ELEC | F:RES_LITE | RES_DARK | SEE_INVIS | SHOW_MODS | VORPAL | WOUNDING F:AGGRAVATE | CURSED D:Forged of black galvorn by the Dark-Elven smith Eol, this blade has the D:living lightning trapped inside. # The Long Sword 'Elvagil' N:85:'Elvagil' I:23:17:2 W:20:8:130:20000 P:0:2d5:5:7:0 F:DEX | CHR | STEALTH | HIDE_TYPE | ESP_ORC | ESP_TROLL F:SLAY_TROLL | SLAY_ORC | FEATHER | SEE_INVIS | SHOW_MODS D:The "Singing Blade", whose wearer can slay Orcs and Trolls in the hidden D:and secret places of the earth. # The Rapier 'Forasgil' N:86:'Forasgil' I:23:7:0 W:15:8:40:15000 P:0:1d6:12:19:0 F:SLAY_ANIMAL | BRAND_COLD | RES_COLD | RES_LITE | SHOW_MODS D:A slender, tapered blade whose wielder strikes icy blows with deadly D:accuracy. # The Sabre 'Careth Asdriag' N:87:'Careth Asdriag' I:23:11:2 W:15:8:50:25000 P:0:2d7:6:8:0 F:DEX | BLOWS | SPEED | CON | F:SLAY_DRAGON | SLAY_ANIMAL | SLAY_TROLL | SLAY_GIANT | F:SLAY_ORC | SHOW_MODS | ESP_ANIMAL D:An heirloom of the Lords of Rhun far to the east, and a name of D:dismay to creatures natural and unnatural. # The Small Sword 'Sting' N:88:'Sting' I:23:8:2 W:20:205:75:100000 P:0:1d6:7:8:0 F:STR | DEX | CON | BLOWS | SPEED | LEVELS | F:ESP_ORC | ESP_UNDEAD | ESP_SPIDER | F:SLAY_EVIL | SLAY_UNDEAD | SLAY_ORC | SLAY_ANIMAL | LITE1 | F:FREE_ACT | RES_LITE | SEE_INVIS | SHOW_MODS | D:"I will give you a name, and I shall call you Sting." The perfect size D:for Bilbo, and stamped forever by the courage he found in Mirkwood, this D:sturdy little blade grants the wearer combat prowess and survival D:abilities they did not know they had. # The Scimitar 'Haradekket' N:89:'Haradekket' I:23:18:2 W:20:8:130:111111 P:0:2d5:9:11:0 F:INT | WIS | BLOWS | F:SLAY_ANIMAL | SLAY_EVIL | SLAY_UNDEAD | SLAY_DRAGON | SLAY_DEMON | F:RES_CHAOS | RES_DISEN | RES_NEXUS | F:SEE_INVIS | BLESSED | F:SHOW_MODS D:A damascened scimitar that seems wondrously easy to hold. Famed in song as D:the "Sickle of Harad", and a deadly foe to the undead. # The Short Sword 'Gilettar' N:90:'Gilettar' I:23:10:2 W:20:8:80:35000 P:0:1d7:3:7:0 F:BLOWS | HIDE_TYPE | F:SLAY_ANIMAL | SLOW_DIGEST | REGEN | SHOW_MODS | SEE_INVIS | RES_DISEN D:A stubby blade worn by Beren, whose horn sounded of old in the glades of D:Brethil. # The Blade of Chaos 'Doomcaller' N:91:'Doomcaller' I:23:30:0 W:70:25:180:250000 P:0:6d5:18:28:-50 F:KILL_DRAGON | SLAY_ANIMAL | SLAY_EVIL | BRAND_COLD | SLAY_TROLL | F:SLAY_ORC | FREE_ACT | RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:RES_CHAOS | SEE_INVIS | ESP_EVIL | AGGRAVATE | SHOW_MODS | F:CHAOTIC | VORPAL | BRAND_FIRE | BRAND_POIS | SPECIAL_GENE D:This weapon of wrath, cursed with a violent anger, dives hungrily D:into the flesh of its enemies. It gathers shadows of death into its D:owner as they inflict wounds that will never heal. # The Long Sword 'Vorpal Blade' N:92:'Vorpal Blade' I:23:17:2 W:50:30:150:250000 P:0:5d5:32:32:0 F:VORPAL | SLAY_EVIL | WOUNDING F:FREE_ACT | SEE_INVIS | SLOW_DIGEST | REGEN | SPEED | STR | DEX D:"One, two! One, two! And through, and through, the vorpal blade D:went snicker-snack!" # The Beaked Axe of Theoden N:93:of Theoden I:22:10:3 W:20:15:180:40000 P:0:2d6:8:10:0 F:WIS | CON | HIDE_TYPE | F:SLAY_DRAGON | ESP_EVIL | ESP_UNDEAD | SLOW_DIGEST | ACTIVATE | SHOW_MODS a:HARDCORE=DRAIN_2 D:The narrow axe head of this weapon, finely balanced by a crow's beak, D:would pierce even the armour of Smaug, and its wielder becomes aware of D:the minds of their enemies. # The Glaive of Pain N:94:of Pain I:22:13:0 W:30:155:190:50000 P:0:9d6:0:30:0 F:SHOW_MODS | LEVELS | DRAIN_MANA F:COULD2H f:COULD2H D:The massive chopper that crowns this glaive glows blood-red and black; D:fell spells of annihilation swirl and dance as you swing death's myrmidon D:down. # The Halberd 'Osondir' N:95:'Osondir' I:22:15:3 W:20:8:190:22000 P:0:3d5:6:9:0 F:CHR | HIDE_TYPE | F:BRAND_FIRE | SLAY_UNDEAD | SLAY_GIANT | RES_FIRE | RES_SOUND | F:FEATHER | SEE_INVIS | SHOW_MODS | ESP_GIANT F:COULD2H f:COULD2H D:Lordly and tall did Osondir stand against the wrath of giants, and D:clear-eyed in barrows fell, wielding a halberd glowing ruby red. # The Pike 'Til-i-arc' N:96:'Til-i-arc' I:22:8:2 W:20:15:160:32000 P:0:2d5:10:12:10 F:INT | HIDE_TYPE | F:BRAND_COLD | BRAND_FIRE | SLAY_DEMON | SLAY_TROLL | SLAY_GIANT | ESP_GIANT F:RES_FIRE | RES_COLD | SUST_INT | SLOW_DIGEST | SHOW_MODS | F:COULD2H f:COULD2H D:Within this long thrusting spear lie the spirits of frost giants and fire D:demons, who war forever, trapped by magely spells. # The Spear 'Aeglos' N:97:'Aeglos' I:22:2:4 W:15:45:50:180000 P:0:3d6:15:25:5 F:DEX | WIS | HIDE_TYPE | F:BRAND_COLD | BRAND_ELEC | LITE1 | F:SLAY_TROLL | SLAY_ORC | SLAY_GIANT | KILL_UNDEAD | F:FREE_ACT | RES_COLD | RES_ELEC | RES_LITE | F:SLOW_DIGEST | ACTIVATE | BLESSED | SHOW_MODS | a:HARDCORE=BA_ELEC_2 D:The mighty spear of Gil-galad, famed as "Snow-point" in the songs of D:Elves, against which all the foul corruptions of Sauron dashed in vain. # The Spear of Orome N:98:of Orome I:22:2:4 W:15:45:50:77777 P:0:4d6:15:15:0 F:INT | WIS | SPEED | TUNNEL | INFRA | HIDE_TYPE | SEARCH | F:BRAND_FIRE | F:SLAY_GIANT | SLAY_EVIL | SLAY_DEMON | SLAY_UNDEAD | SLAY_DRAGON | F:RES_FIRE | RES_LITE | HOLD_LIFE | RES_FEAR | F:FEATHER | ESP_GIANT F:SEE_INVIS | F:ACTIVATE | BLESSED | SHOW_MODS a:HARDCORE=STONE_MUD D:The thrusting spear of wise Orome the Vala, strong against giants of frost, D:which can melt rock or flesh with ease. # The Spear 'Nimloth' N:99:'Nimloth' I:22:2:3 W:15:12:50:30000 P:0:1d6:11:13:0 F:STEALTH | RES_DARK | INFRA | SPEED | BLESSED | F:BRAND_COLD | SLAY_UNDEAD | RES_COLD | SEE_INVIS | SHOW_MODS D:A thin spike of thrice-forged steel caps a straight sylvan shaft cut from D:a legendary tree; spells to break the will of the undead and strike cold D:fear into the hearts of foes lie on this perfectly balanced spear. # The Lance of Eorlingas N:100:of Eorlingas I:22:20:2 W:20:23:360:55000 P:0:3d8:3:21:0 F:STR | DEX | SPEED | HIDE_TYPE | RES_FEAR | F:SLAY_EVIL | SLAY_TROLL | SLAY_ORC | SEE_INVIS | SHOW_MODS F:MUST2H f:MUST2H D:"Forth Eorlingas!" To the field of Cormallen came Eorl the Young D:to save beleaguered Gondor, and from his lance fled massive trolls D:and dire wolves. # The Great Axe of Durin N:101:of Durin I:24:25:3 W:30:90:230:150000 P:0:4d4:10:20:15 F:STR | CON | TUNNEL | HIDE_TYPE | ESP_EVIL | RES_FEAR | F:SLAY_DRAGON | KILL_DEMON | SLAY_TROLL | SLAY_ORC | FREE_ACT | F:RES_ACID | RES_FIRE | RES_LITE | RES_DARK | RES_CHAOS | SHOW_MODS | F:BRAND_ACID | BRAND_FIRE F:MUST2H f:MUST2H D:The twin massive axe heads of this ancient demon's dread gleam with D:mithril inlay, which tell sagas of endurance, invoking the powers of D:Khazad-dum to protect the wearer and slay all evils found underground. # The Great Axe of Eonwe N:102:of Eonwe I:24:25:2 W:30:120:230:200000 P:0:4d4:15:18:8 F:STR | INT | WIS | DEX | CON | CHR | HIDE_TYPE | F:SLAY_EVIL | BRAND_COLD | KILL_DEMON | SLAY_UNDEAD | ESP_NONLIVING F:SLAY_ORC | FREE_ACT | IM_COLD | SEE_INVIS | ACTIVATE | F:BLESSED | SHOW_MODS a:HARDCORE=MASS_GENO D:The axe of Eonwe, leader of the Hosts of the West before the gates of D:Thangorodrim, strikes with icy wrath at the undead, disperses hosts of D:evil at a word, and grants Maia-like powers of body and mind. # The Battle Axe of Balli Stonehand N:103:of Balli Stonehand I:22:22:3 W:30:15:170:90000 P:0:3d8:8:11:5 F:STR | CON | STEALTH | HIDE_TYPE | ESP_NONLIVING F:SLAY_DEMON | SLAY_TROLL | SLAY_ORC | FREE_ACT | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_BLIND | FEATHER | F:SEE_INVIS | REGEN | SHOW_MODS F:COULD2H f:COULD2H D:The twin blades of this weapon were forged in Belegost, and powerful forces D:to resist and endure lie ready for he who shall wield it once more. # The Battle Axe 'Lotharang' N:104:'Lotharang' I:22:22:1 W:30:15:170:21000 P:0:2d8:4:3:0 F:STR | DEX | HIDE_TYPE | F:SLAY_TROLL | SLAY_ORC | ACTIVATE | SHOW_MODS a:HARDCORE=CURE_MW D:A superbly crafted double-bladed axe that slays the creatures of earth and D:allows rapid recovery from their blows. # The Lochaber Axe 'Mundwine' -> of the Dwarves N:105:of the Dwarves I:22:28:10 W:30:8:250:80000 P:0:3d8:12:17:0 F:SLAY_EVIL | TUNNEL | INFRA | SEARCH | SLAY_GIANT | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_FEAR | F:SHOW_MODS F:COULD2H f:COULD2H D:A massive axe with twin razor-sharp heads, so large that it usually D:requires two hands to wield, intricately engraved in gold with spells D:to ward off the elements and smite evil. # The Broad Axe 'Barukkheled' N:106:'Barukkheled' I:24:11:3 W:20:8:160:50000 P:0:2d6:13:19:0 F:CON | HIDE_TYPE | F:SLAY_EVIL | SLAY_TROLL | SLAY_GIANT | SLAY_ORC | F:SEE_INVIS | SHOW_MODS F:COULD2H f:COULD2H D:A royal heirloom of the southern coast, strong in combat against evil D:creatures of the earth. # The Trident of Wrath N:107:of Wrath I:22:5:2 W:15:35:300:90000 P:0:3d8:16:18:0 F:STR | DEX | HIDE_TYPE | CHAOTIC | DRAIN_MANA | F:SLAY_EVIL | KILL_UNDEAD | RES_LITE | RES_DARK | SEE_INVIS | F:BLESSED | SHOW_MODS F:COULD2H f:COULD2H D:A massive triple-pronged spear, so great it normally requires two hands to D:wield, evoking the spirit of Osse who with it pierced legions of D:evil and undead. # The Trident of Ulmo N:108:of Ulmo I:22:5:4 W:30:90:70:120000 P:0:4d8:15:19:0 F:DEX | HIDE_TYPE | F:SLAY_DRAGON | SLAY_ANIMAL | FREE_ACT | HOLD_LIFE | IM_ACID | F:RES_NETHER | SEE_INVIS | SLOW_DIGEST | REGEN | ACTIVATE | F:BLESSED | SHOW_MODS | WATER_BREATH a:HARDCORE=TELE_AWAY D:The awesome weapon of the Vala Ulmo, Lord of Waters. Mightiest of all the D:powers of good save Manwe himself, Ulmo laughs in scorn at the dread powers D:of the undead, and is utterly in command of the element of water. # The Scythe 'Avavir' N:109:'Avavir' I:22:17:3 W:40:8:250:18000 P:0:5d3:8:8:10 F:DEX | CHR | HIDE_TYPE | F:BRAND_COLD | BRAND_FIRE | FREE_ACT | RES_FIRE | RES_COLD | F:RES_LITE | SEE_INVIS | ACTIVATE | SHOW_MODS F:COULD2H f:COULD2H a:HARDCORE=RECALL D:With elemental powers whose struggles turn this weapon red and purest D:white, this shining reaper bears within it a power of going forth and D:returning. # The Long Sword of the Dawn N:110:of the Dawn I:23:17:3 W:40:160:130:250000 P:0:3d5:20:20:0 F:ACTIVATE | BRAND_FIRE | FREE_ACT | RES_FIRE | INFRA | LEVELS | F:SLAY_EVIL | SLAY_DRAGON | SLAY_UNDEAD | SLAY_DEMON | VORPAL | CLONE | F:CHR | SUST_CHR | RES_FEAR | RES_LITE | RES_BLIND | REGEN | SHOW_MODS a:HARDCORE=DAWN D:Forged in the farthest East by a race of mighty spellcasters, this D:shiny pale sword gleams with the rays of rising sun as you invoke D:its power of commanding legions of powerful immortal warriors... # The Mighty Hammer 'Grond' N:111:'Grond' I:21:50:2 W:100:1:1000:500000 P:0:9d9:25:25:10 F:KILL_DRAGON | SLAY_ANIMAL | SLAY_EVIL | IMPACT | KILL_UNDEAD | NO_MAGIC | F:KILL_DEMON | SLAY_TROLL | SLAY_ORC | RES_ACID | RES_ELEC | RES_FIRE | F:RES_COLD | SEE_INVIS | ESP_ALL | AGGRAVATE | SHOW_MODS | INSTA_ART | F:LEVELS | ACTIVATE | SPECIAL_GENE F:MUST2H f:MUST2H a:HARDCORE=GROND D:The mighty Hammer of the Underworld, blackened by doomspells of shattering, D:whose wielder holds the lives of all Morgoth's servants in his hand. # The Flail 'Totila' N:112:'Totila' I:21:13:2 W:20:8:150:55000 P:0:3d6:6:8:0 F:STEALTH | F:SLAY_EVIL | BRAND_FIRE | RES_FIRE | RES_CONF | ACTIVATE | F:SHOW_MODS | LITE1 F:COULD2H f:COULD2H a:HARDCORE=CONFUSE D:A flail whose head befuddles those who stare as you whirl it around, and D:becomes a fiery comet as you bring it down. # The Two-Handed Flail 'Thunderfist' N:113:'Thunderfist' I:21:18:4 W:45:38:300:160000 P:0:3d6:5:18:0 F:STR | CON | HIDE_TYPE | RES_FEAR | F:SLAY_ANIMAL | BRAND_FIRE | BRAND_ELEC | SLAY_TROLL | SLAY_ORC | F:RES_ELEC | RES_FIRE | RES_DARK | SHOW_MODS | F:MUST2H f:MUST2H D:The long-lost weapon of Kzurin, Dwarven champion of ancient Belegost, D:with runes of strength in its handle, and flames and sparks that roar and D:crackle around its massive head. # The Morning Star 'Bloodspike' N:114:'Bloodspike' I:21:12:4 W:20:30:150:30000 P:0:2d6:8:22:0 F:STR | HIDE_TYPE | BRAND_POIS | F:SLAY_ANIMAL | SLAY_TROLL | SLAY_ORC | RES_NEXUS | SEE_INVIS | F:SHOW_MODS D:You feel strong and firm of foot as you whip the chain-suspended spiked orb D:around - and bathe it in the blood of your foes. # The Morning Star 'Firestar' N:115:'Firestar' I:21:12:0 W:20:100:150:35000 P:0:2d6:5:7:2 F:BRAND_FIRE | IM_FIRE | ACTIVATE | SHOW_MODS | LITE1 a:HARDCORE=FIRESTAR D:A famed battle-lord of old, with a ruddy head, coloured as embers are that D:can yet rise up in wrath. # The Mace 'Taratol' N:116:'Taratol' I:21:5:0 W:20:15:200:50000 P:0:3d4:12:12:0 F:KILL_DRAGON | BRAND_ELEC | IM_ELEC | ACTIVATE | SHOW_MODS F:COULD2H f:COULD2H a:HARDCORE=SPEED D:A great ridged mace that calls around you a nimbus of living lightning; D:you remain utterly untouched even as fat sparks arc around your D:fingers and eyebrows. # The War Hammer of Aule N:117:of Aule I:21:8:4 W:40:75:120:250000 P:0:9d3:19:21:5 F:WIS | TUNNEL | HIDE_TYPE | RES_FEAR | F:KILL_DRAGON | SLAY_EVIL | BRAND_ELEC | SLAY_UNDEAD | SLAY_DEMON | F:FREE_ACT | RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_NEXUS | F:SEE_INVIS | SHOW_MODS F:COULD2H f:COULD2H D:The wondrous hammer of Aule, creator of the wise Dwarven lords of old. D:It bears magics of demolishing that no serpent or demon can withstand, and D:invokes the strength of mountains to ward off the tumult of the elements. # The Quarterstaff 'Nar-i-vagil' N:118:'Nar-i-vagil' I:21:3:3 W:20:18:150:70000 P:0:1d9:10:20:0 F:INT | HIDE_TYPE | F:SLAY_ANIMAL | BRAND_FIRE | RES_FIRE | SHOW_MODS F:COULD2H f:COULD2H D:Named for a fiery star and set with gems of great worth binding mystic D:virtues of protection and thought. # The Quarterstaff 'Eriril' N:119:'Eriril' I:21:3:4 W:20:18:150:20000 P:0:1d9:3:5:0 F:INT | WIS | HIDE_TYPE | ESP_EVIL | SPELL_CONTAIN | WIELD_CAST F:SLAY_EVIL | RES_LITE | SEE_INVIS | ACTIVATE | SHOW_MODS a:HARDCORE=ID_PLAIN D:The radiant golden staff of an Istari of legend, this wizard's companion D:grants keen sight and the knowledge of many hidden things. # The Quarterstaff of Olorin N:120:of Olorin I:21:3:4 W:30:105:150:140000 P:0:2d9:10:13:0 F:INT | WIS | CHR | HIDE_TYPE | SEARCH | BRAND_FIRE | F:SLAY_EVIL | BRAND_FIRE | SLAY_TROLL | SLAY_ORC | SPELL_CONTAIN | WIELD_CAST F:HOLD_LIFE | RES_FIRE | RES_NETHER | SEE_INVIS | ACTIVATE | SHOW_MODS a:HARDCORE=DETECT_XTRA D:A staff tall and sturdy, with rough-hewn runes that invoke the element of D:Earth, and which strikes down all creatures who live in the shadow of D:mountains. # The Mace of Disruption 'Deathwreaker' N:121:'Deathwreaker' I:21:20:6 W:80:38:400:444444 P:0:7d8:18:18:0 F:STR | TUNNEL | HIDE_TYPE | NO_TELE | DRAIN_MANA | F:SLAY_DRAGON | SLAY_ANIMAL | SLAY_EVIL | KILL_UNDEAD | BRAND_FIRE | F:IM_FIRE | RES_DARK | RES_CHAOS | RES_DISEN | AGGRAVATE | F:SHOW_MODS | BRAND_POIS | VAMPIRIC F:MUST2H f:MUST2H D:A weapon so massive it seems beyond the strength of mortals, yet you feel D:the might of giants within you as you heft it. As you grip the handle D:of ebony and steel, coronas of fire blaze and mighty spells to preserve D:magic activate around you. You wield the Fear of Dragons and the Despair D:of the Undead! # The Lucerne Hammer 'Turmil' N:122:'Turmil' I:21:10:4 W:20:15:120:30000 P:0:2d5:10:6:8 F:WIS | INFRA | HIDE_TYPE | F:BRAND_COLD | SLAY_ORC | RES_COLD | RES_LITE | REGEN | F:ACTIVATE | SHOW_MODS | ESP_ORC | ESP_TROLL | ESP_GIANT F:COULD2H f:COULD2H a:HARDCORE=TURMIL D:Wielded by the High Priest of Meneltarma, this great mace gleams coldly as D:though moonlit, and it can strike as mighty a blow spiritually as D:physically. # The Whip of Gothmog N:123:of Gothmog I:21:2:-2 W:20:15:120:100000 P:0:3d6:15:16:0 F:INT | DEX | INFRA | HIDE_TYPE | DRAIN_HP | F:HEAVY_CURSE | CURSED | AGGRAVATE | F:BRAND_FIRE | SLAY_ANIMAL | SLAY_DEMON | RES_FIRE | ESP_SPIDER F:VORPAL | RES_LITE | LITE1 | REGEN | ESP_DEMON | WOUNDING F:SHOW_MODS D:With this unbearably bright whip of flame, the Balrog Gothmog has become D:known for never having lost in combat. # The Long Bow 'Belthronding' N:124:'Belthronding' I:19:13:3 W:40:20:40:35000 P:0:0d0:20:22:0 F:DEX | STEALTH | HIDE_TYPE | F:RES_DISEN | XTRA_SHOTS | SHOW_MODS D:The great bow of Beleg, made of black yew and strung with elven hair that D:faintly shines a pale clear gold. # The Long Bow of Bard N:125:of Bard I:19:13:2 W:30:20:40:20000 P:0:0d0:17:19:0 F:DEX | HIDE_TYPE | ESP_DRAGON | LUCK F:FREE_ACT | XTRA_MIGHT | SHOW_MODS D:The great yew bow of grim-faced Bard, who shot the mightiest arrow that D:songs record. # The Light Crossbow 'Cubragol' N:126:'Cubragol' I:19:23:10 W:50:25:110:50000 P:0:0d0:10:14:0 F:SPEED | HIDE_TYPE | F:RES_FIRE | ACTIVATE | SHOW_MODS a:HARDCORE=CUBRAGOL D:A crossbow that grants fiery speed to he who finds it, and from which D:shoot bolts that blaze with flame unquenchable. # The Mage Staff of Eternity # Really powerful for a mage but extremely rare # The ULTIMATE "weapon" for a Sorceror or a magic class N:127:of Eternity I:6:1:12 W:127:220:20:9000000 P:0:1d4:-19:-19:0 F:INT | CHR | WIS | MANA | SPELL | ACTIVATE | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | LUCK | SPECIAL_GENE F:SEE_INVIS | ESP_EVIL | ESP_DEMON | NEVER_BLOW | INFRA F:PRECOGNITION | IM_FIRE | ULTIMATE | SPELL_CONTAIN | WIELD_CAST F:COULD2H f:COULD2H a:HARDCORE=GANDALF D:A simple, wooden wizard's staff. Unremarkable in all aspects... D:except that it pulses with overwhelming power. # Boomerang Artifacts # The Metal Boomerang of Beor N:128:of Beor I:15:4:4 W:20:10:20:40000 P:0:4d5:8:12:0 F:DEX | SPEED | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD D:Beor's boomerang makes its wielder as agile as the winds, D:and as hard to harm. # The Metal Boomerang 'Glimdrir' N:129:'Glimdrir' I:15:4:3 W:40:20:20:60000 P:0:5d5:15:16:0 F:DEX | SPEED | FREE_ACT | BRAND_POIS | SLAY_EVIL | SLAY_UNDEAD | REGEN F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_SOUND | NO_TELE | CURSED D:A powerful boomerang that makes one agile and fast, with a thirst for D:evil and undead creatures, but demands its wielder not teleport, for fear D:of desertion. # The Robe of Incanus [aka Gandalf] N:130:of Incanus I:36:2:3 W:30:20:20:60000 P:2:0d0:0:0:20 F:INT | WIS | SEARCH | HIDE_TYPE | SPELL_CONTAIN | WIELD_CAST F:SUST_INT | SUST_WIS | FREE_ACT | SEE_INVIS | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | Z:weigh magic D:Gandalf's long, flowing robe. It provides insight and allows the D:wearer to see things not seen by all. # The Sling of the Thain N:131:of the Thain I:19:2:4 W:40:20:40:35000 P:0:0d0:15:15:0 F:HIDE_TYPE | DEX | CON F:RES_NETHER | XTRA_SHOTS | XTRA_MIGHT | SHOW_MODS D:This sling was crafted by Faramir I, Thain of the Shire, just in case D:the nasties of his father's stories ever dare to enter the Shire again. # The Whip 'Lasher' N:134:'Lasher' I:21:2:3 W:20:5:30:50000 P:0:1d6:12:15:0 F:DEX | BLOWS | HIDE_TYPE | F:SLAY_ANIMAL | SLAY_ORC | BRAND_POIS | VORPAL | F:RES_POIS | FREE_ACT | ESP_ORC D:A powerful whip that is deadly against orcs. It poisons your foes D:and is said to go "snicker snack". # The Seeker Arrow 'Bullseye' N:135:'Bullseye' I:17:2:0 W:45:1:2:50000 P:0:7d4:20:15:0 F:SLAY_ANIMAL | SLAY_EVIL | SLAY_UNDEAD | KILL_DEMON | F:SLAY_ORC | SLAY_TROLL | SLAY_GIANT | SLAY_DRAGON | F:BRAND_ACID | BRAND_ELEC | BRAND_FIRE | BRAND_COLD | BRAND_POIS D:A powerful arrow that is feared by even the mightiest demons. # The Rounded Pebble 'Travak' N:136:'Travak' I:16:0:0 W:5:1:2:5000 P:0:3d6:8:5:0 F:BRAND_ACID | BRAND_ELEC | BRAND_FIRE | BRAND_COLD | BRAND_POIS D:A rounded pebble imbued with the powers of the elements. # The Harp of Maglor N:137:of Maglor I:14:59:3 W:60:10:20:100000 P:0:3d4:0:0:0 F:CHR | SPEED | WIS | SEE_INVIS | RES_SOUND | STEALTH | LUCK F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | ESP_UNIQUE | WIELD_CAST D:This harp that once belonged to Maglor makes those who use it seem D:more forceful and convincing. It is also said that those who have D:used it found themselves walking faster, as if to an unheard beat. # The Drum of the Sky N:138:of the Sky I:14:58:2 W:40:10:15:80000 P:0:3d4:0:0:0 F:CHR | SPEED | WIS | SEE_INVIS | RES_SOUND | STEALTH | LUCK F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | WIELD_CAST D:The drum is decorated with the images of the stars, the clouds, the D:Sun guided by Arien and the Moon with Tilion. It imparts to the D:wearer an echo of the beauty of the sky, and protects him from the D:elements day or night. The beat of the drum marks the passage of D:time, and will make time pass differently for the wearer. # The Harp of Daeron N:139:of Daeron I:14:59:1 W:20:10:10:50000 P:0:3d4:0:0:0 F:CHR | SPEED | WIS | RES_SOUND | STEALTH | LUCK F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | WIELD_CAST D:A pretty harp that makes those who play it beautiful, wise and D:fast. # The Dwarven Pick of Erebor N:140:of Erebor I:20:6:5 W:50:15:200:55000 P:0:3d4:0:0:0 F:STR | TUNNEL | SUST_STR | HIDE_TYPE | LITE1 | ACTIVATE | CLIMB F:RES_CHAOS | RES_LITE | RES_DARK a:HARDCORE=EREBOR D:A pick that provides a magical light by which to see while tunnelling. # The Drum of the Druedain N:141:of the Druedain I:14:58:4 W:19:10:15:10000 P:0:3d4:0:0:0 F:ACTIVATE | STEALTH | SEARCH | INFRA | RES_POIS | RES_DARK | WIELD_CAST a:HARDCORE=DRUEDAIN D:The fabled Drum of the Druedain that will protect those who play it D:from darkness and poison attacks. It also aids in the seeing of D:warm-blooded creatures. # The Horn of Rohan N:142:of Rohan I:14:60:2 W:14:10:15:80000 P:0:3d4:0:0:0 F:ACTIVATE | CHR | WIS | ESP_DRAGON | WIELD_CAST a:HARDCORE=ROHAN D:A horn carved from the bones of the Dragon of Ered-Mithrin, this D:heirloom of the House of Eorl bestows to its user the gifts of D:courage and command. # The Horn of Helm N:143:of Helm I:14:60:2 W:16:10:15:15000 P:0:3d4:0:0:0 F:ACTIVATE | STR | CON | IM_COLD | RES_NETHER | RES_FEAR | WIELD_CAST a:HARDCORE=HELM D:Heedless of cold, fearless of darkness -- besiegers fled at the wind D:of the solitary coming of King Helm Hammerhand, proclaimed by a single D:horn-blast in the dead of winter. # The Horn of Boromir N:144:of Boromir I:14:60:3 W:18:10:15:18000 P:0:3d4:0:0:0 F:ACTIVATE | STR | CON | RES_FEAR | RES_FIRE | AGGRAVATE | WIELD_CAST a:HARDCORE=BOROMIR D:Boromir's horn gives courage and endurance to the wearer, provided he does D:not wish to travel in secrecy: for it must always sound when its wielder D:sets forth on a journey. "Loud and clear it sounds in the valleys of the D:hills... and then let all the foes of Gondor flee!" # The Lochaber Axe of Gothmog, which slew Fingon N:145:of Gothmog I:22:28:-4 W:30:8:250:30000 P:0:3d8:14:19:0 F:BRAND_FIRE | IM_FIRE | CHR | ACTIVATE | SHOW_MODS | CURSED | TY_CURSE a:HARDCORE=AXE_GOTHMOG D:The black axe of Gothmog, which struck Fingon at Nirnaeth. Mighty D:spells of evil make it unsafe in any hands but those of its original wielder. # The Seeker Arrow of Gondor N:146:of Gondor I:17:2:0 W:20:5:3:25000 P:0:10d8:10:20:0 F:SLAY_EVIL | SLAY_DEMON D:An arrow that was created to rid the world of demons. # The Long Sword of Eternity # The ULTIMATE weapon for a warrior class N:147:of Eternity I:23:17:10 W:127:220:130:9000000 P:0:5d6:21:26:50 F:LIFE | CON | CHR | LUCK F:SUST_STR | SUST_INT | SUST_WIS | SUST_DEX | SUST_CON | SUST_CHR | F:BRAND_FIRE | BRAND_COLD | BRAND_ELEC | VORPAL | IM_COLD | F:SLAY_EVIL | SLAY_UNDEAD | SLAY_DEMON | SLAY_TROLL | SLAY_DEMON | F:FREE_ACT | RES_FIRE | RES_DARK | LITE1 | SEE_INVIS | SLOW_DIGEST | REGEN | F:ACTIVATE | SHOW_MODS | BLESSED | F:PRECOGNITION | NO_MAGIC | ULTIMATE | SPECIAL_GENE a:HARDCORE=ERU D:A warm light bathes this translucent blade. The power of the fates are D:at the command of its wielder as the weapon passes Supreme Judgment on D:the inhabitants of Angband. # The Robe of Great Luck N:148:of Great Luck I:36:2:60 W:50:120:20:60000 P:-30:0d0:0:0:-20 F:LUCK | HIDE_TYPE | F:FREE_ACT | DRAIN_HP | DRAIN_MANA D:A powerful wizard once created this robe to grant him incredible luck.... D:It seems he forgot to wear it. # The Sling of Farmer Maggot N:149:of Farmer Maggot I:19:2:2 W:10:10:5:20000 P:0:0d0:20:0:0 F:INFRA | SEARCH | HIDE_TYPE | F:XTRA_SHOTS | SHOW_MODS | ACTIVATE | SPECIAL_GENE a:SPELL=Artifact Maggot D:This ordinary seeming leather sling has been raised to legendary D:status amongst generations of hobbit children. Farmer Maggot's D:ability to notice and strike any mushroom thief anywhere within D:his patch almost keeps young poachers at bay, but once they get D:within range they soon flee for less painful pastures, frequently D:with rounded pebbles stinging their backsides... # The Long Sword of Angmar (a.k.a. anti-Ringil) # The next time someone wields an unidentified Long Sword (4d5) ... N:150:of Angmar I:23:17:-10 W:20:40:130:30000 P:0:4d5:-22:-25:0 F:SPEED | STR | WIS | CHR | ESP_UNDEAD F:BRAND_FIRE | SEE_INVIS | SLOW_DIGEST | FREE_ACT | F:VAMPIRIC | NO_TELE | AGGRAVATE | WRAITH | INVIS | F:CURSED | HEAVY_CURSE | DG_CURSE | SHOW_MODS | CLONE | D:Dark flames wreath the naked steel of the Witch-King of Angmar. D:A mighty curse to all those who wield it apart from its master, D:the torture of the wraithworld awaits those who dare. # The Seeker Bolt of Feanor N:151:of Feanor I:18:2:0 W:127:220:130:100000 P:0:5d5:5:6:0 F:BRAND_COLD | BRAND_FIRE | BRAND_ELEC | BRAND_ACID | BRAND_POIS | F:SLAY_DRAGON | SLAY_GIANT | SLAY_TROLL | KILL_UNDEAD | SLAY_ORC | F:SLAY_DEMON | SLAY_EVIL | SPECIAL_GENE D:Made during the war against Morgoth by Feanor, this powerful D:bolt is the bane of Morgoth's power, and has especial strength D:against those foes who are already dead. # The Heavy Crossbow of Eternity # The ULTIMATE bow for an archer class N:152:of Eternity I:19:24:5 W:127:220:130:8000000 P:0:0d0:36:28:0 F:SEE_INVIS | SLOW_DIGEST | FREE_ACT | SPEED | DEX | CON | FLY | LUCK F:XTRA_MIGHT | XTRA_SHOTS | IM_ELEC | REFLECT | INVIS | STEALTH | F:SUST_STR | SUST_INT | SUST_WIS | SUST_DEX | SUST_CON | SUST_CHR | F:RES_CHAOS | RES_DISEN | RES_CONF | RES_BLIND | INFRA | ESP_ORC | ESP_TROLL | ESP_EVIL | F:PRECOGNITION | NO_MAGIC | ULTIMATE | SPECIAL_GENE D:Designed to be used with the Seeker Bolt of Feanor, this Crossbow D:is perfect against the terrible powers of Morgoth. # The Soft Leather Armour of the Sandworm N:153:of the Sandworm I:36:4:5 W:30:3:80:65000 P:30:0d0:0:0:0 F:RES_POIS | RES_ELEC | RES_FIRE | RES_ACID | SPECIAL_GENE F:TUNNEL | STR | STEALTH | INFRA | ESP_ANIMAL D:This powerful piece of armour was made using the remains of D:the Sandworm Queen. # The Lochaber Axe 'Dragonbane' N:154:'Dragonbane' I:22:28:2 W:70:20:260:33000 P:0:3d8:20:20:0 F:BLOWS | KILL_DRAGON | RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | F:RES_POIS | SHOW_MODS D:Forged by the Dwarves to defend their home of Khazad-dum from dragons, D:this axe has been lost to time... until now. # The Light War Axe 'Limbslicer' N:155:'Limbslicer' I:24:8:4 W:15:3:140:12000 P:0:2d5:12:15:0 F:DEX | VORPAL | HIDE_TYPE | SHOW_MODS | WOUNDING D:The Petty-dwarves of Bathak forged this blade, and it shares their thirst D:for blood. # The Broad Axe 'Orchast' N:156:'Orchast' I:24:11:4 W:15:2:170:12000 P:0:2d7:20:14:0 F:DEX | SEARCH | SLAY_ORC | ACTIVATE | HIDE_TYPE | SHOW_MODS F:COULD2H f:COULD2H a:HARDCORE=ORCHAST D:Forged by the dwarves of Khazad-dum in a time of desperation, D:this axe turned many a battle against the invading orcs. # The Hatchet of the Night N:157:of the Night I:24:1:4 W:45:20:45:34000 P:0:2d6:34:22:0 F:DEX | STEALTH | VAMPIRIC | KILL_UNDEAD | RES_DARK | HIDE_TYPE | F:SHOW_MODS | SEE_INVIS | ACTIVATE | DRAIN_EXP a:HARDCORE=NIGHT D:Found on an unmarked grave after a violent storm, this hatchet D:has a sinister aura of darkness and decay. # The Slaughter Axe 'Naturebane' N:158:'Naturebane' I:24:30:3 W:70:20:300:28400 P:0:5d7:31:27:0 F:STR | SLAY_ANIMAL | SUST_STR | RES_SHARDS | RES_NEXUS | FEATHER | F:HIDE_TYPE | SHOW_MODS | ACTIVATE | DRAIN_HP a:HARDCORE=NATUREBANE D:Used by the orcs in their battle at Dagor Bragollach against the elves, this D:axe has a bloodthirst for nature. # The Light War Axe of Ice N:159:of Ice I:24:8:3 W:30:25:140:26550 P:0:2d5:3:15:0 F:INT | CHR | SUST_DEX | BRAND_COLD | IM_COLD | RES_NEXUS | HIDE_TYPE | F:SHOW_MODS D:Crafted of purest ice and held solid by powerful spells, this icy axe D:delivers a chill of death to its victims. # The Iron Helm of Knowledge N:160:of Knowledge I:32:5:-6 W:20:5:75:100000 P:6:1d3:0:0:20 F:LITE1 | HIDE_TYPE | SPECIAL_GENE | LUCK F:AUTO_ID | ACTIVATE a:HARDCORE=KNOWLEDGE D:This helm, designed by Petty-Dwarves ages ago to act as the brain of a D:long lost project, is made of finest glass. Its light banishes all secrets, D:and makes audible whispers from the deceased. ### Trapping Kits ### ### note prices and rarities may have to be adjusted ### # The Catapult Trap Set of Ahromarwar N:161:of Ahromarwar I:46:1:3 W:20:10:40:20000 P:0:0d0:25:15:30 F:STEALTH | AUTOMATIC_99 | XTRA_MIGHT | HIDE_TYPE D:A trap that can almost never be detected. Its missiles may be mere pebbles, D:but fired at an incredibly high velocity to penetrate even the toughest D:hide or armour. # The Device Trap Set 'Hanisbroner's Surprise' N:162:'Hanisbroner's Surprise' I:46:6:3 W:20:20:40:20000 P:0:0d0:0:0:25 F:STEALTH | XTRA_SHOTS | TELEPORT_TO | HIDE_TYPE | AUTOMATIC_99 D:A magical trap, armed with a wand. Unaccountably, its victims keep D:on coming back for more... # The Bolt Trap Set 'Merlion Karc's Demonbane' N:163:'Merlion Karc's Demonbane' I:46:3:2 W:20:20:200:20000 P:0:0d0:17:27:37 F:STEALTH | XTRA_SHOTS | XTRA_MIGHT | HIDE_TYPE | ONLY_DEMON D:A snare set not for animals, or people, but for demons alone, and D:enchanted so that whenever the demon sets foot or claw into the D:(hidden) pentagram, its hide is immediately pierced by many magical D:crossbow bolts. # The Broken Sword 'Narsil' N:164:'Narsil' I:23:2:2 W:20:5:30:2000 P:0:3d2:6:10:0 F:STR | DEX | HIDE_TYPE | BLESSED | F:SLAY_ORC | SLAY_TROLL | RES_FIRE D:The sword that was broken shall be reforged... # The Steel Helm 'Lebohaum' # The name comes from a french parody of dungeon dwelling in mp3 # http://penofchaos.com/warham.htm N:165:'Lebohaum' I:32:6:0 W:20:15:15:25000 P:20:0d0:0:0:80 F:ACTIVATE a:SPELL=Artifact Lebauhaum D:With the Helm 'Lebohaum' your head is safe! # The Power Dragon Scale Mail 'Mediator' N:166:'Mediator' I:38:30:0 W:95:12:500:400000 P:50:2d4:-8:0:35 F:FEATHER | FLY | ESP_DRAGON | F:RES_NEXUS | RES_CHAOS | AGGRAVATE | REGEN | F:RES_SHARDS | RES_SOUND | RES_DISEN | RES_CONF | F:IGNORE_ACID | IGNORE_ELEC | IGNORE_FIRE | IGNORE_COLD | F:ACTIVATE a:HARDCORE=MEDIATOR D:A mighty suit of dragon armour, set with the scales of dragons of both D:Law and Chaos, and with power over both. # The Hard Leather Armour of Himring N:167:of Himring I:36:6:0 W:50:20:100:35000 P:6:0d0:0:0:15 F:RES_CHAOS | RES_NETHER | RES_POIS | ACTIVATE a:HARDCORE=PROT_EVIL D:Contained within this studded cuirass of pliable leather is the memory of D:unvanquished Himring, defiant fortress surrounded by the legions of Morgoth. # The Soft Leather Armour 'Hithlomir' N:168:'Hithlomir' I:36:4:4 W:20:3:80:45000 P:4:0d0:0:0:20 F:STEALTH | HIDE_TYPE | SEARCH | F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_DARK D:Familiar with the secret ways hidden in darkness, this leather cuirass is D:truly more than it appears. # The Shield of Deflection of Gil-galad # Description from Sangband N:169:of Gil-galad I:34:10:5 W:70:4:80:65000 P:10:1d3:0:0:20 F:ACTIVATE | F:LITE1 | WIS | CHR | SEARCH | LUCK F:RES_ELEC | RES_ACID | RES_DISEN | RES_DARK | HIDE_TYPE | F:SUST_WIS | SUST_DEX | SUST_CHR a:HARDCORE=GILGALAD D:The legendary shield of Gil-Galad, who fought his way to the gates of D:the Dark Tower, and with whom came light even to Gorgoroth. # The Metal Cap of Celebrimbor N:170:of Celebrimbor I:32:3:3 W:55:12:20:45000 P:3:1d1:0:0:18 F:INT | DEX | CHR | SPELL | SEARCH | F:RES_FIRE | RES_ACID | RES_DISEN | RES_SHARDS | F:ACTIVATE a:HARDCORE=CELEBRIMBOR D:This once belonged to Celebrimbor, maker of the Rings of Power. One who D:knows both fire and acid, from the business of forging and engraving, will D:fear neither: nor have his enchantments ever faded. Celebrimbor was even D:aware of Sauron before Sauron became aware of him, when Sauron put on the D:One Ring for the first time. # The Heavy Crossbow of Umbar N:171:of Umbar I:19:24:2 W:60:20:200:35000 P:0:4d1:18:18:0 F:STR | CON | XTRA_MIGHT | AGGRAVATE | F:RES_LITE | RES_DARK | RES_BLIND | RES_ELEC | F:HIDE_TYPE | ACTIVATE | SHOW_MODS a:HARDCORE=UMBAR D:A great brazen arbalest with arms of gleaming steel, shooting quarrels with D:speed and power for those brave enough to risk betrayal. # The Short Bows of Amrod and Amras, Feanor's twin sons # The Short Bow of Amrod N:172:of Amrod I:19:12:2 W:25:10:30:9000 P:0:0d0:12:15:0 F:STR | CON | XTRA_MIGHT | F:RES_FIRE | RES_ELEC | RES_COLD | REGEN D:This bow, and its twin, belonged to Feanor's last two twin sons, Amrod D:and Amras, who both hunted with the Green-elves for a time. Like the D:twins, the bows are similar, for both protect their wielders from the D:elements: and yet they are also unlike, for this bow gives endurance D:and strength, while the other gives quickness and subtlety. # The Short Bow of Amras N:173:of Amras I:19:12:1 W:25:10:30:9000 P:0:0d0:12:15:0 F:INT | WIS | DEX | XTRA_SHOTS | XTRA_MIGHT | SPEED | F:RES_FIRE | RES_ELEC | RES_COLD | SLOW_DIGEST D:This bow, and its twin, belonged to Feanor's last two twin sons, Amrod D:and Amras, who both hunted with the Green-elves for a time. Like the D:twins, the bows are similar, for both protect their wielders from the D:elements: and yet they are also unlike, for this bow gives quickness D:and subtlety, while the other gives endurance and strength. # The Mattock of Nain N:174:of Nain I:20:7:6 W:60:5:250:30000 P:0:3d8:12:18:0 F:TUNNEL | INFRA | SEARCH | STR | ESP_ORC | CLIMB | F:SLAY_ORC | SLAY_TROLL | SLAY_GIANT | SLAY_DRAGON | F:BRAND_ACID | RES_ACID | RES_DARK | RES_DISEN | F:ACTIVATE a:HARDCORE=STONE_MUD D:Wielded by Nain of the Iron Hills at the Battle of Azanulbizar, this great D:mattock brought victory to the Dwarves over Azog's Orcs - though Nain D:himself fell at the last, even with victory already assured. # The Ball-and-Chain of Fundin Bluecloak N:175:of Fundin Bluecloak I:21:6:4 W:25:100:130:60000 P:0:5d4:13:17:10 F:STR | WIS | SPEED | LITE1 | HIDE_TYPE | F:SLAY_EVIL | SLAY_UNDEAD | F:RES_FIRE | RES_ELEC | RES_NETHER | RES_DISEN | HOLD_LIFE | F:ACTIVATE F:COULD2H f:COULD2H a:HARDCORE=FUNDIN D:The weapon of one of the great dwarven priests, with powers D:to preserve body, soul and enchantments, and the bane of those D:who seek life beyond death. # The Large Leather Shield of the Haradrim N:176:of the Haradrim I:34:4:2 W:35:12:120:25000 P:4:1d2:0:0:15 F:ACTIVATE | F:STR | CON | SUST_STR | SUST_CON | HIDE_TYPE | F:RES_FEAR | RES_BLIND | RES_POIS | AGGRAVATE a:HARDCORE=HARADRIM D:A great shield from the far lands of the South, whose wielder D:will go charging into battle heedless of danger, with the D:strength and endurance of a madman. Nor will he fear poison, for D:the Southron barbarians handle poisoned darts naturally. # The Lead-Filled Mace 'Skullcleaver' N:177:'Skullcleaver' I:21:15:5 W:30:15:500:60000 P:0:5d4:11:23:20 F:STR | TUNNEL | INFRA | HIDE_TYPE | F:CURSED | AGGRAVATE | NO_MAGIC | F:RES_NEXUS | RES_BLIND | RES_SOUND | F:KILL_DRAGON | SLAY_ANIMAL | BRAND_POIS | BRAND_ELEC | F:ACTIVATE F:COULD2H f:COULD2H a:HARDCORE=SKULLCLEAVER D:This mighty bludgeon brings destruction to all around it, and is the D:bane of dragons and magic. # The Set of Gauntlets of Eol N:178:of Eol I:31:2:3 W:55:35:25:40000 P:3:1d1:0:0:15 F:INT | MANA | FREE_ACT | FEATHER | RES_ELEC | RES_DARK | RES_POIS | ACTIVATE F:LUCK | SPELL_CONTAIN | WIELD_CAST a:HARDCORE=EOL D:The iron-shod gauntlets of the Dark Elven smith Eol, tingling with magics D:that he could channel in battle. # The Pair of Hard Leather Boots of Nevrast N:179:of Nevrast I:30:3:3 W:20:8:40:35000 P:3:1d1:0:0:13 F:STEALTH | CON | SPEED | HIDE_TYPE D:Footgear made of bear leather and set with opals, which grant the wearer D:silent, hasted movement. # The Pair of Metal Shod Boots of Gimli N:180:of Gimli I:30:6:4 W:40:8:60:22500 P:4:1d1:5:5:10 F:INFRA | SEARCH | TUNNEL | CLIMB | HIDE_TYPE Z:magic map D:A set of iron-shod boots stamped by Gimli's combat prowess, a peerless D:ally to those journeying through halls of stone under mountains. # The demon garbs of Gothmog # The Demonblade of Gothmog N:181:of Gothmog I:115:55:-20 W:10:0:150:500 P:0:7d6:13:13:0 F:SHOW_MODS | SLAY_DEMON | SLAY_EVIL | BRAND_FIRE | BRAND_POIS F:LUCK | CHAOTIC | LITE1 | WOUNDING | RES_MORGUL | WIELD_CAST F:HEAVY_CURSE | AUTO_CURSE # The Demonshield of Gothmog N:182:of Gothmog I:115:56:4 W:15:0:70:500 P:13:1d1:0:0:13 F:DEX | INVIS | SUST_STR | SUST_CON | SUST_DEX F:FEATHER | SH_FIRE | FREE_ACT | HOLD_LIFE F:HEAVY_CURSE | AUTO_CURSE | WIELD_CAST # The Demonhorn of Gothmog N:183:of Gothmog I:115:57:-5 W:20:0:30:500 P:2:1d1:0:0:13 F:LITE2 | REGEN | ESP_DEMON F:CHR | SLOW_DIGEST | SEE_INVIS F:HEAVY_CURSE | AUTO_CURSE | WIELD_CAST # The Long Sword 'Durandil' # The name comes from a french parody of dungeon dwelling in mp3 # http://penofchaos.com/warham.htm N:184:'Durandil' I:23:17:3 W:5:10:130:500 P:0:2d5:5:6:0 F:RES_FEAR | LUCK F:ACTIVATE | SHOW_MODS a:SPELL=Artifact Durandil D:Don't go adventuring without your Durandil sword! # The Phial of Undeath N:200:of Undeath I:39:103:-5 W:20:10:10:0 P:0:1d1:0:0:0 F:CURSED | INT | WIS | CON | DEX | CHR | STR | ACTIVATE | F:LITE3 | LITE2 | LUCK | MAGIC_BREATH F:INSTA_ART | DG_CURSE | ESP_UNDEAD | a:HARDCORE=UNDEATH D:It appears like the Phial of Galadriel at first - but wait! It D:is a cursed phial created by an evil wizard to lure adventurers D:into wielding it unknowingly. # The template for artifacts corpses N:201: I:9:1:0 W:200:1:10:0 P:0:1d1:0:0:0 F:INSTA_ART | SPECIAL_GENE # The Palantir of Orthanc N:202:of Orthanc I:39:104:2 W:75:60:200:100000 P:0:10d10:0:0:0 F:WIS | INT | SEARCH | INFRA | HIDE_TYPE | ACTIVATE | ESP_ALL | F:SEE_INVIS | RES_BLIND | AGGRAVATE | DRAIN_MANA | LITE2 F:INSTA_ART a:HARDCORE=PALANTIR D:A shining white ball of unbreakable crystal, the ancient Palantiri D:were used by kings of Numenor and later by the Exiles for rapid D:communication between distant lands. Nothing is hidden from one who D:gazes into a Palantir, but the observed will also be aware of the D:observer, as was Sauron when Saruman tried to spy on him with this D:particular Palantir. # The Ring of Phasing N:203:of Phasing I:45:55:15 W:110:0:2:3000000 P:0:1d1:0:0:0 F:SPEED | SEE_INVIS | LUCK | MAGIC_BREATH F:CURSED | HEAVY_CURSE | REGEN F:WRAITH | IM_NETHER | DRAIN_EXP | HOLD_LIFE | SPECIAL_GENE | F:INSTA_ART Z:teleport D:Imbued with the screams of the victims of undead everywhere, this D:ring is more a hole in reality than anything else. Strange forces ripple over D:its surface, giving you visions of a reality considerably less solid than this D:one. You feel your senses reel, and must make a conscious effort not to throw D:this ring as far from you as possible. # The Blue Stone 'Toris Mejistos' N:204:'Toris Mejistos' I:40:18:2 W:50:10:3:60000 Z:restore life F:INT | WIS | HIDE_TYPE | MANA | LUCK F:SUST_INT | SUST_WIS | LITE1 | REGEN F:SLOW_DIGEST | AUTO_CURSE | HEAVY_CURSE F:ESP_GOOD | ESP_EVIL | HOLD_LIFE F:INSTA_ART | SPECIAL_GENE | WATER_BREATH F:SPELL_CONTAIN | WIELD_CAST D:A blue stone, with an incredible number of incredibly small runes of power D:on it. It carries many secrets. # The Ring of Durin - last of the Seven Rings of the Dwarf-lords N:205:of Durin I:45:57:2 W:70:70:2:65000 F:CON | CHR | STR | SUST_CHR | SUST_CON | SUST_STR | HIDE_TYPE | F:ESP_EVIL | AGGRAVATE | HEAVY_CURSE | HOLD_LIFE | DRAIN_EXP | F:RES_DARK | RES_CHAOS | RES_NETHER | RES_COLD | RES_ACID | F:INSTA_ART | SPECIAL_GENE | CURSED Z:Midas touch D:The greatest of the Seven Rings of the Dwarf-lords, and the last to be D:lost. Alone among the Seven, it was not taken by Sauron when he made D:war on the Elves, but was given as a gift from Celebrimbor to King Durin D:III of Moria in token of friendship: nevertheless, Sauron in disguise D:had a hand in its making, and so it is cursed, and draws evil towards it. # The Elfstone 'Elessar' N:206:'Elessar' I:40:19:4 W:60:60:3:40000 P:0:0d0:7:7:10 F:STR | WIS | CHR | SPEED | LITE3 | INSTA_ART | F:RES_FEAR | RES_FIRE | RES_POIS | RES_DISEN | HIDE_TYPE | F:ACTIVATE a:HARDCORE=ELESSAR D:This green gem glows with inner light. Aragorn son of Arathorn wore D:it at the Battle of the Pelennor Fields, and he was himself given the D:name of 'Elessar' by the people of Gondor because of this. # The Jewel 'Evenstar' N:207:'Evenstar' I:40:20:3 W:50:50:3:35000 F:HOLD_LIFE | SUST_CON | SUST_WIS | SUST_INT | LITE1 | CON | F:RES_DARK | RES_COLD | RES_NETHER | REGEN | INSTA_ART | F:ACTIVATE a:HARDCORE=REST_ALL D:A pure white jewel, the last gift of Queen Arwen Undomiel to Frodo D:Baggins, intended to be worn around his neck on the chain that had D:once borne the One Ring. # The Palantir of Minas Ithil (be warned - it's *cursed*!) N:208:of Minas Ithil I:39:107:-3 W:75:60:200:0 P:0:10d10:0:0:-30 F:LIFE | CON | INT | WIS | ESP_ALL | LITE3 | LITE1 F:CURSED | HEAVY_CURSE | TY_CURSE | DRAIN_EXP | F:RES_BLIND | SEE_INVIS | ACTIVATE a:HARDCORE=PALANTIR D:A shining white ball of unbreakable crystal, the ancient Palantiri D:were used by kings of Numenor and later by the Exiles for rapid D:communication between distant lands. This Palantir, however, was D:taken by Sauron long ago, and mastered to his evil uses, to the D:destruction of all others who would gaze into it. # some artifact bolts # The Silver Bolt 'Balefire' N:209:'Balefire' I:18:3:0 W:55:30:2:50000 P:0:6d5:20:15:0 F:ESP_DEMON | ESP_UNDEAD | LITE1 | F:BRAND_FIRE | KILL_DEMON | KILL_UNDEAD | D:This silver-tipped bolt, ablaze with undying celestial fire, D:is especially potent against undead and creatures of the D:netherworld; it even points the way to places where such D:enemies lurk. # The Silver Bolt 'Stone-biter' N:210:'Stone-biter' I:18:3:3 W:55:30:2:50000 P:0:6d5:20:15:0 F:ESP_ORC | ESP_TROLL | F:INFRA | SEARCH | TUNNEL | LUCK F:BRAND_ACID | SLAY_ORC | SLAY_TROLL | D:Wherever it strikes, this silver-tipped bolt eats through rock D:and metal as easily as through flesh. The dwarf-smith who D:crafted Stone-biter also inscribed the shaft with powerful D:doom-spells against the orcs and trolls who had destroyed his D:ancestral home. # The Seeker Bolt 'Heart's Blood' N:211:'Heart's Blood' I:18:2:5 W:85:40:3:35000 P:0:8d5:15:20:0 F:VORPAL | WOUNDING | CRIT | D:The barbed head of this bolt glows deep red with terrible runes D:of destruction; legend has it that Heart's Blood cannot hit its D:mark without causing a mortal wound. # The Seeker Bolt 'Scale-piercer' N:212:'Scale-piercer' I:18:2:0 W:85:40:3:35000 P:0:8d5:15:20:0 F:ESP_DRAGON | RES_FEAR | F:KILL_DRAGON | D:This bolt, crafted from the bones of a Great Wyrm, is less famous D:and less powerful than Bard's black arrow. Nonetheless it enables D:the owner to find dragons unerringly, face them bravely, and kill D:them swiftly. # Artifacts from ToME 3.0.0 for the new maps of Lord Dimwit # The pval was set to the average of the flag values. # The Mage Staff of Forochel N:213:of Forochel I:6:1:3 W:65:70:60:60000 P:0:3d4:-12:-8:0 F:INT | WIS | MANA | SPELL | INFRA | SEE_INVIS F:SUST_INT | SUST_WIS | RES_BLIND | IM_COLD | SENS_FIRE F:SPECIAL_GENE | WIELD_CAST F:COULD2H f:COULD2H D:A shaft of pure, invincible crystal cut from the heart of one D:of the great glaciers ringing the Ice-Bay of Forochel. D:While you hold it, your mind feels as clear as the winter sky. # The Elven Cloak of Mellyrn N:214:of Mellyrn I:35:2:4 W:40:40:5:65000 P:4:0d0:0:0:20 F:HIDE_TYPE | INVIS | DEX | SPEED | STEALTH | LUCK F:SUST_DEX | RES_LITE | RES_DARK | SPECIAL_GENE D:Bearing the same lyrical name as the great trees of Lothlorien D:and containing in its close-woven folds the speed and skill of D:the Galadrim, this grey cloak is ideal for those who travel in D:forests. # The Bluesteel Blade of Ephel Duath N:215:of Ephel Duath I:23:31:-3 W:60:60:50:30000 P:0:2d6:-20:-18:0 F:STR | WIS | CHR | BRAND_POIS | VAMPIRIC | VORPAL F:INVIS | AGGRAVATE | CURSED | HEAVY_CURSE | SHOW_MODS F:SPECIAL_GENE D:This filthy orc-blade is famed for vile deeds of torture and blood, D:and its wielder will never cease to fear treachery. # The Slaughter Axe 'Garachoth' N:216:'Garachoth' I:24:30:2 W:70:300:400:91000 P:0:7d5:18:18:-20 F:STR | CON | SPEED | LEVELS | BLACK_BREATH F:KILL_DEMON | SLAY_ANIMAL | BRAND_FIRE | VORPAL F:RES_FEAR | RES_FIRE | RES_CHAOS | RES_NETHER F:HIDE_TYPE | SHOW_MODS | SPECIAL_GENE D:A ghastly axe with the soul of a demon lord trapped inside, this horrifying D:creation reverberates with the screams of the damned. As you gaze into its D:glassy, translucent blade, it seems that endless sulphrous wastelands D:stretch away from you into the distance, obscured by sheets of fire. # The Set of Cesti 'Skycleaver' N:217:'Skycleaver' I:31:5:1 W:40:45:40:100000 P:5:1d1:16:7:16 F:STR | CON | DEX | CHR | LUCK | FLY F:RES_ACID | RES_ELEC | RES_FIRE | RES_COLD | RES_POIS F:HIDE_TYPE | SHOW_MODS | SPECIAL_GENE D:The handgear of a legendary dragonslaying hero. The wearer of these D:wyrmskin gauntlets will be versed in all aerial ways, and will fear no D:dragon that walks or flies. # The Pair of Metal Shod Boots of the Machine # Replaced the stealth malus with AGGRAVATE N:218:of the Machine I:30:6:3 W:30:100:170:19000 P:6:1d1:0:0:24 F:INT | SPEED | TUNNEL | AGGRAVATE F:RES_CHAOS | RES_SHARDS | RES_CONF F:ESP_NONLIVING | HIDE_TYPE | SPECIAL_GENE D:A massive pair of adamantine boots studded with gold, the final and D:greatest product of the petty-dwarven magical forge. Despite D:the great powers they contain, they are heavy and awkward enough to D:make quite a racket whenever you move. tome-235-src/lib/edit/wf_info.txt0000644000076400017500000000730011012107760014546 0ustar dgdg# File: wf_info.txt # This file is used to initialize the "lib/raw/wf_info.raw" file, which is # used to initialize the "wilderness feats" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/raw/wf_info.raw" file. # The wilderness feat indexes are defined in "defines.h", and must not be # changed. # N:: # D: # W:::::: # F: # X:... # Note for : # 1 = NORTH # 2 = SOUTH # 4 = EAST # 8 = WEST # Note for : # if < 1000 then it points to a town # if >= 1000 then it points to the x - 1000 dungeon type # Version stamp (required) V:2.0.0 N:0:Ekkaia D:the Encircling Sea W:1:0:0:182:0:X X:182:182:182:182:182:182:182:182:182:182:182:182:182:182:182:182:182:182 N:1:Bree D:a small village W:1:1:0:203:1:1 X:88:88:89:89:89:89:96:96:96:96:96:96:96:96:96:96:96:96 N:2:Gondolin D:The hidden town of the Noldor W:1:2:0:203:1:2 X:88:88:88:89:89:89:89:89:89:89:89:89:89:96:96:96:96:96 N:3:Minas Anor D:The great town of Gondor W:1:3:0:203:1:3 X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:4:Lothlorien D:The land of Galadriel W:1:4:0:203:1:4 X:88:88:96:96:96:96:96:96:96:96:96:96:96:96:96:89:89:89 N:5:grass D:a plain of grass W:5:0:0:89:6:. X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:6:forest D:a forest W:20:0:0:96:7:T X:88:88:96:96:96:96:96:96:96:96:96:96:96:96:96:89:89:89 N:7:road D:a west-east road W:5:0:12:1:6:- X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:8:road D:a north-south road W:5:0:3:1:6:| X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:9:mountain D:a mountain chain W:50:0:0:97:11:& X:1:1:89:89:88:96:96:97:97:97:97:97:97:97:97:97:97:97 N:10:road D:a west-east-south road W:5:0:14:1:6:, X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 # XXX N:12:The Nether Realm D:the entrance to the netherworld W:127:1006:0:7:10:6 X:88:88:88:86:86:86:85:85:85:85:85:85:85:85:85:97:97:97 N:13:deep water D:a deep water area W:70:0:0:187:2:= X:187:187:187:187:187:187:187:187:187:187:187:187:84:84:84:84:84:84 N:14:shallow water D:a shallow water area W:20:0:0:84:3:_ X:187:187:187:84:84:84:84:84:84:84:84:84:84:84:84:1:88:89 N:15:Mirkwood D:The Forest of Mirkwood W:20:1001:0:7:7:* X:88:88:96:96:96:96:96:96:96:96:96:96:96:96:96:89:89:89 N:16:Mordor D:The Gates of Mordor W:50:1002:0:7:11:$ X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:17:Angband D:The Pits of Angband W:50:1003:0:7:11:% X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:18:hill D:a hill W:50:0:0:97:11:^ X:1:1:89:89:88:96:96:97:97:97:97:97:97:97:97:97:97:97 N:19:desert D:a desert W:5:0:0:91:6:D X:1:1:88:88:91:91:91:91:91:91:91:91:91:91:91:98:98:92 N:20:jungle D:a jungle W:20:0:0:96:7:t X:88:88:96:96:96:96:96:96:96:96:96:96:96:96:96:89:89:89 N:21:swamp D:a swamp W:5:0:0:89:6:@ X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:22:glacier D:a glacier W:20:0:0:90:7:g X:94:94:90:90:90:90:90:90:90:90:90:90:90:90:90:90:92:92 N:23:grass D:a plain of grass W:5:0:0:89:6:, X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:24:Moria D:The Doors of Moria W:30:1022:0:7:11:) X:1:1:88:88:89:89:89:89:89:89:89:89:89:89:89:89:96:96 N:25:high mountain D:a high mountain chain W:80:0:0:101:11:M X:101:101:101:101:101:101:101:101:101:101:101:101:101:101:101:101:101:101 N:26:Gondolin D:The pillaged city of the Noldor W:1:2:0:203:1:P X:49:49:49:88:88:88:92:92:92:92:93:93:94:94:94:174:205:205 N:27:Khazad-dum D:The dwarven stronghold W:1:5:0:203:1:5 X:1:1:1:1:1:1:1:1:1:1:88:88:88:88:88:88:88:88 tome-235-src/lib/edit/re_info.txt0000644000076400017500000001202011012107760014533 0ustar dgdg# File: re_info.txt # This file is used to initialize the "lib/raw/re_info.raw" file, which is # used to initialize the "monster ego race" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # Version stamp (required) # Most values can be used with the +, -, % and = operators, = will set the # monster value, + and - will modify it based on the normal monster # % will apply that percentage to the monster value # defaults : NO DEFAULT, MUST precise one # N:x:ego name # G:x:y (x=monster letter, y=colour, use * to use the same as the standard monster) # I:speed:(dice)d(side):aaf:ac:sleep # W:lev:rarity:weight:xp:place('B'efore or 'A'fter) # E:weapon:torso:arms:finger:head:legs # B:method:effect:(dice)d(side) (up to x4 lines) # F:flags that the standard monster MUST have - at least ONE of the R_CHAR_x # flags (if present, to determine which monster letters can have this ego # type), plus ALL of the rest # H:flags that the standard monster MUST NOT have # M:monster flags to add for the ego-type # O:monster flags to remove, use MF_ALL for all # S:monster spells to add for the ego-type # T:monster spells to remove, use MF_ALL for all V:2.0.0 # A few undeads, to be created by the ANIM_DEAD spell N:1:Skeleton G:s:* I:%100:+1d+1:+0:+5:-5 W:+5:13:%30:%95:B F:DROP_SKELETON H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g M:DROP_SKELETON | UNDEAD | IM_COLD | IM_POIS | NO_FEAR | NO_CONF | M:NO_SLEEP | EMPTY_MIND | COLD_BLOOD | STUPID | EVIL O:GOOD | DROP_CORPSE | FRIEND | FRIENDS | ESCORT | ESCORTS | SMART | O:DROP_GREAT | DROP_GOOD | RAND_25 | RAND_50 | MORTAL T:MF_ALL N:2:Zombie G:z:* I:%95:%110d%100:%90:+10:-5 W:+10:14:%70:%100:B F:DROP_CORPSE H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g M:DROP_CORPSE | UNDEAD | IM_COLD | IM_POIS | NO_FEAR | NO_CONF M:NO_SLEEP | EVIL | EMPTY_MIND | COLD_BLOOD | STUPID | EVIL O:GOOD | DROP_SKELETON | FRIEND | FRIENDS | ESCORT | ESCORTS | SMART O:DROP_GREAT | DROP_GOOD | RAND_25 | RAND_50 | MORTAL T:MF_ALL N:3:Lich G:L:* I:%100:+0d+1:+10:+20:-10 W:+30:22:+0:%200:B B:TOUCH:LOSE_DEX:+0d+0 B:TOUCH:LOSE_DEX:+0d+0 B:TOUCH:UN_POWER:+0d+0 B:TOUCH:EXP_40:+0d+0 F:DROP_SKELETON | SMART | R_CHAR_h | R_CHAR_p | R_CHAR_P | R_CHAR_O H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g M:UNDEAD | IM_COLD | IM_POIS | NO_FEAR | NO_CONF M:NO_SLEEP | SMART | EVIL | COLD_BLOOD O:DROP_SKELETON | GOOD | DROP_CORPSE | FRIEND | FRIENDS | ESCORT | ESCORTS | O:DROP_GREAT | RAND_25 | RAND_50 | MORTAL S:1_IN_4 | S:BLINK | TELE_TO | TELE_AWAY | BRAIN_SMASH | DRAIN_MANA | CAUSE_3 | S:BLIND | HOLD | SLOW | SCARE N:4:Spectral G:G:* I:+10:%80d%100:+10:+20:-5 W:+20:20:%10:%110:B B:*:EXP_20:+0d+0 B:*:EXP_20:+0d+0 F:DROP_CORPSE H:UNDEAD | NONLIVING | R_CHAR_Z | R_CHAR_A | R_CHAR_E | R_CHAR_g M:UNDEAD | IM_COLD | IM_POIS | NO_FEAR | NO_CONF M:NO_SLEEP | PASS_WALL | EVIL | COLD_BLOOD O:GOOD | DROP_CORPSE | FRIEND | FRIENDS | ESCORT | ESCORTS | O:DROP_GREAT | EMPTY_MIND | RAND_50 | MORTAL S:1_IN_5 | BLIND | HOLD | SCARE T:MF_ALL N:5:Captain G:*:v I:+5:%150d%100:+5:%120:-2 W:+5:4:%120:%150:A B:*:*:+0d+1 B:*:*:+0d+1 B:*:*:+0d+1 B:*:*:+0d+1 F:R_CHAR_o | R_CHAR_y | R_CHAR_k | BASEANGBAND M:FORCE_MAXHP | FRIENDS | SMART | DROP_1D2 N:6:Chieftain G:*:* I:+10:%200d%100:+10:%120:-3 W:+5:4:%120:%200:A B:*:*:+1d+2 B:*:*:+1d+2 B:*:*:+1d+2 B:*:*:+1d+2 F:R_CHAR_T | R_CHAR_P | R_CHAR_O | BASEANGBAND M:FORCE_MAXHP | FRIENDS | SMART | DROP_1D2 N:7:Shaman G:*:r I:+0:%90d%100:+10:%90:+0 W:+2:1:%90:%120:A F:R_CHAR_o | R_CHAR_k | R_CHAR_n | BASEANGBAND M:SMART | FORCE_MAXHP | DROP_1D2 O:FRIENDS S:1_IN_6 | MISSILE | CAUSE_1 | CONF | BLINK N:8:Priest G:*:G I:+0:%90d%100:+10:%90:+0 W:+3:2:%90:%120:A F:R_CHAR_T | R_CHAR_P | R_CHAR_O | BASEANGBAND M:FRIENDS | SMART | FORCE_MAXHP | DROP_1D2 S:1_IN_6 | CAUSE_2 | MISSILE | DARKNESS | CONF | SCARE | BLINK N:9:Mage G:*:r I:+0:%150d%100:+10:%120:+0 W:+5:4:%120:%150:A B:*:*:+0d+0 B:*:*:+0d+0 B:HIT:HURT:=2d=8 B:HIT:HURT:=2d=8 F:R_CHAR_O | BASEANGBAND M:SMART | FORCE_MAXHP | DROP_1D2 O:FRIENDS S:1_IN_6 | BA_COLD | BO_FIRE | TRAPS | HEAL | HOLD | S_MONSTER | TPORT N:10:Archer G:*:W I:+0:+0d+0:+0:+0:+0 W:+1:1:%100:%110:A F:R_CHAR_y | R_CHAR_k | R_CHAR_O | R_CHAR_o | BASEANGBAND S:1_IN_4 | ARROW_2 N:11:Rogue G:*:b I:+2:+0d+0:+0:+10:-30 W:+1:2:%90:%100:A B:*:EAT_GOLD:+0d+0 F:R_CHAR_y | R_CHAR_k | R_CHAR_o # For townpeople N:12:Elven G:*:* I:+2:+0d+0:+0:+0:+0 W:+0:15:+0:+0:B F:WILD_TOWN H:ANIMAL # For townpeople N:13:Dwarven G:*:* I:+2:+0d+0:+0:+0:+0 W:+0:15:+0:+0:B F:WILD_TOWN H:ANIMAL # N:x:ego name # G:x:y x is the char, y the attribute, * means the normal one # I:speed:(dice)d(side):aaf:ac:sleep # W:lev:rarity:weight:xp:place('B'efore or 'A'fter) # F:flags that the normal monster *must* have # H:flags that the normal monster *must not* have # M:monster flags that the ego-monster adds # O:monster flags to remove (use MF_ALL for all) # S:monster spells that the ego-monster adds # T:monster spells to remove (use MF_ALL for all) tome-235-src/lib/edit/ra_info.txt0000644000076400017500000004244311012107760014543 0ustar dgdg# File: ra_info.txt # This file is used to initialize the "lib/raw/ra_info.raw" file, which is # used to initialize the "randart parts" information for the Angband game. # Do not modify this file unless you know exactly what you are doing, # unless you wish to risk possible system crashes and broken savefiles. # After modifying this file, delete the "lib/raw/ra_info.raw" file. # N:index # X:power value:max number of time it can appear on one object # T:tval:min sval:max sval (up to 20 T: lines) # W:mininum player level to create it:rarity1:rarity2 # C:max to dam:max to hit:max to AC:max to pval # F:flags # Version stamp (required) V:2.0.0 # General info, number of powers G:100:1d5:1 G:14:0d0:1 G:10:0d0:1 G:3:0d0:1 ### Mage Staff randarts ### N:1 X:10:1 T:6:0:255 W:5:1:4 C:-5:-5:0:5 F:MANA N:2 X:14:1 T:6:0:255 W:10:1:8 C:-10:-10:0:5 F:SPELL N:3 X:5:1 T:6:0:255 W:1:1:4 C:-3:-3:0:5 F:INT ### Weapons ### # + To damage N:4 X:5:2 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:19:0:255 T:22:0:255 T:24:0:255 T:115:55:55 W:1:1:2 C:10:0:0:0 # + To Damage for swords N:5 X:5:2 T:23:0:255 T:115:55:55 W:1:1:2 C:9:0:0:0 # + To damage for hafted weapons N:6 X:5:2 T:21:0:255 W:1:1:2 C:11:0:0:0 # + To hit N:7 X:5:2 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:19:0:255 T:22:0:255 T:24:0:255 T:115:55:55 W:1:1:2 C:0:10:0:0 # + To Hit for swords N:8 X:5:2 T:23:0:255 T:115:55:55 W:1:1:2 C:0:11:0:0 # + To Hit for hafted weapons N:9 X:5:2 T:21:0:255 W:1:1:2 C:0:9:0:0 N:10 X:15:1 T:24:0:255 T:115:55:55 W:15:1:25 C:4:0:0:0 F:VORPAL N:11 X:15:1 T:23:2:2 T:23:9:9 T:23:11:33 T:115:55:55 W:15:1:25 C:2:2:0:0 F:VORPAL N:12 X:15:1 T:22:30:30 W:10:1:16 C:6:-2:0:0 F:VORPAL N:13 X:15:1 T:22:17:17 T:22:3:3 T:22:0:15 W:15:1:25 C:4:0:0:0 F:VORPAL N:14 X:10:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 T:115:55:55 W:4:1:10 C:5:2:0:0 F:BRAND_POIS N:15 X:10:1 T:23:0:255 T:115:55:55 W:4:1:10 C:4:3:0:0 F:BRAND_POIS N:16 X:10:1 T:21:0:255 W:4:1:10 C:5:2:0:0 F:BRAND_POIS N:17 X:11:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:5:1:11 C:3:1:0:0 F:BRAND_FIRE A:BRAND_COLD N:18 X:11:1 T:23:0:255 T:115:55:55 W:5:1:11 C:2:2:0:0 F:BRAND_FIRE A:BRAND_COLD N:19 X:11:1 T:21:0:255 W:5:1:11 C:4:0:0:0 F:BRAND_FIRE A:BRAND_COLD N:20 X:12:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:5:1:11 C:5:1:0:0 F:BRAND_COLD A:BRAND_FIRE N:21 X:12:1 T:23:0:255 T:115:55:55 W:5:1:11 C:4:2:0:0 F:BRAND_COLD A:BRAND_FIRE N:22 X:12:1 T:21:0:255 W:5:1:11 C:6:0:0:0 F:BRAND_COLD A:BRAND_FIRE N:23 X:13:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:5:1:13 C:4:0:0:0 F:BRAND_ELEC N:24 X:13:1 T:23:0:255 T:115:55:55 W:5:1:13 C:3:1:0:0 F:BRAND_ELEC N:25 X:13:1 T:21:0:255 W:5:1:13 C:5:-1:0:0 F:BRAND_ELEC N:26 X:15:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:7:1:15 C:3:0:0:0 F:BRAND_ACID N:27 X:15:1 T:23:0:255 T:115:55:55 W:7:1:15 C:2:1:0:0 F:BRAND_ACID N:28 X:15:1 T:21:0:255 W:7:1:15 C:4:0:0:0 F:BRAND_ACID N:29 X:5:1 T:21:0:255 W:15:1:35 C:15:2:0:0 F:IMPACT N:30 X:5:1 T:18:0:255 T:19:0:255 T:22:0:255 T:24:0:255 W:2:1:9 C:2:2:0:6 F:STR N:31 X:5:1 T:23:0:255 T:115:55:55 W:2:1:9 C:0:4:0:6 F:STR N:32 X:5:1 T:21:0:255 W:1:1:7 C:4:0:0:6 F:STR N:33 X:3:1 T:18:0:255 T:19:0:255 T:20:0:255 T:22:0:255 T:24:0:255 W:1:1:6 C:0:0:0:6 F:CHR N:34 X:3:1 T:23:0:255 T:115:55:55 W:2:1:6 C:-1:1:0:6 F:CHR N:35 X:2:1 T:21:0:255 W:2:1:6 C:1:-1:0:5 F:CHR N:36 X:4:1 T:18:0:255 T:19:0:255 T:20:0:255 T:22:0:255 T:24:0:255 W:2:1:8 C:0:0:0:4 F:INT N:37 X:4:1 T:21:0:255 W:2:1:8 C:1:-1:0:4 F:INT N:38 X:4:1 T:23:0:255 T:115:55:55 W:2:1:8 C:-1:1:0:4 F:INT N:39 X:6:1 T:18:0:255 T:19:0:255 T:20:0:255 T:22:0:255 T:24:0:255 W:3:1:10 C:0:0:0:6 F:CON N:40 X:6:1 T:23:0:255 T:115:55:55 W:3:1:10 C:-1:1:0:6 F:CON N:41 X:6:1 T:21:0:255 C:1:-1:0:6 F:CON N:42 X:4:1 T:18:0:255 T:19:0:255 T:20:0:255 T:22:0:255 T:24:0:255 W:2:1:8 C:0:0:0:5 F:WIS N:43 X:4:1 T:21:0:255 W:2:1:9 C:1:-1:0:6 F:WIS N:44 X:4:1 T:23:0:255 T:115:55:55 W:2:1:9 C:-1:1:0:5 F:WIS N:45 X:4:1 T:18:0:255 T:19:0:255 T:20:0:255 T:22:0:255 T:24:0:255 W:2:1:7 C:0:0:0:5 F:DEX N:46 X:4:1 T:23:0:255 T:115:55:55 W:2:1:7 C:-1:1:0:6 F:DEX N:47 X:4:1 T:21:0:255 W:2:1:7 C:1:-1:0:5 F:DEX N:48 X:4:1 T:21:0:255 W:9:1:14 C:3:0:0:6 F:TUNNEL N:49 X:40:1 T:22:0:255 T:24:0:255 W:30:1:100 C:0:-4:0:3 F:BLOWS N:50 X:40:1 T:23:0:255 T:115:55:55 W:30:1:100 C:-1:-3:0:3 F:BLOWS N:51 X:40:1 T:21:0:255 W:30:1:100 C:1:-5:0:3 F:BLOWS N:52 X:50:1 T:18:0:255 T:19:0:255 T:22:0:255 T:24:0:255 W:40:1:90 C:-2:-2:0:5 F:SPEED N:53 X:50:1 T:21:0:255 W:40:1:90 C:-1:-3:0:5 F:SPEED N:54 X:50:1 T:23:0:255 T:115:55:55 W:40:1:90 C:-3:-1:0:5 F:SPEED N:55 X:12:1 T:18:0:255 T:22:0:255 T:21:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:11:1:20 C:10:10:0:0 F:CHAOTIC N:56 X:8:1 T:18:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:11:1:20 C:-10:-10:0:0 F:CHAOTIC N:57 X:12:1 T:18:0:255 T:22:0:255 T:24:0:255 W:15:1:20 C:4:0:0:4 F:VAMPIRIC N:58 X:12:1 T:21:0:255 W:15:1:20 C:5:-1:0:0 F:VAMPIRIC N:59 X:12:1 T:23:0:19 T:115:55:55 W:15:1:20 C:3:1:0:4 F:VAMPIRIC N:60 X:11:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:10:1:10 C:0:0:0:0 F:SLAY_ANIMAL N:61 X:11:1 T:21:0:255 W:10:1:10 C:1:-1:0:0 F:SLAY_ANIMAL N:62 X:11:1 T:23:0:255 T:115:55:55 W:10:1:10 C:-1:1:0:0 F:SLAY_ANIMAL N:63 X:19:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:15:1:17 C:0:0:0:0 F:SLAY_EVIL N:64 X:19:1 T:21:0:255 W:15:1:15 C:1:-1:0:0 F:SLAY_EVIL N:65 X:19:1 T:23:0:255 T:115:55:55 W:15:1:17 C:-1:1:0:0 F:SLAY_EVIL N:66 X:15:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:13:1:15 C:0:0:0:0 F:SLAY_UNDEAD A:KILL_UNDEAD N:67 X:15:1 T:21:0:255 W:13:1:15 C:1:-1:0:0 F:SLAY_UNDEAD A:KILL_UNDEAD N:68 X:15:1 T:23:0:255 T:115:55:55 W:13:1:15 C:-1:1:0:0 F:SLAY_UNDEAD A:KILL_UNDEAD N:69 X:5:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:11:1:25 C:0:0:0:0 F:SLAY_DEMON A:KILL_DEMON N:70 X:5:1 T:21:0:255 W:11:1:25 C:1:-1:0:0 F:SLAY_DEMON A:KILL_DEMON N:71 X:5:1 T:23:0:255 T:115:55:55 W:11:1:25 C:-1:1:0:0 F:SLAY_DEMON A:KILL_DEMON N:72 X:10:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:3:1:10 C:0:0:0:0 F:SLAY_ORC N:73 X:10:1 T:21:0:255 W:3:1:10 C:1:-1:0:0 F:SLAY_ORC N:74 X:10:1 T:23:0:255 T:115:55:55 W:3:1:10 C:-1:1:0:0 F:SLAY_ORC N:75 X:11:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:15:2:17 C:0:0:0:0 F:SLAY_TROLL N:76 X:11:1 T:21:0:255 W:15:2:17 C:1:-1:0:0 F:SLAY_TROLL N:77 X:11:1 T:23:0:255 T:115:55:55 W:15:2:17 C:-1:1:0:0 F:SLAY_TROLL N:78 X:10:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:20:1:20 C:0:0:0:0 F:SLAY_GIANT N:79 X:10:1 T:21:0:255 W:20:1:20 C:-1:1:0:0 F:SLAY_GIANT N:80 X:10:1 T:23:0:255 T:115:55:55 W:20:1:20 C:0:0:0:0 F:SLAY_GIANT N:81 X:20:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:17:1:20 C:0:0:0:0 F:SLAY_DRAGON A:KILL_DRAGON N:82 X:20:1 T:21:0:255 W:17:1:20 C:1:-1:0:0 F:SLAY_DRAGON A:KILL_DRAGON N:83 X:20:1 T:23:0:255 T:115:55:55 C:-1:1:0:0 W:17:1:20 F:SLAY_DRAGON A:KILL_DRAGON N:84 X:31:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:22:0:255 T:24:0:255 W:17:1:35 C:0:0:0:0 F:KILL_DRAGON A:SLAY_DRAGON N:85 X:31:1 T:21:0:255 W:17:1:35 C:1:-1:0:0 F:KILL_DRAGON A:SLAY_DRAGON N:86 X:31:1 T:23:0:255 T:115:55:55 W:17:1:35 C:-1:1:0:0 F:KILL_DRAGON A:SLAY_DRAGON N:87 X:15:1 T:18:0:255 T:22:0:255 T:24:0:255 W:5:1:10 C:-2:-2:0:0 F:BLESSED A:CURSED N:88 X:15:1 T:21:0:255 W:5:1:7 C:-1:-3:0:0 F:BLESSED A:CURSED N:89 X:15:1 T:23:0:255 T:115:55:55 W:5:1:10 C:-3:-1:0:0 F:BLESSED A:CURSED N:90 X:-5:1 T:15:0:255 T:16:0:255 T:18:0:255 T:19:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:1:1:20 C:0:0:0:0 F:CURSED A:BLESSED N:93 X:-10:1 T:18:0:255 T:19:0:255 T:20:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:1:1:20 C:0:0:0:0 F:AGGRAVATE A:STEALTH N:94 X:13:1 T:18:0:255 T:19:0:255 T:20:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:1:1:15 C:0:0:0:0 F:LITE1 A:RES_LITE N:95 X:40:1 T:19:0:255 W:20:1:38 C:0:0:0:3 F:XTRA_MIGHT N:96 X:40:1 T:19:0:255 W:20:1:38 C:0:0:0:0 F:XTRA_SHOTS N:97 X:25:1 T:23:0:255 T:24:0:255 T:22:17:17 T:22:3:3 T:22:0:15 T:115:55:55 W:14:1:23 C:3:0:0:0 F:WOUNDING N:98 X:60:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:27:1:50 C:0:0:0:0 F:KILL_UNDEAD A:SLAY_UNDEAD N:99 X:45:1 T:15:0:255 T:16:0:255 T:17:0:255 T:18:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:25:1:34 C:0:0:0:0 F:KILL_DEMON A:SLAY_DEMON N:100 X:20:1 T:18:0:255 T:21:0:255 T:22:0:255 T:23:0:255 T:24:0:255 T:115:55:55 W:15:1:25 C:2:0:0:0 Z:BERSERK N:101 X:15:1 T:20:0:255 T:21:0:255 W:20:1:35 C:0:0:0:0 Z:EARTHQUAKE N:102 X:5:1 T:20:0:255 W:2:1:9 C:0:0:0:6 F:STR ### Armor ### N:295 X:60:1 T:36:0:255 T:37:0:255 W:20:1:90 C:-70:-70:0:2 F:LIFE N:296 X:7:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 W:1:1:14 C:0:0:0:0 F:SUST_STR N:297 X:6:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:6:0:255 W:1:1:12 C:0:0:0:0 F:SUST_INT N:298 X:6:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:6:0:255 W:1:1:12 C:0:0:0:0 F:SUST_WIS N:299 X:5:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 W:1:1:11 C:0:0:1:0 F:SUST_DEX N:300 X:9:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 W:1:1:16 C:0:0:0:0 F:SUST_CON N:301 X:4:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 W:1:1:9 C:0:0:0:0 F:SUST_CHR N:302 X:50:1 T:36:0:255 T:37:0:255 T:38:0:255 W:30:1:70 C:0:0:0:0 F:IM_ACID N:303 X:50:1 T:34:0:255 T:115:56:56 W:30:1:90 C:0:0:0:0 F:IM_ACID N:304 X:50:1 T:35:0:255 W:30:1:80 C:0:0:0:0 F:IM_ACID N:305 X:45:1 T:36:0:255 T:37:0:255 T:38:0:255 W:30:1:78 F:IM_ELEC N:306 X:45:1 T:34:0:255 T:115:56:56 W:30:1:98 C:0:0:0:0 F:IM_ELEC N:307 X:45:1 T:35:0:255 W:30:1:88 C:0:0:0:0 F:IM_ELEC N:308 X:55:1 T:36:0:255 T:37:0:255 T:38:0:255 W:30:1:86 C:0:0:0:0 F:IM_FIRE N:309 X:55:1 T:34:0:255 T:115:56:56 T:35:0:255 W:30:1:95 C:0:0:0:0 F:IM_FIRE N:310 X:47:1 T:36:0:255 T:37:0:255 T:38:0:255 W:30:1:90 C:0:0:0:0 F:IM_COLD N:311 X:47:1 T:34:0:255 T:115:56:56 T:35:0:255 W:30:1:90 C:0:0:0:0 F:IM_COLD N:312 X:47:1 T:35:3:3 W:30:1:100 C:0:0:0:0 F:IM_COLD N:313 X:35:1 T:34:0:255 T:38:0:255 T:115:56:56 W:20:1:45 C:0:0:0:0 F:REFLECT N:314 X:35:1 T:34:10:10 T:115:56:56 W:10:1:15 C:0:0:0:0 F:REFLECT N:315 X:17:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 T:6:0:255 W:5:1:7 C:0:0:0:0 F:FREE_ACT N:316 X:23:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 W:8:1:14 C:0:0:0:0 F:HOLD_LIFE N:317 X:15:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:1:1:10 C:0:0:0:0 F:RES_ACID N:318 X:15:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:1:1:10 C:0:0:0:0 F:RES_FIRE N:319 X:13:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:1:1:9 C:0:0:0:0 F:RES_ELEC N:320 X:12:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:1:1:8 C:0:0:0:0 F:RES_COLD N:321 X:20:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:5:1:18 C:0:0:0:0 F:RES_POIS N:322 X:15:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:6:1:15 C:0:0:0:0 F:RES_FEAR N:323 X:10:1 T:30:0:255 T:31:0:255 T:33:0:255 T:34:0:255 T:115:56:56 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:5:1:10 C:0:0:0:0 F:RES_LITE N:324 X:10:1 T:32:0:255 T:115:57:57 W:1:1:7 C:0:0:0:0 F:RES_LITE N:325 X:15:1 T:32:0:255 T:115:57:57 W:5:1:15 C:0:0:0:0 F:LITE1 A:RES_LITE N:326 X:17:1 T:32:0:255 T:115:57:57 W:10:1:20 C:0:0:0:0 F:LITE2 A:RES_LITE N:327 X:20:1 T:32:0:255 T:115:57:57 W:15:1:25 C:0:0:0:0 F:LITE3 A:RES_LITE N:328 X:15:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:10:1:15 C:0:0:0:0 F:RES_DARK N:329 X:20:1 T:115:57:57 T:32:0:255 T:40:0:255 T:45:0:255 T:6:0:255 W:13:1:27 C:0:0:0:0 F:RES_BLIND N:330 X:17:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:13:1:18 C:0:0:0:0 F:RES_SOUND N:331 X:15:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:115:56:57 T:34:0:255 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:17:1:15 C:0:0:0:0 F:RES_NEXUS N:332 X:19:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:16:1:19 C:0:0:0:0 F:RES_SHARDS N:333 X:30:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:30:1:50 C:0:0:0:0 F:RES_NETHER N:334 X:25:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 W:25:1:30 F:RES_CHAOS N:335 X:20:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 T:6:0:255 W:25:1:35 C:0:0:0:0 F:RES_CONF N:336 X:25:1 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:40:0:255 T:45:0:255 C:0:0:0:0 W:23:1:32 F:RES_DISEN N:337 X:20:1 T:35:0:255 W:10:1:17 C:0:0:0:0 F:SH_FIRE | RES_FIRE N:338 X:22:1 T:35:0:255 W:10:1:20 C:0:0:0:0 F:SH_ELEC | RES_ELEC N:339 X:18:1 T:115:57:57 T:32:0:255 T:33:0:255 T:40:0:255 T:45:0:255 T:6:0:255 W:5:1:15 C:0:0:0:0 F:SEE_INVIS N:340 X:14:1 T:30:0:255 T:40:0:255 T:45:0:255 W:5:1:13 C:0:0:0:0 F:FEATHER A:FLY N:341 X:80:1 T:35:0:255 T:30:0:255 T:6:0:255 W:40:1:90 C:0:0:0:0 F:FLY A:FEATHER N:342 X:30:1 T:115:57:57 T:32:0:255 T:33:0:255 W:20:1:30 C:0:0:0:0 Z:MIND BLAST N:343 X:30:1 T:115:57:57 T:32:0:255 T:33:0:255 W:20:1:30 C:0:0:0:0 Z:TELEKINESIS N:344 X:35:1 T:31:0:255 W:25:1:40 C:0:0:0:0 Z:MIDAS TOUCH N:345 X:15:1 T:31:0:255 C:0:0:0:0 Z:COLD TOUCH N:346 X:30:1 T:35:0:255 W:20:1:27 C:0:0:0:0 Z:BLINK A:RES_NEXUS ### + To AC ### N:347 X:15:4 T:30:0:255 T:31:0:255 T:32:0:255 T:33:0:255 T:34:0:255 T:115:56:57 T:35:0:255 T:36:0:255 T:37:0:255 T:38:0:255 T:6:0:255 W:1:1:5 C:0:0:5:0 ### + To Dam (Only Gloves) ### N:348 X:40:1 T:31:0:255 W:1:1:45 C:10:0:0:0 ### + To Hit (Only Gloves) ### N:349 X:35:1 T:31:0:255 W:1:1:40 C:0:10:0:0 # N:index # X:power value:max number of time it can appear on one object # T:tval:min sval:max sval (up to 20 T: lines) # W:mininum player level to create it:rarity1:rarity2 # C:max to dam:max to hit:max to AC:max to pval # F:flags # Helm of water breathing N:350 X:50:1 T:32:5:10 W:20:1:25 C:0:0:0:0 F:WATER_BREATH ### Amulets And Rings ### N:442 X:15:1 T:40:0:255 T:45:0:255 W:5:1:17 C:0:0:0:5 F:STR N:443 X:11:1 T:40:0:255 T:45:0:255 W:3:1:12 C:0:0:0:5 F:DEX N:444 X:13:1 T:40:0:255 T:45:0:255 W:5:1:15 C:0:0:0:5 F:WIS N:445 X:13:1 T:40:0:255 T:45:0:255 W:1:1:15 C:0:0:0:5 F:INT N:446 X:7:1 T:40:0:255 T:45:0:255 W:1:1:15 C:0:0:0:5 F:CHR N:447 X:18:1 T:40:0:255 T:45:0:255 W:7:1:20 C:0:0:0:5 F:CON N:448 X:15:1 T:40:0:255 T:45:0:255 W:5:1:15 C:0:0:0:0 F:SUST_STR N:449 X:20:1 T:40:0:255 T:45:0:255 W:7:1:20 C:0:0:0:0 F:SUST_CON N:450 X:7:1 T:40:0:255 T:45:0:255 W:1:1:15 F:SUST_CHR N:451 X:11:1 T:40:0:255 T:45:0:255 W:1:1:11 F:SUST_DEX N:452 X:13:1 T:40:0:255 T:45:0:255 W:5:1:13 F:SUST_INT N:453 X:13:1 T:40:0:255 T:45:0:255 W:5:1:13 F:SUST_WIS N:454 X:40:1 T:45:0:255 C:0:0:0:5 W:25:1:55 F:INVIS N:455 X:70:1 T:45:0:255 C:0:0:0:5 W:40:1:90 F:SPEED N:456 X:17:1 T:40:0:255 T:45:0:255 W:5:1:16 C:0:0:0:0 F:SLOW_DIGEST A:REGEN N:457 X:20:1 T:40:0:255 T:45:0:255 W:7:1:19 C:0:0:0:0 F:REGEN A:SLOW_DIGEST N:458 X:15:1 T:40:0:255 T:45:0:255 T:35:0:255 W:10:1:16 C:0:0:0:4 F:STEALTH A:AGGRAVATE N:459 X:7:1 T:40:0:255 T:45:0:255 W:1:1:12 C:0:0:0:6 F:SEARCH N:460 X:10:1 T:40:0:255 T:45:0:255 W:1:1:12 C:0:0:0:4 F:INFRA N:461 X:80:1 T:45:0:255 W:40:1:95 C:0:0:0:3 F:BLOWS N:462 X:70:1 T:45:0:255 W:38:1:75 C:0:0:0:0 F:FLY A:FEATHER N:463 X:80:1 T:45:0:255 W:43:1:85 C:0:0:0:5 F:CRIT ### Lights ### N:501 X:15:1 T:39:0:255 T:6:0:255 W:5:1:15 F:LITE1 N:502 X:20:1 T:39:0:255 W:10:1:25 C:0:0:0:0 F:LITE2 N:503 X:30:1 T:39:0:255 W:20:1:35 C:0:0:0:0 F:LITE3 N:504 X:15:1 T:39:0:255 W:10:1:15 C:0:0:0:0 F:RES_LITE N:505 X:18:1 T:39:0:255 W:11:1:17 C:0:0:0:0 F:RES_DARK N:506 X:20:1 T:39:0:255 W:15:1:22 C:0:0:0:0 F:SEE_INVIS N:507 X:12:1 T:39:0:255 W:1:1:10 C:0:0:0:4 F:SEARCH N:508 X:12:1 T:39:0:255 W:1:1:15 C:0:0:0:4 F:INFRA N:509 X:21:1 T:39:0:255 W:5:1:20 C:0:0:0:0 Z:ILLUMINATE N:510 X:35:1 T:39:0:255 W:20:1:27 C:0:0:0:0 Z:MAGIC MAP N:511 X:30:1 T:39:0:255 W:20:1:24 C:0:0:0:0 Z:DETECT CURSES N:512 X:25:1 T:39:0:255 W:20:1:17 C:0:0:0:0 Z:DAZZLE N:513 X:40:1 T:39:0:255 W:20:1:50 Z:DETECT DOORS AND TRAPS tome-235-src/lib/edit/s_death.map0000644000076400017500000001657111012107760014476 0ustar dgdg# Special level "Deathwatch" in the Orc Caves # # Created for PernAngband 5.0.1 on 18/8/01 # Altered by Mynstral (mynstral@thehelm.com) %:special.txt ### Guaranteed monsters # Snaga on normal floor F:a:1:0:118 # Cave orc on normal floor F:b:1:0:126 # Hill orc on normal floor F:c:1:0:149 # Black orc on normal floor F:d:1:0:244 # Half-orc on normal floor F:e:1:0:264 # Uruk on normal floor F:f:1:0:313 # orc captain on normal floor F:g:1:0:285 # Lagduf on normal floor F:h:1:0:140 # Grishnakh on normal floor F:i:1:0:186 # Golfimbul on normal floor F:j:1:0:215 ### Guaranteed items # Thalkettoth on normal floor F:1:1:0:0:0:0:28 # Maedhros on normal floor F:2:1:0:0:0:0:64 # Cammithrim on normal floor F:3:1:0:0:0:0:53 ### Dungeon Design D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX D:X XXXXXXXXXXXX X D:X X..........X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X D:X X....>.....X X.XdX.X.X.XcX.X.X...XcX.X.XcX.X.XgXd+2X X D:X X..........X XDXDXDXDXDXDXDXDX...XDXDXDXDXDXDXDXDXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X D:X XXXXXDXXXXXX X...............D...D...............X X...f............a...XXXXX.......b..f....a....+1X X D:X X.X XDXDXDXDXDXDXDXDX..cXDXDXDXDXDXDXDXDX X........b...........XXXXX...a..........b.....XXX X D:X X.X X.XcX.XcXdX.X.X.X...XcX.XdXcX.X.X.XgX XXXXXXXXXXDDXXXXXXXXXXXXXXXXXXXXXXXXDDXXXXXXXXX X D:X X.X XXXXXXXXXXXXXXXXX.c.XXXXXXXXXXXXXXXXX XXXXXXXXXXDDXXXXXXXXXXXXXXXXXXXXXXXXDDXXXXXXXXX X D:X X.X XXX X...X X...........f...a....XXXXX....b.a...........b.X X D:X XX.XX X.XXXXXXXXXXXXDDDXXXXX X..f...b.............XXXXX..a....f.....b..a...X X D:X XX...XX XXXDXXXXXXXXX.......c.XX XXXXXXXXXXDDXXXXXXXXXXXXXXXXXXXXXXXXDDXXXXXXXXX X D:X XX.....XX XdD........D...c......dX X........a...............a....................X X D:X XX.......XX XXXDXXXXXXXX......c....X Xf....b..........f............a.........f.....X X D:X X.........X XeX XX.........XX X.............a.......b...........a...........X X D:X XXXXX.XXXXX X.X XXXXDDDXXXX X....a...............................a........X X D:X X.X X.X X...X XXXXXXXXXXXXXXXXXXXXX...XXXXXXXXXXXXXXXXXXXXXXX X D:X X.X X.X X...X X...X X D:X X.X X.X XX...XX X.b.X X D:X X.X X.X XX.....XX X...X X D:X XXDXX XXXX X.X XX.......XX X..bX X D:X X...XXXX..X XdX XX...ccc...XX X...X X D:X X...+..D..X X.X XX....ccc...dXX X...X X D:X X...XXXX..X X.X XX.d..ccicc....XX XXXXXXXXXXXXXDDDXXXXXXXXXXXX X D:X XX.XX XXXX X.X XX......ccc..g...XX XX......a...............f...XX X D:X X.X X.X XX...g...ccc.......XX XXX..f.........................XX XXXXX X D:X X.X X.X X......g.........g..X XX..................b....a.......XX Xa.aX X D:X X.X XgX XXXX..XXXXXXX..XXXXXX XX.....a.........a..............a..XX X.a.X X D:X X.X X.X X..X X..X XXXXXXXX..........f........................XX XDXXX X D:X X.X X.X Xd.XXXXXXX..XXXXXXX X.....D...b.................b...f...........XXXXXXXXXXX.X X D:X X.X X.X X...c.......D.....X X.....D...........a..h.............a........D......a....X X D:X X.X X.X X.......c.g.D.....X X...XXXX.....b.............................XXXXXXXXXXXX.X X D:X XXXX.XXXX X.X XXXXXXXXXXXXXXXX..XXXXXXX X...X XX..............a......a...........XX X.X X D:X X.......X X.X X........XXXXXXX...X XX.........f.............f.......XX X.X X D:X XXX...XXX X.X X..d...............X XX.....b...........b.........f.XX XaX X D:X X.......X X.X X........XXXXXXX...X XX..........b................XX X.X X D:X XXXX.XXXX X.X XXXXXXXXXX XXXXX XXXXXXXXXXXXDDDDDXXXXXXXXXXXX X.X X D:X X.X XDXXXXXXXXXXXXXXX X.....X X.X X D:X X.X X..d...e......d.XXXXXXXXXXX XXXXXXXXXXXX X.b...X X.X X D:X X.X X....e..g.......D.........X X.d..gg..eeX XXX.....XX X.X X D:X X.X XXXXX X..g..d.....e...XXXXXXXXDDXXXXXXXX....gg..eeXXXXX XX...XXX..XXX XXXXXXDXX X D:X X.X XeeeX XDXXXXXXXXXXXXXXX Xg.d.......D.e..e..gg..eej+3+% XX....XXX....XXXXXX XXX...D..aX X D:X X.X Xeg.X XX.XX X....e....eD.e.....gg..eedXXX% X.............X...X XaD...X...X X D:X XXXX.XXX XX+XXXX...X X.d........XXXX....gg..eeXX % XXXXX XXXXXXXXXXXX..D...X XXX..aX...X X D:X X......X XX.......X XXXX...e...d..XXXX...dgg..eeX % X...X XX.....D..XXXXXX XXXXXXXDXX X D:X X......X X.g.....XXXXXX X..D....g..e..Dd.XXXXXXXXXXXX % XXXDXX X......X..X....X X...X X D:X X......X X...d...DeeeeX X..XXXXXXXXXXXX..X + X...X XXXXXXXX..X....X X...X X D:X X......X X.....e.XXXXXX XXXX XXXX % X...XXXXXX X....D..D....X XXXXXXXXDXDXXXX X D:X XXXDDXXXXXXXXXXXXXX+XXXXXX % X....X...X X..XXX..XXXXXXXXX X.....a..X....X X D:X X........%........X %+%%....D...XXXXXX.D..D.....+.X X........X....X X D:X XXXXXXXXXXXXXXXXXXX XXXXXX..........X..X.....XXX XXXXXXXXXXXXXXX X D:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ### Starting Location P:51:125 tome-235-src/lib/file/0000755000076400017500000000000011012107763012353 5ustar dgdgtome-235-src/lib/file/dam_huge.txt0000644000076400017500000000043011012107760014657 0ustar dgdg7 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* You nearly decapitate %s! You impale %s on your weapon. Your weapon almost slices %s in half! %^s's head caves in! You broke %s's spine! Your weapon slices into %s's heart! You smashed %s's ribcage! tome-235-src/lib/file/mondeath.txt0000644000076400017500000002544111012107760014716 0ustar dgdg332 ****** BUFFER LINE *********************************** DO NOT REMOVE ******* 'Live and let live, right..?' 'AAAAAAAAARRRRRRRRRRRRRRRRGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHH!!!!!!!!!!!' 'AAAARRRGGGHHH!!!' 'Somehow, I have a bad feeling about this...' 'Strangely, all of a sudden I don't feel so good.' 'I can see armored women on winged horses coming for me.' 'Oh well, you can't always win.' 'I'm too young to die!' 'I'll be back!' 'O, untimely death!' 'Slave, thou hast slain me!' 'Ouch! That smarts!' 'Who knocked?' 'Did anybody get the number of that truck..?' 'Ouch.' 'Et tu, Brute! Then fall, Caesar!' 'O! I die, Horatio...' 'I told you to be careful with that sword...' 'This guy's a little crazy...' 'Ok, ok, I get it: No more pals.' 'No more Mr. Nice Guy!' 'Who turned off the light..?' 'Join the army, see the world, they said...' 'Mom told me there'd be days like this...' 'Rats!' 'Shall this fellow live?' 'Help, ho!' 'What ho! Help!' 'What hast thou done?' 'I'll be revenged on the whole pack of you!' 'You will *pay* for this!' 'They say blood will have blood...' 'Violence is no solution!' 'Yes?' '#&%#&#%*#*&%!!!!!' 'F***!' 'No time to make a testament?' 'Ugh!' 'Aargh!' 'Aaagghhh!' 'I'm melting!' 'Oof..' 'Oh!' 'Did somebody knock?' 'Later, dude...' 'CU!' 'What? Who? Me? Oh, s..t!' '...amen!' 'Eeek!' 'Aacch!' 'I hate it when that happens.' 'One direct hit can ruin your whole day.' 'Oh no!' 'Not me!' 'Ouch.' 'Oh no, not again.' 'Another one bites the dust.' 'Goodbye.' 'Help me!' 'Farewell, cruel world.' 'Oh man!' 'Doough!' 'This is the End, my only friend.' 'It's all over.' 'The fat lady sang.' 'Why does everything happen to me?' 'I'm going down.' 'Crapola.' 'Pow!' 'Bif!' 'Bam!' 'Zonk!' 'I should've listened to my mother...' 'No... a Bud light!' 'What was that noise?' 'Mama said there'd be days like this.' 'It's just one of those days...' 'I see a bright light...' 'Mommy? Is that you?' 'I let you hit me!' 'Sucker shot!' 'I didn't want to live anyway.' '--' 'Hah haa! Missed me! Ha---' 'Was that as close as I think it was?' 'The monsters rejoice: the hero has been defeated.' 'It wasn't just a job it was an adventure!' 'I didn't like violence anyway!' 'I thought you liked me?' 'Such senseless violence! I don't understand it.' 'I think this guy's a little crazy.' 'Somehow I don't feel like killing anymore.' 'Help me! I am undone!' 'Hey! Killin' ain't cool.' 'This fell sergeant, Death, is strict in his arrest...' 'The rest is silence.' 'Guh!' 'It's game over, man!' 'Trust me, I know what I'm doing...' 'Kill men i' the dark! What be these bloody thieves?' 'Ho! Murder! Murder!' 'O! I am spoil'd, undone by villains!' 'O murderous slave! O villain!' 'O, falsely, falsely murder'd!' 'A guiltless death I die.' 'AAAAAAAAAAAAAAAAAAAAAAAAHHHHHHH!' 'Trust me.' 'Dammit, this thing won't die!' 'He hit me for HOW MUCH?????' 'Look, behind you!!!' 'Who fed steroids to that kobold?' 'Don't worry, be happy!' 'I don't believe this!' 'Oops.' 'Can't you take a joke?' 'Well, I didn't much like this character, anyway...' 'Oops, sorry... didn't mean to disturb you.' 'I never get to have any fun!' 'Stop!' 'Cut it out!' 'Don't worry. I've got a plan.' 'It didn't look so tough.' 'Run away!' 'All clear, guys.' 'AGAIN!?!?!' 'I don't like this dungeon...' 'Maybe this wasn't such a good idea.' 'My God will protect me.' 'You wouldn't dare!' 'But what about my Parry Skill? Tumbling?' 'Don't worry - I have Pilot-7.' 'And I've *never* done you any harm.' 'I don't understand. It should be dead by now.' 'I'm heir to the crown. They wouldn't dare!' 'Hey! Where's my stomach? My hands?' 'Ha! That's the oldest trick in the book.' 'Cover me.' 'Watch this.' 'And damn'd be him that first cries: Hold, enough!' 'I will not yield.' '...but like a man he died.' 'If you cut me down, I will only become more powerful.' 'Well, at least I tried...?' 'What could possibly have gone wrong?' 'What's with that weirdo with the teeth?' 'Surrender? Never!' 'I'm sure reinforcements will get here on time. They promised.' 'Funny, didn't *look* like a cyberpsycho....' 'I have a very bad feeling about this.' 'Do something, SCHMUCK!' 'I feel I could cast Speak with Dead and talk to myself.' 'Oh, that's just a light wound.' 'Ach, is doch nur 'ne Fleischwunde...' 'I thought you were on MY side...' 'Next time, try talking!' 'Oh shit... I'll try to teleport again.' 'Somebody get me a Rod of Resurrection... QUICK!' 'Uhh... oh-oh...' 'Gee, where'd everybody go?' 'I see it coming...aaargllhhhh! {sough}' 'Ay! Ay! Ay!' 'Ohe! Ohe! Ohe!' 'Et tu, Caesar! Then fall, Brute!' 'Even the best laid plans...' 'Hey, not too rough!' 'The Random Number Generator hates me!' 'So when I die, the first thing I will see in heaven is a score list?' 'Can't we talk this thing over?' 'Wait! Spare me and I'll make you rich! Money is not a problem!' 'I hate you!' 'By the kind gods, 'twas most ignobly done!' 'Mein Leben!' 'Meine Lieder!' 'I'm the hero of this story! I CAN'T die!' 'Gee... thanks.' 'I've fallen and I can't get up!' '911?' 'Sure don't look good...' 'Oh No! Here I blow again!' 'I'll be back...' 'Hey - I've got lawyers.' 'Thanks, I needed that.' 'I AM toast!!' 'Scheisse!' 'Oh, basely done! I had hoped for better of thee!' 'I am death incarnate! NOTHING can harm me!' 'And you thought Tristan was unlucky...' 'Just wait till I get my hands on the crook who sold me this crappy armor...' 'All is lost. Monks, monks, monks!' 'All my possessions for a moment of time!' 'Don't let poor Nelly starve!' 'Wally, what is this? It is death, my boy: they have deceived me.' 'Everyone dances with the Grim Reaper.' 'Adios.' 'I'm going home, babe.' 'I am innocent, innocent, innocent!' 'Watch where you're pointing with that sword! You nearly...' 'Hmm, some things are better wanted than had...' 'And they told me it was not loaded.' 'Of course I know what I am doing.' 'It looked harmless.' 'Hilfe, hilfe, hilfe!' 'Look, dad! No head!' 'Look! I'm flying!' 'Think I'm gonna fall for that?' 'I'll be back... as soon as I can.' '3... 2... 1... Liftoff!' 'My wallet? In your dreams!' 'Yes! Yes! YES! YES! YY... AAARRRGGGHH!' 'See you later, alligator!' 'Up, up and awaaaayyy!' 'Been nice knowing you.' 'But I just got a little prick!' 'And I just wanted that fancy suit of armour you were carrying...' 'Hey guys, where are you?' 'Hey look... ARCHERS!' 'I can't probably miss...' 'I don't care. I have a Scroll of Raise Dead.' 'I don't care. I have a Ring of Regeneration.' 'I have this dungeon at home, I know where everything is!' 'This HAS to be an illusion. I attempt to disbelieve it.' 'I thought you could be trusted.' 'Never try to sneak in a plate mail.' 'I'll never surrender.' 'I'll use the Cheat Death option...' 'I'm invincible!' 'Hey, it was only a joke, all right?' 'Hey, don't talk to me like that!' 'I have rights, too!' 'Just because you're big and ugly doesn't mean you can push ME around.' 'Me first! Me first!' 'Let me handle this.' 'No problem. That's easy.' 'Oh, shit.' 'So what?' 'Tell me this is an illusion... please!' 'I hate the RNG...' 'They need a twenty to hit me! I'm invincible!' 'Trust me.' 'CHARGE!' 'What do you mean, how many hit points do I have?' 'What do you mean, my GOI expired?' 'Yeah, I knew it was dangerous, but I was thinking about the XP...' 'You mean you get to use the critical hit chart too?' 'You'd have to be a GOD to smile after that hit!' 'Morons! I have morons on my payroll!' 'Idiots! I am surrounded by incompetent idiots!' 'I have such sweet thoughts' 'I pray you all pray for me.' 'Is not this dying with courage and true greatness?' 'I must sleep now.' 'Nurse, nurse, what murder! What blood! I have done wrong!' 'That unworthy hand! That unworthy hand!' 'I am dying.' 'Oh, dear.' 'I will not kneel. Strike!' 'I have led a happy life.' 'Dying, dying.' 'I feel the flowers growing over me.' 'Now it is come.' 'Let me die to the sound of sweet music.' 'I will now enter the Halls of Mandos.' 'Ungrateful traitors!' 'We perish, we disappear, but the march of time goes on forever.' 'Youth, I forgive thee.' 'Treason! Treason!' 'Cowards! Why did you not protect me?' 'I am absolutely undone.' 'It is well. I die hard, but am not afraid to go.' 'Do let me die in peace.' 'Nothing is real but pain now.' 'Violent use brings violent plans.' 'Soldier boy, made of clay, now an empty shell.' 'Bodies fill the fields I see, the slaughter never ends.' 'Life planned out before my birth, nothing could I say.' 'Blood will follow blood, dying time is here.' 'Never happy endings on these dark sets.' 'No one to play soldier now, no one to pretend.' 'Time for lust, time for lie, time to kiss your life goodbye.' 'Greetings, Death, I'm yours to take away.' 'I was born for dying.' 'The higher you walk, the farther you fall.' 'Exit: light - enter: night!' 'New blood joins this earth...' 'You labeled me, I'll label you, so I dub thee unforgiven.' 'If you're gonna die, die with your boots on!' 'There's a time to live, and a time to die, when it's time to meet the maker.' 'Isn't it strange, as soon as you're born you're dying?' 'Only the good die young, all the evil seem to live forever.' 'I don't wanna die, I'm a god, why can't I live on?' 'And in my last hour, I'm a slave to the power of death.' 'Now I am cold, but a ghost lives in my veins.' 'You got to watch them - be quick or be dead.' 'Heaven can wait till another day.' 'You'll take my life but I'll take yours too.' 'We won't live to fight another day.' 'As I lay forgotten and alone, without fear I draw my parting groan.' 'Somebody please tell me that I'm dreaming!' 'Can't it be there's been some sort of error?' 'Is it really the end not some crazy dream?' 'Life down there is just a strange illusion.' 'My life suffocates, planting seeds of hate.' 'I split my brain, melt through the floor.' 'My body tries to leave my soul.' 'I'm so tired of living, I might as well end today.' 'Life, life! Death, death! How curious it is!' 'Catch my soul 'cos it's willing to fly away!' 'Flames? Not yet, I think.' 'Someone call the Gendarmes!' 'And now the dreams end.' 'I'm off to Never-Never Land!' 'Death greets me warm, now I will just say goodbye.' 'What is this? I've been stricken by fate!' 'This can't be happening to me!' 'Flash before my eyes: now it's time to die.' 'You have been dying since the day you were born.' 'No point asking who's to blame.' 'But for all my power I couldn't foresee my own demise.' 'My creator will lay my soul to rest.' 'Was that worth dying for?' 'Can you say you are proud of what you've done?' 'But there are some things which cannot be excused.' 'Why is it some of us are here just so that we'll die?' 'The shortest straw, pulled for me.' 'There's got to be just more to it that this or tell me why do we exist?' 'I can't believe that really my time has come.' 'Too much of a good thing, I guess...' 'When the dream dies, the nightmare begins.' 'You maggots make me sick. I'll be avenged. Lucifer dwells within all of us!' 'I really screwed up this time.' 'Wow, what a trip!' 'I believe my kingdom will come' tome-235-src/lib/file/readme!0000644000076400017500000000410511012107760013571 0ustar dgdgMost files in this directory are use by the get_rnd_line function for various purposes in the game. They can be edited and customised by the user with any ascii text editor. If you add / remove lines you should modify the index (the first line) accordingly. If you set an invalid index or remove the buffer line weird messages and other things can appear, and you can crash the game. Please see sample.txt before you try modifying the files. The a_*.txt and w_*.txt are used when the game generates a random artifact. However, instead of picking a name from the appropriate file, the game may form a new name from syllables[]. The files in this directory: A_CURSED TXT Possible names for randomly generated cursed armour artifacts A_HIGH TXT Possible names for randomly generated 'powerful' armour artifacts A_LOW TXT Possible names for randomly generated 'weak' armour artifacts A_MED TXT Possible names for randomly generated 'medium' armour artifacts BRAVADO TXT Possible lines for speaking uniques CHAINSWD TXT Possible noise for the Chainsword CRIME TXT Possible crimes that speaking uniques may have committed DEAD TXT The tombstone picture (the death screen) DEATH TXT Possible 'last words' when the player dies ELVISH TXT Syllables for the names of random artifacts ERROR TXT Possible random error messages (instead of "Type ? for help") MONDEATH TXT Possible 'last words' for speaking uniques MONFEAR TXT Possible lines for scared speaking uniques NEWS TXT The game intro screen README! You are reading this file right now RUMORS TXT Possible rumours (for scrolls or rumour and shopkeepers) SAMPLE TXT A sample file for the random line selecting function SILLY TXT Silly monster names for hallucination SMEAGOL TXT Smeagol lines SMEAGOLR TXT Smeagol fleeing W_CURSED TXT Possible names for randomly generated cursed weapon artifacts W_HIGH TXT Possible names for randomly generated 'powerful' weapon artifacts W_LOW TXT Possible names for randomly generated 'weak' weapon artifacts W_MED TXT Possible names for randomly generated 'medium' weapon artifacts tome-235-src/lib/file/death.txt0000644000076400017500000002500111012107760014174 0ustar dgdg349 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* Live and let live, right..? AAAAAAAAARRRRRRRRRRRRRRGGGGGGGGGGGGGHHHHHHHHHHHHHHH!!!!!!!!!!!! AAAARRRGGGHHH!!! Somehow, I have a bad feeling about this... Strangely, all of a sudden I don't feel so good. You can see armored women on winged horses coming for you. Oh well, you can't always win. I'm too young to die! I'll be back! O, untimely death! Slave, thou hast slain me! Ouch! That smarts! Who knocked? Did anybody get the number of that truck..? Ouch. Et tu, Brute! Then fall, Caesar! O! I die, Horatio... I told you to be careful with that sword... This guy's a little crazy... Ok, ok, I get it: No more pals. No more mr. nice guy! Who turned off the light..? Join the army, see the world, they said... Mom told me there'd be days like this... Rats! Shall this fellow live? Help, ho! What ho! Help! What hast thou done? I'll be revenged on the whole pack of you! You will *pay* for this! They say blood will have blood... Violence is no solution! Yes? #&%#&#%*#*&%!!!!! F***! No time to make a testament? Ugh! Aargh! Aaagghhh! I'm melting! Oof.. Oh! Did somebody knock? Later, dude... CU! What? Who? Me? Oh, s..t! ...amen! Eeek! Aacch! I hate it when that happens. One direct hit can ruin your whole day. Oh no! Not me! Ouch. Oh no, not again. Another one bites the dust. Goodbye. Help me! Farewell, cruel world. Oh man! Doough! This is the End, my only friend. It's all over. The fat lady sang. Why does everything happen to me? I'm going down. Crapola. Pow! Bif! Bam! Zonk! I should've listened to my mother... No... a Bud light! What was that noise? Mama said there'd be days like this. It's just one of those days... I see a bright light... Mommy? Is that you? I let you hit me! Sucker shot! I didn't want to live anyway. -- Hah haa! Missed me! Ha--- Was that as close as I think it was? Monsters rejoice: the hero has been defeated. It wasn't just a job it was an adventure! I didn't like violence anyway! I thought you liked me? Such senseless violence! I don't understand it. I think this guy's a little crazy. Somehow I don't feel like killing anymore. Help me! I am undone! Hey! Killin' ain't cool. This fell sergeant, Death, is strict in his arrest... The rest is silence. Guh! It's game over, man! You've run out of life. Thou art slain. Finish him! Trust me, I know what I'm doing... Die, mortal! Kill men i' the dark! What be these bloody thieves? Ho! Murder! Murder! O! I am spoil'd, undone by villains! O murderous slave! O villain! O, falsely, falsely murder'd! A guiltless death I die. AAAAAAAAAAAAAAAAAAAAAAAAHHHHHHH! Trust me. Dammit, this thing won't die! He hit me for HOW MUCH????? Look, behind you!!! Who fed steroids to that kobold? Don't worry, be happy! I don't believe this! Oops. Oups. Can't you take a joke? Well, I didn't much like this character, anyway... Oops, sorry... didn't mean to disturb you. I never get to have any fun! Stop! Cut it out! Don't worry. I've got a plan. It didn't look so tough. Run away! All clear, guys. AGAIN!?!?! I don't like this dungeon... Maybe this wasn't such a good idea. My God will protect me. You wouldn't dare! But what about my Parry Skill? Tumbling? Don't worry - I have Pilot-7. And I've *never* done you any harm. I don't understand. It should be dead by now. I'm heir to the crown. They wouldn't dare! Hey! Where's my stomach? My hands? Ha! That's the oldest trick in the book. Cover me. Watch this. And damn'd be him that first cries, 'Hold, enough!' I will not yield. ...but like a man he died. If you cut me down, I will only become more powerful. Well, at least I tried...? What could possibly have gone wrong? You die... What's with that weirdo with the teeth? Surrender? Never! I'm sure reinforcements will get here on time. They promised. Funny, didn't *look* like a cyberpsycho.... I have a very bad feeling about this. Do something, SCHMUCK! I feel I could cast 'Speak with Dead' and talk to myself. Oh, that's just a light wound. Ach, is doch nur 'ne Fleischwunde... I thought you were on MY side... Next time, try talking! Oh shit... I'll try to teleport again. Somebody get me a Rod of Resurrection... QUICK! Uhh... oh-oh... Gee, where'd everybody go? I see it coming...aaargllhhhh! {sough} What do you mean 'aaargllhhhh'? Hey man, I've paid for this. Ay! Ay! Ay! Ohe! Ohe! Ohe! Et tu, Caesar! Then fall, Brute! Even the best laid plans... Hey, not too rough! The Random Number Generator hates me! So when I die, the first thing I will see in heaven is a score list? Can't we talk this thing over? Wait! Spare me and I'll make you rich! Money is not a problem! I hate you! By the kind gods, 'twas most ignobly done! Mein Leben! Meine Lieder! I'm the hero of this story! I CAN'T die! I thought heroes were supposed to win! Gee... thanks. You've fallen and can't get up! 911? Sure don't look good... Oh No! Here I blow again! Hey - I've got lawyers. Thanks, I needed that. I AM toast!! Scheisse! Fatality! Brutality! Toasty! And you thought Tristan was unlucky... Just wait till I get my hands on the crook who sold me this crappy armor... All is lost. Monks, monks, monks! All my possessions for a moment of time! Don't let poor Nelly starve! Wally, what is this? It is death, my boy: they have deceived me. Everyone dances with the Grim Reaper. Adios. I'm going home, babe. I am innocent, innocent, innocent! Watch where you're pointing with that sword! You nearly... Hmm, some things are better wanted than had... And they told me it was not loaded. Of course I know what I am doing. It looked harmless. Hilfe, hilfe, hilfe! Look, dad! No head! Look! I'm flying! Think I'm gonna fall for that? I'll be back... as soon as I can. 3... 2... 1... Liftoff! My wallet? In your dreams! Yes! Yes! YES! YES! YY... AAARRRGGGHH! See you later, alligator! Up, up and awaaaayyy! Been nice knowing you. But I just got a little prick! And I just wanted that fancy suit of armour you were carrying... Hey guys, where are you? Hey look... ARCHERS! I can't probably miss... I don't care. I have a Scroll of Raise Dead. I don't care. I have a Ring of Regeneration. I have this dungeon at home, I know where everything is! This HAS to be an illusion. I attempt to disbelieve it. I thought you could be trusted. Never try to sneak in a plate mail. I'll never surrender. I'll use the Cheat Death option... I'm invincible! I'm death incarnate! Nothing can harm me! Hey, it was only a joke, all right? Hey, don't talk to me like that! I have rights, too! Just because you're big and ugly doesn't mean you can push ME around. Me first! Me first! Let me handle this. No problem. That's easy. Oh, shit. So what? Tell me this is an illusion... please! I hate the RNG... They need a twenty to hit me! I'm invincible! Trust me. CHARGE! What do you mean, how many hit points do I have? What do you mean, my GOI expired? Yeah, I knew it was dangerous, but I was thinking about the experience points. You mean you get to use the critical hit chart too? You'd have to be a GOD to smile after that hit! I'm not afraid of death. I just don't want to be there when it happens. I have such sweet thoughts. I pray you all pray for me. I shall hear in heaven. Is not this dying with courage and true greatness? I must sleep now. Nurse, nurse, what murder! What blood! I have done wrong! It is finished. That unworthy hand! That unworthy hand! I am dying. Oh, dear. I will not kneel. Strike! I have led a happy life. Dying, dying. I feel the flowers growing over me. Now it is come. Let me die to the sound of sweet music. I will now enter the Halls of Mandos. Ungrateful traitors! We perish, we disappear, but the march of time goes on forever. Youth, I forgive thee. Treason! Treason! Coward! Why did you not protect me? I am absolutely undone. It is well. I die hard, but am not afraid to go. Do let me die in peace. Nothing is real but pain now. Violent use brings violent plans. Soldier boy, made of clay, now an empty shell. Bodies fill the fields I see, the slaughter never ends. Life planned out before my birth, nothing could I say. Blood will follow blood, dying time is here. Never happy endings on these dark sets. No one to play soldier now, no one to pretend. Time for lust, time for lie, time to kiss your life goodbye. Greetings, Death, he's yours to take away. I was born for dying. The higher you walk, the farther you fall. Where's your crown, King Nothing? Exit: light - enter: night! New blood joins this earth... You labeled me, I'll label you, so I dub thee unforgiven. If you're gonna die, die with your boots on! There's a time to live, and a time to die, when it's time to meet the maker. Isn't it strange, as soon as you're born you're dying? Only the good die young, all the evil seem to live forever. I don't wanna die, I'm a god, why can't I live on? And in my last hour, I'm a slave to the power of death. Now I am cold, but a ghost lives in my veins. You got to watch them - be quick or be dead. Heaven can wait 'till another day. You'll take my life but I'll take yours too. We won't live to fight another day. As I lay forgotten and alone, without fear I draw my parting groan. Somebody please tell me that I'm dreaming! Can't it be there's been some sort of error? Is it really the end not some crazy dream? Life down there is just a strange illusion. Your body tries to leave your soul. I'm so tired of living, I might as well end today. Life, life! Death, death! How curious it is! Catch my soul 'cos it's willing to fly away! Flames? Not yet, I think. Someone call the Gendarmes! I split my brain, melt through the floor. And now the dreams end. Off to Never-Never Land! Death greets me warm, now I will just say goodbye. What is this? I've been stricken by fate! This can't be happening to me! Flash before my eyes: now it's time to die. You have been dying since the day you were born. No point asking who's to blame. But for all his power he couldn't foresee his own demise. My creator will lay my soul to rest. Was that worth dying for? Can you say you are proud of what you've done? But there are some things which cannot be excused. Why is it some of us are here just so that we'll die? The shortest straw, pulled for you. There's got to be just more to it that this or tell me why do we exist? I can't believe that really my time has come. Too much of a good thing, I guess... I really screwed up this time. Wow, what a trip! What is Time, friend or foe Time waits for none Running through your fingers like sand Taking us along to future unknown And all too sudden, like it or not We become part of the Land. Hah! I'm not dead yet. I still have five hit points. I don't understand. It should be dead by now. I rolled a 20. How could that be a miss? What the frell?! tome-235-src/lib/file/timefun.txt0000644000076400017500000000206311012107760014561 0ustar dgdgS:0000 E:0059 D:It's the witching hour! S:0100 E:0259 D:There may be Vampires around! S:0200 E:0459 D:Only ToME players are up now! S:0100 E:0459 D:It's really *very* late! S:0500 E:0558 D:Aren't you sleepy yet? S:0559 E:0559 D:It doesn't matter what you found! S:0600 E:0759 D:The sun is up. Time to have fun! S:0601 E:0800 D:Are you having fun yet? S:0800 E:0905 D:@$#$@$!%@$#%$@&$^#%@$!^#&#* S:0800 E:1059 D:You feel there is something special about this level. S:1100 E:1159 D:You see a maze of twisty passages, all alike. S:1155 E:1200 D:Are you having fun yet? S:1159 E:1200 D:This fortune is broken! S:1200 E:1205 D:This fortune is still broken! S:1200 E:1359 D:Uh oh, now you've done it! S:1400 E:1729 D:What did you do with the Phial? S:1730 E:1744 D:You need your chocolate vitamin! S:1745 E:1759 D:Tornado Warning! S:1759 E:1800 D:Night is coming. Danger! Danger! S:1700 E:1859 D:Take a Vampire out for dinner! S:2100 E:2159 D:Warp Factor Nine. Now! S:2200 E:2359 D:PARTY! S:2359 E:2359 D:It's almost the witching hour! tome-235-src/lib/file/sfail.txt0000644000076400017500000000102511012107760014205 0ustar dgdg32 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* rose petals dirty straw rusty metal cutlery small, furry animals assorted toy jewelry visions of merry, dancing gnomes old and dusty accounting records moldy crusts of bread grass wet mud smelly bilge water clean linens scrap metal rotting wood leaves small insects rainwater flowers perfumed water overcooked sausage twigs pine needles hard leather small bones feathers crumbling manuscripts fresh air stale, smelly air dust clay earth wood shavings tome-235-src/lib/file/book-101.txt0000644000076400017500000000010711012107760014340 0ustar dgdgnalo means shadow ure means sun ido means now nimir means shine or elf tome-235-src/lib/file/book-102.txt0000644000076400017500000000011211012107760014335 0ustar dgdggimli means star kadar means city izindi means starlight lomi means night tome-235-src/lib/file/book-103.txt0000644000076400017500000000015111012107760014341 0ustar dgdgattu means father aru means king bawiba means wind dulgi means black balik means ships daira means Earth tome-235-src/lib/file/book-104.txt0000644000076400017500000000017311012107760014346 0ustar dgdgnaur means fire mellon means friend Edain means Dunedain pedo means speak Pheriain means Halflings a minno means and enter tome-235-src/lib/file/book-105.txt0000644000076400017500000000020411012107760014342 0ustar dgdgbaraz means red Baruk means Axes dum means halls Khazad means Dwarves gabil means great aimenu means upon you gathol means fortress tome-235-src/lib/file/book-106.txt0000644000076400017500000000014211012107760014344 0ustar dgdgdori means land hrassa means precipice Danas means Green-elves dunna means black garma means wolf tome-235-src/lib/file/book-107.txt0000644000076400017500000000015011012107760014344 0ustar dgdgnazg means ring ghash means fire snaga means slave burz means black ronk means pool bubhosh means great tome-235-src/lib/file/book-200.txt0000644000076400017500000000001411012107760014335 0ustar dgdg4 34 21 6 0 tome-235-src/lib/file/book-201.txt0000644000076400017500000000001411012107760014336 0ustar dgdg4 49 11 3 0 tome-235-src/lib/file/book-202.txt0000644000076400017500000000001411012107760014337 0ustar dgdg4 50 34 4 0 tome-235-src/lib/file/book-203.txt0000644000076400017500000000001411012107760014340 0ustar dgdg4 60 56 3 0 tome-235-src/lib/file/chainswd.txt0000644000076400017500000000032311012107760014707 0ustar dgdg6 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* KILL, KILL, KILL! The Chainsword roars noisily! VROOM! VROOM! Kill, kill, kill, kill, kill, kill! Blood, blood, blood! Bloodbath! tome-235-src/lib/file/monfear.txt0000644000076400017500000000475211012107760014550 0ustar dgdg61 *********** BUFFER LINE ********************** DO NOT REMOVE ***************** says: 'I am too young to die.' says: 'Ok, ok! I get: no more pals.' screams: 'Help, ho!' screams: 'What ho! Help!' says: 'You will pay for this!' says: 'Violence is no solution!' says: 'I thought you liked me.' says: 'Such senseless violence! I don't understand it!' screams: 'Ho! Murder! Murder!' says: 'Look, behind you!' screams: 'Run away!' screams: 'Run to the hills! Run for your lives!' says: 'Wait! Spare me and I'll make you rich! Money isn't a problem!' says: 'I'll be back...' says: 'Hey -- I've got lawyers!' says: 'All my possession for a moment of time!' says: 'Hey, it was only a joke, all right?' says: 'Stop!' says: 'Cut it out, will you?' says: 'I will not kneel. Strike!' screams: 'Cowards! Why did you not protect me?' screams: 'Idiots! I am surrounded by incompetent idiots!' says: 'I don't wanna die, I'm a god, why can't I live on?' yells: 'Someone call the Gendarmes!' screams: 'Keep that lunatic away from me!' shouts: 'Drop that weapon, now!' says: 'Fool! You don't know what you're doing!' screams for help! begs for mercy. sobs. screams: 'Help! The maniac's murdering me!' says: 'Just what is it you want? Money? Babes? I can arrange it...' says: 'Wait! Let's make a deal!' says: 'Just can't stop this surmounting terror!' says: 'If there is a God, then why has he let me die?' says: 'I know where I'm going -- out!' says: 'No hope, no life, just pain and fear.' says: 'I am a fugitive, hunted down like game.' says: 'You'll live to regret this blasphemous offence!' says: 'All my life's blood is slowly draining away...' asks: 'Should we be fighting at all?' asks: 'What are we fighting for?' asks you: 'Can you say you are proud of what you've done?' says: 'Every minute I get weaker...' says: 'All my life I've run away...' says: 'All that I see, absolute horror!' says: 'I have fallen prey to failure.' says: 'Just leave me alone!' says: 'Please, save me!' says: 'You've won a battle, but I'll win the war!' says: 'You've won this round, next time it's *my* turn!' says: 'Another time, another battlefield, *my* victory.' says: 'I've got to keep running.' says: 'It's all so futile!' says: 'Cowards live to fight another day.' says: 'Life it seems will fade away, drifting further every day.' says: 'Emptiness is filling me, to the point of agony.' says: 'Cannot stand this hell I feel!' cries: 'Someone help me, oh please God help me!' cries: 'Please! I have a mate and six siblings!' cries: 'Mama, they try and break me!' tome-235-src/lib/file/speakpet.txt0000644000076400017500000000426711012107760014736 0ustar dgdg51 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* says: 'Oi, loan me 2 quid for a drink or I'll knock your head off!' says: 'Nice boots, mate.' says: 'Wow, isn't it dark down here?' says: 'I think I saw something move..' says: 'I really think I saw something move this time..' says: 'Phew, what's that smell?' says: 'There's slime all over the walls..' says: 'Isn't it dark down here?' says: 'Dungeon explorers should be *friends*, right?' says: 'I luv you, you luv me..' says: 'Are we there yet?' says: 'I'm hungry, look for a McMorgoth's..' says: 'Is there a 'Monster WC' vault on this level?' says: 'Not sure of max line length, but...' says: 'Excuse me, but do you know the way to vanilla?' says: 'I heard that the orcs just voted in a union' says: 'You gonna finish that?' says: 'You're gonna eat *that*?' says: 'Oops. I've got slime mold on my boot/claw/wisp of vapor.' says: 'It's a fantastic space. Knock in a skylight to open it up...' says: 'I love troll. Eat once, stay full for a week.' says: 'Your sword sure is shiny.' says: 'Hey! WATCH IT! You almost hit me.' says: 'So, you gonna do some abracadabra?' says: 'Keep that demon blade away from me.' says: 'Do the one where the ceiling collapses!' says: 'That oak tree ain't bad looking. Think it has a sister?' says: 'The One Ring. That sure is a silly name...' says: 'Groo and Stormbringer entered a bar...' says: 'If Lokkak asks, I'm not here.' says: 'buurrrrppp' says: 'Kill, kill, kill. Let's play chess.' says: 'Swordmanship: 8.4, Style: 9.0' says: 'When *I* was young, it was up stairs BOTH WAYS.' says: 'Lohengrin, schmohengrin.' says: 'Very fancy. Bet you can't do it again.' says: '10AU says I can behead that snaga!' says: 'I bet the chicks dig those boots.' says: 'Have you seen those Teletubbie uniques?' says: 'Were you looking for these?' says: 'Let's blitz 'em!' says: 'You da bomb!' says: 'Medusa: now, SHE is ugly.' says: 'Do you *really* like me?' says: 'ToME just switched to an HMO.' says: 'Do you like my outfit?' says: 'So, you're an auto-roller baby...' says: 'Where'd you put the snaga call?' says: 'I've split my reed. Bummer.' says: 'A wand of rockets. Yeah, that's the ticket.' says: 'It's Zymurgist's Time!' tome-235-src/lib/file/sample.txt0000644000076400017500000000015411012107760014372 0ustar dgdg3 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* line # 1 line # 2 line # 3 tome-235-src/lib/file/dead.txt0000644000076400017500000000456011012107760014013 0ustar dgdg #s_____#w #D,#w-#Wv#s___#w #s_d&#y*#D'"#w #W/#w #D`#w| #D,#W/#s?#D'#w | |#D'#w #s?#D'#w|#D'#w | #D.,#W~#w-#D'""'#w |#D.#w #D,#w| #sT#w --#y+#w-- #D,#W~#D'#w #D.,#W~#s:#w| #D`#W~\#w | #sL#w | #D,#Wv#s_#D.#w #W/#D'#w #D,#W/#D"#w | #sT#D`#W\#D.`#W\#D.#w |#D.#w |#W\#w | #D""'#w #s?#w--#Wv#D,#s?#w |#D'#w #s?#D,#w #W\#D.#w #W\#w #D`#W\#D.#w #sT#w #D`#W~#w-#W\#s_]#w | #D`#W\#D.#w #D"#W^~v#D.#w | #D"#W^#w-#W~v#w #D`#W\#s_#w #sT#D.#w #D"#W^~v#w #D.#s__#D.#w #W/#w #D``#w-#W~#w--| | |#D,#w #D"#s:#w| #D.#s___#D.#w #D.#w| #D`#W\#w #s?#W\#w #W/#w #W/#w #D"#s:&#w #D,#w-#Wv#s_#W/#w #D`#W\#D.#w #D`#W\#w| |#D'#w #D.,#W~#D'#w #D.#W/#D'#w #D`#W~\#D.#w #D`#W^#D'"#w #D,#W~#D'#w #D.#w| #s__#Wv#w-#W~#D''#w #W/#w #W/#D'#w #D,#w| #D.#w| #W/#w #sJ#w |#D'#w | ---------------------------------------------#W/#w #W/#s:#w------------------------- |#D'#w #D,#w| |#D'#w #D'#w #D`#w tome-235-src/lib/file/dam_xxx.txt0000644000076400017500000000070211012107760014560 0ustar dgdg9 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* %^s disintegrates into a fine mist! %^s splatters all over the floor. %^s explodes into tiny chunks. %^s's bones are crushed at the force of your blow! You almost squash %s into a pancake! Your weapons neatly slice %s into many little pieces. You cleave %s in half. %^s's head flies off in a wide trajectory. %^s is driven several feet into the ground under your blow! tome-235-src/lib/file/smeagol.txt0000644000076400017500000000205711012107760014544 0ustar dgdg27 ******** BUFFER LINE ******************* sniggers. grovels. picks his nose. pines for his precious. searches his pockets. eats some slimy creatures. mutters: 'My precious, wheres my precious?' shouts: 'No Master Hobbitsisisisis!' cries: 'The ring was ours for agesisisisis!' says: 'Smeagol sneeking! ME! Shneekingsisis!' screams: 'Nasty Hobbitsisisisis...' says: 'Come on, quickly, follow Smeagol' says: 'Every way is guarded, silly foolsis!' says: 'Nasty Bagginis, stole my precious.' says: 'She will kill them oh yes she will precious.' whines: 'Weees wants some fishises.' says: 'Whats has its got in its pocketses, hmmm?' whimpers: 'We've lost itses we have.' says: 'He'll eastus all the world if he getsitses it.' says: 'No food, no rest; Smeagol a SNEAK!' says: 'What a dainty little dish you will be for her.' says: 'Hobbitses always SOOOO Polite.' screams: 'Stop, Thief!' says: 'Makeses him drop his weapon precious.' grovels: 'He has only four fingers on the black hand.' growls: 'Not nice Hobbits, not sensible!' says: 'If you findesis it, give it us back.' tome-235-src/lib/file/timenorm.txt0000644000076400017500000000144311012107760014745 0ustar dgdgS:0000 E:0000 D:It is midnight. S:0001 E:0200 D:It is deep night. S:0300 E:0400 D:It is early morning, but still dark. S:0500 E:0544 D:It will be day soon. S:0545 E:0559 D:The sun is rising. S:0600 E:0614 D:The sun has risen. S:0615 E:0659 D:Morning has broken. S:0700 E:0859 D:It is early morning. S:0900 E:0959 D:It is midmorning. S:1000 E:1154 D:It is late morning. S:1155 E:1159 D:It is almost noon. S:1200 E:1200 D:It is noon. S:1201 E:1459 D:It is early afternoon. S:1500 E:1559 D:It is midafternoon. S:1600 E:1659 D:It is late afternoon. S:1700 E:1729 D:It will be night soon. S:1730 E:1759 D:The sun is setting. S:1800 E:1859 D:The night has begun. S:1900 E:2059 D:It is early night. S:2100 E:2358 D:It is late night. S:2359 E:2358 D:It is almost midnight. tome-235-src/lib/file/rumors.txt0000644000076400017500000002533011012107760014443 0ustar dgdg199 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* They say that you can't trust rumors. You have no more Black Potions of Death. They say that smart guys hang around at 1600'. They say that tough guys hang around at 1500'. They say that handsome guys hang around at 1200'. They say that a visit to 3250' can be quite an experience. They say that a visit to 3250' will only get you killed. Throw a Potion of Blindness at a monster and it cannot cast any spells! MAKE MONEY FAST! Find a Treasure Pit! Not satisfied with the artifacts you find? Then create your own! They say that Sauron has forged an all-powerful Ring. A good item will not corrode. They say that Nibelungs live in dark caves. Some weapons that slay dragons can be very deadly against them... Finding the Phial of Galadriel at 50' is nothing to be proud of. There are Black Market stores hidden deep in the dungeon, with COOL stuff! What a pity, you cannot read it! You will encounter a dark, tall stranger... A Mithril mail will not rust. An Adamantite mail will not rust. A Rusty Chain Mail cannot rust any further. If you are a mage, you will NOT want to find Raal's Tome of Destruction! You won't want to find Raal's Tome of Destruction! You won't want to find Raal's Tome of Destruction, unless you are a mage. A Wand of Death is useless against monsters that are tougher than you. A Wand of Death is of little use against foes that are dead already. Try taking off your armor before fighting a Gelatinous Cube! They say that only one sword can score *CRITICAL* hits. This rumor is not true. If you can fall like a feather, you need not care about gravity. They say that you should rejoice if you find a scroll labeled ""! You don't always have to kill everything you meet! If you can't beat it, leave it alone! An umber hulk can be a confusing sight. There *is* a good use for Potions of Detonations, Ruination and Death... Watch your step! It's a bad idea to throw away a Longsword (4d5). It's a bad idea to wield a Longsword (4d5). It's useless to bash monsters with bows - but there's one notable exception... Actually, Slime Mold Juice is not completely useless. Help me! I'm being held captive in a Vault at 2850'! Ever tried inscribing your armor {erodeproof}? Using a Morningstar in the evening has no effect. Why are you wasting time reading fortunes? There is a horrible, ghastly fate awaiting you... at 2700'! You can get the Longsword 'Ringil' by doing the following: You can protect yourself from Great Wyrms of Power by doing the following: Its true name is 249. You feel like someone's pulling your leg! AAAAAAAAAAARRRRRRRRGGGGHHHHHHH! Try inscribing the name of the first monster killed by it in the weapon! The richer the victim the happier the thief. Beware the Jabberwock, my son! The jaws that bite, the claws that catch... There's something bad about what you are carrying in your backpack... Thieves are more likely to appear if you are carrying a lot of money. Brand's sword, Werewindle, probably knows more than just one trick. They say that Scrolls of *Curse Weapon* can create powerful cursed artifacts. They say that the Chainsword makes monsters mad with its awful noise! They say that Ringil shines so brightly that it makes monsters angry. Orcs are mortally afraid of weapons that can slay them. There is a way to turn a Ring of Speed (-20) into a Ring of Speed (+20). There is no way to turn a Ring of Speed (-20) into a Ring of Speed (+20). VECNA LIVES!!! Cool guys can resist fire. They say that death incarnate wears heavy metal boots... You feel the Longsword (t) you are carrying in your backpack is special... If you start seeing red monsters, you have probably gained infravision. They say that the dungeon is deeper than the Abyss. When all else fails, read the instructions. No poison is immediately deadly. I have seen a Ring of Speed (+50) in the Black Market! Telepathy works like a two-way door. Elvish waybread might negate the effects of poison. Once uncursed, Calris will become a deadly weapon. If there's a stairway to hell, there must also be a stairway to heaven. You feel your luck is turning... If you thought Death swords were bad, wait until you meet Killer katanas! Overeating can be bad for your health if there are others nearby. Cave dwellers are accustomed to darkness and rarely enjoy bright light. A creature made of stone can be slain by a spell that turns stone to mud. It is often a good idea to throw items that you don't want to eat or drink. The faster you run the more food you will burn. Invisible monsters will often expose themselves if you drop items around you. They say that the key to killing tougher monsters is called "hit&run". They say that there is no such thing as free advice. Wearing an Amulet of Doom will take you into the Dungeons of Doom. You can often wrest one last charge from an empty wand if you try hard enough. Wands may recharge themselves if you leave them on the floor long enough. There is more than one way to deal with a locked door. Afraid of your valuables getting stolen? Carry more junk! Afraid of your money getting stolen? Invest it! If you hear something smash into splinters, you had better watch out. They say that you had better leave Greater hell-beasts alone. Selling unidentified potions to shopkeepers might be safer than quaffing them. Always look out for trapdoors on "special" feeling levels! There is a way to max out your stats with Potions of Charisma & Nexus. Unique opponents will recover their health faster than other creatures. "So when I die, the first thing I will see in heaven is a score list?" You're going into the morgue at midnight? How dare you! I will not buy that! A Potion of Detonations is also known as nitroglycerin... Operation OVERKILL has started now. There is a trap on this level! A weapon of Undead Slaying has all you need to kill a ghost. A weapon of Dragon Slaying may give you resistance to a dragon's breath attack. They say that only a Warrior will want to wear the Terror Mask. All that is shall come to an end - a dark day dawns for the gods. The One Ring is powerful, but will eventually destroy its owner. Having troubles with summoners? Door Creation is your friend! Stairway Creation may be slower than Teleport Level, but safer... Wands of Heal Monster are useful! Hint: ball spell, @....moo(o)ooo Guaranteed heal self - scenario: o'@, type c4c4c4c4 If it can't see you, it can't hurt you! If it can't see you, you might still be able to hurt it... I love you, you love me, we are a happy family! No animal is interested in sex if it is mortally scared. The butler did it. The butler is innocent. There is a plenty of Longswords around 1000'. Groo is your worst nightmare. Freddy Krueger is your worst nightmare. Groo is an idiot! Groo is a dolt! He is a fool! He has no mind! There are often stairways in graveyards: bad people are carried to hell... Only a god of Thunder could ride a lightning bolt! When the day of Ragnarok comes, Surtur will set the world afire... Surtur's accursed sword, Twilight, burns with everlasting fire. Groo may be as dumb as an amoeba, but he knows a good sword when he sees one. Weapons of Flame will light your way. Want to invest some money? Contact $crooge McDuck, 1300'. Need a loan? Contact $crooge McDuck, 1300'. They say that the gods get angry if you pray too much. For any remedy there is a misery. Poison will kill you slowly. Didn't you forget to pay? Death is just life's way of telling you you've been fired. They say that nobody can defeat his own ghost. A greedy genocide can be a fatal mistake, especially if you are low on hits. PLEASE ignore the previous rumor. There are scrolls that can be read only by mages. Some undead opponents will come back if defeated, more powerful than before! The answer is 42. Your mother wears army boots! One level further down somebody is getting killed, right now. Meet me at 1900' if you are a man. Bashing a creature may sometimes stun it. And now, Groo does what Groo does best! One Ring to rule them all, One Ring to find them. One Ring to bring them all and in the darkness bind them. Three Rings for the Elven-kings under the sky... Never carry a Potion of Detonations if there is a fire trap nearby! Laugh to scorn the power of man, for none of woman born shall harm thee! All hail thee that shalt be king hereafter! He who laughs at Groo's brains will find there is nothing to laugh about. A wise man always speaks too soon... Let us not dwell on possible bad fortunes! Appearance is only the frosting, not the cake! A feeling of Death flows through your body. Violence is no solution. Boots of Speed (+50) are no myth! You will need to Restore the Constitution if the Anarchists strike. Drain you of your sanity: Face the Thing That Should Not Be! Since by curse it came to me, accursed be this Ring! Each shall itch to possess the Ring, but none in it shall find pleasure! I know whatever was; whatever is, whatever shall be. Barney MUST die!!! Pudpadnoy Tooboothokoot is possessed by a demon known only as "It". They say that the One Ring has a very special curse. They say that alcohol is bad for your health. What if you DON'T give a name to the artifact you create..? They say that ancient battlefields are often haunted. Beware of pits that fill the whole level! Liar! I have not the gold! They say that the true name of wall monsters is 177. Never mind the Phial of Galadriel - the Phial of the Gods kicks its butt! A Ring of Speed? Phooey! Try looking for a Ring of *Speed*! Thisss cccity isss guilty... the crime isss life... the ssentence isss DEATH! If you hear heavy steps - watch out! A visit to the Zoo is educational: you meet many strange animals. What happens if you wear a Ring of Extra Ring Fingers (-2) {cursed}? Oremor nhoj em llik tsum uoy emag siht niw ot. If I cancel tomorrow the undead will thank me today. Hellfire will burn your soul... Call the Void needs a lot of room to cast... Why doesn't Detect Monsters show invisible monsters? 'Cos you can't see 'em! I'll tell you the truth, son: your soul's gonna burn in a lake of fire! There is a rare spellbook called [M$ PowerFools] {cursed} *** LOW HITPOINT WARNING! *** You cruelly stab the helpless, sleeping Software bug! Slab: Jus' say AarrghaarrghpleeassennononoUGH. You feel the Windows (95) on your hard disk is broken... Spirit, hatch that painted spirit of the lamb sparrow. Gone insane from the pain that sure they know: for who the flange sound? With time the child dissipates within, this blinking boy made badly. Not to be never, never not to see, so as to dub the thee unforgiven. Soon in order to fill up our lungs: the warmth of twenty dead women. The eternal death of eons of the foreigner of the lie can die not absolutely. Drain you of your sanity: in front do the thing that does not have to be. The opinion you had were salt expresses. They say that the dark mists of Morgoth can both bestow and remove the curse. tome-235-src/lib/file/dam_med.txt0000644000076400017500000000122411012107760014476 0ustar dgdg23 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* You kick %s in the belly! You head-butt %s. You push %s over. You broke %s's finger! You broke %s's toe! You kick %s in the shins. You stab %s in the arm. You stab %s in the leg. You hit %s over the head. You knee %s in the groin! You aim a high kick at %s's head. You stab %s in the ribs. You chop at %s's neck. You put a tight choke-hold on %s. You attempt to topple %s over. You punch %s. You attempt to poke %s in the eye! You twist %s's leg. You twist %s's arm. You bend %s's fingers. You punch %s in the kidneys! You smash %s with your elbow. You smash %s with your knee. tome-235-src/lib/file/silly.txt0000644000076400017500000000731711012107760014255 0ustar dgdg299 ******************BUFFER LINE -- DO NOT REMOVE!***************************** Borg Dalek Destructor Predator Wizard of Yendor Smurf Cosmic Horror Ultimate Unspeakable Lovecraftian Nightmare Space Invader Transformer Master of the Universe He-Man Pizza Worm Bogeyman Care Bear My Little Pony IRA Terrorist Nazi Klingon Cardassian Snark Luggage Killer penguin Were-penguin Giant were-penguin Peeping-Tom Jester Battlemech Invid Amazon Teenage Mutant Ninja Turtle Stork Hippo Roadrunner Fooglebird Ghoti Whale Apocalyptic Beast Anti-Christ Dark Avenger Evil Computer Finnish Sprayer Natas Poodle Fire Hydrant Multi-hued elephant Martian Purple alligator Space ship Miniature space fleet 6-feet tall elephant Insurance salesman Benji Magnet Squid Typewriter Manitou Miniature Shetland pony Munchkin Mad Scientist Keystone Kop Magnificent big-game hunter Wicked witch B-1 Bomber Superman Batman Boy Wonder Incredible Hulk Amazing Spider-Man Orphan Fifth columnist Secret agent Spy Dog catcher Vacuum cleaner Lawnmower Man Bloodletter of Khorne Buzzard Oyster Wombat Midget elephant Chameleon Dungeon Master Dungeon Keeper Beyonder Robocop Robocod Paradroid Dominatrix Paranoid Wagtail Great tit Pope Tribble Jedi knight Dark Jedi Master of Teras Kasi Vulcan Rancor Sarlacc Warbot Tailgunner Skinhead Paul Bunyan Machine Bungee Sumo wrestler Gargantuan sumo wrestler Karateka President King Lobo Trashman Teacher Cheshire Cat Mad Hatter March Hare Voodoo doll Rag doll Scarecrow Porcupine Stone idol Hacker Samurai Samurai Cat Phantom of the Opera X-man Wumpus Walrus Silver Surfer Chimpanzee Omnipotent being Reaperbot G. I. Joe Cobra Commander Dreadnok Autobot Battlemage Saboteur Master of Sinanju Cyborg Lemming Green Goblin Galactus Gooey Kablooie Prowler Iron Fist Stuka Mahdi Xeroc Catwoman Stupendous Man Lost boy Hunter-killer Mad butcher Vore Rotfish Heresiarch False prophet Emperor Tumtum Androgyne Thieving magpie Boast of England Red Rose Knight Unholy cow Q Red Baron Giddy goon Vogon Lizard King Hutt Puppet master Wookie Giant sandworm Muad' Dib Ent Huorn Werepotato Mindless one Alien queen Alligator man Ancient ape Ancient astronaut Astro-zombie Beast from 20000 fathoms Beast with a million eyes Black goat of the woods with a thousand young Behemoth Leviathan Big Bug Blob Khyberdemon Body snatcher Brain from Planet Ardus Scatologist Brain of Venus Brain that would not die Breath blaster Chickenstein's monster Creature from the Black Lagoon Loch Ness monster Creeping death Creeping unknown Fifty-foot woman Flumsh 4D-man Bride of Frankenstein Galaxy being Giant baby Giant chicken Krazy Kat Giant celery stalk Gorilla witch Great god Porno H-dial monster Heap Love lotus Herman munster Highest intelligence H-man Hound of the Baskervilles Wizball ID monster Mancubus Arch-vile Pain elemental I-ball Killdozer Killer tomato Lurking fear Madball M.U.L.E. Magnetic monster Mixed-up zombie Hunchback of Notre Dame Monster that challenged the World Monster from green hell Morlock Queen Kong Robot Kong Mecha-Godzilla Ghidhrah Saucerman Ethereal Space Brain Floating brain of Hitler Stay Puft Marshmallow Man Supercow Swamp Thing Thing Teenage Frankenstein Teenage Werewolf Terror from the year 5000 Triffid Tripod Xenophobic man Undying monster Unknown terror Unnamable Womaneater E.T. Toxic Avenger Onslaught Pacman Paradroid Bantha Ass-headed fish Wizard of Oz Juggernaut Cheshire Cat Tauntaun Heretic Other Uncanny Libido Super-ego Boy Blunder Big nothing Parademon Zelda Super Mario Great Giana Sister Magnetic man Pink elephant Elephant man Great Unknown Lurking unknown Cenobite Cheerleader Model T-1000 Terminator Whippoorwill Moon Maniac Killer Clown Stocking Strangler Torture Doctor Beast of the Black Forest Demon of the Belfry Sex Beast Sunday Morning Slasher tome-235-src/lib/file/book-0.txt0000644000076400017500000000716311012107760014207 0ustar dgdg Mordekainen's Magical Compendum of Deep Thought. ------------------------------------------------ If they ever come up with a swashbuckling School, I think one of the courses should be Laughing, Then Jumping Off Something. It takes a big man to cry, but it takes a bigger man to laugh at that man. The people in the village were real poor, so none of the children had any toys. But this one little boy had gotten an old enema bag and filled it with rocks, and he would go around and whap the other children across the face with it. Man, I think my heart almost broke. Later the boy came up and offered to give me the toy. This was too much! I reached out my hand, but then he ran away. I chased him down and took the enema bag. He cried a little, but that's the way of these people. Dad always thought laughter was the best medicine, which I guess is why several of us died of tuberculosis. Maybe in order to understand mankind, we have to look at the word itself: "Mankind". Basically, it's made up of two separate words - "mank" and "ind". What do these words mean? It's a mystery, and that's why so is mankind. Ambition is like a frog sitting on a Venus Flytrap. The flytrap can bite and bite, but it won't bother the frog because it only has little tiny plant teeth. But some other stuff could happen and it could be like ambition. I'd rather be rich than stupid. We tend to scoff at the beliefs of the ancients. But we can't scoff at them personally, to their faces, and this is what annoys me. Probably the earliest flyswatters were nothing more than some sort of striking surface attached to the end of a long stick. As the evening sky faded from a salmon color to a sort of flint gray, I thought back to the salmon I caught that morning, and how gray he was, and how I named him Flint. When I was a kid my favorite relative was Uncle Caveman. After school we'd all go play in his cave, and every once in a while he would eat one of us. It wasn't until later that I found out that Uncle Caveman was a bear. Why do there have to be rules for everything? It's gotten to the point that rules dominate just about every aspect of our lives. In fact, it might be said that rules have become the foot-long sticks of mankind. If I had a mine shaft, I don't think I would just abandon it. There's got to be a better way. If I had a nickname, I think I would want it to be "Prince of Weasels", because then I could go up and bite people and they would turn around and go, "What the-?" And then they would recognize me, and go, "Oh, it's you, the Prince of Weasels." It's amazing to me that one of the world's most feared diseases would be carried by one of the world's smallest animals: the real tiny dog. Sometimes life seems like a dream, especially when I look down and see that I forgot to put on my pants. I bet it was pretty hard to pick up girls if you had the Black Death. It's fascinating to think that all around us there's an invisible world we can't even see. I'm speaking, of course, of the World of the Invisible Scary Skeletons. Whenever I hear the sparrow chirping, watch the woodpecker chirp, catch a chirping trout, or listen to the sad howl of the chirp rat, I think: Oh boy! I'm going insane again. He was the kind of man who was not ashamed to show affection. I guess that's what I hated about him. The next time I have meat and mashed potatoes, I think I'll put a very large blob of potatoes on my plate with just a little piece of meat. And if someone asks me why I didn't get more meat, I'll just say, "Oh, you mean this?" and pull out a big piece of meat from inside the blob of potatoes, where I've hidden it. Good magic trick, huh? tome-235-src/lib/file/book-1.txt0000644000076400017500000000642311012107760014206 0ustar dgdg Mordekainen's Magical Compendum of Deep Thought, Vol. 2 ------------------------------------------------------- It makes me mad when people say I turned and ran like a scared rabbit. Maybe it was like an angry rabbit, who was running to go fight in another fight, away from the first fight. Perhaps, if I am very lucky, the feeble efforts of my lifetime will someday be noticed, and maybe, in small way, they will be acknowledged as the greatest works of genius ever created by Man. Sometimes I think I'd be better off dead. No, wait, not me, you. If you ever catch on fire, try to avoid looking in a mirror, because I bet that will really throw you into a panic. Children need encouragement. If a kid gets an answer right, tell him it was a lucky guess. That way he develops a good, lucky feeling. The crows seemed to be calling his name, thought Caw. If your friend is already dead, and being eaten by vultures, I think it's okay to feed some bits of your friend to one of the vultures, to teach him to do some tricks. But only if you're serious about adopting the vulture. Broken promises don't upset me. I just think, why did they believe me? One thing vampire children have to be taught early on is, don't run with a wooden stake. Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff. I think my new thing will be to try to be a real happy guy. I'll just walk around being real happy until some jerk says something stupid to me. I hope some animal never bores a hole in my head and lays its eggs in my brain, because later you might think you're having a good idea but it's just eggs hatching. Whenever you read a good book, it's like the author is right there, in the room talking to you, which is why I don't like to read good books. What is it about a beautiful sunny afternoon, with the birds singing and the wind rustling through the leaves, that makes you want to get drunk? Instead of a trap door, what about a trap window? The guy looks out it, and if he leans too far, he falls out. Wait. I guess that's like a regular window. If I ever get real rich, I hope I'm not real mean to poor people, like I am now. Most of the time it was probably real bad being stuck down in a dungeon. But some days, when there was a bad storm outside, you'd look out your little window and think, "Boy, I'm glad I'm not out in that." Sometimes you have to be careful when selecting a new name for yourself. For instance, let's say you have chosen the nickname "Fly Head." Normally you would think that "fly Head" would mean a person who has beautiful swept-back features, as if flying through the air. But think again. Couldn't it also mean "having a head like a fly"? I'm afraid some people might actually think that. I hope that after I die, people will say of me: "That guy sure owed me a lot of money." The tired and thirsty prospector threw himself down at the edge of the watering hole and started to drink. But then he looked around and saw skulls and bones everywhere. "Uh-oh," he thought. "This watering hole is reserved for skeletons." Anytime I see something screech across a room and latch onto someone's neck, and the guy screams and tries to get it off, I have to laugh, because what is that thing. I hope life isn't a big joke, because I don't get it. tome-235-src/lib/file/book-2.txt0000644000076400017500000000702111012107760014202 0ustar dgdg Mordekainen's Magical Compendum of Deep Thought, Vol. 3 ------------------------------------------------------- I think my new thing will be to try to be a real happy guy. I'll just walk around being real happy until some jerk says something stupid to me. When you're going up the stairs and you take a step, kick the other leg up high behind you to keep people from following too close. I wonder if angels believe in ghosts. I don't understand people who say life is a mystery, because what is it they want to know? I think people tend to forget that trees are living creatures. They're sort of like dogs. Huge, quiet, motionless dogs, with bark instead of fur. Sometimes I think the world has gone completely mad. And then I think, "Aw, who cares?" And then I think, "Hey, what's for supper?" If a kid asks where rain comes from, I think a cute thing to tell him is "God is crying". And if he asks why God is crying, another cute thing to tell him is "Probably because of something you did". Contrary to popular belief, the most dangerous animal is not the lion or tiger or even the elephant. The most dangerous animal is a shark riding on an elephant, just trampling and eating everything they see. As I bit into the nectarine, it had a crisp juiciness about it that was very pleasurable- until I realized it wasn't a nectarine at all, but a HUMAN HEAD!! Anytime I see something screech across a room and latch onto someone's neck, and the guy screams and tries to get it off, I have to laugh, because what _is_ that thing?! If you define cowardice as running away at the first sign of danger, screaming and tripping and begging for mercy, then yes, Mister Brave Man, I guess I am a coward. Blow ye winds, like the trumpet blows, but without that noise. The face of a child can say it all, especially the mouth part of the face. When I heard that trees grow a new "ring" for each year they live, I thought, we humans are kind of like that; we grow a new layer of skin each year; and after many years we are thick and unwieldy from all our skin layers. It's too bad that whole families have been torn apart by something as simple as wild dogs. Even though he was an enemy of mine, I had to admit that what he had accomplished was a brilliant piece of strategy. First, he punched me, then he kicked me, then he punched me again. To me, truth is not some vague, foggy notion. Truth is real. And, at the same unreal. Fiction and fact and everything in-between, plus some things I can't remember, all rolled into one big "thing". This is truth, to me. If you're ever stuck in some thick undergrowth, in your underwear, don't stop and start thinking of what other words have "under" in them, because that's probably the first sign of jungle madness. Sometimes the beauty of the world is so overwhelming, I just want to throw back my head and gargle. Just gargle and gargle, and I don't care who hears me, because I am beautiful. We used to laugh at Grandpa when he'd head off to go fishing. But we wouldn't be laughing when he'd come back with some whore he picked up in town. I think in one of my previous lives I was a mighty king, because I like people that do what I say. A man doesn't automatically get my respect. He has to get down in the dirt and beg for it. People think it would be fun to be a bird because you could fly. But they forget the negative side, which is the preening. When I think back on all the blessings I have been given in my life, I can't think of a single one, unless you count that rattlesnake that granted me all those wishes. tome-235-src/lib/file/book-4.txt0000644000076400017500000000034711012107760014210 0ustar dgdgAsh nazg durbatuluk, ash nazg gimbatul, ash nazg thrakatuluk agh burzum-ishi krimpatul. ------------------------------- One Ring to rule them all, One Ring to find them, One Ring to bring them all, And in the darkness bind them. tome-235-src/lib/file/book-6.txt0000644000076400017500000003012511012107760014207 0ustar dgdg Artifact Lore, Vol. I Ancient Weapons --------------------- The Longsword 'Ringil' (4d5) (+22,+25) The Sword of Fingolfin (High-Elf). When wielded it will haste its wielder. It is a blade of such deathly cold that it shines bright white acting as a permanent light and delivering cold criticals. It slays evil, demons, undead and trolls. Allows you to resist cold, regenerate mana and hit points more quickly with no extra food consumption. Also lets you see invisible and be immune to paralyzation. Being made of white eog, it is capable of casting Ice Storms. The Longsword 'Anduril' (3d5) (+10,+15) [+5] The Sword of Aragorn the Dunadan Ranger and King. It increases your strength to match true Kingly strength, increases armour class by +5. Being the 'Flame of the West' it delivers heat criticals and defends against fire. It slays evil, orcs and trolls. It allows you to see invisible and avoid paralyzation. So near to the element fire is the blade, that Fire Balls can be cast from its searing surface. The Lead-filled Mace 'Grond' (9d9) (+25,+25) [+10] The Hammer of the Underworld, this is Morgoth's chief weapon. It weighs so much that it slows anything of less than godly status. It is so awesome that it aggravates all that see it. It makes it's wielder see all and resist all. It slays all of Morgoths personal creations of orcs, trolls, and demons and it executes dragons doing five times normal damage against them, (it can kill all but a very few dragons in one mighty blow!). Plus it causes impact criticals that cause earthquakes and it can tunnel through solid granite walls! The Two-Handed Sword 'Gurthang' (3d6) (+13,+17) This Iron of Death belonging to Turin Turambar, made of black eog, was designed to slay Dragons (and Trolls), doing five times normal damage against dragons. It gives you the strength to wield it, regenerates your hit points and mana at no extra cost and allows you to be free of paralyzation. The Two-Handed Sword 'Mormegil' (6d7) (0,0) [-20] This evil black sword is heavily cursed, slowing its wielder and aggravating all that see it... The Broadsword 'Arunruth' (2d5) (+20,+12) This Sword of Accuracy rarely misses. It increases the wielders dexterity, saves from falls, slays orcs and demons, and protects from paralyzation. The Broadsword 'Glamdring' (2d5) (+10,+15) This High-Elven sword (mate to Orcrist) was made during foul orc wars of long ago. It was once wielded by Gandalf the Grey Wizard. It slays orcs and other evil, shining bright red continuously, which aids searching and decreases food consumption. Its element is flame, and it gives resistance to flame to the wielder, and slays those who have not. The Broadsword 'Orcrist' (2d5) (+10,+15) This High-Elven sword (mate to Glamdring) was made during foul orc wars of long ago. It was once wielded by Thorin Oakenshield the Dwarf-King-Under-the-Mountain. It slays orcs and other evil, shining bright white continuously, which decreases food consumption, plus making the wielder more stealthy. Being of the element frost, it protects from cold, and slays non-cold based creatures. The Broadsword 'Aeglin' (2d5) (+12,+16) This High-Elven sword, is the long, lost and forgotten third mate to Orcrist and Glamdring. It is also the most powerful. Like Glamdring and Orcrist, made during the Orc-wars, it slays Orcish-kind, shining bright blue continuously, which decreases food consumption and aiding searching. Being of electric element, it delivers lightning criticals, which it also defends against. The Long Bow 'Belthronding' (+20,+22) (+3) This Noldorin black-yew bow, belonged to the greatest elven archer, Beleg Cuthalion, who was slain by his own blade, by his best friend Turin Turumbar. The bow increases stealth and dexterity, and rarely missed its target. The Long Bow of Bard (+17,+19) This bow of men gives free action and increased dexterity. The Light Crossbow 'Cubragol' (+10,+14) This amazing bow of fire hastes its wielder and brands all bolts with its element. The Bastard Sword 'Calris' (5d4) (-20,+20) This sword of Lungorthin the Balrog of White Flame, is an evil cursed sword that needs great mastering to control its powers. If mastered it can execute dragons, slay other evil including demons and trolls, this naturally aggravates them. Also it gives its wielder far greater internal constitution. The Spear 'Aeglos' (3d6) (+15,+25) [+5] This Snow-thorn of Gil-Galad the High-Elf, delivers very deep cold-criticals, while protecting you from cold and increasing your armour class. Being elvish it naturally slays orcs and trolls. It increases the wielders wisdom, slows their digestion and frees their actions from holding forces of evil, also casting Frost Balls occasionally. The Spear 'Nimloth' (1d6) (+11,+13) (+3 to stealth) This elven spear, branded with frost, allows its wielder to creep up on the Undead and Slay them. The Dagger 'Angrist' (2d5) (+10,+15) [+5] This Iron-cleaver of Beren the Edain, increases and sustains dexterity, increases you protection, prevents paralyzation and slays orcs and trolls. The Small sword 'Sting' (1d6) (+7,+8) This small weapon is one of the most powerful weapons of Westernesse. Once wielded by Bilbo and Frodo Baggins (of Hobbit kind), Sting slays undead, evil, and orcs and also shines a continuous, bright blue. It increases the wielder's physical statistics and its piercing blue light lights up those normally invisible to sight. The Great Axe of Durin (4d4) (+10,+20) [+15] This Wonderful Dwarven Axe was once wielded by Durin the Deathless (Father and King of the Dwarves), gives its wielder high protection, executes dragons, while resisting fire and acid. It slays demons, trolls and orcs, frees action and increases constitution. The War Hammer of Aule (5d5) (+19,+21) [+5] This is the great war hammer of the deity, Aule the Smith. Forged in his great furnaces it delivers Shock criticals causing five times normal damage to those not resistant to this element, and even then it executes dragons, slays evil, demons and undead. It resists fire, cold, acid and lightning and allows you to see invisible and be free of paralyzation. It increases its wielder's wisdom so that one may choose wisely what to slay with it. Truly an awesome weapon. The Two-Handed Great Flail 'Thunderfist' (3d6) (+5,+18) This weapon of Electricity and Flame, delivers shock and heat criticals, delivering five times or three times normal damage against the respective types of creatures, also slays animals, trolls and orcs. It also gives the wielder great strength. The Morningstar 'Bloodspike' (2d6) (+8,+22) This Bloody weapon slays animals, trolls, and orcs. It allows you to see invisible creatures, as well as giving the wielder great strength. The Quarterstaff 'Nar-i-vagil' (1d10) (+10,+20) This fiery staff slays animals and resists fire, doing times fire criticals. It also increases the wielders intelligence. The Blade of Chaos 'Doomcaller' (6d5) (+18,+28) [-50] This deadly blade calls doom to all who see it, this naturally aggravates them. It shows you wherever a creature is, be it invisible or blocked by a wall. It resists all elements and executes dragons, slays evil, animal, orc and troll. It delivers cold criticals, but severely impedes its wielders health. The Three Daggers, 'Narthanc', 'Nimthanc', 'Dethanc' (1d4) (+4,+6) These elemental daggers of flame, frost, and electricity respectively do their elemental criticals, and defend against them. They also cast bolts of their element often. The Dagger of Rilia (2d4) (+4,+3) This ancient, and poisonous dagger casts stinking clouds with great frequency. The Dagger 'Belangil' (2d4) (+6,+9) This nimble weapon of cold increases the wielder's dexterity and regeneration, while slowing digestion. Being of dark origins it see alls invisible and casts frost balls. The Battle Axe of Balli Stonehand (3d6) (+8,+11) [+5] This Dwarvish Battle axe protects from elements, falls and the invisible. It slays all demons, trolls and orcs, giving even dwarves the stealth, strength and constitution to do so, never letting holding spells affect its use in a fight. The Battle Axe 'Lotharang' (2d8) (+4,+3) This petty-dwarvish axe, slays orcs and trolls, increasing strength and dexterity. For those of faint heart it also cures medium wounds and cuts. The Morningstar 'Firestar' (2d6) (+5,+7) [+2] This weapon of flame casts fire balls. The Quarterstaff 'Eriril' (1d10) (+3,+5) This staff of people who believe in the power of mind over matter, greatly increases wisdom and intelligence and gives the power to identify. It also sees invisible and slays all evil. The Longsword 'Elvagil' (2d5) (+2,+7) This joyful sword increases dexterity, charisma and stealth. It protects from falls and the invisible, and slays orcs and trolls. The Glaive of Pain (9d6) (+0,+30) This weapon is designed to cause pain to anything without discrimination. The Lance of the Eorlingas (3d8) (+3,+21) This heavy lance is suprisingly easy to control, allowing slaughter of orcs, trolls and other evil (visible or not). The Broad Axe 'Barukkheled' (2d6) (+13,+19) This beautiful axe slays orcs, trolls, giants and other evil (visible or not), while greatly increasing the wielders internal constitution. The Trident of Wrath (3d8) (+16,+18) This extremely heavy and dangerous trident belonging to the greatest Maiar spirit, Osse, slaughters evil and undead without mercy wherever they hide, and increases the wielder's strength and dexterity. The Scimitar 'Haradekket' (2d5) (+9,+11) This sword of the south slays the invisible undead, evil and animals, and increases the wielder's dexterity. In addition, the magically enhanced blade is rumored to give extra attacks in combat. The Lochaber Axe 'Mundwine' (3d8) (+12,+17) This strong friend in battle, slays evil and resists the elements. The Cutlass 'Gondricam' (1d7) (+10,+11) This defender increases the wielders dexterity. The Sabre 'Careth Asdriag' (1d7) (+6,+8) This lightning-quick blade slays dragons, giants, trolls, orcs, and animals. The Rapier 'Forasgil' (1d6) (+12,+19) This glittering ice-blade also slays animals as well as lighting the way. The Executioner's Sword 'Crisdurian' (4d5) (+18,+19) This executer slays evil, invisible undead, dragons, giants orcs and trolls. The Flail 'Totila' (3d6) (+6,+8) (+2) This flaming flail slays evil in stealth. It also casts confusion. The Short sword 'Gilettar' (1d7) (+3,+7) This roguish sword gives better regeneration and slower digestion, slaying all animals with uncanny speed. The Katana 'Aglarang' (8d4) (+0,+0) This super-light and sharp katana greatly increases the wielders dexterity and sustains it. Rarely does the wielder get less than four attacks a round with it, and often as many as six! tome-235-src/lib/file/book-7.txt0000644000076400017500000001300511012107760014206 0ustar dgdg Artifact Lore, Vol. II Ancient Armor ---------------------- Adamantite Plate Mail 'Soulkeeper' [40,+20] This amazing armour protects your soul from cold, and from life level loss. It is also capable of fully healing you. The Pair of Hard Leather Boots of Feanor [3,+20] These amazing boots belonging to Feanor the High-Elf, haste the wearer permanently and temporarily in combat, making him or her stealthy as well. The Pair of Soft Leather Boots 'Dal-i-thalion' [3,+15] These amazing boots of agility, ensure free action in combat, greatly increasing your dexterity and ensuring that you will never become less agile. It is said that they can also make you more confident and brave. Full Plate Armour of Isildur [25,+25] This armour of the Dunedain Lord, Isildur, Resists. The Large Metal Shield of Anarion [5,+20] This shield Resists and sustains your stats. The Set of Cesti of Fingolfin (+10,+10) [5,+20] These amazing gauntlets increase the wearers dexterity, and slay creatures at (+10,+10). They will never be stopped by paralyaztion and they also resist damage. They occasionally grow magical spikes that can be fired causing great damage. The Set of Leather Gloves 'Cambeleg' (+5,+5) [1,+15] These Gloves of Might, increase strength and constitution. They never allow their wearer to be paralyzed, and help his/her slaying abilities. The Set of Leather Gloves 'Cammithrim' [1,+10] These Gloves of Light, sustain dexterity and give off light so brightly that they can cast magic missiles almost endlessly. The Set of Gauntlets 'Paurhach' [2,+15] These Fists of Fire resist fire and can cast fire bolts. The Set of Gauntlets 'Paurnimmen' [2,+15] These Fists of Frost resist cold and can cast frost bolts. The Set of Gauntlets 'Pauraegen' [2,+15] These Fists of Lightning resist lightning and can cast lightning bolts. The Set of Gauntlets 'Paurnen' [2,+15] These Fists of Water resist acid and can cast acid bolts. The Set of Gauntlets 'Camlost' (-11,-12) [2,+0] (-5) The Empty Hand aggravates monsters, and greatly reduces fighting ability. Named after the empty hand of Beren that once clasped a Silmaril. Mithril Chain Mail of Belegennon [28,+20] This Chain Mail Resists and makes you stealthy. The Iron Helm of Dor-Lomin [8,+20] This is the Dragon Helm of Turin Turambar. It is rumored that its wearer will never die in combat. It resists all and sees all, and increases all fighting stats. The Iron Helm of Holhenneth [5,+10] This helm of brilliance and vision, greatly increases your mental prowess. It allows you to see all that is hidden, casting detection spells at frequent intervals. The Iron Helm of Gorlim [5,+10] (-125) This unhappy helm of betrayal ruins thought and sight. Soft Leather Armour 'Hithlomir' [4,+20] (+4) This dark-misty leather resists the elements and melds the wearer into the background with incredible stealth. Leather Scale Mail 'Thalkettoth' (+3) [11,+25] This light leather scale mail is suprisingly good at dodging attacks, and is resistant to acid. Often nicknamed Blade-Turner. Chain Mail of Arvedui [14,+15] This wonderful chain mail belonged to the last king of Arnor. It resists the elements and increases strength and charisma. The Hard Leather Cap of Thranduil [2,+10] This acid resistant leather is a thinker's cap. Increasing wisdom and intelligence. The Metal Cap of Thengel [3,+12] This cap of the Rohan King Thengel, gives kingly wisdom and charisma. The Steel Helm 'Hammerhand' [6,+20] This warriors' helm increases the fighting stats. The Large Leather Shield of Celegorm [4,+20] A quality shield of Resistance. The Pair of Metal Shod Boots of Thror [6,+20] These Dwarf-king boots are ideal for combat, increasing strength and constitution. The Cloak 'Colluin' [1,+15] This cloak of resistance even casts extra resistance spells that can defend against poison. The Cloak 'Holcolleth' [1,+4] This mage cloak increases intelligence and wisdom and casts spells to make monsters lose their concentration and fall to sleep. The Cloak 'Colannon' [1,+15] This Gate-cloak, teleports the player at will, and gives stealth so as to avoid awkward situations. The Iron Crown of Beruthiel [0,+20] (-125) This crown once belonged to the Cat-Queen of Gondor, who disdained armed combat. Giving you cat like vision, and sight within sight, it allows its wearer to be free of combat, and infact finding armed combat beyond his or her means. The Iron Crown of Morgoth This awesome artifact is a plain iron crown, mounted with three jewels that capture the eternal light of the Trees of the Valar, Teleperion and Laurelein. These Jewels were made by the Noldorian High-Elf, Feanor who named them the Silmarils. Their beauty, unsurpassed, drove Morgoth to steal these jewels (with the aid of Ungoliant the Unlight). The crown then, maximises all you stats, sustains all your stats, is a permanent light source and allows the wearer to see all. tome-235-src/lib/file/book-8.txt0000644000076400017500000000322111012107760014206 0ustar dgdg Artifact Lore, Vol. III Ancient Magical Tools ----------------------- The Amulet of Ingwe (+3) This amulet belonged to the high king of the Vanyar, the most powerful of the High Elves. It gives resistance, and greatly increases your wisdom and charisma. It gives you good infravision, see invisible, and it casts a x5 strength dispel evil. The Amulet of Carlammas (+2) This fiery amulet protects from flame, casts protection from evil and increases your constitution. The Phial of Galadriel (+4) This wonderful object is an infinite light source, and once identified it can light up rooms. The Three Elven Rings Made by Celebrimbor, Elf of the Girth-I-Mirdain. These Rings of Power are of awesome power, and are very rare. The Ring of Power 'Narya' (+1) Celeborn gave this to Cirdan who gave it to Gandalf. The least powerful of the Elven rings is of the element fire. And as such makes you completely immune to fire. It is also capable of casting very powerful fire balls. It increases all your stats by one. It also protects from from life draining and helps you regenerate. The Ring of Power 'Nenya' (+2) This was kept by Galadriel. As Narya is to fire, Nenya is to Frost... Plus two to all your stats. The Ring of Power 'Vilya' (+3) This was kept by Gil-galad who gave it to Elrond. This gives immunity to lightning and resists poison. Plus three to all your stats. Casts very powerful lightning balls. Rumors exist of a Ring of Power known as the One Ring, which was made to master the other Rings of Power. Its powers are what legends are made of.... tome-235-src/lib/file/book-9.txt0000644000076400017500000001626611012107760014224 0ustar dgdgThe Filthy street urchin is an uncommon monster, occurring at surface depths. He is laughably weak, just a little bit dangerous, and has no magical powers. The Scrawny cat is a somewhat rare animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Scruffy little dog is a somewhat rare animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Farmer Maggot is a unique monster, occurring at surface depths. He is somewhat weak, somewhat dangerous, and has no magical powers. The Blubbering idiot is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Boil-covered wretch is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Village idiot is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Pitiful looking beggar is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Mangy looking leper is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Squint eyed rogue is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Singing, happy drunk is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Aimless looking merchant is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Mean looking mercenary is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Town Guardsman is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Grey mold is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Grey mushroom patch is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Giant yellow centipede is a common monster, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Giant white centipede is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The White icky thing is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Clear icky thing is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Giant white mouse is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Large brown snake is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Large white snake is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Small kobold is a common monster, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Kobold is a common monster, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The White worm mass is a common animal, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Floating eye is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Rock lizard is a common animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Jackal is a common animal, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Soldier ant is a common monster, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Fruit bat is a common animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Shrieker mushroom patch is a common monster, occurring at surface depths. It is laughably weak, not at all dangerous, and has an inkling of magical powers. The Blubbering icky thing is a common monster, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Metallic green centipede is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Novice warrior is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Novice rogue is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Novice priest is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has small magical powers. The Novice mage is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has rudimentary magical powers. The Yellow mushroom patch is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The White jelly is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Giant green frog is a common animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Giant black ant is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Salamander is a common animal, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The White harpy is a common animal, occurring at surface depths. She is laughably weak, not one little bit dangerous, and has no magical powers. The Blue yeek is a common animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Grip, Farmer Maggot's dog is a unique animal, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. Fang, Farmer Maggot's dog is a unique animal, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Green worm mass is a common animal, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. tome-235-src/lib/file/monspeak.txt0000644000076400017500000002475111012107760014737 0ustar dgdg# This is the file for allowing uniques to speak their "own" lines. # Deleting this file will have no real effect on the game. Modifying it may # cause STRANGE unique lines to come up if the format's wrong, but shouldn't # crash anything. The format goes like so: # # N:45:whoever this is # 3 # says bravado line 1 # says bravado line 2 # says bravado line 3 # 2 # says fear line 1 # says fear line 2 # # The number after the N: is the "monster index number" obtained from # r_info.txt. The text field after that number isn't actually used--it's # just there to help humans edit the file. The numbers on lines by # themselves say the number of "bravado" and "fear" lines. Getting these # numbers wrong won't crash anything, but will produce strange lines. # # Two or more monsters can share lines; just put their N: lines in a # contiguous block. # # To stop a certain monster from having unique lines, put a # in front of # its N: line. # # Have fun with this! --Matt G N:8:Farmer Maggot 3 says, 'I'm carrying CASH!' smirks, 'You wouldn't kill me, would you?' gleefully shows off a nifty object he just bought. 2 screams, 'Don't hurt a poor helpless hobbit!' yells, 'Where are my vicious dogs when I need them?' N:63:Smeagol 27 sniggers. grovels. picks his nose. pines for his precious. searches his pockets. eats some slimy creatures. mutters, 'My precious, wheres my precious?' shouts, 'No Master Hobbitsisisisis!' cries, 'The ring was ours for agesisisisis!' says, 'Smeagol sneeking! ME! Shneekingsisis!' screams, 'Nasty Hobbitsisisisis...' says, 'Come on, quickly, follow Smeagol' says, 'Every way is guarded, silly foolsis!' says, 'Nasty Bagginis, stole my precious.' says, 'She will kill them oh yes she will precious.' whines, 'Weees wants some fishises.' says, 'Whats has its got in its pocketses, hmmm?' whimpers, 'We've lost itses we have.' says, 'He'll eastus all the world if he getsitses it.' says, 'No food, no rest; Smeagol a SNEAK!' says, 'What a dainty little dish you will be for her.' says, 'Hobbitses always SOOOO Polite.' screams, 'Stop, Thief!' says, 'Makeses him drop his weapon precious.' grovels, 'He has only four fingers on the black hand.' growls, 'Not nice Hobbits, not sensible!' says, 'If you findesis it, give it us back.' 3 says, 'Don't hurt us, mastersisis.' says, 'Poor Smeagol, poor Smeagol.' says, 'No AH! Don't hurtsis us.' N:135:Mughash the Kobold Lord 4 says, 'I may be a kobold, but I can beat you!' says, 'Feel my wrath, fool!' says, 'Death and destruction make me happy!' snickers evilly. 2 screams, 'Cowards! Why did you abandon me?' begs for mercy. N:137:Wormtongue, Agent of Saruman 6 whines and sniggers. leafs through 'Cowards Monthly.' whispers nasty things. says, 'I'll slaughter you slowly...' giggles as he fingers his knife. says, 'Now, you shall taste my wrath!' 3 begs you to spare his miserable life. whines, 'This is not my fault!' screams, 'Help! Help!' N:138:Robin Hood, the Outlaw 6 eyes your money pouch covetously. says, 'You look like Nottingham's man to me!' says, 'I bet I can shoot better than you...' says, 'Give 'til it hurts!' says, 'Don't force me to put an arrow in your skull...' says, 'Kevin Costner has soiled my name!' 3 begs you to spare his life. says, 'But I'm a GOOD guy, really!' says, 'Money? Sure, take it all back!' #N:169:Brodda, the Easterling #N:291:Ulfast, Son of Ulfang N:180:Orfax, Son of Boldor N:237:Boldor, King of the Yeeks 5 wonders aloud about the quality of your weapon. spouts torrents of taunts. shouts, 'YEEK! YEEK! YEEK!' says, 'I'll teach you to respect yeeks!' says, 'Feel lucky, punk?' 2 sobs, 'I didn't MEAN it...' whimpers and moans. N:200:Hobbes the Tiger 4 says, 'Why were people put here? TIGER FOOD!' says, 'Yum! Adventurer sandwiches!' says, 'I ate Calvin, now I'll eat YOU!' says, 'I'll make your short life nasty and brutish!' 1 yells, 'Ow! Get me back to the comics!' N:140:Lagduf, the Snaga N:186:Grishnakh, the Hill Orc N:215:Golfimbul, the Hill Orc Chief N:260:Ufthak of Cirith Ungol N:314:Shagrat, the Orc Captain N:315:Gorbag, the Orc Captain N:330:Bolg, Son of Azog N:350:Ugluk, the Uruk N:356:Lugdush, the Uruk N:373:Azog, King of the Uruk-Hai 19 fingers his blade and grins evilly. snickers, 'Now, I strike a blow for *our* side!' says, 'Orcs don't get no respect... I'm gonna change that!' calls your mother nasty names. says, 'I'll bet your innards would taste real sweet...' belches and spits. scratches his armpits. says, 'I love the smell of fresh blood.' says, 'Yeeha! Another idiot to slaughter!' hawks a loogie in your direction. farts thunderously. wonders aloud how many experience points you're worth. says, 'I love being psychotic!' says, 'My brain's on fire with the feeling to kill!' says, 'I shall torture you slowly.' calls you a scum-sucking pig-dog. says, 'I shall break you!' says, 'You're not so tough, loser!' says, 'Heh-heh, heh-heh, killing people is cool.' 6 screams, 'Hey, orcs have rights too!' says, 'You're just prejudiced against orc-kind, aren't you?' begs, 'Spare me and I'll get you Ringil! Really!' says, 'Next time, I'm bringing more Uruks with me!' says, 'Don't hate me because I'm ugly!' whimpers and grovels. N:382:Mime, the Nibelung 4 says, 'Wagner misrepresented us!' says, 'I'll mess up all your stuff!' says, 'Give me the Rheingold, or die!' hums 'Ride of the Valkyries.' 1 screams, 'Help! Murder! Murder!' #N:392:Sangahyando of Umbar #N:380:Angamaite of Umbar #This next may be unnecessarily evil... :-] N:393:It 6 says, 'Nyah, nyah, betcha can't find me!' says, 'Come get some!' magically summons mighty undead opponents! chuckles evilly. magically summons Cyberdemons! summons special opponents! 2 howls, 'I'll be back!' whimpers, 'They said this invisibility thing was better than it is!' N:441:Barney the Dinosaur 7 says, 'Cooperation! That's the magic word!' mutters, 'I *hate* those Teletubbies...' says, 'Won't you be my friend?' says, 'Let's all sing a HAPPY SONG!' mugs for the camera. simpers disgustingly. chews up a 'Tinky Winky' doll. 3 begs, 'Don't! Think of the children!' screams, 'But I'm a big TV star!' sobs, 'All right! I apologise! I really really do!' N:505:Groo the Wanderer 4 says: 'A fray! A fray!' says: 'Groo does what Groo does best!' says: 'All right, you savage, mindless creature. Prepare to meet your equal!' says: 'I will slay you, and hack you, and waste you, and destroy you!' 3 says: 'Did I err?' says: 'I did not think Groo could be frightened...' says: 'I need no aid! Groo is beyond help!' N:934:Fangorn the Treebeard 6 says: 'The night stretches out on the Isengard!' says: 'Trolls are strong, Ents are STRONGER!' says: 'Saruman will now stop using his axes on the trees...' says: 'have you seen some Ent women ?' says: 'I will crush all those burarum ... those orcs!' says: 'I am totally of the side of nobody since nobody is totally of my side...' 0 N:732:Bull Gates 10 says, '640K should be enough for ANYBODY!' says, 'Buy Windows 2000; the filesystem rocks!' says, 'Linux? Never heard of it...' says, 'Resistance is futile--you will be assimilated.' says, 'NT is the solution for ALL your needs!' hacks out some code and calls it a Service Pack. says, 'We don't have a monopoly... Mac OS still exists!' wonders if he should buy a small country. says, 'Where will we let you go today? The Recycle Bin!' cackles diabolically. 3 sobs, 'OK, Linux doesn't suck. Let me live?' screams, 'Is megalomania THAT bad?' apologises for MS-DOS. N:733:Santa Claus 8 says, 'Ho ho ho! You're gonna die!' says, 'You're gettin' COAL in your stocking!' says, 'On Smasher, on Crasher, now dash away all!' chortles sadistically. says, 'You're on the Naughty List!' says, 'No presents for you, ever!' says, 'I'll sic my man-eating reindeer on you!' says, 'I hate Christmas so much that I've gone psychotic!' 3 sobs, 'Think of the children you'll disappoint!' sobs, 'No, Virginia, there isn't... not any more...' attempts to buy you off with offers of goodies. N:764:Uriel, Angel of Fire N:765:Azriel, Angel of Death N:769:Gabriel, the Messenger 7 says, 'Repent, evildoer!' says, 'My righteousness shall cleanse you!' says, 'Don't EVER steal from the collection plate!' says, 'God may love you, but *I* don't!' says, 'I shall smite thee with extreme prejudice!' says, 'Hope you like eternal damnation!' says, 'Verily, it is too late for thee.' 3 screams, 'Help! I am undone!' says, 'The Most High hath ordained this; I must follow.' screams, 'My God, my God, why hast thou forsaken me?' N:850:Carcharoth, the Jaws of Thirst N:846:Fenris Wolf N:840:Draugluin, Sire of All Werewolves 8 barks and bellows frighteningly! says, 'Oh good, another chew toy!' says, 'Yummy! I was getting tired of chicken...' lets out an earsplitting howl. drools all over the dungeon. lifts his leg at the nearest wall. says, 'Bad adventurer! No more living for you!' snarls and howls. 3 cringes and whimpers. says, 'Look, I promise I won't bite the mailman anymore!' says, 'Hey, put that rolled-up newspaper down!' N:830:Cantoras, the Skeletal Lord N:831:Mephistopheles, Lord of Hell N:818:The Mouth of Sauron N:819:Klingsor, Evil Master of Magic N:804:Vecna, the Emperor Lich N:844:Feagwath the Undead Sorceror N:856:Gothmog, the High Captain of Balrogs N:860:Sauron, the Sorcerer 12 brags, 'My power is beyond compare!' snorts, 'A mere mortal dares challenge my might? HA!' says, 'Not another one! I just finished chewing on the last!' wonders aloud how many XP you're worth. leafs through 'Evil Geniuses For Dummies'. mutters, 'Another darn loser to kill...' says, 'Angband shall claim your remains!' says, 'Another 12 skulls and I get that reward from the Boss!' yawns at your pathetic efforts to kill him. says, 'Minions, slaughter this fool!' says, 'Set thine house in order, for thou shalt die...' says, 'I'm no god... God has MERCY!' 2 screams, 'This CAN'T be happening!' shouts, 'Kill me if you want, the Boss will getcha!' N:928:Mathilde, the Science Student 3 waves. wishes you luck. skips along happily. 1 is surrounded by the purple aura of the RNG. Touch at your peril. N:861:Dark God, the Mighty Coder of Hell 6 says 'Hullo'. emits a low 'hmmmm'. screams 'I came from the Hells for YOU!' laughs out loudly. mutters something about bugs. asks you about the new version. 1 screams 'ToME rules!'. N:969:Princess 4 cries. screams 'Help me !!!'. whines 'I need your help, great hero...'. implores you to help her. 1 screams 'I am too young to die!'. N:970:Merton Proudfoot, the lost hobbit 1 whines 'Please help me, noble hero! My leg is broken, and I cannot walk.' 1 whines 'No, please don't hurt me!' N:1039:Improv, the mighty MoLD 2 screams 'Your code is ugly!' mutters something about bugs. 1 screams 'ToME rules!'. tome-235-src/lib/file/elvish.txt0000644000076400017500000000176611012107760014415 0ustar dgdg216 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* adan ael in agl ar aina alda al qua am arth amon anca an dune anga anna ann on ar ien atar band bar ad bel eg brag ol breth il brith cal en gal en cam car ak cel eb cor on cu cui vie cul curu dae dag or del din dol dor draug du duin dur ear ech or edh el eith elen er ereg es gal fal as far oth faug fea fin for men fuin gaer gaur gil gir ith glin gol odh gond gor groth grod gul gurth gwaith gwath wath had hod haudh heru him hini hith hoth hyar men ia iant iath iaur ilm iluve kal gal kano kel kemen khel ek khil kir lad laure lhach lin lith lok lom lome londe los loth luin maeg mal man mel men menel mer eth min as mir mith mor moth nan nar naug dil dur nel dor nen nim orn orod os pal an pel quen quet ram ran rant ras rauko ril rim ring ris roch rom rond ros ruin ruth sarn ser eg sil sir sul tal dal tal ath tar tath ar taur tel thal thang thar thaur thin thol thon thor on til tin tir tol tum tur uial ur val wen wing yave tome-235-src/lib/file/rart_f.txt0000644000076400017500000000464211012107760014374 0ustar dgdg85 The Bag of Tricks Kenault's Cantrip Generator The Deck of Wild Magic Baalzebub's Tormented Box Baalzebub's All-seeing Servant Boccob's Unfinished Works The Gem of Fire The Gem of Ice The Gem of Venom The Gem of Knowledge The Gem of Rage The Gem of Hate The Gem of Wisdom The Gem of Ghosts The Shrunken Head of Nightmares Raal's Voodoo Doll of Revenge The Mirror of Alternate Dimensions The Ebon Cube of Darkness The Diamond Prism of Light Gruumsh's Bottle of Death The Devil's Pentagram Mordekainen's Sneaking Eye Kelek's Practical Joke Kelek's Wormhole Machine Tenser's Alteration Manual Raal's Tome of Unconventional Warfare The Tome of Collected Weird Magic The Pendulum of Orcus Raal's Black Candle Mordekainen's Pocket Magician Benetar's Death Ray Experiment Valdarbon's Automatic Alchemist Lloth's Ceremonial Dagger The Tome of Elven Household Magic a Parchment titled ``Demigods and their Uses'' a Parchment titled ``Magic for the Layman'' Balrilbon's Bag of Wondrous Tricks Bumganir's Bag of Magic Toys The Skull of Ancient Wisdom Benetar's Mana Battery Benetar's Portable Plague Gamenlon's Summoning Manual Balrilbon's Soulgem The Lost Works of Kenault The Crystal Ball of Godly Sights The Box of Many Wonders Baalzebub's Tormented Skullcap The Jester's Cap of Insanity The Bottomless Bottle a Parchment titled ``Planar Travel Made Easy'' The Wand Construction Kit The Clay Tablets of Antiquity Raal's Tormented Spirits Tenser's Mechanical Magician Boccob's Magical Mish-mash The Grail of Kenault a Parchment titled ``Household Magic'' a Parchment titled ``Tenser's Last Words'' The Hand of Vecna The Skull of Vecna The Eye of Vecna The Crystal Ball of The Witch-King of Angmar a Parchment titled ``Secrets of the Gnomish Wizards'' The Medallion of Good Will The Immortal Skull of Benetar Heward's Excellent Experimental Earmuffs Bigby's Big Book of Brutality The Cunning Plan of Zog a Parchment titled ''Immortality For Dummies'' Raistlin's Ready Ranger Tenser's Torch of Spontaneous Combustion Mordenkainen's Mysterious Mind-Masher a Parchment titled ''Famous Last Words'' Jor's Buckler of Missile Attraction Jor's Compendium of Strange Behaviour Agannazar's Antique Acorn Cathal's Corrupting Cymbal Pytar's Portable Pandemonium The Toenail of Vecna Jor's Book of Impossible Occurences a Parchment titled ''Finer Points of Munchkinism'' Agannazar's Altruistic Assassin Tenser's Top-Heavy Teaspoon Olive's Omnipotent Ostrich Cathal's Collapsible Crutch tome-235-src/lib/file/rart_s.txt0000644000076400017500000000226611012107760014411 0ustar dgdg85 a Bag a Shiny, Black Box a Deck of Cards a Rusty, Slimy Box an Eyeball a Red Tome a Red Gem a Blue Gem a Green Gem a White Gem an Orange Gem a Black Gem a Gray Gem a Translucent Gem a Shrunken Head a Voodoo Doll a Mirror a Black Cube a Prism a Black Bottle a Pentagram a Glass Eyeball something weird a Portable Vortex a Green Tome a Black Tome a White Tome a Pendulum a Black Candle a Tiny Doll a Black Staff a Tiny Doll a Slimy Dagger a Gray Tome a Parchment a Parchment a Bag a Bag a Human Skull a Blue Box a Gray Bottle an Orange Tome a Shiny Gem an Ancient Gray Tome a Crystal Ball a Golden Box a Skullcap a Jester's Cap a Broken Bottle an Arcane Parchment many Small Wooden Sticks some Clay Tablets a Smoky Vial a Doll some Multi-colored Clay a Clay Jar an Arcane Parchment an Arcane Parchment a Decayed Hand a Decayed Skull a Decayed Eye a Large Crystal Ball an Arcane Parchment a Medallion a Jewel-Encrusted Skull some Earmuffs a Battered Book a Small Note a Parchment a Small Figurine a Torch a Rune a Singed Parchment a Holed Buckler a Red Book an Acorn a Cymbal a Mechanical Music-Box a Toenail a Torn Book a Greasy Parchment a Blackened Figurine a Heavy Teaspoon an Avian Figurine a Crutch tome-235-src/lib/file/dam_lots.txt0000644000076400017500000000116411012107760014715 0ustar dgdg18 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* You stab %s in the stomach. You cut off %s's hand. You chop down on %s's shins. You gave %s a deep gash. You gave %s a gigantic bruise. You cut off %s's arm! You cut off %s's leg! You stab %s in the heart. You slash at %s face. You throw %s down at the ground. You attempt to strangle %s. You grab %s's head and twist it. You knocked out several of %s's teeth! You broke some of %s's ribs! %^s spins around dizzily after your blow. %^s sputters at your tight, choking hold! %^s grunts under the force of your blows. %^s screams shrilly in fear. tome-235-src/lib/file/news.txt0000644000076400017500000000343011012107760014065 0ustar dgdg#G #W ~ ~~~ ~~~ ( #G #G ======/ ===== #W ~~ ) ~~ ) #G === === === #G / // / __ \ #W )~ #r,.#W~ ( (#G // || \\ // #G // | | | | #W _#r,-"####`-^ #W ) #G || || || ||==: #G || | | | | #W ,#D###########r`W='#D###W`.#W () #G || || || || #G \\_// \ -- / #W ,#D#######################D###W:#r,=. #G || || || \\=== #G \_/ ===== #W /.#D###W,".#D#####W,".#D###########r"#W##\ #G #ov2.3.5#G #W ,-. _,-= /"._ ,-. #w ," #W `:' `:#D#####W[JW] ,. #G #W," `," `=._ `" -#w; #G The #W\#D#####W;"' V \#W __,-. ,-=. #W / " `-. #w / #GTroubles of #W `" `-.#W__,-""._," "--," >-=- #W ,-"`. #w _' #G Middle Earth#w "._ #W` _/ _," #y __ #w "=.". _," #y _,' `-. #w `._,=-._ _,-. _._ ,"._," #y ,'_,'Y`-. `. #w "-." \,-. -" `-" #y / / ,' `. \ #w `- #y / / / \ \ #w One Ring to rule them all, Maintained by darkgod #y f f f l l#w One Ring to find them. #o darkgod@t-o-m-e.net #y t t t j j #y \ \ \ / / #w One Ring to bring them all #ohttp://www.t-o-m-e.net #y \ \ \._ / /#w and in the Darkness bind them. #y `_`-._J-' / #y `-.___,-' In the Land of Mordor, where the Shadows lie. [J.R.R. Tolkien] . tome-235-src/lib/file/bravado.txt0000644000076400017500000001046511012107760014535 0ustar dgdg104 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* cackles evilly. cackles diabolically. says: 'Surrender, miserable flea!' says: 'Come get some!' says: 'Let's rock!' laughs devilishly. says: 'Flee while you can, gnat!' says: 'You are about to die, maggot!' says: 'Read your prayers!' hisses: 'Die!' says: 'You don't have a chance, moron!' says: 'Fear my wrath, fool!' says: 'Feel my fury, dolt!' says: 'Groo is a genius, compared to you!' gives you a contemptuous glance. says: 'Prepare to meet your Maker, fool!' says: 'Perish, mortal!' says: 'Your puny efforts make me laugh!' says: 'Drop dead, wimp!' says: 'You should have fled while you had the chance.' screams: 'Die by my hand!' says: 'Your last wish, punk?' says: 'Your death shall be a slow, painful one.' says: 'Your head shall be my next trophy.' screams: 'You are DOOMED!' grins sadistically. says: 'This dungeon shall be your TOMB!' laughs fiendishly. says: 'Your fate is sealed, worm.' says: 'Resistance is useless.' says: 'Hell shall soon claim your remains.' says: 'Thou shalt repent of thy cunning.' says: 'Verily, thou shalt be one dead cretin.' says: 'Surrender or die!' says: 'Savor thy breath, it be thine last.' says: 'Prepare to die, miscreant!' says: 'You're history, dude!' says: 'Feeling lucky, punk?' says: 'You're toast!' says: 'You're dead meat.' says: 'Make my day.' says: 'I shall flatten you!' says: 'I could spare you, but why?' says: 'Take this, you sissy!' says: 'Nothing can save you now!' says: 'This dungeon ain't big enough for the both of us.' says: 'I'm gonna break your face!' says: 'I hope you enjoy pain!' says: 'Give me your best blow!' says: 'Draw, if you are a man!' says: 'A time to die, fool!' bellows frighteningly! says: 'You will never leave this dungeon alive!' says: 'You'll leave this dungeon only in a wooden box!' says: 'Your mother wears army boots!' says: 'Drop that weapon, NOW!' says: 'Life ain't for you, and I'm the cure!' says: 'Resistance is futile. You will be terminated.' says: 'Sight and smell of this, it gets me going.' says: 'Victim is your name and you shall fall.' says: 'Stepping out? You'll feel our hell on your back!' says: 'Now I will waste my hate on you.' says: 'Don't tread on me!' says: 'So be it! Threaten no more!' says: 'Kill for gain or shoot to maim, but I don't need a reason.' says: 'You'll die as you lived, in a flash of the blade.' says: 'You'd better stand cos there's no turning back.' says: 'I just want to see your blood, I just want to stand and stare.' says: 'I've been looking so long for you; you won't get away from my grasp.' says: 'I'm coming after you; you can kiss your arse good-bye.' says: 'It's official; you suck!' sings: 'I hate you, you hate me, we're a helluva family.' says: 'A mere mortal dares challenge *ME*?!' says: 'There is no escape and that's for sure.' says: 'This is the end; I won't take any more.' says: 'Say good-bye to the world you live in.' says: 'You've always been taking, but now you're giving.' says: 'My brain's on fire with the feeling to kill.' says: 'Don't try running away, because you're the one I'll find.' says: 'I was looking for you to start up a fight.' says: 'My innocent victims are slaughtered with wrath and despise!' says: 'I have found you, and there is no place to run.' says: 'My blood lust defies all my needs.' says: 'And damn'd be him that first cries: Hold, enough!' says: 'I can smell your blood, human!' says: 'Has your folly led to this?' wonders aloud how many experience points you're worth... says: 'Pride yourself on this, that you were slain by a champion.' thunders: 'May heaven have mercy on your soul, for I will have none.' screams for your blood! sighs: 'They send a poorer grade of adventurers down each year than the last.' says: 'Your life-blood will baptise my blade!' shouts: 'You will serve me in Valhalla!' snickers: 'Mommy's not here to save you now!' says: 'You're almost not worth killing... almost!' leaps towards you with death in its eye. sings: 'Cuts yer if ye stand, shoot yer if ye run.' says: 'Another adventurer? I just got through picking my teeth with the last.' says: 'Your two ears will decorate my belt.' says: 'I love all that blood.' says: 'I don't want to hurt you. I only want to kill you.' says: 'I like killing people, because it's so much fun.' screams: 'I'm out to destroy and I will cut you down!' says: 'Bring it on!' tome-235-src/lib/file/dam_none.txt0000644000076400017500000000122711012107760014673 0ustar dgdg22 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* You scratch %s. You give %s a nasty bruise. You stub %s's toe. You jab %s in the ribs. You almost poked your eye out while fighting %s! You made %s's nose bleed. You almost slipped while fighting %s. %^s doesn't even flinch! You accidentally hurt yourself while fighting %s. You slap %s. %^s slips and falls. %^s laughs at your wild swings. You pull at %s's hair. You punch %s in the nose. You pull at %s's ear. %^s growls at you. %^s is very, very annoyed! You scream an insult at %s. %^s makes a nasty face. You scowl at %s. %^s gnashes his teeth. %^s lets out a gurgling laugh. tome-235-src/lib/file/smeagolr.txt0000644000076400017500000000021711012107760014722 0ustar dgdg3 ******** BUFFER LINE ************** says: 'Don't hurt us, mastersisis.' says: 'Poor Smeagol, poor Smeagol.' says: 'No AH! Don't hurtsis us.' tome-235-src/lib/file/news2.txt0000644000076400017500000000343011012107760014147 0ustar dgdg#G #W ~ ~~~ ~~~ ( #G #G ======/ ===== #W ~~ ) ~~ ) #G === === === #G / // / __ \ #W )~ #r,.#W~ ( (#G // || \\ // #G // | | | | #W _#r,-"####`-^ #W ) #G || || || ||==: #G || | | | | #W ,#D###########r`W='#D###W`.#W () #G || || || || #G \\_// \ -- / #W ,#D#######################D###W:#r,=. #G || || || \\=== #G \_/ ===== #W /.#D###W,".#D#####W,".#D###########r"#W##\ #G #ov2.3.5#G #W ,-. _,-= /"._ ,-. #w ," #W `:' `:#D#####W[JW] ,. #G #W," `," `=._ `" -#w; #G The #W\#D#####W;"' V \#W __,-. ,-=. #W / " `-. #w / #G Tales of #W `" `-.#W__,-""._," "--," >-=- #W ,-"`. #w _' #G Middle Earth#w "._ #W` _/ _," #y __ #w "=.". _," #y _,' `-. #w `._,=-._ _,-. _._ ,"._," #y ,'_,'Y`-. `. #w "-." \,-. -" `-" #y / / ,' `. \ #w `- #y / / / \ \ #w One Ring to rule them all, Maintained by darkgod #y f f f l l#w One Ring to find them. #o darkgod@t-o-m-e.net #y t t t j j #y \ \ \ / / #w One Ring to bring them all #ohttp://www.t-o-m-e.net #y \ \ \._ / /#w and in the Darkness bind them. #y `_`-._J-' / #y `-.___,-' In the Land of Mordor, where the Shadows lie. [J.R.R. Tolkien] . tome-235-src/lib/file/book-10.txt0000644000076400017500000001656011012107760014271 0ustar dgdgThe Large yellow snake is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Cave spider is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Wild cat is an uncommon monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Smeagol is a unique monster, occurring at surface depths. He is laughably weak, not at all dangerous, and has no magical powers. The Green ooze is an uncommon monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Poltergeist is a common undead monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Metallic blue centipede is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Giant white louse is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Black naga is a common monster, occurring at surface depths. She is laughably weak, not one little bit dangerous, and has no magical powers. The Spotted mushroom patch is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Silver jelly is an uncommon monster, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Yellow jelly is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Scruffy looking hobbit is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Giant white ant is a common monster, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Yellow mold is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Metallic red centipede is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Yellow worm mass is an uncommon animal, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Clear worm mass is an uncommon animal, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Radiation eye is a common monster, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Cave lizard is a common animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Novice ranger is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has an inkling of magical powers. The Novice paladin is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has an inkling of magical powers. The Blue jelly is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Creeping copper coins is an uncommon animal, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Giant white rat is a common monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Blue worm mass is a common animal, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Large grey snake is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Bullroarer the Hobbit is a unique monster, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Novice mage is an uncommon monster, occurring at surface depths. He is laughably weak, just a small bit dangerous, and has rudimentary magical powers. The Green naga is a common monster, occurring at surface depths. She is extremely weak, just a small bit dangerous, and has no magical powers. The Blue ooze is a common monster, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Green glutton ghost is a common undead monster, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Green jelly is a common monster, occurring at surface depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Large kobold is a common monster, occurring at surface depths. It is extremely weak, just a little bit dangerous, and has no magical powers. The Skeleton kobold is a common undead monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Grey icky thing is a common monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Disenchanter eye is an uncommon monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Red worm mass is a common animal, occurring at surface depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Copperhead snake is a common animal, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Purple mushroom patch is an uncommon monster, occurring at surface depths. It is laughably weak, moderately dangerous, and has no magical powers. The Novice priest is an uncommon monster, occurring at surface depths. He is laughably weak, just a little bit dangerous, and has small magical powers. The Novice warrior is an uncommon monster, occurring at surface depths. He is laughably weak, just a small bit dangerous, and has no magical powers. The Novice rogue is an uncommon monster, occurring at surface depths. He is laughably weak, just a small bit dangerous, and has no magical powers. The Brown mold is a common monster, occurring at surface depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Giant brown bat is a common animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Novice archer is an uncommon monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has an inkling of magical powers. The Creeping silver coins is an uncommon animal, occurring at surface depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Snaga is a common orc, occurring at surface depths. He is laughably weak, just a little bit dangerous, and has no magical powers. The Rattlesnake is a common animal, occurring at surface depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Cave orc is a common orc, occurring at surface depths. He is extremely weak, just a little bit dangerous, and has no magical powers. tome-235-src/lib/file/book-11.txt0000644000076400017500000001655611012107760014277 0ustar dgdgThe Wood spider is a somewhat rare animal, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Manes is an uncommon monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Bloodshot eye is a somewhat rare monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Pink naga is an uncommon monster, occurring at surface depths. She is extremely weak, just a little bit dangerous, and has no magical powers. The Pink jelly is a common monster, occurring at surface depths. It is very weak, somewhat dangerous, and has no magical powers. The Giant pink frog is a common animal, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Green icky thing is an uncommon monster, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Zombified kobold is a common undead monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Lost soul is an uncommon undead monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has rudimentary magical powers. The Dark elf is an uncommon monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has an inkling of magical powers. The Night lizard is an uncommon monster, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Mughash the Kobold Lord is a unique monster, occurring at surface depths. He is extremely weak, moderately dangerous, and has no magical powers. Wormtongue, Agent of Saruman is a unique monster, occurring at surface depths. He is very weak, not at all dangerous, and has remarkable magical powers. Lagduf, the Snaga is a unique orc, occurring at surface depths. He is very weak, somewhat dangerous, and has no magical powers. The Brown yeek is a common animal, occurring at surface depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Novice ranger is a common monster, occurring at surface depths. He is laughably weak, just a little bit dangerous, and has an inkling of magical powers. The Giant salamander is a common animal, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Green mold is an uncommon monster, occurring at surface depths. It is extremely weak, moderately dangerous, and has no magical powers. The Skeleton orc is a common undead monster, occurring at surface depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Novice paladin is an uncommon monster, occurring at surface depths. He is laughably weak, just a little bit dangerous, and has an inkling of magical powers. The Lemure is a somewhat rare monster, occurring at surface depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Hill orc is a common monster, occurring at surface depths. He is extremely weak, just a small bit dangerous, and has no magical powers. The Bandit is an uncommon monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. The Yeti is a somewhat rare animal, occurring at surface depths. It is extremely weak, not one little bit dangerous, and has no magical powers. The Bloodshot icky thing is a somewhat rare monster, occurring at surface depths. It is laughably weak, not at all dangerous, and has no magical powers. The Giant grey rat is a common animal, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Black harpy is a common animal, occurring at surface depths. She is laughably weak, not one little bit dangerous, and has no magical powers. The Orc shaman is a common orc, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has rudimentary magical powers. The Baby blue dragon is an uncommon dragon, occurring at surface depths. It is extremely weak, not at all dangerous, and has no magical powers. The Baby white dragon is an uncommon dragon, occurring at surface depths. It is extremely weak, not at all dangerous, and has no magical powers. The Baby green dragon is an uncommon dragon, occurring at surface depths. It is extremely weak, not at all dangerous, and has no magical powers. The Baby black dragon is an uncommon dragon, occurring at surface depths. It is extremely weak, not at all dangerous, and has no magical powers. The Baby red dragon is an uncommon dragon, occurring at surface depths. It is extremely weak, not at all dangerous, and has no magical powers. The Giant pink ant is an uncommon monster, occurring at surface depths. It is laughably weak, somewhat dangerous, and has no magical powers. Brodda, the Easterling is a unique monster, occurring at surface depths. It is very weak, just a little bit dangerous, and has no magical powers. The King cobra is an uncommon animal, occurring at surface depths. It is extremely weak, just a little bit dangerous, and has no magical powers. The Giant spider is an uncommon animal, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Dark elven mage is a common monster, occurring at very shallow depths. He is laughably weak, not at all dangerous, and has simple magical powers. Orfax, Son of Boldor is a unique animal, occurring at very shallow depths. He is extremely weak, somewhat dangerous, and has remarkable magical powers. The Dark elven warrior is a common monster, occurring at very shallow depths. He is extremely weak, not one little bit dangerous, and has no magical powers. The Clear mushroom patch is an uncommon monster, occurring at very shallow depths. It is laughably weak, somewhat dangerous, and has no magical powers. Grishnakh, the Hill Orc is a unique orc, occurring at very shallow depths. He is very weak, somewhat dangerous, and has no magical powers. The Giant white tick is an uncommon animal, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Hairy mold is an uncommon monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Disenchanter mold is an uncommon monster, occurring at very shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. The Pseudo dragon is an uncommon monster, occurring at very shallow depths. It is very weak, not at all dangerous, and has simple magical powers. The Tengu is a common monster, occurring at very shallow depths. It is extremely weak, just a small bit dangerous, and has rudimentary magical powers. The Creeping gold coins is a somewhat rare animal, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Wolf is a common animal, occurring at very shallow depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Giant fruit fly is a legendary animal, occurring at very shallow depths. It is laughably weak, not one little bit dangerous, and has no magical powers. tome-235-src/lib/file/book-12.txt0000644000076400017500000001720611012107760014271 0ustar dgdgThe Panther is an uncommon monster, occurring at very shallow depths. It is extremely weak, not one little bit dangerous, and has no magical powers. The Brigand is an uncommon monster, occurring at very shallow depths. He is extremely weak, not one little bit dangerous, and has no magical powers. The Baby multi-hued dragon is an uncommon dragon, occurring at very shallow depths. It is extremely weak, moderately dangerous, and has arcane magical powers. The Hippogryph is a common monster, occurring at very shallow depths. It is extremely weak, not one little bit dangerous, and has no magical powers. The Zombified orc is a common undead monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Gnome mage is an uncommon monster, occurring at very shallow depths. He is laughably weak, not one little bit dangerous, and has unremarkable magical powers. The Black mamba is a somewhat rare animal, occurring at very shallow depths. It is extremely weak, just a small bit dangerous, and has no magical powers. The White wolf is a common animal, occurring at very shallow depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Grape jelly is a somewhat rare monster, occurring at very shallow depths. It is moderately strong, just a small bit dangerous, and has no magical powers. The Nether worm mass is a somewhat rare animal, occurring at very shallow depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Golfimbul, the Hill Orc Chief is a unique orc, occurring at very shallow depths. He is somewhat weak, moderately dangerous, and has no magical powers. The Master yeek is an uncommon animal, occurring at very shallow depths. It is extremely weak, not one little bit dangerous, and has arcane magical powers. The Priest is a common monster, occurring at very shallow depths. He is extremely weak, not one little bit dangerous, and has unremarkable magical powers. The Dark elven priest is a common monster, occurring at very shallow depths. He is extremely weak, not one little bit dangerous, and has unremarkable magical powers. The Air spirit is an uncommon monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Skeleton human is a common undead monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Zombified human is a common undead monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Tiger is an uncommon monster, occurring at very shallow depths. It is extremely weak, not one little bit dangerous, and has no magical powers. The Moaning spirit is an uncommon undead monster, occurring at very shallow depths. It is laughably weak, moderately dangerous, and has rudimentary magical powers. The Swordsman is a common monster, occurring at very shallow depths. He is extremely weak, not one little bit dangerous, and has no magical powers. The Stegocentipede is an uncommon monster, occurring at very shallow depths. It is extremely weak, not at all dangerous, and has no magical powers. The Spotted jelly is a somewhat rare monster, occurring at very shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. The Drider is an uncommon monster, occurring at very shallow depths. It is extremely weak, just a little bit dangerous, and has rudimentary magical powers. The Killer brown beetle is an uncommon monster, occurring at very shallow depths. It is extremely weak, not at all dangerous, and has no magical powers. Boldor, King of the Yeeks is a unique animal, occurring at very shallow depths. He is very weak, somewhat dangerous, and has remarkable magical powers. The Ogre is an uncommon monster, occurring at very shallow depths. It is extremely weak, just a small bit dangerous, and has no magical powers. The Creeping mithril coins is a rare animal, occurring at very shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Illusionist is an uncommon monster, occurring at very shallow depths. He is extremely weak, not one little bit dangerous, and has arcane magical powers. The Druid is an uncommon monster, occurring at very shallow depths. He is extremely weak, not one little bit dangerous, and has remarkable magical powers. The Black orc is an uncommon orc, occurring at very shallow depths. He is extremely weak, just a little bit dangerous, and has no magical powers. The Ochre jelly is a somewhat rare monster, occurring at very shallow depths. It is extremely weak, very dangerous, and has no magical powers. The Giant flea is a common monster, occurring at very shallow depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Ufthak of Cirith Ungol is a unique orc, occurring at very shallow depths. He is somewhat weak, moderately dangerous, and has no magical powers. The Giant white dragon fly is a somewhat rare animal, occurring at very shallow depths. It is laughably weak, not at all dangerous, and has no magical powers. The Blue icky thing is a rare monster, occurring at very shallow depths. It is laughably weak, just a small bit dangerous, and has an inkling of magical powers. The Hill giant is a common monster, occurring at very shallow depths. It is very weak, not one little bit dangerous, and has no magical powers. The Flesh golem is a common monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Warg is an uncommon animal, occurring at very shallow depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Giant black louse is a common monster, occurring at very shallow depths. It is laughably weak, not at all dangerous, and has no magical powers. The Lurker is a somewhat rare monster, occurring at very shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Wererat is an uncommon animal, occurring at very shallow depths. It is extremely weak, not one little bit dangerous, and has simple magical powers. The Black ogre is an uncommon giant, occurring at very shallow depths. It is very weak, just a little bit dangerous, and has no magical powers. The Magic mushroom patch is an uncommon monster, occurring at very shallow depths. It is laughably weak, not at all dangerous, and has arcane magical powers. The Guardian naga is an uncommon monster, occurring at very shallow depths. She is somewhat weak, not one little bit dangerous, and has no magical powers. The Light hound is a common monster, occurring at very shallow depths. It is laughably weak, just a little bit dangerous, and has an inkling of magical powers. The Dark hound is a common monster, occurring at very shallow depths. It is laughably weak, just a little bit dangerous, and has an inkling of magical powers. The Half-orc is a somewhat rare orc, occurring at very shallow depths. He is very weak, just a small bit dangerous, and has no magical powers. The Giant tarantula is a somewhat rare animal, occurring at very shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. The Giant clear centipede is an uncommon monster, occurring at very shallow depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Mirkwood spider is an uncommon animal, occurring at very shallow depths. It is laughably weak, moderately dangerous, and has no magical powers. tome-235-src/lib/file/book-13.txt0000644000076400017500000001675211012107760014277 0ustar dgdgThe Frost giant is a common giant, occurring at very shallow depths. It is very weak, not at all dangerous, and has no magical powers. The Griffon is a common animal, occurring at very shallow depths. It is very weak, not one little bit dangerous, and has no magical powers. The Homonculous is a somewhat rare monster, occurring at very shallow depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Gnome mage is an uncommon monster, occurring at very shallow depths. He is laughably weak, just a little bit dangerous, and has unremarkable magical powers. The Clear hound is an uncommon monster, occurring at very shallow depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Clay golem is an uncommon monster, occurring at very shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. The Umber hulk is a common animal, occurring at very shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Orc captain is a somewhat rare orc, occurring at very shallow depths. He is very weak, not one little bit dangerous, and has no magical powers. The Gelatinous cube is a rare monster, occurring at very shallow depths. It is somewhat weak, hellishly dangerous, and has no magical powers. The Giant green dragon fly is an uncommon animal, occurring at very shallow depths. It is laughably weak, just a little bit dangerous, and has no magical powers. The Fire giant is an uncommon giant, occurring at very shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Hummerhorn is an extremely rare animal, occurring at very shallow depths. It is laughably weak, just a little bit dangerous, and has no magical powers. Ulfast, Son of Ulfang is a unique monster, occurring at very shallow depths. He is somewhat weak, just a little bit dangerous, and has no magical powers. The Quasit is an uncommon monster, occurring at very shallow depths. It is laughably weak, somewhat dangerous, and has average magical powers. The Imp is an uncommon monster, occurring at very shallow depths. It is laughably weak, moderately dangerous, and has average magical powers. The Forest troll is a common troll, occurring at very shallow depths. He is very weak, just a little bit dangerous, and has no magical powers. Nar, the Dwarf is a unique monster, occurring at very shallow depths. He is somewhat strong, moderately dangerous, and has simple magical powers. The 2-headed hydra is an uncommon monster, occurring at very shallow depths. It is somewhat weak, not one little bit dangerous, and has no magical powers. The Water spirit is a common monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Giant pink scorpion is a common monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Earth spirit is an uncommon monster, occurring at very shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. The Fire spirit is an uncommon monster, occurring at very shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. The Fire hound is a common animal, occurring at very shallow depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Cold hound is a common animal, occurring at very shallow depths. It is laughably weak, just a small bit dangerous, and has no magical powers. The Energy hound is a common animal, occurring at very shallow depths. It is laughably weak, moderately dangerous, and has no magical powers. The Mimic (potion) is a somewhat rare monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has small magical powers. The Blink dog is an uncommon monster, occurring at very shallow depths. It is laughably weak, just a little bit dangerous, and has rudimentary magical powers. The Uruk is a common orc, occurring at very shallow depths. He is extremely weak, somewhat dangerous, and has no magical powers. Shagrat, the Orc Captain is a unique orc, occurring at very shallow depths. He is moderately strong, somewhat dangerous, and has no magical powers. Gorbag, the Orc Captain is a unique orc, occurring at very shallow depths. He is moderately strong, somewhat dangerous, and has no magical powers. The Shambling mound is an uncommon monster, occurring at very shallow depths. It is extremely weak, just a small bit dangerous, and has an inkling of magical powers. The Stone giant is a common monster, occurring at very shallow depths. It is very weak, not one little bit dangerous, and has no magical powers. The Giant black dragon fly is an uncommon animal, occurring at very shallow depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Stone golem is an uncommon monster, occurring at very shallow depths. It is very weak, moderately dangerous, and has no magical powers. The Red mold is a common monster, occurring at very shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Giant gold dragon fly is an uncommon animal, occurring at very shallow depths. It is laughably weak, not one little bit dangerous, and has no magical powers. Bolg, Son of Azog is a unique orc, occurring at somewhat shallow depths. He is somewhat strong, somewhat dangerous, and has no magical powers. The Phase spider is an uncommon animal, occurring at somewhat shallow depths. It is laughably weak, moderately dangerous, and has rudimentary magical powers. The 3-headed hydra is an uncommon monster, occurring at somewhat shallow depths. It is somewhat strong, not one little bit dangerous, and has no magical powers. The Earth hound is a common monster, occurring at somewhat shallow depths. It is extremely weak, just a little bit dangerous, and has no magical powers. The Air hound is a common animal, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Sabre-tooth tiger is an uncommon monster, occurring at somewhat shallow depths. It is somewhat weak, not one little bit dangerous, and has no magical powers. The Water hound is an uncommon animal, occurring at somewhat shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. The Chimera is a common monster, occurring at somewhat shallow depths. It is extremely weak, not at all dangerous, and has no magical powers. The Quylthulg is a common monster, occurring at somewhat shallow depths. It is laughably weak, just a small bit dangerous, and has rudimentary magical powers. The Sasquatch is a somewhat rare animal, occurring at somewhat shallow depths. It is moderately strong, not one little bit dangerous, and has no magical powers. The Werewolf is a common animal, occurring at somewhat shallow depths. It is moderately strong, not one little bit dangerous, and has no magical powers. The Dark elven lord is an uncommon monster, occurring at somewhat shallow depths. He is somewhat weak, not one little bit dangerous, and has average magical powers. The Cloud giant is a common giant, occurring at somewhat shallow depths. It is somewhat weak, somewhat dangerous, and has no magical powers. Ugluk, the Uruk is a unique orc, occurring at somewhat shallow depths. He is very strong, somewhat dangerous, and has no magical powers. tome-235-src/lib/file/book-14.txt0000644000076400017500000001754011012107760014274 0ustar dgdgLugdush, the Uruk is a unique orc, occurring at somewhat shallow depths. He is extremely strong, moderately dangerous, and has no magical powers. The Blue dragon bat is a common animal, occurring at somewhat shallow depths. It is laughably weak, not at all dangerous, and has an inkling of magical powers. The Mimic (scroll) is a somewhat rare monster, occurring at somewhat shallow depths. It is extremely weak, moderately dangerous, and has average magical powers. The Fire vortex is a common monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Water vortex is a common monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Cold vortex is a common monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Energy vortex is a common monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Mummified orc is a common undead monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Killer stag beetle is a common monster, occurring at somewhat shallow depths. It is very weak, not one little bit dangerous, and has no magical powers. The Iron golem is an uncommon monster, occurring at somewhat shallow depths. It is unimaginably strong, moderately dangerous, and has no magical powers. The Giant yellow scorpion is a common monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Black ooze is a common monster, occurring at somewhat shallow depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Hardened warrior is a common monster, occurring at somewhat shallow depths. He is very weak, not one little bit dangerous, and has no magical powers. Azog, King of the Uruk-Hai is a unique orc, occurring at somewhat shallow depths. He is alarmingly strong, moderately dangerous, and has no magical powers. The Master rogue is an uncommon monster, occurring at somewhat shallow depths. He is extremely weak, not one little bit dangerous, and has no magical powers. The Red dragon bat is a common animal, occurring at somewhat shallow depths. It is laughably weak, not one little bit dangerous, and has an inkling of magical powers. The Killer white beetle is a common monster, occurring at somewhat shallow depths. It is very weak, not one little bit dangerous, and has no magical powers. The Giant bronze dragon fly is a common animal, occurring at very shallow depths. It is laughably weak, not one little bit dangerous, and has no magical powers. The Forest wight is a common undead monster, occurring at somewhat shallow depths. It is extremely weak, just a little bit dangerous, and has an inkling of magical powers. Ibun, Son of Mim is a unique monster, occurring at somewhat shallow depths. He is alarmingly strong, somewhat dangerous, and has small magical powers. Khim, Son of Mim is a unique monster, occurring at somewhat shallow depths. He is alarmingly strong, somewhat dangerous, and has small magical powers. The 4-headed hydra is an uncommon monster, occurring at somewhat shallow depths. It is strong, not one little bit dangerous, and has no magical powers. The Mummified human is a common undead monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has no magical powers. The Vampire bat is an uncommon undead monster, occurring at somewhat shallow depths. It is extremely weak, moderately dangerous, and has no magical powers. Sangahyando of Umbar is a unique monster, occurring at somewhat shallow depths. He is extremely strong, somewhat dangerous, and has rudimentary magical powers. Angamaite of Umbar is a unique monster, occurring at somewhat shallow depths. He is extremely strong, somewhat dangerous, and has rudimentary magical powers. The Banshee is an uncommon undead monster, occurring at somewhat shallow depths. She is laughably weak, somewhat dangerous, and has rudimentary magical powers. The Pukelman is a somewhat rare monster, occurring at somewhat shallow depths. It is unimaginably strong, moderately dangerous, and has small magical powers. The Dark elven druid is a somewhat rare monster, occurring at somewhat shallow depths. He is moderately strong, just a little bit dangerous, and has unremarkable magical powers. The Stone troll is a common troll, occurring at somewhat shallow depths. He is very weak, just a little bit dangerous, and has no magical powers. The Troll priest is a common troll, occurring at somewhat shallow depths. He is somewhat weak, just a little bit dangerous, and has unremarkable magical powers. The Wereworm is a somewhat rare animal, occurring at somewhat shallow depths. It is hellishly strong, somewhat dangerous, and has no magical powers. The Carrion crawler is an uncommon animal, occurring at somewhat shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Killer pink beetle is an uncommon monster, occurring at somewhat shallow depths. It is very weak, just a small bit dangerous, and has no magical powers. The Giant grey ant is a common monster, occurring at somewhat shallow depths. It is extremely weak, not one little bit dangerous, and has no magical powers. Ulwarth, Son of Ulfang is a unique monster, occurring at somewhat shallow depths. He is extremely strong, just a little bit dangerous, and has no magical powers. The Displacer beast is an uncommon monster, occurring at somewhat shallow depths. It is somewhat weak, just a little bit dangerous, and has no magical powers. The Giant red tick is a common animal, occurring at somewhat shallow depths. It is extremely weak, just a small bit dangerous, and has no magical powers. The Cave ogre is a common monster, occurring at somewhat shallow depths. It is somewhat weak, just a small bit dangerous, and has no magical powers. The White wraith is a common undead monster, occurring at somewhat shallow depths. It is extremely weak, somewhat dangerous, and has rudimentary magical powers. The Monadic Deva is a legendary monster, occurring at somewhat shallow depths. It is somewhat weak, moderately dangerous, and has small magical powers. Mim, Betrayer of Turin is a unique monster, occurring at somewhat shallow depths. He is hellishly strong, moderately dangerous, and has unremarkable magical powers. The Killer red beetle is a common animal, occurring at somewhat shallow depths. It is extremely weak, just a little bit dangerous, and has no magical powers. The Creeping adamantite coins is a rare animal, occurring at somewhat shallow depths. It is somewhat strong, moderately dangerous, and has no magical powers. The Algroth is a common monster, occurring at somewhat shallow depths. It is somewhat weak, moderately dangerous, and has no magical powers. The Vibration hound is a somewhat rare animal, occurring at somewhat shallow depths. It is very weak, just a small bit dangerous, and has an inkling of magical powers. The Nexus hound is a somewhat rare animal, occurring at somewhat shallow depths. It is very weak, just a small bit dangerous, and has an inkling of magical powers. The Ogre mage is an uncommon giant, occurring at somewhat shallow depths. It is moderately strong, not one little bit dangerous, and has arcane magical powers. Lokkak, the Ogre Chieftain is a unique giant, occurring at somewhat shallow depths. He is hellishly strong, somewhat dangerous, and has no magical powers. The Vampire is a common undead monster, occurring at somewhat shallow depths. It is somewhat weak, moderately dangerous, and has arcane magical powers. tome-235-src/lib/file/book-15.txt0000644000076400017500000001716011012107760014273 0ustar dgdgThe Gorgimera is an uncommon monster, occurring at somewhat shallow depths. It is somewhat strong, just a small bit dangerous, and has no magical powers. The Colbran is an uncommon monster, occurring at somewhat shallow depths. It is unimaginably strong, moderately dangerous, and has an inkling of magical powers. The Spirit naga is an uncommon monster, occurring at somewhat shallow depths. She is somewhat strong, somewhat dangerous, and has unremarkable magical powers. The 5-headed hydra is an uncommon animal, occurring at somewhat shallow depths. It is extremely strong, moderately dangerous, and has rudimentary magical powers. The Black knight is a common monster, occurring at somewhat shallow depths. He is somewhat weak, not one little bit dangerous, and has rudimentary magical powers. Uldor the Accursed is a unique monster, occurring at somewhat shallow depths. He is unimaginably strong, just a little bit dangerous, and has no magical powers. The Mage is a common monster, occurring at somewhat shallow depths. He is extremely weak, not one little bit dangerous, and has unimaginably powerful magical powers. The Mind flayer is a common monster, occurring at somewhat shallow depths. It is very weak, moderately dangerous, and has remarkable magical powers. Draebor, the Imp is a unique monster, occurring at somewhat shallow depths. It is somewhat strong, very dangerous, and has arcane magical powers. The Basilisk is a somewhat rare animal, occurring at somewhat shallow depths. It is strong, not at all dangerous, and has no magical powers. The Ice troll is a common troll, occurring at somewhat shallow depths. He is very weak, somewhat dangerous, and has no magical powers. The Giant purple worm is a somewhat rare animal, occurring at somewhat shallow depths. It is somewhat strong, somewhat dangerous, and has no magical powers. The Movanic Deva is a legendary monster, occurring at somewhat shallow depths. It is moderately strong, moderately dangerous, and has unremarkable magical powers. The Catoblepas is an uncommon animal, occurring at somewhat shallow depths. It is somewhat weak, just a small bit dangerous, and has no magical powers. The Mimic (ring) is a somewhat rare monster, occurring at somewhat shallow depths. It is moderately strong, extremely dangerous, and has hellishly powerful magical powers. The Young blue dragon is a common dragon, occurring at somewhat shallow depths. It is somewhat weak, just a small bit dangerous, and has an inkling of magical powers. The Young white dragon is a common dragon, occurring at somewhat shallow depths. It is somewhat weak, just a small bit dangerous, and has an inkling of magical powers. The Young green dragon is a common dragon, occurring at somewhat shallow depths. It is somewhat weak, just a small bit dangerous, and has an inkling of magical powers. The Young bronze dragon is a somewhat rare dragon, occurring at somewhat shallow depths. It is somewhat weak, just a small bit dangerous, and has an inkling of magical powers. The Mithril golem is a rare monster, occurring at shallow depths. It is hellishly strong, moderately dangerous, and has no magical powers. The Shadow drake is an uncommon dragon, occurring at shallow depths. It is very weak, just a small bit dangerous, and has simple magical powers. The Skeleton troll is a common undead monster, occurring at shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Manticore is an uncommon monster, occurring at shallow depths. It is very weak, not at all dangerous, and has an inkling of magical powers. The Giant blue ant is an uncommon animal, occurring at shallow depths. It is extremely weak, just a little bit dangerous, and has no magical powers. The Giant army ant is a somewhat rare monster, occurring at shallow depths. It is extremely weak, just a small bit dangerous, and has no magical powers. The Grave wight is a common undead monster, occurring at shallow depths. It is extremely weak, just a little bit dangerous, and has rudimentary magical powers. The Killer slicer beetle is an uncommon monster, occurring at shallow depths. It is very weak, not at all dangerous, and has no magical powers. The Ghost is a common undead monster, occurring at shallow depths. It is extremely weak, alarmingly dangerous, and has an inkling of magical powers. The Death watch beetle is a somewhat rare monster, occurring at shallow depths. It is somewhat weak, just a small bit dangerous, and has no magical powers. The Ogre shaman is an uncommon giant, occurring at shallow depths. It is extremely weak, not one little bit dangerous, and has advanced magical powers. The Nexus quylthulg is a common monster, occurring at shallow depths. It is extremely weak, not at all dangerous, and has average magical powers. Shelob, Spider of Darkness is a unique animal, occurring at shallow depths. She is hellishly strong, unimaginably dangerous, and has very powerful magical powers. The Ninja is an uncommon monster, occurring at shallow depths. He is very weak, moderately dangerous, and has no magical powers. The Memory moss is a somewhat rare monster, occurring at shallow depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Storm giant is a common giant, occurring at shallow depths. It is moderately strong, moderately dangerous, and has average magical powers. The Cave troll is a common troll, occurring at shallow depths. He is somewhat weak, somewhat dangerous, and has no magical powers. The Half-troll is an uncommon troll, occurring at shallow depths. He is moderately strong, somewhat dangerous, and has no magical powers. The Mystic is a somewhat rare monster, occurring at shallow depths. He is moderately strong, moderately dangerous, and has rudimentary magical powers. The Barrow wight is a somewhat rare undead monster, occurring at shallow depths. It is extremely weak, somewhat dangerous, and has small magical powers. The Giant skeleton troll is a common undead monster, occurring at shallow depths. It is somewhat strong, moderately dangerous, and has no magical powers. The Chaos drake is a somewhat rare dragon, occurring at shallow depths. It is strong, somewhat dangerous, and has remarkable magical powers. The Law drake is a somewhat rare dragon, occurring at shallow depths. It is strong, somewhat dangerous, and has average magical powers. The Balance drake is a somewhat rare dragon, occurring at shallow depths. It is very strong, somewhat dangerous, and has hellishly powerful magical powers. The Ethereal drake is a somewhat rare dragon, occurring at shallow depths. It is somewhat strong, somewhat dangerous, and has unremarkable magical powers. Bert the Stone Troll is a unique troll, occurring at shallow depths. He is hellishly strong, somewhat dangerous, and has no magical powers. Bill the Stone Troll is a unique troll, occurring at shallow depths. He is hellishly strong, somewhat dangerous, and has no magical powers. Tom the Stone Troll is a unique troll, occurring at shallow depths. He is hellishly strong, somewhat dangerous, and has no magical powers. The Shade is a somewhat rare undead monster, occurring at shallow depths. It is somewhat weak, moderately dangerous, and has small magical powers. The Spectre is a somewhat rare undead monster, occurring at shallow depths. It is somewhat weak, moderately dangerous, and has small magical powers. The Water troll is a common troll, occurring at shallow depths. He is moderately strong, moderately dangerous, and has no magical powers. tome-235-src/lib/file/book-16.txt0000644000076400017500000001664711012107760014305 0ustar dgdgThe Fire elemental is an uncommon monster, occurring at shallow depths. It is very weak, moderately dangerous, and has no magical powers. The Astral Deva is a legendary monster, occurring at shallow depths. It is somewhat strong, alarmingly dangerous, and has advanced magical powers. The Water elemental is an uncommon monster, occurring at shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Invisible stalker is a somewhat rare monster, occurring at shallow depths. It is very weak, moderately dangerous, and has no magical powers. The Carrion crawler is an uncommon animal, occurring at shallow depths. It is very weak, somewhat dangerous, and has no magical powers. The Master thief is an uncommon monster, occurring at shallow depths. He is very weak, not at all dangerous, and has no magical powers. Ulfang the Black is a unique monster, occurring at shallow depths. He is unimaginably strong, just a little bit dangerous, and has no magical powers. The Lich is a somewhat rare undead monster, occurring at shallow depths. It is somewhat weak, very dangerous, and has very powerful magical powers. The Master vampire is a somewhat rare undead monster, occurring at shallow depths. It is moderately strong, moderately dangerous, and has very powerful magical powers. The Giant grey scorpion is a rare monster, occurring at shallow depths. It is moderately strong, somewhat dangerous, and has no magical powers. The Earth elemental is an uncommon monster, occurring at shallow depths. It is somewhat weak, very dangerous, and has no magical powers. The Air elemental is an uncommon monster, occurring at shallow depths. It is very weak, alarmingly dangerous, and has no magical powers. The Hell hound is a somewhat rare animal, occurring at shallow depths. It is moderately strong, just a small bit dangerous, and has an inkling of magical powers. The Eog golem is a rare monster, occurring at shallow depths. It is hellishly strong, moderately dangerous, and has no magical powers. The Olog is a common troll, occurring at shallow depths. It is moderately strong, somewhat dangerous, and has no magical powers. The Dagashi is a rare monster, occurring at shallow depths. He is somewhat weak, extremely dangerous, and has no magical powers. The Gravity hound is an uncommon animal, occurring at shallow depths. It is somewhat weak, somewhat dangerous, and has an inkling of magical powers. The Acidic cytoplasm is an extremely rare monster, occurring at shallow depths. It is moderately strong, hellishly dangerous, and has no magical powers. The Inertia hound is an uncommon animal, occurring at shallow depths. It is somewhat weak, just a small bit dangerous, and has an inkling of magical powers. The Impact hound is an uncommon animal, occurring at shallow depths. It is somewhat weak, just a small bit dangerous, and has no magical powers. The Dread is an uncommon undead monster, occurring at shallow depths. It is somewhat strong, moderately dangerous, and has simple magical powers. The Ooze elemental is a somewhat rare monster, occurring at shallow depths. It is very weak, hellishly dangerous, and has small magical powers. The Smoke elemental is a somewhat rare monster, occurring at shallow depths. It is very weak, moderately dangerous, and has rudimentary magical powers. The Young black dragon is a common dragon, occurring at shallow depths. It is somewhat weak, just a small bit dangerous, and has an inkling of magical powers. The Mumak is a somewhat rare monster, occurring at shallow depths. It is alarmingly strong, not one little bit dangerous, and has no magical powers. The Giant red ant is a common animal, occurring at shallow depths. It is very weak, moderately dangerous, and has no magical powers. The Mature white dragon is a common dragon, occurring at shallow depths. It is moderately strong, somewhat dangerous, and has an inkling of magical powers. The Xorn is an uncommon monster, occurring at shallow depths. It is very weak, very dangerous, and has no magical powers. The Shadow is a somewhat rare undead monster, occurring at shallow depths. It is very weak, extremely dangerous, and has an inkling of magical powers. The Phantom is a somewhat rare undead monster, occurring at shallow depths. It is somewhat strong, extremely dangerous, and has an inkling of magical powers. The Grey wraith is a common undead monster, occurring at shallow depths. It is very weak, somewhat dangerous, and has small magical powers. The Young multi-hued dragon is a common dragon, occurring at shallow depths. It is somewhat weak, very dangerous, and has very powerful magical powers. The Colossus is a rare monster, occurring at shallow depths. It is hellishly strong, extremely dangerous, and has no magical powers. The Young gold dragon is an uncommon dragon, occurring at shallow depths. It is somewhat weak, not at all dangerous, and has an inkling of magical powers. Rogrog the Black Troll is a unique troll, occurring at shallow depths. He is hellishly strong, moderately dangerous, and has no magical powers. The Mature blue dragon is a common dragon, occurring at shallow depths. It is moderately strong, somewhat dangerous, and has an inkling of magical powers. The Mature green dragon is a common dragon, occurring at shallow depths. It is moderately strong, somewhat dangerous, and has an inkling of magical powers. The Mature bronze dragon is an uncommon dragon, occurring at shallow depths. It is somewhat strong, just a small bit dangerous, and has rudimentary magical powers. The Young red dragon is a common dragon, occurring at shallow depths. It is somewhat weak, just a small bit dangerous, and has an inkling of magical powers. The Trapper is a somewhat rare monster, occurring at shallow depths. It is strong, moderately dangerous, and has no magical powers. The Bodak is an uncommon monster, occurring at shallow depths. It is moderately strong, somewhat dangerous, and has average magical powers. The Ice elemental is an uncommon monster, occurring at shallow depths. It is moderately strong, moderately dangerous, and has unremarkable magical powers. The Necromancer is an uncommon monster, occurring at shallow depths. He is somewhat weak, just a little bit dangerous, and has unimaginably powerful magical powers. Lorgan, Chief of the Easterlings is a unique monster, occurring at shallow depths. He is hellishly strong, very dangerous, and has rudimentary magical powers. The Demonologist is an uncommon monster, occurring at shallow depths. He is somewhat weak, not at all dangerous, and has unremarkable magical powers. The Mummified troll is a common undead monster, occurring at shallow depths. It is very weak, moderately dangerous, and has no magical powers. The Queen Ant is a unique animal, occurring at shallow depths. She is hellishly strong, moderately dangerous, and has rudimentary magical powers. The Will o' the Wisp is a rare monster, occurring at shallow depths. It is somewhat weak, hellishly dangerous, and has average magical powers. The Magma elemental is an uncommon monster, occurring at shallow depths. It is moderately strong, extremely dangerous, and has simple magical powers. The Black pudding is an extremely rare monster, occurring at shallow depths. It is moderately strong, hellishly dangerous, and has no magical powers. tome-235-src/lib/file/book-17.txt0000644000076400017500000001744311012107760014301 0ustar dgdgThe Killer blue beetle is an uncommon animal, occurring at shallow depths. It is somewhat weak, somewhat dangerous, and has no magical powers. The Nexus vortex is a common monster, occurring at shallow depths. It is somewhat weak, not one little bit dangerous, and has no magical powers. The Plasma vortex is a common monster, occurring at shallow depths. It is somewhat weak, somewhat dangerous, and has no magical powers. The Mature red dragon is a common dragon, occurring at shallow depths. It is somewhat strong, somewhat dangerous, and has rudimentary magical powers. The Mature gold dragon is an uncommon dragon, occurring at shallow depths. It is strong, just a small bit dangerous, and has rudimentary magical powers. The Crystal drake is an uncommon dragon, occurring at shallow depths. It is strong, somewhat dangerous, and has small magical powers. The Mature black dragon is a common dragon, occurring at shallow depths. It is somewhat strong, somewhat dangerous, and has an inkling of magical powers. The Mature multi-hued dragon is an uncommon dragon, occurring at shallow depths. It is very strong, extremely dangerous, and has extremely powerful magical powers. The Death knight is a common monster, occurring at shallow depths. It is very strong, somewhat dangerous, and has remarkable magical powers. Castamir the Usurper is a unique monster, occurring at shallow depths. He is alarmingly strong, not at all dangerous, and has extremely powerful magical powers. The Time vortex is a rare monster, occurring at shallow depths. It is somewhat weak, not one little bit dangerous, and has no magical powers. The Shimmering vortex is a rare monster, occurring at shallow depths. It is extremely weak, not one little bit dangerous, and has small magical powers. The Ancient blue dragon is a common dragon, occurring at shallow depths. It is very strong, somewhat dangerous, and has rudimentary magical powers. The Ancient bronze dragon is an uncommon dragon, occurring at shallow depths. It is extremely strong, somewhat dangerous, and has rudimentary magical powers. The Beholder is a rare monster, occurring at shallow depths. It is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Emperor wight is an uncommon undead monster, occurring at shallow depths. It is moderately strong, somewhat dangerous, and has small magical powers. The Planetar is a legendary monster, occurring at shallow depths. It is somewhat strong, extremely dangerous, and has hellishly powerful magical powers. Vargo, Tyrant of Fire is a unique monster, occurring at shallow depths. It is hellishly strong, moderately dangerous, and has unremarkable magical powers. The Black wraith is an uncommon undead monster, occurring at shallow depths. It is somewhat strong, somewhat dangerous, and has small magical powers. The Erinyes is an uncommon monster, occurring at shallow depths. She is very weak, moderately dangerous, and has an inkling of magical powers. The Nether wraith is an uncommon undead monster, occurring at shallow depths. It is somewhat strong, moderately dangerous, and has unremarkable magical powers. The Eldrak is a somewhat rare troll, occurring at shallow depths. It is extremely strong, somewhat dangerous, and has no magical powers. The Ettin is a somewhat rare troll, occurring at shallow depths. It is hellishly strong, somewhat dangerous, and has no magical powers. Waldern, King of Water is a unique monster, occurring at shallow depths. It is hellishly strong, somewhat dangerous, and has unimaginably powerful magical powers. Kavlax the Many-Headed is a unique dragon, occurring at shallow depths. He is hellishly strong, moderately dangerous, and has hellishly powerful magical powers. The Ancient white dragon is a common dragon, occurring at shallow depths. It is very strong, somewhat dangerous, and has rudimentary magical powers. The Ancient green dragon is a common dragon, occurring at shallow depths. It is extremely strong, somewhat dangerous, and has rudimentary magical powers. The 7-headed hydra is an uncommon animal, occurring at shallow depths. It is unimaginably strong, moderately dangerous, and has unremarkable magical powers. The Night mare is a somewhat rare undead monster, occurring at shallow depths. It is hellishly strong, very dangerous, and has no magical powers. The Vampire lord is a somewhat rare undead monster, occurring at shallow depths. It is hellishly strong, unimaginably dangerous, and has very powerful magical powers. The Ancient black dragon is a common dragon, occurring at shallow depths. It is extremely strong, somewhat dangerous, and has rudimentary magical powers. The Disenchanter worm mass is a somewhat rare animal, occurring at shallow-to-moderate depths. It is laughably weak, somewhat dangerous, and has no magical powers. The Rotting quylthulg is a common animal, occurring at shallow-to-moderate depths. It is extremely weak, just a small bit dangerous, and has unremarkable magical powers. The Spirit troll is a somewhat rare troll, occurring at shallow-to-moderate depths. It is unimaginably strong, very dangerous, and has no magical powers. The Lesser titan is a somewhat rare monster, occurring at shallow-to-moderate depths. It is unimaginably strong, moderately dangerous, and has unremarkable magical powers. The 9-headed hydra is an uncommon animal, occurring at shallow-to-moderate depths. It is hellishly strong, just a small bit dangerous, and has simple magical powers. The Enchantress is a rare monster, occurring at shallow-to-moderate depths. She is somewhat strong, somewhat dangerous, and has rudimentary magical powers. The Archpriest is an uncommon monster, occurring at shallow-to-moderate depths. He is somewhat strong, somewhat dangerous, and has arcane magical powers. The Sorcerer is an uncommon monster, occurring at shallow-to-moderate depths. He is somewhat strong, somewhat dangerous, and has hellishly powerful magical powers. The Xaren is a common monster, occurring at shallow-to-moderate depths. It is moderately strong, very dangerous, and has no magical powers. The Giant roc is a somewhat rare animal, occurring at shallow-to-moderate depths. It is hellishly strong, somewhat dangerous, and has no magical powers. Uvatha the Horseman is a unique undead monster, occurring at shallow-to-moderate depths. He is hellishly strong, extremely dangerous, and has no magical powers. The Minotaur is an uncommon monster, occurring at shallow-to-moderate depths. It is unimaginably strong, not one little bit dangerous, and has no magical powers. Medusa, the Gorgon is a unique monster, occurring at shallow-to-moderate depths. She is hellishly strong, moderately dangerous, and has hellishly powerful magical powers. The Death drake is an uncommon dragon, occurring at shallow-to-moderate depths. It is hellishly strong, hellishly dangerous, and has small magical powers. The Ancient red dragon is a common dragon, occurring at shallow-to-moderate depths. It is hellishly strong, somewhat dangerous, and has rudimentary magical powers. The Ancient gold dragon is an uncommon dragon, occurring at shallow-to-moderate depths. It is hellishly strong, somewhat dangerous, and has rudimentary magical powers. The Great crystal drake is an uncommon dragon, occurring at shallow-to-moderate depths. It is hellishly strong, somewhat dangerous, and has small magical powers. The Vrock is an uncommon monster, occurring at shallow-to-moderate depths. It is moderately strong, moderately dangerous, and has no magical powers. The Death quasit is a somewhat rare monster, occurring at shallow-to-moderate depths. It is somewhat strong, alarmingly dangerous, and has unremarkable magical powers. tome-235-src/lib/file/book-18.txt0000644000076400017500000002021011012107760014264 0ustar dgdgAdunaphel the Quiet is a unique undead monster, occurring at shallow-to-moderate depths. She is hellishly strong, moderately dangerous, and has hellishly powerful magical powers. The Dark elven sorceror is an uncommon monster, occurring at shallow-to-moderate depths. He is extremely strong, just a small bit dangerous, and has hellishly powerful magical powers. The Master lich is an uncommon undead monster, occurring at shallow-to-moderate depths. It is hellishly strong, extremely dangerous, and has hellishly powerful magical powers. The Hezrou is a somewhat rare monster, occurring at shallow-to-moderate depths. It is somewhat strong, moderately dangerous, and has rudimentary magical powers. Akhorahil the Blind is a unique undead monster, occurring at shallow-to-moderate depths. He is hellishly strong, somewhat dangerous, and has hellishly powerful magical powers. Gorlim, Betrayer of Barahir is a unique monster, occurring at shallow-to-moderate depths. He is hellishly strong, hellishly dangerous, and has remarkable magical powers. The Solar is a legendary monster, occurring at shallow-to-moderate depths. It is hellishly strong, alarmingly dangerous, and has advanced magical powers. The Glabrezu is an uncommon monster, occurring at shallow-to-moderate depths. It is strong, somewhat dangerous, and has rudimentary magical powers. Ren the Unclean is a unique undead monster, occurring at shallow-to-moderate depths. He is hellishly strong, moderately dangerous, and has hellishly powerful magical powers. The Nalfeshnee is an uncommon monster, occurring at shallow-to-moderate depths. It is very strong, somewhat dangerous, and has small magical powers. The Undead beholder is a rare undead monster, occurring at shallow-to-moderate depths. It is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Dread is a common undead monster, occurring at shallow-to-moderate depths. It is somewhat strong, extremely dangerous, and has simple magical powers. The Mumak is an uncommon monster, occurring at shallow-to-moderate depths. It is alarmingly strong, just a small bit dangerous, and has no magical powers. The Ancient multi-hued dragon is a common dragon, occurring at shallow-to-moderate depths. It is hellishly strong, alarmingly dangerous, and has extremely powerful magical powers. The Ethereal dragon is an uncommon dragon, occurring at shallow-to-moderate depths. It is hellishly strong, moderately dangerous, and has average magical powers. Ji Indur Dawndeath is a unique undead monster, occurring at shallow-to-moderate depths. He is hellishly strong, moderately dangerous, and has very powerful magical powers. The Marilith is an uncommon monster, occurring at shallow-to-moderate depths. She is hellishly strong, somewhat dangerous, and has an inkling of magical powers. Quaker, Master of Earth is a unique monster, occurring at shallow-to-moderate depths. He is hellishly strong, hellishly dangerous, and has rudimentary magical powers. The Lesser Balrog is a somewhat rare monster, occurring at shallow-to-moderate depths. It is hellishly strong, moderately dangerous, and has simple magical powers. Ariel, Queen of Air is a unique monster, occurring at shallow-to-moderate depths. She is hellishly strong, hellishly dangerous, and has average magical powers. The 11-headed hydra is an uncommon animal, occurring at shallow-to-moderate depths. It is hellishly strong, just a small bit dangerous, and has extremely powerful magical powers. The Patriarch is an uncommon monster, occurring at shallow-to-moderate depths. He is extremely strong, somewhat dangerous, and has extremely powerful magical powers. The Dreadmaster is an uncommon undead monster, occurring at shallow-to-moderate depths. It is hellishly strong, unimaginably dangerous, and has very powerful magical powers. The Drolem is a somewhat rare dragon, occurring at shallow-to-moderate depths. It is hellishly strong, hellishly dangerous, and has small magical powers. Scatha the Worm is a unique dragon, occurring at shallow-to-moderate depths. He is hellishly strong, somewhat dangerous, and has small magical powers. Dwar, Dog Lord of Waw is a unique undead monster, occurring at shallow-to-moderate depths. He is hellishly strong, moderately dangerous, and has hellishly powerful magical powers. Smaug the Golden is a unique dragon, occurring at shallow-to-moderate depths. He is hellishly strong, somewhat dangerous, and has small magical powers. The Dracolich is an uncommon undead monster, occurring at shallow-to-moderate depths. It is hellishly strong, alarmingly dangerous, and has simple magical powers. The Greater titan is a somewhat rare monster, occurring at shallow-to-moderate depths. It is hellishly strong, moderately dangerous, and has simple magical powers. The Dracolisk is an uncommon dragon, occurring at shallow-to-moderate depths. It is hellishly strong, somewhat dangerous, and has simple magical powers. The Death mold is a common monster, occurring at shallow-to-moderate depths. It is hellishly strong, hellishly dangerous, and has no magical powers. Itangast the Fire Drake is a unique dragon, occurring at shallow-to-moderate depths. He is hellishly strong, somewhat dangerous, and has small magical powers. Glaurung, Father of the Dragons is a unique dragon, occurring at shallow-to-moderate depths. He is hellishly strong, somewhat dangerous, and has unremarkable magical powers. The Master mystic is a somewhat rare monster, occurring at moderate depths. He is hellishly strong, hellishly dangerous, and has small magical powers. Durin's Bane is a unique monster, occurring at moderate depths. He is hellishly strong, moderately dangerous, and has remarkable magical powers. The Nightwing is a rare undead monster, occurring at moderate depths. It is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Nether hound is an uncommon animal, occurring at moderate depths. It is very strong, just a small bit dangerous, and has an inkling of magical powers. The Time hound is a rare animal, occurring at moderate depths. It is very strong, just a small bit dangerous, and has no magical powers. The Plasma hound is an uncommon animal, occurring at moderate depths. It is very strong, somewhat dangerous, and has an inkling of magical powers. The Demonic quylthulg is a common animal, occurring at moderate depths. It is moderately strong, just a small bit dangerous, and has unremarkable magical powers. The Great storm wyrm is an uncommon dragon, occurring at moderate depths. It is hellishly strong, somewhat dangerous, and has rudimentary magical powers. Baphomet the Minotaur Lord is a unique monster, occurring at moderate depths. He is hellishly strong, somewhat dangerous, and has hellishly powerful magical powers. Harowen the Black Hand is a unique monster, occurring at moderate depths. He is hellishly strong, moderately dangerous, and has no magical powers. Hoarmurath of Dir is a unique undead monster, occurring at moderate depths. He is hellishly strong, somewhat dangerous, and has hellishly powerful magical powers. The Grand master mystic is a somewhat rare monster, occurring at moderate depths. He is hellishly strong, hellishly dangerous, and has arcane magical powers. Khamul the Easterling is a unique undead monster, occurring at moderate depths. He is hellishly strong, moderately dangerous, and has hellishly powerful magical powers. The Ethereal hound is a somewhat rare animal, occurring at moderate depths. It is unimaginably strong, somewhat dangerous, and has an inkling of magical powers. The Great ice wyrm is an uncommon dragon, occurring at moderate depths. It is hellishly strong, somewhat dangerous, and has rudimentary magical powers. The Phoenix is a unique animal, occurring at moderate depths. It is hellishly strong, alarmingly dangerous, and has hellishly powerful magical powers. The Nightcrawler is a rare undead monster, occurring at moderate depths. It is hellishly strong, unimaginably dangerous, and has hellishly powerful magical powers. tome-235-src/lib/file/book-19.txt0000644000076400017500000002024311012107760014273 0ustar dgdgThe Hand druj is a rare undead monster, occurring at moderate depths. It is very strong, somewhat dangerous, and has extremely powerful magical powers. The Eye druj is a rare undead monster, occurring at moderate depths. It is unimaginably strong, moderately dangerous, and has hellishly powerful magical powers. The Skull druj is a rare undead monster, occurring at moderate depths. It is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Chaos vortex is a common monster, occurring at moderate depths. It is very strong, not one little bit dangerous, and has no magical powers. The Aether vortex is an uncommon monster, occurring at moderate depths. It is strong, unimaginably dangerous, and has hellishly powerful magical powers. The Lernean Hydra is a unique animal, occurring at moderate depths. It is hellishly strong, alarmingly dangerous, and has hellishly powerful magical powers. Thuringwethil is a unique undead monster, occurring at moderate depths. She is hellishly strong, alarmingly dangerous, and has very powerful magical powers. The Great hell wyrm is an uncommon dragon, occurring at moderate depths. It is hellishly strong, somewhat dangerous, and has rudimentary magical powers. The Draconic quylthulg is a somewhat rare animal, occurring at moderate depths. It is very strong, just a small bit dangerous, and has unremarkable magical powers. Fundin Bluecloak is a unique monster, occurring at moderate depths. It is hellishly strong, extremely dangerous, and has unimaginably powerful magical powers. Uriel, Angel of Fire is a unique monster, occurring at moderate depths. He is hellishly strong, alarmingly dangerous, and has hellishly powerful magical powers. Azriel, Angel of Death is a unique monster, occurring at moderate depths. He is hellishly strong, extremely dangerous, and has hellishly powerful magical powers. Ancalagon the Black is a unique dragon, occurring at moderate depths. He is hellishly strong, moderately dangerous, and has extremely powerful magical powers. The Nightwalker is a rare undead monster, occurring at moderate depths. It is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. Gabriel, the Messenger is a unique monster, occurring at moderate depths. He is hellishly strong, hellishly dangerous, and has remarkable magical powers. Saruman of Many Colours is a unique monster, occurring at moderate-to-deep depths. He is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Dreadlord is an uncommon undead monster, occurring at moderate-to-deep depths. It is hellishly strong, unimaginably dangerous, and has arcane magical powers. The Cat Lord is a unique monster, occurring at moderate-to-deep depths. He is hellishly strong, hellishly dangerous, and has an inkling of magical powers. The Chaos beetle is a rare monster, occurring at moderate-to-deep depths. It is hellishly strong, not at all dangerous, and has rudimentary magical powers. The Chaos hound is a common animal, occurring at moderate-to-deep depths. It is hellishly strong, just a small bit dangerous, and has an inkling of magical powers. The Great Wyrm of Chaos is an uncommon dragon, occurring at moderate-to-deep depths. It is hellishly strong, somewhat dangerous, and has very powerful magical powers. The Great Wyrm of Law is an uncommon dragon, occurring at moderate-to-deep depths. It is hellishly strong, somewhat dangerous, and has very powerful magical powers. The Great Wyrm of Balance is a rare dragon, occurring at moderate-to-deep depths. It is hellishly strong, somewhat dangerous, and has hellishly powerful magical powers. Tselakus, the Dreadlord is a unique undead monster, occurring at moderate-to-deep depths. He is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. Tiamat, Celestial Dragon of Evil is a unique dragon, occurring at deep depths. She is hellishly strong, unimaginably dangerous, and has hellishly powerful magical powers. The Black reaver is a somewhat rare undead monster, occurring at deep depths. It is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Master quylthulg is a somewhat rare animal, occurring at deep depths. It is hellishly strong, just a small bit dangerous, and has hellishly powerful magical powers. The Greater draconic quylthulg is a somewhat rare animal, occurring at deep depths. It is hellishly strong, just a small bit dangerous, and has simple magical powers. The Greater rotting quylthulg is a somewhat rare animal, occurring at deep depths. It is hellishly strong, just a small bit dangerous, and has simple magical powers. Vecna, the Emperor Lich is a unique undead monster, occurring at deep depths. He is hellishly strong, unimaginably dangerous, and has hellishly powerful magical powers. Omarax the Eye Tyrant is a unique monster, occurring at deep depths. He is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. Ungoliant, the Unlight is a unique animal, occurring at deep depths. She is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Aether hound is an uncommon animal, occurring at deep depths. It is hellishly strong, very dangerous, and has hellishly powerful magical powers. The Mouth of Sauron is a unique monster, occurring at deep depths. He is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Emperor Quylthulg is a unique animal, occurring at deep depths. It is hellishly strong, just a little bit dangerous, and has unimaginably powerful magical powers. Qlzqqlzuup, the Lord of Flesh is a unique animal, occurring at deep depths. It is hellishly strong, just a little bit dangerous, and has hellishly powerful magical powers. Murazor, the Witch-King of Angmar is a unique undead monster, occurring at very deep depths. He is hellishly strong, extremely dangerous, and has hellishly powerful magical powers. Pazuzu, Lord of Air is a unique monster, occurring at very deep depths. He is hellishly strong, hellishly dangerous, and has advanced magical powers. The Hell hound is a rare animal, occurring at very deep depths. It is somewhat strong, moderately dangerous, and has an inkling of magical powers. Cantoras, the Skeletal Lord is a unique undead monster, occurring at very deep depths. He is hellishly strong, unimaginably dangerous, and has hellishly powerful magical powers. The Tarrasque is a unique monster, occurring at very deep depths. It is hellishly strong, somewhat dangerous, and has average magical powers. Lungorthin, the Balrog of White Fire is a unique monster, occurring at very deep depths. He is hellishly strong, extremely dangerous, and has advanced magical powers. Draugluin, Sire of All Werewolves is a unique animal, occurring at very deep depths. He is hellishly strong, moderately dangerous, and has simple magical powers. Feagwath the Undead Sorceror is a unique undead monster, occurring at extremely deep depths. He is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. Carcharoth, the Jaws of Thirst is a unique animal, occurring at extremely deep depths. He is hellishly strong, moderately dangerous, and has advanced magical powers. Cerberus, Guardian of Hades is a unique animal, occurring at extremely deep depths. It is hellishly strong, moderately dangerous, and has very powerful magical powers. Gothmog, the High Captain of Balrogs is a unique monster, occurring at extremely deep depths. He is hellishly strong, unimaginably dangerous, and has advanced magical powers. Sauron, the Sorcerer is a unique monster, occurring at extremely deep depths. He is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. Morgoth, Lord of Darkness is a unique monster, occurring at bottomless depths. He is hellishly strong, hellishly dangerous, and has hellishly powerful magical powers. The Haughty noble is a common monster, occurring at surface depths. He is laughably weak, not one little bit dangerous, and has no magical powers. tome-235-src/lib/file/book-20.txt0000644000076400017500000001331411012107760014264 0ustar dgdg#####R /----------------------------------------\ #####R < Adventurer's guide to the Middle-earth > #####R \----------------------------------------/ Summary: *****/abook-20.txt*1[(a) The Towns] *****/bbook-20.txt*2[(b) Other strange and frightening places] *****/cbook-20.txt*3[(c) Equipment issues] *****/dbook-20.txt*4[(d) Macros] Introduction: Middle-earth is vast and mysterious, full of dangers but also full of rewards for the brave. New adventurers should know that pressing < and > can switch the wilderness view between a normal scale and a larger map. This map makes travelling safer and faster, but you can't enter wilderness dungeons from it. ~~~~~1 #####G(a) The Towns You start in a small village named Bree in the western part of the Middle-earth. Here you will also find the entrance to the Barrow-Downs, a fairly safe and simple dungeon. When the Barrow-Downs become too easy for you, and Bree too small, you might consider going to Lothlorien, the land of Galadriel. [[[[[BNote that] [[[[[Byou should take a lot of food with you, for it is a long journey.] You'll have to head south-east following the Moria mountain's chain, then walk around the forest of Fangorn to head north to finally find your destination. The Forest of Mirkwood (another dungeon) can be found to the north east of Lothlorien. If you survive this dangerous dungeon, you should head south, following the Anduin river. There, near the dark land of Mordor, you will find the great town of Gondor, Minas Anor. From there you can want to pay a "visit" to the land of Mordor, which is east of Minas Anor. After Mordor you should finally travel to Gondolin, the hidden town of the Noldor. First go back to Bree, and then from there walk northeast and you will find it. From this city, you will be able to attack Angband, the dungeon of Morgoth, which is north west west of Gondolin. ~~~~~2 #####G(b) Other strange and frightening places The Old Forest to the west is the last remains of the big forests of the first age, but it has been corrupted. It is said it is guarded by a living tree. You may also wish to investigate the Orc Caves north of Bree; they are another place suitable for those finished with the Barrow-Downs. They also are rumored to hold great mysteries. The Maze: To the south of Bree there is a magical Maze. Many adventurers that ventured there never came back... It is rumored that a Minotaur is lurking down there, guarding an ancient and powerful artifact. Bring along digging equipment and some means to recall. Durin's Bane, the Balrog of Moria, guards the Mines of Moria, to the south east of Bree. During the Second Age of the world there was a great island called Numenor. The people who dwelt there were wise and powerful, but as time passed their last kings fell under the power of Sauron. Under Sauron's orders, they tried to attack Valinor, the blessed land, and for this Numenor was destroyed, swallowed by the sea. The ruins are still accessible, far out to sea to the west of Bree. Many other strange places wait to be explored by the valiant adventurer, but their locations are secret. You will have to find them yourself! ~~~~~3 #####G(c) Equipment issues Beware adventurer! If you plan to go down into the dungeons be prepared. Some items you will need badly. First think of some light, maybe a lantern is better than the torches. Second things to mention are your combat equipment. Sometimes the weapon and armor you got from your mentor are not enough for the nasties inside the dungeons. And third and most important, [[[[[Balways carry a shovel or other digger with you], because there is much rubble in the dungeons, which you cannot clear with your hands. ~~~~~4 #####G(d) Macros Spellcasters might find that pressing 4 keys (at least) to cast a spell is a lot, they are right. That is why there are macros. You can access the macro screen by pressing @. You can find help on the *****macrofaq.txt*0[macros] in the docs. Now you either have the hard way or the easy way. **The Hard Way** What the fellow adventurer should know is how to create a basic spell macro. Press @ to enter the macro screen. Press 4 to create a new macro. Press the key to bind the macro to, usually one uses the F* keys(you can combine them with the ctrl, shift, ... keys too) Enter the key sequence to be done for the macro. Press 2 to save the macro. Now a problem that might arise, imagine your macro looks like: mcaa*t to cast manathrust spell('m' to use skill, 'c' for cast a spell skill, 'a' for first book, 'a' for first spell, *t to… target the first monster). This macro will break if you gain a new skill so that "Cast a spell" is no more the skill 'c', or if you get a new book. There is a way around that. When the game asks for a skill or a spell it allows you to press @ to enter the skill/spell name directly, so your macro would become: m@Cast a spell\r@Manathrust\r*t Now this will always work as long as one of your books have the spell in it. **The Easy Way** This time you will only use the macro recorder. To do that: Press $ to start it Now each key you press will be recorded, so press all keys you want. It is recommended to start your macro by pressing Escape key a few time, so if there are messages when you use the macro it will first erase them instead of screwing your macro :) it is also recommended to take advantage of the @ key when selecting skills or objects whenever the possibility is offered to you. It will make sure you always use the good object/skill even if it moves in your inventory. Once all keys are pressed press $ again to stop it. It you are satisfied with your macro now you get to press the key to bind it to. As in the Hard Way you must use the macro screen if you want to permanently save your macros. tome-235-src/lib/file/error.txt0000644000076400017500000000337511012107760014252 0ustar dgdg65 ******** BUFFER LINE *********************************** DO NOT REMOVE ******* What game do you think you are playing anyway? Aivan sairas kaveri kun tuollaista aikoo puuhata! Insufficient data for further analysis. Non sequitur. Your facts are uncoordinated. Type '?' or '\' for help. Invalid command. What? WHAT?! You must be out of your mind! You're killing me. Are you sure? Are you sure you know what you are doing? Aww, come on! That makes no sense. I beg your pardon. Degreelessness mode on. Degreelessness mode off. Syntax error. That doesn't compute. I don't understand you. ??? Sure. Piece of cake. Error. You can't do that! Help! Come again? Sorry? Sorry, I'm not sure I understand you. What's your point? Unknown command. Command not found. An unexpected error has occurred because an error of type 42 occurred. Somehow, you think that would never work. Welcome to level 42. Don't be ridiculous! lfae aierty agnxzcg? Soyha, azho bouate! I don't fully understand you. Why would anybody want to do THAT? Yes, yes, now tell me about your childhood. Satisfied? Something is wrong here. There's something wrong with YOU. You leap up 9' and perform a miraculous 5xSpiral in the air. Aw, shaddap! Shut up, smartass! I see little point in doing that. Oh, really? Very funny. You've got to be kidding! I'm not amused. I must have misheard you. Nothing happens. Where did you learn THAT command? When all else fails, read the instructions. Why not read the instructions first? Cut it out! Nothing interesting happens. Just how exactly am I supposed to do THAT? That's morally wrong and I won't do it. I'm not gonna take this abuse. AAAAAAAAAAAAAHHHHHHHHHHHHHHHRRRRRRRRRRRGGGGGGGGGGG! No more, if you value your character's life! Give it up, guy. Disk error. (a)bort, (r)etry, (f)ail? tome-235-src/lib/help/0000755000076400017500000000000011012107763012364 5ustar dgdgtome-235-src/lib/help/r_kobold.txt0000644000076400017500000000200711012107760014714 0ustar dgdg~~~~~01|Kobold ~~~~~02|Races|Kobold #####R=== Kobolds === #####GDescription Kobolds are a weak goblin race. They love poisoned weapons, and can learn to throw poisoned darts (of which they carry an unlimited supply). They are also inherently resistant to poison, and can become adequate fighters, although they are not one of the more powerful races. #####GStat Modifiers Strength +1 Intelligence -1 Wisdom 0 Dexterity +1 Constitution 0 Charisma -4 Hit Dice Sides 9 Exp Penalty +25% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 1.000 [0.000] Archery -0.800 [0.000] Sneakiness 0.100 [0.000] Stealth -1.000 [0.000] Disarming -0.200 [0.000] Magic Magic-Device -0.300 [0.000] Spirituality -1.000 [0.000] tome-235-src/lib/help/c_monk.txt0000644000076400017500000000647511012107760014404 0ustar dgdg|||||oy ~~~~~01|Monk ~~~~~02|Classes|Monk #####R=== Monks === #####GDescription The Monk character class is very different from all other classes. Although they can use weapons and armour just like any other class, their training in martial arts makes them much more powerful with no armour nor weapons. As the Monk's skill level rises, new and more powerful forms of attack become available. It is also rumoured that the monastic training makes experienced monks faster than any other character class! A Monk might need to wear some kind of armour to gain the resistances necessary for survival at higher levels, but if that armour is too heavy, it will severely disturb his/her martial arts maneuvers. If skill points are invested in *****skills.txt*20[Dodging], a Monk's defensive capabilities (blocking and dodging) will also increase. However, if armour is being worn, dodging is much less effective. Fortunately, a Monk can increase his/her ability to fight while still wearing armor by increasing his/her *****skills.txt*13[Barehanded-combat] skill. Monks also have access to the schools of *****m_meta.txt*0[Meta], *****m_tempo.txt*0[Temporal] and *****m_mind.txt*0[Mind] magic. #####GStarting Stat Modifiers Strength +1 Intelligence -2 Wisdom +1 Dexterity +1 Constitution +0 Charisma +1 Hit Die +d8 Spell Points +0% Exp Penalty 40% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 0.000 [0.900] Weaponmastery 0.000 [0.300] Archery 0.000 [0.400] Barehand-combat 1.000 [0.900] Sneakiness 1.000 [0.900] Stealth 1.000 [0.900] Disarming 1.000 [0.900] Dodging 0.000 [0.700] Magic 0.000 [0.600] Magic-Device 1.000 [1.000] Meta 0.000 [0.500] Temporal 0.000 [0.500] Mind 0.000 [0.500] Spirituality 1.000 [0.900] Prayer 0.000 [0.500] Music 0.000 [0.300] Monster-lore 1.000 [1.100] Corpse-preservation 1.000 [0.500] Possession 0.000 [0.100] #####GStarting Equipment A Monk begins the game with: a Potion of Healing a Soft Leather Armour ~~~~~03|Monk|Monk attacks ~~~~~04|Tables|Monk attacks #####GMonk Attacks #####BAttack Name Min.lvl Damage Stun Notes ----------------------------------------------------------------------------- Punch 1 1d4 - Kick 2 1d6 - Strike 3 1d7 - Knee 5 2d3 * Painful to males; likely to stun them Elbow 7 1d8 - Butt 9 2d5 - Ankle Kick 11 3d4 - May slow down the opponent Uppercut 13 4d4 6 Double-kick 16 5d4 8 Cat's Claw 20 5d5 - Jump Kick 25 5d6 10 Eagle's Claw 29 6d6 - Circle Kick 33 6d8 10 Iron Fist 37 8d8 10 Flying Kick 41 8d10 12 Dragon Fist 45 10d10 16 Crushing Blow 48 10d12 18 tome-235-src/lib/help/lua_ques.txt0000644000076400017500000003433711012107760014752 0ustar dgdg|||||oy #####R /----------------------------------------\ #####R < Adding a new quest > #####R \----------------------------------------/ #####R=== Introduction === Adding a quest involves a bit more work, and there is, in some ways, rather more potential for things to go wrong! But it's a great way of showing just WHAT can be done with lua scripting. It proves just how much a lua patch can change the overall feel of the game. And it will give you a much better idea of how lua interfaces with the game source. You should have read the *****lua_intr.txt*0[scripting introduction], *****lua_pow.txt*0[racial power tutorial] and *****lua_skil.txt*0[adding new skills tutorial] before going much further. All of the above files contain some fairly fundamental information which you will find necessary for full understanding of this file. The script we're looking at is going to create a quest entrance in the middle of Bree. Entering the quest you see a little girl who has had her necklace stolen. Your job is to travel down a corridor, killing some monsters on the way, pick up the amulet and return it to the girl. Once done, she'll reveal the stairs back to Bree, and give you a (randomly generated) ring. If you feel the monsters are too hard, the only thing to do is talk to the little girl who will reveal the stairs again, failing the quest for you, and also block off the entrance to the amulet so that you can't cheat and make off with the amulet! #####R=== Getting started === Open amulet.lua (you have downloaded the example scripts from [[[[[Ghttp://www.moppy.co.uk/angband.htm], haven't you?). The first thing you should see is that yet again we're calling a function that takes its arguments from a table, making it easy to read what's going on in the script. This time our function is add_quest and we have the following keys and values: #####B["global"] = "AMULET_QUEST", #####B["name"] = "Hannahs lost amulet", #####B["desc"] = { #####B "Retrieve an amulet for Hannah Cooke. It's guarded!" #####B }, #####B["level"] = 5, #####B["hooks"] = { [[[[[B"global" = ] is a constant that we set when we refer to this quest in various places... [[[[[B"name" = ] Obviously a long name for the quest. This will appear in the quest screen (Ctrl-Q) and we may use in some map files too. [[[[[B"desc" = ] This is a long description for the quest. Again this is what will appear in the quest screen, and each line should be not more than 80 characters. [[[[[B"level" = ] This is a rough indicator of how hard the quest is, and again, appears in the quest screen [[[[[B"hooks" = ] This is the real 'meat' of the quest. Like the [[[[[B"spell_list"] key in the [[[[[Badd_magic] function, this is another sub-table. To understand fully the structure of the "hooks" key it's worth taking a bit of a detour at this point and discussing how the scripting interface works in general. #####R=== How the scripts work (ish) === Essentially there's a list of events that happen in the game. As each of these events happen they run a check to see if there's any functions that they need to run at that event. When we ran the add_mkey part of adding a new skill power, we essentially said "when the 'm' key is pressed in the game, perform the [[[[[Bexecute_magic(constructor_powers)] function". Likewise we did a similar thing with adding the racial power, only we hooked onto the pressing of the 'U' key. All of this was partly hidden because of the way that the [[[[[Badd_magic] and [[[[[Badd_power] functions work. But here in the [[[[[Badd_quest] function it's a bit more specific. We are going to specify what events we're going to hook onto, and what functions we want to trigger at that event. A full list of hooks can be found in the source-file util.pkg. #####R=== The hooks === #####B[HOOK_BIRTH_OBJECTS] = function() #####B quest(AMULET_QUEST).status = QUEST_STATUS_TAKEN #####Bend, So here we are with our first hook. We've declared that we're adding it to the birth of your character. That is, the function will be called when you create your character. And what we're doing here is automatically declaring the quest as being taken, like the Dol Guldur quest is. Each quest has 7 different statuses: [[[[[BQUEST_STATUS_IGNORED -1 ] This is unused, but the quest is ignored (will not be taken and has not been taken). [[[[[BQUEST_STATUS_UNTAKEN 0 ] The quest has not been accepted yet [[[[[BQUEST_STATUS_TAKEN 1 ] You have accepted the quest [[[[[BQUEST_STATUS_COMPLETED 2 ] You have completed the quest successfully but not been rewarded for it [[[[[BQUEST_STATUS_REWARDED 3 ] You've completed and rewarded the quest [[[[[BQUEST_STATUS_FAILED 4 ] You've failed the quest [[[[[BQUEST_STATUS_FINISHED 5 ] The quest is completely finished successfully. [[[[[BQUEST_STATUS_FAILED_DONE 6 ] The quest is completely finished unsuccessfully. You see that we've used the constant we defined in the "global" section is passed as an argument to [[[[[Bquest.status]. Next hook then: #####B[HOOK_GEN_QUEST] = function() #####B if (player.inside_quest ~= AMULET_QUEST) then #####B return FALSE #####B else #####B load_map("amulet.map", 2, 2) #####B return TRUE #####B end #####Bend, Ok, we're hooking onto the generation of the quest here. This is specifically triggered in this instance by going down the quest entrance stairs in Bree. Once you've gone down the stairs, you are technically inside the quest, which means we can say if the person is not inside the amulet quest, then ignore this function, otherwise load the file 'amulet.map' at co-ordinates x=2 y=2. You'll find the amulet.map file in the edit directory, make sure you check it out. The syntax for map files is fairly simple, though I might get round to writing a tutorial on them some day! In the mean time holler for me at the usual email address if you're unsure. #####B[HOOK_FEELING] = function() #####B if (player.inside_quest ~= AMULET_QUEST) then #####B return FALSE #####B else #####B cmsg_print(TERM_L_BLUE, "Hannah speaks to you:") #####B cmsg_print(TERM_YELLOW, "'Some nasty monsters stole my #####B favourite necklace.'") #####B cmsg_print(TERM_YELLOW, "'It's hidden at the back of that #####B corridor! Please fetch it for me'") #####B return TRUE #####B end #####Bend, We're moving into some rather more obvious territory here, and getting into the meat of the quest. The [[[[[BHOOK_FEELING] is triggered at the point when the level feeling appears. It's important that this is run only if the player is inside the amulet quest, as otherwise it will trigger EVERY time a level feeling occurs, when you go down a level in the barrow-downs, whenever! Returning TRUE will replace the level feeling with what's above, returning FALSE will still perform the function but will amend the normal level feeling - so here if we'd returned false we'd still get our custom messages, but they'd follow with 'looks like a typical quest level'. Of course returning false may cause you other problems (see end of this file!) depending on what else you have in your function. #####B[HOOK_GIVE] = function(m_idx, item) #####B m_ptr = monster(m_idx) #####B o_ptr = get_object(item) #####B if (m_ptr.r_idx == test_monster_name("Hannah Cooke, a little girl")) #####B and (o_ptr.tval == TV_AMULET) and (o_ptr.sval == 2) then #####B cmsg_print(TERM_YELLOW, "'Thank-you!'") #####B inven_item_increase(item, -1) #####B inven_item_optimize(item) #####B quest(AMULET_QUEST).status = QUEST_STATUS_COMPLETED #####B cave_set_feat(7, 6, 6) #####B cmsg_print(TERM_YELLOW, "'Here, take this pretty ring I found #####B as a token of gratitude!'") #####B random_type = randint(57) #####B reward = create_object(TV_RING, random_type) #####B drop_near(reward, -1, py, px) #####B quest(AMULET_QUEST).status = QUEST_STATUS_REWARDED #####B return TRUE #####B else #####B return FALSE #####B end #####Bend, This is a fairly long function, but don't be intimidated. It's not really difficult to understand. As you can see we're hooking into the giving of an object to a monster (the 'y' key). Because of this, the function takes two arguments - [[[[[Bm_idx] (the monster that you're giving to) and [[[[[Bitem] (the item that you're giving). We then make it possible to work with the monster and item variables by referencing them to two functions which identify them from the edit files: [[[[[Bmonster()] and [[[[[Bget_object()]. This enables us to now say, 'if the name of the monster is "Hannah Cooke, a little girl" and the type of item is an amulet and that amulet is an amulet of adornment, then carry out the following commands'. We then say call the function [[[[[Binven_item_increase()] which places an object in the inventory. It takes two arguments, the first being what object to put in the inventory and the second being how many of that type of objects to put in the inventory. You can see that by placing -1 as the second argument it fairly obviously subtracts that item from the inventory. The [[[[[Binven_item_optimize()] function checks that there are no empty inventory slots, and if there are, erases them. The quest is then completed, and the stairs are revealed using the [[[[[Bcave_set_feat()] function. This function takes three arguments, the first is the x co-ordinate of the cave square you wish to change (counted from top left) the second is the y co-ordinate, and the third is the index number of the feature you wish the square to become as defined in f_info.txt. We then set about rewarding the player. As you can see we call [[[[[Bcreate_object()] which takes two variables: the first is the type of object (these are all listed in object.pkg) and the second is the sub-type of that object. I searched k_info.txt to see how many different types of ring there were (57) and used a randomly selected number with a maximum value of 57 as that specific sub-type. We then drop the object (although it's been created, it has only been created in the game's memory, it's nowhere that the player can interact with it until we drop it). The [[[[[Bdrop_near()] function takes 3 variables, the first being the object that you wish to drop, the second being the chance that it disappears (like an arrow, or mimicked creature) on drop. If you set it to -1, it won't ever disappear. The last two are the co-ordinates at which the object will be dropped. py and px are the global variables defined by where the player is standing, so in this case it will drop under the player. You could do [[[[[Binven_item_increase(reward, 1)] if you wanted, but I wanted to show a variety of ways of handling objects. OK, let's take a look at the next hook: #####B[HOOK_CHAT] = function(m_idx) #####B m_ptr = monster(m_idx) #####B if (m_ptr.r_idx == test_monster_name("Hannah Cooke, a little girl")) then #####B if (quest(AMULET_QUEST).status == QUEST_STATUS_REWARDED) then #####B cmsg_print(TERM_YELLOW, "'Bye!'") #####B else #####B cmsg_print(TERM_YELLOW, "'Are the monsters too tough? #####B Do you want to leave?'") #####B if (get_check("Really leave and fail the quest?") == #####B FALSE) #####B then #####B cmsg_print(TERM_YELLOW, "'Go and get my #####B amulet then!'") #####B else #####B cmsg_print(TERM_YELLOW, "'Awww. Never #####B mind. It was only a bit of rabbits foot'") #####B quest(AMULET_QUEST).status = #####B QUEST_STATUS_FAILED #####B cave_set_feat(7, 6, 6) #####B cave_set_feat(12, 5, 60) #####B end #####B end #####B return TRUE #####B end #####B return FALSE #####Bend, This only looks complicated because of the nested 'if' statements. It's easy to lose your way when doing this kind of thing, always make sure you close all the statements and put the returns in the right place. [[[[[BHOOK_CHAT] functions have one argument - the monster you are chatting to. As you can see, we perform a check to make sure it's the right monster and then away we go.... If the player wants to leave the quest without completion they talk to Hannah, who gives them a chance to change their mind! If the player asks to leave the entrance to the corridor is blocked off (the second cave_set_feat()) so that the user can't then go and get the amulet. Gumband or Zangband players may at this point think they've lost out on the rabbits foot of burglary! (they haven't though as it doesn't exist in ToME). #####B[HOOK_CHAR_DUMP] = function() #####B if (quest(AMULET_QUEST).status == QUEST_STATUS_FAILED) then #####B print_hook("\n You chickened out of rescuing a necklace and #####B made a little girl sad. ") #####B elseif (quest(AMULET_QUEST).status == QUEST_STATUS_COMPLETED) or #####B (quest(AMULET_QUEST).status == QUEST_STATUS_REWARDED) or #####B (quest(AMULET_QUEST).status == QUEST_STATUS_FINISHED) then #####B print_hook("\n You rescued little Hannah Cooke's necklace from #####B the nasty monsters ") #####B end #####B return FALSE #####Bend, This quite simply and obviously prints an appropriate line in the character dump based on the status of the quest. The [[[[[B\n] bit ensures the text goes on a new line, so make sure you include it! Also you should return FALSE as returning TRUE will stop executing all the other character dump lines (and you may get other quests not having their lines printed). === A word about returning TRUE and FALSE === As I mentioned above, you need to be careful what you return when dealing with HOOKS as you can mess up the game a bit. Bear in mind that if you add a function to [[[[[BHOOK_GEN_QUEST], every time a quest is generated, that function will run. If you return TRUE, then no further functions attached to that hook will run. If you return FALSE, it continues processing functions on that hook. That is pretty much it. Do take a look at the other included scripts that I haven't gone into any detail about in the files, as you'll pick up some useful techniques there too. Especially worthy of note is the hina.lua file which uses hooks outside of the quest structure and also global variables and variables in a table. If you have any questions, let me know at the email addy below. Back to the *****lua.hlp*0[lua help index] . [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)] tome-235-src/lib/help/luckspoi.txt0000644000076400017500000000632511012107760014761 0ustar dgdg|||||oy ~~~~~01|Luck (spoiler) ~~~~~02|Spoilers|Luck #####RLuck "You've got to ask yourself one question: do I feel lucky? Well do ya punk?" --Clint Eastwood (Dirty Harry) #####G1. Starting luck Most races start with no luck points. Those that start with luck are listed below from most luck to least luck. Hobbit (+5); Maia (+4); Gnome, Dunadan, Thunderlord (+2); Beorning (+1); Half-Ogre, Dark Elf, Ent (-2); Orc (-3); Troll (-4); Petty Dwarf, DeathMold, Yeek (-5). Most subraces start with no luck points. Those that start with luck are listed below from most luck to least luck. Barbarian (+1); Spectre, Skeleton (-3); Zombie (-4). So, a Hobbit starts with 5 luck points, a Beorning Barbarian starts with 2 luck points, while a Yeek Zombie starts with -9 luck points. #####G2. Descriptions Drinking a potion of self-knowledge will tell you how lucky or unlucky your character is. DESCRIPTION VALUE incredibly unlucky less than -27 extremely unlucky less than -18 very unlucky less than -9 unlucky less than 0 normal luck 0 lucky more than 0 very lucky more than 9 extremely lucky more than 18 incredibly lucky more than 27 Luck < -30 is treated as -30 and luck > 30 is treated as +30. #####G3. Items affecting luck Elven cloaks give a bonus to luck. Only one type of ego item is lucky, or perhaps that should be unlucky. All Morgul items have -10 luck. Artifacts can affect your luck. Beware: not all artifacts give you good luck. Listed below are the artifacts which affect your luck. The Phial of Galadriel (+4) The Arkenstone of Thrain (+3) The Ring of Power 'Narya' (+1) The Ring of Power 'Nenya' (+2) The Ring of Power 'Vilya' (+3) The Metal Cap of Thengel (+3) The Shadow Cloak of Luthien (+2) The Set of Cesti of Fingolfin (+4) The Long Sword 'Anduril' (+4) The Long Bow of Bard (+2) The Mage Staff of Eternity (+12) The Harp of Maglor (+3) The Drum of the Sky (+2) The Harp of Daeron (+1) The Long Sword of Eternity (+10) The Robe of Great Luck (+60) The Heavy Crossbow of Eternity (+5) The Iron Helm of Knowledge (-6) The Shield of Deflection of Gil-galad (+5) The Set of Gauntlets of Eol (+3) The Demonblade of Gothmog (-20) The Long Sword 'Durandil' (+3) The Phial of Undeath (-5) The Ring of Phasing (+15) The Blue Stone 'Toris Mejistos' (+2) The Silver Bolt 'Stone-biter' (+3) The Elven Cloak of Mellyrn (+4) The Set of Cesti 'Skycleaver' (+1) #####G4. What does it affect. It affects your chance to-hit in ranged combat and melee combat. It affects your chance of critical hits in ranged combat and melee combat. It affects your chance of being missed by a monster attack. This effectively changes armour class by -13 (incredibly unlucky) to +13 (incredibly lucky). It affects the rarity of special objects, artifacts, and ego items. It affects the number of wishes on a staff of wishing. It affects the base level for applying magic to an item. It affects the chance of an item being good or great. It affects the chance of creating a special object. It prevents the death fate if you are lucky. It affects the number of skill points you receive when quaffing the Potion of Learning. Written for ToME 2.0 by Chris Hadgis tome-235-src/lib/help/rm_vamp.txt0000644000076400017500000000250511012107760014565 0ustar dgdg~~~~~01|Vampire ~~~~~02|Race Modifiers|Vampire #####R=== Vampire === #####GDescription One of the mightier undead creatures, the vampire is an awe-inspiring sight. Yet this mighty creature has a serious weakness: the bright rays of sun are its bane, and it will need to flee the surface to the deep recesses of the earth until the sun finally sets. Darkness, on the other hand, only makes the vampire stronger. Being undead, the vampire has a firm hold on its life force, and resists nether attacks. The vampire also resists cold and poison based attacks. It is, however, susceptible to its perpetual hunger for fresh blood, which can only be satiated by sucking the blood from a nearby monster, which is the vampire's special power. It should be noted that the vampires are so sensitive to daylight that even certain artifact light items which are filled with daylight will hurt them if they try to wield the items. Fortunately, the vampires do not really need these items, since they radiate an aura of 'dark light' of their own. Light resistance will, in any case, protect the vampire from the adverse effects of sunlight. #####GStat Modifiers Strength +3 Intelligence +2 Wisdom -3 Dexterity -2 Constitution +1 Charisma -4 Hit Dice +1 side Spell Points +0% Exp penalty +100% tome-235-src/lib/help/rm_barb.txt0000644000076400017500000000222311012107760014525 0ustar dgdg~~~~~01|Barbarian ~~~~~02|Race Modifiers|Barbarian #####R=== Barbarian Race === #####GDescription Barbarians are hardy members of their race. They are fierce in combat, and their wrath is feared throughout the world. Combat is their life: they learn to feel no fear. Barbarians are, however, suspicious of magic, which makes magic devices fairly hard for them to use, and also makes it impossible for them to play Mages. #####GStat Modifiers Strength +2 Intelligence -3 Wisdom -2 Dexterity +1 Constitution +1 Charisma -3 Hit Dice +1 side Spell Points -50% Exp Penalty +25% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 1.200 [0.000] Archery 0.500 [0.000] Sneakiness Stealth -2.000 [0.000] Disarming -0.200 [0.000] Magic Magic-Device -1.000 [0.000] Spirituality 0.200 [0.000] #####GStarting Equipment A barbarian character begins the game with: Some rations Some torches tome-235-src/lib/help/def.aux0000644000076400017500000000005611012107760013637 0ustar dgdgfile_ext="html" link_prefix="" link_suffix="" tome-235-src/lib/help/c_warrio.txt0000644000076400017500000000326111012107760014731 0ustar dgdg~~~~~01|Warrior ~~~~~02|Classes|Warrior #####R=== Warriors === #####GDescription A Warrior is a hack-and-slash character, who solves most of his problems by cutting them to pieces, but will occasionally fall back on the help of a magical device or a bow. A Warrior learns no magic, and can even suppress it like an Unbeliever through the Antimagic skill. #####GStarting Stat Modifiers Strength +5 Intelligence -2 Wisdom -2 Dexterity +2 Constitution +2 Charisma -1 Hit Die +d9 Spell Points +0% Exp Penalty 0% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 2.000 [0.800] Weaponmastery 1.000 [0.850] Sword-mastery 0.000 [0.400] Axe-mastery 0.000 [0.400] Hafted-mastery 0.000 [0.400] Polearm-mastery 0.000 [0.400] Archery 1.000 [0.600] Antimagic 0.000 [0.550] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Disarming 1.000 [0.900] Magic 1.000 [0.300] Magic-Device 1.000 [1.150] Spirituality 1.000 [0.400] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Extra Max Blow(1) 1 Extra Max Blow(2) 1 Spread blows 25 #####GStarting Equipment A Warrior begins the game with: a Ring of Fear Resistance a Broad Sword a Chain Mail tome-235-src/lib/help/c_demono.txt0000644000076400017500000000333711012107760014713 0ustar dgdg|||||oy ~~~~~01|Demonologist ~~~~~02|Classes|Demonologist #####R=== Demonologists === #####GDescription Masters of the Demons, members of this class can gain tremendous power over demonkind, either for good or for evil ends. Their spells are contained in specific blades, shields and helms (actually shaped in the form of horns) which when wielded allow the Demonologist to cast spells unique to her class; each piece of equipment holds 3 spells. See the information on the *****m_demono.txt*0[Demonology] school of magic for more details. #####GStarting Stat Modifiers Strength +5 Intelligence -2 Wisdom -2 Dexterity +2 Constitution +2 Charisma -1 Hit Die +d9 Spell Points +0% Exp Penalty 0% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 2.000 [0.750] Weaponmastery 1.000 [0.750] Sword-mastery 0.000 [0.600] Archery 2.000 [0.400] Sneakiness 2.000 [1.800] Stealth 0.000 [0.400] Disarming 2.000 [1.800] Magic 2.000 [0.700] Magic-Device 1.000 [1.150] Demonology 1.000 [1.000] Spirituality 2.000 [0.700] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Extra Max Blow(1) 1 Extra Max Blow(2) 1 Spread blows 25 #####GStarting Equipment A Demonologist begins the game with: a Ring of Fear Resistance a Demonblade a Chain Mail tome-235-src/lib/help/lua_play.txt0000644000076400017500000007545211012107760014745 0ustar dgdg|||||oy #####R /----------------------------------------\ #####R < player.pkg functions helper file > #####R \----------------------------------------/ ---------------------------------------------------------------------- #####RFunction: set_parasite #####GDeclaration: bool set_parasite(int v, int r); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->parasite" and "p_ptr->parasite_r_idx" * notice observable changes */ #####GDescription: Set time "v" until parasite with monster index "r" is created. The player gets the message "You feel something growing in you" if "v" is > 0. Otherwise the player gets the message "Your body convulse and spawn " if the monster is created (80% chance) or "The hideous thing growing in you seems to die" if the monster dies. #####GParameters: >v is the time until the parasite gestates (must be between 0 and 10000). >r is the monster index of parasite to be created. ---------------------------------------------------------------------- #####RFunction: set_disrupt_shield #####GDeclaration: bool set_disrupt_shield(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->disrupt_shield" * notice observable changes */ #####GDescription: Set time "v" until shield of invulnerability expires. The player gets the message "You feel invulnerable" if "v" is > 0. Otherwise the player gets the message "You are more vulnerable". #####GParameters: >v is the time until the shield expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_prob_travel #####GDeclaration: bool set_prob_travel(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->prob_travel" * notice observable changes */ #####GDescription: Set time "v" until random teleportation expires. The player gets the message "You feel instable" if "v" is > 0. Otherwise the player gets the message "You are more stable". #####GParameters: >v is the time until random teleportation expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_tim_deadly #####GDeclaration: bool set_tim_deadly(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_deadly" */ #####GDescription: Set time "v" until deadly accuracy expires. The player gets the message "You feel extremely accurate" if "v" is > 0. Otherwise the player gets the message "You are suddenly much less accurate". #####GParameters: >v is the time until deadly accuracy expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_tim_res_time #####GDeclaration: bool set_tim_res_time(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_res_time" */ #####GDescription: Set time "v" until space-time distortions expire. The player gets the message "You are now protected against the space-time distortions" if "v" is > 0. Otherwise the player gets the message "You are no longer protected against the space-time distortions". #####GParameters: >v is the time until space-time distortions expire (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_tim_reflect #####GDeclaration: bool set_tim_reflect(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_reflect" */ #####GDescription: Set time "v" until reflection expire. The player gets the message "You start reflecting the world around you" if "v" is > 0. Otherwise the player gets the message "You stop reflecting". #####GParameters: >v is the time until reflection expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_meditation #####GDeclaration: bool set_meditation(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->meditation" */ #####GDescription: Set time "v" until meditation expire. The player gets the message "You start meditating on yourself" if "v" is > 0. Otherwise the player gets the message "You stop your self meditation". #####GParameters: >v is the time until meditation expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_strike #####GDeclaration: bool set_strike(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->strike" */ #####GDescription: Set time "v" until accurate strikes expire. The player gets the message "You feel very accurate" if "v" is > 0. Otherwise the player gets the message "You are no longer very accurate". #####GParameters: >v is the time until accurate strikes expire (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_walk_water #####GDeclaration: bool set_walk_water(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->walk_water", notice observable changes */ #####GDescription: Set time "v" until walking on water expires. The player gets the message "You feel strangely insubmersible" if "v" is > 0. Otherwise the player gets the message "You are no longer insubmersible". #####GParameters: >v is the time until walking on water expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_tim_ffall #####GDeclaration: bool set_tim_ffall(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_ffall" */ #####GDescription: Set time "v" until feather-fall expires. The player gets the message "You feel very light" if "v" is > 0. Otherwise the player gets the message "You are suddenly heavier". #####GParameters: >v is the time until feather-fall expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_tim_fire_aura #####GDeclaration: bool set_tim_fire_aura(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_fire_aura" */ #####GDescription: Set time "v" until fiery aura expires. The player gets the message "You are enveloped in flames" if "v" is > 0. Otherwise the player gets the message "You are no longer enveloped in flames". #####GParameters: >v is the time until fiery aura expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_holy #####GDeclaration: bool set_holy(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->holy", notice observable changes */ #####GDescription: Set time "v" until holiness expires. The player gets the message "You feel a holy aura around you" if "v" is > 0. Otherwise the player gets the message "The holy aura vanishes". #####GParameters: >v is the time until holiness expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_grace #####GDeclaration: void set_grace(s32b v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->grace", notice observable changes */ #####GDescription: Set grace to value "v". Don't allow grace to fall below -30000 or rise above 30000. #####GParameters: >v is the value of grace. ---------------------------------------------------------------------- #####RFunction: set_mimic #####GDeclaration: bool set_mimic(int v, int p); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_mimic", and "p_ptr->mimic_form", * notice observable changes */ #####GDescription: Set time "v" until morph into monster with monster index "p" expires. The player gets the message "You feel your body change" if "v" is > 0. Otherwise the player gets the message "You are no longer transformed". #####GParameters: >v is the time until transformation expires (must be between 0 and 10000). >p is the monster index of the monster the player wants to mimic. ---------------------------------------------------------------------- #####RFunction: set_no_breeders #####GDeclaration: bool set_no_breeders(int v); #####GFile: xtra2.c #####GComment: /* * Set "no_breeds" */ #####GDescription: Set time "v" until breeders can breed again. The player gets the message "You feel an anti-sexual aura" if "v" is > 0. Otherwise the player gets the message "You no longer feel an anti-sexual aura". Okay... #####GParameters: >v is the time until breeders can breed again (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_invis #####GDeclaration: bool set_invis(int v,int p); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_invis", and "p_ptr->tim_inv_pow", * notice observable changes */ #####GDescription: Set time "v" until invisibility expires. The player gets the message "You feel your body fade away" if "v" is > 0. Otherwise the player gets the message "You are no longer invisible". #####GParameters: >v is the time until invisibility expires (must be between 0 and 10000). >p is the power of timed invisibility. ---------------------------------------------------------------------- #####RFunction: set_lite #####GDeclaration: bool set_lite(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_lite", notice observable changes * * Note the use of "PU_VIEW", which is needed to * memorise any terrain features which suddenly become "visible". * Note that blindness is currently the only thing which can affect * "player_can_see_bold()". */ #####GDescription: Set time "v" until brightness expires. The player gets the message "You suddenly seem brighter" if "v" is > 0. Otherwise the player gets the message "You are no longer bright". #####GParameters: >v is the time until brightness expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_blind #####GDeclaration: bool set_blind(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->blind", notice observable changes * * Note the use of "PU_UN_VIEW", which is needed to memorise any terrain * features which suddenly become "visible". * Note that blindness is currently the only thing which can affect * "player_can_see_bold()". */ #####GDescription: Set time "v" until blindness expires. The player gets the message "You are blind" if "v" is > 0. Otherwise the player gets the message "You can see again". #####GParameters: >v is the time until blindness expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_confused #####GDeclaration: bool set_confused(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->confused", notice observable changes */ #####GDescription: Set time "v" until confusion expires. The player gets the message "You are confused" if "v" is > 0. Otherwise the player gets the message "You feel less confused now". #####GParameters: >v is the time until confusion expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_poisoned #####GDeclaration: bool set_poisoned(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->poisoned", notice observable changes */ #####GDescription: Set time "v" until poison expires. The player gets the message "You are poisoned" if "v" is > 0. Otherwise the player gets the message "You are no longer poisoned". #####GParameters: >v is the time until poison expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_afraid #####GDeclaration: bool set_afraid(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->afraid", notice observable changes */ #####GDescription: Set time "v" until fear expires. The player gets the message "You are terrified" if "v" is > 0. Otherwise the player gets the message "You feel bolder now". #####GParameters: >v is the time until fear expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_paralyzed #####GDeclaration: bool set_paralyzed(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->paralyzed", notice observable changes */ #####GDescription: Set time "v" until paralysis expires. The player gets the message "You are paralyzed" if "v" is > 0. Otherwise the player gets the message "You can move again". #####GParameters: >v is the time until paralysis expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_image #####GDeclaration: bool set_image(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->image", notice observable changes * * Note that we must redraw the map when hallucination changes. */ #####GDescription: Set time "v" until hallucination expires. The player gets the message "Oh, wow! Everything looks so cosmic now" if "v" is > 0. Otherwise the player gets the message "You can see clearly again". #####GParameters: >v is the time until hallucination expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_fast #####GDeclaration: bool set_fast(int v, int p); #####GFile: xtra2.c #####GComment: (none) #####GDescription: Set time "v" until speed of speed factor "p" expires. The player gets the message "You feel yourself moving faster" if "v" is > 0. Otherwise the player gets the message "You feel yourself slow down". #####GParameters: >v is the time until speed expires (must be between 0 and 10000). >p is the speed factor. ---------------------------------------------------------------------- #####RFunction: set_light_speed #####GDeclaration: bool set_light_speed(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->lightspeed", notice observable changes */ #####GDescription: Set time "v" until light-speed expires. The player gets the message "You feel as if time has stopped" if "v" is > 0. Otherwise the player gets the message "You feel time returning to its normal rate". #####GParameters: >v is the time until light-speed expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_slow #####GDeclaration: bool set_slow(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->slow", notice observable changes */ #####GDescription: Set time "v" until slowness expires. The player gets the message "You feel yourself moving slower" if "v" is > 0. Otherwise the player gets the message "You feel yourself speed up". #####GParameters: >v is the time until slowness expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_shield #####GDeclaration: bool set_shield(int v, int p, s16b o, s16b d1, s16b d2); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->shield", notice observable changes */ #####GDescription: Set time "v" until stone-shield expires. The player gets the message "Your skin turns to stone" if "v" is > 0. Otherwise the player gets the message "Your skin returns to normal". Stone-shield has spell power "p", spell option "o", and power options "d1" and "d2". #####GParameters: >v is the time until stone-shield expires (must be between 0 and 10000). >p is the power of the stone-shield spell. >o is the option of the stone-shield spell. >d1 is the power for option 1 of the stone-shield spell. >d2 is the power for option 2 of the stone-shield spell. ---------------------------------------------------------------------- #####RFunction: set_blessed #####GDeclaration: bool set_blessed(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->blessed", notice observable changes */ #####GDescription: Set time "v" until blessing expires. The player gets the message "You feel righteous" if "v" is > 0. Otherwise the player gets the message "The prayer has expired". #####GParameters: >v is the time until blessing expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_hero #####GDeclaration: bool set_hero(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->hero", notice observable changes */ #####GDescription: Set time "v" until heroism expires. The player gets the message "You feel like a hero" if "v" is > 0. Otherwise the player gets the message "The heroism wears off". #####GParameters: >v is the time until heroism expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_shero #####GDeclaration: bool set_shero(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->shero", notice observable changes */ #####GDescription: Set time "v" until berserk expires. The player gets the message "You feel like a killing machine" if "v" is > 0. Otherwise the player gets the message "You feel less Berserk". #####GParameters: >v is the time until berserk expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_protevil #####GDeclaration: bool set_protevil(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->protevil", notice observable changes */ #####GDescription: Set time "v" until protection from evil expires. The player gets the message "You feel safe from evil" if "v" is > 0. Otherwise the player gets the message "You no longer feel safe from evil". #####GParameters: >v is the time until protection from evil expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_protgood #####GDeclaration: bool set_protgood(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->protgood", notice observable changes */ #####GDescription: Set time "v" until protection from good expires. The player gets the message "You feel safe from good" if "v" is > 0. Otherwise the player gets the message "You no longer feel safe from good". #####GParameters: >v is the time until protection from evil expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_protundead #####GDeclaration: bool set_protundead(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->protundead", notice observable changes */ #####GDescription: Set time "v" until protection from undead expires. The player gets the message "You feel safe from undead" if "v" is > 0. Otherwise the player gets the message "You no longer feel safe from undead". #####GParameters: >v is the time until protection from undead expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_invuln #####GDeclaration: bool set_invuln(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->invuln", notice observable changes */ #####GDescription: Set time "v" until invulnerability expires. The player gets the message "Invulnerability" if "v" is > 0. Otherwise the player gets the message "The invulnerability wears off". #####GParameters: >v is the time until invulnerability expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_tim_invis #####GDeclaration: bool set_tim_invis(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_invis", notice observable changes */ #####GDescription: Set time "v" until see invisible expires. The player gets the message "Your eyes feel very sensitive" if "v" is > 0. Otherwise the player gets the message "Your eyes feel less sensitive". #####GParameters: >v is the time until see invisible expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_tim_infra #####GDeclaration: bool set_tim_infra(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_infra", notice observable changes */ #####GDescription: Set time "v" until infravision expires. The player gets the message "Your eyes begin to tingle" if "v" is > 0. Otherwise the player gets the message "Your eyes stop tingling". #####GParameters: >v is the time until infravision expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_mental_barrier #####GDeclaration: bool set_mental_barrier(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->tim_mental_barrier", notice observable changes */ #####GDescription: Set time "v" until mental barrier expires. The player gets the message "Your mind grows stronger" if "v" is > 0. Otherwise the player gets the message "Your mind is no longer especially strong". #####GParameters: >v is the time until mental barrier expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_acid #####GDeclaration: bool set_oppose_acid(int v); #####GFile: xtra2.c #####GComment: #####GDescription: Set time "v" until feather-fall expires. The player gets the message "You feel very light" if "v" is > 0. Otherwise the player gets the message "You are suddenly heavier". #####GParameters: >v is the time until feather-fall expires (must be between 0 and 10000). >v is the time until feather-fall expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_elec #####GDeclaration: bool set_oppose_elec(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->oppose_elec", notice observable changes */ #####GDescription: Set time "v" until electricity resistance expires. The player gets the message "You feel resistant to electricity" if "v" is > 0. Otherwise the player gets the message "You feel less resistant to electricity". #####GParameters: >v is the time until electricity resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_fire #####GDeclaration: bool set_oppose_fire(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->oppose_fire", notice observable changes */ #####GDescription: Set time "v" until fire resistance expires. The player gets the message "You feel resistant to fire" if "v" is > 0. Otherwise the player gets the message "You feel less resistant to fire". #####GParameters: >v is the time until fire resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_cold #####GDeclaration: bool set_oppose_cold(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->oppose_cold", notice observable changes */ #####GDescription: Set time "v" until cold resistance expires. The player gets the message "You feel resistant to cold" if "v" is > 0. Otherwise the player gets the message "You feel less resistant to cold". #####GParameters: >v is the time until cold resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_pois #####GDeclaration: bool set_oppose_pois(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->oppose_pois", notice observable changes */ #####GDescription: Set time "v" until poison resistance expires. The player gets the message "You feel resistant to poison" if "v" is > 0. Otherwise the player gets the message "You feel less resistant to poison". #####GParameters: >v is the time until poison resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_ld #####GDeclaration: bool set_oppose_ld(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->oppose_ld" */ #####GDescription: Set time "v" until light and dark resistance expires. The player gets the message "You feel protected against the light's fluctuation" if "v" is > 0. Otherwise the player gets the message "You are no longer protected against the light's fluctuation". #####GParameters: >v is the time until light and dark resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_cc #####GDeclaration: bool set_oppose_cc(int v); #####GFile: xtra2.c /* * Set "p_ptr->oppose_cc" */ #####GComment: #####GDescription: Set time "v" until chaos resistance expires. The player gets the message "You feel protected against raw chaos" if "v" is > 0. Otherwise the player gets the message "You are no longer protected against chaos". #####GParameters: >v is the time until chaos resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_ss #####GDeclaration: bool set_oppose_ss(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->oppose_ss" */ #####GDescription: Set time "v" until sound and shard resistance expires. The player gets the message "You feel protected against the ravages of sound and shards" if "v" is > 0. Otherwise the player gets the message "You are no longer protected against the ravages of sound and shards". #####GParameters: >v is the time until sound and shard resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_oppose_nex #####GDeclaration: bool set_oppose_nex(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->oppose_nex" */ #####GDescription: Set time "v" until nexus resistance expires. The player gets the message "You feel protected against the strange forces of nexus" if "v" is > 0. Otherwise the player gets the message "You are no longer protected against the strange forces of nexus". #####GParameters: >v is the time until nexus resistance expires (must be between 0 and 10000). ---------------------------------------------------------------------- #####RFunction: set_stun #####GDeclaration: bool set_stun(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->stun", notice observable changes * * Note the special code to only notice "range" changes. */ #####GDescription: Set stun level "v". If the player race can't be stunned then the level is forced to 0. A value > 100 means the player is knocked out. A value >50 is a heavy stun. A value > 0 is a stun. If the stun level has increased, a message is printed. There is a small chance of stun level in 1000, or a 1 in 16 chance of a vicious blow which decreases intelligence and/or wisdom for a while. #####GParameters: >v is the stun level. ---------------------------------------------------------------------- #####RFunction: set_cut #####GDeclaration: bool set_cut(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->cut", notice observable changes * * Note the special code to only notice "range" changes. */ #####GDescription: Set cut level "v". If the player race can't be cut then the time is forced to 0. A value > 1000 is a mortal wound. A value > 200 is a deep gash. A value > 100 is a severe cut. A value > 50 is a nasty cut. A value > 25 is a bad cut. A value > 10 is a light cut. A value > 0 is a graze. If the cut level has increased, a message is printed. There is a small chance of stun level in 1000, or a 1 in 16 chance of scarring which decreases charisma for a while. #####GParameters: >v is the cut level. ---------------------------------------------------------------------- #####RFunction: set_food #####GDeclaration: bool set_food(int v); #####GFile: xtra2.c #####GComment: /* * Set "p_ptr->food", notice observable changes * * The "p_ptr->food" variable can get as large as 20000, allowing the * addition of the most "filling" item, Elvish Waybread, which adds * 7500 food units, without overflowing the 32767 maximum limit. * * Perhaps we should disturb the player with various messages, * especially messages about hunger status changes. XXX XXX XXX * * Digestion of food is handled in "dungeon.c", in which, normally, * the player digests about 20 food units per 100 game turns, more * when "fast", more when "regenerating", less with "slow digestion", * but when the player is "gorged", he digests 100 food units per 10 * game turns, or a full 1000 food units per 100 game turns. * * Note that the player's speed is reduced by 10 units while gorged, * so if the player eats a single food ration (5000 food units) when * full (15000 food units), he will be gorged for (5000/100)*10 = 500 * game turns, or 500/(100/5) = 25 player turns (if nothing else is * affecting the player speed). */ #####GDescription: Set hunger level "v". A value < 500 is fainting. A value < 1000 is weak. A value < 2000 is weak. A value < 10000 is full. A value < 15000 is bloated. A value < 20000 is gorged. If one of these levels is crossed a message is printed. #####GParameters: >v is the hunger level (must be between 0 and 20000). ---------------------------------------------------------------------- #####RFunction: check_experience #####GDeclaration: void check_experience(void); #####GFile: xtra2.c #####GComment: /* * Advance experience levels and print experience */ #####GDescription: Check if player experience level has changed. If a player has achieved a level for the first time, give reward or corruption (1 chance in 3) if they apply, and increase skill points. ---------------------------------------------------------------------- #####RFunction: check_experience_obj #####GDeclaration: void check_experience_obj(object_type *o_ptr); #####GFile: xtra2.c #####GComment: /* * Advance experience levels and print experience */ #####GDescription: Check if object "o_ptr" experience level has changed. If an object has achieved a level for the first time, apply gains. #####GParameters: >o_ptr is the pointer to the object gaining experience. ---------------------------------------------------------------------- #####RFunction: gain_exp #####GDeclaration: void gain_exp(s32b amount); #####GFile: xtra2.c #####GComment: /* * Gain experience (share it to objects if needed) */ #####GDescription: Gain "amount" of experience. Count the number of objects which will gain experience. The objects share equally 2/3 of "amount". Give corruption if it applies. Gain experience. If experience is less than maximum, then increase maximum experience by 20% of "amount". Check for level change and print experience (check_experience). #####GParameters: >amount is the amount of experience to share. ---------------------------------------------------------------------- #####RFunction: lose_exp #####GDeclaration: void lose_exp(s32b amount); #####GFile: xtra2.c #####GComment: /* * Lose experience */ #####GDescription: Decrease experience by "amount". Experience can not fall below zero. Check for level change and print experience (check_experience). #####GParameters: >amount is the amount of experience to lose. ---------------------------------------------------------------------- Back to the *****lua.hlp*0[lua help index] . [[[[[gThis file by Chris Hadgis] tome-235-src/lib/help/r_dwarf.txt0000644000076400017500000000300011012107760014537 0ustar dgdg~~~~~01|Dwarf ~~~~~02|Races|Dwarf #####R=== Dwarves === #####GDescription Dwarves are the headstrong miners and fighters of legend. Since dungeons are the natural home of a dwarf, they are excellent choices for a warrior or priest. Dwarves tend to be stronger and tougher but less agile and intelligent than humans. Because they are so headstrong and are somewhat wise, they resist spells which are cast on them. Dwarves also have very good infra-vision because they live underground. They do have one big drawback, though: dwarves are loud-mouthed and proud, singing in boisterous voices, arguing with themselves for no good reason, and screaming out challenges at nearby foes. In other words, dwarves have miserable stealth. They can never be blinded, and they can also open secret tunnels through rock. #####GStat Modifiers Strength +2 Intelligence -2 Wisdom +2 Dexterity -2 Constitution +2 Charisma -3 Hit Dice Sides 11 Exp Penalty +25% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 1.500 [0.000] Axe-mastery 0.000 [0.200] Archery 0.500 [0.000] Sneakiness 0.700 [0.000] Stealth -1.000 [0.000] Disarming 0.200 [0.000] Magic Magic-Device 0.900 [0.000] Spirituality 5.000 [0.000] tome-235-src/lib/help/c_assass.txt0000644000076400017500000000400511012107760014720 0ustar dgdg~~~~~01|Assassin ~~~~~02|Classes|Assassin #####R=== Assassins === #####GDescription Assassins are similar to Rogues, but have trained their combat abilities more extensively by neglecting the study of magic. They also tend to be more stealthy and careful in their dungeon exploration, but aren't so good at stealing, trapping and disarming as their more "peaceful" counterparts. Assassins have access to the schools of *****m_convey.txt*0[Conveyance], *****m_divin.txt*0[Divination] and *****m_tempo.txt*0[Temporal] magic. #####GStarting Stat Modifiers Strength +2 Intelligence +1 Wisdom -2 Dexterity +3 Constitution +1 Charisma -1 Hit Die +d6 Spell Points +0% Exp Penalty 25% #####GStarting Skills #####BSkill Start Level Skill Point Gains Combat 1.000 [0.800] Weaponmastery 1.000 [0.800] Sword-mastery 1.000 [0.600] Critical-hits 2.000 [0.800] Archery Boomerang-mastery 1.000 [0.300] Sneakiness 1.000 [2.000] Stealth 1.000 [2.000] Disarming 1.000 [1.000] Backstab 1.000 [2.000] Stealing 1.000 [0.200] Dodging 1.000 [2.000] Magic 1.000 [0.200] Magic-Device 1.000 [0.750] Conveyance 0.000 [0.100] Divination 0.000 [0.100] Temporal 0.000 [0.200] Spirituality 1.000 [0.700] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] *An Assassin cannot learn the Archery skill, but it is shown in his skill screen because Boomerang-mastery is a sub-skill of it. #####GInnate Abilities: #####BAbility Character level Extra Max Blow(1) 10 #####GStarting Equipment An Assassin begins the game with: a Dagger tome-235-src/lib/help/dungeon.txt0000644000076400017500000010710411012107760014564 0ustar dgdg|||||oy ~~~~~02|Dungeons #####R /----------------------------------------\ #####R < The Dungeons and Places of Middle-earth > #####R \----------------------------------------/ *****dungeon.txt*04[Symbols On Your Map] *****dungeon.txt*07[The Town and Buildings] *****dungeon.txt*01[The Wilderness] *****dungeon.txt*06[In the Dungeon] *****dungeon.txt*08[Objects] *****dungeon.txt*13[Mining] *****dungeon.txt*12[Doors, Rooms, Staircases etc.] *****dungeon.txt*18[Pets] *****dungeon.txt*14[Winning] *****dungeon.txt*15[Dying] *****dungeon.txt*16[Where to get more help] After you have *****birth.txt*0[created your character], you will begin your ToME adventure. Symbols appearing on your screen will represent the world's walls, floor, objects, features, and creatures lurking about. In order to direct your character through his adventure, you will enter single character commands (see "*****command.txt*0[command.txt]"). ~~~~~03|Symbols ~~~~~04|Identifying features #####R=== Symbols On Your Map === Symbols on your map can be broken down into three categories: Features of the world such as walls, floor, doors, and traps; Objects which can be picked up such as treasure, weapons, magical devices, etc; and creatures which may or may not move about the dungeon, but are mostly harmful to your character's well being. Some symbols are used to represent more than one type of entity, and some symbols are used to represent entities in more than one category. The "@" symbol (by default) is used to represent the character. It will not be necessary to remember all of the symbols and their meanings. The "slash" command ("/") will identify any character appearing on your map (see "*****command.txt*0[command.txt]"). Note that you can use a *****command.txt*105["user pref file"] to change any of these symbols to something you are more comfortable with. #####G Features that do not block line of sight . A floor space 1 Entrance to General Store . A trap (hidden) 2 Entrance to Armoury ^ A trap (known) 3 Entrance to Weapon Smith [[[[[y;] A glyph of warding 4 Entrance to Temple [[[[[U'] An open door 5 Entrance to Alchemy Shop [[[[[U'] A broken door 6 Entrance to Magic Shop < A staircase up 7 Entrance to the Black Market [[[[[y<] A quest exit 8 Entrance to your Home [[[[[r<] A quest up level 9 Entrance to Bookstore [[[[[U<] A shaft up [[[[[r>] A quest down level > A staircase down [[[[[U>] A shaft down [[[[[y>] A quest entrance [[[[[v>] Dungeon entrance _ A fountain [[[[[D_] An empty fountain * Straight road start/exit [[[[[B*] Section of the Straight Road [[[[[b*] Section of the Straight Road [[[[[W*] Section of the Straight Road [[[[[D*] Corrupted straight road [[[[[R*] An explosive rune [[[[[B~] Stream of water (shallow) [[[[[b~] Stream of water (deep) [[[[[u~] Tainted stream (water) [[[[[s#] Underground tunnel [[[[[U#] Pool of lava (shallow) [[[[[r#] Pool of lava (deep) [[[[[D#] Dark pit [[[[[u.] Dirt [[[[[g.] Patch of Grass [[[[[W.] Ice [[[[[y.] Sand [[[[[D.] Ash [[[[[u.] Mud [[[[[v.] Nether mist [[[[[r.] Floor [[[[[D0] Altar of Darkness [[[[[R0] Altar of Force [[[[[B0] Altar of Winds [[[[[W0] Altar of Being [[[[[v+] Void Jumpgate [[[[[v;] Monster trap [[[[[B.] Glass wall [[[[[w#] Illusion wall [[[[[g;] Grass with flowers [[[[[w.] Cobblestone road [[[[[g#] Small tree [[[[[w*] Town (in wilderness) [[[[[U^] Underground tunnel [[[[[y+] A web #####G Features that block line of sight [[[[[w#] A secret door # A wall [[[[[U+] A closed door % A mineral vein [[[[[U+] A locked door [[[[[o*] A mineral vein + treasure [[[[[U+] A jammed door [[[[[w:] A pile of rubble [[[[[D#] A dead tree [[[[[W#] Ice wall [[[[[G#] A tree [[[[[y#] Sand wall [[[[[U^] A mountain chain [[[[[W^] High mountain chain #####G Objects ! A potion (or flask) / A pole-arm ? A scroll, book, map, parchment / Music instrument ? A rune, runestone | An edged weapon , A mushroom (or food) \ A hafted weapon or digger - A wand, rod or rod tip } A sling, bow, or x-bow _ A staff { A shot, arrow, bolt, boomerang = A ring ( Soft armour/cloak " An amulet [ Hard armour $ Gold or gems ] Misc. armour ~ Lites, Tools, Chests, etc ) A shield ~ Junk, Sticks, Skeletons, etc ` Trapping kit, climbing set ~ Stone, random artifact o Egg * An essence & (unused) ~~~~~05|Monsters #####G Monsters $ Creeping Coins , Mushroom Patch a Giant Ant A Angelic being b Giant Bat B Bird c Giant Centipede C Canine d Dragon D Ancient Dragon e Floating Eye E Elemental f Feline F Dragon Fly g Golem G Ghost h Humanoids H Hybrid i Icky-Thing I Insect j Jelly J Snake k Kobold K Killer Beetle l Giant Louse L Lich m Mold M Multi-Headed Hydra n Naga N (unused) o Orc O Ogre p Human P Giant Human(oid) q Quadruped Q Quylthulg r Rodent R Reptile/Amphibian s Skeleton S Spider/Scorpion/Tick t Townsperson T Troll u Minor demon U Major demon v Vortex V Vampire w Worm or Worm Mass W Wight/Wraith x (unused) X Xorn/Xaren y Yeek Y Yeti z Zombie/Mummy Z Zephyr Hound ~~~~~07|Town #####R=== The Town Level === The town level is where you will begin your adventure. The town consists of several buildings (most with an entrance), some townspeople, and a main wall which surrounds the town (with gates in it). Outside the gates may be found unclaimed lands and wilderness, where beasts still run wild. The first time you are in town it will be daytime (unless you are an undead character), but note that the sun will rise and set (rather instantly) as time passes. There are a few different towns around the world map, and your starting town will eventually become too small for you (if you survive the dangers of the dungeon). Other towns will have some different facilities, and you can find your way to other towns by reading the "Adventurer's Guide to Middle-earth" parchment with which *every* character begins the game. #####R=== Townspeople === The town contains many different kinds of people. There are the street urchins, young children who will mob an adventurer for money, and seem to come out of the woodwork when excited. Blubbering idiots are a constant annoyance, but not harmful. Public drunks wander about the town singing, and are of no threat to anyone. Sneaky rogues who work for the black market are always greedily eyeing your backpack for potential new 'purchases'... And finally, what town would be complete without a swarm of half drunk warriors, who take offense or become annoyed just for the fun of it. Most of the townspeople should be avoided by the largest possible distance when you wander from store to store. Fights will break out, though, so be prepared. Since your character grew up in this world of intrigue, no experience is awarded for killing the town inhabitants, though you may acquire treasure. ~~~~~21|Buildings #####R=== Town Buildings === Your character will begin his adventure with some basic supplies, and some extra gold with which to purchase more supplies at the town stores. You may enter any open store and barter with the owner for items you can afford. When bartering, you enter prices you will pay (or accept) for some object. You can either enter the absolute amount, or precede a number with a plus or minus sign to give a positive or negative increment on your previous offer. But be warned that the owners can easily be insulted, and may even throw you out for a while if you insult them too often. [[[[[BTo enter] [[[[[Ba store, simply move onto the entrance, which is represented by a number] [[[[[Bfrom 1 to 9.] If you consistently bargain well in a store, that is, you reach the final offer much more often than not, then the store owner will eventually recognise that you are a superb haggler, and will go directly to the final offer instead of haggling with you. Items which cost less than 10 gold pieces do not count, as haggling well with these items is usually either very easy or almost impossible. The more expensive the item is, the less likely the store owner is to assume that you are a good haggler. Note that you may disable haggling with a software option, though this will inflict a 10% "sales tax" on all purchases for which the store owner would have required you to haggle. Once inside a store, you will see the name and race of the store owner, the name of the store, the maximum amount of cash that the store owner will pay for any one item, and the store inventory, listed along with tentative prices, which will become "fixed" (at the "final offer") should you ever manage to haggle a store owner down to his final offer. You will also see an (incomplete) list of available commands. Note that many of the commands which work in the dungeon work in the stores as well, but some do not, especially those which involve "using" objects. Stores do not always have everything in stock. As the game progresses, they may get new items, so check back from time to time. Also, if you sell them an item, it may get sold to a customer while you are adventuring, so don't always expect to be able to get back everything you have sold. If you have a lot of spare gold, you can purchase every item in a store, which will induce the store owner to bring out new stock, and perhaps even retire. If you are low on funds (and morals), you may attempt to steal an item from the store, but beware -- if you are caught, the store owner will not let you back in for a very long time. Store owners will not buy harmful or useless items. If an object is unidentified, they will pay you some base price for it. Once they have bought it they will immediately identify the object. If it is a good object, they will add it to their inventory. If it was a bad bargain, they simply throw the item away. In any case, you may receive some knowledge of the item in case another is encountered. #####GThe General Store ("1") The General Store sells foods, drinks, some clothing, torches, lamps, oil, shovels, picks, and spikes. All of these items and some others can be sold back to the General store for money. #####GThe Armoury ("2") The Armoury is where the town's armour is fashioned. All sorts of protective gear may be bought and sold here. #####GThe Weaponsmith's Shop ("3") The Weaponsmith's Shop is where the town's weapons are fashioned. Hand and missile weapons may be purchased and sold here, along with arrows, bolts, and shots. #####GThe Temple ("4") The Temple deals in healing and restoration potions, as well as bless scrolls, word of recall scrolls, some approved priestly weapons, and priest spell books. #####GThe Alchemy shop ("5") The Alchemy Shop deals in all types of potions and scrolls. #####GThe Magic User's Shop ("6") The Magic User's Shop deals in all sorts of rings, wands, amulets, and staves, as well as spell books. #####GThe Black Market ("7") The Black Market will sell and buy anything at extortionate prices. However it occasionally has VERY good items in it. The shopkeepers are not known for their tolerance... #####GYour Home ("8") This is your house where you can store objects that you cannot carry on your travels, or will need at a later date. #####GThe Bookstore ("9") The Bookstore deals in all sorts of magical books. You can purchase and sell spellbooks for spellcasters and priests here. #####ROther Buildings In addition to the basic stores, there are some special buildings that can be found in some towns. These Buildings (represented by +'s) include: #####GMayor's Office/Castle The home office for the town. Adventurers looking for work besides exploring the dungeon should hunt in here. #####GPet Shop Great place to purchase eggs and get pets. #####GThe Soothsayer To discover what *****/afatespoi.txt*0[fates ("a")] lie in store for you. #####GThe Prancing Pony Wine, dine, rest and relax! #####GThe Nest Thunderlords are masters of teleportation, and will consent to bear you to your chosen dungeon destination for a fee. #####GBeastmaster Shanty For those who enjoy trophy hunting, and to research that strange animal you saw during your adventures. #####GFighters Hall The place to reforge weapons and armour. #####GRangers Guild The place to reforge distance weapons and their ammunition. #####GLibrary For information of all kinds. #####GGambling House Read the *****/bgambling.txt*0[rules ("b")] before paying. The games are not rigged, just naturally difficult. #####GTower of Magery/Wizards Spire The wizards will identify your items or recharge your magical items for a fee. #####GInner temple/Priests Circle A place of healing. #####GPaladin guild Some healing and enchantments available. #####GThe Mathom House Donate important, but unwanted items you find in the dungeon. ~~~~~1|Wilderness #####R=== The Wilderness and the Wilderness Map === Between the towns, the hand of civilisation has not tamed the lands, and wild creatures run rampant. This is another place that is worth exploring. Hidden within the wilderness are several interesting locations, with the four main ones for any adventurer - Barrow Downs, Mirkwood, Mordor and Angband each being located at or near one of the main towns of Middle- earth. These locations should be explored consecutively, as each one increases in difficulty from the point where the previous dungeon finished. A new character should not try to go at Mordor or Angband as their first dungeon (well, not if you wish to survive your first step, anyway)! As well as these (and other) locations, the wilderness can be a good place to go when you are seeking a change from the scenery of the dungeons, or just a bit of fast experience. Be warned - some creatures found in the wilderness can be quite dangerous, and travel through the wilderness can be time-consuming. If you are wishing to simply move to another town, there is an overview map (called the "Wilderness Map") that can be travelled through by going up "<" from the town level. While travelling through this map, your character is still having to actually walk through each square of the normal view, but you only see the end result of them moving from one 4x4 panel to the next. As such, food consumption will appear to be much higher in the Wilderness View than it is normally, and it is recommended that you travel prepared. It is also possible for the wild creatures within the wilderness to ambush you when travelling, which will force you out of the Wilderness Map so that you can safely get yourself out of trouble, before continuing on your way. All of the special locations can be seen as downstairs (">") on the Wilderness Map and towns as "*"s. This makes it *much* easier to find your way from one interesting place to another. The "Adventurer's Guide to Middle-earth" (a parchment with which *every* character begins the game) contains details about the towns and some of the dungeons, including rough directions on how to get there. ~~~~~06|Dungeons|In the dungeon #####R=== Within The Dungeon === Once your character is adequately supplied with food, light, armor, and weapons, he is ready to enter Barrow Downs. Move on top of the ">" symbol and use the "Down" command (">"). Your character will enter a maze of interconnecting staircases and finally arrive somewhere on the first level of the dungeon. Each level of the dungeon is fifty feet high (thus dungeon level "Lev 1" is often called "50 ft"), and is divided into rectangular regions several times larger than the screen. Once you leave a level by a staircase, you will never again find your way back to that region of that level, but there are an infinite number of other regions at that same "depth" that you can explore later. So be careful that you have found all the treasure before you leave a level, or you may never find it again! The monsters, of course, can use the stairs, and you may eventually encounter them again. In the dungeon, there are many things to find, but your character must survive many horrible and challenging encounters to find the treasure lying about and take it safely back to the town to sell. ~~~~~23|Light There are two sources for light once inside the dungeon: permanent light which has been magically placed within rooms, and a light source carried by the player (or some of the monsters). If neither is present, the character will be unable to see. This will affect searching, picking locks, disarming traps, reading scrolls, casting spells, browsing books, etc. So be very careful not to run out of light! A character must wield a torch or lamp in order to supply his own light. A torch or lamp burns fuel as it is used, and once it is out of fuel, it stops supplying light. You will be warned as the light approaches this point. You may use the "Fuel" command ("F") to refuel your lantern (with flasks of oil) or your torch (with other torches), so it is a good idea to carry extra torches or flasks of oil, as appropriate. There are rumours of objects of exceptional power which glow with their own never-ending light. ~~~~~08|Objects #####R=== Objects Found In The Dungeon === The mines are full of objects just waiting to be picked up and used. How did they get there? Well, the main source for useful items are all the foolish adventurers (like you?) that proceeded into the dungeon before you. They get killed, and the helpful creatures scatter the various treasures throughout the dungeon. Most cursed items are placed there by the joyful evil sorcerers, who enjoy a good joke when it gets you killed. You pick up objects by moving on top of them. You can carry up to 23 different items in your backpack while wearing and wielding up to 12 others. Although you are limited to 23 different items, each item may actually be a "pile" of up to 99 similar items. If you somehow manage to stuff 24 items into your pack, for example, by removing an item from your head while your pack is full, then your pack will "overflow" and the most recently added item will fall out and onto the ground. You will be warned about any command that seems likely to induce this behaviour. You are, in addition, limited in the total amount of weight that you can carry. As you approach this value, you become slower, making it easier for monsters to chase you. Note that there is no upper bound on how much you can carry, if you do not mind being slow. Your weight limit is determined by your strength. Objects do not block the line of sight, but may stack on top of one another, with the one on top hiding others beneath it. Q: I'm standing on a pile of items. How do I see what's in the pile without picking it all up, moving it, or destroying it all? A: 1. Stand on the pile in question 2. Type shift + i (examine) 3. Type - (examine items on floor) 4. Type * (expand list of items on floor) 5. (as needed) Type letter associated with item to look at it more closely. Objects may also obscure stairs, Ways and void jumpgates. Q: I'm standing on a pile of items. Is there a command to see if there is a stair beneath the pile? A: Stairs, void jumpgates and Ways that obscured by clutter still function. You are advised to take a good hard look at your surroundings before creating lots of dungeon clutter. You can see if there is a stair beneath the pile with either of these methods: 1. Pick up, move, or eliminate the pile. 2. Press l (look), then select the square you wish to inquire about. Press ; it will scroll through everything on the ground, and eventually it ends with "It is in a Void Jumpgate", or whatever. Many objects found within the dungeon have special commands for their use. Wands must be Aimed, staves must be Used, scrolls must be Read, and potions must be Quaffed. You may, in general, not only use items in your pack, but also items on the ground, if you are standing on top of them. For a detailed list of the commands to use objects, see *****command.txt*0[command.txt]. Chests are complex objects, containing traps, locks, and possibly treasure or other objects inside them once they are opened. Many of the commands that apply to traps or doors also apply to chests and, like traps and doors, these commands do not work if you are carrying the chest. One item in particular will be discussed here. [[[[[BThe scroll of "Word of] [[[[[BRecall"] can be found within the dungeon, or bought at the temple in town. It acts in two manners, depending upon your current location. If read within the dungeon, it will teleport you back to town. If read in town, it will teleport you back down to the deepest level of the dungeon to which your character has previously journeyed. This makes the scroll very useful for getting back to the deeper levels of the dungeon. Once the scroll has been read it takes a while for the spell to act, so don't expect it to save you in a crisis. Reading a second scroll before the first has had a chance to take effect will cancel both scrolls. Since an accidental dive to a new depth (via a trapdoor, for example), may result in the Word of Recall dungeon depth being 'broken', so to speak (meaning that the next Word of Recall in town will take you back deeper than you would like to), there is a feature in ToME which allows you to read a scroll of Word of Recall on a different level and 'reset' the recall depth to that level (instead of the deepest level). Some dungeons cannot be recalled into, though you can still recall out. You may "inscribe" any object with a textual inscription of your choice. These inscriptions are not limited in length, though you may not be able to see the whole inscription on the item. The game applies special meaning to inscriptions containing any text of the form "@#" or "@x#" or "!x" or "!*", see "*****command.txt*0[command.txt]" and "*****macrofaq.txt*0[macrofaq.txt]". The game provides some "fake" inscriptions to help you keep track of your possessions. Wands and staves which are known to be empty will be inscribed with "empty". Objects which have been tried at least once but haven't been identified yet will be inscribed with "tried". Cursed objects are inscribed with "cursed". Broken objects may be inscribed with "broken". Also, any item which was purchased at a discount, implying that it is slightly "sub-standard", will be inscribed with the appropriate "discount", such as "25% off". Note that these inscriptions are fake, and cannot be removed, though they can be covered up by a real inscription if you so desire. Try "_" as a nice short one. Also, occasionally you will notice that something in your inventory or equipment list seems to be magical. High level characters are much more likely to notice this than beginning characters. When you do notice this, the item in question will be inscribed with "good" or "cursed" as is relevant. You can increase your ability to notice magical effects of armour and weapons by increasing the *****skills.txt*01[Combat] skill. You can increase your ability to sense particularly well enchanted magical items (potions, scrolls. wands etc) by increasing your *****skills.txt*21[Magic] skill. If you increase these high enough, you will gain a special method of "sensing" your inventory/equipment items, which tells you not only whether an item is "good" or "cursed", but also if it is "average", "special", "excellent", "terrible" or "worthless". ~~~~~21|Objects|Colour of inventory slot letter The colour of the letter that identifies each item in your backpack can tell you something about their magical status. Grey indicates the item has not been identified yet. After identification, the colour changes to one of the following: white, indicating it is normal; blue indicates it is an ego-item (pseudo-id's as {excellent}); yellow indicates it is an artifact {special}; green shows it is an artifact which is part of a set. It is rumoured that rings of power and extra rare spell books may be found deeper in the dungeon.... And lastly, a final warning: not all objects are what they seem. The line between tasty food and annoying mushroom is a fine one, and sometimes a potion will reach out and bite you... ~~~~~09|Objects|Cursed Objects ~~~~~10|Cursed Objects #####R=== Cursed Objects === Some objects, mainly armour and weapons, have had curses laid upon them. These horrible objects will look like any other normal item, but will detract from your character's stats or abilities if worn. They will also be impossible to remove until the curse is removed. In fact some are so badly cursed that even this will not work, and more potent methods are needed. If you wear or wield a cursed item, you will immediately feel something wrong. The item will also be inscribed "cursed". Shopkeepers will refuse to buy any known cursed item. ~~~~~13|Mining ~~~~~11|Dungeons|Mining #####R=== Digging and Mining === It is possible for you to be trapped within the dungeon. You will not be able to dig your way out without a digging tool (shovel, pick, or other means of digging). It is absolutely essential to always carry some kind of digging tool, even when you are not planning on tunnelling for treasure. Do not leave the town level of Bree without a digger! Picks and shovels have a digging ability expressed as "(+)", e.g. (+2). The higher the number, the better the digging ability of the tool. Diggers are effective against rubble, trees, and many walls. Rubble and veins may hide treasure; trees do not. You dig in something with the tunnel (shift + t) command. Thorough digging removes one ASCII square (i.e. tile) of what is being dug. This may require multiple attempts depending on how good your digger is (and how high your strength is). Once the square is removed, you will be informed if you found anything there. If another diggable square exists beyond the area you just dug, you can begin the process again. Some dungeons contain rich strikes which may be found only by mining it out of the walls. Quartz veins are the richest, yielding the most metals and gems, but magma veins may also hide hoards within them. When digging rock, granite is much harder to dig through than quartz or magma veins, so it is much faster to follow a vein exactly and dig around the granite. There is also a game option for highlighting magma and quartz within the walls, which makes this easier. If the character has a scroll, staff, or spell of treasure location, she can immediately locate all strikes of treasure within a vein shown on the screen. This makes mining much easier and more profitable. ~~~~~12|Dungeons|Doors, Passages, Rooms and Staircases #####R=== Staircases, Ways, Void jumpgates, Secret Doors, Passages, and Rooms === Staircases are the manner in which you get deeper or climb out of the dungeon. The symbols for the up and down staircases are the same as the commands to use them. A "<" represents an up staircase and a ">" represents a down staircase. You must move your character over the staircase before you can use it. You use it by typing the same character as the staircase itself (either "<" or ">".) In flat environments such as forests, Ways replace staircases. On the map, Ways are identical to staircases and behave the same way. Yellow down stairs and Ways are quest entrances (although not every quest is reached by such means). Shafts are also represented by "<" or ">", but are brown. They work similarly to stairs and Ways, but if you use one, you might traverse more than one dungeon level all in one go as a result. Stairs, impenetrable walls, and shop entrances like titanium walls, and the doors into shops, cannot be destroyed by any means (although their location can occasionally change under the right circumstances). ~~~~~23|Void jumpgates A void jumpgate appears on your map as a violet "+". Jumpgates always occur in pairs. To activate a jumpgate, stand on it and type ">". You will instantly appear on top of its paired jumpgate, which will be somewhere else on the same dungeon level. Many secret doors are used within the dungeon to confuse and demoralise adventurers foolish enough to enter. But with some luck, and lots of concentration, you can find these secret doors. Secret doors will sometimes hide rooms or corridors, or even entire sections of that level of the dungeon. Sometimes they simply hide small empty closets or even dead ends. Secret doors always look like granite walls, just like traps always look like normal floors. Creatures in the dungeon will generally know and use these secret doors, and can sometimes be counted on to leave them open behind them when they pass through. For historical reasons, secret doors are never locked. ~~~~~18|Pets ~~~~~19|Companions ~~~~~20|Monsters|Pets #####R=== Pets and Companions === You may, in the course of a game, acquire friendly monsters who will help you defeat enemies. There are several different types of these, you can determine which your monster is by 'l'ooking at it. [[[[[vneutral] This monster will not help you by attacking other monsters, but nor will it attack you. [[[[[vco-aligned] This monster will attack other enemy monsters, but you will not gain any experience for its kills. [[[[[vpet] This monster will kill things for you. The amount of experience you gain from its kills is determined by the level of your *****skills.txt*42[Monster-lore] skill. This monster will gain levels and experience of its own, but cannot travel between dungeon levels. [[[[[vcompanion] This type of monster will not only take experience and level up like pets, but will also follow you from one dungeon level to the next. If you successfully complete an adventurer quest for a lost sword and let him join you, he will become a companion. Once again the amount of experience you gain from a companion's kill depends upon your Monster-lore skill. Your Monster-lore skill also determines the maximum number of pets and companions you can have at any one time. Pets, companions and co-aligned creatures cannot deliver killing blows to uniques or quest monsters. You must do this yourself! You can give commands to pets and companions to make them more useful, using the "P" command. The list of available commands is as follows: [[[[[vdismiss companions] Dismisses your companions. They can be difficult to get rid of any other way. [[[[[vdismiss pets] Dismisses pets. You will be given the opportunity to dismiss all current pets, or if you answer no to that first question, to dismiss specific pets. [[[[[vcall pets] Calls your pets (and companions) to you. [[[[[vfollow me] Asks your pets (and companions) to follow you. They do have a mind of their own, and may not be able to travel as fast as you can. [[[[[vseek and destroy] Selecting this will cause your pets and companions to wander further from you, looking for enemies to kill. [[[[[vallow/disallow open doors] Selecting this toggles whether your pets and companions can open doors. [[[[[vallow/disallow pickup items] Selecting this toggles whether your pets and companions can pick up items. Disallowing it will cause the monster to drop any items he is carrying on the floor. [[[[[vgive target to a friend] Selecting this will cause one of your pets or companions to attack your current target. [[[[[vgive target to all friends] Causes all pets or companions to attack your current target. [[[[[vfriend forget target] All your friends will follow their normal attack patterns, neglecting any targets you have given them. ~~~~~14|Objectives #####R=== Game Objectives === In ToME you will be required to complete a certain number of quests. Your first quest is to discover the true nature of the evil lurking in the Tower of Dol Goldur near Mirkwood. Each quest may lead on to others, and most quests can be postponed until when you feel ready to tackle them. Simply explore other dungeons until you feel you have gained enough experience to tackle your next task. Other quests are optional and can be used for further experience. Once you have finished your final quest, when you are ready to retire, simply "commit suicide" ("^Q") to have your character entered into the high score list as a winner. Note that until you retire, you can still be killed, so you may want to retire before wandering into a hoard of nasties.... You may also like to make a character sheet of your winning character (by going through the "C"haracter screen and choosing "f"ile), and post in the rec.games.roguelike.angband newsgroup with a text copy of the dump pasted into the post. Include details about anything major that happened to your character - did they find a ring of speed (+10) on dungeon level 2? Or had they reached dungeon level 60 before finding their first artifact? Did you have a really scary moment that stands out from the rest of the game? And how *did* you actually win the game, anyway? ~~~~~15|Dying ~~~~~17|Loading old characters #####R=== Upon Death and Dying === If your character falls below 0 hit points, he has died and cannot be restored (for most classes, anyway). A tombstone showing information about your character will be displayed. You are also permitted to get a record of your character, and all your equipment (identified) either on the screen or in a file. Your character will leave behind a reduced save file, which contains only the monster memory and your option choices. It may be restored, in which case the new character is generated exactly as if the file was not there, but the new player will find his monster memory containing all the experience of past incarnations. In this way, death in ToME is permanent. You cannot simply 'reload at the last save' as in most other contemporary games. Death is permanent, just as it is in real life. tome-235-src/lib/help/m_meta.txt0000644000076400017500000000471611012107760014374 0ustar dgdg|||||oy ~~~~~01|Magic|Meta School ~~~~~02|Meta Magic ~~~~~03|Skills|Meta - Spell Info #####R === ToME Magic - Meta School === The meta school of magic contains spells where the raw forces of magic are manipulated by the spell. There are rumours of a "Tome of Meta Spells" which contains all the meta school spells within its bindings. Worshipping the God Manwe Sulimo also gives the ability to cast spells from the meta school at a level of 1/3 of your prayer level. E.g. if the skill "Spirituality: Prayer" is at level 15, you can cast up to level 5 meta school spells. #####sMeta Spells There are five spells available for the meta school. These spells are: 1. [[[[[sRecharge] (school level 5) Taps the ambient mana to recharge an object's power (charges or mana). 2. [[[[[sDisperse Magic] (school level 15) Dispels a lot of magic that can affect you, be it good or bad: Spell Level 1: blindness and light. Spell Level 5: confusion and hallucination. Spell Level 10: speed (either bad or good) and light speed. Spell Level 15: stunning, meditation and cuts. Spell Level 20: heroism, super heroism, blessing, shields, fear, parasites and mimicry. 3. [[[[[sSpellbinder] (school level 20) Stores spells in a trigger. When the condition is met all spells fire off at the same time. This spell takes a long time to cast so you are advised to prepare it in a safe area. Also it will use the mana for the Spellbinder and the mana for the selected spells. 4. [[[[[sTracker] (dual school level 30) Tracks down the last teleportation that happened on the level and teleports you to it. #####v Your Meta and Conveyance skills must have reached a combined average level #####v of 30 in order to cast this spell. 5. [[[[[sInertia Control] (school level 37) Changes the energy flow of a spell to be continuously recasted at a given interval. The inertia-controlled spell reduces your maximum mana by four times its cost. #####R=== List of Controllable Spells === Armor of Fear Banishment Disperse Magic Disruption Shield Elemental Shield Ent's Potion Essence of Speed Fiery Shield Flame of Udun Globe of Light Grow Trees Ice Storm Invisibility Phase Door Poison Blood Probability Travel Recovery Regeneration Remove Curses Reveal Ways Sense Hidden Sense Monsters Shake Stone Skin Teleportation Thunderstorm Tidal Wave Vapor Vision Wings of Winds Wraithform tome-235-src/lib/help/r_beorn.txt0000644000076400017500000000202111012107760014543 0ustar dgdg~~~~~01|Beorning ~~~~~02|Races|Beorning #####R=== Beornings === #####GDescription Beornings are the descendants of Beorn, a powerful shapeshifter who dwells near Mirkwood. They have all inherited his shapeshifting abilities and can turn into powerful bears at will. #####GStat Modifiers Strength +4 Intelligence -2 Wisdom -2 Dexterity -1 Constitution +3 Charisma -5 Hit Dice Sides 12 Exp Penalty +50% #####GSkill Bonuses (supplementary to existing skills) #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 2.500 [0.000] Archery 0.500 [0.000] Bearform-combat 1.000 [1.000] Sneakiness -0.100 [0.000] Stealth -2.000 [0.000] Disarming -0.600 [0.000] Magic Magic-Device -0.800 [0.000] Spirituality -3.000 [0.000] tome-235-src/lib/help/m_convey.txt0000644000076400017500000000613111012107760014742 0ustar dgdg|||||oy ~~~~~01|Magic|Conveyance School ~~~~~02|Conveyance Magic ~~~~~03|Skills|Conveyance - Spell Info #####R === ToME Magic - Conveyance School === The conveyance school of magic contains spells where the forces of space are manipulated by the spell. There are rumours of a "Tome of of Translocation" which contains all the conveyance school spells within its bindings. Worshipping the God Manwe Sulimo also gives the ability to cast spells from the conveyance school at a level of 1/2 of your prayer level. E.g. if the skill "Spirituality: Prayer" is at level 10, you can cast up to level 5 conveyance school spells. #####sConveyance Spells There are six spells available for the conveyance school. These Spells are: 1. [[[[[sPhase Door] (school level 1) Teleports you on a small scale range. At spell level 30 it creates void jumpgates. 2. [[[[[sDisarm] (school level 3) Destroys doors and disarms traps in adjacent tiles. At spell level 10 it unlocks doors and disarms traps. 3. [[[[[sTeleportation] (school level 10) Teleports you around the level. The casting time decreases with level. 4. [[[[[sTeleport Away] (school level 23) Teleports a line of monsters away. At spell level 10 it turns into a ball. At spell level 20 it teleports all monsters in sight. 5. [[[[[sRecall] (school level 30) Cast on yourself, it will recall you to the surface/dungeon. Cast at a monster, it will make you swap positions with the monster. Cast at an object, it will fetch the object to you (note that you must have an empty space under your feet for the object to fall onto). 6. [[[[[sProbability Travel] (school level 35) Renders you unstable. When you hit a wall you travel through it and instantly appear on the other side of it. You can also float up and down at will. #####GAir spells that can be cast with Conveyance skill 1. [[[[[BWings of Winds] (dual school level 22) Grants the power of levitation. At spell level 16 it grants the power of controlled flight. #####v Your Air and Conveyance skills must have reached a combined average level #####v of 22 in order to cast this spell. #####GTemporal spells that can be cast with Conveyance skill 1. [[[[[sBanishment] (dual school level 30) Disrupts the space/time continuum in your area and teleports all monsters away. At spell level 15 it also may lock them in a time bubble for some turns. #####v Your Temporal and Conveyance skills must have reached a combined average level #####v of 30 in order to cast this spell. #####GMeta spells that can be cast with Conveyance skill 1. [[[[[sTracker] (dual school level 30) Tracks down the last teleportation that happened on the level and teleports you to it. #####v Your Meta and Conveyance skills must have reached a combined average level #####v of 30 in order to cast this spell. #####GUdun spells that can be cast with Conveyance skill 1. [[[[[DWraithform] (dual school level 30) Turns you temporarily into an immaterial being. #####v Your Udun and Conveyance skills must have reached a combined average level #####v of 30 in order to cast this spell. tome-235-src/lib/help/automat.txt0000644000076400017500000013011111012107760014571 0ustar dgdg|||||oy ~~~~~01|Automatizer ~~~~~02|Auto pick-up ~~~~~03|Auto destroy ~~~~~04|Autosquelch #####R /----------------------------------------\ #####R < The Automatizer > #####R \----------------------------------------/ #####GWhat is the Automatizer? The automatizer is an advanced auto-pickup or auto-squelch (auto-destroyer). At a basic level, it will allow you to automatically destroy things that you have no use for once you walk over them, providing that you have identified one of them with your current character. #####GIs that it? Well no. The automatizer is far more flexible than that. The old-fashioned auto squelch allowed you to destroy things dependent on how they pseudo-id'd - you could auto-destroy all {cursed} swords for instance. This is fine to start with, but once you get deep in the dungeon, and have a lot of money and a decent weapon, you'll be interested in destroying {average} and {good} items too right? Well the automatizer allows you to define destruction of things providing you are of a certain level. #####GSounds quite cool, but wha... STOP RIGHT THERE! I haven't finished yet! Let's look at some other examples. Most of the time, scrolls of darkness are pretty useless. Unless you are a vampire, or an alchemist, right? So you might think it was no good to add auto-destroy of scrolls of darkness to the automatizer. But you'd be wrong, for you can add rules that are dependent on certain conditions, like that you are of a certain race, or class. #####GHey this is sounding good. What if it destroys my artifacts? It can't. Artifacts can never be destroyed, by the automatizer. However, watch out for items that are VERY cool but not artifacts... you wouldn't want to go destroying boots of speed would you? Fortunately there are provisions for this too, you could set a rule that destroyed all excellent boots (providing you were past character level 45 say), but not if they were boots of speed. #####GWoah! This sounds amazing! Yes it is, isn't it. #####GSo how do I use it? Well the very simplest way is as follows. When you hit 'k' (^D in the roguelike keyset) to destroy an item, you'll see that one option is "$ new automatizer rule(OFF)". If you want to destroy all future items like that that you find, then hit the $ key. You'll see that (OFF) changes to (ON). Now pick the item you want to destroy. Let's say it is a Potion of Salt Water. You would now, as normal, see a message "You destroy a Potion of Salt Water". Following this you get a prompt, "Destroy all of the same [T]ype, [F]amily, or [N]ame, also use [S]tatus (no)?". Let's take the easy one first and hit 'n' to go with name. You'll now see a message, "Rule added, please go to the automatizer screen (press = then T) to save the modified ruleset". Let's do that then, shall we. If this is the first time you have used the automatizer with this savefile, you'll be asked to enable it as you hit T. Confirm that you would like to enable it, otherwise it won't work. #####GWhat's the point in having it disabled then? Well let's say you spotted something that you weren't sure how it would be affected by your rules, but didn't want to destroy it; you could just disable the automatizer for a moment and check it over before deciding what to do with it and switching the automatizer back on. #####GHmmm, ok. So I've enabled the automatizer, now what? Well, you'll see a screen like this: &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|GsGaGlGtG GwGaGtGeGrB B B w B|GB B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wfwowowdB B B B B B B B B w B|G G G G Gwpwowtwiwownw wowfw wswawlwtw wwwawtwewrgB B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|B B B B B B B B B B B B B w B|w BuBpW/BdBoBwBnW WtWoW WsWcWrWoWlWlW,W BtBaBbW WtWoW WsWwWiWtWcWhW WtWoW WtWhWeW WrWuWlWeW WwWiWnWdWoWww w w w w w w w w w w w w &&&&&B|w w w w w w w w w w w w w w B|w BuW/BdW WtWoW WmWoWvWeW WrWuWlWeWsW,W BnWeWwW WrWuWlWeW,W BrWeWnWaWmWeW WrWuWlWeW,W BsWaWvWeW WrWuWlWeWsw w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w RkW WtWoW rdrirsrarbrlreW WtWhWeW WaWuWtWoWmWaWtWiWzWeWrw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w (snipped for brevity). The automatizer rules are written in XML, so if you're familiar with that format you shouldn't find things too difficult. It's also similar in format to HTML, as you may notice from the way that there are opening tags () and closing tags (), and that everything between those tags is affected by that rule. #####GXML? HTML? What is this? Isn't ToME enough acronyms to be going on with? OK, so you don't know anything about mark-up languages, it's no problem. Let's take a look at the automatizer screen bit by bit, starting with the instructions bottom right. up/down to scroll. Well as you move the up/down cursor keys or number keys, a different rule name is highlighted in the left hand window, and that rule is displayed in the right hand window. tab to switch to the rule window. Does what it says on the tin: switches to the rule window (the right hand pane) to allow editing of existing rules. u/d to move rules. Pressing 'u' or 'd' will move the rule up or down the order displayed in the left hand window. Purely for cosmetic reasons. new rule. Adds the beginning of a new rule. rename rule. This is handy, as every rule added from the destroy prompt (as explained above) is automatically named 'destroy', which gets a bit confusing when you have 50 or so rules... renaming your rules will make them much easier to edit later. save rules. Saves all existing rules to a filename you designate (default is automat.atm). Don't forget to do this after adding new rules/before exiting the game. k to disable the automatizer. Disables the automatizer, preserving the rules you have made. #####GYeah yeah, so what about the rule window on the right hand side itself? OK, here we go. This is the real juicy stuff. Anything inside pointy brackets (greater than and less than signs) is called a tag. You'll notice that each tag opens with a word, and then that same word appears in another tag later on, preceded by a slash. These are referred to as opening tags (like ) and closing tags (like ). Everything within a set of closing and opening tags is affected by those tags. This will make more sense as we continue. Tags and the things they enclose are like "mini-rules" which will together make up one rule. I call these mini-rules, clauses. the first line: Each rule starts with the tag , and this contains the rule name, and the rule type. The rule name is how it is identified in the left hand window, and need not be unique. The rule type will be either "destroy" (destroys items when conditions stated below are met) or "pickup" (picks up item when conditions are met) or "nothing" (neither picks up, nor destroys item when conditions are met) The second line: Potion of Salt Water This tells us that for the rule to be carried out, the name of the item must be "Potion of Salt Water" The third line: This tells us the rule is ended. In total then, the rule named "destroy" checks to see if the name of every item is Potion of Salt water, and if it is, it destroys it. Nice and simple huh? #####GYes Yes, very simple. It doesn't look very advanced at the moment. Well, we've barely scratched the surface. Let's take a look at those other options we got at the destroy prompt. Let's say I was at a stage in the game where I wanted to be able to switch on an auto- destroy for all swords that pseudo-id'd as {average}. So let's say I have a dagger in my backpack, and I want to create an auto-destroy rule for that and all subsequent swords... This is what I'd do: Hit 'k' to destroy items and hit '$' to turn on automatizer rules. Then I'd select the dagger and confirm the destruction. Hit 's' to switch the status toggle. This toggle will include (when ON) how the dagger pseudo-ids, and finally hit 'f' to add a rule saying destroy by family. What you'll see in the automatizer screen now is this: &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|GdGeGsGtGrGoGyB B B B B B w B|GB B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wdwewswtwrwowyB B B B B B w B|G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wfwowowdB B B B B B B B B w B|G G G G G G G G Gw2w3gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G GwawvwewrwawgwegB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w B| &&&&&B|B B B B B B B B B B B B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|B B B B B B B B B B B B B w B|w BuBpW/BdBoBwBnW WtWoW WsWcWrWoWlWlW,W BtBaBbW WtWoW WsWwWiWtWcWhW WtWoW WtWhWeW WrWuWlWeW WwWiWnWdWoWww w w w w w w w w w w w w &&&&&B|w w w w w w w w w w w w w w B|w BuW/BdW WtWoW WmWoWvWeW WrWuWlWeWsW,W BnWeWwW WrWuWlWeW,W BrWeWnWaWmWeW WrWuWlWeW,W BsWaWvWeW WrWuWlWeWsw w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w RkW WtWoW rdrirsrarbrlreW WtWhWeW WaWuWtWoWmWaWtWiWzWeWrw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w #####GOK, well I can see the pseudo-id status is there, what's that tval thing? And #####Gwhere does it say swords? Well actually the tval thing is where it says swords! This is what is added by the 'destroy by family' option. It's probably worth explaining a bit here about the internal structure of ToME code. Don't worry it's not too scary. In ToME, all objects are divided into types: swords, axes, hafted-weapons, scrolls, rings etc. Every type is further divided into sub-types. Eg swords are divided into daggers, broad swords, two- handed swords and so on. Scrolls are divided into their specific actions; scrolls of light, scrolls of satisfy hunger etc. Each type has a number assigned to it, that never changes, and so does each sub-type. In this way we can identify an exact object using just two values: it's type, or tvalue (tval) and it's sub-type, or svalue (sval). You see where we're going with this? Now daggers have a tval of 23 and an sval of 4. So you can see that we've said in the rule that all things with a tval of 23 and a status of average can be destroyed. #####GAh, right. I see. And what's with the tags? Well, everything in those tags must be true for the rule to carry out. If we had the 23 and the average lines without the tags, it would not be clear whether we wanted just one of those clauses to be true for the rule to be carried out, or both of them. #####GErr... In other words, without the tags it might look like we wanted to destroy a) EVERYTHING that pseudo id'd as average, and b) EVERY sword, regardless of how it pseudo-id'd! #####GRight. What if I did want a rule that was more general, and had either/or options in it? Then there are tags to do that - the tags. If ANY of the clauses return as true within or tags, then the rule is carried out. Substitute tags for the tags in our sword example above, and the rule will operate in the rather unhelpful way I explained above (all {average} things destroyed, and all swords destroyed, regardless of how they pseudo-id). So essentially, if your rule has more than one clause, you will need to include either tags or tags, or in some cases both. #####GOK and so what does the [T]ype option do? It merely adds the sval, thus narrowing down the parameters for the auto- destroy. For instance if I'd chosen to destroy by type rather than family in the last example, we'd have ended up with this: &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|GdGeGsGtGrGoGyB B B B B B w B|GB B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wdwewswtwrwowyB B B B B B w B|G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wfwowowdB B B B B B B B B w B|G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G Gw2w3gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G GgB B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G GwawvwewrwawgwegB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w B| &&&&&B|B B B B B B B B B B B B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|B B B B B B B B B B B B B w B|w BuBpW/BdBoBwBnW WtWoW WsWcWrWoWlWlW,W BtBaBbW WtWoW WsWwWiWtWcWhW WtWoW WtWhWeW WrWuWlWeW WwWiWnWdWoWww w w w w w w w w w w w w &&&&&B|w w w w w w w w w w w w w w B|w BuW/BdW WtWoW WmWoWvWeW WrWuWlWeWsW,W BnWeWwW WrWuWlWeW,W BrWeWnWaWmWeW WrWuWlWeW,W BsWaWvWeW WrWuWlWeWsw w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w RkW WtWoW rdrirsrarbrlreW WtWhWeW WaWuWtWoWmWaWtWiWzWeWrw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w You can see in this example that we have nested tags. Evaluating the tags from the ones nested deepest first we can see that if an object has a tval of 23 and an sval between the values of 4 and 4 (i.e. if it is 4) then the rule will check against the next part, which is to see if the object identifies {average}. If it does, then all the clauses have been met and rule is carried out. In short, it destroys all average daggers, rather than all average swords. Strictly speaking the nested tags aren't needed, but they do no harm, and are added automatically when destroying by [T]ype. #####GThis is all well and good but the numbers are going to get rather confusing #####Garen't they? Be much easier if I could just write 'swords' or 'daggers'. Well, you can. Kind of. Instead of using the admittedly rather obtuse numbers, you can use the name of that tvalue rather than the number it represents. So instead of 23 you could write TV_SWORD. #####GAh that would be better. But where can I find out what all the names, and #####Gnumbers of tvalues are? Well I've written a *****defines.txt*0[file] which lists tvalues and one which lists svalues for you to check on, and you may want to check the objects entry in k_info.txt in your lib/edit directory. If you look at the entry for dagger you'll see: N:43:& Dagger~ G:|:W I:23:4:0 W:0:0:12:10 A:0/1:5/1:10/1:20/1 P:0:1d4:0:0:0 The only line we're interested in is the one that starts I (for Index). The first number is the tval, and the second is the sval. Of course you could always rename your rule to make things clearer. #####GOK so you mentioned something about setting rules up that happen only if a #####Gplayer is a certain level? Yeah, good point. Well, let's develop our destroy average swords rule for the moment. Let's say we always wanted to destroy average swords by the time we got to character level 20. They don't earn enough gold to make it worth carrying back to town, and we'll have a better weapon by then anyway. So here we are in the automatizer screen, with the destroy sword rule displaying in the right hand window. If we hit tab, the right window becomes active and the rules at the bottom change: &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|gdgegsgtgrgogyB B B B B B w B|vB B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wdwewswtwrwowyB B B B B B w B|G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wfwowowdB B B B B B B B B w B|G G G G G G G G Gw2w3gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G GwawvwewrwawgwegB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|vB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|B B B B B B B B B B B B B w B|w BuBpW/BdBoBwBnW/BlBeBfBtW/BrBiBgBhBtW WtWoW WnWaWvWiWtWaWgWeW WrWuWlWeW,W B9W/B3W/B7W/B1W WtWoW WsWcWrWoWlWlw w w w w w w w w w &&&&&B|w w w w w w w w w w w w w w B|w BtBaBbW WfWoWrW WsWwWiWtWcWhW,W BaWdWdW WcWlWaWuWsWeW,W BdWeWlWeWtWeW WcWlWaWuWsWeW/WrWuWlWew w w w w w w w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w You can see the tags have changed to purple, indicating they are the active ones, that all key presses will act upon. Let's just quickly scoot through these new commands: up/down/left/right to navigate rule: These will change which clause is active, enabling you to delete that clause, or add further clauses inside that one if it so allows it. 9/3/7/1 to scroll: scrolls the whole screen which can become useful if you have a particularly long rule or one with lots of nested clauses. tab for switch: will make the left-hand window active again. add clause: adds a new clause within the active one, providing the active clause is either a , or tag. delete clause/rule: deletes the active clause, and any clauses nested within that one. Therefore if the tags are active, the whole rule will be deleted. Beware! So if we now hit our right arrow we see that the tags are active. We can now add a new clause here. Let's do so by pressing 'a'. You'll now see a list of different types of clauses you can add, which you simply scroll through using up and down keys, and select by hitting enter. A brief description of the selected clause is shown in the right hand window. Scroll down to the 'level' rule type and hit enter. You'll be asked to enter a player level. Let's go for 20. You'll then be asked for a maximum level, put 50, as we want the rule to be true from level 20 and upwards. You'll now see our rule displays as: &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|gdgegsgtgrgogyB B B B B B w B|GB B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wdwewswtwrwowyB B B B B B w B|v v v v vB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wfwowowdB B B B B B B B B w B|G G G G G G G G Gw2w3gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G GwawvwewrwawgwegB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G GgB B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|v v v v vB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|B B B B B B B B B B B B B w B|w BuBpW/BdBoBwBnW/BlBeBfBtW/BrBiBgBhBtW WtWoW WnWaWvWiWtWaWgWeW WrWuWlWeW,W B9W/B3W/B7W/B1W WtWoW WsWcWrWoWlWlw w w w w w w w w w &&&&&B|w w w w w w w w w w w w w w B|w BtBaBbW WfWoWrW WsWwWiWtWcWhW,W BaWdWdW WcWlWaWuWsWeW,W BdWeWlWeWtWeW WcWlWaWuWsWeW/WrWuWlWew w w w w w w w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w So there we go. A rule which will destroy all {average} swords once the player is past character level 20. #####GHmmm I've tried this, it doesn't destroy cursed swords though... Nope. You haven't told it to. If you want a scaling rule, which always destroys cursed swords and then destroys average swords at character level 20, then {good} swords at character level 35, have a look at this, rather more complicated rule. &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|wswhwiwewlwdB B B B B B B w B|GB B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wbwowwB B B B B B B B B B w B|G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|whwrwdw wawrwmwowuwrB B B w B|G G G G G G G G Gw2w3gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wawxwewsB B B B B B B B B w B|G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|whwewlwmwsB B B B B B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wswowfwtw wawrwmB B B B B w B|G G G G G G G G G G G G G G G G GgB B B B B B B B B B B B B B B w B| &&&&&B|wbwowlwtwsB B B B B B B B w B|G G G G G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wbwowowtwsB B B B B B B B w B|G G G G G G G G G G G G G G G G G G G G Gwvwewrwyw wbwawdgB B B B B B B B B B B B B B B B B B w B| &&&&&B|wgwlwowvwewsB B B B B B B w B|G G G G G G G G G G G G G G G G G G G G GwbwawdgB B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wpwowlwewawrwmwsB B B B B w B|g g g g g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wcwlwowawkB B B B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|GsGwGoGrGdGsB B B B B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|whwawfwtwewdwsB B B B B B w B|G G G G G G G G G G G G G G G G GgB B B B B B B B B B B B B B w B| &&&&&B|wawrwrwowwwsB B B B B B B w B|G G G G G G G G G G G G G G G G GwawvwewrwawgwegB B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wswhwowtB B B B B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wbwowowmwewrwawnwgB B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wtwowrwcwhB B B B B B B B w B|G G G G G G G G G G G G G G G G GgB B B B B B B B B B B B B B w B| &&&&&B|wrwowdw wtwiwpwsB B B B B w B|G G G G G G G G G G G G G G G G GwgwowowdgB B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wpwowtwiwownwsB B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wrwiwnwgwsB B B B B B B B w B|g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wwwawnwdwsB B B B B B B B w B|g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wmwuwswhwrwowowmwsB B B B w B|gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wswcwrwowlwlwsB B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wawmwuwlwewtwsB B B B B B w B|w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w B| &&&&&B|wpwawrwcwhwmwewnwtwsB B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|wswhwawpwew wpwowtB B B B w B|w BuBpW/BdBoBwBnW WtWoW WsWcWrWoWlWlW,W BtBaBbW WtWoW WsWwWiWtWcWhW WtWoW WtWhWeW WrWuWlWeW WwWiWnWdWoWww w w w w w w w w w w w w &&&&&B|wswtwawvwewsw w w w w w w w B|w BuW/BdW WtWoW WmWoWvWeW WrWuWlWeWsW,W BnWeWwW WrWuWlWeW,W BrWeWnWaWmWeW WrWuWlWeW,W BsWaWvWeW WrWuWlWeWsw w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w RkW WtWoW rdrirsrarbrlreW WtWhWeW WaWuWtWoWmWaWtWiWzWeWrw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w #####GWoah! What the heck is that?! OK ok slow down a minute. Look at it carefully and a clause at a time. It's not difficult. Let's take it from the top. It's a destroying rule called swords. It opens with some tags. The object must be a sword (tval 23). Now we have an OR tag, so we know that there are going to be some options: option 1: the player is between level 0 and level 50, and the sword pseudo id's as either cursed or worthless. option 2: the player is above character level 15, and the sword pseudo id's as average. option 3: the player is above character level 25, and the sword pseudo id's as good. If any of these options are true, the rule is carried out. This rule could easily be copied for other weapons or pieces of armour, substituting only the tval, and perhaps the name. #####GHmmm ok. looks good. I might want to change those character level values #####Gthough. they look a bit low... Well yeah, that's up to your playing style I guess... If you want to edit clauses directly rather than delete and re-add them, you might want to edit the automat.atm file directly. Just open it in your text editor (it's located in your lib/user directory or in ~/.tome on multiuser systems) and you'll see the format is identical to how it is displayed in the automatizer file. Just watch your spellings, and keep a back-up of the original to replace if things go wrong. Don't mess about in there if you feel unsure of what you're doing though. #####GSo what about those examples you gave up above? Like destroying scrolls of #####Gdarkness unless you are a vampire or an alchemist? OK, let's add this rule from scratch rather than from the destroy item prompt. In the automatizer screen, hit 'n' for new rule. It asks for a name and a type of rule (destroy/pickup/nothing). I called my rule "? of darkness", and it's a destroy rule. It is worthwhile thinking at this point how the rule is going to be structured; for very complicated rules pen and paper may help. We're going to need to define the object (either by name, or by tval and sval) then we're going to say unless the player race modifier is vampire, or the player class is alchemist. So we are obviously going to have more than one clause, and the clauses are going to have to BOTH be true for the rule to take effect so the first clause we add is an one. So hit 'a' for add clause and enter to select the clause. Lets now hit our right arrow, so the tags are active, and add a new rule. We can now select the tags. At this point we're prompted for the name. Now it's not case-sensitive, but you do need to spell it correctly! With the tags still highlighted we now want to add our "unless vampire or alchemist" clause. Seeing as this is an "unless" type clause, we start with a tag. So again, 'a'dd a new clause, and select . Now make the tag active by moving right and down with the cursor keys. We want "EITHER vampire or alchemist" so we include tags, again by moving across to make the tags active and 'a'dding a new clause. Then select the tags and 'a'dd a new clause. Enter 'vampire'. So the last part is to add alchemist. Now this might at first glance seem to be a simple case of 'a'dding a new clause of the type, within the tags, and there is certainly nothing 'wrong' with doing this. At present there is no way for non-alchemists to get the alchemy skill, but it is sometimes best to 'future-proof' against such possibilities. That's what we're going to do here. So rather than add a clause, we're going to add a clause. With the tags active, 'a'dd a new clause. You're first asked for a minimum skill level. Well, we can't use any skill unless we have 1.00 whole skill points in it or more, so we can put 1 in here. We're then asked for a maximum skill level, so we'll put in 50 here. The skill name must be spelled correctly (as it appears on the skill screen) so we put 'Alchemy' here. Your complete rule now appears as follows: &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|G?G GdGaGrGkGnGeGsGsB B B w B|GB B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wswwwowrwdwsB B B B B B B w B|G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wswawlwtw wwwawtwewrB B B w B|G G G G G G G G GwSwcwrwowlwlw wowfw wdwawrwkwnwewswsgB B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wfwowowdB B B B B B B B B w B|G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GwvwawmwpwiwrwegB B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GwAwlwcwhwewmwygB B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|B B B B B B B B B B B B B w B|w BuBpW/BdBoBwBnW WtWoW WsWcWrWoWlWlW,W BtBaBbW WtWoW WsWwWiWtWcWhW WtWoW WtWhWeW WrWuWlWeW WwWiWnWdWoWww w w w w w w w w w w w w &&&&&B|w w w w w w w w w w w w w w B|w BuW/BdW WtWoW WmWoWvWeW WrWuWlWeWsW,W BnWeWwW WrWuWlWeW,W BrWeWnWaWmWeW WrWuWlWeW,W BsWaWvWeW WrWuWlWeWsw w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w RkW WtWoW rdrirsrarbrlreW WtWhWeW WaWuWtWoWmWaWtWiWzWeWrw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w You'll notice I've also renamed the rules to make things a bit more legible. #####GOK I'm getting there now, what about the boots of speed thing you talked about? Heh. Take a look at this, and see if you can work out what it's doing first before I talk you through it &&&&&B/B-B-B-B-BRBuBlBeBsB-B-B-B-B-B/B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B\ &&&&&B|GbGoGoGtGsB B B B B B B B w B|GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|w?w wdwawrwkwnwewswsB B B w B|G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wswwwowrwdwsB B B B B B B w B|G G G G G G G G GwTwVw_wBwOwOwTwSgB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wswawlwtw wwwawtwewrB B B w B|G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|wfwowowdB B B B B B B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GgB B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G G G G G Gwvwewrwyw wbwawdgB B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G G G G G GwbwawdgB B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GgB B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GwawvwewrwawgwegB B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GgB B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GwgwowowdgB B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GgB B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G Gwvwewrwyw wgwowowdgB B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GwiwdwewnwtwiwfwiwewdgB B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G GB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|G G G G G G G G G G G G G G G G G G G G GwswpwewewdgB B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|g g g g gB B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B w B| &&&&&B|B B B B B B B B B B B B B w B|gw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w B| &&&&&B|B B B B B B B B B B B B B w B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/ &&&&&B|B B B B B B B B B B B B B w B|w BuBpW/BdBoBwBnW WtWoW WsWcWrWoWlWlW,W BtBaBbW WtWoW WsWwWiWtWcWhW WtWoW WtWhWeW WrWuWlWeW WwWiWnWdWoWww w w w w w w w w w w w w &&&&&B|w w w w w w w w w w w w w w B|w BuW/BdW WtWoW WmWoWvWeW WrWuWlWeWsW,W BnWeWwW WrWuWlWeW,W BrWeWnWaWmWeW WrWuWlWeW,W BsWaWvWeW WrWuWlWeWsw w w w w w w w w w w w &&&&&B\B-B-B-B-B-B-B-B-B-B-B-B-B-B-B/w RkW WtWoW rdrirsrarbrlreW WtWhWeW WaWuWtWoWmWaWtWiWzWeWrw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w The majority of this is fairly similar to the swords rule; it destroys {average} boots at character level 20, {good} ones at character level 35 and cursed ones always. The addition is at the bottom. It adds clauses which will destroy excellent items providing that they have been identified and that the name does not contain the word "speed". The identified bit is important here, as it would destroy the boots on pseudo-id otherwise, before it even saw the full name of the boots. #####GThis is fantastic! Where can I get more help? email me: fearoffours@t-o-m-e.net tome-235-src/lib/help/corspoil.txt0000644000076400017500000001077611012107760014767 0ustar dgdg~~~~~01|Corruptions (Spoiler) ~~~~~02|Spoilers|Corruptions #####R=== ToME Corruptions Spoiler === Sometimes adventurers become exposed to the dark powers of Morgoth. If they are unable to resist these powers, they become corrupted. Corruptions can change their physical or mental abilities, some of which can be good, and some bad. Most corruptions will affect you permanently, although some only operate when they are activated (whether by player choice or as a random event). You can check which corruptions do you have in the knowledge screen 6 (accessed through the '~' menu) or in a character dump. #####GGaining and (not) losing corruptions There are several ways that you can become corrupted. You can become corrupted by quaffing a Potion of Corruption or by drinking from a Fountain of Corruption. Also some strange items can be activated for corruption. Corruptions are permanent. Once you have one, you have it for life. [[[[[BBalrog Aura] Surrounds you with a fiery aura But it can burn scrolls when you read them [[[[[GGain message: A corrupted wall of flames surrounds you.] [[[[[RLose message: The wall of corrupted flames abandons you.] [[[[[BBalrog Wings] Creates ugly, but working, wings allowing you to fly But it reduces charisma by 4 and dexterity by 2 [[[[[GGain message: Wings of shadow grow in your back.] [[[[[RLose message: The wings in your back fall apart.] [[[[[BBalrog Strength] Provides 3 strength and 1 constitution But it reduces charisma by 1 and dexterity by 3 [[[[[GGain message: Your muscles get unnatural strength.] [[[[[RLose message: Your muscles get weaker again.] [[[[[BBalrog Form] Allows you to turn into a Balrog at will You need Balrog Aura, Balrog Wings and Balrog Strength to activate it [[[[[GGain message: You feel the might of a Balrog inside you.] [[[[[RLose message: The presence of the Balrog seems to abandon you.] It depends on: Balrog Aura Balrog Wings Balrog Strength [[[[[BDemon Spirit] Increases your intelligence by 1 But reduce your charisma by 2 [[[[[GGain message: Your spirit opens to corrupted thoughts.] [[[[[RLose message: Your spirit closes again to the corrupted thoughts.] [[[[[BDemon Hide] Increases your armour class by your level Provides immunity to fire at level 40 But reduces speed by your level / 7 [[[[[GGain message: Your skin grows into a thick hide.] [[[[[RLose message: Your skin returns to a natural state.] [[[[[BDemon Breath] Provides fire breath But gives a small chance to spoil potions when you quaff them [[[[[GGain message: Your breath becomes mephitic.] [[[[[RLose message: Your breath is once again normal.] [[[[[BDemon Realm] Provides access to the demon school skill and the use of demonic equipment You need Demon Spirit, Demon Hide and Demon Breath to activate it [[[[[GGain message: You feel more attuned to the demon realm.] [[[[[RLose message: You lose your attunement to the demon realm.] It depends on: Demon Spirit Demon Hide Demon Breath [[[[[BRandom teleportation] Randomly teleports you around [[[[[GGain message: Space seems to fizzle around you.] [[[[[RLose message: Space solidify again around you.] It is opposed to: Anti-teleportation [[[[[BAnti-teleportation] Prevents all teleportations, be it of you or monsters [[[[[GGain message: Space continuum freezes around you.] [[[[[RLose message: Space continuum can once more be altered around you.] It is opposed to: Random teleportation [[[[[BTroll Blood] Troll blood flows in your veins, granting increased regeneration It also enables you to feel the presence of other troll beings But it will make your presence more noticeable and aggravating [[[[[GGain message: Your blood thickens, you sense corruption in it.] [[[[[RLose message: Your blood returns to a normal state.] [[[[[BVampiric Teeth] Your teeth allow you to drain blood to feed yourself However your stomach now only accepts blood. [[[[[GGain message: You grow vampiric teeth!] It is not removable. [[[[[BVampiric Strength] Your body seems somewhat dead In this near-undead state it has improved strength, constitution and intelligence, but also reduced dexterity, wisdom and charisma. [[[[[GGain message: Your body seems more dead than alive.] It is not removable. It depends on: Vampiric Teeth [[[[[BVampire] You are a Vampire. As such you resist cold, poison, darkness and nether. Your life is sustained, but you cannot stand the light of the sun. [[[[[GGain message: You die to be reborn in a Vampire form.] It is not removable. It depends on: Vampiric Strength tome-235-src/lib/help/skills.txt0000644000076400017500000007725211012107760014440 0ustar dgdg|||||oy ~~~~~55|Skills #####R=== ToME Skills System === One of the big differences between standard "Vanilla" Angband and ToME is the implementation of a skill system where the player can choose what skills she will improve as her character progresses. As such, many abilities such as spell casting, fighting and trap disarming *do not* increase automatically - the player must choose to use skill points to improve those abilities. This gives the player the chance to tailor a character to suit their playing style with a lot more flexibility than has existed with a fixed progression system in the past. However, not all types of characters are able to gain skills to the same degree; while a fighter can learn some magic, he's unlikely to become as good at it as a mage can. So the number of skill points required to raise a skill to the next level varies according to the starting "type" of character. You can also spend skill points in "one-off purchase" *****ability.txt*0[Abilities]. ~~~~~56|Skills|Screen #####GThe Skills Menu Each time you gain a level of experience, you receive 6 skill points to spread around as you wish. To use these skill points, you need to access the skills menu ("G" for both keysets). This opens up a long list of abilities that can be improved. The menu may look something like this: &&&&&w w w w w w w w w w w w w w w w w w w w w w w w w w w w wTwowMwEw wSwkwiwlwlwsw wSwcwrwewewnw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w &&&&&BEBnBtBeBrW WtWoW WdWeWvWeWlWoWpW WaW WbWrWaWnWcWhW,W BuBpW/BdBoBwBnW WtWoW WmWoWvWeW,W BrBiBgBhBtW/BlBeBfBtW WtWoW WmWoWdWiWfWyW,W B?W WfWoWrW WhWeWlWpw w w w &&&&&BSBkBiBlBlB BpBoBiBnBtBsB BlBeBfBtB:B B6w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w &&&&&yGyeynyeyryayly yaybyiylyiytyyy ytyoy yfyiygyhyty yaynydy ytyoy ypysyeyuydyoy-yiydy yayrymyoyrysy yaynydy ywyeyaypyoynysy.w w w w w w w w w w w w w w w w w w w &&&&&yIyty yaylysyoy yaylylyoywysy ytyoy yuysyey yhyeyayvyiyeyry yayrymyoyuyrysy ywyiytyhyoyuyty ypyeynyaylytyiyeysw w w w w w w w w w w w w w w w w w w w w w w w w &&&&&G[G-G]GCGoGmGbGaGtw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w G0G2G.G0G0G0G G[G0G.G8G0G0G]w w w w w w &&&&&w w w w w w-w wWwewawpwownwmwawswtwewrwyw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0w1w.w0w0w0w w[w0w.w8w5w0w]w w w w w w &&&&&w w w w w w w w o o.o oSowooorodo-omoaosotoeoroyw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w o0o0o.o0o0o0o o[o0o.o4o0o0o]w w w w w w &&&&&w w w w w w w w o o.o oAoxoeo-omoaosotoeoroyw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w o0o0o.o0o0o0o o[o0o.o4o0o0o]w w w w w w &&&&&w w w w w w w w o o.o oHoaofotoeodo-omoaosotoeoroyw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w o0o0o.o0o0o0o o[o0o.o4o0o0o]w w w w w w &&&&&w w w w w w w w o o.o oPoooloeoaoromo-omoaosotoeoroyw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w o0o0o.o0o0o0o o[o0o.o4o0o0o]w w w w w w &&&&&w w w w w w.w wAwrwcwhwewrwyw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0w1w.w0w0w0w w[w0w.w6w0w0w]w w w w w w &&&&&w w w w o o.o oAonotoiomoaogoiocw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w o0o0o.o0o0o0o o[o0o.o5o5o0o]w w w w w w &&&&&w w+w wSwnwewawkwiwnwewswsw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0w1w.w0w0w0w w[w0w.w9w0w0w]w w w w w w &&&&&w w+w wMwawgwiwcw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0w1w.w0w0w0w w[w0w.w3w0w0w]w w w w w w &&&&&w w-w wSwpwiwrwiwtwuwawlwiwtwyw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w0w1w.w0w0w0w w[w0w.w4w0w0w]w w w w w w &&&&&w w w w o o.o oPoroaoyoeorw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w o0o0o.o0o0o0o o[o0o.o5o0o0o]w w w w w w &&&&&o o.o oMooonosotoeoro-oloooroew w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w o0o0o.o0o0o0o o[o0o.o5o0o0o]w w w w w w Now, looking at this screen, there are several things to be aware of. The first line lets you know if you have any available skill points to spend, and how many there are. Following that are 2 description lines for the currently selected skill - in this case they are describing the "Combat" skill. When looking at the list of skills, there are a few different colours used - the light green coloured skill (which also has its starting character in square brackets []) is the currently selected one - Combat in the example above. Skills that you cannot learn are omitted from the list. Skills that you are capable of learning, but as yet have not, are coloured in orange, while skills of which you have some knowledge are shown in white. At the end of each skill is a pair of numbers. The first represents your current level of knowledge in the skill, and the second how much an advance in this knowledge investing one skill point in this skill would produce. So, in the above example, if the player invested one skill point in their Combat skill, the skill would increase from 02.000 to 02.800. In addition, investing in some skills may raise your knowledge in others. This improvement is based on the modifier in the related class (the one which gets the free points). For example, a skill point put into Weaponmastery raises Combat by 0.5 skill points. This is actually multiplied by the skill modifier that your character has in the Combat skill. For example, a Swordmaster investing a skill point into Weaponmastery would have his Combat skill raised by 0.5 * [0.900] while a Runecrafter would have his Combat skill raised by 0.5 * [0.200]. As well as this, skills are grouped together in similar types. Looking under the Combat skill, there are subtypes of Weaponmastery, Archery and Antimagic. An increase of one of these subskills may also increase the main skill by a small amount. You can tell which skills have subskills by the + (or -) in front of their name. The + indicates that there are more skills within this category. To open a skill category up, move the cursor up/down until the skill category is green, then hit the "Enter" key. Likewise, the - indicates that the category is already opened, and selecting this and hitting the "Enter" key will close it up again. Skills which don't have usable subskills start with a ".". To spend points on a skill (including skill categories), use the left/right arrow (right arrow or "6" adds one skill point, left arrow or "4" removes one). Spending points on a sub-skill will also marginally improve the parent skill (or skill category). When you've finished spending skill points (and any unspent points *will* be saved), hit the "Esc" key to finish. This will give a confirmation prompt to check that you really do want to spend your points as you've assigned them. Saying 'y' saves the changes and allows you to use or apply your new skills :). All skills have a maximum level of 50, and as long as you can learn a skill, and have enough skill points to pump into it, it is theoretically possible to get it to level 50 no matter what your race, class or how you learned it. Each skill affects your character differently. It may be worth getting one or more of your characters skills to 50, but it may not be worth investing [[[[[Bany] skill points in some other skills. As general and personal advice, which may not work for you, I'd say concentrate on a few skills, and leave the others empty. Just because you [[[[[Bcan] learn a skill, it doesn't mean you have to. It often pays to have a plan ("I'm going to make this assassin the stealthiest, most able-dodging, backstabber around. I'm not going to bother with trapping or thieving ability") which you can stick to for the whole game. ~~~~~57|Skills|List of skills #####GThe Skills Themselves So you want to know what each of the skills do so that you can decide how to spend you're hard-earned points, huh? Well, each skill affects different abilities, and not all of them are intuitive - but they don't take all that long to learn :). If you don't find this informative enough, and would like more detailed spoilers on what each skill does, try [[[[[ghttp://www.killerbunnies.org/angband/skill-220.html] for some third party help! The skills are: *****skills.txt*27[Air] *****skills.txt*49[Alchemy] *****skills.txt*50[Antimagic] *****skills.txt*08[Archery] *****skills.txt*05[Axe-mastery] *****skills.txt*18[Backstab] *****skills.txt*13[Barehand-combat] *****skills.txt*61[Bearform-combat] *****skills.txt*12[Boomerang-mastery] *****skills.txt*58[Boulder-throwing] *****skills.txt*10[Bow-mastery] *****skills.txt*01[Combat] *****skills.txt*30[Conveyance] *****skills.txt*44[Corpse-preservation]*****skills.txt*04[Critical-hits] *****skills.txt*11[Crossbow-mastery] *****skills.txt*52[Demonology] *****skills.txt*16[Disarming] *****skills.txt*31[Divination] *****skills.txt*20[Dodging] *****skills.txt*28[Earth] *****skills.txt*25[Fire] *****skills.txt*60[Geomancy] *****skills.txt*06[Hafted-mastery] *****skills.txt*21[Magic] *****skills.txt*54[Magic-device] *****skills.txt*24[Mana] *****skills.txt*29[Meta] *****skills.txt*47[Mimicry] *****skills.txt*33[Mind] *****skills.txt*41[Mindcraft] *****skills.txt*42[Monster-lore] *****skills.txt*59[Music] *****skills.txt*34[Nature] *****skills.txt*35[Necromancy] *****skills.txt*07[Polearm-mastery] *****skills.txt*45[Possession] *****skills.txt*39[Prayer] *****skills.txt*36[Runecraft] *****skills.txt*09[Sling-mastery] *****skills.txt*14[Sneakiness] *****skills.txt*22[Spell-power] *****skills.txt*38[Spirituality] *****skills.txt*23[Sorcery] *****skills.txt*19[Stealing] *****skills.txt*15[Stealth] *****skills.txt*53[Stunning-blows] *****skills.txt*43[Summoning] *****skills.txt*03[Sword-mastery] *****skills.txt*46[Symbiosis] *****skills.txt*32[Temporal] *****skills.txt*37[Thaumaturgy] *****skills.txt*48[Udun] *****skills.txt*26[Water] *****skills.txt*02[Weaponmastery] ~~~~~01|Skills|Combat [[[[[BCombat] The combat skill is used to determine the maximum combined weight of armour you can wear before you become encumbered by it. It also affects your general fighting ability, although not to as great an extent as Weaponmastery, and determines the speed and strength of pseudo-id of weapons and armour. Investing in the combat skill? You might be interested in the *****ability.txt*05[Extra Max Blow(1)] and *****ability.txt*06[(2)] abilities. Sub-skills of Combat are Weaponmastery, Archery, Barehand-combat, Boulder-throwing and Anti-magic. ~~~~~02|Skills|Weaponmastery [[[[[BWeaponmastery] This skill is a sub-skill of the Combat skill. It affects your general ability to use melee weapons of all sorts. Spending 1 skill point on Weaponmastery adds 0.5 bonus skill points to Combat. Investing in the weaponmastery skill? You might be interested in the *****ability.txt*02[Spread Blows] ability. Sub-skills of Weaponmastery are Sword-mastery, Axe-mastery, Hafted-mastery and Polearm-mastery. ~~~~~03|Skills|Sword-mastery [[[[[BSword-mastery] This skill is a sub-skill of the Weaponmastery skill. It affects your ability to use bladed weapons (e.g. daggers, swords). Spending 1 skill point on your Sword-mastery skill adds 0.25 bonus skill points to your Weaponmastery skill and adds 0.07 bonus skill points to your Combat skill. Critical-hits is a sub-skill of Sword-mastery. ~~~~~04|Skills|Critical-Hits [[[[[BCritical-hits] This skill is a sub-skill of the Sword-mastery skill. It affects your ability to deal critical hits to monsters using a bladed weapon that weighs less than 5 pounds. Spending one skill point on your Critical-hits skill also increases your Sword-mastery skill by 0.05 skill points. ~~~~~05|Skills|Axe-mastery [[[[[BAxe-mastery] This skill is a sub-skill of the Weaponmastery skill. It affects your ability to use axes. Spending 1 skill point on your Axe-mastery skill adds 0.25 bonus skill points to your Weaponmastery skill and adds 0.07 bonus skill points to your Combat skill. ~~~~~06|Skills|Hafted-mastery [[[[[BHafted-mastery] This skill is a sub-skill of the Weaponmastery skill. It affects your ability to use hafted weapons (e.g. whips & maces). Spending 1 skill point on your Hafted-mastery skill adds 0.25 bonus skill points to your Weaponmastery skill and adds 0.07 bonus skill points to your Combat skill. Stunning-blows is a sub-skill of Hafted-mastery. ~~~~~53|Skills|Stunning-blows [[[[[BStunning-blows] This skill is a sub-skill of the Hafted-mastery skill. It affects your ability to stun opponents when doing critical hits with a hafted weapon that weighs more than 5 lbs. Spending one skill point on your Stunning-blows skill also increases your Hafted-mastery skill by 0.05 skill points. ~~~~~07|Skills|Polearm-mastery [[[[[BPolearm-mastery] This skill is a sub-skill of the Weaponmastery skill. It affects your ability to use polearms (e.g. pikes & halberds). Spending 1 skill point on your Polearm-mastery skill adds 0.25 bonus skill points to your Weaponmastery skill and adds 0.07 bonus skill points to your Combat skill. Investing in the Polearm-mastery skill? You might be interested in the *****ability.txt*10[Far reaching attack] ability. ~~~~~08|Skills|Archery [[[[[BArchery] This skill is a sub-skill of the Combat skill. It affects your general ability to use ranged weapons of all sorts. Spending one skill point on your Archery skill adds 0.5 bonus skill points to your Combat skill. Investing in the Archery skill? You might be interested in the *****ability.txt*07[Ammo creation] ability. Sub-skills of Archery include Sling-mastery, Bow-mastery, Crossbow-mastery and Boomerang-mastery. ~~~~~09|Skills|Sling-mastery [[[[[BSling-mastery] This skill is a sub-skill of the Archery skill. It affects your ability to use Slings. Spending 1 skill point on your Sling-mastery skill adds 0.25 bonus skill points to your Archery skill and 0.07 bonus skill points to your Combat skill. ~~~~~10|Skills|Bow-mastery [[[[[BBow-mastery] This skill is a sub-skill of the Archery skill. It affects your ability to use both Long and Short Bows. Spending 1 skill point on your Bow-mastery skill adds 0.25 bonus skill points to your Archery skill and 0.07 bonus skill points to your Combat skill. ~~~~~11|Skills|Crossbow-mastery [[[[[BCrossbow-mastery] This skill is a sub-skill of the Archery skill. It affects your ability to use both Heavy and Light Crossbows. Spending 1 skill point on your Crossbow-mastery skill adds 0.25 bonus skill points to your Archery skill and 0.07 bonus skill points to your Combat skill. ~~~~~12|Skills|Boomerang-mastery [[[[[BBoomerang-mastery] This skill is a sub-skill of the Archery skill. It affects your ability to use all boomerangs. Spending 1 skill point on your Boomerang-mastery skill adds 0.25 bonus skill points to your Archery skill and 0.07 bonus skill points to your Combat skill. ~~~~~13|Skills|Barehand-combat [[[[[BBarehand-combat] This skill is a sub-skill of the Combat skill. It affects your general ability to fight using martial arts. In order to utilise it, you must be capable of using a weapon in the first place, but choose not to. Spending 1 skill point on your Barehand-combat skill adds 0.5 bonus skill points to your Combat skill. Barehand-combat fighters develop stronger and faster attacks, and also gain speed bonuses, as they advance in skill. However, they cannot use this skill whilst wearing heavy armour. ~~~~~61|Skills|Bearform-combat [[[[[BBearform-combat] This skill is a sub-skill of the Combat skill. It affects your ability to fight while in the form of a bear. In order to utilise it, you must be in bearform. *****r_beorn.txt*0[Beornings] are the adventurers most likely to use this form of skill. ~~~~~58|Skills|Boulder-throwing [[[[[BBoulder-throwing] This skill is a sub-skill of the Combat skill. It affects your ability to throw boulders and make them from granite walls. Spending 1 skill point on your Boulder-throwing skill adds 0.4 bonus skill points to your Combat skill. ~~~~~50|Skills|Antimagic [[[[[BAntimagic] This skill is a sub-skill of the Combat skill. It generates a field around the character within which magic cannot work. As such, it can be very useful to prevent monsters from casting offensive spells against you or from teleporting away from you just before you kill them - but it will also prevent you from casting spells, or teleporting away when they've almost killed you! It also inhibits your ability to do magic, affecting *all* the magic and spirituality sub-skills. This skill does not affect your ability to use scrolls and potions, but other items that require [Self]Magic-Device are affected. At higher levels you gain the ability to detect traps and disrupt all teleportation. ~~~~~14|Skills|Sneakiness [[[[[BSneakiness] The sneakiness skill affects your searching and perception abilities. Sub-skills of Sneakiness include Stealth, Disarming, Trapping, Backstab, Stealing and Dodging. ~~~~~15|Skills|Stealth [[[[[BStealth] This skill is a sub-skill of the Sneakiness skill. It affects your ability to move around the dungeon quietly so that you are not noticed by its inhabitants. Spending 1 skill point on your Stealth skill adds 0.15 bonus skill points to your Sneakiness skill. ~~~~~16|Skills|Disarming [[[[[BDisarming] This skill is a sub-skill of the Sneakiness skill. It affects your ability to safely disarm any traps you find. Spending 1 skill point on your Disarming skill adds 0.1 bonus skill points to your Sneakiness skill. Investing in the Disarming skill? You might be interested in the *****ability.txt*11[Trapping] ability. ~~~~~18|Skills|Backstab [[[[[BBackstab] This skill is a sub-skill of the Sneakiness skill. It affects your ability to sneak up on monsters and do extra damage to them before they wake up. It also affects monsters who have turned to flee from you. Spending 1 skill point on your Backstab skill adds 0.05 bonus skill points to your Sneakiness skill. ~~~~~19|Skills|Stealing [[[[[BStealing] This skill is a sub-skill of the Sneakiness skill. It affects your ability to steal items from monsters and shops. Be careful when stealing from shops; if you're caught, the shopkeeper will close his doors to you and not open them again. I have heard that shop keepers do not stay in one shop forever though. Spending 1 skill point on your Stealing skill adds 0.15 bonus skill points to your Sneakiness skill. ~~~~~20|Skills|Dodging [[[[[BDodging] This skill is a sub-skill of the Sneakiness skill. It affects your ability to dodge out of the way of monster blows and bolts. The less armour you wear and the less you carry, the greater your chance of dodging a blow. Rings and amulets do not affect your chance to dodge, but full armour will almost render the effect of the skill obsolete. Spending 1 skill point on your Dodging skill adds 0.1 bonus skill points to your Sneakiness skill. ~~~~~21|Skills|Magic [[[[[BMagic] The Magic skill affects your general use of magic items, the amount of mana you can handle, and in general your ability to do magic. It can also affect the strength of wands and staffs. Investing in the Magic skill? You might be interested in the *****ability.txt*04[Perfect Casting] ability. Sub-skills include: Magic-device, Spell-power, Sorcery, Mana, Fire, Water, Air, Earth, Meta, Conveyance, Divination, Temporal, Mind, Nature, Udun, Demonology, Necromancy, Runecraft, Thaumaturgy, and Alchemy. ~~~~~54|Skills|Magic-device [[[[[BMagic-device] This skill is a sub-skill of the Magic skill. It eases the use of magical devices, such as wands, staves, and rods, and boosts the casting level of spells stored in a wand or a staff. *****magic.txt*02[More on this]. It also helps pseudo-id of magic objects. Spending 1 skill point on your Magic-device skill adds 0.07 bonus skill points to your Magic skill. ~~~~~22|Skills|Spell-power [[[[[BSpell-power] This skill is a sub-skill of the Magic skill. It boosts the casting level of most spells you are capable of casting. For example, if you have level one in the mana school, you could cast "Manathrust". For every 2.5 skill levels of Spell-power, Manathrust becomes more powerful, adding +1 casting level to the spell. Note that this is not exactly the same as certain magic items which boost spell power. Spending 1 skill point on your Spell-power skill adds 0.2 bonus skill points to your Magic skill. [[[[[BThis skill only affects the 11 primary schools] (Mana, Earth, Air, Fire, Water, Meta, Mind, Temporal, Conveyance, Divination and Nature), as well as Geomancy and the spells granted by the Gods. ~~~~~23|Skills|Sorcery [[[[[BSorcery] This skill is a sub-skill of the Magic skill. It allows you to access any spell in the 11 schools up to the sorcery skill level. For example, if you have a sorcery skill of 1, you could cast "Manathrust", which is a level 1 mana school spell; and "Phase Door", which is a level 1 conveyance school spell. Spending 1 skill point on your Sorcery skill adds 0.2 bonus skill points to your Magic skill. [[[[[BThis skill only affects the 11 primary schools] (Mana, Earth, Air, Fire, Water, Meta, Mind, Temporal, Conveyance, Divination and Nature). However, handling that much magic is hazardous to your health, and as such reduces both your hit points and your fighting ability. Any ability in sorcery affects your Weaponmastery, Archery, Barehand-combat and gives a negative percentage modifier to your total hit points, equal to the level of your sorcery skill (i.e. if sorcery is 12.500, hit points get modified by -12.5%). ~~~~~24|Skills|Mana [[[[[BMana] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_mana.txt*0[mana] school, and as it increases so does the casting level of spells already attained in the school. For example, if you have level 1 in the mana school, you could cast "Manathrust" at a casting level of 1. For every skill level you add to Mana, Manathrust will become more powerful, adding 1 casting level to the spell. Spending 1 skill point on your Mana skill adds 0.1 bonus skill points to your Magic skill. ~~~~~60|Skills|Geomancy [[[[[BGeomancy] This skill is a subskill of the Magic skill. It gives access to spells within the *****m_geoman.txt*0[Geomancy] school, and as it increases so does the casting level of spells already attained in the school. Most spells from this school rely on the Fire, Water, Air and Earth skills as well. Spending 1 skill point on your Geomancy skill adds 0.45 bonus skill points to your Fire, Water, Air and Earth skills. ~~~~~25|Skills|Fire [[[[[BFire] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_fire.txt*0[fire] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Fire skill adds 0.1 bonus skill points to your Magic skill. ~~~~~26|Skills|Water [[[[[BWater] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_water.txt*0[water] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Water skill adds 0.1 bonus skill points to your Magic skill. ~~~~~27|Skills|Air [[[[[BAir] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_air.txt*0[air] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Air skill adds 0.1 bonus skill points to your Magic skill. ~~~~~28|Skills|Earth [[[[[BEarth] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_earth.txt*0[earth] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Earth skill adds 0.1 bonus skill points to your Magic skill. ~~~~~29|Skills|Meta [[[[[BMeta] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_meta.txt*0[meta] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Meta skill adds 0.1 bonus skill points to your Magic skill. ~~~~~30|Skills|Conveyance [[[[[BConveyance] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_convey.txt*0[conveyance] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Conveyance skill adds 0.1 bonus skill points to your Magic skill. ~~~~~31|Skills|Divination [[[[[BDivination] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_divin.txt*0[divination] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Divination skill adds 0.1 bonus skill points to your Magic skill. ~~~~~32|Skills|Temporal [[[[[BTemporal] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_tempo.txt*0[temporal] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Temporal skill adds 0.1 bonus skill points to your Magic skill. ~~~~~33|Skills|Mind [[[[[BMind] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_mind.txt*0[mind] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Mind skill adds 0.1 bonus skill points to your Magic skill. ~~~~~34|Skills|Nature [[[[[BNature] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_nature.txt*0[nature] school, and as it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Nature skill adds 0.1 bonus skill points to your Magic skill. Investing in the Nature skill? You might be interested in the *****ability.txt*03[Tree Walking] ability. ~~~~~48|Skills|Udun [[[[[BUdun] This skill is a sub-skill of the Magic skill. It gives access to spells within the *****m_udun.txt*0[Udun] school, and is available only to worshippers of Melkor. As it increases so does the casting level of spells already attained in the school. Spending 1 skill point on your Udun skill adds 0.1 bonus skill points to your Magic skill. ~~~~~52|Skills|Demonology [[[[[BDemonology] This skill is a sub-skill of the Magic skill. *****m_demono.txt*0[Demonology] gives access to spells contained within special Demon-blades, -shields and -horns (helms), and as it increases so does the casting level of spells already attained in the school. This skill is available only to Demonologists, or those sufficiently corrupted with demon-like powers. Spending 1 skill point on your Demonology skill adds 0.1 bonus skill points to your Magic skill. ~~~~~35|Skills|Necromancy [[[[[BNecromancy] This skill is a sub-skill of the Magic skill. It grants access to *****m_necrom.txt*0[necromancy] spells. This is the base skill of the Necromancer class. Spending 1 skill point on your Necromancy skill adds 0.04 bonus skill points to your Magic skill. Investing in the Necromancy skill? You might be interested in the *****ability.txt*08[Touch of Death] and *****ability.txt*12[Undead Form] abilities. ~~~~~36|Skills|Runecraft [[[[[BRunecraft] This skill is a sub-skill of the Magic skill. This is the base skill of the Runecrafter class. Spending 1 skill point on your Runecraft skill adds 0.12 bonus skill points to your Magic skill. ~~~~~37|Skills|Thaumaturgy [[[[[BThaumaturgy] This skill is a sub-skill of the Magic skill. Each level of *****m_thaum.txt*0[thaumaturgy] gives a few random attack spells that can be cast without the use of spell books of any sort. However, once learned these spells do not gain in levels as the thaumaturgy skill or the spell-power skills are increased. Spending 1 skill point on your Thaumaturgy skill adds 0.06 bonus skill points to your Magic skill. ~~~~~49|Skills|Alchemy [[[[[BAlchemy] The Alchemy skill affects your ability to extract and use essences to create magical items. Investing in the Alchemy skill? You might be interested in the *****ability.txt*09[Artifact Creation] ability. ~~~~~38|Skills|Spirituality [[[[[BSpirituality] The spirituality skill influences things which have a "helping hand" from the Gods, like your saving throw, and the general spirituality skills. Sub-skills of Spirituality are Prayer, Mindcraft and Music. ~~~~~39|Skills|Prayer [[[[[BPrayer] This skill is a sub-skill of the Spirituality skill. It affects what level of your *****gods.txt*0[God's] special magic you can access (and what levels of the additional schools that each God also provides). Spending 1 skill point on your Prayer skill adds 0.1 bonus skill points to your Spirituality skill and 0.1 bonus skill points to your Magic skill. ~~~~~41|Skills|Mindcraft [[[[[BMindcraft] This skill is a sub-skill of the Spirituality skill. It affects what level of *****m_mindcr.txt*0[Mindcrafter powers] you can access, which is done without books and is available under the "m" menu. Spending 1 skill point on your Mindcraft skill adds 0.1 bonus skill points to your Spirituality skill and 0.1 bonus skill points to your Magic skill. ~~~~~59|Skills|Music [[[[[BMusic] This skill is a sub-skill of the Spirituality skill. It affects what level of *****m_music.txt*0[Musical songs] you can access through instruments. This power is available under the "m" menu. Spending 1 skill point on your Music skill adds 0.1 bonus skill points to your Spirituality skill and 0.1 bonus skill points to your Magic skill. ~~~~~42|Skills|Monster-lore [[[[[BMonster-lore] The monster-lore skill affects your general ability at the monster related skills. It determines how much experience you will gain if your *****dungeon.txt*18[pets] kill a monster, and how many companions you can have. At skill level 12, it allows you to turn a pet into a loyal companion. Sub-skills of Monster-lore are Summoning, Corpse-preservation, Possession, Symbiosis, and Mimicry. ~~~~~43|Skills|Summoning [[[[[BSummoning] This skill is a sub-skill of the Monster-lore skill. It affects your ability to create "totems" and use them to summon monsters to your aid. Spending 1 skill point on your Summoning skill adds 0.1 bonus skill points to your Monster-lore skill. ~~~~~44|Skills|Corpse-preservation [[[[[BCorpse-preservation] This skill is a sub-skill of the Monster-lore skill. It affects your ability to kill monsters without destroying their bodies, so the corpses will be available to use. Spending 1 skill point on your Corpse-preservation skill adds 0.1 bonus skill points to your Monster-lore skill. ~~~~~45|Skills|Possession [[[[[BPossession] This skill is a sub-skill of the Monster-lore skill. It affects your ability to possess a dead monster's corpse. Spending 1 skill point on your Possession skill adds 0.1 bonus skill points to your Monster-lore skill. ~~~~~46|Skills|Symbiosis [[[[[BSymbiosis] This skill is a sub-skill of the Monster-lore skill. It affects your ability to go into symbiosis with monsters that cannot move, and to cast *****m_symbio.txt*0[Symbiotic] spells. Spending 1 skill point on your Symbiosis skill adds 0.1 bonus skill points to your Monster-lore skill. ~~~~~47|Skills|Mimicry [[[[[BMimicry] This skill is a sub-skill of the Monster-lore skill. It affects your ability to use cloaks of mimicry to change form and to cast *****m_mimic.txt*0[Mimicry spells]. Spending 1 skill point on your Mimicry skill adds 0.1 bonus skill points to your Monster-lore skill. tome-235-src/lib/help/m_necrom.txt0000644000076400017500000000313211012107760014720 0ustar dgdg|||||oy ~~~~~01|Magic|Necromancy ~~~~~02|Necromancy Magic ~~~~~03|Skills|Necromancy - Spell Info #####R === ToME Magic - Necromancy === The art of Necromancy is the foul practice of manipulating the life force of creatures. Necromancy powers are accessed using the 'm' key and then selecting 'Use Necromancy'; they are cast with Spell Points, like normal spells, and do not need light to be performed. 1. [[[[[DHorrify] (Level 1) Cost:2 Calls upon the dark forces and opens a channel into the mind of a monster, stunning and scaring it. At level 21 it affects all monsters in a beam. At level 36 it affects all monsters in a ball. At level 46 it affects all monsters in sight. 2. [[[[[DRaise Dead] (Level 5) Cost:6 This power makes corpses in a small radius around the caster rise as undead ego monsters at the service of the caster. The loyalty of those monsters is not guaranteed, though. It also heals all monsters within the same radius. 3. [[[[[DNecromantic Teeth] (Level 12) Cost:20 This conjures up a temporary vampiric weapon. 4. [[[[[DAbsorb Soul] (Level 20) Cost:10 This heals you by a substantial amount every time you kill a monster within its duration. It is especially useful when your character is in *****ability.txt*12[Undead Form]. 5. [[[[[DVampirism] (Level 30) Cost:15 Drains part of the life-force from a nearby monster and gives it to you. 6. [[[[[DDeath] (Level 35) Cost:100 Yes, the name is not nice. Neither are the effects: the target dies immediately, but so does your character (note that death is not such a great annoyance for necromancers). tome-235-src/lib/help/c_alchem.txt0000644000076400017500000001407111012107760014660 0ustar dgdg|||||oy ~~~~~01|Alchemist ~~~~~02|Classes|Alchemist #####R=== Alchemists === #####GDescription Alchemists are the only class that can harness the abilities of the essences found in the dungeon. They can add these essences to staves, rings, wands, rods, and sometimes weapons and armour to create new items or recharge old ones. They can also extract essences from magical items they find. Using these abilities, Alchemists can get very good items at low levels. The trouble is getting them to survive later on. Alchemists are extremely proficient with all kinds of magical devices, and have made a fine art of extracting, storing, and using these objects' magical energies. Because they neither fight well nor cast powerful spells, Alchemists rely on their craftsmanship to cope with the dangers of the dungeons. They will quickly learn to create damage- dealing wands, rods, and staffs, forge powerful weapons and armour, make highly useful objects of other kinds, and eventually, at great cost to other knowledge, they can learn the perilous art of artifact creation itself. #####GStarting Stat Modifiers Strength -5 Intelligence +3 Wisdom +0 Dexterity +1 Constitution -2 Charisma +1 Hit Die +d0 Spell Points +0% Exp Penalty 30% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 1.000 [0.700] Weaponmastery 0.700 [0.700] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Magic 3.000 [0.900] Magic-Device 1.000 [1.250] Geomancy Fire 0.000 [0.100] Water 0.000 [0.100] Air 0.000 [0.100] Earth 0.000 [0.100] Meta 0.000 [0.500] Conveyance 0.000 [0.100] Divination 0.000 [0.500] Temporal 0.000 [0.100] Mind 0.000 [0.100] Nature 0.000 [0.100] Necromancy 0.000 [0.100] Runecraft 0.000 [0.700] Thaumaturgy 0.000 [0.100] Alchemy 1.000 [0.800] Spirituality 1.000 [0.800] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] *An Alchemist cannot learn the Geomancy skill, but it is shown in his skill screen because the elemental schools are sub-skills of it. #####GInnate Abilities: #####BAbility Character level Perfect casting 1 #####GStarting Equipment An Alchemist begins the game with: a Dagger six Essences of Explosion an Empty Bottle a Set of Leather Gloves ~~~~~03|Alchemist|Alchemy powers explained ~~~~~05|Skills|Alchemy - Alchemy powers #####GAlchemy [[[[[BThe alchemical techniques are accessed using the 'm' key.] Alchemists may then 'E'xtract essences or add 'P'owers. The Alchemist [[[[[vmust] be wearing GLOVES to use their alchemy powers. An Alchemists is also capable of [[[[[Bcreating their own artifacts], but this is a time-consuming, and costly, activity. To do so, he must first learn the ability *****ability.txt*09[Artifact Creation], which costs a whopping 70 skill points to learn, and requires some high pre-requisites. Once he has done so, he needs to imbue an ego item with a number of essences of magic (equal to their skill level) and then wield the item. While using the item, it will gain experience (which reduces the amount of exp the wearer gains during this time). When the Alchemist feels that the item is powerful enough, he can finalise the artifact by "buying" powers using the experience the artifact has collected. He will also require exotic ingredients to add the abilities. Most (but not all) potions, scrolls, wands, staffs, rods, rings, and amulets contain usable magical energies. An Alchemist taps that energy, using the technique "'E'xtract essences" to create one or more essences of a type appropriate to the original object. The drained object itself is now called "of nothing". Unlike any other kind of object, it can have new magics added to it. An Alchemist can add power to such items by using essences he made or found. He does this with the technique "'P'ower". He can then select the object he wishes to enchant, and the kind of object he wishes to create. Only object types for which he knows the recipe will be displayed, and ones for which essences are lacking will be displayed in red. Objects whose level exceeds his own are sometimes difficult to create, though he can always add gold to improve the chances of his success. [[[[[BA few pointers:] -Recipes are (usually) logical. Acid essences don't make Dragon Weapons. And you can always look at the recipes you know with the "recipe 'B'ook" command. -Not all objects or ego-item types can be made using alchemy. -Alchemy is mostly reversible. Most items that you can 'E'xtract from, you can later re-create, if you learn about them when extracting from them. You won't always get enough essences from destroying an item to recreate it, though the chance of doing so will get higher as you increase in skill. -*Identifying* an object that you can destroy will always teach you how to create it (if creating it is possible). -Since you can't create abilities in artifacts that you aren't aware of, make sure to *identify* all the artifacts you can. -You can't *identify* things you buy in shops, so you'll have to extract from them and take your chances. [[[[[BSome Recipes:] Any Alchemist worth his salt knows lots of recipes. By extracting from items in the dungeon, he learns to create more and more items. You can see the recipes you know using the "recipe 'B'ook" command. The Alchemist starts off knowing some basic recipes, and gains more recipes as time goes on. More details can be found in the *****essences.txt*0[Essences SPOILER]). tome-235-src/lib/help/command.txt0000644000076400017500000022170011012107760014542 0ustar dgdg|||||oy ~~~~~99|Commands #####R=== List of Commands === Angband commands are entered as an "underlying command" (a single key) plus a variety of optional or required arguments. You may choose how the "keyboard keys" are mapped to the "underlying commands" by choosing one of two standard "keysets", the "original" keyset or the "roguelike" keyset. The original keyset is very similar to the "underlying" command set, with a few additions (such as the ability to use the numeric "directions" to "walk" or the "5" key to "stay still"). The roguelike keyset provides similar additions, and also allows the use of the h/j/k/l/y/u/b/n keys to "walk" (or, in combination with the shift or control keys, to run or tunnel), which thus requires a variety of key mappings to allow access to the underlying commands used for walking/running/tunneling. In particular, the "roguelike" keyset includes many more "capital" and "control" keys, as shown below. Note that any keys that are not required for access to the underlying command set may be used by the user as "command macro" triggers (see below). You may always specify any "underlying command" directly by pressing backslash ("\") plus the "underlying command" key. This is normally only used in "macro" definitions. [[[[[BYou may often enter "control-keys" as a caret ("^") plus the key] (so "^" + "p" often yields "^P"). Some commands allow an optional "repeat count", which allows you to tell the game that you wish to do the command multiple times, unless you press a key or are otherwise disturbed. To enter a "repeat count", type '0', followed by the numerical count, followed by the command. You must type "space" before entering certain commands. Skipping the numerical count yields a count of 99. An option allows certain commands (open, disarm, tunnel, etc) to auto-repeat. Some commands will prompt for extra information, such as a direction, an inventory or equipment item, a spell, a textual inscription, the symbol of a monster race, a sub-command, a verification, an amount of time, a quantity, a file name, or various other things. Normally you can hit return to choose the "default" response, or escape to cancel the command entirely. Some commands will prompt for a spell or an inventory item. Pressing space (or '*') will give you a list of choices. Pressing "-" (minus) selects the item on the floor. Pressing a lowercase letter selects the given item. Pressing a capital letter selects the given item after verification. Pressing a numeric digit '#' selects the first item (if any) whose inscription contains "@#" or "@x#", where "x" is the current "underlying command". You may only specify items which are "legal" for the command. Whenever an item inscription contains "!*" or "!x" (with "x" as above) you must verify its selection. In ToME, there are items which occasionally teleport you away, asking for permission first. The recurring "Teleport (y/n)?" can be annoying, and this behavior can be eliminated by inscribing the object which causes the teleportation with "." (or any inscription containing the character "."). With this inscription, the object will no longer teleport you around nor keep asking you. If you want to restore the teleport ability to the object, just remove the "." from its inscription. Note that cursed items which teleport you are unaffected by the inscription. Some commands will prompt for a direction. You may enter a "compass" direction using any of the "direction keys" shown below. Sometimes, you may specify that you wish to use the current "target", by pressing "t" or "5", or that you wish to select a new target, by pressing "*" (see "Target" below). ~~~~~95 #####G Original Keyset Directions Roguelike Keyset Directions 7 8 9 y k u 4 6 h l 1 2 3 b j n Each of the standard keysets provides some short-cuts over the "underlying commands". For example, both keysets allow you to "walk" by simply pressing an "original" direction key (or a "roguelike" direction key if you are using the roguelike keyset), instead of using the "walk" command plus a direction. [[[[[BThe roguelike keyset allows you to "run" or "tunnel" by simply holding the] [[[[[Bshift or control modifier key down while pressing a "roguelike" direction key,] [[[[[Binstead of using the "run" or "tunnel" command plus a direction.] Both keysets allow the use of the "5" key to "stand still", which is most convenient when using the original keyset. Note that on many systems, it is possible to define "macros" (or "command macros") to various keys, or key combinations, so that it is often possible to make macros which, for example, allow the use of the shift or control modifier keys, plus a numeric keypad key, to specify the "run" or "tunnel" command, with the given direction, regardless of any keymap definitions, by using the fact that you can always, for example, use "\" + "." + "6", to specify "run east". ~~~~~100|Commands|Original keyset #####R=== Original Keyset Command Summary (4.2.x) === *****command.txt*1[a Aim a wand] *****command.txt*2[A Activate an artifact] *****command.txt*3[b Browse a book] *****command.txt*4[B Bash a door] *****command.txt*5[c Close a door] *****command.txt*6[C Character description] *****command.txt*7[d Drop an item] *****command.txt*8[D Disarm a trap] *****command.txt*9[e Equipment list] *****command.txt*10[E Eat some food] *****command.txt*11[f Fire (shoot) an item] *****command.txt*12[F Fuel your lantern/torch] *****command.txt*13[g Stay still (flip pickup)] *****command.txt*14[G Gain new skills] *****command.txt*15[h Hack up a corpse] *****command.txt*16[H Drink from a fountain] *****command.txt*17[i Inventory list] *****command.txt*18[I Inspect (closely examine) an item] *****command.txt*19[j Jam a door] J (unused) *****command.txt*20[k Destroy an item] *****command.txt*21[K Cure meat] *****command.txt*22[l Look around] *****command.txt*23[L Look around dungeon by sector] *****command.txt*24[m Cast a spell / use mental power] *****command.txt*25[M Full dungeon map] *****command.txt*85[n Repeat last command] *****command.txt*91[N Abilities Screen] *****command.txt*26[o Open a door or chest] *****command.txt*27[O Sacrifice at an altar] *****command.txt*28[p Pray to your god (if any)] *****command.txt*29[P Pet commands] *****command.txt*30[q Quaff a potion] *****command.txt*31[Q Quit (commit suicide)] *****command.txt*32[r Read a scroll] *****command.txt*33[R Rest for a period] *****command.txt*34[s Search for traps/doors] *****command.txt*35[S Toggle search mode] *****command.txt*36[t Take off equipment] *****command.txt*37[T Dig a tunnel] *****command.txt*38[u Use a staff] *****command.txt*39[U Use bonus power (if any)] *****command.txt*40[v Throw an item] *****command.txt*41[V Version Info] *****command.txt*42[w Wear/wield equipment] W (unused) *****command.txt*43[x Engrave the floor] X (unused) *****command.txt*44[y Give item to monster] *****command.txt*96[Y Chat with a monster] *****command.txt*45[z Zap a rod] *****command.txt*46[Z Steal] *****command.txt*47[! Interact with system] *****debug.txt*101[^A (special - debug command)] *****command.txt*49[@ Interact with macros] ^B (unused) *****command.txt*89[# Begin extended command] ^C (special - break) *****command.txt*97[$ Record macros] ^D (unused) *****command.txt*51[% Interact with visuals] *****command.txt*52[^E Toggle choice window] ^ (special - control key) *****command.txt*53[^F Repeat level feeling] *****command.txt*54[& Interact with colors] ^G (unused) *****command.txt*55[* Target monster or location] ^H (unused) ( (unused) ^I (special - tab) ) (unused) ^J (special - linefeed) *****command.txt*58[{ Inscribe an object] ^K (unused) *****command.txt*59[} Uninscribe an object] ^L (unused) [ (unused) ^M (special - return) ] (unused) ^N (unused) *****command.txt*60[- Walk (flip pickup)] ^O (unused) *****command.txt*61[_ Re-Enter store] *****command.txt*62[^P Show previous messages] *****command.txt*63[+ Alter grid] *****command.txt*64[^Q Quit to next midi song] *****command.txt*65[= Set options] *****command.txt*66[^R Redraw the screen] *****command.txt*67[; Walk (with pickup)] *****command.txt*68[^S Save and don't quit] *****command.txt*69[: Take notes] *****command.txt*70[^T Time of the day] ' (unused) ^U (unused) *****command.txt*71[" Enter a user pref command] ^V (unused) *****command.txt*72[, Stay still (with pickup)] ^W (special - wizard mode) *****command.txt*74[< Go up staircase] *****command.txt*75[^X Save and quit] *****command.txt*76[. Run] ^Y (unused) *****command.txt*77[> Go down staircase] ^Z (special - borg command) *****command.txt*79[\ (special - bypass keymap)] *****command.txt*80[| Do cmovies] *****command.txt*81[` (special - escape)] *****command.txt*82[~ Display current knowledge] *****command.txt*83[/ Identify symbol] *****command.txt*84[? Help] *****command.txt*98[^\] Take an html screenshot] ~~~~~101|Commands|Roguelike keyset #####R=== Roguelike Keyset Command Summary (4.2.x) === *****command.txt*45[a Zap a rod (Activate)] *****command.txt*2[A Activate an artifact] *****command.txt*95[b (walk - south west)] *****command.txt*95[B (run - south west)] *****command.txt*5[c Close a door] *****command.txt*6[C Character description] *****command.txt*7[d Drop an item] *****command.txt*8[D Disarm a trap or chest] *****command.txt*9[e Equipment list] *****command.txt*10[E Eat some food] *****command.txt*4[f Bash a door (force)] *****command.txt*12[F Fuel your lantern/torch] *****command.txt*13[g Stay still (flip pickup)] *****command.txt*14[G Gain new skills] *****command.txt*95[h (walk - west)] *****command.txt*95[H (run - west)] *****command.txt*17[i Inventory list] *****command.txt*18[I Observe an item] *****command.txt*95[j (walk - south)] *****command.txt*95[J (run - south)] *****command.txt*95[k (walk - north)] *****command.txt*95[K (run - north)] *****command.txt*95[l (walk - east)] *****command.txt*95[L (run - east)] *****command.txt*24[m Spell casting / mental power] *****command.txt*25[M Full dungeon map] *****command.txt*95[n (walk - south east)] *****command.txt*95[N (run - south east)] *****command.txt*26[o Open a door or chest] *****command.txt*39[O Use bonus power (if any)] *****command.txt*28[p Pray to your god (if any)] *****command.txt*3[P Browse a book] *****command.txt*30[q Quaff a potion] *****command.txt*31[Q Quit (commit suicide)] *****command.txt*32[r Read a scroll] *****command.txt*33[R Rest for a period] *****command.txt*34[s Search for traps/doors] *****command.txt*97[S Record macros] *****command.txt*11[t Fire an item] *****command.txt*36[T Take off equipment] *****command.txt*95[u (walk - north east)] *****command.txt*95[U (run - north east)] *****command.txt*40[v Throw an item] *****command.txt*16[V Drink from a fountain] *****command.txt*42[w Wear/wield equipment] *****command.txt*23[W Locate player on map (Where)] *****command.txt*22[x Look around] *****command.txt*29[X Pet commands] *****command.txt*95[y (walk - north west)] *****command.txt*95[Y (run - north west)] *****command.txt*1[z Aim a wand (Zap)] *****command.txt*38[Z Use a staff (Zap)] *****command.txt*47[! Interact with system] ^A (special - debug command) *****command.txt*49[@ Interact with macros] *****command.txt*95[^B (tunnel - south west)] *****command.txt*35[# Toggle search mode] ^C (special - break) *****command.txt*15[$ Hack up a corpse] *****command.txt*20[^D Destroy item] *****command.txt*51[% Interact with visuals] *****command.txt*52[^E Toggle choice window] ^ (special - control key) *****command.txt*53[^F Repeat level feeling] *****command.txt*54[& Interact with colors] *****command.txt*27[^G Sacrifice at an altar] *****command.txt*55[* Target monster or location] *****command.txt*95[^H (tunnel - west)] *****command.txt*96[( Chat] ^I (special - tab) *****command.txt*89[) Begin extended command] *****command.txt*95[^J (tunnel - south)] *****command.txt*58[{ Inscribe an object] *****command.txt*95[^K (tunnel - north)] *****command.txt*59[} Uninscribe an object] *****command.txt*95[^L (tunnel - east)] [*****command.txt*46[ Steal] *****command.txt*95[^M (tunnel - south)] ]*****command.txt*43[ Engrave the floor] *****command.txt*95[^N (tunnel - south east)] *****command.txt*60[- Walk (flip pickup)] *****command.txt*21[^O Cure meat] *****command.txt*61[_ Enter store] *****command.txt*62[^P Show previous messages] *****command.txt*63[+ Alter grid] *****command.txt*64[^Q Quit to next midi song] *****command.txt*65[= Set options] *****command.txt*66[^R Redraw the screen] *****command.txt*67[; Walk (with pickup)] *****command.txt*68[^S Save and don't quit] *****command.txt*69[: Take notes] *****command.txt*37[^T Dig a Tunnel] *****command.txt*44[' Give object to monster] *****command.txt*95[^U (tunnel - north east)] *****command.txt*71[" Enter a user pref command] ^V (unused) *****command.txt*76[, Run] ^W (special - wizard mode) *****command.txt*74[< Go up staircase] *****command.txt*75[^X Save and quit] *****command.txt*72[. Stay still (with pickup)] *****command.txt*95[^Y (tunnel - north west)] *****command.txt*77[> Go down staircase] ^Z (special - borg command) *****command.txt*79[\ (special - bypass keymap)] *****command.txt*80[| Do cmovies] *****command.txt*81[` (special - escape)] *****command.txt*82[~ Display current knowledge] *****command.txt*83[/ Identify symbol] *****command.txt*84[? Help] ~~~~~102|Commands|Special keys #####R=== Special Keys === Certain special keys may be intercepted by the operating system or the host machine, causing unexpected results. In general, these special keys are control keys, and often, you can disable their special effects. If you are playing on a UNIX or similar system, then Ctrl-C will interrupt ToME. The second and third interrupt will induce a warning bell, and the fourth will induce both a warning bell and a special message, since the fifth will quit the game, after killing your character. Also, Ctrl-Z will suspend the game, and return you to the original command shell, until you resume the game with the "fg" command. There is now a compilation option to force the game to prevent the "double ctrl-z escape death trick". The Ctrl-\ and Ctrl-D and Ctrl-S keys should not be intercepted. It is often possible to specify "control-keys" without actually pressing the control key, by typing a caret ("^") followed by the key. This is useful for specifying control-key commands which might be caught by the operating system as explained above. ~~~~~79 Pressing [[[[[Gbackslash ("\\")] before a command will bypass all keymaps, and the next keypress will be interpreted as an "underlying command" key, unless it is a caret ("^"), in which case the keypress after that will be turned into a control-key and interpreted as a command in the underlying ToME keyset. The backslash key is useful for creating macro actions which are not affected by any keymap definitions that may be in force, for example, the sequence "\" + "." + "6" will always mean "run east", even if the "." key has been mapped to a different underlying command. The "0" and "^" and "\" keys all have special meaning when entered at the command prompt, and there is no "useful" way to specify any of them as an "underlying command", which is okay, since they would have no effect. ~~~~~81 For many input requests or queries, the [[[[[Gspecial character ESCAPE] will abort the command. The "[y/n]" prompts may be answered with "y" or "n", or escape. The "-more-" message prompts may be cleared (after reading the displayed message) by pressing ESCAPE, SPACE, RETURN, LINEFEED, or by any keypress, if the "quick_messages" option is turned on. ~~~~~103|Commands|Command counts ~~~~~104|Commands|Repeating a command #####R=== Command Counts === Some commands can be executed a fixed number of times by preceding them with a count. Counted commands will execute until the count expires, until you type any character, or until something significant happens, such as being attacked. Thus, a counted command doesn't work to attack another creature. While the command is being repeated, the number of times left to be repeated will flash by on the line at the bottom of the screen. [[[[[BTo give a count to a command, type 0, the repeat count, and then] [[[[[Bthe command.] If you want to give a movement command and you are using the original command set (where the movement commands are digits), press space after the count and you will be prompted for the command. Counted commands are very useful for searching or tunneling, as they automatically terminate on success, or if you are attacked. You may also terminate any counted command (or resting or running), by typing any character. This character is ignored, but it is safest to use a SPACE or ESCAPE which are always ignored as commands in case you type the command just after the count expires. You can tell ToME to automatically use a repeat count of 99 with commands you normally want to repeat (open, disarm, tunnel, bash, alter, etc) by setting the "always_repeat" option. #####R=== Selection of Objects === Many commands will also prompt for a particular object to be used. For example, the command to read a scroll will ask you which of the scrolls that you are carrying that you wish to read. In such cases, the selection is made by typing a letter of the alphabet. The prompt will indicate the possible letters, and will also allow you to type the key "*", which causes all of the available options to be described. The list of choices will also be shown in the Choice window, if you are using a windows environment and windows are turned on. Often you will be able to press "/" to select an object from your equipment instead of your inventory. Pressing space once will have the same effect as "*", and the second time will cancel the command and run the "i" or "e" command. [[[[[BThe particular object may be selected by an upper case or a lower] [[[[[Bcase letter. If lower case is used, the selection takes place] [[[[[Bimmediately. If upper case is used, then the particular option is] [[[[[Bdescribed, and you are given the option of confirming or retracting that] [[[[[Bchoice.] Upper case selection is thus safer, but requires an extra key stroke. Also see the "!*" and "!x" inscriptions, below. For many commands, [[[[[Byou can also use "-" to select an object on the] [[[[[Bfloor where you are standing.] This lets you read scrolls or quaff potions, for example, off the dungeon floor without picking them up. ~~~~~90 If you enter a number between 0 and 9, the first item engraved with "@#" where "#" is the number you entered will be selected. For example, if you have a shovel engraved with "@0" and you type "w" (for wield) and then 0, you will wield the shovel. This is very useful for macros (see below), since you can use this to select an object regardless of its location in your pack. Multiple numbers can be engraved on the same object; for example, if a sword is engraved with @1@0, then either "w1" or "w0" will wield it. Normally, you inscribe "@1@0" on your primary weapon, and "@2@0" on your secondary weapon. [[[[[BNote that an inscription containing] [[[[[B"@x#" will act like "@#" but only when the current "ToME command"] [[[[[Bis "x".] Thus you can put "@z4" on a rod and "@u4" on a staff, and then use both "z4" and "u4" as desired. Note that any object containing "!x" in its inscription, where "x" is the current "ToME command" (or containing "!*" ever) will induce "verification" whenever that object is "selected". Thus, inscribing, say, "!f!k!d" on an object will greatly reduce the odds of you "losing" it by accident, and [[[[[Binscribing "!*" on an object] will allow you to be very paranoid about the object. Note that "selling" and "dropping" both use the "d" command. ~~~~~105|Pref files #####R=== User Pref Files === ToME allows you to change various aspects of the game to suit your tastes. You may define keymaps (changing the way ToME maps your keypresses to underlying commands), create macros (allowing you to map a single keypress to a series of keypresses), modify the visuals (allowing you to change the appearance of monsters, objects, or terrain features), change the colors (allowing you to make a given color brighter, darker, or even completely different), or set options (turning them off or on). ToME stores your preferences in files called "user pref files", which contain comments and "user pref commands", which are simple strings describing one aspect of the system about which the user has a preference. There are many ways to load a user pref file, and in fact, some of these files are automatically loaded for you by the game. All of the files are kept in the "lib/user/" directory, though you may have to use one of the command line arguments to redirect this directory, especially on multiuser systems. You may also enter single user pref commands directly, using the special "Enter a user pref command" command, activated by "double quote". You may have to use the "redraw" command (^R) after changing certain of the aspects of the game, to allow ToME to adapt to your changes. When the game starts up, after you have loaded an old character, or created a new character, some user pref files are loaded automatically. First, the "pref.prf" file is loaded. This file contains some user pref commands which will work on all platforms. Then one of "font-xxx.prf" (for normal usage) or "graf-xxx.prf" (for bitmap usage) is loaded. These files contain attr/char changes to allow the monsters, objects, and/or terrain features to look "better" on your system. Then the "pref-xxx.prf" file is loaded. This file contains pre-defined system specific stuff (macros, color definitions, etc). Then, the "user-xxx.prf" file is loaded. This file contains user-defined system specific stuff. The "user-xxx.prf" file is used as the "default" user pref file in many places. The "xxx" is the "system suffix" for your system, taken from the "main-xxx.c" file which was used to generate your executable. Finally, the "Race.prf", "Class.prf", and "Name.prf" files are loaded, where "Race", "Class", and "Name" are replaced by the actual race, class, and name of the current character. Several commands allow you to both load existing user pref files, create new user pref files, append information to existing user pref files, and/or interact with various of the user preferences in a more intuitive way than the user pref commands allow. The commands include "Interact with macros" (@), "Interact with visuals" (%), and "Interact with colors" (&), described below. ~~~~~106|Pref files|Macros #####G--- User Pref Files (Macros) --- The "Interact with macros" command allows you to define or remove "macros", which are mappings from a single logical keypress to a sequence of keypresses, allowing you to use special keys on the keyboard, such as function keys or keypad keys, possibly in conjunction with modifier keys, to "automate" repetitive multi-keypress commands that you use a lot. Since macros represent keypress sequences, and not all keypresses have a printable representation, macro triggers and actions must often be "encoded" into a human readable form. This is done using several types of encoding, including "\xHH" for character number HH in hexidecimal, "\e" for the "escape" code, "\n" for the "newline" code, "\r" for the "return" code, "\s" for the "space" code, "\\" for backslash, "\^" for caret, and "^X" for the code for any "control" key "ctrl-X". Note that the "action" of a macro will not be checked against other macro triggers (unless the macro action contains a "control-backslash"), so you cannot make infinite loops. You may specify extremely long macros, but you are limited in length by the underlying input mechanisms, which in general limit you to about 1024 keys in both triggers and actions. The special "\" command (which must be encoded in macros as "\\") is very useful in macros, since it bypasses all keymaps and allows the next keystroke to be considered a command in the underlying ToME command set. For example, a macro which maps Shift-KP6 to "\" + "." + "6" will induce the "run east" behavior, regardless of what keyset the user has chosen, and regardless of what keymaps have been defined. Macros can be specified in user pref files as a pair of lines, one of the form "A:", which defines the encoded macro action, and one of the form "P:", which defines the encoded macro trigger. A [[[[[Bcommon example of a macro] to cast the first spell in your first spell book at the nearest monster would be: \e\e\em1a*t where \e is an escape (to make sure you are not still within another command), m1 selects the spell book that is inscribed ({) with @m1, a selects the first spell in that book, and *t targets the nearest monster. More detailed information about specific macros can be found in *****macrofaq.txt*0[macrofaq.txt], originally written by Jim Lyon (jplyon@attglobal.net), modified for ToME with Jim's permission by Dawnmist (angband@dawnmist.8m.com). ~~~~~107|Pref files|Keymaps #####G--- User Pref Files (Keymaps) --- The "Interact with macros" command also allows you to define "keymaps", which are vaguely related to macros. A keymap maps a single keypress to a series of keypresses, which bypass both other keymaps and any macros. ToME uses keymaps to map the original and the roguelike keysets to the underlying command set, and allows the user to modify or add keymaps of their own. Note that all keymap actions must be specified using underlying commands, not keypresses from the original or roguelike keysets. The original keyset is almost identical to the underlying keyset, except that "numbers" are mapped to ";" plus a direction, "5" is mapped to ",", and a few control-keys are mapped to various things. See "command.txt" for the full set of underlying commands. Some uses for keymaps include the ability to "disable" a command by mapping it to "\x00", Keymaps can be specified in user pref files as line of the form "M: ", where is the keyset (0/1 for original/roguelike), is the encoded trigger key, and is the encoded keymap action. ~~~~~108|Pref files|Visuals #####G--- User Pref Files (Visuals) --- You can use the "Interact with visuals" command to change various visual information, currently including the choice of what attr/char values are used to represent various monsters, objects, or terrain features. Note that in combination appropriate support in "main-xxx.c", and with the use of the "use_graphics" flag, you may be able to specify that "graphic bitmaps" should be used instead of normal "colored characters" for various things. When interactively modifying the attr/char values for monsters, objects, or terrain features, pressing "n" or "N" will change which entry you are changing, pressing "a" or "A" will rotate through the available attr values, and pressing "c" or "C" will rotate though the available char values. Note that attr/char values with the "high bit" set may induce the display of special "graphic" pictures if the "use_graphics" flag is set, and your system supports the "use_graphics" flag. Note that this command can be abused in various ways, and if you must do so, remember that you are only cheating yourself. Keymaps can be specified in user pref files as line of the form "R::/" or "K::/" or "F::/" or "U::/". ~~~~~109|Pref files|Colors #####G--- User Pref Files (Colors) --- The "Interact with colors" command allows you to change the actual internal values used to display various colors. This command may or may not have any effect on your machine. Advanced machines may allow you to change the actual RGB values used to represent each of the 16 colors used by ToME, and perhaps even allow you to define new colors which are not currently used by ToME. Colors can be specified in user pref files as line of the form "V:::::". ~~~~~110|Pref files|Options #####G--- User Pref Files (Options) --- The "Interact with options" command allows you to turn options on or off. You may turn options off or on using the user pref commands of the form "X: which applies the command (+) Alter to that direction. #####G---------------------------------------------------------------------- #####G4.15 Farming techniques #####G---------------------------------------------------------------------- #####v+++ NOTE: This is considered scumming! (cheating) +++ Farming is the practice of automatically "harvesting" large numbers of weaker monsters for their experience value. This is usually done to advance a lower level character. There are apparently several methods that the "old timers" used to use. I don't know that farming is that popular any more. Even then it was sort of a lark. Apparently a golf ball is just the right size and weight for many keyboards to hold a key down and get it to auto repeat. Then you walk away, and the next morning you have gained several levels. Ballpoint pen caps are also supposed to be good at wedging a key down. Using a farming macro for long periods of time like this requires a way of getting food, so it really needs to be employed by a magic user who can create their own food. Use turn counts with attack (move) commands to move around the room, mowing down creatures as you move. Periodically rest enough to regenerate to full mana. This may not be necessary if it takes long enough to kill the monsters as you move. This requires an effective macro and a room full of breeders which can't attack for enough damage to kill you. Farming for short periods of time with a fighter class is quite feasible. The limitation for fighters is food. The limitation for spell casters is probably hit points. You may also need to insert action sequences for healing if the farmed monsters are capable of significantly damaging you. Note that red and green worm masses can knock down the doors of the room you're in. Blues can destroy potions and flasks, so you will need to stash your potions outside somewhere before farming. ~~~~~10 #####G---------------------------------------------------------------------- #####G4.16 Macros can contain their own trigger key #####G---------------------------------------------------------------------- It is permissible to make a macro or keymap which contains its own key in its action. It won't cause recursion, but there are a few wrinkles. Example: you can bind "*tf1" to the 'f' key, to cause it to auto-fire at the nearest target. You can still use the 'f' key for Fire in other macros or keymaps. If you bound 'f' as a keymap you will need to use "\\f" for Fire when it is used in a macro action string. You don't need to do anything special to use it in a keymap in its usual sense. Keymap and macro expansion isn't done inside keymap action strings. If you bound 'f' as a macro, the problem will be in entering the new macro or keymap in the editor. When you try to press an 'f' key for the action, it will expand to "*tf1", even when you don't want it to. You will first have to remove the macro bound to 'f', then add the macro or keymap that uses 'f' in its action, and then reenter the 'f' macro. You can also create the macro in a pref file and load it using the "Load pref file" command in the (@) Interact with macros screen. #####G---------------------------------------------------------------------- #####G4.17 Changing the player's color and character (ASCII text display) #####G---------------------------------------------------------------------- #####B= Using the Visuals Editor = 1) % Interact with visuals. 2) 6 Change monster attr/chars 3) a (repeatedly) cycle thru colors (A moves backwards) 4) c (repeatedly) cycle thru characters (C moves backwards) 5) Esc accept changes 6) Esc exit the editor #####B= Using the Enter User Pref command = 1) " Enter user pref line 2) "R:0::" The user pref line. - the attr (color) specified as an integer index. - the (ASCII) character specified as an integer. 3) (Hit Enter) You can't directly use the Angband attr letters to specify colors, but must instead use their index. Eg 4 is Red. These indexes can be found from within the game using the (&) Interact with colors command. That editor also allows you to change the colors used by the game. The integer is generally the index of an (ASCII) character. Non-ASCII characters may be available on some systems. Available characters can found using the (%) Interact with visuals command. These integers can be specified in decimal, hexadecimal, or octal notation. Decimal is the default, hexadecimal numbers are prefixed with "0x", and octal numbers are prefixed with 0 (zero). Example: the standard character for the player is '@'. This may be entered as "64", "0x40", or "0100". Yellow may be entered as "11", "0x0B", or "013". This pref line can be added to any pref file to save the change for future reuse. Changes made using the internal colors editor screen can be dumped from that screen. Note that colors and characters saved in pref dumps are in hexadecimal. After making a change, you must move the character or otherwise cause a screen redraw for the change to be visible. If you make a mistake, you can use the (0) command in the editor to reset the visuals to their original colors and characters. #####B= Changing Using the Monster Info file = #####B---------------------------------------- This may also be done by changing the entry for the player in the info file "r_info.txt". The player data starts with line "N:0:Player". In the following line G:: the character is entered directly, and the attr (color) is specified by letter. See the section "Message color lines" for the list of standard colors. In many versions you will have to delete the file "lib\data\r_info.raw" and restart the game for this change to take effect. Note that that char/attr pair is entered in the opposite order as for an R: user pref line. #####B= Options which Change Player appearance = #####B------------------------------------------ These are accessible through the (=) Set options command. *****option.txt*2[(hilite_player)] -- causes the player's symbol to be drawn with the "cursor" on it. It will be drawn with the same color as the character. *****option.txt*3[(player_symbols)] -- for graphics mode only, and only works when option (use_graphics) is also on. This apparently varies the player graphic and its color based on class, race, and sex. #####G---------------------------------------------------------------------- #####G4.18 Recharging a rod using a Recharge Item spell #####G---------------------------------------------------------------------- (You can also recharge staffs and wands with this technique.) Inscribe the rod with {@m}, where is any decimal digit not already used as a label. The trick is that we want to use a digit to label the rod so we can refer to it using its label instead of its inventory letter, but we have usually used up many of the digits for spell books. If we were to label the rod with {@m1} and the first spellbook was also labeled with {@m1}, then the spellbook will sort first in the inventory so it will be found first when looking for item '1' to use with the (m) command. So that would try to recharge the spellbook, which will fail. Angband doesn't restrict itself to "appropriate" items when looking for a labeled item. It simply finds the first one whose command letter and digit match. You can't get around this by omitting the letter 'm', or using 'z' instead. Using no command letter means it will still match. And if you use a command letter it has to be 'm', because that is the built-in trigger for the current command. Note that the digits used with different command triggers can be different, so inscribing {@z1@m0} is perfectly legal. Use digit 1 when zapping the rod, and 0 when referring to it during the casting of a [mage] spell. You can also use this technique with scrolls. In that case you need to use the inscription {@r} since the item is being referred to while processing the (r) Read scroll command. #####G---------------------------------------------------------------------- #####G4.19 Disabling a built-in command #####G---------------------------------------------------------------------- At times it may be useful to disable an underlying Angband command. For example, a dangerous key may be too easy to press by accident. The macro editor commands for removing macros and keymaps can't be used in this situation. [[[[[BInstead bind the trigger key to the action] [[[[[Bstring "\x00"]. This special 'command' takes no "energy" and won't generate an error message. It truly does "nothing". This will work for both macros and keymaps. If possible you should use a keymap instead of a macro to disable the key. A keymap will catch occurrences of the key both in macros and by typing, and will still allow you to use the key when it isn't being interpreted as a command. If you use the "Query a macro/keymap" on a trigger key bound to this action, it will report having found it, but no action string will be printed. Another technique is to use the action "\e\e\e". This is used in some of the standard pref files. [[[[[BIf you need to use the built-in command again you can use the '\' key] [[[[[Bat any prompt to bypass its macro/keymap.] #####G---------------------------------------------------------------------- #####G4.20 "Naming" an item (patch) #####G---------------------------------------------------------------------- #####B= 'Fake artifact' name = # "Name" an item This isn't an actual command in the interface, but a flag character that alters the way an item description is generated. This isn't part of standard Angband. It's added by Tom Morton's 'fake artifact' patch. Example: inscription {#Thumper} will cause a Club (+8,+8) to display as Club 'Thumper' (+8,+8) in your inventory and messages. ~~~~~34 #####R====================================================================== #####R5. Common Questions #####R====================================================================== #####G---------------------------------------------------------------------- #####G5.1 Why can't I add a keymap for a function key? #####G---------------------------------------------------------------------- Because keymaps can only be created for keys with system-independent representations. This leaves out function keys, and several other special keys. The "Create a keymap" command will continue waiting for a keypress until you press a valid keymap trigger. You can, however, create a macro for a function key. #####G---------------------------------------------------------------------- #####G5.2 How can I automatically inscribe items when I pick them up? #####G---------------------------------------------------------------------- You need to turn on the "Merge inscriptions when stacking" option. If you are already carrying the same item with an inscription, a new one will be added to the stack. Note that this WON'T merge discounts. Although discounts display like inscriptions, they are different. 1) = Options 2) 1 User interface options 3) "Merge inscriptions when stacking" (stack_force_notes) move down to this line and change to "yes". #####G---------------------------------------------------------------------- #####G5.3 Can I use macros inside other macros? #####G---------------------------------------------------------------------- No. Macros don't expand macro triggers they contain in their actions, in order to avoid recursion and other problems. However, keymap substitution is done, so you can use keymaps to alter the behavior of macros. This keymap expansion can be bypassed by preceding a trigger with "\\" in the action. Keymaps don't expand macro or keymap triggers in their actions. Also see section *****macrofaq.txt*9["Can I create an infinite loop using a macro?"]. #####G---------------------------------------------------------------------- #####G5.4 How do I find out what the standard commands are? #####G---------------------------------------------------------------------- 1) ? Angband help 2) 6 *****command.txt*0[Command Descriptions (command.txt)] Space - moves you down by a page Minus - moves up by a page 2 - moves down by a line 8 - moves you up by a line Note that the original and roguelike command sets differ, and both are different from the "underlying" command set. #####G---------------------------------------------------------------------- #####G5.5 How can I tell if a key has a keymap/macro? #####G---------------------------------------------------------------------- #####B= Query Macro/Keymap = In ToME this is easy: 1) @ Interact with macros 2) 3 Query a macro OR 7 Query a keymap 3) (Press the trigger key to test) 4) Esc (Exit macro editor when done) It will report "Found no macro" or "Found a macro" at the top of the screen. The action it is bound to will be displayed at the bottom of the screen, under the "Current action..." line. You must test for both macros and keymaps, and keymaps will only show for the current "mode", i.e. original/roguelike. #####B= Notes = Note: on some machines, there are duplicate keys such as left and right Shift keys. These will generally produce different key codes and can have different macros and keymaps. Note: just because a key doesn't have a macro doesn't mean there isn't a command that uses that key. #####G---------------------------------------------------------------------- #####G5.6 How can I tell if a key has a built-in command bound to it? #####G---------------------------------------------------------------------- Er ... try pressing the key. If there is a command bound to that key it should usually generate a message of some kind. If there isn't one, it may respond: "Type '?' for help.". Some keys may not generate any message at all. Function keys are a good example. In ToME, the game will also generate "silly" error messages which may not look like error messages at first. After a few repeated key presses it uses the standard "Type '?' for help." message. Failing that, look in *****command.txt*0["command.txt"], which lists all commands, and is up-to-date. There is no specific method for checking if a key has a command bound to it from within the game. #####G---------------------------------------------------------------------- #####G5.7 Can I inscribe multiple items with the same number? #####G---------------------------------------------------------------------- You can, but it can cause problems if you aren't careful. Use the command letter in the inscriptions to minimise problems. For example, it is safe to inscribe both rods with {@z1} and a spell book with {@m1} because the command letter allows distinguishing the two. When the game looks for an item to use with a command, it tries the first one it finds that matches. If the command fails on that item, it doesn't continue looking. The search for a matching item also doesn't know how to only check the right kind of item, so if you have a Spellbook inscribed {@1} and scrolls inscribed {@1} or {@r1}, when you read a scroll it will find the spellbook first, even though it doesn't make sense to read it, and the command will fail. #####G---------------------------------------------------------------------- #####G5.8 How do I convert a macro to a keymap? #####G---------------------------------------------------------------------- You can simply remove it and re-add it "by hand", but for more complex actions there are faster, safer ways. #####B= Directly modifying the pref file = A macro with the following form in the pref file: A: P:\r Should be converted to the keymap form: A: C:0: The "\r" needs to be removed, and the 0 (zero) means standard keyset. Use 1 for roguelike keyset. To make a keymap for both keysets: A: C:0: C:1: #####G= Using the "Interact with Macros" editor = 1) @ Interact with Macros 2) 3 Query a macro The trigger key for the macro (its action string will now become the current action) 3) 5 Remove a macro The trigger key for the macro 4) 8 Create a keymap The trigger key for the keymap 5) (Hit Enter to accept the current action) (Hit Esc to clear the message "Added a keymap") This technique can also be used to move or copy actions between macros or keymaps of the same kind. [[[[[BAnd old macro MUST be removed from a key] [[[[[Bbefore it can be used as the trigger key for a keymap], otherwise the macro action will expand when you press the trigger key in the editor. Converting a keymap to a macro doesn't require removing the keymap first. Note that not all macros can be converted to keymaps. Keymaps don't do macro or keymap expansion on their action strings, so macros that rely on this will no longer work. Also, keymaps can only be bound to a trigger key with a printable internal representation. For example, a function key can't be a trigger for a keymap. ~~~~~9 #####G---------------------------------------------------------------------- #####G5.9 Can I create an infinite loop using a macro? #####G---------------------------------------------------------------------- No. Well, okay, you can, but only if you work *really* hard at it and abuse bugs in the macro handling code. This isn't something that will happen by accident just by using the trigger key inside its action. You also can't create recursion. So don't worry about this. See the section *****macrofaq.txt*10["Macros can contain their own trigger key"] for more info. ~~~~~4 #####G---------------------------------------------------------------------- #####G5.10 What just killed me? #####G---------------------------------------------------------------------- When you are using lots of escapes and spaces in your macros to skip over messages, you can miss important things happening. One of these is dying. Usually when something goes wrong, you can just use the (^P) Previous Messages command to see what happened. But if you died the escapes can take you past the tombstone screen, your last chance to examine the previous messages list. This also happens without macros. To examine your recall, load the savefile and start a new character. You will then be able to use the message recall command to see the last messages of that character's previous incarnation. ~~~~~35 #####R====================================================================== #####R6. Common Problems #####R====================================================================== #####G---------------------------------------------------------------------- #####G6.1 My macro works all the time when I press its key! #####G---------------------------------------------------------------------- Macros *do* work all the time. Every time you press a key, macro expansion is done on it, and then keymap expansion. So if you use 'y' as a trigger key for a macro, and then you try and answer a yes/no prompt with 'y', instead you will get the macro's action string. The answer to this is to change your macro to a keymap. These can be bound to keys which have a system-independent representation in the game, which includes all keys that you would use when interacting with the game interface. If you don't want to change it to a keymap, try changing the trigger key to a "special" key, such as a function key. ~~~~~6 #####G---------------------------------------------------------------------- #####G6.2 My auto-firing macro shoots the wrong target! #####G---------------------------------------------------------------------- Your macro is probably firing at the previous target. This will happen if the option (*****option.txt*4[use_old_target]) is set. Then a macro will like "f1*t" or "m1a*t" will execute as: f Fire 1 Ammo inscribed 1 (it will now fire at the last [wrong] target) * Choose a [new] target t Accept first target If there are no valid targets, the (t) targeting command will centre on your position. If you move, the target will still be your old square. The first time you use the "f1*t" macro it will fire at that square, even if there is now a valid target (monster) nearby. One fix is to turn off the (use_old_taret) option, since the action doesn't require it. This is done with the (=) Set Options command. Another is to change the action to choose the target before it fires. Example: "*tf1". [[[[[BNote:] just because you can "see" a monster doesn't mean you can target it. The code used for vision (line of sight) and firing (projection) is slightly different. So when shooting near corners or pillars it may happen that you can "see" a monster but not target it. If your action kills messages at the end, you could keep hitting your auto-fire macro and the only thing happening would be a large pile of missiles quietly accumulating underneath you. #####G---------------------------------------------------------------------- #####G6.3 I used to have items inscribed, and now they aren't! #####G---------------------------------------------------------------------- The game only knows about inscriptions that you are carrying. There is no way to "store" them independently of a character's save file. So if you lose all of an item that was inscribed, picking up another of that kind won't automatically inscribe it. Normal inscriptions aren't affected by your player's "memory". Note that some items, when fully identified, could have their descriptions grow so long that no inscription will show. In that case you can use the (I) Identify command. It will display the full description, even if nothing special is known about that item. #####G---------------------------------------------------------------------- #####G6.4 I changed some macros in a pref file and nothing happened! #####G---------------------------------------------------------------------- Settings loaded in later pref files will overwrite earlier ones. So if you add macros for the same trigger key to files "<$CLASS>.prf" and "<$PLAYER>.prf", the second one will get used because its file loads later. This affects macros, keymaps, actions, attrs/colors, and other info. See section *****macrofaq.txt*11["Pref lines summary"] for all the types of settings that can be loaded. Also see section *****macrofaq.txt*7["Pref file loading order"]. #####G---------------------------------------------------------------------- #####G6.5 I can't even FIND the macro editing commands! #####G---------------------------------------------------------------------- Angband can be compiled without the ALLOW_MACROS symbol. This is done on some systems to reduce executable size. Macros and keymaps are still used by the game and loaded from files, but they can't be edited or saved from within the game. The "Interact with macros" screen only has the single option "Load a user pref file" in this case. #####G---------------------------------------------------------------------- #####G6.6 It moves me when I try to use my bow/rod/wand! #####G---------------------------------------------------------------------- Example: you type "f1" and it moves you in direction 1 (South West). What is happening is that the 'f' key isn't being handled correctly. It may be remapped to a bogus command, or one which doesn't take an argument. So the 'f' command is skipped/dealt with, and the '1' key is then treated as a direction. You can examine what is going on with the 'f' key using the (@) Interact with macros screen to check for any macros or keymaps bound to that key. Use the appropriate "Remove ..." command to restore the built-in Angband command. ~~~~~3 #####G---------------------------------------------------------------------- #####G6.7 My macro drops/takes off my main weapon! #####G---------------------------------------------------------------------- This is probably caused by an auto-fire macro like "*tm1a" for magic missile. If you hold down the trigger key to repeatedly use it, and some game event (possibly caused by the macro) creates a message, then the action will be interpreted as: * (cancel message) t Take off item m (ignored as invalid) 1 (ignored as invalid) a Item a (main weapon) If there is room in your inventory, it will be put there. If not, your inventory will overflow and it will be dropped on the ground. If this happens during combat this is a very good way to die. This is just another good reason to have {!d!k!v} on your main weapon. See the section *****macrofaq.txt*12["Prevent unwanted use of an item"]. This can be fixed by using the escape sequence "\e\e\e" before and after the action string to cancel any pending messages or commands. See the section *****macrofaq.txt*13["Clearing the command buffer"]. ~~~~~2 #####G---------------------------------------------------------------------- #####G6.8 My macro outputs "e - Floating Eye" on the message line! #####G---------------------------------------------------------------------- It is wise to add an escape sequence "\e\e\e" to the beginning and end of all macros for which this doesn't destroy useful information. See section *****macrofaq.txt*13["Clearing the command buffer"] for more information on this. But many players play on flavors of unix, which uses '/' as the path separator for files, and automatically type a forward slash when they mean to type a backslash. So many actions in macros/keymaps in usenet posts have the wrong type of slash. Angband "gurus" are perhaps more vulnerable to this than novices. The game sees this as: / Identify a character e Character to be identified And outputs "e - Floating Eye" on the message line. If this sequence gets expanded when you are trying to select an item, it will lead to different behaviors. Example: / Switch between inventory and equipment e Select item e. Or: / Switch between inventory and equipment e (ignored because invalid) Select item e. / Switch between inventory and equipment e Select item e. ~~~~~36 #####R====================================================================== #####R7. Inscriptions added by the game #####R====================================================================== Some inscriptions are added by the game itself. These can overwrite your inscriptions. There are also "fake" and "special" inscriptions, which "look" like real inscriptions to the player. #####G---------------------------------------------------------------------- #####G7.1 Fake inscriptions #####G---------------------------------------------------------------------- These "fake" inscriptions are "covered up" by real inscriptions, but will reappear if the real inscription is removed. "fake" inscriptions are unaffected by the uninscribe command (}). {cursed} - cursed item {empty} - item out of charges {tried} - a "flavored" item which the character has used, but whose effects are unknown. {N% off} - item bought on sale {quest} - this item is a quest item. It may need to be taken to someone. #####G---------------------------------------------------------------------- #####G7.2 Auto-inscriptions #####G---------------------------------------------------------------------- These added when your character gets a "feeling" about an item. In ToME these are "special" inscriptions, like "fake" inscriptions above, which don't overwrite user inscriptions. They just hide user inscriptions, which are still there. {terrible} - cursed or broken artifact {broken} - broken item {cursed} - cursed item {uncursed} - previously cursed item {average} {good} - good (magical) item {excellent} - ego item {special} - unique item {on sale} - displayed only in the store ~~~~~37 #####R====================================================================== #####R8. Keys and commands #####R====================================================================== This section gives short descriptions of keys and commands used in actions and trigger key representations. They are only listed in this section if they aren't fully described elsewhere in this FAQ. Not all of these keys are actually for "commands". See the normal Angband help for a fuller description of these commands. The commands and keysets are documented in *****command.txt*0["command.txt"]. #####G---------------------------------------------------------------------- #####G8.1 Keysets #####G---------------------------------------------------------------------- ToME supports two "keysets", which are fully customisable sets of keymaps. The "original" command set is close to the built-in commands, with some additions for ease of use such as number keys moving you in that direction. The "roguelike" command set allows easy movement on a keyboard without a numeric keypad. As a consequence its letter keys are almost completely "full". These used to be hard-coded by the game, but are now fully customisable. The default keymaps are in "pref.prf". #####G---------------------------------------------------------------------- #####G8.2 Item selection #####G---------------------------------------------------------------------- (*) - gives list of choices (-) - selects item on the floor (/) - toggles between the inventory and equipment lists. (space) - shows list of choices. Pressing (space) again hides the list. (lower) - selects the inventory item with that letter. (upper) - selects the inventory item with that letter, and requires confirmation. (digit) - selects first item inscribed with "@#" or "@x#" where 'x' is the command, and '#' is the digit. Only legal items are allowed. #####G---------------------------------------------------------------------- #####G8.3 Directions and Movement #####G---------------------------------------------------------------------- Original keyset directions 7 8 9 4 5 6 1 2 3 Roguelike keyset directions y k u h 5 l b j n #####B= Underlying command keys = ; - walk (with pickup) + - alter . - run Digits AREN'T built-in movement commands in ToME. They are actually keymaps found in the standard pref file "pref.prf". The digits are direction arguments to the (;) Walk command. #####G---------------------------------------------------------------------- #####G8.4 Escape sequences #####G---------------------------------------------------------------------- Many [non-printable] characters have a standard printable encoding which uses an "escape" character to change the meaning of the following character. The backslash character is used as in the C language for many keys. The caret '^' is used for control keys. #####B= Escape sequences = \b backspace \e escape \n newline \r return \s space \t tab \xNN hex ASCII char \\ (literal) backslash \^ (literal) caret #####B= Backslash = In a macro, "\\" followed by a character uses the "underlying" command for that character without translation. This is useful in macros to avoid keymaps changing the behavior of the macro. In particular this can be used to make macros which work for both original and roguelike keysets. Keymaps don't have this problem. #####B= Newline and Return = These two characters can be used interchangeably. #####B= ASCII chars = Any ASCII character can be encoded in this way. So many keys will have more than one representation. For example, [Enter] can be "\r", "^M", and "\x09". The backslash representations are case sensitive, so "\t" is [Tab], but "\T" will just be interpreted as "T". The hexadecimal number must be exactly 2 digits. #####B= Escape and Space = See section *****macrofaq.txt*13["Clearing the command buffer"] for their main uses. #####G---------------------------------------------------------------------- #####G8.5 Repeats and Counts #####G---------------------------------------------------------------------- #####B= Auto repeat = Some commands will automatically repeat. These are: (T) Tunnel (B) Bash (D) Disarm (o) Open (c) Close (+) Alter #####B= Number keys = 0 - starts a repeat count. Some commands take a repeat count argument. They can be entered as "0". If the command is movement, it can (must) be preceded by space(s) to separate the direction (command) number from the count number. ~~~~~1 #####G---------------------------------------------------------------------- #####G8.6 Messages and Questions #####G---------------------------------------------------------------------- #####B= Yes/No queries = Yes/No questions can be answered with 'y', 'n', or Esc. These are not case sensitive. Only 'y' or 'Y' will respond Yes. 'n', 'N', and Esc are No. If the option (quick_messages) is on, any other keypress is also No. When the option is off, it will keep waiting for a valid key. #####B= "-more-" message prompts = These may be cleared by Esc(\e), Space(\s), Enter(\r), or Newline(\n). If the (quick_messages) option is on, they can be cleared by any key. #####G---------------------------------------------------------------------- #####G8.7 Special keys #####G---------------------------------------------------------------------- #####B= Function keys = Function keys are free for reassignment, but only as macros. [[[[[BFunction] [[[[[Bkeys can be modified by Alt, Ctrl, Shift like other keys.] #####B= Alt keys = Alt-modified keys are generally free for reassignment as either macros or keymaps. #####B= Control keys = Control keys can be entered in as "^x" where 'x' is the key. Note that the case of 'x' is unimportant. This also allows typing control keys which would be intercepted by the operating system, such as ^C. You must type the caret '^' and the following key separately. Note that some have special meanings, such as ^M for Return, and ^H for backspace. Some also have special Operating System meanings, such as "^Z" in un*x, and "^C" in DOS. Control keys can be trigger keys for both macros and keymaps. #####B= Interrupting the game = (^C) This will kill your character and quit the game, after verifying. #####G---------------------------------------------------------------------- #####G8.8 Keys used in inscriptions #####G---------------------------------------------------------------------- #####B= Confirm command = ^ Confirm the following command. This isn't an actual command, but a character with a special meaning inside command strings. {^*} will confirm all actions for the item. ~~~~~38 #####R====================================================================== #####R9. Pref files #####R====================================================================== All pref files are loaded from and saved to folder "\lib\user". The folder "\lib\pref" is unused at this time! The location and name of this folder can be configured. Warning: the directory "\lib\pref" is unused by the game. Pref files moved there will never get used (unless the user has redirected the folder locations). Integers can be in hex "0x10", decimal "16", or octal "020" formats. These are converted using the C library fn strtol(), and are case insensitive. Decimal numbers start with '1'-'9'. Octal numbers must start with '0' (zero). Hex numbers start with '0x' or '0X'. #####G---------------------------------------------------------------------- #####G9.1 Standard Pref files #####G---------------------------------------------------------------------- Below "***" stands for the 3-letter system abbreviations, such as "acn", "mac", "win", "x11", ... "font.prf" Includes "font-***.prf" files. This file defines special attr/char mappings for "text" mode. "graf.prf" Includes "graf-***.prf" files. This file defines special attr/char mappings for "graphics" mode. "pref.prf" Includes "pref-***.prf" files. This file defines "default" actions of various kinds. This includes mapping the original and roguelike keysets to the underlying keyset. "user.prf" Includes "user-***.prf" files. This file defines "override" actions of various kinds. It includes the pref files based on system, race, and class. "xtra-***.prf" This file defines special attr/char mappings for "graphics" mode. Currently this just maps the player icon based on race and class. "new" refers to Adam Bolt's tiles. [[[[[vWarning:] you shouldn't edit the base pref files without a good reason, and understanding what you are doing. Breaking these files can make your game unusable. They are, however, the place to make changes that should affect all users. ~~~~~7 #####G---------------------------------------------------------------------- #####G9.2 Pref file loading order #####G---------------------------------------------------------------------- This loading order follows from the order of includes in "pref.prf". Files which are "hard-coded" in the source are preceded with an index. The rest are included by the other files. Files which come later will overwrite settings from earlier files. (1) "pref.prf" "message.prf" "pref-***.prf" (2) "graf.prf" "font-xxx.prf" "graf-***.prf" (3) "font.prf" "font-xxx.prf" "font-***.prf" (4) "user.prf" "user-***.prf" "<$RACE>.prf" "<$CLASS>.prf" (5) "<$PLAYER>.prf" (6) ".angband.prf" = $RACE = Can be one of any of the races in ToME. = $CLASS = Can be one of any of the classes in ToME. = $PLAYER = The name of the current player being loaded or born. See section *****macrofaq.txt*15["Automatically loading pref files"] for more information. #####B= Specific pref files = #####B----------------------------------- "user-mac.prf" This is the only user pref file with example macros that ships with ToME. A good set of examples. "pref-win.prf" This is the same as (missing) "pref-dos.prf" and "pref-ibm.prf". "colours.prf" Amiga only. Contains Amiga palette. ".angband.prf" Only on multi-user systems. This doesn't ship with the source. This file must be located in the directory contained in environ variable "HOME". ~~~~~11 #####G---------------------------------------------------------------------- #####G9.3 Pref lines summary #####G---------------------------------------------------------------------- Comment lines start with a '#' and extend to end of line. Note: integer values can be specified as decimal, as hexadecimal by preceding with an "x", or as octal by using a leading "0" (zero). E:: - attr/char values for inventory objects by index F::: - attr/char values for features by index K::: - attr/char values for objects by index R::: - attr/char values for monsters by index S::: - attr/char values for special things by index A: - action line An action line should be followed by a keymap trigger "C:" line or a macro trigger "P:" line. There can be intervening comments and lines. The same action will be [re]used by all keymap and command lines which follow it until there is another action line. P: - macro line a macro encoding of a keypress. (system dependent) C:: - keymap line 0 = "original, 1 = "roguelike". logical keypress, including backslash codes such as "\e" and control codes such as "^K". (system independent) Note that there are 2 independent sets of keymaps now. Changing a keymap in one doesn't affect the other. V::::: - specify visual information is the color index (0-255, only 0-15 used) black (?) value -- unused red value (0-255) green value (0-255) blue value (0-255) W::: - turn a window flag on/off. window number (1-7) (0-31) 0 = off, 1 = on X: - turn option off Y: - turn option on the name of an option in option_text[]. These are the names displayed in the options screen (=). ?: - conditional expression %: - include another pref file #####G---------------------------------------------------------------------- #####G9.4 Option lines "X:" and "Y:" #####G---------------------------------------------------------------------- Options and their descriptions are listed in help file *****option.txt*0["option.txt"]. These options are set within the game using the (=) Options command, and the option names are the ones displayed within parentheses in the options screen. #####B= Common options = rogue_like_commands use_old_target always_pickup depth_in_feet alert_hitpoint auto_haggle auto_scum #####G---------------------------------------------------------------------- #####G9.5 Conditional expression lines "?:" #####G---------------------------------------------------------------------- expressions are lisp-like prefix notation. names (class, race, ...) aren't placed in quotes. AND - logical AND IOR - inclusive OR EQU - (string) equals NOT - logical negation LEQ - (string) less than or equal to GEQ - (string) greater than or equal to [,] - group expressions $CLASS - current class $GRAF - 3-letter graphics abbr in "graf-***.prf" (old, new) $PLAYER - current player name $RACE - current race $SYS - 3-letter system abbr in "pref-***.prf" (ami, mac, win,...) 0 - false 1 - true (can't just be non-zero) If the conditional expression is false all pref file commands encountered until the next conditional pref line are skipped. This isn't an actual command. It only works in pref files. The variables $CLASS, $GRAF, $PLAYER, $RACE, $PLAYER, $SYS and the string values they take on are case sensitive. The values also can't contain spaces. These constraints on the values hold when they are used in a pref file, but might not when used as pref filenames. This can be "turned back on" using the pref line "?:1", which is generally the last line in a file which contains conditional macros, to make sure that any files loaded after it don't get ignored as well. #####G---------------------------------------------------------------------- #####G9.6 Macro trigger lines "P:" #####G---------------------------------------------------------------------- All "special" keys are translated by "main-***.c" into encoded "macro triggers". These macro triggers have the encoded form "^_MMMxSS\r", where the "modifier" flags are stored in "MMM", and the two digit hexadecimal scan code of the keypress is stored in "SS". See source file "main-ibm.c" and others for more info. Note that because these scan codes are system-dependent, macro trigger encodings are as well. Keymaps are used for system independent mapping of triggers to actions. #####BModifier flags A - Alt C - Control S - Shift O - Option key (Mac) #####BIBM Scan codes x47 - keypad 7 x48 - keypad 8 x49 - keypad 9 x4A - keypad - x4B - keypad 4 x4C - keypad 5 x4D - keypad 6 x4E - keypad + x4F - keypad 1 x50 - keypad 2 x51 - keypad 3 x52 - keypad Ins / . x53 - keypad Del / Enter x45 - Pause Others can be found using the "Query a macro" feature. Note that scan codes can't be assumed to be "in order", even for keys like function keys which "logically" should be! Note that you can't always just add a modifier to a known scan code because that combination might not be recognised by the hardware or the translation code in "main-***.c". Example: a Windows system will recognise function key F1, Shift-F1, and Ctrl-F1, but not Ctrl-Shift-F1. Similarly Pause and Alt-Pause are recognised, but not Ctrl-Pause, and Shift-Pause gives the same encoding as Pause alone. #####G---------------------------------------------------------------------- #####G9.7 Saving to a pref file #####G---------------------------------------------------------------------- Commands "Append macros to file" and "Append keymaps to file" don't erase the previous macros or keymaps. Instead they are appended. Note that this can produce *large* files after a while. Newer versions append to "<$PLAYER>.prf" by default, whereas older versions appended to "user.prf". The appended sections are preceded by headers of the form "Automatic macro/keymap dump". Using a distinctive comment line such as ###... after your entries can make editing the appended ones easier. [[[[[BNote: macros and keymaps aren't saved in the character file, so they] [[[[[Bmust be saved separately. All macros and keymaps entered by the user] [[[[[Bare lost when Angband terminates.] Note: keeping macros in the <$PLAYER>.prf files allows several users to share the same installation without interfering with each other. You can easily reuse or share preferences by moving them into a pref file ".prf" and using the pref line "%:.prf" to include them in "user.prf" for single user installations, or <$PLAYER>.prf for multi-user installations. #####G---------------------------------------------------------------------- #####G9.8 Editing pref files #####G---------------------------------------------------------------------- This is still most easily done in a text editor. ~~~~~39 #####R====================================================================== #####R10. Macro editing commands #####R====================================================================== #####G---------------------------------------------------------------------- #####G10.1 (") Enter a User Pref Command #####G---------------------------------------------------------------------- This allows entering a single pref line. Example: "X:auto_scum" turns auto-scum off. Example "A:" sets the current action string. If you open the "Interact with macros" screen this action will be the default used. Then using the (") command again with "P:" will create a macro for the action previously entered. Not all pref commands can be used here, or are meaningful. The "pseudo" pref commands (?), (%) cannot be used here. See section *****macrofaq.txt*20["Advanced macro techniques"] for ways to [ab]use this. #####G---------------------------------------------------------------------- #####G10.2 (@) Interact with macros #####G---------------------------------------------------------------------- #####B= Vanilla command set = (2.8.3 - 2.9.1) #####B----------------------------------- Load a user pref file Append macros to a file Query a macro action Create a macro Remove a macro Append keymaps to a file Query a keymap Create a keymap Remove a keymap Enter a new action #####B= Load a user pref file = #####B----------------------------------- Loads a user pref file from "lib\user". Defaults to the name of the current character. Macros/keymaps loaded will replace existing ones. #####B= Append macros to a file = #####B----------------------------------- Macros are dumped in macro list order. Newer ones are at the end. Macros are *appended* to the file. The old one isn't overwritten. This prevents you from accidentally wiping out your old pref file. However, the file can grow very long without your noticing it. Placing a line of ###'s at the end of your macros can help sort out what is what. Macros are labeled with comment "# Macro 'NNN' ". These numbers are the internal macro list numbers, and have no relation to key scan codes. The filename must end in ".prf". It will save correctly without this extension, or with a different one, but if you save as "<$NAME>" instead of "<$NAME>.prf", it won't be automatically loaded when you load the character with that name. #####B= Query a macro = #####B----------------------------------- Press the trigger key to test at the prompt. This will show "Found a macro" on the message line if it found one, and the line "Trigger: ". This will show "Found no macro" on the message line if it didn't find a macro. Some keys such as function keys won't be recognised by the prompt. It will wait until you hit a key it recognises. This command doesn't alter any settings. It will return to the main menu after you hit any key it recognises. #####B= Create a macro = #####B----------------------------------- After choosing this command, press the trigger key for the macro. The internal form will be shown after the "Trigger: " prompt. Note that some keys may not be recognised for remapping, such as the new Windows keys, as well as modifier keys such as Alt, Control, Shift pressed by themselves. In this case it will continue to wait for a valid trigger key. The current action (if any) will be shown *below* the "Trigger: " prompt line. On the prompt line ("Action: ") will be shown the last macro sequence entered. This is the action in the "action buffer". This isn't necessarily the macro sequence currently bound to this key. This is the action that will be bound to the current trigger key if you hit Enter. You may type in an action string to replace the one after the prompt. Hit Enter when you are finished. For ToME you can quit the command assignment by hitting Esc. The new action entered won't be assigned, and the previous one will remain unaltered. #####B= Remove a macro = #####B----------------------------------- Removes the macro from the trigger key by creating an identity macro on that key for itself. So the macro isn't completely removed, just overwritten. The new identity macro will be saved when the macros are appended to a file. This is different from the "Remove a keymap" command, which completely removes the keymap. #####B---------------------------------------------------------------------- The following "keymap" commands only apply to the current "mode" (original/roguelike). Keymaps for the other mode will be unaffected. Because keymaps can only be bound to trigger keys which have a system independent representation, some key presses won't be recognised by these editing commands. They will instead wait until you press a valid trigger key. #####B---------------------------------------------------------------------- #####B= Append keymaps to a file = #####B----------------------------------- Works just like "Append macros to a file". These are appended after a header comment "# Automatic keymap dump". #####B= Query a keymap = #####B----------------------------------- Works just like "Query a macro". This will show "Found a keymap" on the message line if it found one, and will display "Keypress: ". This will show "Found no keymap" on the message line if it didn't find a keymap. This command doesn't alter any settings. It will return to the main menu after you hit any key it recognises. #####B= Create a keymap = #####B----------------------------------- Works just like the "Create a macro" command. Keymaps can only be assigned to keys which have a system independent representation. Note that creating a keymap will cause the behavior of any macro whose action string contains that key to change. #####B= Remove a keymap = #####B----------------------------------- Removes the keymap completely from the trigger key. If the key had a built-in command it can now be used again. Note that removing a keymap will cause the behavior of any macro whose action string contained that key to change. This behaves differently from the "Remove a macro" command, which creates an identity macro. If the original "command" was itself a keymap, removing a user-entered keymap won't restore it. Example: the key (n) is bound to the built-in command "Repeat last action" in file "pref.prf" via a keymap. If you add a keymap for (n) and then remove it, the "Repeat last command" functionality won't be restored. You will have to add it back by hand, or reload a pref file that contains that stored keymap. [[[[[BIn particular] [[[[[Balmost all roguelike commands are now implemented as keymaps.] #####B= Enter a new action = #####B----------------------------------- Allows entering a new action. Actions are entered into a static buffer which is shared by both macros and keymaps. The action string entered will become the default action for creating a keymap or action, and will only change when a keymap or macro is created with a different action string, or when one is queried. Note that the same action can be bound to multiple trigger keys by hitting Enter when using the commands to create a keymap/macro. ~~~~~20 #####R====================================================================== #####R11. Advanced Macro Techniques #####R====================================================================== This section outlines advanced techniques not really required for game play. But macros become addictive after a while ... Action strings in this section are enclosed in braces {} because many use a double quote (") inside the action string. These are not inscriptions. #####G---------------------------------------------------------------------- #####G11.1 Set current action using (@) command in an action #####G---------------------------------------------------------------------- {"@0\r\e} @ - Interact with macros 0 - Enter a new action - (action string) \r - Enter the action \e - Exit the macro editor This will work when bound to a macro. #####G---------------------------------------------------------------------- #####G11.2 Set current action using (") command in an action #####G---------------------------------------------------------------------- {"A:\r} - sets the current action. " - Enter pref line A: - Action line - (action string) \r - Enter the action This works in either a macro or keymap. #####G---------------------------------------------------------------------- #####G11.3 Create a new keymap using (") command in an action #####G---------------------------------------------------------------------- {"A:\r"C:0:\r} Here can't contain an '\r' or '\e'. Example {"A:z0\r"C:0:J\r} binds action "z0" to (standard) keymap 'J'. #####G---------------------------------------------------------------------- #####G11.4 Create a new macro using (") command in an action #####G---------------------------------------------------------------------- {"A:\r"P:\r} Here can't contain an '\r' or '\e'. Here is a standard key. (not a "special" one like F1, \b, or ^A) Example {"A:\r"P:j\r} binds action to trigger 'j'. {"A:\r"P:j\r} binds action to trigger 'j'. If we bind these 2 macros to different trigger keys, the action that is on key (j) can be swapped back and forth. #####G---------------------------------------------------------------------- #####G11.5 Turning an option on/off in an action #####G---------------------------------------------------------------------- Turn an option on: {"Y:\r} Turn an option of: {"Y:\r} Example: Turn (quick_messages) on, do an action, and turn it back off: {"Y:quick_messages\r"X:quick_messages\r} This will work in either a macro or keymap. is the name of the option as it appears in the option editor accessed through the (=) command. These are also listed in the help file *****option.txt*0["option.txt"]. Note that option names contain underscores instead of spaces. #####G---------------------------------------------------------------------- #####G11.6 Inscribe/Uninscribe an item in an action #####G---------------------------------------------------------------------- (These action strings are enclosed in double quotes) Inscribe an item: "{\s\r" Uninscribe an item: "}\r" must be the inventory letter of the item, possibly preceded by a '/' to switch to the equipment list. You can't use digit labels for items with inscriptions that contain the command triggers '{' or '}', but you can use "@". This will work in either a macro or keymap. ~~~~~41 #####R====================================================================== #####R12. Problems #####R====================================================================== #####G---------------------------------------------------------------------- #####G12.1 Keys to avoid remapping #####G---------------------------------------------------------------------- These don't really *need* to be avoided, but all carry dangers of one kind or another. You should think through potential problems before deciding to use them. You have been warned. #####B= Navigation keys = Enter, Esc, Backspace, ... These aren't a good choice unless you *really* need them. If you do it is far better to use keymaps. If you bind a macro to the Enter key, you will lose the ability to enter line-based commands like Inscribe. #####B= Commands generated internally = (_) Enter store This command is generated internally by the game when the player moves onto the door of a store. In some versions, if this key has a keymap bound to it, that will fire when you try to enter a store. #####B= Keys with important Operating System meanings = ^Z (un*x) Suspends the game and returns to the command shell. This is an operating system command, not an Angband command. Command "fg" returns to Angband. ^\, ^D, ^S These are keys that shouldn't be bound to macros or have their behavior altered. #####B= Keys with dangerous ToME meanings = (Q) Quit (commit suicide), (k) destroy item, (^A) Enter Debug mode... Using these as triggers is dangerous in case, for some reason, you wind up in a situation where the macro hasn't loaded or is disabled. You also don't want to get into a habit of typing these too fast. #####B= Selection keys = (e) Equipment, (i) Inventory, (-) Floor item, (/) Switch inventory lists. You should avoid binding these as macro triggers, to prevent making inventory and choice management next to impossible. But even as keymaps they hold some dangers. Example: you bind keymap on '-' to destroy item on the floor. Now if you try to do an action on a floor item, and it fails (such as using rod to identify), then the '-' can be taken from the input stream and used as a keymap, which would destroy the item you tried to identify. #####B= Response keys = (y) yes, (n) no, (Esc) cancel, (Space) skip message,... Binding macros to these is a [[[[[vVery Bad Idea.] Macro expansion will then be done when you answer a question like "Are you sure you want to quit the game without saving?". The expanded macro action string will be used as the input, and may not lead to the answer you were trying for. Keymaps don't have this problem. As a rule you should never use a macro instead of a keymap unless necessary. #####G---------------------------------------------------------------------- #####G12.2 Num lock #####G---------------------------------------------------------------------- Whether/not NumLock is on can make a difference for some macros. For example, if NumLock is on under X11 the 'X' macro won't work. #####G---------------------------------------------------------------------- #####G12.3 Recovering #####G---------------------------------------------------------------------- Restarting ToME clears all macros entered during the last session. You can use "Load a pref file" in the "Interact with macros" screen to reload a good set of prefs, overwriting bad ones being used. This will not "erase" a macro/keymap which doesn't have a corresponding saved one in the pref file. So if you add a macro/keymap to a trigger key which didn't have anything bound to it, reloading the pref file won't restore the key to its original state. If you still have problems, restore or edit any modified *.prf files that might be loaded. Try saving your macros, and examine them to see what went wrong. [[[[[BYou can use the backspace '\' key at the command prompt to use the] [[[[[Boriginal "underlying" command bound to that key. For example, if you] [[[[[Bbound the key '@' to a macro, you wouldn't be able to enter the macro] [[[[[Beditor to rebind it to itself.] Pressing '\' first, then '@' causes the command handler to use the built-in command, which allows you to enter the command editor. Note: when you use the backspace inside an action string, you have to double it as "\\". Do not use just a single back- slash, or it will be ignored, and possibly alter the meaning of the character that follows it. You can remove a macro/keymap from an essential key (such as the Esc key). Use the (@) "Interact with macros" command to access the remove commands. #####G---------------------------------------------------------------------- #####G12.4 Unrecognised keys #####G---------------------------------------------------------------------- #####B= Un*x = Function keys may not be recognised on some Un*x systems. #####B= PC/Dos/Windows = Doesn't recognise the WINDOWS key (start menu) or the APPLICATION key (context menu). On some systems, doesn't recognise modifier keys (Alt, Ctrl, Shift) on keypad keys when NumLock is on. See special_key_list[] in "main-win.c" for list of "special" keys that are recognised. #####G---------------------------------------------------------------------- #####G12.5 Nonexistent commands #####G---------------------------------------------------------------------- Macros and keymaps can only be bound to keypresses. The game state changing isn't a keypress, so you can't trigger an action when you become hungry, blind, confused, slowed, pseudo-id an item, pick up an item, gain a level, have a rod recharge, or any other event that isn't directly triggered by a keypress. "Attacking" also isn't a command, but you can use commands (+) Alter grid, (;) Walk, and (.) Run. So you don't really _attack_ Morgoth, you just _alter_ him. First he's alive, then he's not. :) #####G---------------------------------------------------------------------- #####G12.6 File permissions #####G---------------------------------------------------------------------- If you lack write permission to the pref file currently loaded by the game, try saving to a file with a new name. The macros can be copied over "by hand" later. ~~~~~42 #####R====================================================================== #####R13. Miscellaneous #####R====================================================================== #####G---------------------------------------------------------------------- #####G13.1 References #####G---------------------------------------------------------------------- *****command.txt*0["COMMAND.TXT"] - lists standard and roguelike keys and commands. full descriptions. - long description of command behavior. - intro to macros and user pref files. *****dungeon.txt*8["DUNGEON.TXT"] - look under "Objects Found in the Dungeon". *****option.txt*0["OPTION.TXT"] - list of options and their descriptions. "INSCRIPTIONS.HTML" - short intro by Julian Lighton. Available from "http://www.fragment.com/~jl8e/angband/inscriptions.html". #####G---------------------------------------------------------------------- #####G13.2 Contributors #####G---------------------------------------------------------------------- This FAQ was largely compiled from newsgroup postings to "r.g.r.a". So thanks to the generous contributors to the newsgroup! Email addresses have been removed to foil spam-bots. Ben Harrison -- maintainer: Angband 2.7.1 - 2.8.5, =Ben= in source. Robert Ruehlman -- maintainer: Angband 2.9.0 - present. DarkGod -- maintainer: PernAngband 2.9.9a - present Scott Bigham, DamonShawX, Jonathan Ellis, George W. Harris, Roger Hoyle, Graham S. Johnson, Chris Kern, Matthias Kurzke, Steve Lamb, Julian Lighton, Art Mruczek, Daniel Nash, Timo Pietilä, Jack Wise, Greg Wooledge, and others. #####G---------------------------------------------------------------------- #####G13.3 Legalese #####G---------------------------------------------------------------------- Copyright 2000 Jim Lyon and others. Redistribution of unaltered copies of this document is permitted without restriction. Distribution of altered copies is permitted without restriction as long as the alteration does not significantly alter the content. (For example, translation and conversion to another format is permitted.) Distribution of all other altered copies is permitted as long as credit for previous authors is maintained, the contact information is replaced with that of the alterer, and redistribution is not further restricted. Edited for PernAngband V5.x.x by Dawnmist with permission from Jim Lyon August 2001. All comments to angband@dawnmist.8m.com tome-235-src/lib/help/lua_spel.txt0000644000076400017500000014763211012107760014743 0ustar dgdg|||||oy #####R /----------------------------------------\ #####R < spell.pkg functions helper file > #####R \----------------------------------------/ ---------------------------------------------------------------------- #####R=== teleport_player_directed === #####GDeclaration extern void teleport_player_directed(int rad, int dir); #####GFile spells1.c #####GComment /* * Teleport player, using a distance and a direction as a rough guide. * * This function is not at all obsessive about correctness. * This function allows teleporting into vaults (!) */ #####GDescription Teleport a player up to "rad" grids away roughly in "dir" direction. #####GParameters > "rad" must not exceed 200. The distance teleported is a minimum of a quarter of "rad". > "dir" must be from 0 to 9. *****fields.txt*0[direction] ---------------------------------------------------------------------- #####R=== teleport_away === #####GDeclaration extern void teleport_away(int m_idx, int dis); #####GFile spells1.c #####GComment /* * Teleport a monster, normally up to "dis" grids away. * * Attempt to move the monster at least "dis/2" grids away. * * But allow variation to prevent infinite loops. */ #####GDescription Teleport monster indicated by "m_idx" up to "dis" grids away. #####GParameters > "m_idx" is the index of the monster in m_list[]. > "dis" must not exceed 200. The distance teleported is a minimum of a quarter of "dis". ---------------------------------------------------------------------- #####R=== teleport_player === #####GDeclaration extern void teleport_player(int dis); #####GFile spells1.c #####GComment /* * Teleport the player to a location up to "dis" grids away. * * If no such spaces are readily available, the distance may increase. * Try very hard to move the player at least a quarter that distance. */ #####GDescription Teleport player up to "dis" grids away. #####GParameters > "dis" must not exceed 200. The distance teleported is a minimum of a quarter of "dis". ---------------------------------------------------------------------- #####R=== teleport_player_to === #####GDeclaration extern void teleport_player_to(int ny, int nx); #####GFile spells1.c #####GComment /* * Teleport player to a grid near the given location * * This function is slightly obsessive about correctness. * This function allows teleporting into vaults (!) */ #####GDescription Teleport player to a grid near the given location ("ny", "nx"). If the location is empty, the player goes there, otherwise they go to a grid as close as possible to the location. #####GParameters > "ny" is the y co-ordinate of the location. > "nx" is the x co-ordinate of the location. ---------------------------------------------------------------------- #####R=== teleport_monster_to === #####GDeclaration extern void teleport_monster_to(int m_idx, int ny, int nx); #####GFile spells1.c #####GComment /* * Teleport a monster to a grid near the given location * * This function is slightly obsessive about correctness. */ #####GDescription Teleport monster indicated by "m_idx" to a grid near the given location ("ny", "nx"). If the location is empty, the monster goes there, otherwise they go to a grid as close as possible to the location. #####GParameters > "m_idx" is the index of the monster in m_list[]. > "ny" is the y co-ordinate of the location. > "nx" is the x co-ordinate of the location. ---------------------------------------------------------------------- #####R=== teleport_player_level === #####GDeclaration extern void teleport_player_level(void); #####GFile spells1.c #####GComment /* * Teleport the player one level up or down (random when legal) */ #####GDescription Teleport the player one level up or down at random. ---------------------------------------------------------------------- #####R=== recall_player === #####GDeclaration extern void recall_player(void); #####GFile spells1.c #####GComment /* * Recall the player to town or dungeon */ #####GDescription Recall the player to town (if in dungeon) or dungeon (if in town). ---------------------------------------------------------------------- #####R=== take_hit === #####GDeclaration extern void take_hit(int damage, cptr kb_str); #####GFile spells1.c #####GComment /* * Decreases players hit points and sets death flag if necessary * * XXX XXX XXX Invulnerability needs to be changed into a "shield" * * XXX XXX XXX Hack -- this function allows the user to save (or quit) * the game when he dies, since the "You die." message is shown before * setting the player to "dead". */ #####GDescription Reduce the player's current hit points by "damage" points. If the player dies, "kb_str" is used to record what the player was killed by (see high-score table). #####GParameters > "damage" is the amount of damage. > "kb_str" is a string describing what killed the player. ---------------------------------------------------------------------- #####R=== take_sanity_hit === #####GDeclaration extern void take_sanity_hit(int damage, cptr hit_from); #####GFile spells1.c #####GComment /* Decrease player's sanity. This is a copy of the function above. */ #####GDescription Reduce the player's current sanity points by "damage" points. If the player dies, "hit_from" is used to record what the player was killed by (see high-score table). #####GParameters > "damage" is the amount of damage. > "hit_from" is a string describing what killed the player. ---------------------------------------------------------------------- #####R=== project === #####GDeclaration extern bool project(int who, int rad, int y, int x, int dam, int typ, int flg); #####GFile spells1.c #####GComment /* * Generic "beam"/"bolt"/"ball" projection routine. * * Input: * who: Index of "source" monster (negative for "player") * jk -- -2 for traps, only used with project_jump * rad: Radius of explosion (0 = beam/bolt, 1 to 9 = ball) * y,x: Target location (or location to travel "towards") * dam: Base damage roll to apply to affected monsters (or player) * typ: Type of damage to apply to monsters (and objects) * flg: Extra bit flags (see PROJECT_xxxx in "defines.h") * * Return: * TRUE if any "effects" of the projection were observed, else FALSE * * Allows a monster (or player) to project a beam/bolt/ball of a given kind * towards a given location (optionally passing over the heads of interposing * monsters), and have it do a given amount of damage to the monsters (and * optionally objects) within the given radius of the final location. * * A "bolt" travels from source to target and affects only the target grid. * A "beam" travels from source to target, affecting all grids passed through. * A "ball" travels from source to the target, exploding at the target, and * affecting everything within the given radius of the target location. * * Traditionally, a "bolt" does not affect anything on the ground, and does * not pass over the heads of interposing monsters, much like a traditional * missile, and will "stop" abruptly at the "target" even if no monster is * positioned there, while a "ball", on the other hand, passes over the heads * of monsters between the source and target, and affects everything except * the source monster which lies within the final radius, while a "beam" * affects every monster between the source and target, except for the casting * monster (or player), and rarely affects things on the ground. * * Two special flags allow us to use this function in special ways, the * "PROJECT_HIDE" flag allows us to perform "invisible" projections, while * the "PROJECT_JUMP" flag allows us to affect a specific grid, without * actually projecting from the source monster (or player). * * The player will only get "experience" for monsters killed by himself * Unique monsters can only be destroyed by attacks from the player * * Only 256 grids can be affected per projection, limiting the effective * "radius" of standard ball attacks to nine units (diameter nineteen). * * One can project in a given "direction" by combining PROJECT_THRU with small * offsets to the initial location (see "line_spell()"), or by calculating * "virtual targets" far away from the player. * * One can also use PROJECT_THRU to send a beam/bolt along an angled path, * continuing until it actually hits something (useful for "stone to mud"). * * Bolts and Beams explode INSIDE walls, so that they can destroy doors. * * Balls must explode BEFORE hitting walls, or they would affect monsters * on both sides of a wall. Some bug reports indicate that this is still * happening in 2.7.8 for Windows, though it appears to be impossible. * * We "pre-calculate" the blast area only in part for efficiency. * More importantly, this lets us do "explosions" from the "inside" out. * This results in a more logical distribution of "blast" treasure. * It also produces a better (in my opinion) animation of the explosion. * It could be (but is not) used to have the treasure dropped by monsters * in the middle of the explosion fall "outwards", and then be damaged by * the blast as it spreads outwards towards the treasure drop location. * * Walls and doors are included in the blast area, so that they can be * "burned" or "melted" in later versions. * * This algorithm is intended to maximise simplicity, not necessarily * efficiency, since this function is not a bottleneck in the code. * * We apply the blast effect from ground zero outwards, in several passes, * first affecting features, then objects, then monsters, then the player. * This allows walls to be removed before checking the object or monster * in the wall, and protects objects which are dropped by monsters killed * in the blast, and allows the player to see all affects before he is * killed or teleported away. The semantics of this method are open to * various interpretations, but they seem to work well in practice. * * We process the blast area from ground-zero outwards to allow for better * distribution of treasure dropped by monsters, and because it provides a * pleasing visual effect at low cost. * * Note that the damage done by "ball" explosions decreases with distance. * This decrease is rapid, grids at radius "dist" take "1/dist" damage. * * Notice the "napalm" effect of "beam" weapons. First they "project" to * the target, and then the damage "flows" along this beam of destruction. * The damage at every grid is the same as at the "centre" of a "ball" * explosion, since the "beam" grids are treated as if they ARE at the * centre of a "ball" explosion. * * Currently, specifying "beam" plus "ball" means that locations which are * covered by the initial "beam", and also covered by the final "ball", except * for the final grid (the epicentre of the ball), will be "hit twice", once * by the initial beam, and once by the exploding ball. For the grid right * next to the epicentre, this results in 150% damage being done. The centre * does not have this problem, for the same reason the final grid in a "beam" * plus "bolt" does not -- it is explicitly removed. Simply removing "beam" * grids which are covered by the "ball" will NOT work, as then they will * receive LESS damage than they should. Do not combine "beam" with "ball". * * The array "gy[],gx[]" with current size "grids" is used to hold the * collected locations of all grids in the "blast area" plus "beam path". * * Note the rather complex usage of the "gm[]" array. First, gm[0] is always * zero. Second, for N>1, gm[N] is always the index (in gy[],gx[]) of the * first blast grid (see above) with radius "N" from the blast centre. Note * that only the first gm[1] grids in the blast area thus take full damage. * Also, note that gm[rad+1] is always equal to "grids", which is the total * number of blast grids. * * Note that once the projection is complete, (y2,x2) holds the final location * of bolts/beams, and the "epicentre" of balls. * * Note also that "rad" specifies the "inclusive" radius of projection blast, * so that a "rad" of "one" actually covers 5 or 9 grids, depending on the * implementation of the "distance" function. Also, a bolt can be properly * viewed as a "ball" with a "rad" of "zero". * * Note that if no "target" is reached before the beam/bolt/ball travels the * maximum distance allowed (MAX_RANGE), no "blast" will be induced. This * may be relevant even for bolts, since they have a "1x1" mini-blast. * * Note that for consistency, we "pretend" that the bolt actually takes "time" * to move from point A to point B, even if the player cannot see part of the * projection path. Note that in general, the player will *always* see part * of the path, since it either starts at the player or ends on the player. * * Hack -- we assume that every "projection" is "self-illuminating". * * Hack -- when only a single monster is affected, we automatically track * (and recall) that monster, unless "PROJECT_JUMP" is used. * * Note that all projections now "explode" at their final destination, even * if they were being projected at a more distant destination. This means * that "ball" spells will *always* explode. * * Note that we must call "handle_stuff()" after affecting terrain features * in the blast radius, in case the "illumination" of the grid was changed, * and "update_view()" and "update_monsters()" need to be called. */ #####GDescription Generate a beam/bolt/ball starting from "who" with a radius of "rad" at target grid "y,x" for "damage" points of "typ" damage. The beam/ bolt/ball can have various properties as denoted by "flg". #####GParameters > "who" is > 0 (index of monster in m_list[]), < 0 and not -100 or -101 (player), -100 or -101 (trap). > "rad" is 0 for a beam/bolt and 1-9 for a ball. > "y" is the y co-ordinate of the target grid. > "x" is the x co-ordinate of the target grid. > "dam" is the number of points of damage. > "typ" is the type of damage *****fields.txt*0[GF_fields] > "flg" is the projection effect *****fields.txt*0[PROJECT_fields] ---------------------------------------------------------------------- #####R=== corrupt_player === #####GDeclaration extern void corrupt_player(void); #####GFile spells1.c #####GComment (none) #####GDescription Swap two of the players stats at random. ---------------------------------------------------------------------- #####R=== grow_trees === #####GDeclaration extern void grow_trees(int rad); #####GFile spells2.c #####GComment /* * Grow trees */ #####GDescription Grow up to (("rad" x "rad") + 11) trees around the player. #####GParameters > "rad" is the radius of the area where trees may grow. ---------------------------------------------------------------------- #####R=== hp_player === #####GDeclaration extern bool hp_player(int num); #####GFile spells2.c #####GComment /* * Increase players hit points, notice effects */ #####GDescription Add "num" points to the player's current hit points. The total can not exceed the maximum. #####GParameters > "num" is the number of points to add. ---------------------------------------------------------------------- #####R=== heal_insanity === #####GDeclaration extern bool heal_insanity(int val); #####GFile spells2.c #####GComment /* Heal insanity. */ #####GDescription Add "val" points to the player's current sanity points. The total can not exceed the maximum. #####GParameters > "val" is the number of points to add. ---------------------------------------------------------------------- #####R=== warding_glyph === #####GDeclaration extern void warding_glyph(void); #####GFile spells2.c #####GComment /* * Leave a "glyph of warding" which prevents monster movement */ #####GDescription Place a glyph at the player's location. The location must be bare. ---------------------------------------------------------------------- #####R=== explosive_rune === #####GDeclaration extern void explosive_rune(void); #####GFile spells2.c #####GComment (none) #####GDescription Place a minor glyph (explosive rune) at the player's location. The location must be bare. ---------------------------------------------------------------------- #####R=== do_dec_stat === #####GDeclaration extern bool do_dec_stat(int stat, int mode); #####GFile spells2.c #####GComment /* * Lose a "point" */ #####GDescription Attempt to reduce the player's "stat" statistic by a point. #####GParameters > "stat" is the statistic *****fields.txt*0[A_fields] > "mode" is the type of decrease: temporary, normal, or permanent *****fields.txt*0[STAT_DEC_fields] ---------------------------------------------------------------------- #####R=== do_res_stat === #####GDeclaration extern bool do_res_stat(int stat); #####GFile spells2.c #####GComment /* * Restore lost "points" in a stat */ #####GDescription Restore the player's "stat" statistic. #####GParameters > "stat" is the statistic *****fields.txt*0[A_fields] ---------------------------------------------------------------------- #####R=== do_inc_stat === #####GDeclaration extern bool do_inc_stat(int stat); #####GFile spells2.c #####GComment /* * Gain a "point" in a stat */ #####GDescription Increase the player's "stat" statistic by a point. #####GParameters > "stat" is the statistic *****fields.txt*0[A_fields] ---------------------------------------------------------------------- #####R=== identify_pack === #####GDeclaration extern void identify_pack(void); #####GFile spells2.c #####GComment /* * Identify everything being carried. * Done by a potion of "self knowledge". */ #####GDescription Identify all items in the inventory. ---------------------------------------------------------------------- #####R=== remove_curse === #####GDeclaration extern bool remove_curse(void); #####GFile spells2.c #####GComment /* * Remove most curses */ #####GDescription Remove all curses except for heavy curses. ---------------------------------------------------------------------- #####R=== remove_all_curse === #####GDeclaration extern bool remove_all_curse(void); #####GFile spells2.c #####GComment /* * Remove all curses */ #####GDescription Remove all curses including heavy curses. ---------------------------------------------------------------------- #####R=== restore_level === #####GDeclaration extern bool restore_level(void); #####GFile spells2.c #####GComment /* * Restores any drained experience */ #####GDescription Restore all drained experience points (if any). ---------------------------------------------------------------------- #####R=== self_knowledge === #####GDeclaration extern void self_knowledge(FILE *fff); #####GFile spells2.c #####GComment /* * self-knowledge... idea from nethack. Useful for determining powers and * resistances of items. It saves the screen, clears it, then starts listing * attributes, a screenful at a time. (There are a LOT of attributes to * list. It will probably take 2 or 3 screens for a powerful character whose * using several artifacts...) -CFT * * It is now a lot more efficient. -BEN- * * See also "identify_fully()". * * XXX XXX XXX Use the "show_file()" method, perhaps. */ #####GDescription Show all attributes including racial powers, mutations, and equipment effects. #####GParameters > "*ffff" points to a file (write info to file) or is NULL (write info to screen). ---------------------------------------------------------------------- #####R=== lose_all_info === #####GDeclaration extern bool lose_all_info(void); #####GFile spells2.c #####GComment /* * Forget everything */ #####GDescription Forget about objects and the map. ---------------------------------------------------------------------- #####R=== detect_traps === #####GDeclaration extern bool detect_traps(void); #####GFile spells2.c #####GComment /* * Detect all traps on current panel */ #####GDescription Detect all traps on current panel. ---------------------------------------------------------------------- #####R=== detect_doors === #####GDeclaration extern bool detect_doors(void); #####GFile spells2.c #####GComment /* * Detect all doors on current panel */ #####GDescription Detect all doors on current panel. ---------------------------------------------------------------------- #####R=== detect_stairs === #####GDeclaration extern bool detect_stairs(void); #####GFile spells2.c #####GComment /* * Detect all stairs on current panel */ #####GDescription Detect all stairs on current panel. ---------------------------------------------------------------------- #####R=== detect_treasure === #####GDeclaration extern bool detect_treasure(void); #####GFile spells2.c #####GComment /* * Detect any treasure on the current panel */ #####GDescription Detect any treasure on the current panel. ---------------------------------------------------------------------- Field: hack_no_detect_message Value: FALSE ---------------------------------------------------------------------- #####R=== detect_objects_gold === #####GDeclaration extern bool detect_objects_gold(void); #####GFile spells2.c #####GComment /* * Detect all "gold" objects on the current panel */ #####GDescription Detect all objects with the TV_GOLD flag. ---------------------------------------------------------------------- #####R=== detect_objects_normal === #####GDeclaration extern bool detect_objects_normal(void); #####GFile spells2.c #####GComment /* * Detect all "normal" objects on the current panel */ #####GDescription Detect all objects without the TV_GOLD flag. ---------------------------------------------------------------------- #####R=== detect_objects_magic === #####GDeclaration extern bool detect_objects_magic(void); #####GFile spells2.c #####GComment /* * Detect all "magic" objects on the current panel. * * This will light up all spaces with "magic" items, including artifacts, * ego-items, potions, scrolls, books, rods, wands, staves, amulets, rings, * and "enchanted" items of the "good" variety. * * It can probably be argued that this function is now too powerful. */ #####GDescription Detect all "magic" objects which are artefacts, ego items, or have one of the following flags - TV_AMULET, TV_RING, TV_BATERIE, TV_STAFF, TV_WAND, TV_ROD, TV_ROD_MAIN, TV_SCROLL, TV_POTION, TV_POTION2, TV_VALARIN_BOOK, TV_MAGERY_BOOK, TV_SHADOW_BOOK, TV_CHAOS_BOOK, TV_SPIRIT_BOOK, TV_NETHER_BOOK, TV_DAEMON_BOOK, TV_CRUSADE_BOOK, TV_SIGALDRY_BOOK, TV_SYMBIOTIC_BOOK, TV_MUSIC_BOOK. ---------------------------------------------------------------------- #####R=== detect_monsters_normal === #####GDeclaration extern bool detect_monsters_normal(void); #####GFile spells2.c #####GComment /* * Detect all "normal" monsters on the current panel */ #####GDescription Detect all non-invisible monsters (without RF2_INVISIBLE). ---------------------------------------------------------------------- #####R=== detect_monsters_invis === #####GDeclaration extern bool detect_monsters_invis(void); #####GFile spells2.c #####GComment /* * Detect all "invisible" monsters on current panel */ #####GDescription Detect all invisible monsters (with RF2_INVISIBLE). ---------------------------------------------------------------------- #####R=== detect_monsters_evil === #####GDeclaration extern bool detect_monsters_evil(void); #####GFile spells2.c #####GComment /* * Detect all "evil" monsters on current panel */ #####GDescription Detect all evil monsters (with RF3_EVIL). ---------------------------------------------------------------------- #####R=== detect_monsters_good === #####GDeclaration extern bool detect_monsters_good(void); #####GFile spells2.c #####GComment /* Detect good monsters */ #####GDescription Detect all good monsters (with RF3_GOOD). ---------------------------------------------------------------------- #####R=== detect_monsters_xxx === #####GDeclaration extern bool detect_monsters_xxx(u32b match_flag); #####GFile spells2.c #####GComment /* * A "generic" detect monsters routine, tagged to flags3 */ #####GDescription Detect all monsters with "match_flag" flag. #####GParameters > "match_flag" can be any RF3_ flag (see defines.h) but only RF3_DEMON, RF3_UNDEAD, RF3_GOOD work. ---------------------------------------------------------------------- #####R=== detect_monsters_string === #####GDeclaration extern bool detect_monsters_string(cptr); #####GFile spells2.c #####GComment /* * Detect all (string) monsters on current panel */ #####GDescription Detect all monsters whose default monster character matches a character pointed to by "cptr". #####GParameters > "cptr" is a pointer to a single character, eg 'Z' for hounds. For available characters, see the "symbol" field of the graphics (G) line of r_info.txt. ---------------------------------------------------------------------- #####R=== detect_monsters_nonliving === #####GDeclaration extern bool detect_monsters_nonliving(void); #####GFile spells2.c #####GComment /* * Detect all "nonliving", "undead" or "demonic" monsters on current panel */ #####GDescription Detect all non-living monsters (with RF3_NONLIVING, RF3_UNDEAD, or RF3_DEMON). ---------------------------------------------------------------------- #####R=== detect_all === #####GDeclaration extern bool detect_all(void); #####GFile spells2.c #####GComment /* * Detect everything */ #####GDescription Detects traps, doors, stairs, treasure, gold objects, normal objects, invisible monsters, normal (visible) monsters. ---------------------------------------------------------------------- #####R=== stair_creation === #####GDeclaration extern void stair_creation(void); #####GFile spells2.c #####GComment /* * Create stairs at the player location */ #####GDescription Create stairs at the player location. This is not allowed if the grid is not empty, the player is not in a dungeon, the player is on a special level, the player is in an arena or quest. If the player is in the town or wilderness the stairs will go down. If the player is on a quest level or at the bottom of a dungeon, the stairs will go up. Otherwise there is an even chance the stairs will go up or down. ---------------------------------------------------------------------- #####R=== wall_stone === #####GDeclaration extern bool wall_stone(void); #####GFile spells2.c #####GComment (none) #####GDescription Create a stone wall on the player's grid. This function uses the project() function to create the stone wall. Apparently zero can be used as the "who" parameter for the player. See details for the project() function elsewhere in this document. ---------------------------------------------------------------------- #####R=== create_artifact === #####GDeclaration extern bool create_artifact(object_type *o_ptr, bool a_scroll, bool get_name); #####GFile randart.c #####GComment (none) #####GDescription Create an artifact from object "*optr". #####GParameters > "*optr* is a pointer to an object > "a_scroll" is true if the artifact is created by reading a scroll > "get_name" is true if the artifact is to be named by the player (if a_scroll is true) or created randomly (a_scroll is false), or false if an inscription is used. ---------------------------------------------------------------------- #####R=== ident_spell === #####GDeclaration extern bool ident_spell(void); #####GFile spells2.c #####GComment /* * Identify an object in the inventory (or on the floor) * This routine does *not* automatically combine objects. * Returns TRUE if something was identified, else FALSE. */ #####GDescription Identify an object in the inventory (or on the floor). ---------------------------------------------------------------------- #####R=== identify_fully === #####GDeclaration extern bool identify_fully(void); #####GFile spells2.c #####GComment /* * Fully "identify" an object in the inventory -BEN- * This routine returns TRUE if an item was identified. */ #####GDescription Fully "identify" an object in the inventory (or on the floor). ---------------------------------------------------------------------- #####R=== recharge === #####GDeclaration extern bool recharge(int num); #####GFile spells2.c #####GComment /* * Recharge a wand/staff/rod from the pack or on the floor. * This function has been rewritten in Oangband. -LM- * * Mage -- Recharge I --> recharge(90) * Mage -- Recharge II --> recharge(150) * Mage -- Recharge III --> recharge(220) * * Priest or Necromancer -- Recharge --> recharge(140) * * Scroll of recharging --> recharge(130) * Scroll of *recharging* --> recharge(200) * * It is harder to recharge high level, and highly charged wands, * staffs, and rods. The more wands in a stack, the more easily and * strongly they recharge. Staffs, however, each get fewer charges if * stacked. * * XXX XXX XXX Beware of "sliding index errors". */ #####GDescription Recharge an object in the inventory (or on the floor) with "num" power. #####GParameters > "num" is the power used in recharging. It is compared to the object's level to determine whether the item is recharged successfully or destroyed. If it is recharged, it also determines how many charges are added, or how much recharge time is reduced. ---------------------------------------------------------------------- #####R=== aggravate_monsters === #####GDeclaration extern void aggravate_monsters(int who); #####GFile spells2.c #####GComment /* * Wake up all monsters, and speed up "los" monsters. */ #####GDescription Aggravate monsters, originating from "who". #####GParameters > "who" is the index of monster in m_list[] (1 if it is the player) which triggers the aggravation; ---------------------------------------------------------------------- #####R=== genocide === #####GDeclaration extern bool genocide(bool player_cast); #####GFile spells2.c #####GComment (none) #####GDescription Genocide a monster race. #####GParameters > "player_cast" is true if the player cast the spell so the player can take damage. ---------------------------------------------------------------------- #####R=== mass_genocide === #####GDeclaration extern bool mass_genocide(bool player_cast); #####GFile spells2.c #####GComment /* * Delete all nearby (non-unique) monsters */ #####GDescription Delete all nearby (non-unique) monsters. #####GParameters > "player_cast" is true if the player cast the spell so the player can take damage. ---------------------------------------------------------------------- #####R=== probing === #####GDeclaration extern bool probing(void); #####GFile spells2.c #####GComment /* * Probe nearby monsters */ #####GDescription Probe all nearby monsters. ---------------------------------------------------------------------- #####R=== banish_evil === #####GDeclaration extern bool banish_evil(int dist); #####GFile spells2.c #####GComment /* * Banish evil monsters */ #####GDescription Banish nearby evil monsters doing "dist" points of GF_AWAY_EVIL damage. #####GParameters > "dist" is the amount of damage done to each monster. ---------------------------------------------------------------------- #####R=== dispel_evil === #####GDeclaration extern bool dispel_evil(int dam); #####GFile spells2.c #####GComment /* * Dispel evil monsters */ #####GDescription Dispel nearby evil monsters doing "dam" points of GF_DISP_EVIL damage. #####GParameters > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== dispel_good === #####GDeclaration extern bool dispel_good(int dam); #####GFile spells2.c #####GComment /* * Dispel good monsters */ #####GDescription Dispel nearby good monsters doing "dam" points of GF_DISP_GOOD damage. #####GParameters > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== dispel_undead === #####GDeclaration extern bool dispel_undead(int dam); #####GFile spells2.c #####GComment /* * Dispel undead monsters */ #####GDescription Dispel nearby undead monsters doing "dam" points of GF_DISP_UNDEAD damage. #####GParameters > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== dispel_monsters === #####GDeclaration extern bool dispel_monsters(int dam); #####GFile spells2.c #####GComment /* * Dispel all monsters */ #####GDescription Dispel all nearby monsters doing "dam" points of GF_DISP_ALL damage. #####GParameters > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== dispel_living === #####GDeclaration extern bool dispel_living(int dam); #####GFile spells2.c #####GComment /* * Dispel 'living' monsters */ #####GDescription Dispel nearby living monsters doing "dam" points of GF_DISP_LIVING damage. #####GParameters > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== dispel_demons === #####GDeclaration extern bool dispel_demons(int dam); #####GFile spells2.c #####GComment /* * Dispel demons */ #####GDescription Dispel nearby demon monsters doing "dam" points of GF_DISP_DEMON damage. #####GParameters > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== turn_undead === #####GDeclaration extern bool turn_undead(void); #####GFile spells2.c #####GComment /* * Turn undead */ #####GDescription Turn nearby undead monsters doing a point of GF_TURN_UNDEAD damage for each player level. ---------------------------------------------------------------------- #####R=== wipe === #####GDeclaration extern void wipe(int y1, int x1, int r); #####GFile spells2.c #####GComment /* * Wipe -- Empties a part of the dungeon */ #####GDescription Delete monsters and objects from an area of the dungeon centred at grid "y1,x1" for a radius "r". This does not work on special levels or quests. The player may be blinded. The player forgets the affected area and it becomes dark. All grids become floor. #####GParameters > "y1" is the y-coordinate of the wipe's origin. > "x1" is the x-coordinate of the wipe's origin. > "r" is the radius of the wipe. ---------------------------------------------------------------------- #####R=== destroy_area === #####GDeclaration extern void destroy_area(int y1, int x1, int r, bool full); #####GFile spells2.c #####GComment /* * The spell of destruction * * This spell "deletes" monsters (instead of "killing" them). * * Later we may use one function for both "destruction" and * "earthquake" by using the "full" to select "destruction". */ #####GDescription Delete monsters and objects from an area of the dungeon centred at grid "y1,x1" for a radius "r". This does not work on special levels or quests. The epicentre is NOT affected. The player may be blinded. The player forgets the affected area and it becomes dark. The grids can become granite, quartz, magma, or floor. #####GParameters > "y1" is the y-coordinate of the destruction's origin. > "x1" is the x-coordinate of the destruction's origin. > "r" is the radius of the destruction. > "full" is currently unused. ---------------------------------------------------------------------- #####R=== earthquake === #####GDeclaration extern void earthquake(int cy, int cx, int r); #####GFile spells2.c #####GComment /* * Induce an "earthquake" of the given radius at the given location. * * This will turn some walls into floors and some floors into walls. * * The player will take damage and "jump" into a safe grid if possible, * otherwise, he will "tunnel" through the rubble instantaneously. * * Monsters will take damage, and "jump" into a safe grid if possible, * otherwise they will be "buried" in the rubble, disappearing from * the level in the same way that they do when genocided. * * Note that thus the player and monsters (except eaters of walls and * passers through walls) will never occupy the same grid as a wall. * Note that as of now (2.7.8) no monster may occupy a "wall" grid, even * for a single turn, unless that monster can pass_walls or kill_walls. * This has allowed massive simplification of the "monster" code. */ #####GDescription Create an earthquake centred on grid "cy,cx" with a radius of "r". This does not work on quest levels. The epicentre is NOT affected. Only about 15% of the grids are affected. The player takes 300 points of damage if they can't be moved to a safe grid, otherwise damage is from 10 to 40 points. The player forgets the affected area and it becomes dark. The grids can become granite, quartz, magma, or floor. #####GParameters Parameters: > "cy" is the y-coordinate of the earthquake origin. > "cx" is the x-coordinate of the earthquake origin. > "r" is the radius of the earthquake. ---------------------------------------------------------------------- #####R=== map_area === #####GDeclaration extern void map_area(void); #####GFile cave.c #####GComment /* * Hack -- map the current panel (plus some) ala "magic mapping" */ #####GDescription Map the current panel plus up to 10 grids up and down, and up to 20 grids left and right. ---------------------------------------------------------------------- #####R=== wiz_lite === #####GDeclaration extern void wiz_lite(void); #####GFile cave.c #####GComment /* * Light up the dungeon using "clairvoyance" * * This function "illuminates" every grid in the dungeon, memorises all * "objects", memorises all grids as with magic mapping, and, under the * standard option settings (view_perma_grids but not view_torch_grids) * memorises all floor grids too. * * Note that if "view_perma_grids" is not set, we do not memorise floor * grids, since this would defeat the purpose of "view_perma_grids", not * that anyone seems to play without this option. * * Note that if "view_torch_grids" is set, we do not memorise floor grids, * since this would prevent the use of "view_torch_grids" as a method to * keep track of what grids have been observed directly. */ #####GDescription Light up the entire dungeon and show all monsters and objects. ---------------------------------------------------------------------- #####R=== wiz_lite_extra === #####GDeclaration extern void wiz_lite_extra(void); #####GFile cave.c #####GComment (none) #####GDescription Light up the entire dungeon and show all monsters and objects. All squares are lit and remembered. ---------------------------------------------------------------------- #####R=== wiz_dark === #####GDeclaration extern void wiz_dark(void); #####GFile cave.c #####GComment /* * Forget the dungeon map (ala "Thinking of Maud..."). */ #####GDescription Forget all grids and objects. All grids become dark. ---------------------------------------------------------------------- #####R=== lite_room === #####GDeclaration extern void lite_room(int y1, int x1); #####GFile spells2.c #####GComment /* * Illuminate any room containing the given location. */ #####GDescription Light up the room (if any) of grid "y1,x1". #####GParameters > "y1" is the y-coordinate of the grid. > "x1" is the x-coordinate of the grid. ---------------------------------------------------------------------- #####R=== unlite_room === #####GDeclaration extern void unlite_room(int y1, int x1); #####GFile spells2.c #####GComment /* * Darken all rooms containing the given location */ #####GDescription Darken all rooms (if any) of grid "y1,x1". #####GParameters > "y1" is the y-coordinate of the grid. > "x1" is the x-coordinate of the grid. ---------------------------------------------------------------------- #####R=== lite_area === #####GDeclaration extern bool lite_area(int dam, int rad); #####GFile spells2.c #####GComment /* * Hack -- call light around the player * Affect all monsters in the projection radius */ #####GDescription Light up the room (if any) of the player's grid. Monsters take "dam" points of GF_LITE_WEAK damage if they are within "r" grids of the player. #####GParameters > "dam" is the number of points of damage. > "rad" is the radius of the effect of the damage. ---------------------------------------------------------------------- #####R=== unlite_area === #####GDeclaration extern bool unlite_area(int dam, int rad); #####GFile spells2.c #####GComment /* * Hack -- call darkness around the player * Affect all monsters in the projection radius */ #####GDescription Darken the room (if any) of the player's grid. Monsters take "dam" points of GF_DARK_WEAK damage if they are within "r" grids of the player. #####GParameters > "dam" is the number of points of damage. > "rad" is the radius of the effect of the damage. ---------------------------------------------------------------------- #####R=== fire_ball_beam === #####GDeclaration extern bool fire_ball_beam(int typ, int dir, int dam, int rad); #####GFile spells2.c #####GComment /* * Cast a ball-beamed spell * Stop if we hit a monster, act as a "ball" * Allow "target" mode to pass over monsters * Affect grids, objects, and monsters */ #####GDescription Cast a ball-beamed spell of type "typ" in direction "dir" for damage "dam" points with a radius of "rad" grids. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. *****fields.txt*0[direction] > "dam" is the number of points of damage. > "rad" is the radius of the effect of the damage (must be <= 16). ---------------------------------------------------------------------- #####R=== fire_ball === #####GDeclaration extern bool fire_ball(int typ, int dir, int dam, int rad); #####GFile spells2.c #####GComment /* * Cast a ball spell * Stop if we hit a monster, act as a "ball" * Allow "target" mode to pass over monsters * Affect grids, objects, and monsters */ #####GDescription Cast a ball spell of type "typ" in direction "dir" for "dam" points of damage. The ball has a radius of "rad" grids. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. *****fields.txt*0[direction] > "dam" is the number of points of damage. > "rad" is the radius of the effect of the damage (must be <= 16). ---------------------------------------------------------------------- #####R=== fire_bolt === #####GDeclaration extern bool fire_bolt(int typ, int dir, int dam); #####GFile spells2.c #####GComment /* * Cast a bolt spell * Stop if we hit a monster, as a "bolt" * Affect monsters (not grids or objects) */ #####GDescription Cast a bolt spell of type "typ" in direction "dir" for "dam" points of damage. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9 *****fields.txt*0[direction] > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== fire_beam === #####GDeclaration extern bool fire_beam(int typ, int dir, int dam); #####GFile spells2.c #####GComment /* * Cast a beam spell * Pass through monsters, as a "beam" * Affect monsters (not grids or objects) */ #####GDescription Cast a beam spell of type "typ" in direction "dir" for "dam" points of damage. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. *****fields.txt*0[direction] > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== fire_druid_ball === #####GDeclaration extern bool fire_druid_ball(int typ, int dir, int dam, int rad); #####GFile spells2.c #####GComment /* * Cast a druidic ball spell * Stop if we hit a monster, act as a "ball" * Allow "target" mode to pass over monsters * Affect grids, objects, and monsters */ #####GDescription Cast a ball spell of type "typ" in direction "dir" for "dam" points of damage. The ball has a radius of "rad" grids. The spell follows a mana path. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. *****fields.txt*0[direction] > "dam" is the number of points of damage. > "rad" is the radius of the effect of the damage (must be <= 16). ---------------------------------------------------------------------- #####R=== fire_druid_bolt === #####GDeclaration extern bool fire_druid_bolt(int typ, int dir, int dam); #####GFile spells2.c #####GComment /* * Cast a druidic bolt spell * Stop if we hit a monster, as a "bolt" * Affect monsters (not grids or objects) */ #####GDescription Cast a bolt spell of type "typ" in direction "dir" for "dam" points of damage. The spell follows a mana path. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. *****fields.txt*0[direction] > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== fire_druid_beam === #####GDeclaration extern bool fire_druid_beam(int typ, int dir, int dam); #####GFile spells2.c #####GComment /* * Cast a druidistic beam spell * Pass through monsters, as a "beam" * Affect monsters (not grids or objects) */ #####GDescription Cast a beam spell of type "typ" in direction "dir" for "dam" points of damage. The spell follows a mana path. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. *****fields.txt*0[direction] > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== fire_bolt_or_beam === #####GDeclaration extern bool fire_bolt_or_beam(int prob, int typ, int dir, int dam); #####GFile spells2.c #####GComment /* * Cast a bolt spell, or rarely, a beam spell */ #####GDescription Cast a beam (chance of "prob" in 100) or bolt spell of type "typ" in direction "dir" for "dam" points of damage. #####GParameters > "prob" is the number of times out of 100 that the bolt will actually be a beam. Obviously this value should range from 1 to 99 (0 will always give a beam, 100 or higher will always give a beam. There are separate functions for these cases). > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. *****fields.txt*0[direction] > "dam" is the number of points of damage. ---------------------------------------------------------------------- #####R=== alchemy === #####GDeclaration extern bool alchemy(void); #####GFile spells2.c #####GComment /* Turns an object into gold, gain some of its value in a shop */ #####GDescription The player selects an object (and quantity if it applies) from the inventory or the floor and attempts to turn it into gold. If the price of the item is < 0 then the player gains nothing (fool's gold), otherwise the player gets a third of the price in gold. Artifacts are not affected. ---------------------------------------------------------------------- #####R=== alter_reality === #####GDeclaration extern void alter_reality(void); #####GFile spells2.c #####GComment (none) #####GDescription The player leaves the level immediately. ---------------------------------------------------------------------- #####R=== teleport_swap === #####GDeclaration extern void teleport_swap(int dir); #####GFile spells2.c #####GComment (none) #####GDescription Player swaps places with target in direction "dir". The target must be a monster. It will not work if the space-time continuum can not be disrupted or if the monster resists teleportation. ---------------------------------------------------------------------- #####R=== project_meteor === #####GDeclaration extern void project_meteor(int radius, int typ, int dam, u32b flg); #####GFile spells2.c #####GComment /* * Apply a "project()" a la meteor shower */ #####GDescription Generate between "rad" and "rad" x 2 ball spells of type "typ" for "dam" points of damage. The ball can have various properties as denoted by "flg". #####GParameters > "rad" is the minimum number of balls created. "rad" + randint("rad") balls are created. Each ball has a radius of 2 grids. Each target grid is within 5 grids of the player. > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dam" is the number of points of damage. > "flg" is the projection effect *****fields.txt*0[PROJECT_fields] ---------------------------------------------------------------------- #####R=== passwall === #####GDeclaration extern bool passwall(int dir, bool safe); #####GFile spells2.c #####GComment /* * Send the player shooting through walls in the given direction until * they reach a non-wall space, or a monster, or a permanent wall. */ #####GDescription Move the player through walls in direction "dir". if "safe" then the player can not end up in a wall - if they do, the wall is replaced by a floor. This does not work in the wilderness, on quest levels, or if teleport is not allowed. Stopping on monsters or inside vaults is not allowed. #####GParameters > "dir" must be from 0 to 9. It can not be 5. *****fields.txt*0[direction] > "safe" must be true if the player is not to be trapped in a wall when the movement is finished. ---------------------------------------------------------------------- #####R=== project_hook === #####GDeclaration extern bool project_hook(int typ, int dir, int dam, int flg); #####GFile spells2.c #####GComment /* * Hack -- apply a "projection()" in a direction (or at the target) */ #####GDescription Generate a beam/bolt of type "typ" in direction "dir" (or at a target) for "dam" points of damage. The beam/bolt can have various properties as denoted by "flg". #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dir" must be from 0 to 9. 5 means use the current target. *****fields.txt*0[direction] > "dam" is the number of points of damage. > "flg" is the projection effect *****fields.txt*0[PROJECT_fields] ---------------------------------------------------------------------- #####R=== reset_recall === #####GDeclaration extern bool reset_recall(void); #####GFile spells2.c #####GComment (none) #####GDescription Ask the player for a dungeon and appropriate level within the dungeon. The player can not specify a dungeon they have not gone to yet. If the player chooses levels 99 or 100, the level is set to 98. ---------------------------------------------------------------------- #####R=== get_aim_dir === #####GDeclaration extern bool get_aim_dir(int *dp = 0); #####GFile xtra2.c #####GComment /* * Get an "aiming direction" from the user. * * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and * "0" for "current target", and "-1" for "entry aborted". * * Note that "Force Target", if set, will pre-empt user interaction, * if there is a usable target already set. * * Note that confusion over-rides any (explicit?) user choice. */ #####GDescription Get an aiming direction from the user and store it in "dp". A target can be selected. If the player is confused, the direction will be random. #####GParameters > "dp" = player direction. ---------------------------------------------------------------------- #####R=== project_hack === #####GDeclaration extern bool project_hack(int typ, int dam); #####GFile spells2.c #####GComment /* * Apply a "project()" directly to all viewable monsters * * Note that affected monsters are NOT auto-tracked by this usage. */ #####GDescription Generate beam/bolt spells of type "typ" for "dam" points of damage to all viewable monsters in line of site. #####GParameters > "typ" is the type of damage *****fields.txt*0[GF_fields] > "dam" is the number of points of damage. ---------------------------------------------------------------------- Back to the *****lua.hlp*0[lua help index] . [[[[[gThis file by Chris Hadgis] tome-235-src/lib/help/r_orc.txt0000644000076400017500000000240611012107760014230 0ustar dgdg~~~~~01|Orc ~~~~~02|Races|Orc #####R=== Orcs === #####GDescription Orcs make excellent warriors and decent priests, but are terrible at magic. They are as bad as dwarves at stealth, and horrible at searching, disarming, and perception. Orcs are quite ugly, and tend to pay more for goods in town. Orcs do make good warriors and rogues, for the simple reason that Orcs tend to have great constitutions and lots of hit points. Because of their preference for living underground rather than on the surface, orcs resist darkness attacks. Upon reaching experience level 3, an orc learns to dispel any fear that may be upon him. #####GStat Modifiers Strength +2 Intelligence -1 Wisdom 0 Dexterity +1 Constitution +1 Charisma -4 Hit Dice Sides 10 Exp Penalty +10% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 1.200 [0.000] Archery -0.500 [0.000] Sneakiness Stealth -1.000 [0.000] Disarming -0.300 [0.000] Magic Magic-Device -0.300 [0.000] Spirituality -1.000 [0.000] tome-235-src/lib/help/m_fire.txt0000644000076400017500000000413011012107760014361 0ustar dgdg|||||oy ~~~~~01|Magic|Fire School ~~~~~02|Fire Magic ~~~~~03|Skills|Fire - Spell Info #####R === ToME Magic - Fire School === The fire school of magic contains spells where the element of fire is used to create the final spell effect. There are rumours of a "Tome of the Eternal Flame" which contains all the fire school spells within its bindings. #####RFire Spells There are five spells available for the fire school. These spells are: 1. [[[[[RGlobe of Light] (school level 1) Creates a globe of pure light. At spell level 3 it starts damaging monsters. At spell level 15 it starts creating a more powerful kind of light. 2. [[[[[RFire Golem] (dual school level 7) Creates a fiery golem and controls it. During the control the available keylist is: Movement keys: move the golem (depending on its speed it can move more than one square). , : pickup all items on the floor d : drop all carried items i : list all carried items m : end the possession/use golem powers Most of the other keys are disabled; you cannot interact with your real body while controlling the golem. But to cast the spell you will need a lantern or a wooden torch to create the golem. #####v Your Fire and Mind skills must have reached a combined average level #####v of 7 in order to cast this spell. 3. [[[[[RFireflash] (school level 10) Conjures a ball of fire to burn your foes to ashes. At spell level 20 it turns into a ball of holy fire. 4. [[[[[RFirewall] (school level 15) Creates a fiery wall to incinerate monsters stupid enough to attack you. At spell level 6 it turns into a wall of hell fire. 5. [[[[[RFiery Shield] (school level 20) Creates a shield of fierce flames around you. At spell level 8 it turns into a greater kind of flame that cannot be resisted by your foes. #####GUdun spells that can be cast with Fire skill 1. [[[[[DFlame of Udun] (dual school level 35) Turns you temporarily into a powerful Balrog. #####v Your Fire and Udun skills must have reached a combined average level #####v of 35 in order to cast this spell. tome-235-src/lib/help/m_symbio.txt0000644000076400017500000000464711012107760014753 0ustar dgdg|||||oy ~~~~~01|Magic|Symbiosis ~~~~~02|Symbiosis Magic ~~~~~03|Skills|Symbiosis - Symbiotic Powers #####R === ToME Magic - Symbiosis === Symbiosis is the art of joining body, fate and sometimes even mind with creatures not capable of moving on their own. While a humble student of the Craft of Slime (as it's sometimes called) has very few options apart from asking the symbiote to help him in combat, master practitioners have access to an incredible array of tricks. Once hypnotised, the monster is placed onto the body, or "worn", in order to initiate the symbiotic relationship. #####uSymbiotic Powers There are nine powers a symbiant can develop. They are: 1. [[[[[uHypnotize] (level 1) Cost:1 The very basis of symbiosis itself, this asks a monster to lower its natural defences so that it can be safely "worn". 2. [[[[[uRelease] (level 1) Cost:1 Sometimes even life-long friends part. This power allows you to revert a monster on the floor to its primal state, even though the shock of waking up will lower it to 0 HP. 3. [[[[[uCharm never-moving] (level 3) Cost:2 A symbiant soon learns to communicate with molds and slimes. This power allows him to gain the "friendship" of such a creature. 4. [[[[[uLife share] (level 5) Cost:5 The cells of the symbiant and the symbiote intermingle, spreading damage evenly among the two organisms. 5. [[[[[uUse minor powers] (level 10) Cost:10 Allows you to tap into minor magic abilities provided by your symbiote such as Blink or Slow. 6. [[[[[uHeal symbiote] (level 15) Cost:14 Consciously altering the metabolism of your symbiote, you can urge its bodily structure to repair itself almost instantaneously. 7. [[[[[uUse major powers] (level 25) Cost:30 Highly intelligent slimes such as Quylthulgs may be more than willing to employ their summoning or teleporting powers on your behalf; this power can also call upon the abilities normally invoked by "Use minor powers" (but this would be a waste of mana). 8. [[[[[uSummon never-moving pet] (level 30) Cost:35 By releasing certain chemicals in the air, a symbiant can attract the attention of slimes and mold; the better specimens are found in deeper dungeons, of course. 9. [[[[[uForce symbiosis] (level 40) Cost:60 An expert symbiant has such control over the cells of primitive life-forms that he can temporarily "charm" part of them, thus forcing their powers to manifest at his own advantage. tome-235-src/lib/help/r_yeek.txt0000644000076400017500000000167311012107760014407 0ustar dgdg~~~~~01|Yeek ~~~~~02|Races|Yeek #####R=== Yeeks === #####GDescription Yeeks are the least powerful of all the races. They suffer disadvantages in nearly all skills and attributes but to compensate they learn (and thus gain levels) extremely quickly. "Live fast, die young!" #####GStat Modifiers Strength -5 Intelligence -5 Wisdom -5 Dexterity -5 Constitution -5 Charisma -5 Hit Dice Sides 6 Exp Penalty -75% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery -0.500 [0.000] Archery -0.500 [0.000] Sneakiness -0.500 [0.000] Stealth -5.000 [0.000] Disarming -0.500 [0.000] Magic Magic-Device -0.500 [0.000] Spirituality -2.500 [0.000] tome-235-src/lib/help/r_dunad.txt0000644000076400017500000000210411012107760014533 0ustar dgdg~~~~~01|Dunedain ~~~~~02|Races|Dunedain #####R=== Dunedain === #####GDescription Dunedain are a race of hardy men from the West. This elder race surpasses human abilities in every field, especially constitution. However, being men of the world, very little is new to them, and levels are very hard for them to gain. They can play all classes. Their constitution cannot be reduced and they regain hit points quickly. #####GStat Modifiers Strength +1 Intelligence +2 Wisdom +2 Dexterity +2 Constitution +3 Charisma +2 Hit Dice Sides 10 Exp Penalty +80% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 1.500 [0.000] Archery 1.000 [0.000] Sneakiness 0.800 [0.000] Stealth 2.000 [0.000] Disarming 0.400 [0.000] Magic Magic-Device 0.500 [0.000] Spirituality 2.500 [0.000] tome-235-src/lib/help/c_geoman.txt0000644000076400017500000000412011012107760014667 0ustar dgdg|||||oy ~~~~~01|Geomancer ~~~~~02|Classes|Geomancer #####R=== Geomancers === #####GDescription Geomancers harness the power of the elements earth, air, fire and water. The level of their *****skills.txt*60[Geomancy] skill gives them access to their own *****m_geoman.txt*0[school of Geomancy], but the levels of the Fire, Water, Air, and Earth skills will have an effect on the outcome of each spell. Geomancers need the aid of a Mage Staff in order to use their powers. #####GStarting Stat Modifiers Strength -5 Intelligence +3 Wisdom +0 Dexterity +1 Constitution -2 Charisma +1 Hit Die +d0 Spell Points +50% Exp Penalty 30% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 1.000 [0.200] Weaponmastery 0.700 [0.400] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Magic 1.000 [0.900] Magic-Device 1.000 [1.050] Spell-power 1.000 [0.700] Geomancy 1.000 [0.700] Fire 1.000 [1.050] Water 1.000 [1.050] Air 1.000 [1.050] Earth 1.000 [1.050] Meta 0.000 [0.700] Conveyance 0.000 [0.700] Divination 0.000 [0.700] Temporal 0.000 [0.700] Mind 0.000 [0.700] Nature 0.000 [0.700] Necromancy 0.000 [0.700] Runecraft 0.000 [0.700] Thaumaturgy 0.000 [0.700] Spirituality 1.000 [0.550] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Perfect casting 1 #####GStarting Equipment A Geomancer begins the game with: a Spellbook of Geyser a Mage Staff tome-235-src/lib/help/magic.hlp0000644000076400017500000000260111012107760014145 0ustar dgdg|||||oy ~~~~~01|Magic|Index ~~~~~02|Help|Magic #####RWelcome to the ToME Magic Help System. #####R============================================= Please choose one of the following help files: General Info *****/amagic.txt*0[(a) The ToME magic system] *****/bmagic.txt*02[(b) Wands and Staves] Magic schools *****/cm_air.txt*0[(c) The Air School] *****/dm_convey.txt*0[(d) The Conveyance School] *****/em_demono.txt*0[(e) The Demonology School] *****/fm_divin.txt*0[(f) The Divination School] *****/gm_earth.txt*0[(g) The Earth School] *****/hm_fire.txt*0[(h) The Fire School] *****/im_geoman.txt*0[(i) The Geomancy School] *****/jm_mana.txt*0[(j) The Mana School] *****/km_meta.txt*0[(k) The Meta School] *****/lm_mind.txt*0[(l) The Mind School] *****/mm_nature.txt*0[(m) The Nature School] *****/nm_necrom.txt*0[(n) The Necromancy School] *****/om_tempo.txt*0[(o) The Temporal School] *****/pm_udun.txt*0[(p) The Udun School] *****/qm_water.txt*0[(q) The Water School] Other powers accessed by the 'm' menu *****/rm_mimic.txt*0[(r) Mimicry Powers] *****/sm_mindcr.txt*0[(s) Mindcrafting Powers] *****/tm_music.txt*0[(t) Musical Songs] *****/um_symbio.txt*0[(u) Symbiotic Powers] *****/vm_thaum.txt*0[(v) Thaumaturgical Spells] *****/zhelp.hlp*0[(z) Main Help menu] tome-235-src/lib/help/m_mindcr.txt0000644000076400017500000000465611012107760014725 0ustar dgdg|||||oy ~~~~~01|Magic|Mindcraft ~~~~~02|Mindcrafter|Mindcraft powers ~~~~~03|Skills|Mindcraft - Spell Info #####R === ToME Magic - Mindcraft === Mindcrafting uses the power of the mind to cast its spells. Therefore neither books nor light are necessary, and as the mindcrafter's skill increases, so do the powers of his mind. The powers are accessed using the 'm' key and then selecting 'Use Mindcraft'; they are cast with spell points, like normal spells, which can be increased as usual through the *****skills.txt*21[Magic] skill. 1. [[[[[sPrecognition] (Level 1) Cost:1 Detects monster minds around you. At level 5 it also detects traps. At level 15 it also allows you to see invisible monsters for a time. At level 20 it maps out the surrounding area. At level 25 it gives you ESP for a time. At level 30 it also detects objects and treasure. At level 45 it fully shows the entire level. 2. [[[[[sNeural blast] (Level 2) Cost:1 Fires a bolt or beam, to stun and damage monsters. 3. [[[[[sMinor Displacement] (Level 3) Cost:2 Teleports you a short distance. At level 25 it grants the ability to create void jumpgates. 4. [[[[[sMajor Displacement] (Level 7) Cost:6 Teleports you a good distance. At level 30 it also banishes the monsters around you. 5. [[[[[sDomination] (Level 9) Cost:7 Attempts to dominate the minds of your foes, scaring them. At level 30 it attempts to charm monsters. 6. [[[[[sPulverise] (Level 11) Cost:7 Fires pure sound at your opponents, crushing their bodies. 7. [[[[[sCharacter Armour] (Level 13) Cost:12 Raises a physical shield around your body. At level 15 it also grants resistance to acid. At level 20 it also grants resistance to fire. At level 25 it also grants resistance to cold. At level 30 it also grants resistance to electricity. At level 35 it also grants resistance to poison. 8. [[[[[sPsychometry] (Level 15) Cost:12 Senses the quality of an item. At level 40 it identifies an item. 9. [[[[[sMindwave] (Level 18) Cost:10 Blasts the minds of monsters close to you. At level 25 it affect all monsters in line of sight. 10.[[[[[sAdrenaline Channeling] (Level 23) Cost:15 Heals you, hastes you and cures you. 11.[[[[[sPsychic Drain] (Level 25) Cost:10 Drains the life of your foes into your mana reserves. 12.[[[[[sTelekinesis] (Level 28) Cost:20 Projects a wave of pure telekinetic force from your body, damaging and maybe banishing monsters. tome-235-src/lib/help/magic.txt0000644000076400017500000002330711012107760014207 0ustar dgdg|||||oy ~~~~~03|Magic #####R === ToME Magic system === *****magic.txt*02[Wands and Staves] For the basics of how to use skills, please see *****skills.txt*0[Using Skills]. In ToME you have a basic *****skills.txt*21[Magic] skill. This skill is one of the most important ones for a spellcaster, since it is responsible for how much mana you have. You can never have too much of it. If you like magical devices, the Magical Device skill is also important, since it controls the Magical Device ability of your character. This ability again dictates the fail rates of use of wands/rods/staffs and activation of random-artifacts/artifacts, and it will also increase the power of these items. ~~~~~01|Magic|Schools ToME uses skills to define the various schools of magic. There are 11 primary schools: *****m_mana.txt*0[Mana] *****m_fire.txt*0[Fire] *****m_water.txt*0[Water] *****m_air.txt*0[Air] *****m_earth.txt*0[Earth] *****m_meta.txt*0[Meta] *****m_convey.txt*0[Conveyance] *****m_divin.txt*0[Divination] *****m_tempo.txt*0[Temporal] *****m_mind.txt*0[Mind] *****m_nature.txt*0[Nature] Other magical skills, generally being used primarily by characters of a specific class, are: *****m_demono.txt*0[Demonology] *****m_necrom.txt*0[Necromancy] *****skills.txt*36[Runecraft] *****m_thaum.txt*0[Thaumaturgy] *****skills.txt*49[Alchemy] *****m_geoman.txt*0[Geomancy] The *****m_demono.txt*0[Demonology] skill is primarily used by *****c_demono.txt*0[Demonologists] for their special spells, whereas the *****m_necrom.txt*0[Necromancy] skill is used by *****c_necro.txt*0[Necromancers] for their own set of special spells. The same goes for *****skills.txt*36[Runecraft], which is used by *****c_runecr.txt*0[Runecrafters] to allow use of more difficult runes or rune-combinations. *****m_thaum.txt*0[Thaumaturgy] gives you randomly chosen attack spells, and as such each game with it will be different. *****c_geoman.txt*0[Geomancers] harness the powers of the elements using *****m_geoman.txt*0[Geomancy]. Lastly we have *****skills.txt*49[Alchemy], which is used by *****c_alchem.txt*0[Alchemists]. In addition to the schools of magic, you can get access to special sets of spells if you worship a God. There are currently four good Gods, *****g_eru.txt*0[Eru Iluvatar], *****g_manwe.txt*0[Manwe Sulimo], *****g_yavann.txt*0[Yavanna Kementari] and *****g_tulkas.txt*0[Tulkas]. There is also an evil god, *****g_melkor.txt*0[Melkor]. Each of them gives you access to different types of spells. *****c_pr_drk.txt*0[Worshippers of Melkor] also have access to the special *****m_udun.txt*0[Udun] school of magic, whereas other *****c_priest.txt*0[Priests] and *****c_mindcr.txt*0[Mindcrafters] can use *****m_mindcr.txt*0[Mindcrafting Powers]. *****c_symbia.txt*0[Symbiants] have access to their own special brand of *****m_symbio.txt*0[magic powers], and *****c_bard.txt*0[Bards] have access to *****m_music.txt*0[Songs], which affect creatures in ways that can appear to be magical. The 11 different primary schools give you access to different spells of variable usefulness. The way they work is that adding skill points to a specific school will enable you to get higher level spells for that specific school. By level requirements for a specific spell you could actually say skill requirement, since they correlate exactly. Let's take a simple example: If you have the *****m_mana.txt*0[Mana] school skill at level 24.000, it means you can use any spell in the mana school up to and including those requiring level 24. [[[[[BThere are] [[[[[Balso some spells requiring a certain skill level in two schools, and there is a] [[[[[Bpossibility of spells requiring three or more. For this kind of spells the ] [[[[[Bspell level is determined by taking an average of the necessary skills. ] When calculating spell level for spells which require more than one school, sorcery (or god-granted access) can be used in place of the primary schools in the normal way. Once the average has been calculated, any bonus from the spell-power skill can also be applied as normal. If one of the schools required is the Udun school, then the appropriate bonus from character level will be applied. Lastly, if you look at a spell, and the spell level reads -2 or some other negative value while it's also grayed out, that means you need to increase the corresponding school's skill level by 3, since only 2 will have it end up on spell level 0, where it still is unusable. If it reads n/a, you currently have no skill points in that school. Another thing that should be explained about the skills and schools of magic right now, is that the skill doesn't stop being useful only for gaining spells. The higher the skill level, the higher the spell level will be, and the more powerful your spells will be. For instance, say you have the *****m_mana.txt*0[Mana] skill at level 24. Now, the Manathrust spell is one of the spells for that school that only requires skill level 1, but since you've got skill at level 24, the power of the spell is increased as well. For comparison, a level 1 Manathrust costs 1 mana and does 4d2 damage, while at level 24 it costs 12 mana and does a whopping 27d10 damage. The *****skills.txt*23[Sorcery] skill is a nice skill, since it gives you access to all the 11 primary schools of magic, just as if you'd spent an equal amount of skill points in all the skills. It's available to any mage character, but only a *****c_sorcer.txt*0[Sorceror] will be able to be proficient in it. Also, having this skill at level 1 will give you a hitpoint-penalty of 1%, all the way up to skill level 50, with a hitpoint-penalty of 50%. There are also ToHit and ToDam penalties for sorcery, so don't choose sorcery if you plan to do much fighting. There is also the *****skills.txt*22[Spell Power] skill. This skill is rather nice, since it will augment the power of spells you already know. The distinction between this and the others, is that it will not grant you new spells, but instead increases the levels of spells. At level 50 it grants 20 extra spell levels. [[[[[BThis skill ] [[[[[Bonly affects the 11 primary schools] (Mana, Earth, Air, Fire, Water, Meta, Mind, Temporal, Conveyance, Divination and Nature) as well as Geomancy and the spells granted by the Gods. There is also the Magic-Device skill which affects your ability to use wands, staves, rods and to activate special objects. It also affects the spell-levels of the staff and wand spells, as explained below. ~~~~~02|Wands ~~~~~04|Magic|Wands and Staves ~~~~~05|Staves #####GWands and Staves Wands and staves (sticks) operate in a similar fashion, and in fact most of them use the same spells with the same effects. When you pick up a stick, you'll see it has two numbers in the format [x|y] in addition to the number of charges it holds. By increasing your magic-device skill you can increase the level (and hence the power) of the spell in that stick. The x value are skill level bonuses which the staff itself holds, and these are added onto your existing magic-device skill for the purpose of using the staff. The y value is the maximum possible skill level for that stick. Things are balanced by the use of a "minimum magic-device skill level required to raise spell level". Here's an example: A Staff of Sense Hidden [1|10]. Your magic device skill is at 6. If you were to identify the staff and then 'I'nspect it, you would see the following information: &&&&&w wSwpwewlwlw wdwewswcwrwiwbwtwiwownw:w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w &&&&&w wDwewtwewcwtwsw wtwhwew wtwrwawpwsw wiwnw waw wcwewrwtwawiwnw wrwawdwiwuwsw wawrwowuwnwdw wywowuw w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w &&&&&w wAwtw wlwewvwewlw w1w5w wiwtw wawlwlwowwwsw wywowuw wtwow wswewnwswew wiwnwvwiwswiwbwlwew wfwowrw waw wwwhwiwlwew w w w w w w w w w w w w w w w w w w w w w w &&&&&w wSwpwewlwlw wlwewvwewlw:w B3w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w &&&&&w wMwiwnwiwmwuwnw wMwawgwiwcw wDwewvwiwcwew wlwewvwewlw wtwow wiwnwcwrwewawswew wswpwewlwlw wlwewvwewlw:w B5w w w w w w w w w w w w w w w w w w w w w w w w w w &&&&&w wSwpwewlwlw wfwawiwlw:w g2g3w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w &&&&&w wSwpwewlwlw wiwnwfwow:w yryaydy y1y3w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w w The Spell level is the level at which the spell will actually be cast. Spell fail is the spell fail percentage. The spell info may contain the radius of effect, amount of damage, or duration the spell might last. The Minimum Magic Device level to increase your spell level is just that. If your magic device skill was less than this level, then the staff would be casting the spell at level one. Our magic device skill is 6. Therefore we are casting at level 2 (at skill level 5, we should be casting the spell at level 1). Then we add the bonus from the staff of 1, which gives us our spell level of 3. If our magic device in this example had been 14, this would have given us a spell level of 1 + (14 - 5 + 1) = 11. This is calculated from the formula: spell level = staff bonus + (magic device - minimum magic device + 1)). However given that the maximum spell level with this staff is 10, you'll be casting with a spell level of 10. As you get deeper into the dungeons, you will find sticks with higher bonuses and maximum spell levels. Written by: vrak AKA Per-Arne Holtmon Akoe Wands and Staves section added by fearoffours tome-235-src/lib/help/c_polear.txt0000644000076400017500000000332011012107760014704 0ustar dgdg~~~~~01|Polearmmaster ~~~~~02|Classes|Polearmmaster #####R=== Polearmmasters === #####GDescription The Polearmmaster is a Warrior who specialises in polearms. The training is so intense and specific that Polearmmasters gain huge bonuses when fighting with their chosen weapon, dependent on their Polearm-mastery skill. In most other respects they perform about as well as a generic Warrior. #####GStarting Stat Modifiers Strength +5 Intelligence -2 Wisdom -2 Dexterity +2 Constitution +2 Charisma -1 Hit Die +d9 Spell Points +0% Exp Penalty 0% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 2.000 [0.900] Weaponmastery 1.000 [0.950] Sword-mastery 0.000 [0.300] Axe-mastery 0.000 [0.300] Hafted-mastery 0.000 [0.300] Polearm-mastery 1.000 [0.700] Archery 1.000 [0.600] Antimagic 0.000 [0.550] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Disarming 1.000 [0.900] Magic 1.000 [0.300] Magic-Device 1.000 [1.150] Spirituality 1.000 [0.400] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Extra Max Blow(1) 1 Extra Max Blow(2) 1 Spread blows 25 #####GStarting Equipment A Polearmmaster begins the game with: a Ring of Fear Resistance a Chain Mail a Pike tome-235-src/lib/help/m_tempo.txt0000644000076400017500000000347711012107760014575 0ustar dgdg|||||oy ~~~~~01|Magic|Temporal School ~~~~~02|Temporal Magic ~~~~~03|Skills|Temporal - Spell Info #####R === ToME Magic - Temporal School === The temporal school of magic contains spells where magic is used to meddle in the relationship between time and space. There are rumours of a "Tome of the Time" which contains all the temporal school spells within its bindings. Worshipping the Goddess Yavanna Kementari also gives the ability to cast spells from the temporal school at a level of 1/6 of your prayer level. E.g. if the skill "Spirituality: Prayer" is at level 12, you can cast up to level 2 temporal school spells. #####sTemporal Spells There are four spells available for the temporal school. These Spells are: 1. [[[[[sMagelock] (school level 1) Magically locks a door. At spell level 30 it creates a glyph of warding. At spell level 40 the glyph can be placed anywhere in the field of vision. 2. [[[[[sSlow Monster] (school level 10) Magically slows down the passing of time around a monster. At level 20 it affects a zone. 3. [[[[[sEssence of Speed] (school level 15) Magically decreases the passing of time around you, allowing you to move and act more quickly with respect to the rest of the universe. 4. [[[[[sBanishment] (school level 30) Disrupts the space/time continuum in your area and teleports all monsters away. At spell level 15 it also may lock them in a time bubble for some turns. #####v Your Temporal and Conveyance skills must have reached a combined average level #####v of 30 in order to cast this spell. #####GNature spells that can be cast with Temporal skill 1. [[[[[GGrow Trees] (dual school level 6) Makes trees grow extremely quickly around you. #####v Your Nature and Temporal skills must have reached a combined average level #####v of 6 in order to cast this spell. tome-235-src/lib/help/g_melkor.txt0000644000076400017500000000617411012107760014731 0ustar dgdg|||||oy ~~~~~01|Melkor ~~~~~02|Gods|Melkor #####R === Melkor Bauglir === Melkor Bauglir is Morgoth, the Dark Enemy. He once was the most powerful of the Valar. His most faithful followers are those of the class *****c_pr_drk.txt*0[Dark Priest]. #####GThe benefits of Worshipping Melkor Bauglir 1. As you increase your piety, Melkor will grant boosts to your strength, constitution and charisma and will decrease intelligence and wisdom. 2. As a follower of Melkor you are resistant to fire. 3. If you are praying, Melkor may make you invisible and immune to fire. 4. If you are praying, Melkor may cast Curse on your foes when you melee them. 5. If you are praying, Melkor likes it when you kill monsters. 6. If you are praying, Melkor *likes* it when you kill monsters that are aligned with good. 7. Melkor likes the sacrifice of corpses and books at his altars. 8. Melkor likes the permanent sacrifice of your own health at his altars. 9. Melkor hates elves. 10. Melkor grants access to the *****m_udun.txt*0[Udun] school of magic. 11. Melkor can summon undead and demons to help you when your life goes down. #####GThe disadvantages of Worshipping Melkor Bauglir 1. Your piety decreases with time. 2. Your piety decreases with time even more if you are praying. 3. He will completely abandon you if you destroy The One Ring. ~~~~~03|Melkor|Prayers #####GMelkor Bauglir's Magic Worshipping Melkor Bauglir gives the adventurer access to a set of special spells that come directly from the hands of Melkor. These spells use your piety to cast rather than your spellpoints, and the level of spells that Melkor will permit you to use is determined by your Prayer skill - how skillful you are in asking for his help without offending him! There is a special book called the "Corrupted Tome of Melkor" which contains instructions for the procedure for each of the prayers Melkor will grant. There are three prayers all told, which are: 1. [[[[[BCurse] (Level 1) It curses a monster, reducing its melee power At level 5 it can be auto-casted (with no piety cost) while fighting if your piety is over 5000. At level 15 it also reduces armor At level 25 it also reduces speed At level 35 it also reduces max life (but it is never fatal) 2. [[[[[BCorpse Explosion] (Level 10) It makes corpses in an area around you explode for a percent of their hit points as damage 3. [[[[[BMind Steal] (Level 20) It allows your spirit to temporarily leave your own body, which will be vulnerable, to control one of your enemies body Each of these spells can be increased in level both by improving your Prayer skill, and by improving your Spell-power skill. In addition to his specific magic, Melkor will also assist with your ability to use some magic from the "standard" schools, in relation to how skilled you are at Prayer. This school is as follows: *****m_mind.txt*0[Mind School] at 1/3 the Prayer skill level. Melkor also grants all of his followers access to the *****m_udun.txt*0[Udun] school of magic, but only powerful mages are able to cast all of its spells. The spells from these schools are all cast using your normal spellpoints. tome-235-src/lib/help/index.txt0000644000076400017500000005003611012107760014235 0ustar dgdg|||||oy #####R /----------------------------------------\ #####R < Help Index > #####R \----------------------------------------/ This is the index of everything in the T.o.M.E. documentation. #####BHit a letter key to jump to the entries for that letter. Some entries in the index link to the same place as other entries. This is intentional, so that the information you want is easy to find. Don't forget you can browse the help from the *****help.hlp*02[Main menu]. #####sSpotted a problem with the help files, or some content thats missing? #####sContact fearoffours@t-o-m-e.net . ~~~~~65 *****/Aindex.txt*65[A] *****birth.txt*81[Abbreviations] *****birth.txt*20[AC] *****birth.txt*17[AU] *****tome_faq.txt*25[FF] *****birth.txt*21[HP] *****birth.txt*29[Pt] *****birth.txt*24[SN] *****birth.txt*26[SP] *****ability.txt*01[Abilities] *****ability.txt*07[Ammo creation] *****ability.txt*09[Artifact Creation] *****ability.txt*05[Extra Max Blow 1] *****ability.txt*06[Extra Max Blow 2] *****ability.txt*10[Far reaching attack] *****ability.txt*04[Perfect casting] *****ability.txt*02[Spread blows] *****ability.txt*08[Touch of death] *****ability.txt*11[Trapping] *****ability.txt*03[Tree walking] *****ability.txt*12[Undead Form] *****m_air.txt*02[Air Magic] *****c_alchem.txt*01[Alchemist] *****c_alchem.txt*03[Alchemy powers explained] *****essences.txt*02[Essence Spoiler] *****tome_faq.txt*03[Altars] *****tome_faq.txt*37[Anti-magic Amulets and the Anti-magic shell] *****c_unbel.txt*04[Antimagic] *****c_archer.txt*01[Archer] *****attack.txt*03[Armor] *****birth.txt*19[Armor Class] *****attack.txt*05[Resistances] *****tome_faq.txt*18[Artifacts that activate but I cannot wear or wield] *****c_assass.txt*01[Assassin] *****attack.txt*01[Attacking Monsters] *****attack.txt*06[Damage Effect type ] *****attack.txt*04[Resistances] *****birth.txt*48[Fighting ability] *****birth.txt*50[Shooting] *****automat.txt*03[Auto destroy] *****automat.txt*02[Auto pick-up] *****automat.txt*01[Automatizer] *****defines.txt*82[Defines] *****automat.txt*04[Autosquelch] *****c_axemas.txt*01[Axemaster] ~~~~~66 *****/Bindex.txt*66[B] *****rm_barb.txt*01[Barbarian] *****c_bard.txt*01[Bard] *****tome_faq.txt*36[Beginner strategy] *****r_beorn.txt*01[Beorning] *****birth.txt*84[Birth] *****dungeon.txt*21[Buildings] ~~~~~67 *****/Cindex.txt*67[C] *****birth.txt*11[Character] *****birth.txt*46[Abilities] *****birth.txt*10[Ability tables] *****birth.txt*23[Armor Class] *****birth.txt*02[Characteristics] *****birth.txt*01[Creating a Character] *****birth.txt*22[Hit Points] *****birth.txt*28[Mana] *****birth.txt*31[Piety] *****birth.txt*08[Race and Class Combinations] *****birth.txt*25[Sanity Points] *****birth.txt*09[Stat Bonus Table] *****birth.txt*13[Stats 1] *****birth.txt*39[Stats 2] *****tome_faq.txt*34[Character choice is too confusing] *****birth.txt*45[Charisma] *****birth.txt*05[Classes] *****c_alchem.txt*02[Alchemist] *****c_archer.txt*02[Archer] *****c_assass.txt*02[Assassin] *****c_axemas.txt*02[Axemaster] *****c_bard.txt*02[Bard] *****birth.txt*68[Combinations with Race] *****c_pr_drk.txt*02[Dark Priest] *****c_demono.txt*02[Demonologist] *****c_druid.txt*02[Druid] *****c_geoman.txt*02[Geomancer] *****c_hafted.txt*02[Haftedmaster] *****c_lorema.txt*02[Loremaster] *****c_mage.txt*02[Mage] *****c_mimic.txt*02[Mimic] *****c_mindcr.txt*02[Mindcrafter] *****c_monk.txt*02[Monk] *****c_necro.txt*02[Necromancer] *****c_palad.txt*02[Paladin] *****c_polear.txt*02[Polearmmaster] *****c_posses.txt*02[Possessor] *****c_pr_eru.txt*02[Priest - Eru] *****c_pr_man.txt*02[Priest - Manwe] *****c_ranger.txt*02[Ranger] *****c_rogue.txt*02[Rogue] *****c_runecr.txt*02[Runecrafter] *****c_sorcer.txt*02[Sorceror] *****birth.txt*77[Stat Bonuses] *****c_summon.txt*02[Summoners] *****c_swordm.txt*02[Swordmasters] *****c_symbia.txt*02[Symbiant] *****c_thaum.txt*02[Thaumaturgy] *****c_unbel.txt*02[Unbeliever] *****c_warper.txt*02[Warper] *****c_warrio.txt*02[Warrior] *****rm_class.txt*01[Classical] *****command.txt*99[Commands] *****command.txt*116[Alteration commands] *****command.txt*103[Command counts] *****command.txt*111[Command descriptions ] *****command.txt*129[Extras] *****command.txt*123[Game status] *****command.txt*128[Help] *****command.txt*112[Inventory] *****command.txt*121[Looking ] *****command.txt*122[Messages] *****command.txt*113[Movement] *****command.txt*119[Object manipulation] *****command.txt*100[Original keyset] *****command.txt*126[Pref files] *****command.txt*104[Repeating a command] *****command.txt*114[Resting] *****command.txt*101[Roguelike keyset] *****command.txt*124[Saving and Exiting] *****command.txt*115[Searching] *****command.txt*102[Special keys] *****command.txt*118[Spells and prayers] *****command.txt*117[Terrain interaction] *****command.txt*120[Throwing and missile weapons] *****dungeon.txt*19[Companions] *****birth.txt*43[Constitution] *****m_convey.txt*02[Conveyance Magic] *****corspoil.txt*01[Corruptions ] *****c_archer.txt*03[Creating Ammo] *****birth.txt*12[Creating a Character] *****dungeon.txt*10[Cursed Objects] ~~~~~68 *****/Dindex.txt*68[D] *****attack.txt*09[Damage Effects] *****r_drkelf.txt*01[Dark Elf] *****c_pr_drk.txt*01[Dark Priest] *****tome_faq.txt*29[Dark grey things are difficult to see] *****r_deathm.txt*01[DeathMolds] *****spoil_faq.txt*19[Deathmolds on Mount Doom and other quest areas] *****debug.txt*99[Debug] *****debug.txt*100[Command List] *****debug.txt*111[Command descriptions ] *****debug.txt*112[General] *****defines.txt*81[Defines] *****defines.txt*84[Svals] *****defines.txt*85[Tvals] *****c_demono.txt*01[Demonologist] *****m_demono.txt*02[Demonology Magic] *****version.txt*01[Development history] *****birth.txt*41[Dexterity] *****birth.txt*56[Disarming traps] *****birth.txt*37[Display] *****m_divin.txt*02[Divination Magic] *****c_druid.txt*01[Druid] *****r_dunad.txt*01[Dunedain] *****dungeon.txt*02[Dungeons] *****dungeon.txt*12[Doors] *****dungeon.txt*06[In the dungeon] *****dungeon.txt*11[Mining] *****dunspoil.txt*01[Spoilers] *****r_dwarf.txt*01[Dwarf] *****dungeon.txt*15[Dying] ~~~~~69 *****/Eindex.txt*69[E] *****m_earth.txt*02[Earth Magic] *****r_elf.txt*01[Elf] *****r_ent.txt*01[Ent] *****g_eru.txt*02[Eru] *****g_eru.txt*03[Prayers] *****c_pr_eru.txt*03[Priest - Eru] *****tome_faq.txt*10[Essences] *****experien.hlp*01[Experience] *****explore.hlp*02[Exploring menu] ~~~~~70 *****/Findex.txt*70[F] *****tome_faq.txt*02[FAQ - Spoiler free] *****spoil_faq.txt*02[FAQ - contains spoilers] *****tome_faq.txt*13[Prophets] *****fatespoi.txt*02[Fates ] *****m_fire.txt*02[Fire Magic] *****inscrip.txt*01[Floor Inscriptions ] *****tome_faq.txt*28[Floor tiles displaying incorrectly] *****tome_faq.txt*05[Fountains] *****tome_faq.txt*24[Fumblefingers quests] ~~~~~71 *****/Gindex.txt*71[G] *****gambling.txt*01[Gambling] *****tome_faq.txt*30[Game ] *****c_geoman.txt*01[Geomancer] *****m_geoman.txt*02[Geomancy spells] *****r_gnome.txt*01[Gnome] *****gods.txt*01[Gods] *****tome_faq.txt*04[Altars] *****g_eru.txt*01[Eru] *****g_manwe.txt*01[Manwe] *****g_melkor.txt*02[Melkor] *****birth.txt*30[Piety] *****spoil_faq.txt*23[Quest - Spoilers] *****g_tulkas.txt*02[Tulkas] *****g_yavann.txt*02[Yavanna] *****birth.txt*16[Gold] ~~~~~72 *****/Hindex.txt*72[H] *****c_hafted.txt*01[Haftedmaster] *****r_hafelf.txt*01[Half-Elf] *****r_hafogr.txt*01[Half-Ogre] *****general.txt*01[Help] *****explore.hlp*01[Exploring menu] *****tome_faq.txt*01[FAQ - Spoiler free] *****magic.hlp*02[Magic] *****help.hlp*01[Main Menu] *****newbie.hlp*01[New players] *****spoil_faq.txt*01[Spoiled FAQ] *****rm_herm.txt*01[Hermit] *****r_hielf.txt*01[High-Elf] *****r_hobbit.txt*01[Hobbit] *****tome_faq.txt*12[Homes] *****r_human.txt*01[Human] ~~~~~73 *****/Iindex.txt*73[I] *****tome_faq.txt*35[I STILL keep dying] *****tome_faq.txt*31[I keep dying] *****dungeon.txt*04[Identifying features] *****birth.txt*66[Infra-vision] *****birth.txt*35[Intelligence] *****birth.txt*85[Inventory - starting info] *****tome_faq.txt*32[Invisible character] ~~~~~75 *****/Kindex.txt*75[K] *****macrofaq.txt*44[Keymaps] *****macrofaq.txt*46[Macro recorder] *****r_kobold.txt*01[Kobold] ~~~~~76 *****/Lindex.txt*76[L] *****dungeon.txt*23[Light] *****dungeon.txt*17[Loading old characters] *****c_lorema.txt*01[Loremaster] *****rm_lsoul.txt*01[Lost Soul] *****luckspoi.txt*01[Luck ] ~~~~~77 *****/Mindex.txt*77[M] *****macrofaq.txt*43[Macros] *****macrofaq.txt*45[Macro recorder] *****c_mage.txt*01[Mage] *****magic.txt*03[Magic] *****m_air.txt*01[Air School] *****m_convey.txt*01[Conveyance School] *****m_demono.txt*01[Demonology School] *****m_divin.txt*01[Divination School] *****m_earth.txt*01[Earth School] *****m_fire.txt*01[Fire School] *****m_geoman.txt*01[Geomancy] *****magic.hlp*01[Index] *****birth.txt*27[Mana] *****m_mana.txt*01[Mana School] *****m_meta.txt*01[Meta School] *****m_mimic.txt*01[Mimicry] *****m_mind.txt*01[Mind School] *****m_mindcr.txt*01[Mindcraft] *****m_music.txt*01[Music] *****m_nature.txt*01[Nature School] *****m_necrom.txt*01[Necromancy] *****magic.txt*01[Schools] *****m_symbio.txt*01[Symbiosis] *****m_tempo.txt*01[Temporal School] *****m_thaum.txt*01[Thaumaturgy] *****m_udun.txt*01[Udun School] *****magic.txt*04[Wands and Staves] *****m_water.txt*01[Water School] *****birth.txt*58[Magical Devices] *****r_maia.txt*01[Maia] *****help.hlp*02[Main Menu] *****m_mana.txt*02[Mana Magic] *****g_manwe.txt*02[Manwe] *****g_manwe.txt*03[Prayers] *****c_pr_man.txt*03[Priest - Manwe] *****tome_faq.txt*14[Mathilde] *****g_melkor.txt*01[Melkor] *****c_pr_drk.txt*03[Dark Priests] *****g_melkor.txt*03[Prayers] *****m_meta.txt*02[Meta Magic] *****c_mimic.txt*01[Mimic] *****m_mimic.txt*02[Mimicry powers] *****m_mind.txt*02[Mind Magic] *****c_mindcr.txt*01[Mindcrafter] *****m_mindcr.txt*02[Mindcraft powers] *****dungeon.txt*13[Mining] *****birth.txt*18[Money] *****c_monk.txt*01[Monk] *****c_monk.txt*03[Monk attacks] *****dungeon.txt*05[Monsters] *****attack.txt*02[Attacking] *****attack.txt*07[Monster Memory] *****dungeon.txt*20[Pets] *****tome_faq.txt*08[They are talking to me] *****m_music.txt*02[Music] ~~~~~78 *****/Nindex.txt*78[N] *****m_nature.txt*02[Nature Magic] *****c_necro.txt*01[Necromancer] *****m_necrom.txt*02[Necromancy Magic] ~~~~~79 *****/Oindex.txt*79[O] *****dungeon.txt*14[Objectives] *****dungeon.txt*08[Objects] *****dungeon.txt*21[Colour of inventory slot letter] *****dungeon.txt*09[Cursed Objects] *****tome_faq.txt*33[Piles] *****option.txt*05[Options] *****option.txt*16[Automatizer] *****option.txt*15[Autosave] *****option.txt*13[Base Delay Factor] *****option.txt*18[Cheating] *****option.txt*09[Disturbance] *****option.txt*19[Dump] *****option.txt*11[Efficiency] *****option.txt*10[Game-play] *****option.txt*14[Hitpoint Warning] *****option.txt*07[Ingame] *****option.txt*08[Interface] *****option.txt*06[Startup] *****option.txt*12[ToME Options] *****option.txt*17[Window Flags] *****r_orc.txt*01[Orc] ~~~~~80 *****/Pindex.txt*80[P] *****c_palad.txt*01[Paladin] *****birth.txt*62[Perception] *****dungeon.txt*18[Pets] *****r_pettyd.txt*01[Petty Dwarf] *****c_polear.txt*01[Polearmmaster] *****c_posses.txt*01[Possessor] *****c_posses.txt*03[Possessor powers ] *****command.txt*105[Pref files] *****command.txt*109[Colors] *****command.txt*127[Commands] *****command.txt*107[Keymaps] *****command.txt*106[Macros] *****command.txt*110[Options] *****command.txt*108[Visuals] *****c_pr_eru.txt*01[Priest - Eru] *****c_pr_man.txt*01[Priest - Manwe] *****c_priest.txt*01[Priests] ~~~~~82 *****/Rindex.txt*82[R] *****birth.txt*04[Race Modifiers] *****birth.txt*79[Ability table] *****rm_barb.txt*02[Barbarian] *****rm_class.txt*02[Classical] *****rm_herm.txt*02[Hermit] *****rm_lsoul.txt*02[Lost Soul] *****rm_skel.txt*02[Skeleton] *****rm_spec.txt*02[Spectre] *****birth.txt*76[Stat Bonuses] *****rm_vamp.txt*02[Vampire] *****rm_zomb.txt*02[Zombie] *****birth.txt*03[Races] *****birth.txt*78[Ability table] *****r_beorn.txt*02[Beorning] *****birth.txt*67[Combinations with class] *****r_drkelf.txt*02[Dark Elf] *****r_deathm.txt*02[DeathMolds] *****r_dunad.txt*02[Dunedain] *****r_dwarf.txt*02[Dwarf] *****r_elf.txt*02[Elf] *****r_ent.txt*02[Ent] *****r_gnome.txt*02[Gnome] *****r_hafelf.txt*02[Half-Elf] *****r_hafogr.txt*02[Half-Ogre] *****r_hielf.txt*02[High-Elf] *****r_hobbit.txt*02[Hobbit] *****r_human.txt*02[Human] *****r_kobold.txt*02[Kobold] *****r_maia.txt*02[Maia] *****r_orc.txt*02[Orc] *****r_pettyd.txt*02[Petty Dwarf] *****r_rohank.txt*02[RohanKnight] *****birth.txt*75[Stat Bonuses] *****r_thlord.txt*02[Thunderlord] *****r_troll.txt*02[Troll] *****r_wodelf.txt*02[Wood Elf] *****r_yeek.txt*02[Yeek] *****tome_faq.txt*26[Random quests are not working] *****tome_faq.txt*36[Random quests strategy] *****c_ranger.txt*01[Ranger] *****c_rogue.txt*01[Rogue] *****r_rohank.txt*01[RohanKnight] *****c_runecr.txt*01[Runecrafter] *****c_runecr.txt*03[Runecrafter powers] *****tome_faq.txt*11[Runes] ~~~~~83 *****/Sindex.txt*83[S] *****command.txt*125[Saving and Exiting] *****birth.txt*52[Saving throw] *****birth.txt*60[Searching] *****birth.txt*63[Searching Ability] *****birth.txt*61[Searching Frequency - Perception] *****tome_faq.txt*09[Sentient weapons] *****rm_skel.txt*01[Skeleton] *****skills.txt*55[Skills] *****skills.txt*27[Air] *****m_air.txt*03[Air - Spell Info] *****skills.txt*49[Alchemy] *****c_alchem.txt*05[Alchemy - Alchemy powers] *****skills.txt*50[Antimagic] *****c_unbel.txt*05[Antimagic powers] *****skills.txt*08[Archery] *****skills.txt*05[Axe-mastery] *****skills.txt*18[Backstab] *****skills.txt*13[Barehand-combat] *****skills.txt*61[Bearform-combat] *****skills.txt*12[Boomerang-mastery] *****skills.txt*58[Boulder-throwing] *****skills.txt*10[Bow-mastery] *****skills.txt*01[Combat] *****skills.txt*30[Conveyance] *****m_convey.txt*03[Conveyance - Spell Info] *****skills.txt*44[Corpse-preservation] *****skills.txt*04[Critical-Hits] *****skills.txt*11[Crossbow-mastery] *****skills.txt*52[Demonology] *****m_demono.txt*03[Demonology - Spell Info] *****skills.txt*16[Disarming] *****skills.txt*31[Divination] *****m_divin.txt*03[Divination - Spell Info] *****skills.txt*20[Dodging] *****skills.txt*28[Earth] *****m_earth.txt*03[Earth - Spell Info] *****skills.txt*25[Fire] *****m_fire.txt*03[Fire - Spell Info] *****skills.txt*60[Geomancy] *****m_geoman.txt*03[Geomancy - Spell Info] *****skills.txt*06[Hafted-mastery] *****skills.txt*57[List of skills] *****skills.txt*21[Magic] *****skills.txt*54[Magic-device] *****skills.txt*24[Mana] *****m_mana.txt*03[Mana - Spell Info] *****skills.txt*29[Meta] *****m_meta.txt*03[Meta - Spell Info] *****skills.txt*47[Mimicry] *****m_mimic.txt*03[Mimicry - mimicry powers] *****skills.txt*33[Mind] *****m_mind.txt*03[Mind - Spell Info] *****skills.txt*41[Mindcraft] *****m_mindcr.txt*03[Mindcraft - Spell Info] *****skills.txt*42[Monster-lore] *****skills.txt*59[Music] *****m_music.txt*03[Music - Song Info] *****skills.txt*34[Nature] *****m_nature.txt*03[Nature - Spell Info] *****skills.txt*35[Necromancy] *****m_necrom.txt*03[Necromancy - Spell Info] *****skills.txt*07[Polearm-mastery] *****skills.txt*45[Possession] *****c_posses.txt*04[Possession - Possessor powers ] *****skills.txt*39[Prayer] *****skills.txt*36[Runecraft] *****c_runecr.txt*04[Runecrafting - Runecrafter powers] *****skills.txt*56[Screen] *****skills.txt*09[Sling-mastery] *****skills.txt*14[Sneakiness] *****skills.txt*23[Sorcery] *****skills.txt*22[Spell-power] *****skills.txt*38[Spirituality] *****skills.txt*19[Stealing] *****skills.txt*15[Stealth] *****skills.txt*53[Stunning-blows] *****skills.txt*43[Summoning] *****c_summon.txt*04[Summoning - Summoning powers] *****skills.txt*03[Sword-mastery] *****skills.txt*46[Symbiosis] *****m_symbio.txt*03[Symbiosis - Symbiotic Powers] *****skills.txt*32[Temporal] *****m_tempo.txt*03[Temporal - Spell Info] *****skills.txt*37[Thaumaturgy] *****m_thaum.txt*03[Thaumaturgy - Spell Info] *****skills.txt*48[Udun] *****m_udun.txt*03[Udun - Spell Info] *****skills.txt*26[Water] *****m_water.txt*03[Water - Spell Info] *****skills.txt*02[Weaponmastery] *****c_sorcer.txt*01[Sorceror] *****rm_spec.txt*01[Spectre] *****spoiler.hlp*01[Spoilers] *****corspoil.txt*02[Corruptions] *****dunspoil.txt*02[Dungeons] *****essences.txt*01[Essences] *****fatespoi.txt*01[Fates] *****inscrip.txt*02[Floor Inscriptions] *****spoil_faq.txt*20[God Quest - directions] *****spoil_faq.txt*22[God Quest - how many] *****spoil_faq.txt*21[God Quest - relic] *****spoil_faq.txt*07[Lothlorien Poisoned water quest] *****luckspoi.txt*02[Luck] *****spoil_faq.txt*06[Merton the lost Hobbit quest] *****wishing.txt*01[Wishing] *****birth.txt*82[Stats] *****birth.txt*71[Bonus table] *****birth.txt*44[Charisma] *****birth.txt*42[Constitution] *****birth.txt*40[Dexterity] *****birth.txt*14[Display] *****birth.txt*06[Individual explanations] *****birth.txt*33[Intelligence] *****birth.txt*32[Strength] *****birth.txt*36[Wisdom] *****magic.txt*05[Staves] *****birth.txt*54[Stealth] *****tome_faq.txt*17[Strange items] *****birth.txt*34[Strength] *****c_summon.txt*01[Summoners] *****c_summon.txt*03[Summoning] *****defines.txt*12[Svals] *****c_swordm.txt*01[Swordmasters] *****c_symbia.txt*01[Symbiant] *****c_symbia.txt*03[Naming your symbiote] *****m_symbio.txt*02[Symbiosis Magic] *****dungeon.txt*03[Symbols] ~~~~~84 *****/Tindex.txt*84[T] *****birth.txt*69[Tables] *****birth.txt*74[Ability Tables] *****birth.txt*70[Combinations of Race and Class] *****c_monk.txt*04[Monk attacks] *****birth.txt*72[Stat bonuses] *****m_tempo.txt*02[Temporal Magic] *****m_thaum.txt*02[Thaumaturgical Magic] *****c_thaum.txt*01[Thaumaturgist] *****r_thlord.txt*01[Thunderlord] *****whattome.txt*01[ToME - a General Description] *****dungeon.txt*07[Town] *****r_troll.txt*01[Troll] *****g_tulkas.txt*01[Tulkas] *****c_palad.txt*03[Paladin] *****g_tulkas.txt*03[Prayers] *****defines.txt*83[Tvals] ~~~~~85 *****/Uindex.txt*85[U] *****m_udun.txt*02[Udun Magic] *****c_unbel.txt*01[Unbeliever] *****c_unbel.txt*03[Antimagic] ~~~~~86 *****/Vindex.txt*86[V] *****rm_vamp.txt*01[Vampire] *****tome_faq.txt*16[Void jumpgates] *****dungeon.txt*23[Void jumpgates] ~~~~~87 *****/Windex.txt*87[W] *****magic.txt*02[Wands] *****c_warper.txt*01[Warper] *****c_warrio.txt*01[Warrior] *****m_water.txt*02[Water Magic] *****birth.txt*86[Weapons - starting info] *****tome_faq.txt*27[Weird display] *****dungeon.txt*1[Wilderness] *****birth.txt*38[Wisdom] *****r_wodelf.txt*01[Wood Elf] *****tome_faq.txt*15[Wrists hurting] ~~~~~89 *****/Yindex.txt*89[Y] *****g_yavann.txt*01[Yavanna] *****c_druid.txt*03[Druid] *****g_yavann.txt*03[Prayers] *****r_yeek.txt*01[Yeek] ~~~~~90 *****/Zindex.txt*90[Z] *****rm_zomb.txt*01[Zombie] tome-235-src/lib/help/rm_skel.txt0000644000076400017500000000266611012107760014570 0ustar dgdg~~~~~01|Skeleton ~~~~~02|Race Modifiers|Skeleton #####R=== Skeletal Race === #####GDescription As undead beings, skeletons need to worry very little about poison or attacks that can drain life. They do not really use eyes for perceiving things, and are thus not fooled by invisibility. Their bones are resistant to sharp shrapnels (not much to cut there), and they will quickly become resistant to cold. It is very hard for skeletons to eat food or drink potions. Although the magical effects of these will affect the skeleton even without entering the skeleton's (non-existent) belly, the potion / food itself will fall through the skeleton's jaws, giving no nutritional benefit. #####GStat Modifiers Strength 0 Intelligence -2 Wisdom -2 Dexterity 0 Constitution +1 Charisma -4 Hit Dice +0 sides Spell Points -30% Exp Penalty +45% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 0.800 [0.000] Sneakiness -0.100 [0.000] Stealth -1.000 [0.000] Disarming -0.500 [0.000] Magic Magic-Device -0.500 [0.000] Spirituality 0.500 [0.000] #####GStarting Equipment A skeletal character begins the game with: Some scrolls of satisfy hunger Some torches tome-235-src/lib/help/c_pr_drk.txt0000644000076400017500000000405411012107760014710 0ustar dgdg|||||oy ~~~~~01|Dark Priest ~~~~~02|Classes|Dark Priest ~~~~~03|Melkor|Dark Priests #####R=== Melkor's Priests === #####GDescription All gods have priests; but those serving *****g_melkor.txt*0[Melkor], the dark enemy, are not like their good counterparts. While usually it takes devotion and awe to be inspired into serving a deity, Melkor's followers revere him because of the power he gives them. Some of them may even be so ambitious as to aspire to take his place upon the black throne of Angband. This he knows very well, but as long as he can use those puny mortals to inspire fear into the followers of the Valar and to bring destruction to Arda, he doesn't mind; he even lends power to the ones more bent on destruction, while sapping their minds to reduce them to unthinking slaves. #####GStarting Stat Modifiers Strength -1 Intelligence -3 Wisdom +3 Dexterity -1 Constitution +0 Charisma +2 Hit Die +d2 Spell Points +0% Exp Penalty 20% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 2.000 [0.700] Weaponmastery 1.000 [0.700] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Disarming 0.000 [0.900] Magic 1.000 [0.900] Magic-Device 1.000 [1.050] Spell-power 0.000 [0.800] **Udun 0.000 [0.400] Necromancy 0.000 [0.800] Spirituality 1.000 [1.000] Prayer 1.000 [1.400] Monster-lore 0.000 [0.500] Corpse-preservation 1.000 [1.000] **Actually, every character has this level of proficiency with the *****m_udun.txt*0[Udun] school, provided they are worshipping Melkor #####GInnate Abilities: #####BAbility Character level Perfect casting 1 #####GStarting Equipment A Priest serving Melkor begins the game with: a Spellbook of Curse a Mace tome-235-src/lib/help/experien.hlp0000644000076400017500000000214011012107760014702 0ustar dgdg|||||oy ~~~~~01|Experience #####RGaining experience #####R============================================== The principle way for your character to gain experience (XP) is to kill monsters. There are a few other ways too, like lockpicking, but these only give small rewards. Once your character has gained enough experience to go up a level, then she will be given skill points to spend as you see fit. These points can be spent on either *****/askills.txt*0[(a) Skills] which improve more for each point you put into them, or *****/bability.txt*0[(b) Abilities] which are one-off purchases and grant your character new, non-improvable powers Certain monsters can "drain" your experience, and thus your level. Although you do not lose the skill points you've already gained, you also will not gain further points until you reach a character level you have not already achieved. Luckily, you can restore drained experience through magical means, or by simply regaining the experience all over again. *****/ynewbie.hlp*0[(y) New player help menu] *****/zhelp.hlp*0[(z) Main menu] tome-235-src/lib/help/m_nature.txt0000644000076400017500000000417211012107760014740 0ustar dgdg|||||oy ~~~~~01|Magic|Nature School ~~~~~02|Nature Magic ~~~~~03|Skills|Nature - Spell Info #####R === ToME Magic - Nature School === The nature school of magic contains spells that interact with nature. There are rumours of a "Tome of the Tree" which contains all the nature school spells within its bindings. Worshipping the Goddess Yavanna Kementari also gives the ability to cast spells from the nature school at a level of 1/2 of your prayer level. E.g. if the skill "Spirituality: Prayer" is at level 10, you can cast up to level 5 nature school spells. #####GNature Spells There are five spells available for the nature school. These spells are: 1. [[[[[GGrow Trees] (dual school level 6) Makes trees grow extremely quickly around you. #####v Your Nature and Temporal skills must have reached a combined average level #####v of 6 in order to cast this spell. 2. [[[[[GHealing] (school level 10) Heals a portion of your hitpoints. 3. [[[[[GRecovery] (school level 15) Reduces the length of time that you are poisoned. At spell level 5 it cures poison and cuts. At spell level 10 it restores drained stats. At spell level 15 it restores lost experience. 4. [[[[[GRegeneration] (school level 20) Increases your body's regeneration rate. 5. [[[[[GSummon Animal] (school level 25) Summons a leveled animal to your aid. #####GAir spells that can be cast with Nature skill 1. [[[[[BThunderstorm] (dual school level 25) Charges up the air around you with electricity. Each turn it will throw a bolt of thunder at a random monster in sight. This thunder does 3 types of damage: one third of lightning one third of sound and one third of light. #####v Your Nature and Air skills must have reached a combined average level #####v of 25 in order to cast this spell. #####GUdun spells that can be cast with Nature skill 1. [[[[[DGenocide] (dual school level 25) Genocides all monsters of a specified race on the level. At level 10 it can genocide all monsters near you. #####v Your Nature and Udun skills must have reached a combined average level #####v of 25 in order to cast this spell. tome-235-src/lib/help/m_mind.txt0000644000076400017500000000404311012107760014366 0ustar dgdg|||||oy ~~~~~01|Magic|Mind School ~~~~~02|Mind Magic ~~~~~03|Skills|Mind - Spell Info #####R === ToME Magic - Mind School === The mind school of magic contains spells which alter the mind. There are rumours of a "Tome of the Mind" which contains all the mind school spells within its bindings. Worshipping the God Eru Iluvatar or the God Melkor Bauglir also gives the ability to cast spells from the mind school at a level of 1/3 of your prayer level. E.g. if the skill "Spirituality: Prayer" is at level 12, you can cast up to level 4 mind school spells. #####sMind Spells There are four spells available for the mind school. These spells are: 1. [[[[[sCharm] (school level 1) Tries to manipulate the mind of a monster to make it friendly. At spell level 15 it turns into a ball. At spell level 35 it affects all monsters in sight. 2. [[[[[sConfuse] (school level 5) Tries to manipulate the mind of a monster to confuse it. At spell level 15 it turns into a ball. At spell level 35 it affects all monsters in sight. 3. [[[[[sArmor of Fear] (school level 10) Creates a shield of pure fear around you. Any monster attempting to hit you must save or flee. 4. [[[[[sStun] (school level 15) Tries to manipulate the mind of a monster to stun it. At spell level 20 it turns into a ball. #####GFire spells that can be cast with Mind skill 1. [[[[[RFire Golem] (school level 7) Creates a fiery golem and controls it. During the control the available keylist is: Movement keys: move the golem (depending on its speed it can move more than one square). , : pickup all items on the floor d : drop all carried items i : list all carried items m : end the possession/use golem powers Most of the other keys are disabled; you cannot interact with your real body while controlling the golem. But to cast the spell you will need a lantern or a wooden torch to create the golem. #####v Your Fire and Mind skills must have reached a combined average level #####v of 7 in order to cast this spell. tome-235-src/lib/help/fatespoi.txt0000644000076400017500000000311011012107760014727 0ustar dgdg|||||oy ~~~~~01|Spoilers|Fates ~~~~~02|Fates (spoiler) #####R Fate Spoiler #####R Accurate for PernAngband 5.x.x #####R by Dustin Ragan Numerous spirits inhabit the land of Arda, from the murderous barrow wights to the enigmatic Tom Bombadil. These spirits usually are bound to a specific geographic region, but there are exceptions to this rule. Sometimes one of these spirits will take interest in an adventurer. This can either be very, very good or very, very bad. These spirits will "rig" reality to ensure that something happens--or doesn't happen. In order to attract the attention of a spirit, the adventurer must be somewhat experienced, having attained at least the 11th level of experience. Every 10 game turns, which corresponds to 1 normal speed player turn, there is a 1 in 50,000 chance of gaining a fate. When this fate is chosen, there is a 7/18 chance of being fated to find a specific mundane item on a specific dungeon level. A more belligerent spirit will, 7/18 of the time, summon a malicious monster to do battle on a specific dungeon level. There is a 1/9 chance to be destined to find an artifact on a given level. There is also a 1/18 chance that you will meet your demise on a given level. Finally, there is a 1/18 chance of becoming invulnerable to attacks from mortals. Whenever a level is being chosen for a fate, it is always chosen within 20 levels of your current recall depth. Items, monsters, and artifacts are all generated up to 10 levels out of depth for your current recall depth. tome-235-src/lib/help/r_hafogr.txt0000644000076400017500000000214511012107760014713 0ustar dgdg~~~~~01|Half-Ogre ~~~~~02|Races|Half-Ogre #####R=== Half-Ogres === #####GDescription Half-Ogres are a crossbreed between a human and an ogre. They are big, bad, and stupid. For warriors, they have all the necessary attributes, and they can even become priests: after all, they are related to Ogre Magi, from whom they have learned the skill of setting trapped runes once their level is high enough. Like orcs, they resist darkness, and like trolls, they have their strength sustained. #####GStat Modifiers Strength +3 Intelligence -1 Wisdom -1 Dexterity -1 Constitution +3 Charisma -3 Hit Dice Sides 12 Exp Penalty +30% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 2.000 [0.000] Sneakiness -0.100 [0.000] Stealth -2.000 [0.000] Disarming -0.300 [0.000] Magic Magic-Device -0.500 [0.000] Spirituality -2.500 [0.000] tome-235-src/lib/help/c_ranger.txt0000644000076400017500000000353511012107760014710 0ustar dgdg|||||oy ~~~~~01|Ranger ~~~~~02|Classes|Ranger #####R=== Rangers === #####GDescription Rangers are warrior-mages, devoted to nature. They are good fighters and quite effective with bows; their magic often allows them to avoid the worst of situations, but they have only a mild chance of resisting magical effects and are not terribly stealthy. They have access to the schools of *****m_divin.txt*0[Divination], *****m_convey.txt*0[Conveyance] and *****m_nature.txt*0[Nature] magic. #####GStarting Stat Modifiers Strength +2 Intelligence +1 Wisdom +0 Dexterity +2 Constitution +1 Charisma +1 Hit Die +d4 Spell Points +0% Exp Penalty 30% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 1.000 [0.800] Weaponmastery 1.000 [0.500] Archery 1.000 [0.750] Sling-mastery 0.000 [0.300] Bow-mastery 0.000 [0.300] Crossbow-mastery 0.000 [0.300] Boomerang-mastery 0.000 [0.300] Sneakiness 1.000 [0.950] Stealth 0.000 [0.400] Disarming 1.000 [1.600] Magic 1.000 [0.700] Magic-Device 1.000 [1.100] Conveyance 0.000 [0.500] Divination 0.000 [0.500] Nature 0.000 [0.500] Spirituality 1.000 [0.400] Prayer 0.000 [0.500] Monster-lore 0.000 [0.700] #####GInnate Abilities: #####BAbility Character level Ammo creation 2 #####GStarting Equipment A Ranger begins the game with: a Spellbook of Phase Door a Short sword a Short Bow some Arrows tome-235-src/lib/help/m_geoman.txt0000644000076400017500000000644511012107760014715 0ustar dgdg|||||oy ~~~~~01|Magic|Geomancy ~~~~~02|Geomancer|Geomancy spells ~~~~~03|Skills|Geomancy - Spell Info #####R === ToME Magic - Geomancy === Geomancy harnesses the power of nature to awesome effect. Therefore neither books nor light are necessary, and as the geomancers's skill increases, so do his powers over the elements of nature. Because Geomancy relies so heavily on the environment, you will need sufficient knowledge of the elemental skills (Earth, Air, Fire and Water) in order to cast some of the spells, and the exact effects of a spell often depend upon your levels in the elemental skills and your current surroundings. The powers are accessed using the 'm' key and then selecting 'Use Geomancy'; they are cast with spell points, like normal spells, which can be increased as usual through the *****skills.txt*21[Magic] skill. 1. [[[[[RCall] [[[[[GThe] [[[[[BElements] (Level 1) Cost:2 Randomly creates various elements around you. The chance for each type of element is controlled by your level in the corresponding skill. At level 17 it can be targeted. 2. [[[[[UChannel] [[[[[GElements] (Level 3) Cost:3 Draws on the caster's immediate environs to form an attack or other effect. Grass/Flower heals. Water creates water bolt attacks. Ice creates ice bolt attacks. Sand creates a wall of burning sand around you, but the wall is thick and blinds you. Lava creates fire bolt attacks. Deep lava creates fire ball attacks. Chasm creates darkness bolt attacks. At Earth level 18, darkness becomes nether. At Water level 8, water attacks become beams with a striking effect. At Water level 12, ice attacks become balls of ice shards. At Water level 18, water attacks push monsters back. At Fire level 15, fire becomes hellfire. 3. [[[[[RElemental] [[[[[BWave] (Level 15) Cost:15 Draws on an adjacent special square to project a slow-moving wave of that element in that direction. Abyss squares cannot be channeled into a wave. 4. [[[[[UElemental] [[[[[RMinion] (Level 20) Cost:40 Summons a minion from a nearby element. Walls can summon Earth elmentals, Xorns and Xarens. Dark Pits can summon Air elementals, Ancient blue dragons, Great Storm Wyrms and Sky Drakes. Sandwalls and lava can summon Fire elementals and Ancient red dragons. Icewalls and water can summon Water elementals, Water trolls and Water demons. 5. [[[[[GVaporize] (Level 4) Cost:3 Draws upon your immediate environs to form a cloud of damaging vapors. #####v You must have reached at least level 4 in the Air skill to cast this #####v spell. 6. [[[[[UGeolysis] (Level 7) Cost:15 Burrows deeply and slightly at random into a wall, leaving behind tailings of various different sorts of walls in the passage. #####v You must have reached at least level 7 in the Earth skill to cast this #####v spell. 7. [[[[[BDripping Tread] (Level 10) Cost:15 Causes you to leave random elemental forms behind as you walk. #####v You must have reached at least level 10 in the Water skill to cast this #####v spell. 8. [[[[[UGrow Barrier] (Level 12) Cost:30 Creates impassable terrain (walls, trees, etc.) around you. At air level 20 it can be projected around another area. #####v You must have reached at least level 12 in the Earth skill to cast this #####v spell. tome-235-src/lib/help/r_human.txt0000644000076400017500000000114711012107760014556 0ustar dgdg~~~~~01|Human ~~~~~02|Races|Human #####R=== Humans === #####GDescription Humans act as a baseline race -- all other races are compared to them. Humans can choose any class and are average at everything. Humans tend to go up levels faster than most other races because of their shorter life spans. No racial adjustments or intrinsics occur to characters choosing the human race. #####GStat Modifiers Strength 0 Intelligence 0 Wisdom 0 Dexterity 0 Constitution 0 Charisma 0 Hit Dice Sides 10 Exp Penalty 0% #####GRacial Skill Modifiers: None. Humans are the baseline race. tome-235-src/lib/help/c_pr_man.txt0000644000076400017500000000353011012107760014701 0ustar dgdg|||||oy ~~~~~01|Priest - Manwe ~~~~~02|Classes|Priest - Manwe ~~~~~03|Manwe|Priest - Manwe #####R=== Manwe's Priests === #####GDescription As the forces of darkness arose, *****g_manwe.txt*0[Manwe], lord of air, realised that urgent action was needed to save Arda from the incoming darkness. So he started gathering followers from the ranks of men and elves and he instructed them to do battle against the forces of Udun. His priests must be quick and strike before the situation becomes critical, always keeping a direct line of prayer with their patron deity. Manwe doesn't tolerate laziness, but He also does not appreciate mindless killing; only a few measure up to his standards, but those are granted access to a whole series of divine powers which will help them in their enduring efforts. #####GStarting Stat Modifiers Strength -1 Intelligence -3 Wisdom +3 Dexterity -1 Constitution +0 Charisma +2 Hit Die +d2 Spell Points +0% Exp Penalty 20% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 2.000 [0.700] Weaponmastery 1.000 [0.750] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Disarming 0.000 [0.900] Magic 1.000 [0.900] Magic-Device 1.000 [1.050] Spell-power 0.000 [0.600] Spirituality 1.000 [1.000] Prayer 1.000 [1.500] Mindcraft 0.000 [0.600] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Perfect casting 1 #####GStarting Equipment A Priest serving Manwe begins the game with: a Spellbook of Manwe's Blessing a Mace tome-235-src/lib/help/c_archer.txt0000644000076400017500000000537311012107760014700 0ustar dgdg~~~~~01|Archer ~~~~~02|Classes|Archer #####R=== Archers === #####GDescription Archers are to bows what warriors are to melee. They are the best class around with any bow/crossbow/sling/boomerang. Needing a lot of ammo, they will learn early how to make it from junk found in the dungeons. They also gain, at skill level 20, the unique ability to make their arrows/bolts/shots pierce through monsters! #####GStarting Stat Modifiers Strength +2 Intelligence +1 Wisdom +0 Dexterity +2 Constitution +1 Charisma +1 Hit Die +d4 Spell Points +0% Exp Penalty 30% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 1.000 [0.800] Weaponmastery 1.000 [0.500] Archery 1.000 [0.850] Sling-mastery 0.000 [0.500] Bow-mastery 0.000 [0.500] Crossbow-mastery 0.000 [0.500] Boomerang-mastery 0.000 [0.500] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Disarming 1.000 [0.900] Magic 0.000 [0.200] Magic-Device 1.000 [1.100] Spirituality 1.000 [0.400] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Ammo creation 2 #####GStarting Equipment An Archer begins the game with: a Short Bow a Sling some ammo ~~~~~03|Creating Ammo #####GCreating AMmo Archers automatically gain the *****ability.txt*07[Ammo Creation] ability when they reach character level 2. (Other classes can purchase this ability when they have enough skill points.) This ability is accessed via the 'm' command. The first type of ammo you can make is sling ammo (pebbles or shots); as you increase in skill you'll be able to make other arrows (bow ammo) or bolts (crossbow ammo). Shots (or other sling ammo) are created from rubble piles found in the dungeons and other places. To make shots, stand next to a rubble pile, activate the ammo creation ability from the 'm' menu, select 's'hots, then specify the direction to the rubble pile, which will be consumed during the ammo creation. Arrows or bolts are made from "junk" items ('~' symbol, such as shards of pottery) that you can find in the dungeons and other places. To make arrows or bolts, assuming you have sufficient Archery skill, you must have the junk item in your inventory or on the ground at your feet. Specify the junk item after selecting 'a'rrows or 'b'olts from the ammo creation menu, and it will be consumed and replaced with a stack of ammo. tome-235-src/lib/help/c_merch.txt0000644000076400017500000000200511012107760014517 0ustar dgdg#####R=== Merchants === #####GDescription A Merchant is neither a warrior nor a spellcaster. They still have some great advantages, they can use chests to warp items into other items, they can indentify items, they soon learn to detect all objects in the area, and at higher level they can see all monsters carrying objects. They will also get the power to appraise items and to turn them into gold. A merchant will naturraly get better prices in shops and get access to the merchant guild services, loan and item request. #####GPrimary Stats Charisma Intelligence (Ability stat) #####GMagic Usage Merchants can use portable holes to carry more stuff than other classes but at the cost of an increased weight. To do that they must wear a portable hole and use it with 'm'. They also can use their merchants abilities and midas touch in the 'U' menu. #####GStarting Equipment A merchant begins the game with: A portable hole A small steel chest containing gold and items A long sword A wand of tame monsters tome-235-src/lib/help/r_deathm.txt0000644000076400017500000000213611012107760014707 0ustar dgdg~~~~~01|DeathMolds ~~~~~02|Races|DeathMolds #####R=== DeathMolds === #####GDescription Death Molds are incredibly powerful creatures. However, they are also molds. Lacking the ability to move as other creatures do, Death Molds have the powers of Phase Door, targeted teleportation, telekinesis, and controlled Teleport Level. They also intrinsically resist Nexus and Nether, and are more skilled at Necromancy than other races. #####GStat Modifiers Strength +10 Intelligence 0 Wisdom +10 Dexterity 0 Constitution +10 Charisma -15 Hit Dice Sides 15 Exp Penalty +150% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery 2.500 [0.000] Archery 2.500 [0.000] Sneakiness Stealth 25.000 [0.000] Disarming 1.500 [0.000] Magic Magic-Device -0.500 [0.000] Necromancy 0.000 [0.200] Spirituality 7.500 [0.000] tome-235-src/lib/help/c_swordm.txt0000644000076400017500000000331111012107760014735 0ustar dgdg~~~~~01|Swordmasters ~~~~~02|Classes|Swordmasters #####R=== Swordmasters === #####GDescription The Swordmaster is a Warrior who specialises in swords. The training is so intense and specific that Swordmasters gain huge bonuses when fighting with their chosen weapon, dependent on their Sword-mastery skill. In most other respects they perform about as well as a generic Warrior. #####GStarting Stat Modifiers Strength +5 Intelligence -2 Wisdom -2 Dexterity +2 Constitution +2 Charisma -1 Hit Die +d9 Spell Points +0% Exp Penalty 0% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 2.000 [0.900] Weaponmastery 1.000 [0.950] Sword-mastery 1.000 [0.700] Axe-mastery 0.000 [0.300] Hafted-mastery 0.000 [0.300] Polearm-mastery 0.000 [0.300] Archery 1.000 [0.600] Antimagic 0.000 [0.550] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Disarming 1.000 [0.900] Magic 1.000 [0.300] Magic-Device 1.000 [1.150] Spirituality 1.000 [0.400] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Extra Max Blow(1) 1 Extra Max Blow(2) 1 Spread-blows 25 #####GStarting Equipment A Swordmaster begins the game with: a Ring of Fear Resistance a Chain Mail a Broad Sword tome-235-src/lib/help/m_thaum.txt0000644000076400017500000000302211012107760014551 0ustar dgdg|||||oy ~~~~~01|Magic|Thaumaturgy ~~~~~02|Thaumaturgical Magic ~~~~~03|Skills|Thaumaturgy - Spell Info #####R === ToME Magic - Thaumaturgy === Thaumaturgy is a different type of magic where the spells learnt are not restricted to one school, nor are they read out of spellbooks. Each time an adventurer increases her thaumaturgy skill, she gains access to a few [[[[[Rrandom] attack spells, each one automatically "learnt" at a specific casting level. Since she doesn't need spellbooks, she does not end up with inventory slots being filled up so quickly by the necessary items for safe exploration of the dungeon, and can therefore collect more loot. The downside of this is that she has no ability to choose what spells she learns, and no ability to improve the power of a learnt spell. So, a bolt spell with damage 1d5 will remain at 1d5 damage for the whole game. And the spells learnt are *all* attack spells of some sort (remembering that things like light and stone-to-mud can damage some monsters) - so no teleporting, no identify, no healing spells are learnt. At most, some wall creation may be employed. Thaumaturgist use their magic through the 'm' key. They then select a general group of spells, followed by a specific spell. Thaumaturgy spells can take the form of: - a bolt, targeted at a single location; - a beam, which hits all monsters in a line; - a ball (either centred on the caster or targetable); - an meteor strike (multiple balls in the vicinity of the caster); - a spell that affects all monsters in line of sight. tome-235-src/lib/help/g_eru.txt0000644000076400017500000000647211012107760014234 0ustar dgdg|||||oy ~~~~~01|Gods|Eru ~~~~~02|Eru #####R === Eru Iluvatar === Eru Iluvatar is the father of the Valar. His most faithful followers are those of the class *****c_pr_eru.txt*0[Priest(Eru)]. #####GThe benefits of Worshipping Eru Iluvatar 1. As you increase your piety, Eru will grant you a boost to your wisdom. Eventually he will also start increasing your ability to handle magical power, resulting in a boost to your spellpoints. 2. If you are praying to him at the time, there is a chance that he will deflect some blows from evil monsters (that increases with your level of piety). 3. If you are praying to him at the time, there is a chance that he will resurrect you from the dead (provided you are very pious!). 4. Your piety automatically increases over time if you are: a) Not praying, and b) Actively doing something (i.e. not resting or in the Wilderness map). #####GThe disadvantages of Worshipping Eru Iluvatar 1. He doesn't like it if you destroy blessed weapons. 2. You can only wield blunt or blessed weapons without penalty. 3. He doesn't like it if you kill monsters that are aligned with good. 4. He will completely abandon you if you wear The One Ring. ~~~~~~03|Eru|Prayers #####GEru Iluvatar's Magic Worshipping Eru Iluvatar gives the adventurer access to a set of special spells that come directly from the hands of Eru. These spells use your piety to cast rather than your spellpoints, and the level of spells that Eru will permit you to use is determined by your Prayer skill - how skillful you are in asking for his help without offending him! There is a special book called the "Holy Tome of Eru Iluvatar" which contains instructions for the procedure for each of the prayers Eru will grant. There are four prayers all told, which are: 1. [[[[[BSee the Music] (Level 1) Allows you to 'see' the Great Music from which the world originates, allowing you to see unseen things, and can be cast while blind. At spell level 10 it allows you to see your surroundings. At spell level 20 it allows you to cure blindness. At spell level 30 it allows you to fully see all the level. 2. [[[[[BListen to the Music] (Level 7) Allows you to listen to the Great Music from which the world originates, allowing you to understand the meaning of things. At spell level 14 it allows you to identify all your pack. At spell level 30 it allows you to identify all items on the level. 3. [[[[[BKnow the Music] (Level 30) Allows you to understand the Great Music from which the world originates, allowing you to know the full abilities of things. At spell level 10 it allows you to *identify* all your pack. 4. [[[[[BLay of Protection] (Level 35) Creates a circle of safety around you. Each of these spells can be increased in level both by improving your Prayer skill, and by improving your Spell-power skill. In addition to his specific magic, Eru will also assist with your ability to use some magic from the "standard" schools, in relation to how skilled you are at Prayer. These schools are as follows: *****m_mana.txt*0[Mana School] at 1/2 the Prayer skill level. *****m_divin.txt*0[Divination School] at 2/3 the Prayer skill level. *****m_mind.txt*0[Mind School] at 1/3 the Prayer skill level. The spells from these schools are all cast using your normal spellpoints. tome-235-src/lib/help/c_warper.txt0000644000076400017500000000413311012107760014725 0ustar dgdg|||||oy ~~~~~01|Warper ~~~~~02|Classes|Warper #####R=== Warpers === #####GDescription A Warper is a type of mage that prefers to deal in magic that alters the fabric of space and time. They specialise in the schools of *****m_convey.txt*0[Conveyance], *****m_divin.txt*0[Divination] and *****m_tempo.txt*0[Temporal] magic. #####GStarting Stat Modifiers Strength -5 Intelligence +3 Wisdom +0 Dexterity +1 Constitution -2 Charisma +1 Hit Die +d0 Spell Points +50% Exp Penalty 30% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 1.000 [0.200] Weaponmastery 0.700 [0.400] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Magic 1.000 [0.900] Magic-Device 1.000 [1.050] Spell-power 1.000 [0.700] Mana 1.000 [0.700] Geomancy Fire 0.000 [0.800] Water 0.000 [0.800] Air 0.000 [0.800] Earth 0.000 [0.800] Meta 0.000 [0.800] Conveyance 0.000 [1.200] Divination 0.000 [1.200] Temporal 0.000 [1.200] Mind 0.000 [0.700] Nature 0.000 [0.800] Necromancy 0.000 [0.700] Runecraft 0.000 [0.700] Thaumaturgy 0.000 [0.700] Spirituality 1.000 [0.550] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] *A Warper cannot learn the Geomancy skill, but it is shown in his skill screen because the elemental schools are sub-skills of it. #####GInnate Abilities: #####BAbility Character level Perfect casting 1 #####GStarting Equipment A Warper begins the game with: a Book of Beginner Cantrips a Dagger tome-235-src/lib/help/r_maia.txt0000644000076400017500000000141411012107760014352 0ustar dgdg~~~~~01|Maia ~~~~~02|Races|Maia #####R=== Maia === #####GDescription An old race, dating from before the creation of Arda, the Maiar were created by Eru to help the Valar in their task. However, they can not worship a God, nor is experience easy to remember for them. Due to their perceived advantages, they are rather disliked by the denizens of the dungeon, and will find that most creatures take an instant dislike for the Maia. However, when they do finally manage to remember their encounters, they will find that their abilities will increase as they gain in knowledge. #####GStat Modifiers Strength 0 Intelligence 0 Wisdom 0 Dexterity 0 Constitution 0 Charisma 0 Hit Dice Sides 10 Exp Penalty +0% tome-235-src/lib/help/attack.txt0000644000076400017500000001731511012107760014400 0ustar dgdg|||||oy ~~~~~01|Attacking Monsters ~~~~~02|Monsters|Attacking #####R=== Attacking and Being Attacked === {{{{{

}Attacking is simple in ToME; attempting to move over a creature attacks it. It is also possible to attack from a distance by firing a missile or by magical means (wand, rod, spell, etc). Creatures attack in the same way. This means that if you do not wish to melee with a creature, it is wise to keep distant from it. This strategy is not perfect -- some monsters, such as dragons, have a way to attack from a distance. Some creatures, such as Ghosts, have the ability to pass through walls. To attack creatures (that you can see) who are currently in a wall, attempt to move over it (even if you cannot pass through walls, the attack will still happen). Monsters will take less damage from attacks while they are in walls. Also, if you cannot see the monster (e.g. if you are blind, or it is invisible and you do not have see invisible), this will not work: you'll have to try to tunnel. Most spells and magic devices cannot target monsters in walls. In situations like this, it is usually wise to lure the monster out of the wall before attacking it. Melee attacks are handled as such: #####G To-hit: Your strength grants a bonus or penalty to-hit Your class might grant a bonus or penalty to-hit Your skill with specific kinds of weapons gives a bonus to-hit (e.g.: Swordmastery gives a to-hit bonus when using swords) Enchantments on your weapon grant a bonus or penalty to-hit Certain rings (accuracy, slaying) may also grants a bonus or penalty to-hit Your Tactic setting may give bonuses o penalties to-hit (to change it, press 'C' and then 't' or 'T') Other temporary effects (berserk, etc) might affect your chance to hit The armor rating of the monster you're attacking makes a big difference #####G Blows: Your strength and dexterity affect how many blows you get Your class and level might affect how many blows you get The weight of the weapon very likely will affect how many blows you get Certain skills (e.g. Swordmastery) may affect how many blows you get with particular weapons Enchantments on your weapon might also affect how many blows you get (this is rare) Certain very rare rings (of attacks) may also affect how many blows you get #####G Damage: The base damage of your weapon is rolled Strength grants a bonus or penalty Your class might grant a bonus or penalty Combat and Weaponmastery skills increase your melee damage Ranged masteries increase the damage multiplier of slings, bows, crossbows or boomerangs(see below) Enchantments on your weapon might also grant a bonus or penalty Your Tactic setting may give bonuses o penalties to damage (to change it, press 'C' and then 't'or'T') Temporary effects also might grant a bonus or penalty So, each blow you are entitled to is checked for a hit. If this is the case, the damage is then applied to the monster. Note that unless you have some barehanded combat training or are possessing a monster, melee without a weapon will result in a single blow that does base damage of 1d1. This might, however, be useful in attacking certain rare monsters that destroy weapons. Combat with a bow/sling is similar, except ammo is used (which will eventually run out, requiring replacement). Bows don't have a base damage rating (ammo does), instead having a damage multiplier. Bows can, however, be enchanted, and enchantment on bows and arrows is cumulative (meaning that well-enchanted bows and arrows can be one of the more effective weapons in the game. They do, however, tend to be very expensive, as non-artifact arrows frequently break after being fired). Using ammo without the appropriate bow generally has poor results. ~~~~~03|Armor #####R=== Armor === As the armor class of a monster greatly affects how hard it is for it to be hit, your armor class affects how hard it is for it to hit you. A high armor rating will make it much easier to survive deep in the dungeon. For a warrior style class (Unbelievers, Fighters, Archers, etc), it is generally wise to wear as much and as powerful armor as possible (subject to weight limitations, of course). Spellcasting classes, however, have limits on how much armor they can wear before it disrupts their motion and makes it hard for them to cast spells properly. For many of these classes, gloves are especially bad for spellcasting. Monks and Rogues skilled at dodging will often find heavy armor cumbersome, too. Armor has a base rating and an enchantment rating. The base rating is constant for the type of armor (e.g. paper armor always has a base rating of 4), and the enchantment depends on the item. There are also ways to further enchant armor you have. Certain very powerful enchantments grant resistances to specific forms of magical attacks. ~~~~~04|Attacking Monsters|Resistances ~~~~~05|Armor|Resistances #####R=== Resistances and typed attacks=== Many kinds of monsters, traps, and other effects do damage that has a type. Types can have side effects in addition to the raw damage they deal. Certain enchanted items can grant resistances, reducing the raw damage and possibly reducing or eliminating the side effects. Some monsters also have resistances, so watching the messages when attacking a monster can often reveal that a particular attack is ineffective. ~~~~~06|Attacking Monsters|Damage Effect type (Fire/cold/nether etc) ~~~~~09|Damage Effects #####GLow attacks Fire - Destroys weapons, armor, scrolls, and staves. Reduces strength. Cold - Shatters potions. Elec - Reduces dexterity, destroys rings and wands. Acid - Reduces bonuses on equipped armor, reduces charisma. #####GMiddle attacks Poison - Player becomes poisoned Light - Blinds player, perma-lights area Dark - Blinds player, darkens area Confusion - Confuses player #####GHigh attacks Nether - Drains experience Nexus - Scrambles statistics, teleports player randomly Disenchantment - Reduces bonuses on equipped items Chaos - Confuses, drains life, causes hallucination, and more Sound - Shatters potions Shards - Cuts player #####GUnresistable attacks Water - Stuns player Ice - Stuns player, shatters potions Plasma - Stuns player, otherwise same as fire attacks Force - Pushes player a few squares back Inertia - Slows player Gravity - Slows and teleports player a few squares Disintegration - Destroys items on ground, destroys walls Mana - Destroys items on ground ~~~~~07|Monsters|Monster Memory #####R=== Monster Memory === The thousands of different creatures in ToME have many different characteristics, including spells, resistances, health, attacks, and speed. The information you have learned about each monster from your encounters with them is recorded in the monster memory (accessed with '/' or by 'l'ooking at a monster). It is possible to eventually learn all the characteristics of any given monster by interacting with them enough, but this is not always desirable (hanging around great hell wyrms, for example, can be hazardous to one's health). Certain spells may help you learn faster, as well as research centres in town. tome-235-src/lib/help/gods.txt0000644000076400017500000000404711012107760014063 0ustar dgdg|||||oy ~~~~~01|Gods #####RThe Guide to the Gods. #####G1. Introduction Everybody likes to have a little helping hand now and then. What could be better than having a god on your side? But it's not quite that easy. The gods won't help just any mortal who calls for help. You have to give them a little something too. #####G2. How Do I Get in on This? When you start a character, you get a choice of whether or not you wish to begin worshipping a God (unless you're something like a priest - they *must* start with a God to worship). If you do choose to be a follower of one of the Gods, you will gain certain abilities provided you do not do things that displease them. The measure of how happy your God is with you is your Piety - the Pt stat is your measure of Piety. Different actions will allow you to gain or lose Piety over time. You can change your mind about whom (if anyone) to worship during the game by finding an *****tome_faq.txt*04[altar] of that God. #####G3. What about spells? God-granted spells are also known as prayers, and are cast using Piety instead of Mana. God-spells can be increased in level by improving either your Prayer or Spell-power skill. The chance of successfully invoking a prayer depends on the Prayer skill and your wisdom. Each God also grants access to standard magical spell schools; which school(s) vary depending on the Gods' individual preferences. Spells from these schools are cast using Mana, not Piety; and success depends on your intelligence, not your wisdom. #####G4. So, Who Are These Gods? In ToME, there are five Gods you may choose to worship, being: 1. *****g_eru.txt*0[Eru Iluvatar] - the father of the Valar. 2. *****g_manwe.txt*0[Manwe Sulimo] - the second strongest of the Valar (Morgoth was the strongest). 3. *****g_yavann.txt*0[Yavanna Kementari] - the Earth Queen who created plants and animals. 4. *****g_tulkas.txt*0[Tulkas] - another of the Valar, Tulkas values strength and courage. 5. *****g_melkor.txt*0[Melkor Bauglir] - the Dark Enemy himself, once the most powerful of the Valar. tome-235-src/lib/help/c_pr_eru.txt0000644000076400017500000000373511012107760014730 0ustar dgdg|||||oy ~~~~~01|Priest - Eru ~~~~~02|Classes|Priest - Eru ~~~~~03|Eru|Priest - Eru #####R=== Eru's Priests === #####GDescription *****g_eru.txt*0[Eru] is the father of the Valar: he created the world and all its inhabitants. He is the wisest being ever and even if he foresaw Morgoth's evil, his role was that of the creator; as such, he chose not to destroy anything on Arda. His priests are therefore expected to avoid all forms of bloodshed (so they can only use blunt weapons without penalty); however, Eru knows that sometimes destruction is unavoidable and marks a blade with his rune; his priests call them Blessed and use them without feeling guilty, for they know that divine wisdom will guide every swing of those weapons. Still, a priest serving Eru will find that his true strength lies in knowledge and in the use of the force of Mana to avoid close contact with evil beings, rather than in blind assault of Morgoth's hordes. #####GStarting Stat Modifiers Strength -1 Intelligence -3 Wisdom +3 Dexterity -1 Constitution +0 Charisma +2 Hit Die +d2 Spell Points +0% Exp Penalty 20% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 2.000 [0.700] Weaponmastery 1.000 [0.700] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Disarming 0.000 [0.900] Magic 1.000 [0.900] Magic-Device 1.000 [1.050] Spell-power 0.000 [0.700] Spirituality 1.000 [1.000] Prayer 1.000 [1.500] Mindcraft 0.000 [0.600] Monster-lore 0.000 [0.500] #####GInnate Abilities: #####BAbility Character level Perfect casting 1 #####GStarting Equipment A Priest serving Eru begins the game with: a Spellbook of See the Music a Mace tome-235-src/lib/help/general.txt0000644000076400017500000000347111012107760014544 0ustar dgdg|||||oy ~~~~~01|Help #####R=== Using the Online Help === This help system has been designed to be read whilst in-game. Printing it off will make it look clumsy and a little difficult to read. Any text in orange/yellow colour is likely to be a hyperlink, and pressing while the link is active (yellow) will take you to the relevant page. Navigate between viewable links by using the left-right keys. Some links also have bracketed letters included in the links. Pressing these letters on your keyboard will activate the link even if it is orange. The help files total over 850 kb, so there is a lot of information. They have been designed to be browsed, but you may be looking for specific information, in which case you should try looking at the alphabetical *****index.txt*0[index]. Here are all the relevant keypresses for navigating the help system. #####GKey | Action ------------------------------------------------------------------- Escape | Leave the Online Help Backspace | Return to previous Help File Space | Advance 1 page (screen) 2, down arrow | Advance 1 line 8, up arrow | Back up 1 line - | Back up 1 page (screen) 6, right arrow | Advance 1 link 4, left arrow | Back up 1 link Return | Activate the selected link # | Go to a specific line (defaults to line 0) % | Go to a specific help file (defaults to help.hlp) = | Highlight lines containing a string (e.g. "word") / | Search for a string (e.g. "word") ------------------------------------------------------------------- There are other sources for help playing ToME. Try http://forum.t-o-m-e.net and http://wiki.t-o-m-e.net . We also have an IRC channel #tome on the worldirc and freenode networks (they are linked) which is fairly low traffic. tome-235-src/lib/help/c_sorcer.txt0000644000076400017500000000472511012107760014731 0ustar dgdg|||||oy ~~~~~01|Sorceror ~~~~~02|Classes|Sorceror #####R=== Sorcerors === #####GDescription Sorcerors are to magic what Unbelievers are to melee. They are the all- around best magicians, being able to cast spells from any school using only a single skill. They cannot comfortably use any weapon but a Mage Staff, and even with a Mage Staff, they will be unable to achieve anything remotely resembling battle effectiveness. The energies used for learning Sorcery also sap the life force of a Sorceror, penalising them with the loss of a percentage of their hit points equal to their Sorcery skill score and penalising their combat ability even more strongly. For more information on magic schools and spell effects see the *****magic.txt*01[Magic help file]. #####GStarting Stat Modifiers Strength -5 Intelligence +3 Wisdom +0 Dexterity +1 Constitution -2 Charisma +1 Hit Die +d0 Spell Points +50% Exp Penalty 30% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Magic 1.000 [1.000] Magic-Device 1.000 [1.000] Spell-power 0.000 [0.600] Sorcery 1.000 [0.700] Mana 0.000 [0.900] Geomancy Fire 0.000 [1.000] Water 0.000 [1.000] Air 0.000 [1.000] Earth 0.000 [1.000] Meta 0.000 [1.000] Conveyance 0.000 [1.000] Divination 0.000 [1.000] Temporal 0.000 [1.000] Mind 0.000 [1.000] Nature 0.000 [1.000] Necromancy 0.000 [1.000] Runecraft 0.000 [0.900] Thaumaturgy 0.000 [0.900] Spirituality 1.000 [0.550] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] *A Sorceror cannot learn the Geomancy skill, but it is shown in his skill screen because the elemental schools are sub-skills of it. #####GInnate Abilities: #####BAbility Character level Perfect casting 1 #####GStarting Equipment A Sorceror begins the game with: a Book of Beginner Cantrips a Robe tome-235-src/lib/help/c_summon.txt0000644000076400017500000000622711012107760014751 0ustar dgdg~~~~~01|Summoners ~~~~~02|Classes|Summoners #####R=== Summoners === #####GDescription A Summoner is, with one exception, a fairly weak class. While he starts out a decent enough fighter, his fighting skill doesn't improve that much, he doesn't cast magic and has little in the way of survival skills. However, this weakness doesn't trouble him much, because he can summon creatures to do his bidding and still gain experience from their kills. #####GStarting Stat Modifiers Strength +1 Intelligence -2 Wisdom +1 Dexterity +1 Constitution 0 Charisma +1 Hit Die +d8 Spell Points +0% Exp Penalty 40% #####GStarting Skills #####BSkill Start Level Skill Point Gains Combat 1.000 [0.600] Weaponmastery 1.000 [0.600] Archery 1.000 [0.400] Sneakiness 1.000 [0.700] Stealth 1.000 [0.700] Disarming 1.000 [0.500] Magic 1.000 [0.800] Magic-Device 1.000 [1.000] Spirituality 1.000 [0.500] Prayer 0.000 [0.500] Music 0.000 [0.300] Monster-lore 16.000 [1.200] Summoning 1.000 [0.700] Corpse-preservation 1.000 [1.000] #####GStarting Equipment A Summoner starts the game with: A Potion of Healing A Short Sword A Suit of Hard Leather Armour ~~~~~03|Summoners|Summoning ~~~~~04|Skills|Summoning - Summoning powers #####GSummoning [[[[[BThe summoner's powers of invocation are accessed using the 'm' key.] In order to invoke a monster, a summoner must possess a related totem. There are two kinds of summoning, decided by the totem used: [[[[[BPartial Summoning] Partial summoning creates a simulacrum of the monster, with little will of its own. The Summoner must maintain the simulacrum using mana; when he runs out, or stops paying the mana, the simulacrum vanishes. [[[[[BTrue Summoning] True summoning is quite different in effect from Partial Summoning, but the two are closely related in usage. A True Totem conjures a full copy of the creature in question; the process tends to make the monster a loyal ally to the summoner, but this loyalty is not guaranteed, nor is the survival of the totem used in the summoning. [[[[[BTotem Creation] In order to summon any creature, the Summoner needs a totem. Totems cannot be found; they must be created through a special process which involves taking the corpse of a creature (the summoner need not have been involved in the death of the creature in question), and extracting certain essences from it. The summoner can create a totem using the 'm' command, and unless one is working on a unique's corpse, must choose whether the resulting totem is a Partial or True Totem. [[[[[BImportant Note] Uniques are very willful creatures by definition, and thus have three special rules about their summoning: 1. No partial totem can be made from a unique's corpse. 2. The totem in question is always destroyed. 3. The unique is twice as likely to be disloyal. tome-235-src/lib/help/m_water.txt0000644000076400017500000000260011012107760014556 0ustar dgdg|||||oy ~~~~~01|Magic|Water School ~~~~~02|Water Magic ~~~~~03|Skills|Water - Spell Info #####R === ToME Magic - Water School === The water school of magic contains spells where the element of water is used to create the final spell effect. There are rumours of a "Tome of the Everrunning Wave" which contains all the water school spells within its bindings. Worshipping the Goddess Yavanna Kementari also gives the ability to cast spells from the water school at a level of 1/2 of your prayer level. E.g. if the skill "Spirituality: Prayer" is at level 10, you can cast up to level 5 water school spells. #####bWater Spells There are four spells available for the water school. These Spells are: 1. [[[[[bGeyser] (school level 1) Shoots a geyser of water from your fingertips. Sometimes it can blast through its first target. 2. [[[[[bVapor] (school level 2) Fills the air with toxic moisture to wash away annoying creatures. 3. [[[[[bEnt's Potion] (school level 6) Fills up your stomach (i.e. satisfy hunger). At spell level 5 it emboldens your heart (boldness). At level 12 it make you heroic. 4. [[[[[bTidal Wave] (school level 16) Summons a monstrous tidal wave that will expand and crush monsters under its mighty waves. 5. [[[[[bIce Storm] (school level 22) Engulfs you in a storm of roaring cold that strikes your foes. At spell level 10 it turns into shards of ice. tome-235-src/lib/help/m_mimic.txt0000644000076400017500000000315011012107760014533 0ustar dgdg|||||oy ~~~~~01|Magic|Mimicry ~~~~~02|Mimic|Mimicry powers ~~~~~03|Skills|Mimicry - mimicry powers #####R === ToME Magic - Mimicry === Mimics can alter their form using special cloaks called cloaks of mimicry. Even though this ability can give them access to increased stats, regeneration, speed and resistances, there is always the risk of the shape-change going horribly wrong, turning the character into an abomination for some time. Also, you should keep in mind that any racial power or stat modifier is overridden during the shape-shift. As your mimicry skill increases, your character is less likely to spoil the transformation attempt and may even gain other powers, such as making his colouration match his surroundings (becoming in all respects invisible) or even stranger abilities... rumours abound about Tarka the Chameleon and her two pairs of boots of speed. The powers are accessed using the 'm' key and then selecting 'Use Mimicry'; they are cast with spell points, like normal spells, which can be increased as usual through the *****skills.txt*21[Magic] skill. 1. [[[[[sMimic] (Level 1) Cost:2 Allows you to mimic the creature whose cloak you are wearing for a time. 2. [[[[[sInvisibility] (Level 10) Cost:6 Turns you invisible for a time. 3. [[[[[sLegs Mimicry] (Level 25) Cost:20 Gives you an additional set of legs for a time. 4. [[[[[sWall Mimicry] (Level 30) Cost:40 Allows you to move within walls, and [[[[[Bonly] walls, for a time. [[[[[v Be careful you don't get stuck in a wall when it runs out.] 5. [[[[[sArms Mimicry] (Level 35) Cost:100 Gives you an additional set of arms for a time. tome-235-src/lib/help/lua_skil.txt0000644000076400017500000004111211012107760014724 0ustar dgdg|||||oy #####R /----------------------------------------\ #####R < Adding new skill-based powers > #####R \----------------------------------------/ #####R=== Introduction === This is very much in the same vein as adding a racial/extra power, but has to be tied into skills, and we're defining more than one spell at once. You should have read the *****lua_intr.txt*0[scripting introduction] and *****lua_pow.txt*0[racial power tutorial] before going much further. Both of the above files contain some fairly fundamental information which you will find necessary for full understanding of this file. #####R=== Getting started === Open construc.lua (you have downloaded the example scripts from [[[[[Ghttp://www.moppy.co.uk/angband.htm], haven't you?). The idea behind this script is that it adds a skill which affects you ability to build/knock down stuff. It treats the equivalent of stone-to-mud and trap-door destruction spells as if they were "building skills". It also adds quite a few high-level 'spells' which do funky things like carving out corridors and chambers in a single turn, and building doors and stuff. Just think of it as if the person who has plenty of skills in this area would be a builder-type with lots of strength and constitution... In order to add these powers we're going to edit the s_info.txt file which lives in the edit folder, and add a new skill, underneath the 'misc' tree, called construction. The powers will then be accessed through the 'm' menu, in a similar way to mindcraft or alchemy skills or such. (That is, no books are needed to cast them, as we're treating them as a craft that has been learnt, rather than spells.) Our fist line of the script file reads: #####BSKILL_CONSTRUCT = 57 This merely links the skill index that we'll be defining in s_info.txt to this file. We'll come back to this at the end of the tutorial. #####Bconstructor_powers = add_magic In a similar way to the [[[[[Badd_power] function we called when we added the Phoenix racial ability, this line calls a special function which we use to define new skills. It follows a very specific, but easy to understand form. It starts with a brace, which indicates the add_magic function will be storing these values in a table. Don't worry about this too much, but understand that a table starts and ends with braces [[[[[B{] and [[[[[B}] respectively. Each key (or field name) takes the format [[[[[B"key" = value,] (the comma is important!). #####B ["fail"] = function() #####B msg_print("You decide now is a good time for a cuppa") #####B end, #####B ["stat"] = A_STR, #####B ["get_level"] = function() #####B return get_skill_scale(SKILL_CONSTRUCT, 50) #####B end, #####B ["spell_list"] = [[[[[B"fail"] is a function that is called whenever you ##fail to cast the spells##. Here it does nothing spectacular. [[[[[B"stat"] defines the stat used to cast the spells. Here it is strength. Any other stat can be used, prefix it with [[[[[BA_]. [[[[[B"get_level"] is used to determine the level of the spell. It's associated with spells that increase in power the more points that are invested in the associated skill. I know that's not terribly clear, I'll come back to it in a moment. [[[[[B"spell_list"] is just that, a list of all the spells. Each of these four properties within the table must end with a comma. If a function is defined in the property itself then we add the comma after the closing [[[[[Bend]. Again compare with construct.lua to see it. Any line NOT ending with a comma will cause a lua error on startup, probably of the type [[[[[V'}' expected to close '{' at line .] #####R=== The spell list === Each spell, within the [[[[[B"spell_list"] key has its own set of properties that we need to define from a sub-table so we open another set of braces to start the spell list, and then a third set of braces to start the first spell. So with all this, our first spell looks like: #####B ["spell_list"] = #####B { #####B { #####B ["name"] = #####B ["desc"] = #####B ["mana"] = #####B ["level"] = #####B ["fail"] = #####B ["spell"] = #####B ["info"] = #####B }, [[[[[B"name"] is, as you would expect, the name of the spell, as you want it to appear in the spell list when choosing a spell. The maximum number of characters for this is 29. [[[[[B"desc"] is the description received when you hit the capital letter of that spell in the menu. (i.e., press 'a' to cast the first spell, but press 'A' to receive info about the first spell. [[[[[B"mana"] is the amount of mana required to cast the spell. [[[[[B"level"] is the level required to use that spell (that's level of the (in this case construction) skill, not character level!). [[[[[B"fail"] is base fail rate. [[[[[B"spell"] is the function that is executed when the spell is cast. Note that it MUST take the form [[[[[Bfunction() blah end] even if you're calling a C function directly. If you have a look at the end of the file, you'll see the "rebuild dungeon" spell which is identical to the "alter_reality" spell. However, rather than reading [[[[[B"spell" = alter_reality()], it reads: #####B["spell"] = function() #####B alter_reality() #####Bend, which appears to be a long way round to do the same thing, but this is how it must be done. In a similar way, the [[[[[B"info"] key must begin with a [[[[[Bfunction()] and return the value of what is to be displayed alongside the spell name, level and mana in the spell list. The maximum number of characters that can be displayed here is dependent on the width of the user's screen, but try to keep it under 12 if you can, as this will fit in a standard 80x24 terminal screen. The first character will need to be a space otherwise you'll have the info line squashed right up against the fail rate and it will look odd. If you wish to have this part blank in the spell list, you still need to return a value, so just a single space will do : [[[[[Breturn " "] All of these keys are repeated for each spell, with each spell in its own table (therefore, it's own set of braces). Again, check the lua file for clarification. When entering the spells in the "spell_list", you must take care to specify them in the order which they are gained, otherwise they display incorrectly in the spell list. You should by now be experienced enough to understand most of what's going on in the actual spell functions (especially if you dig around in the source a bit, and check out Chris Hadgis' excellent *****lua_spel.txt*0[spell.pkg] helper files. I'm not going to go through the whole file line by line, as this is something you should do yourself, figuring out what's going on. I'm going to examine a few of the things we haven't covered before though, so pay attention. #####R=== The get_level() function === Probably one of the most important functions that you see reappearing in the file is the [[[[[Bget_level()] function. All this does is return the numerical value of the power that is given as the first argument. So [[[[[Bget_level] [[[[[B(constructor_power)] will return the current level of the constructor power. Given that the level of this is taken directly from the construction skill, (we defined that in the [[[[[B"get_level"] key, by saying [[[[[Bget_skill_scale] [[[[[B(SKILL_CONSTRUCT, 50)] ) it will return the value of your construction skill. [[[[[Bconstructor_power] is the name of the whole power, we named it thus on the second line of the script! [[[[[Bget_level] takes the following arguments: [[[[[Bget_level(power, max, ] [[[[[Bmin)]. The power is obviously which power we're taking the value from, and the max and min allow you to define boundaries for the spell. For instance the current maximum value that [[[[[Bget_level(constructor_power)] can return is 50, as that is the maximum number of skill points you can have in that skill. If you were using this as the basis for the damage of a low-level bolt spell, you might decide that having a damage of 50 would be too much (unlikely, but still possible). You could therefore define a maximum value of 20 so that when the value of the construction skill was over 50, the maximum value for damage of that spell would be 20. To achieve this you'd have: [[[[[Bget_level(constructor_power, 20)]. In a similar way, you can force the minimum value of the spell to be higher than the actual construction skill level, with a [[[[[Bget_level(constructor_power, 50, 15)]. This would be useful say for spells that you wanted to be available when the construction skill level reaches 10, but for whom you wanted a (for example) base damage of 15 right from the word go. These re-scale values rather than capping them! You can leave out the minimum value as I have done above. You can also leave the maximum value out (it will default to 50). If you want to specify a minimum value though, you MUST specify a maximum value as well. As you have hopefully been able to tell, the [[[[[Bget_level()] function enables us to have spells that increase in usefulness as you gain levels. Let's take the "Dismantle" spell. The function in the [[[[[B"spell"] key is as follows: #####Bfunction() #####B local ret, dir, dam #####B if (get_level(constructor_powers, 50) >= 11) then #####B ret, dir = get_aim_dir(); #####B if (ret == FALSE) then return end #####B fire_beam(GF_KILL_TRAP, dir, 1) #####B else #####B fire_ball(GF_KILL_TRAP, 0, 1, 1) #####B end #####Bend, The [[[[[Bif] statement is obviously what really interests us here. You'll notice that this has the amendment of an [[[[[Belse] clause, which the [[[[[Bif] statement we used in the previous tutorial did not. As you would expect, if the condition on the first line of this statement is met, then the instructions immediately below it are carried out. If the condition is not met, then the statements that follow the [[[[[Belse] are executed. Coming back to the [[[[[Bget_level] function, we learnt from above, that the [[[[[Bget_level] part of this function translates as, "if the value of the construction_power level (which happens to be identical to the construction skill level) is greater than or equal to 11, cast a beam of trap disarming in the specified direction. (The first part of this is all straightforward, getting a direction, and cancelling correctly if the player presses 'ESC'.) Otherwise, cast a ball of trap disarming with a radius of one, centred on the player." In the same way, as you look at the construc.lua file, you will see that [[[[[Bget_level()] is used many times in this way, to increase the power of detection spells, to change bolt spells to ball spells, to keep a constantly increasing damage going, and so on. #####R=== Elseif's and things === If you want to provide more than one alternative condition, in an [[[[[Bif-then-else] statement, you can use [[[[[Belseif]s which do what you might expect. Take a look at the first spell, "Survey area", for an example of this: #####Bif (get_level(constructor_powers, 50) >= 28) then #####B wiz_lite() #####Belseif (get_level(constructor_powers, 50) >= 15) then #####B map_area() #####B detect_traps(DEFAULT_RADIUS) #####Belseif (get_level(constructor_powers, 50) >= 5) then #####B detect_traps(DEFAULT_RADIUS) #####B detect_stairs(DEFAULT_RADIUS) #####B detect_doors(DEFAULT_RADIUS) #####Belse #####B detect_stairs(DEFAULT_RADIUS) #####B detect_doors(DEFAULT_RADIUS) #####Bend If the level of constructor powers is greater or equal to 28, then the function [[[[[Bwiz_lite()] is performed, and no other part of the if statement is executed. [[[[[Bwiz_lite()] is just the enlightenment spell. If it is less than 28, the next condition is examined: that if the level of constructor powers is greater than or equal to 15, then [[[[[Bmap_area()](Magic mapping) and detect traps are called. If the level of constructor power is less than 15, it moves onto the next condition, which says that if the level of constructor power is greater than 5, then detect stairs, traps and doors. If none of these conditions are met,(that is, if the level of construction skill is less than 5) then we just detect doors and stairs. You'll note that each of the detection spells includes a DEFAULT_RADIUS constant. You could change this to a numerical value, or a variable defined somewhere else in your script. eg [[[[[Bdetect_traps(2)] would detect traps with a radius of 2 centred on the player. #####R=== Registering the skill type === This is what we do at the end of the file, and is what ties the powers we've defined to the action of pressing the 'm' key in game. Once more we're calling a special function [[[[[Badd_mkey()] which takes its arguments for a table. There are only two keys in this table though which keeps things simple. #####Badd_mkey #####B{ #####B ["mkey"] = MKEY_CONSTRUCT_POWERS, #####B ["fct"] = function() #####B execute_magic(constructor_powers) #####B energy_use = energy_use + 100; #####B end #####B} [[[[[B"mkey"] must be a UNIQUE value > 1000 . Here I've defined it as a constant, [[[[[BMKEY_CONSTRUCT_POWERS], which has the value 1004. This value we'll call again in the s_info.txt file. [[[[[B"fct"] is the function that's called when the user presses the key in the 'm' menu. So here, it calls the [[[[[Bexecute_magic] function which actually displays a list of powers for the user to choose from. The argument it takes is the powers it will use (alchemy, mindcraft, etc., or in this case constructor), and then the [[[[[Benergy_use] line tells the game to take one game turn to do the action. #####R=== Adding the skill in s_info.txt === Take a look in the s_info.txt file, under the Misc section. You'll see, #####BN:57:Construction #####BD:Ability to use constructor powers #####BD:Construction powers use strength #####BA:1004:Build or knock down stuff #####BI:1000 The first line is the index of the skill; again this must be unique. The second property is the name of the skill. The [[[[[BD] lines are the lines displayed when the skill is highlighted in the skill screen. The first entry on the [[[[[BA] line is the value of the [[[[[B"mkey"] we defined in the [[[[[Badd_mkey] function in our script. The second entry is the display for selecting the construction power in the 'm' menu. The [[[[[BI] line is currently unused, but add a 1000 there anyway. That's what all the others have so when it's introduced, at least it will affect your powers identically to how it affects all the other powers. If you scroll to the very bottom of the file now, you'll see I've placed the skill at the bottom of the Misc branch of the skills tree. I then made a new class, constructor, which you can see in p_info.txt. That is all that is NEEDED when writing a script to add a skill - defining an mkey using add_mkey, and defining any powers that are called in the [[[[[B"fct"] (generally using [[[[[Badd_magic] ). And I've added the line #####Btome_dofile("construc.lua") in init.lua so the script is loaded on start-up! Below I'm going to talk in depth about a few other functions that you may find useful in your scripting. #####R=== fire_bolt() and fire_beam() === In the last help file we looked at the routine for firing a ball - [[[[[Bfire_ball()]. Here's a quick note about beams and bolts... [[[[[Bfire_beam()] and [[[[[Bfire_bolt()] take 2 arguments: [[[[[B(type, direction, damage)]. So in the dismantle spell we have the direction passed from [[[[[Bget_aim_dir()] (the function that asks the player for a direction), the type of damage is [[[[[BGF_KILL_TRAP], which as you might expect disarms traps. And the damage is only 1 because it's not going to hurt monsters, just dismantle traps. #####R=== set_oppose_elec() === OK here's another thing. Wander on down to the sparky_skills spell. After the appropriate bolt/ball is fired, we have the line: #####Bif player.oppose_elec == 0 then #####B set_oppose_elec(randint(10) + 20 + get_level(constructor_powers, 20)*3) #####Bend This is the bit that grants temporary resist electricity. We've called the function [[[[[Bset_oppose_elec(turns)], which sets the player's resist electricity to "on" for the time specified in the argument "turns". We're only calling this if the player is not already granted temporary resist electricity, and we've linked the number of turns it is active to the level of the construction skill. I've limited the maximum value of get_level to 20 in this instance. A similar idea can be used for temporarily granting levitation, extended infravision, protection against evil, resist fire, stuns, cuts and so on and so on. Have a look in player.pkg in the source for a full list.... [[[[[gThis file by fearoffours (fearoffours@moppy.co.uk)] tome-235-src/lib/help/c_runecr.txt0000644000076400017500000001106111012107760014721 0ustar dgdg~~~~~01|Runecrafter ~~~~~02|Classes|Runecrafter #####R=== Runecrafters === #####GDescription Instead of using spellbooks like the other spellcasters they instead use mystic runes. To cast a spell they select a primary rune of the elements (fire, cold, etc.) and they also choose a set of secondary runes, which shape the effect of the first one. The secondary runes include Self, Arrow, Ray, ... and Armageddon. After that they chose the amount of mana to use and the spell is cast! But the more secondary runes they chose the more mana is used to cast the spell. They also are bad fighters, but if they concentrate all their mana in one spell (especially with a mage staff of mana) they could kill nearly anything. #####GStarting Stat Modifiers Strength -5 Intelligence +3 Wisdom +0 Dexterity +1 Constitution -2 Charisma +1 Hit Die +d0 Spell Points +50% Exp Penalty 30% #####GStarting Skills: #####BSkill Start Level Skill Point Gains Combat 1.000 [0.200] Weaponmastery 0.700 [0.400] Sneakiness 1.000 [0.900] Stealth 0.000 [0.400] Magic 2.000 [0.950] Magic-Device 1.000 [1.200] Spell-power 0.000 [0.600] Mana 1.000 [0.600] Geomancy Fire 0.000 [0.700] Water 0.000 [0.700] Air 0.000 [0.700] Earth 0.000 [0.700] Meta 0.000 [0.700] Conveyance 0.000 [0.700] Divination 0.000 [0.700] Temporal 0.000 [0.700] Mind 0.000 [0.700] Nature 0.000 [0.700] Necromancy 0.000 [0.700] Runecraft 1.000 [1.000] Thaumaturgy 0.000 [0.700] Spirituality 1.000 [0.550] Prayer 0.000 [0.500] Monster-lore 0.000 [0.500] *A Runecrafter cannot learn the Geomancy skill, but it is shown in his skill screen because the elemental schools are sub-skills of it. #####GInnate Abilities: #####BAbility Character level Perfect casting 1 ~~~~~03|Runecrafter|Runecrafter powers ~~~~~04|Skills|Runecrafting - Runecrafter powers #####GRune Magic Runecrafters combine runes using the 'm' command. They first select a rune that controls magic type, then apply one or more runes to fine-tune effects, (pressing ESC when done), and then input the amount of mana they wish to expend on the spell. Runecrafters can cast the spells from their runes in several ways: 1. On-the-fly by combining runes when they need them. 2. Memorise rune combinations for quick use when needed (and they don't need to be able to see then!), and then later cast from memory. 3. Carving them into a Runestone, then using the Runestone later (takes less mana, but they have to be able to see). [[[[[BSpell Types:] (Some kinds are not listed, and are left for the reader to discover...) Knowledge: Identify all objects in affected grids, Self-knowledge if Self rune is used. Life: Heals monsters in affected grids, heals player if Self rune is used. Fire, Cold, Lightning, Acid: Casts magics of that element. Elements: Irresistible damage. Mind: A mind blast that badly effects intelligent monsters. Temporary ESP if Self rune is used. Gravity: A gravity spell that both does damage and whisks affected creatures around. [[[[[BSpell Effects] (all are listed): Self: Effects the caster. This rune can be used with any other; if used alone, only the caster's grid is affected. Arrow: Spell will include a bolt effect. This allows aiming. Ray: Spell will include a beam effect. This allows aiming. Increases difficulty slightly. Sphere: Spell will end with a circular explosion. Increases difficulty a bit. Can be used alone, or with Self, Arrow, or Ray. Power Surge: Not currently recommended for use. Increases difficulty a lot. Armageddon: Hurls down meteors of the magical type in the vicinity of the caster. Increases difficulty noticeably, but can do a great deal of damage. #####GStarting Equipment A Runecrafter begins the game with: a Rune [Fire] a Rune [Arrow] a Dagger tome-235-src/lib/help/rm_lsoul.txt0000644000076400017500000000166311012107760014764 0ustar dgdg~~~~~01|Lost Soul ~~~~~02|Race Modifiers|Lost Soul #####R=== LostSoul === #####GDescription #####RThis is a difficult modifier. Your character will almost always die quickly. #####RIt's probably best only to play it after you have some experience with normal #####Rcharacters. There are haunting whispers of souls that have come back from the Halls of Mandos, for purposes unknown. These are called Lost Souls, for it is presumed that their real body died off long ago, leaving only a soul to wander forever... or until killed again. Lost Souls start at level 98 of the Halls of Mandos. Very few ever make it out again. Those that do can continue as a fairly normal character, but with the advantage of any treasure and experience gained. #####GStat Modifiers No changes to stats. #####GStarting Equipment A Lost Soul starts the game with: Some torches. Over thirty scrolls of Identify. Over twenty scrolls of Satisfy Hunger. tome-235-src/lib/help/spoil_faq.txt0000644000076400017500000000745511012107760015112 0ustar dgdg|||||oy ~~~~~01|Help|Spoiled FAQ ~~~~~02|FAQ - contains spoilers #####R ToME Spoiler FAQ #####R Updated for version 2.3.x #####G------------------------------------------------------------------------------ This page contains significant spoilers. Don't browse it unless you want some parts of the game ruined, but don't expect the spoilers to spoil you completely! ~~~~~06|Spoilers|Merton the lost Hobbit quest #####G------------------------------------------------------------------------------ #####GQ: I'm in the Maze, but I cannot find Merton! A: Merton appears on a *random* level between dungeon level 26 (1300') and 36 (1800'). Each maze level is one panel by one panel in size, but *full* of passageways - so you may have to do quite a bit of tunnelling to search the whole level. #####G------------------------------------------------------------------------------ #####GQ: I've found Merton, now what? A: There is a new command that has been added to ToME that allows you to pass objects to creatures. What would you try and do if you had a broken leg and needed to get back to the town? ~~~~~07|Spoilers|Lothlorien Poisoned water quest #####G------------------------------------------------------------------------------ #####GQ: I'm trying to find the Poisoned water quest at Lothlorien, but cannot #####G find the quest entrance! A: This quest is located in the wilderness. To the west of Lothlorien are 4 water squares in an upside down L shape. One of these squares will contain the quest. (Viewed from the Wilderness map). There is no yellow > sign, so don't bother looking for one. ~~~~~20|Spoilers|God Quest - directions ~~~~~23|Gods|Quest - Spoilers #####G------------------------------------------------------------------------------ #####GQ: I've been given directions to a temple by my God but can't find the #####G temple anywhere! A: It [[[[[BIS] there. However, your god's idea of compass directions that are not directly on the 4 main axes are probably slightly less acurate than your idea. In other words, if your god says it is South-East, s/he means it is somewhere in the quadrant that is between the south and east axes. ~~~~~21|Spoilers|God Quest - relic #####G------------------------------------------------------------------------------ #####GQ: Where is the relic by god was talking about? I've looked in the lost #####G temple and can't find it anywhere! A: It [[[[[BIS] there. However, when your god told you to look for it VERY carefully, s/he meant it. Regardless of your game settings, the relic will only be created once in the temple, at a random place. If you have searched the whole temple once over, and not located it, then you have missed it, and it is lost forever. Each temple has 5 dungeon levels, and the relic might be on any of these 5 levels. ~~~~~22|Spoilers|God Quest - how many? #####G------------------------------------------------------------------------------ #####GQ: Apparently my god has lost another piece of his relic and wants me to go #####G find it again. How many of these are there? A: You can receive up to five god quests, with the final piece yielding an extra reward. However you will only receive extra quests if you have sucessfully completed all the previous ones. ~~~~~19|Deathmolds on Mount Doom and other quest areas. #####G------------------------------------------------------------------------------ #####GQ: How do I complete the special no-teleport level quests with a Deathmold? A: You will need either some morphic oils, some mimicry skill, or the ring of Flare. Deathmolds are marked as experimental for a reason you know. Morphic oils can also help if you're having trouble communictaing with monsters. A very beautiful Elf springs to mind as possibly causing some problems if you are in Deathmold form. tome-235-src/lib/help/r_wodelf.txt0000644000076400017500000000243411012107760014726 0ustar dgdg~~~~~01|Wood Elf ~~~~~02|Races|Wood Elf #####R=== Wood Elves === #####GDescription The first love of Wood Elves is hunting. As such, their skill with the bow is unparalleled. They train tirelessly with their bows, to the point of neglecting even melee skills. They resist light as with other elves, and do extra damage with a ranged weapon. They are almost custom made for the archer class, but also make interesting warriors. Even Wood Elf Mages are feasible, using the bow to attack and saving their magic for defence. #####GStat Modifiers Strength -3 Intelligence +2 Wisdom +1 Dexterity +5 Constitution -4 Charisma +1 Hit Dice Sides 7 Exp Penalty +30% #####GRacial Skill Modifiers: #####BSkill Start Mod Skill Point Gains Mod Combat Weaponmastery -2.500 [0.000] Archery 4.000 [0.000] Sneakiness 0.800 [0.000] Stealth 5.000 [0.000] Disarming 0.500 [0.000] Magic Magic-Device 0.600 [0.000] Spirituality 4.000 [0.000] #####GInnate Abilities: #####BAbility Character level Tree-walking 1 tome-235-src/lib/help/c_priest.txt0000644000076400017500000000044611012107760014736 0ustar dgdg|||||oy ~~~~~01|Priests #####R=== Priests === #####GDescription There are 6 separate classes of Priest: *****c_pr_eru.txt*0[Priest(Eru)] *****c_pr_man.txt*0[Priest(Manwe)] *****c_druid.txt*0[Druid] *****c_palad.txt*0[Paladin] *****c_pr_drk.txt*0[Dark-Priest] *****c_mindcr.txt*0[Mindcrafter] tome-235-src/lib/help/head.aux0000644000076400017500000000072311012107760014003 0ustar dgdg T.o.M.E. Documentation


tome-235-src/lib/help/birth.txt0000644000076400017500000010104111012107760014227 0ustar  dgdg|||||oy
~~~~~84|Birth
~~~~~11|Character
#####R             /----------------------------------------\
#####R            <           Creating a Character           >
#####R             \----------------------------------------/

     *****birth.txt*01[Creating a Character]            *****birth.txt*02[Character Characteristics]
     *****birth.txt*03[Races]                           *****birth.txt*04[Race Modifiers]
     *****birth.txt*05[Classes]                         *****birth.txt*83[Gods]
     *****birth.txt*06[Stats]                           *****birth.txt*07[Abilities]                     
     *****birth.txt*08[Combinations of Race and Class]  *****birth.txt*09[Stat bonus tables]

~~~~~01|Character|Creating a Character
~~~~~12|Creating a Character
#####R=== Creating a Character ===

ToME is a roleplaying game, in which you, the player, control a
character in the various dungeons and places of Arda. Perhaps the most
important thing you control is the birth of your character, in which you
choose or allow to be chosen various attributes that will affect the future
life of your character.

Character creation, or birth, is controlled through a variety of choices
as to constraints on the type of character you wish to play, followed by
a series of random calculations to generate ("roll up") a random character
matching the appropriate constraints.

Once your character has been generated, you will be given the choice to
generate a new character obeying the same constraints, and once you have
generated more than one character, you can switch back and forth between
the two most recent characters, until you are presented with a personality
that you feel comfortable with.

You may start the entire process over at any time.

Once you have accepted a character you will asked to provide a name for the
character. In general, the actual choice of a name is not important, but do
keep in mind that it may have some effect on the game itself. For example,
on some machines, the character name determines the filename that will be
used to save the character to disk. On others, the character name specifies
special "pref" files. And the character name is used on the high score list.

~~~~~02|Character|Characteristics
~~~~~13|Character|Stats 1
~~~~~14|Stats|Display
~~~~~37|Display
~~~~~82|Stats
#####R=== Character Characteristics ===

Each character has four primary attributes -- gender, race, race modifier and
class -- that are chosen before the character is generated, and all but gender
stay fixed for the entire life of that character. These attributes have many
effects, which will be mentioned as they come up. Keep in mind that in the
current version of ToME, your choice of race may restrict your choice
of class.

Each character has a few secondary attributes -- height, weight, social class,
and background history -- which are randomly determined, but which are affected
by the gender and race of the character. In general, these attributes are only
used to provide "flavor" to the character, to assist in the role playing, but
they do have a few minor effects on the game. For example, background history
affects social class, which affects the amount of money the character will
start with. 

Each character also has six primary "stats": strength (STR), intelligence 
(INT), wisdom (WIS), dexterity (DEX), constitution (CON), and charisma (CHR).

By default, primary statistics are represented in a linear way rather than a 
percentile way. You can change to percentile via the game option sequence '=', 
'5' (ToME options), arrow down to 'stats are represented in a linear way', and 
type 'n' for no. Don't forget to save your options when you are done.

These stats modify the abilities of the character in a variety of ways. Every 
stat has a numerical value, ranging from a minimum of 3, up to a normal maximum 
of 18, and even higher, into the "percentile" range, represented as "18/01" 
through "18/100". Actually, every stat can be raised even above 18/100 by 
magical means, up to a pure maximum of 18/220, which is represented as 
"18/***". Traditionally, a percentile stat such as "18/50" has been though of 
as representing a value part way between 18 and 19, and this is one way to 
think of them. However, often, the best way to view the "bonus" values after 
the "18/" is as "tenth" points, since it often takes the same magic to raise a 
stat from, say, 4 to 5, or 16 to 17, as it does from, say, 18/40 to 18/50. The
important thing to remember is that almost all internal calculations "ignore" 
the final digit of any "bonus", so that, for example, "18/40" and "18/49" 
generally have the same effects. During character generation, each stat is
rolled out as a number from 8 to 17, with a normal (bell-curve) distribution,
and is then immediately modified based on the race and class of the character.

Each character also has several primary "skills" -- disarming, magic devices,
saving throws, stealth, searching ability, searching frequency, fighting skill,
and shooting skill -- which are derived from the character's race, class, level,
stats, and current equipment. These skills have rather obvious effects, but
will be described more completely below.

Each character may have one or more "intrinsic racial skills", based on
the race of the character. These may include special resistances, abilities
such as infravision, or even activatable powers such as food creation.
~~~~~16|Gold
~~~~~81|Abbreviations
~~~~~17|Abbreviations|AU
~~~~~18|Money
Money in ToME is referred to in gold pieces, also frequently abbreviated as AU 
(the chemical symbol for gold).

Each character starts with some gold, which can be used to buy items from the 
shops in town. Additionally, gold can be obtained by several means:

    * selling items you have, or find, to the shops
    * taking it from dead monsters
    * finding it lying around on the floor in the dungeon
    * digging it out of the walls in certain dungeons

Each character starts out with some gold. The amount you start with is based on 
social class (higher is better), charisma (higher is better), and some other 
stats (less powerful characters start with more gold). 
~~~~~85|Inventory - starting info
Inventory is what you are carrying and/or wearing at the moment. All items you 
carry/wear have a certain weight. If the weight is very heavy for your 
strength, it can slow you down, and that is not a good thing for your 
character's continuing health. When your character is first created, all items 
you are granted upon creation will be in your inventory. Sometimes starting 
inventory includes something other than a weapon or armor (for example, a light 
source, scroll, potion, or food.)
~~~~~86|Weapons - starting info
Some characters start with a weapon. If yours does, you will need to 'w'ield it 
in order to gain its attack capabilities.
~~~~~23|Character|Armor Class
~~~~~19|Armor|Armor Class
~~~~~20|Abbreviations|AC
#####R === Armour Class ===
Each character has an armor class, representing how well the character can 
avoid damage. The armor class is affected by dexterity, the equipment, and 
sometimes the race. The higher the AC, the better.

The numbers following a piece of armor's name indicate how good it is. A Metal 
Cap [3,+0] is not as good as an Iron Helm [5,+0], AC-wise, since the 5 is a 
bigger number than the 3. On the other hand, an Iron Helm is heavier than a 
Metal Cap, and that may make a difference to you.

The plusses following the first number (e.g. the +0) indicate a magical bonus. 
If the plus number is more than zero, it should be added on to the base 
number. E.g. a Metal Cap [3,+3] has a higher AC than an Iron Helm [5,+0].

Some characters start with armor. If yours does, you need will need to 'w'ield 
it in order to gain its protection. 
~~~~~21|Abbreviations|HP
~~~~~22|Character|Hit Points
Each character has hit points (HP), representing how much damage the character
can sustain before death. Hit points are derived from your race, class,
level, and constitution, and can be temporarily boosted by magical means.
Hit points may be regained by resting, or by a variety of magical means.
~~~~~24|Abbreviations|SN
~~~~~25|Character|Sanity Points
Each character has sanity points (SN), representing how much mental damage the
character can sustain before death. Sanity points are derived from your wisdom
and character level. Sanity points may only be regained by magical means and 
won't be regained by resting.
~~~~~26|Abbreviations|SP
~~~~~27|Magic|Mana
~~~~~28|Character|Mana
Each character has a certain amount of mana. The amount of mana represents how
many spells of a certain difficulty a character can cast. When a spell is 
cast, you lose amount of mana corresponding to the 'cost' of the spell.

When all mana is gone, or the cost of a given spell is greater than the amount 
of mana you have left, you may attempt to cast a spell; beware, as there are
consequences to such a rash act.

Spell points may be regained by resting. They can also be restored by a few 
magical means.

Your spell points are derived from your Magic skill, player level and the 
greatest of INT and WIS.

Your total spell points are additionally affected by:

    * your character's race modifier
    * character class

Your total spell points may be affected by:

    * your encumbrance
    * what you wear

~~~~~29|Abbreviations|Pt
~~~~~30|Gods|Piety
~~~~~31|Character|Piety
Finally, characters that have chosen to follow a *****gods.txt*0[God] will have piety points
(Pt). These points represent the character's standing with their God, a 
standing which may rise or fall over time. A character may spend piety points 
to cast a spell granted by his/her God. Spent piety points can be regained in 
different fashions, depending on which God is involved -- each is pleased or 
displeased by assorted actions. Pleasing your God gains you piety, while 
displeasing your god will lose you piety.

In addition to forming the basis for God-granted spells, accumulated piety
points may also confer various benefits or penalties upon your character,
depending on the God involved.  For example, followers of Eru who have
accmulated lots of piety points gain a WIS bonus.  The actual rules are
quite specific to each God.
~~~~~03|Races
#####R=== Races ===

There are lots different races that you can choose from in ToME. Some
races are restricted as to what profession they may be, and each race has
its own adjustments to a character's stats and abilities. Most races also
have intrinsic abilities, which can be accessed via the "U" command (original
keyset, or "O" in the roguelike keyset).

     *****r_beorn.txt*0[Beorning]           *****r_hafelf.txt*0[Half-Elf]           *****r_orc.txt*0[Orc]
     *****r_drkelf.txt*0[Dark Elf]           *****r_hafogr.txt*0[Half-Ogre]          *****r_pettyd.txt*0[Petty-Dwarf]
     *****r_deathm.txt*0[Death Mold]         *****r_hielf.txt*0[High-Elf]           *****r_rohank.txt*0[Rohan Knight]
     *****r_dunad.txt*0[Dunadan]            *****r_hobbit.txt*0[Hobbit]             *****r_thlord.txt*0[Thunderlord]
     *****r_dwarf.txt*0[Dwarf]              *****r_human.txt*0[Human]              *****r_troll.txt*0[Troll]
     *****r_elf.txt*0[Elf]                *****r_kobold.txt*0[Kobold]             *****r_wodelf.txt*0[Wood Elf]
     *****r_ent.txt*0[Ent]                *****r_maia.txt*0[Maia]               *****r_yeek.txt*0[Yeek]
     *****r_gnome.txt*0[Gnome]

~~~~~04|Race Modifiers
#####R=== Race Modifiers ===

There are many different race modifiers from which you can choose in ToME.
Some are restricted as to what race they can be used with, and each one has
its own adjustments to a character's stats and abilities. Most also have
intrinsic abilities. If you are not asked for a race modifier, it is because
your race only supports the classical form.

     *****rm_class.txt*0[Classical]                *****rm_barb.txt*0[Barbarian]
     *****rm_herm.txt*0[Hermit]                   *****rm_lsoul.txt*0[Lost Soul]
     *****rm_skel.txt*0[Skeleton]                 *****rm_spec.txt*0[Spectre]
     *****rm_vamp.txt*0[Vampire]                  *****rm_zomb.txt*0[Zombie]

~~~~~05|Classes
#####R=== Classes ===

Once a race has been chosen, you will need to pick a class. Some classes will
not be available to certain races, for instance, a Troll cannot become a
Paladin. For the first few adventures it is suggested that you run a warrior
or rogue. Spell casting generally requires a more experienced player that is
familiar with survival techniques.

     *****c_alchem.txt*0[Alchemist]                 *****c_mage.txt*0[Mage]                     *****c_rogue.txt*0[Rogue]
     *****c_archer.txt*0[Archer]                    *****c_mimic.txt*0[Mimic]                    *****c_runecr.txt*0[Runecrafter]   
     *****c_assass.txt*0[Assassin]                  *****c_mindcr.txt*0[Mindcrafter]              *****c_sorcer.txt*0[Sorceror]       
     *****c_axemas.txt*0[Axemaster]                 *****c_monk.txt*0[Monk]                     *****c_summon.txt*0[Summoner]
     *****c_bard.txt*0[Bard]                      *****c_necro.txt*0[Necromancer]              *****c_swordm.txt*0[Swordmaster]
     *****c_pr_drk.txt*0[Dark-Priest]               *****c_palad.txt*0[Paladin]                  *****c_symbia.txt*0[Symbiant]
     *****c_demono.txt*0[Demonologist]              *****c_polear.txt*0[Polearmmaster]            *****c_thaum.txt*0[Thaumaturgist] 
     *****c_druid.txt*0[Druid]                     *****c_posses.txt*0[Possessor]                *****c_unbel.txt*0[Unbeliever]
     *****c_geoman.txt*0[Geomancer]                 *****c_pr_eru.txt*0[Priest(Eru)]              *****c_warper.txt*0[Warper]
     *****c_hafted.txt*0[Haftedmaster]              *****c_pr_man.txt*0[Priest(Manwe)]            *****c_warrio.txt*0[Warrior]
     *****c_lorema.txt*0[Loremaster]                *****c_ranger.txt*0[Ranger]                   
~~~~~83
#####R=== Gods ===

Once a class has been chosen you may be given the option to choose a god. Some 
classes (notably most Priests) will be given a God to worship automatically.   
Some classes are not necessarily suited to following a God, and Gods are not 
recommended for new players. You can also choose your mind about who (if 
anyone) to worship during the game by finding an *****tome_faq.txt*04[altar] of that God.

Read *****gods.txt*0[gods.txt] for a little more information about Gods.

    *****g_eru.txt*0[Eru Iluvatar]                  *****g_manwe.txt*0[Manwe Sulimo]
    *****g_yavann.txt*0[Yavanna Kementari]             *****g_tulkas.txt*0[Tulkas]
    *****g_melkor.txt*0[Melkor Bauglir]


~~~~~39|Character|Stats 2
~~~~~06|Stats|Individual explanations
#####R=== Stats ===
~~~~~32|Stats|Strength
~~~~~34|Strength
#####G          Strength (STR)
               Strength is important in fighting with weapons and in melee
               combat. A high strength can improve your chances of hitting
               as well as the amount of damage done with each hit. Char-
               acters with low strengths may receive penalties. Strength
               is also useful in tunnelling and in carrying heavy items.
~~~~~33|Stats|Intelligence
~~~~~35|Intelligence
#####G          Intelligence (INT)
               Intelligence affects the spellcasting abilities of mage-like
               spell schools (whether these spells are learned directly through
	       their associated skills, or indirectly through the Prayer
	       skill), as well as some of the special abilities of various
	       classes (e.g. Symbiants).  Intelligence will affect the number
               of spell points you receive. A high intelligence may also
	       improve your chances of successfully casting a spell. You cannot
	       learn spells if your intelligence is 7 or lower. A good
	       intelligence can also help with using magic devices, picking
	       locks, and disarming traps.
~~~~~36|Stats|Wisdom
~~~~~38|Wisdom
#####G          Wisdom (WIS)
               The primary function of wisdom is to determine the ability
               of a priest or paladin to use prayers (God-granted spells), just
	       like intelligence affects mage spells. Again, high wisdom will
	       increase the number of spell points you have (even though
	       prayers use piety points), and will improve the chance that a
	       prayer will be successful. A good wisdom can also help to
	       improve your chances of resisting magical spells cast
               upon you by monsters.
~~~~~40|Stats|Dexterity
~~~~~41|Dexterity
#####G          Dexterity (DEX)
               Dexterity is a combination of agility and quickness. A high
               dexterity may allow your character to get multiple blows with
               lighter weapons, thus greatly increasing your kill power, and
               will increase your chances of hitting with any weapon and
               dodging blows from enemies. Dexterity is also useful in
               picking locks, disarming traps, and protecting yourself from
               some of the thieves that inhabit the dungeons.  The unscrupulous
	       adventurer may also find dexterity effective in obtaining items
	       from stores without rendering payment.
~~~~~42|Stats|Constitution
~~~~~43|Constitution
#####G          Constitution (CON)
               Constitution is a character's ability to resist damage to his
               body, and to recover from damage received. Therefore a
               character with a high constitution will receive more hit
               points and also recover them faster while resting.
~~~~~44|Stats|Charisma
~~~~~45|Charisma
#####G          Charisma (CHR)
               Charisma represents a character's personality and physical
               appearance. A character with a high charisma will receive
               better prices from store owners, whereas a character with a
               very low charisma may be robbed blind. A high charisma will
               also mean more starting money for the character.
~~~~~07
~~~~~46|Character|Abilities
#####R=== Abilities ===

          Characters possess some different abilities which can help them
          to survive. The starting abilities of a character are based upon
          race and class. Abilities may be adjusted by high or low stats,
          and increase with the corresponding *****skills.txt*0[skill] level.
~~~~~48|Attacking monsters|Fighting ability
#####G          Fighting
               Fighting is the ability to hit and do damage with weapons or
               fists. Normally  a  character  gets  a single blow from any
               weapon, but if his dexterity and strength are  high  enough,
               he  may  receive  more blows per round with lighter weapons.
               Strength and dexterity both modify the  ability  to  hit  an
               opponent. This skill increases  with the *****skills.txt*02[Weaponmastery] skill
               and its sub-skills.
~~~~~50|Attacking monsters|Shooting
#####G          Shooting Ability  (Bows/Throw)
               Using  ranged  missile  weapons (and  throwing  objects) is
               included  in this skill. Different stats apply to different
               weapons, but this ability may modify the distance an  object
               is  thrown/fired, the amount of damage done, and the ability
               to hit a creature. This skill increases with the *****skills.txt*08[Archery] skill
               and its sub-skills.
~~~~~52|Saving throw
#####G          Saving Throw
               A Saving Throw is the ability of a character to  resist  the
               effects  of  a spell cast on him by another person/creature.
               This does not include spells cast on the player by  his  own
               stupidity, such  as  quaffing a nasty potion. This ability
               increases with the *****skills.txt*38[Spirituality] skill,
               A high wisdom also increases this  ability.
~~~~~54|Stealth
#####G          Stealth
               The ability to move  silently about is very useful. Charac-
               ters with good stealth can usually surprise their opponents,
               gaining the first blow. Also, creatures may fail to  notice
               a  stealthy  character  entirely, allowing a player to avoid
               certain fights. This skill is based upon race, class and the
               *****skills.txt*15[Stealth] skill.
~~~~~56|Disarming traps
#####G          Disarming
               Disarming is the  ability  to  remove  traps  (safely), and
               includes  picking  locks  on  traps and doors. A successful
               disarming will gain the character  some experience. A  trap
               must  be  found  before  it  can be disarmed. Dexterity and
               intelligence both modify the ability  to  disarm, and  this
               ability increases with the *****skills.txt*16[Disarming] skill.
~~~~~58|Magical Devices
#####G          Magic Device
               Using a magical device such as  a  wand  or  staff  requires
               experience  and  knowledge. Spell  users such as  magi  and
               priests are therefore much better at using a magical  device
               than say a warrior. This skill is modified by intelligence,
               and increases with the *****skills.txt*54[Magic-Device] skill.
~~~~~60|Searching
~~~~~61|Searching|Searching Frequency - Perception
~~~~~62|Perception
#####G          Searching Frequency (Perception)
               Perception  is  the  ability  to  notice  something  without
               actively  seeking it out. This  skill  is  based  upon  race,
               class and the *****skills.txt*14[Sneakiness] skill.
~~~~~63|Searching|Searching Ability
#####G          Searching Ability (Searching)
               To search is to actively look for secret doors, floor traps,
               and  traps on chests. Rogues are the best at searching, but
               magi, rangers, and priests are also good at it. This  skill
               is  based  upon  race, class and the *****skills.txt*14[Sneakiness] skill.
~~~~~66|Infra-vision
#####G          Infra-vision
               Infra-vision is the ability to see heat sources. Since most
               of the dungeon is cool or cold, infra-vision will not allow
               the player to see walls and objects. Infra-vision will allow
               a character to see any warm-blooded creatures up to a cer-
               tain distance. This ability works equally well with or with
               out a light source. The majority of ToME's creatures are
               cold-blooded, and will not be detected unless lit up by a
               light source. Most non-human races have innate infra-vision
               ability. Humans can gain infra-vision only through magic
               enhancement.

~~~~~08|Character|Race and Class Combinations
~~~~~67|Races|Combinations with class
~~~~~68|Classes|Combinations with Race
~~~~~69|Tables
~~~~~70|Tables|Combinations of Race and Class
#####R=== Combinations of Race and Class ===

These are the classes that are recommended for different races. You can
still select a race that is not in the chart, but these combinations are
either rather poor (like a zombie mage), a concept so silly that they
are not recommended, or an incredibly unfair combination of race and class.
If you pick a combination that is not on the chart, don't complain if things
don't turn out as you expected them to.

#####B            Warrior  Archer  Rogue  Mage   Priest  Loremaster
#####B
Beorning      Yes     No      Yes    No     No        Yes
Dark Elf      Yes     Yes     Yes    Yes    Yes       No
Death Mold    No      No      No     Yes    Yes       No
Dunadan       Yes     Yes     Yes    Yes    Yes       Yes
Dwarf         Yes     No      No     No     Yes       No
Elf           Yes     Yes     No     Yes    Yes       Yes
Ent           Yes     No      No     No     Yes       Yes
Gnome         Yes     No      Yes    Yes    No        No
Half-Elf      Yes     Yes     Yes    Yes    Yes       Yes
Half-Ogre     Yes     No      No     No     Yes       No
High-Elf      Yes     Yes     No     Yes    Yes       Yes
Hobbit        Yes     Yes     Yes    Yes    No        Yes
Human         Yes     Yes     Yes    Yes    Yes       Yes
Kobold        Yes     Yes     Yes    No     No        No
Maia          Yes     Yes     Yes    Yes    Yes       Yes
Orc           Yes     Yes     Yes    No     Yes       No
Petty Dwarf   Yes     No      Yes    No     No        No
RohanKnight   Yes     No      No     No     Yes       No
Thunderlord   Yes     Yes     No     Yes    Yes       No
Troll         Yes     No      No     No     No        No
Wood Elf      Yes     Yes     No     Yes    Yes       Yes
Yeek          Yes     Yes     Yes    Yes    Yes       Yes
~~~~~09|Character|Stat Bonus Table
~~~~~71|Stats|Bonus table
~~~~~72|Tables|Stat bonuses
#####R=== Stat Bonus Tables ===

Stat, hit dice, and experience points per level modifications due to race
are listed in the following table.
~~~~~75|Races|Stat Bonuses
#####GRaces:
#####B                       STR  INT  WIS  DEX  CON  CHR  Hit Dice  Rqd Exp/level
           Beorning    +4   -2   -2   -1   +3   -5      12         +50%
           Dark Elf    -1   +3   +2   +2   -2   +1       9         +50%
           Death Mold  +10   0   +10  +0   +10 -15      15         +150%
           Dunadan     +1   +2   +2   +2   +3   +2      10         +80%
           Dwarf       +2   -2   +2   -2   +2   -3      11         +25%
           Elf         -1   +2   +2   +1   -2   +2       8         +20%
           Ent         +10  -3   +2   -5   +11  -3      14         +110%
           Gnome       -1   +2    0   +2   +1   -2       8         +35%
           Half-Elf     0   +1   +1   +1   -1   +1       9         +10%
           Half-Ogre   +3   -1   -1   -1   +3   -3      12         +30%
           High-Elf    +1   +3   +2   +3   +1   +5      10         +100%
           Hobbit      -2   +2   +1   +3   +2   +1       7         +10%
           Human        0    0    0    0    0    0      10         +0%
           Kobold      +1   -1    0   +1    0   -4       9         +25%
           Maia         0    0    0    0    0    0      10         +0%
           Petty Dwarf +1   -1   +2    0   +2   -4      11         +35%
           Orc         +2   -1    0   +1   +1   -4      10         +10%
           RohanKnight +4   -2   +3   +1   +4   +2      10         +120%
           Thunderlord +6   +2   +1   +1   +3   +8      12         +300%
           Troll       +4   -4   -2   -4   +3   -6      12         +37%
           Wood Elf    -3   +2   +1   +5   -4   +1       7         +30%
           Yeek        -5   -5   -5   -5   -5   -5       6         -75%
~~~~~76|Race Modifiers|Stat Bonuses
#####GRace Modifiers:
#####B                       STR  INT  WIS  DEX  CON  CHR  Hit Dice  Rqd Exp/level
           Classical    0    0    0    0    0    0      +0         +0%
           Barbarian   +2   -3   -2   +1   +1   -3      +1         +25%
           Hermit      -3   +1   +1   -3   -3   +1      -3         +20%
           Lost Soul    0    0    0    0    0    0      +0         +0%
           Skeleton     0   -2   -2    0   +1   -4      +0         +45%
           Spectre     -5   +2   +2   +2   -3   -6      -4         +80%
           Vampire     +3   +2   -3   -2   +1   -4      +1         +100%
           Zombie      +2   -6   -6   +1   +4   -5      +3         +45%

~~~~~77|Classes|Stat Bonuses
#####GClasses:
#####B                         STR     INT     WIS     DEX     CON     CHR
           Axemaster     +5      -2      -2      +2      +2      -1
           Demonologist  +5      -2      -2      +2      +2      -1
           Haftedmaster  +5      -2      -2      +2      +2      -1                      
           Polearmmaster +5      -2      -2      +2      +2      -1
           Swordmaster   +5      -2      -2      +2      +2      -1
           Unbeliever    +5      -2      -2      +2      +2      -1
           Warrior       +5      -2      -2      +2      +2      -1

           Alchemist     -5      +3       0      +1      -2      +1
           Geomancer     -5      +3       0      +1      -2      +1
           Mage          -5      +3       0      +1      -2      +1
           Necromancer   -5      +3       0      +1      -2      +1
           Runecrafter   -5      +3       0      +1      -2      +1
           Sorceror      -5      +3       0      +1      -2      +1
           Thaumaturgist -5      +3       0      +1      -2      +1
           Warper        -5      +3       0      +1      -2      +1

           Archer        +2      +1       0      +2      +1      +1
           Ranger        +2      +2       0      +2      +1      +1

           Assassin      +2      +1      -2      +3      +1      -1
           Rogue         +2      +1      -2      +3      +1      -1

           Bard          +1      -2      +1      +1       0      +1
           Loremaster    +1      -2      +1      +1       0      +1
           Mimic         +1      -2      +1      +1       0      +1
           Monk          +1      -2      +1      +1       0      +1
           Possessor     +1      -2      +1      +1       0      +1
           Summoner      +1      -2      +1      +1       0      +1
           Symbiant      +1      -2      +1      +1       0      +1

           Dark-Priest   -1      -3      +3      -1       0      +2
           Druid         -1      -3      +3      -1       0      +2
           Mindcrafter   -1      -3      +3      -1       0      +2
           Paladin       -1      -3      +3      -1       0      +2
           Priest(Eru)   -1      -3      +3      -1       0      +2
           Priest(Manwe) -1      -3      +3      -1       0      +2
~~~~~10|Character|Skill tables
~~~~~74|Tables|Skill Tables
#####R=== Skill Tables ===

~~~~~78|Races|Skill table
#####GRaces:
#####B                         Disarm  Devices Sprtlty Stealth Sneak   Wepnmas Archery
           Beorning      -0.6    -0.8    -3.0    -2.0    -0.1    +2.5    +0.5
           Dark-Elf      +0.5    +1.5    +10.0   +3.0    +0.8    -0.5    +1.0
           DeathMold     +1.5    -0.5    +7.5    +25     0       +2.5    +2.5
           Dunadan       +0.4    +0.5    +2.5    +2.0    +0.8    +1.5    +1.0
           Dwarf         +0.2    +0.9    +5.0    -1.0    +0.7    +1.5    +0.5
           Elf           +0.5    +0.6    +3.0    +2.0    +0.8    -0.5    +1.5
           Ent           +0.5    +0.5    +10.0   -6.0    +0.5    -0.3    -0.2
           Gnome         +1.0    +1.2    +6.0    +3.0    +0.6    -0.8    +1.2
           Half-Elf      +0.2    +0.3    +1.5    +1.0    +0.6    -0.1    +0.5
           Half-Ogre     -0.3    -0.5    -2.5    -2.0    -0.1    +2.0    0
           High-Elf      +0.4    +2.0    +10.0   +4.0    +0.3    +1.0    +2.5
           Hobbit        +1.5    +1.8    +9.0    +5.0    +1.2    -1.0    +2.0
           Human         0       0       0       0       0       0       0
           Kobold        -0.2    -0.3    -1.0    -1.0    +0.1    +1.0    -0.8
           Maia          0       0       0       0       0       0       0
           Orc           -0.3    -0.3    -1.0    -1.0    0       +1.2    -0.5
           Petty Dwarf   +0.3    +0.5    +5.0    +1.0    +0.5    0       0
           RohanKnight   +1.0    +0.5    +2.5    -8.0    +0.1    +0.1    +0.5
           Thunderlord   +0.6    0       +5.0    -16.0   +3.0    +1.5    +0.5
           Troll         -0.5    -0.8    -4.0    -2.0    -0.1    +2.0    -1.0
           Wood-Elf      +0.5    +0.6    +3.0    +5.0    +0.8    -2.5    +4.0
           Yeek          -0.5    -0.5    -2.5    -5.0    -0.5    -0.5    -0.5

In addition to the racial starting bonuses for the standard skills listed
above, there are some special bonuses to the skill modifier:

	   Beorning     +1.0 Bearform-combat modifier (also 1.0 points to start)
	   Dark-Elf     +0.2 Magic modifier
	   DeathMold    +0.2 Necromancy modifier
	   Dwarf        +0.2 Axe-mastery modifier
	   Ent          +0.2 Barehand-combat modifier;
	                +0.6 Boulder-throwing modifier
           Hobbit       +0.3 Sling-mastery modifier
           Maia         Not allowed to use Prayer (modifier reduced to 0.000)
	   RohanKnight  +0.2 Weaponmastery modifier
	   Wood-Elf     +0.2 Archery modifier

(If the character's class does not normally possess the skill, this racial
modifier bonus will grant the skill at a starting level of 0.000.)

~~~~~79|Race Modifiers|Skill table
#####GRace Modifiers:
#####B                        Disarm  Devices Sprtlty Stealth Sneak   Wepnmas Archery
           Classical    0       0       0       0       0       0       0
           Barbarian    -0.2    -1.0    +0.2    -2.0    +0.0    +1.2    +0.5
           Hermit       +0.5    +1.0    +0.5    +3.0    +0.4    -0.5    -0.5
           Lost Soul    0       0       0       0       0       0       0
           Skeleton     -0.5    -0.5    +0.5    -1.0    -0.1    +0.8    0
           Spectre      +0.2    +0.8    +0.7    +2.0    +0.2    -0.5    -0.2
           Vampire      0       0       0       0       0       0       0
           Zombie       -0.2    -0.2    +0.5    -1.0    -0.1    +0.5    0
tome-235-src/lib/help/defines.txt0000644000076400017500000005724211012107760014551 0ustar  dgdg|||||oy
~~~~~81|Defines
~~~~~85|Defines|Tvals
~~~~~82|Automatizer|Defines
~~~~~83|Tvals
#####R             /----------------------------------------\
#####R            <             Tvals and svals              >
#####R             \----------------------------------------/

Some objects don't have svals as such. Spellbooks, wands, and staves for
instance don't have svalues as they are defined in lua.

TV_SKELETON      1      /* Skeletons ('s') */
TV_BOTTLE        2      /* Empty bottles ('!') */
*****defines.txt*04[TV_BATERIE]       4      /* For the Alchemists */
TV_SPIKE         5      /* Spikes ('~') */
TV_MSTAFF        6      /* Mage Staffs */
TV_CHEST         7      /* Chests ('~') */
TV_PARCHMENT     8      /* Parchments from Kamband */
*****defines.txt*09[TV_CORPSE]        9      /* Monster corpses */
TV_EGG          10      /* Monster Eggs */
TV_JUNK         11      /* Sticks, Pottery, etc ('~') */
*****defines.txt*12[TV_TOOL]         12      /* Tools */
*****defines.txt*14[TV_INSTRUMENT]   14      /* Musical instruments */
*****defines.txt*15[TV_BOOMERANG]    15      /* Boomerangs */
*****defines.txt*16[TV_SHOT]         16      /* Ammo for slings */
*****defines.txt*16[TV_ARROW]        17      /* Ammo for bows */
*****defines.txt*16[TV_BOLT]         18      /* Ammo for x-bows */
*****defines.txt*19[TV_BOW]          19      /* Slings/Bows/Xbows */
*****defines.txt*20[TV_DIGGING]      20      /* Shovels/Picks */
*****defines.txt*21[TV_HAFTED]       21      /* Priest Weapons */
*****defines.txt*22[TV_POLEARM]      22      /* Pikes/Glaives/Spears/etc. */
*****defines.txt*23[TV_SWORD]        23      /* Edged Weapons */
*****defines.txt*24[TV_AXE]          24      /* Axes/Cleavers */
*****defines.txt*30[TV_BOOTS]        30      /* Boots */
*****defines.txt*31[TV_GLOVES]       31      /* Gloves */
*****defines.txt*32[TV_HELM]         32      /* Helms */
*****defines.txt*32[TV_CROWN]        33      /* Crowns */
*****defines.txt*34[TV_SHIELD]       34      /* Shields */
*****defines.txt*35[TV_CLOAK]        35      /* Cloaks */
*****defines.txt*36[TV_SOFT_ARMOR]   36      /* Soft Armor */
*****defines.txt*37[TV_HARD_ARMOR]   37      /* Hard Armor */
*****defines.txt*38[TV_DRAG_ARMOR]   38      /* Dragon Scale Mail */
*****defines.txt*39[TV_LITE]         39      /* Lites (including Specials) */
*****defines.txt*40[TV_AMULET]       40      /* Amulets (including Specials) */
*****defines.txt*45[TV_RING]         45      /* Rings (including Specials) */
*****defines.txt*46[TV_TRAPKIT]      46      /* Trapkits */
TV_TOTEM        54      /* Summoner totems */
*****defines.txt*55[TV_STAFF]        55      /* Staffs */
*****defines.txt*65[TV_WAND]         65      /* Wands */
*****defines.txt*66[TV_ROD]          66      /* Rod tips */
*****defines.txt*67[TV_ROD_MAIN]     67      /* Rod body's */
*****defines.txt*70[TV_SCROLL]       70      /* Scrolls */
*****defines.txt*71[TV_POTION]       71      /* potions */
*****defines.txt*72[TV_POTION2]      72      /* Second set of potion */
TV_FLASK        77      /* Flasks of oil */
*****defines.txt*80[TV_FOOD]         80      /* Food, including mushrooms */
TV_HYPNOS       99      /* To wield monsters !:) */
TV_GOLD         100     /* Gold can only be picked up by players */
TV_RANDART      102     /* Random Artifacts */
TV_RUNE1        104     /* Base runes */
TV_RUNE2        105     /* Modifier runes */
TV_BOOK         111     /* spell books */
*****defines.txt*115[TV_DAEMON_BOOK]  115     /* Demon blades, shields and horns */
~~~~~84|Defines|Svals
~~~~~12|Svals
/* The "sval" codes for TV_TOOL */
 SV_TOOL_CLIMB 0
 SV_PORTABLE_HOLE 1
~~~~~16
/* The "sval" codes for TV_SHOT/TV_ARROW/TV_BOLT */
 SV_AMMO_LIGHT                    0	/* pebbles */
 SV_AMMO_NORMAL                   1	/* shots, arrows, bolts */
 SV_AMMO_HEAVY                    2	/* seeker arrows and bolts, mithril shots */
~~~~~14
/* The "sval" codes for TV_INSTRUMENT */
 SV_FLUTE                         1
 SV_BANJO                         2
 SV_LUTE                          3
 SV_MANDOLIN                      4
 SV_DRUM                          5
 SV_HARP                          6
 SV_HORN                          7
~~~~~46
/* The "sval" codes for TV_TRAPKIT */
 SV_TRAPKIT_SLING                 1
 SV_TRAPKIT_BOW                   2
 SV_TRAPKIT_XBOW                  3
 SV_TRAPKIT_POTION                4
 SV_TRAPKIT_SCROLL                5
 SV_TRAPKIT_DEVICE                6
~~~~~15
/* The "sval" codes for TV_BOOMERANG */
 SV_BOOM_S_WOOD                   1      /* 1d4  */
 SV_BOOM_WOOD                     2      /* 1d9  */
 SV_BOOM_S_METAL                  3      /* 1d8  */
 SV_BOOM_METAL                    4      /* 2d4  */
~~~~~19
/* The "sval" codes for TV_BOW (note information in "sval") */
 SV_SLING                         2	/* (x2) */
 SV_SHORT_BOW                    12	/* (x2) */
 SV_LONG_BOW                     13	/* (x3) */
 SV_LIGHT_XBOW                   23	/* (x3) */
 SV_HEAVY_XBOW                   24	/* (x4) */
~~~~~20
/* The "sval" codes for TV_DIGGING */
 SV_SHOVEL                        1
 SV_GNOMISH_SHOVEL                2
 SV_DWARVEN_SHOVEL                3
 SV_PICK                          4
 SV_ORCISH_PICK                   5
 SV_DWARVEN_PICK                  6
 SV_MATTOCK                       7
~~~~~21
/* The "sval" values for TV_HAFTED */
 SV_CLUB                          1	/* 1d4  */
 SV_WHIP                          2	/* 1d6  */
 SV_QUARTERSTAFF                  3	/* 1d9  */
 SV_NUNCHAKU                      4	/* 2d3  */
 SV_MACE                          5	/* 2d4  */
 SV_BALL_AND_CHAIN                6	/* 2d4  */
 SV_WAR_HAMMER                    8	/* 3d3  */
 SV_LUCERN_HAMMER                10	/* 2d5  */
 SV_THREE_PIECE_ROD              11	/* 3d3  */
 SV_MORNING_STAR                 12	/* 2d6  */
 SV_FLAIL                        13	/* 2d6  */
 SV_LEAD_FILLED_MACE             15	/* 3d4  */
 SV_TWO_HANDED_FLAIL             18	/* 3d6  */
 SV_GREAT_HAMMER                 19	/* 4d6  */
 SV_MACE_OF_DISRUPTION           20	/* 5d8  */
 SV_GROND                        50	/* 3d4  */
~~~~~24
/* The "sval" values for TV_AXE */
 SV_HATCHET                       1	/* 1d5 */
 SV_CLEAVER                       2      /* 2d4 */
 SV_LIGHT_WAR_AXE                 8      /* 2d5 */
 SV_BEAKED_AXE                   10	/* 2d6 */
 SV_BROAD_AXE                    11	/* 2d6 */
 SV_BATTLE_AXE                   22	/* 2d8 */
 SV_GREAT_AXE                    25	/* 4d4 */
 SV_LOCHABER_AXE                 28	/* 3d8 */
 SV_SLAUGHTER_AXE                30      /* 5d7 */
~~~~~22
/* The "sval" values for TV_POLEARM */
 SV_SPEAR                         2	/* 1d6 */
 SV_SICKLE                        3	/* 2d3 */
 SV_AWL_PIKE                      4	/* 1d8 */
 SV_TRIDENT                       5	/* 1d9 */
 SV_FAUCHARD                      6  /* 1d10 */
 SV_BROAD_SPEAR                   7	/* 1d9 */
 SV_PIKE                          8	/* 2d5 */
 SV_GLAIVE                       13	/* 2d6 */
 SV_HALBERD                      15	/* 3d4 */
 SV_GUISARME                     16  /* 2d5 */
 SV_SCYTHE                       17	/* 5d3 */
 SV_LANCE                        20	/* 2d8 */
 SV_TRIFURCATE_SPEAR             26	/* 2d9 */
 SV_HEAVY_LANCE                  29  /* 4d8 */
 SV_SCYTHE_OF_SLICING            30	/* 8d4 */
~~~~~23
/* The "sval" codes for TV_SWORD */
 SV_BROKEN_DAGGER                 1  /* 1d1 */
 SV_BROKEN_SWORD                  2  /* 1d2 */
 SV_DAGGER                        4  /* 1d4 */
 SV_MAIN_GAUCHE                   5  /* 1d5 */
 SV_RAPIER                        7  /* 1d6 */
 SV_SMALL_SWORD                   8  /* 1d6 */
 SV_BASILLARD                     9  /* 1d8 */
 SV_SHORT_SWORD                  10  /* 1d7 */
 SV_SABRE                        11  /* 1d7 */
 SV_CUTLASS                      12  /* 1d7 */
 SV_KHOPESH                      14  /* 2d4 */
 SV_TULWAR                       15  /* 2d4 */
 SV_BROAD_SWORD                  16  /* 2d5 */
 SV_LONG_SWORD                   17  /* 2d5 */
 SV_SCIMITAR                     18  /* 2d5 */
 SV_KATANA                       20  /* 3d4 */
 SV_BASTARD_SWORD                21  /* 3d4 */
 SV_GREAT_SCIMITAR               22  /* 4d5 */
 SV_CLAYMORE                     23  /* 2d8 */
 SV_ESPADON                      24  /* 2d9 */
 SV_TWO_HANDED_SWORD             25  /* 3d6 */
 SV_FLAMBERGE                    26  /* 3d7 */
 SV_EXECUTIONERS_SWORD           28  /* 4d5 */
 SV_ZWEIHANDER                   29  /* 4d6 */
 SV_BLADE_OF_CHAOS               30  /* 6d5 */
 SV_SHADOW_BLADE                 31  /* 4d4 */
 SV_BLUESTEEL_BLADE              32  /* 3d9 */
 SV_DARK_SWORD                   33  /* 3d7 */
~~~~~34
/* The "sval" codes for TV_SHIELD */
 SV_SMALL_LEATHER_SHIELD          2
 SV_SMALL_METAL_SHIELD            3
 SV_LARGE_LEATHER_SHIELD          4
 SV_LARGE_METAL_SHIELD            5
 SV_DRAGON_SHIELD                 6
 SV_SHIELD_OF_DEFLECTION         10
~~~~~32
/* The "sval" codes for TV_HELM */
 SV_HARD_LEATHER_CAP              2
 SV_METAL_CAP                     3
 SV_IRON_HELM                     5
 SV_STEEL_HELM                    6
 SV_DRAGON_HELM                   7
 SV_IRON_CROWN                   10
 SV_GOLDEN_CROWN                 11
 SV_JEWELED_CROWN                12
 SV_MORGOTH                      50
~~~~~30
/* The "sval" codes for TV_BOOTS */
 SV_PAIR_OF_SOFT_LEATHER_BOOTS    2
 SV_PAIR_OF_HARD_LEATHER_BOOTS    3
 SV_PAIR_OF_METAL_SHOD_BOOTS      6
~~~~~35
/* The "sval" codes for TV_CLOAK */
 SV_CLOAK                         1
 SV_ELVEN_CLOAK                   2
 SV_FUR_CLOAK                     3
 SV_SHADOW_CLOAK                  6
~~~~~31
/* The "sval" codes for TV_GLOVES */
 SV_SET_OF_LEATHER_GLOVES         1
 SV_SET_OF_GAUNTLETS              2
 SV_SET_OF_CESTI                  5
~~~~~36
/* The "sval" codes for TV_SOFT_ARMOR */
 SV_FILTHY_RAG                    1
 SV_ROBE                          2
 SV_PAPER_ARMOR                   3  /* 4 */
 SV_SOFT_LEATHER_ARMOR            4
 SV_SOFT_STUDDED_LEATHER          5
 SV_HARD_LEATHER_ARMOR            6
 SV_HARD_STUDDED_LEATHER          7
 SV_RHINO_HIDE_ARMOR              8
 SV_CORD_ARMOR                    9  /*  6 */
 SV_PADDED_ARMOR                 10  /*  4 */
 SV_LEATHER_SCALE_MAIL           11
 SV_LEATHER_JACK                 12
 SV_STONE_AND_HIDE_ARMOR         15  /* 15 */
 SV_THUNDERLORD_SUIT             16
~~~~~37
/* The "sval" codes for TV_HARD_ARMOR */
 SV_RUSTY_CHAIN_MAIL              1  /* 14- */
 SV_RING_MAIL                     2  /* 12  */
 SV_METAL_SCALE_MAIL              3  /* 13  */
 SV_CHAIN_MAIL                    4  /* 14  */
 SV_DOUBLE_RING_MAIL              5  /* 15  */
 SV_AUGMENTED_CHAIN_MAIL          6  /* 16  */
 SV_DOUBLE_CHAIN_MAIL             7  /* 16  */
 SV_BAR_CHAIN_MAIL                8  /* 18  */
 SV_METAL_BRIGANDINE_ARMOUR       9  /* 19  */
 SV_SPLINT_MAIL                  10  /* 19  */
 SV_PARTIAL_PLATE_ARMOUR         12  /* 22  */
 SV_METAL_LAMELLAR_ARMOUR        13  /* 23  */
 SV_FULL_PLATE_ARMOUR            15  /* 25  */
 SV_RIBBED_PLATE_ARMOUR          18  /* 28  */
 SV_MITHRIL_CHAIN_MAIL           20  /* 28+ */
 SV_MITHRIL_PLATE_MAIL           25  /* 35+ */
 SV_ADAMANTITE_PLATE_MAIL        30  /* 40+ */
~~~~~38
/* The "sval" codes for TV_DRAG_ARMOR */
 SV_DRAGON_BLACK                  1
 SV_DRAGON_BLUE                   2
 SV_DRAGON_WHITE                  3
 SV_DRAGON_RED                    4
 SV_DRAGON_GREEN                  5
 SV_DRAGON_MULTIHUED              6
 SV_DRAGON_SHINING               10
 SV_DRAGON_LAW                   12
 SV_DRAGON_BRONZE                14
 SV_DRAGON_GOLD                  16
 SV_DRAGON_CHAOS                 18
 SV_DRAGON_BALANCE               20
 SV_DRAGON_POWER                 30
~~~~~39
/* The sval codes for TV_LITE */
 SV_LITE_TORCH                    0
 SV_LITE_LANTERN                  1
 SV_LITE_TORCH_EVER               2
 SV_LITE_DWARVEN                  3
 SV_LITE_FEANORIAN                4
 SV_LITE_GALADRIEL                100
 SV_LITE_ELENDIL                  101
 SV_LITE_THRAIN                   102
 SV_LITE_UNDEATH                  103
 SV_LITE_PALANTIR                 104
 SV_ANCHOR_SPACETIME              105
 SV_STONE_LORE                    106
~~~~~40
/* The "sval" codes for TV_AMULET */
 SV_AMULET_DOOM                   0
 SV_AMULET_TELEPORT               1
 SV_AMULET_ADORNMENT              2
 SV_AMULET_SLOW_DIGEST            3
 SV_AMULET_RESIST_ACID            4
 SV_AMULET_SEARCHING              5
 SV_AMULET_BRILLANCE              6
 SV_AMULET_CHARISMA               7
 SV_AMULET_THE_MAGI               8
 SV_AMULET_REFLECTION             9
 SV_AMULET_CARLAMMAS             10
 SV_AMULET_INGWE                 11
 SV_AMULET_DWARVES               12
 SV_AMULET_NO_MAGIC              13
 SV_AMULET_NO_TELE               14
 SV_AMULET_RESISTANCE            15
 SV_AMULET_NOTHING               16
 SV_AMULET_SERPENT               17
 SV_AMULET_TORIS_MEJISTOS        18
 SV_AMULET_ELESSAR               19
 SV_AMULET_EVENSTAR              20
 SV_AMULET_SUSTENANCE            21
 SV_AMULET_TELEPATHY             22
 SV_AMULET_TRICKERY              23
 SV_AMULET_WEAPONMASTERY         24
 SV_AMULET_DEVOTION              25
 SV_AMULET_INFRA                 26
 SV_AMULET_SPELL                 27
 SV_AMULET_WISDOM                28
 SV_AMULET_RESIST_ELEC           29
 SV_AMULET_REGEN                 30
~~~~~45
/* The sval codes for TV_RING */
 SV_RING_WOE                      0
 SV_RING_AGGRAVATION              1
 SV_RING_WEAKNESS                 2
 SV_RING_STUPIDITY                3
 SV_RING_TELEPORTATION            4
 SV_RING_SPECIAL                  5
 SV_RING_SLOW_DIGESTION           6
 SV_RING_FEATHER_FALL             7
 SV_RING_RESIST_FIRE              8
 SV_RING_RESIST_COLD              9
 SV_RING_SUSTAIN_STR             10
 SV_RING_SUSTAIN_INT             11
 SV_RING_SUSTAIN_WIS             12
 SV_RING_SUSTAIN_CON             13
 SV_RING_SUSTAIN_DEX             14
 SV_RING_SUSTAIN_CHR             15
 SV_RING_PROTECTION              16
 SV_RING_ACID                    17
 SV_RING_FLAMES                  18
 SV_RING_ICE                     19
 SV_RING_RESIST_POIS             20
 SV_RING_FREE_ACTION             21
 SV_RING_SEE_INVIS               22
 SV_RING_SEARCHING               23
 SV_RING_STR                     24
 SV_RING_INT                     25
 SV_RING_DEX                     26
 SV_RING_CON                     27
 SV_RING_ACCURACY                28
 SV_RING_DAMAGE                  29
 SV_RING_SLAYING                 30
 SV_RING_SPEED                   31
 SV_RING_BARAHIR                 32
 SV_RING_TULKAS                  33
 SV_RING_NARYA                   34
 SV_RING_NENYA                   35
 SV_RING_VILYA                   36
 SV_RING_POWER                   37
 SV_RING_RES_FEAR                38
 SV_RING_RES_LD                  39
 SV_RING_RES_NETHER              40
 SV_RING_RES_NEXUS               41
 SV_RING_RES_SOUND               42
 SV_RING_RES_CONFUSION           43
 SV_RING_RES_SHARDS              44
 SV_RING_RES_DISENCHANT          45
 SV_RING_RES_CHAOS               46
 SV_RING_RES_BLINDNESS           47
 SV_RING_LORDLY                  48
 SV_RING_ATTACKS                 49
 SV_RING_NOTHING                 50
 SV_RING_PRECONITION             51
 SV_RING_FLAR                    52
 SV_RING_INVIS                   53
 SV_RING_FLYING                  54
 SV_RING_WRAITH                  55
 SV_RING_ELEC                    56
 SV_RING_DURIN                   57
 SV_RING_SPELL                   58
 SV_RING_CRIT                    59
~~~~~55
/* The "sval" codes for TV_STAFF */
 SV_STAFF_SCHOOL                 1
 SV_STAFF_NOTHING                2
~~~~~65
/* The "sval" codes for TV_WAND */
 SV_WAND_SCHOOL                  1
 SV_WAND_NOTHING                 2
~~~~~66
/* The "sval" codes for TV_ROD(Rod Tips) */
 SV_ROD_NOTHING                   0
 SV_ROD_DETECT_DOOR               1
 SV_ROD_IDENTIFY                  2
 SV_ROD_RECALL                    3
 SV_ROD_ILLUMINATION              4
 SV_ROD_MAPPING                   5
 SV_ROD_DETECTION                 6
 SV_ROD_PROBING                   7
 SV_ROD_CURING                    8
 SV_ROD_HEALING                   9
 SV_ROD_RESTORATION              10
 SV_ROD_SPEED                    11
 SV_ROD_TELEPORT_AWAY            13
 SV_ROD_DISARMING                14
 SV_ROD_LITE                     15
 SV_ROD_SLEEP_MONSTER            16
 SV_ROD_SLOW_MONSTER             17
 SV_ROD_DRAIN_LIFE               18
 SV_ROD_POLYMORPH                19
 SV_ROD_ACID_BOLT                20
 SV_ROD_ELEC_BOLT                21
 SV_ROD_FIRE_BOLT                22
 SV_ROD_COLD_BOLT                23
 SV_ROD_ACID_BALL                24
 SV_ROD_ELEC_BALL                25
 SV_ROD_FIRE_BALL                26
 SV_ROD_COLD_BALL                27
 SV_ROD_HAVOC                    28
 SV_ROD_DETECT_TRAP              29
 SV_ROD_HOME                     30
~~~~~67
/* The "sval" codes for TV_ROD_MAIN(Rods) */
 SV_ROD_WOODEN                   10
 SV_ROD_COPPER                   20
 SV_ROD_IRON                     50
 SV_ROD_ALUMINIUM                75
 SV_ROD_SILVER                   100
 SV_ROD_GOLDEN                   125
 SV_ROD_MITHRIL                  160
 SV_ROD_ADMANTITE                200
~~~~~70
/* The "sval" codes for TV_SCROLL */
 SV_SCROLL_DARKNESS               0
 SV_SCROLL_AGGRAVATE_MONSTER      1
 SV_SCROLL_CURSE_ARMOR            2
 SV_SCROLL_CURSE_WEAPON           3
 SV_SCROLL_SUMMON_MONSTER         4
 SV_SCROLL_SUMMON_UNDEAD          5
 SV_SCROLL_SUMMON_MINE            6
 SV_SCROLL_TRAP_CREATION          7
 SV_SCROLL_PHASE_DOOR             8
 SV_SCROLL_TELEPORT               9
 SV_SCROLL_TELEPORT_LEVEL        10
 SV_SCROLL_WORD_OF_RECALL        11
 SV_SCROLL_IDENTIFY              12
 SV_SCROLL_STAR_IDENTIFY         13
 SV_SCROLL_REMOVE_CURSE          14
 SV_SCROLL_STAR_REMOVE_CURSE     15
 SV_SCROLL_ENCHANT_ARMOR         16
 SV_SCROLL_ENCHANT_WEAPON_TO_HIT 17
 SV_SCROLL_ENCHANT_WEAPON_TO_DAM 18
 SV_SCROLL_ENCHANT_WEAPON_PVAL   19
 SV_SCROLL_STAR_ENCHANT_ARMOR    20
 SV_SCROLL_STAR_ENCHANT_WEAPON   21
 SV_SCROLL_RECHARGING            22
 SV_SCROLL_RESET_RECALL          23
 SV_SCROLL_LIGHT                 24
 SV_SCROLL_MAPPING               25
 SV_SCROLL_DETECT_GOLD           26
 SV_SCROLL_DETECT_ITEM           27
 SV_SCROLL_DETECT_TRAP           28
 SV_SCROLL_DETECT_DOOR           29
 SV_SCROLL_DETECT_INVIS          30
 SV_SCROLL_DIVINATION            31
 SV_SCROLL_SATISFY_HUNGER        32
 SV_SCROLL_BLESSING              33
 SV_SCROLL_HOLY_CHANT            34
 SV_SCROLL_HOLY_PRAYER           35
 SV_SCROLL_MONSTER_CONFUSION     36
 SV_SCROLL_PROTECTION_FROM_EVIL  37
 SV_SCROLL_RUNE_OF_PROTECTION    38
 SV_SCROLL_TRAP_DOOR_DESTRUCTION 39
 SV_SCROLL_DEINCARNATION         40
 SV_SCROLL_STAR_DESTRUCTION      41
 SV_SCROLL_DISPEL_UNDEAD         42
 SV_SCROLL_MASS_RESURECTION      43
 SV_SCROLL_GENOCIDE              44
 SV_SCROLL_MASS_GENOCIDE         45
 SV_SCROLL_ACQUIREMENT           46
 SV_SCROLL_STAR_ACQUIREMENT      47
 SV_SCROLL_FIRE                  48
 SV_SCROLL_ICE                   49
 SV_SCROLL_CHAOS                 50
 SV_SCROLL_RUMOR                 51
 SV_SCROLL_ARTIFACT              52
 SV_SCROLL_NOTHING               53
 SV_SCROLL_SPELL                 54
~~~~~71
/* The "sval" codes for TV_POTION */
 SV_POTION_WATER                  0
 SV_POTION_APPLE_JUICE            1
 SV_POTION_SLIME_MOLD             2
 SV_POTION_BLOOD                  3
 SV_POTION_SLOWNESS               4
 SV_POTION_SALT_WATER             5
 SV_POTION_POISON                 6
 SV_POTION_BLINDNESS              7
 SV_POTION_INVIS                  8
 SV_POTION_CONFUSION              9
 SV_POTION_MUTATION              10
 SV_POTION_SLEEP                 11
 SV_POTION_LEARNING              12
 SV_POTION_LOSE_MEMORIES         13
 SV_POTION_RUINATION             15
 SV_POTION_DEC_STR               16
 SV_POTION_DEC_INT               17
 SV_POTION_DEC_WIS               18
 SV_POTION_DEC_DEX               19
 SV_POTION_DEC_CON               20
 SV_POTION_DEC_CHR               21
 SV_POTION_DETONATIONS           22
 SV_POTION_DEATH                 23
 SV_POTION_INFRAVISION           24
 SV_POTION_DETECT_INVIS          25
 SV_POTION_SLOW_POISON           26
 SV_POTION_CURE_POISON           27
 SV_POTION_BOLDNESS              28
 SV_POTION_SPEED                 29
 SV_POTION_RESIST_HEAT           30
 SV_POTION_RESIST_COLD           31
 SV_POTION_HEROISM               32
 SV_POTION_BESERK_STRENGTH       33
 SV_POTION_CURE_LIGHT            34
 SV_POTION_CURE_SERIOUS          35
 SV_POTION_CURE_CRITICAL         36
 SV_POTION_HEALING               37
 SV_POTION_STAR_HEALING          38
 SV_POTION_LIFE                  39
 SV_POTION_RESTORE_MANA          40
 SV_POTION_RESTORE_EXP           41
 SV_POTION_RES_STR               42
 SV_POTION_RES_INT               43
 SV_POTION_RES_WIS               44
 SV_POTION_RES_DEX               45
 SV_POTION_RES_CON               46
 SV_POTION_RES_CHR               47
 SV_POTION_INC_STR               48
 SV_POTION_INC_INT               49
 SV_POTION_INC_WIS               50
 SV_POTION_INC_DEX               51
 SV_POTION_INC_CON               52
 SV_POTION_INC_CHR               53
 SV_POTION_AUGMENTATION          55
 SV_POTION_ENLIGHTENMENT         56
 SV_POTION_STAR_ENLIGHTENMENT    57
 SV_POTION_SELF_KNOWLEDGE        58
 SV_POTION_EXPERIENCE            59
 SV_POTION_RESISTANCE            60
 SV_POTION_CURING                61
 SV_POTION_INVULNERABILITY       62
 SV_POTION_NEW_LIFE              63
~~~~~72
/* The "sval" codes for TV_POTION2 */
 SV_POTION2_MIMIC_ABOMINATION     1
 SV_POTION2_MIMIC_WOLF            2
 SV_POTION2_MIMIC_APE             3
 SV_POTION2_MIMIC_GOAT            4
 SV_POTION2_MIMIC_INSECT          5
 SV_POTION2_MIMIC_SPARROW         6
 SV_POTION2_MIMIC_STATUE          7
 SV_POTION2_MIMIC_VAMPIRE         8
 SV_POTION2_MIMIC_SPIDER          9
 SV_POTION2_MIMIC_MANA_BALL       10
 SV_POTION2_MIMIC_FIRE_CLOUD      11
 SV_POTION2_MIMIC_COLD_CLOUD      12
 SV_POTION2_MIMIC_CHAOS_CLOUD     13
 SV_POTION2_CURE_LIGHT_SANITY     14
 SV_POTION2_CURE_SERIOUS_SANITY   15
 SV_POTION2_CURE_CRITICAL_SANITY  16
 SV_POTION2_CURE_SANITY           17
 SV_POTION2_CURE_WATER            18
~~~~~80
/* The "sval" codes for TV_FOOD */
 SV_FOOD_POISON                   0
 SV_FOOD_BLINDNESS                1
 SV_FOOD_PARANOIA                 2
 SV_FOOD_CONFUSION                3
 SV_FOOD_HALLUCINATION            4
 SV_FOOD_PARALYSIS                5
 SV_FOOD_WEAKNESS                 6
 SV_FOOD_SICKNESS                 7
 SV_FOOD_STUPIDITY                8
 SV_FOOD_NAIVETY                  9
 SV_FOOD_UNHEALTH                10
 SV_FOOD_DISEASE                 11
 SV_FOOD_CURE_POISON             12
 SV_FOOD_CURE_BLINDNESS          13
 SV_FOOD_CURE_PARANOIA           14
 SV_FOOD_CURE_CONFUSION          15
 SV_FOOD_CURE_SERIOUS            16
 SV_FOOD_RESTORE_STR             17
 SV_FOOD_RESTORE_CON             18
 SV_FOOD_RESTORING               19
 SV_FOOD_BISCUIT                 32
 SV_FOOD_JERKY                   33
 SV_FOOD_RATION                  35
 SV_FOOD_SLIME_MOLD              36
 SV_FOOD_WAYBREAD                37
 SV_FOOD_PINT_OF_ALE             38
 SV_FOOD_PINT_OF_WINE            39
 SV_FOOD_ATHELAS                 40
 SV_FOOD_GREAT_HEALTH            41
 SV_FOOD_FORTUNE_COOKIE          42
~~~~~04
/* The "sval" codes for TV_BATERIE */
 SV_BATERIE_POISON    1
 SV_BATERIE_EXPLOSION 2
 SV_BATERIE_TELEPORT  3
 SV_BATERIE_COLD      4
 SV_BATERIE_FIRE      5
 SV_BATERIE_ACID      6
 SV_BATERIE_LIFE      7
 SV_BATERIE_CONFUSION 8
 SV_BATERIE_LITE      9
 SV_BATERIE_CHAOS     10
 SV_BATERIE_TIME      11
 SV_BATERIE_MAGIC     12
 SV_BATERIE_XTRA_LIFE 13
 SV_BATERIE_DARKNESS  14
 SV_BATERIE_KNOWLEDGE 15
 SV_BATERIE_FORCE     16
 SV_BATERIE_LIGHTNING 17
 SV_BATERIE_MANA      18
 MAX_BATERIE_SVAL     18
~~~~~09
/* The "sval" codes for TV_CORPSE */
 SV_CORPSE_CORPSE     1
 SV_CORPSE_SKELETON   2
 SV_CORPSE_HEAD       3
 SV_CORPSE_SKULL      4
 SV_CORPSE_MEAT       5
~~~~~115
/* The "sval" codes for TV_DAEMON_BOOK */
 SV_DEMONBLADE  55
 SV_DEMONSHIELD 56
 SV_DEMONHORN   57
tome-235-src/lib/help/ability.txt0000644000076400017500000001141311012107760014557 0ustar  dgdg|||||oy
~~~~~01|Abilities
#####R=== ToME Abilities ===
As well as spending your skill points on *****skills.txt*0[skills], you can also choose
to spend them on abilities. 
Abilities are bought once, and then have a permanent effect. You cannot 
continue adding skill points into them, (which you can with *****skills.txt*0[skills]) as there 
would be no way that these abilities can improve. They are a "one-off 
purchase".
As a consequence of this, they are often quite powerful abilities and can 
cost quite a few skill points to buy.
Most abilities have a prerequisite skill or stat level which you must reach 
before being able to buy.

For instance, you can invest in the *****ability.txt*03[Tree walking] ability. This will allow 
you to pass through dense undergrowth. In order to purchase this skill you must 
first have your *****skills.txt*34[Nature] skill at 20 or greater, and then it will cost you 7 
skill points to buy. This means you have to "save up" enough skill points in
order to be able to afford this ability.

You can access the Ability screen by pressing 'N' (in the original keyset, or
'\N' in the roguelike keyset). Scroll up and down the abilities and then
navigate right to buy selected ability.

Adapt your character with skills and abilities in order to make it unique, 
playable, and maybe even powerful enough to win the game!

Here follows a list of all the available abilities:

*****ability.txt*02[Spread blows]               *****ability.txt*03[Tree walking]
*****ability.txt*04[Perfect casting]            *****ability.txt*05[Extra Max Blow(1)]
*****ability.txt*06[Extra Max Blow(2)]          *****ability.txt*07[Ammo creation]
*****ability.txt*08[Touch of death]             *****ability.txt*09[Artifact Creation]
*****ability.txt*10[Far reaching attack]        *****ability.txt*11[Trapping]
*****ability.txt*12[Undead Form]

~~~~~02|Abilities|Spread blows
[[[[[BSpread blows]
If a monster dies to your attack but you still have blows left
you won't lose the full turn, allowing you to attack some other
monster in the same turn.
#####UPrereq: Weaponmastery skill@30, Dex@17
#####rCost: 5
Warriors (of all types) gain this ability for free at character level 25.
~~~~~03|Abilities|Tree walking
[[[[[BTree walking]
Allows you to walk in dense forest.
#####UPrereq: Nature skill@20
#####rCost: 7
Ents and Wood Elves are born with this ability.
~~~~~04|Abilities|Perfect casting
[[[[[BPerfect casting]
Allows you to reach 0% failure rate on spells.
#####UPrereq: Magic skill@35
#####rCost: 6
Priests and Mages (of all types) are born with this ability.
~~~~~05|Abilities|Extra Max Blow 1
[[[[[BExtra Max Blow(1)]
Increases your max possible blows number by 1.
#####UPrereq: Combat skill@10
#####rCost: 7
Warriors (of all types) and Paladins are born with this ability.
Rogues (of all types) gain this ability for free at character level 10.
~~~~~06|Abilities|Extra Max Blow 2
[[[[[BExtra Max Blow(2)]
Increases your max possible blows number by 1 (Cumulative with 
Extra Max Blow(1)).
#####UPrereq: Combat skill@20, Extra Max Blow(1)
#####rCost: 7
Warriors (of all types) are born with this ability.
~~~~~07|Abilities|Ammo creation
[[[[[BAmmo creation]
Allows you to create shots, arrows and bolts from various materials.
You can always make shots.
At Archery level 10 you can start making arrows.
At Archery level 20 you can start making bolts.
#####UPrereq: Archery skill@10
#####rCost: 8
Archers (of all types) gain this ability for free at character level 2.
~~~~~08|Abilities|Touch of death
[[[[[BTouch of death]
Your melee blows can insta-kill, but you only receive 1/3 of the experience
for that kill.
You must activate this from your 'm' menu.
#####UPrereq: Necromancy skill@50, Combat skill@40, DEX@30, STR@30
#####rCost: 15
~~~~~09|Abilities|Artifact Creation
[[[[[BArtifact Creation]
In combination with a high alchemy skill this ability will let you
design your very own artifacts.
Prereq: Alchemy@40, INT@35, WIS@35
#####rCost: 70
~~~~~10|Abilities|Far reaching attack
[[[[[BFar reaching attack]
You can attack an enemy one square far using a long polearm.
At high levels of Polearm-mastery skill, you can even hit two enemies at once.
#####UPrereq: Combat@15, Polearm-mastery@15
#####rCost: 10
~~~~~11|Abilities|Trapping
[[[[[BTrapping]
Enables you to set traps which harm monsters.
#####UPrereq: Disarming@15
#####rCost: 10
Rogues are born with this ability.
~~~~~12|Abilities|Undead Form
[[[[[BUndead Form]
With this ability your character receives a small amount of Death Points (DP) 
when they 'die'. Every normal (+0 speed) turn, one DP
is lost; you can regain it like you would do with Hit Points.
If you manage to kill enough monsters before your DP goes below 0, your
character is brought back to life.
#####UPrereq: Necromancy@30, INT@25
#####rCost: 15
Necromancers gain this ability for free at character level 25.

tome-235-src/lib/help/m_udun.txt0000644000076400017500000000333711012107760014417 0ustar  dgdg|||||oy
~~~~~01|Magic|Udun School
~~~~~02|Udun Magic
~~~~~03|Skills|Udun - Spell Info
#####R === ToME Magic - Udun School ===

The Udun school of magic contains spells where the corrupted forces of Melkor
Bauglir are used to create the final spell effect. There are rumours of an
"Unholy Tome of the Hellflame" which contains all the Udun school spells within
its bindings.

The Udun school is available only to worshippers of *****g_melkor.txt*0[Melkor Bauglir]. They will also
need some proficiency in the magic schools of Mana, Nature, Conveyance, and Fire
(or alternatively Sorcery) to cast the Udun spells. On the other hand, the spell
power of Udun spells is greatly increased by the level of the caster.

#####DUdun Spells
There are four spells available for the Udun school. These spells are:
1. [[[[[DDrain] (dual school level 1)
   Drains the mana contained in wands, staves and rods to increase yours.
#####v   Your Udun and Mana skills must have reached a combined average level 
#####v   of 1 in order to cast this spell.
2. [[[[[DGenocide] (dual school level 25)
   Genocides all monsters of a specified race on the level.
   At level 10 it can genocide all monsters near you.
#####v   Your Udun and Nature skills must have reached a combined average level 
#####v   of 25 in order to cast this spell.
3. [[[[[DWraithform] (dual school level 30)
   Turns you temporarily into an immaterial being.
#####v   Your Udun and Conveyance skills must have reached a combined average level 
#####v   of 30 in order to cast this spell.
4. [[[[[DFlame of Udun] (dual school level 35)
   Turns you temporarily into a powerful Balrog.
#####v   Your Udun and Fire skills must have reached a combined average level 
#####v   of 35 in order to cast this spell.
tome-235-src/lib/help/c_mage.txt0000644000076400017500000000464511012107760014346 0ustar  dgdg|||||oy
~~~~~01|Mage
~~~~~02|Classes|Mage
#####R=== Mages ===

#####GDescription
A Mage must live by his wits. He cannot hope to simply hack his way 
through the dungeon, and so must therefore use his magic to defeat, 
deceive, confuse, and escape. A Mage is not really complete without an
assortment of magical devices to use in addition to his spells. He can
master the higher level magical devices easily and has good saving throws. 

There is no reason a Mage cannot become a good fighter, but spells are 
his true realm. For more information on magic schools and spell effects see 
the *****magic.txt*01[Magic help file].

#####GStarting Stat Modifiers
Strength         -5
Intelligence     +3
Wisdom           +0
Dexterity        +1
Constitution     -2
Charisma         +1
Hit Die          +d0
Spell Points    +50%
Exp Penalty      30%

#####GStarting Skills:
#####BSkill                   Start Level     Skill Point Gains
Combat                  1.000           [0.500]
  Weaponmastery         0.700           [0.500]
Sneakiness              1.000           [0.900]
  Stealth               0.000           [0.400]
Magic                   1.000           [0.900]
  Magic-Device          1.000           [1.200]
  Spell-power           0.000           [0.600]
  Sorcery               0.000           [0.200]
  Mana                  1.000           [0.900]
  Geomancy
    Fire                0.000           [0.900]
    Water               0.000           [0.900]
    Air                 0.000           [0.900]
    Earth               0.000           [0.900]
  Meta                  0.000           [0.900]
  Conveyance            0.000           [0.900]
  Divination            0.000           [0.900]
  Temporal              0.000           [0.900]
  Mind                  0.000           [0.900]
  Nature                0.000           [0.900]
  Necromancy            0.000           [0.700]
  Runecraft             0.000           [0.700]
  Thaumaturgy           0.000           [0.700]
Spirituality            1.000           [0.550]
  Prayer                0.000           [0.500]
Monster-lore            0.000           [0.500]

*A Mage cannot learn the Geomancy skill, but it is shown in his skill 
screen because the elemental schools are sub-skills of it.

#####GInnate Abilities:
#####BAbility              Character level
Perfect casting             1

#####GStarting Equipment
A Mage begins the game with:
    a Book of Beginner Cantrips
    a Dagger
tome-235-src/lib/help/lua_mon.txt0000644000076400017500000003661011012107760014562 0ustar  dgdg|||||oy

#####R             /----------------------------------------\
#####R            <    monster.pkg functions helper file     >
#####R             \----------------------------------------/


----------------------------------------------------------------------

#####R=== race_info_idx ===

#####GDeclaration
    extern monster_race* race_info_idx(int r_idx, int ego);

#####GFile
    monster2.c

#####GComment
/*
 * Return a (monster_race*) with the combinations of the monster
 * properties and the ego type
 */

#####GDescription
Get monster info and ego info for monster with monster index "r_idx"
and monster ego "ego". The ego information is applied to the monster
information and the new monster information is returned.

For example, race_info_idx(141,7) will create a brown yeek (monster)
shaman (ego).

#####GParameters
> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
  range checking.
> "ego" is an entry from the "re_info.txt". Beware: there is no range
  checking.

----------------------------------------------------------------------

#####R=== delete_monster_idx ===

#####GDeclaration
    extern void delete_monster_idx(int i);

#####GFile
    monster2.c

#####GComment
/*
 * Delete a monster by index.
 *
 * When a monster is deleted, all of its objects are deleted.
 */

#####GDescription
Delete monster "i" from the monster array.

#####GParameters
> "i" is the index for the monster list (m_list[]). Beware: there is
  no range checking.

----------------------------------------------------------------------

#####R=== m_pop ===

#####GDeclaration
    extern s16b m_pop(void);

#####GFile
    monsters2.c

#####GComment
/*
 * Acquires and returns the index of a "free" monster.
 *
 * This routine should almost never fail, but it *can* happen.
 */

#####GDescription
Get an empty slot in the monster list (m_list[]). If there are no
empty slots, a slot will be reclaimed from a "dead" monster. If all
slots are full, 0 is returned, which means the function has failed
("Too many monsters!").

----------------------------------------------------------------------

#####R=== get_mon_num_prep ===

#####GDeclaration
    extern errr get_mon_num_prep(void);

#####GFile
    monster2.c

#####GComment
/*
 * Apply a "monster restriction function" to the "monster allocation table"
 */

#####GDescription
There are no parameters, but there are some other variables which will
need to be set. They are get_mon_num_hook and get_mon_num2_hook. They
are pointers to functions.

For example, get_mon_num_hook = monster_volcano means when
get_mon_num_hook is called (*get_mon_num_hook)(index), the actual
function called is monster_volcano(index). This particular function
returns TRUE if the monster indicated by "index" has the
RF8_WILD_VOLCANO flag set.

It is a good idea to store the old value of get_mon_num_hook before
setting a new one, and restoring it when your function is finished.

Following is a list of functions which can be assigned to
get_mon_num_hook:

create_molds_hook
create_townpeople_hook
mon_hook_bounty
monster_dungeon
monster_grass
monster_mountain
monster_ocean
monster_quest
monster_shore
monster_town
monster_volcano
monster_waste
monster_wood
mutate_monster_okay
place_monster_okay
summon_specific_okay
vault_aux_animal
vault_aux_chapel
vault_aux_clone
vault_aux_demon
vault_aux_dragon
vault_aux_giant
vault_aux_jelly
vault_aux_kennel
vault_aux_orc
vault_aux_symbol
vault_aux_treasure
vault_aux_troll
vault_aux_undead

Or you can write your own. The function must take an integer (index)
as a parameter and return boolean (TRUE if the monster is selected,
or FALSE if it is not).

----------------------------------------------------------------------

#####R=== get_mon_num ===

#####GDeclaration
    extern s16b get_mon_num(int level);

#####GFile
    monster2.c

#####GComment
/*
 * Choose a monster race that seems "appropriate" to the given level
 *
 * This function uses the "prob2" field of the "monster allocation table",
 * and various local information, to calculate the "prob3" field of the
 * same table, which is then used to choose an "appropriate" monster, in
 * a relatively efficient manner.
 *
 * Note that "town" monsters will *only* be created in the town, and
 * "normal" monsters will *never* be created in the town, unless the
 * "level" is "modified", for example, by polymorph or summoning.
 *
 * There is a small chance (1/50) of "boosting" the given depth by
 * a small amount (up to four levels), except in the town.
 *
 * It is (slightly) more likely to acquire a monster of the given level
 * than one of a lower level.  This is done by choosing several monsters
 * appropriate to the given level and keeping the "hardest" one.
 *
 * Note that if no monsters are "appropriate", then this function will
 * fail, and return zero, but this should *almost* never happen.
 */

Description:
For the given level "level", return the index of an appropriate
monster race.

#####GParameters
> "level" is a dungeon level

----------------------------------------------------------------------

#####R=== monster_desc ===

#####GDeclaration
    extern void monster_desc(char *desc, monster_type *m_ptr,
    int mode);

#####GFile
    monster2.c

#####GComment
/*
 * Build a string describing a monster in some way.
 *
 * We can correctly describe monsters based on their visibility.
 * We can force all monsters to be treated as visible or invisible.
 * We can build nominatives, objectives, possessives, or reflexives.
 * We can selectively pronominalize hidden, visible, or all monsters.
 * We can use definite or indefinite descriptions for hidden monsters.
 * We can use definite or indefinite descriptions for visible monsters.
 *
 * Pronominalization involves the gender whenever possible and allowed,
 * so that by cleverly requesting pronominalization / visibility, you
 * can get messages like "You hit someone.  She screams in agony!".
 *
 * Reflexives are acquired by requesting Objective plus Possessive.
 *
 * If no m_ptr arg is given (?), the monster is assumed to be hidden,
 * unless the "Assume Visible" mode is requested.
 *
 * If no r_ptr arg is given, it is extracted from m_ptr and r_info
 * If neither m_ptr nor r_ptr is given, the monster is assumed to
 * be neuter, singular, and hidden (unless "Assume Visible" is set),
 * in which case you may be in trouble... :-)
 *
 * I am assuming that no monster name is more than 70 characters long,
 * so that "char desc[80];" is sufficiently large for any result.
 *
 * Mode Flags:
 *   0x01 --> Objective (or Reflexive)
 *   0x02 --> Possessive (or Reflexive)
 *   0x04 --> Use indefinites for hidden monsters ("something")
 *   0x08 --> Use indefinites for visible monsters ("a kobold")
 *   0x10 --> Pronominalize hidden monsters
 *   0x20 --> Pronominalize visible monsters
 *   0x40 --> Assume the monster is hidden
 *   0x80 --> Assume the monster is visible
 *
 * Useful Modes:
 *   0x00 --> Full nominative name ("the kobold") or "it"
 *   0x04 --> Full nominative name ("the kobold") or "something"
 *   0x80 --> Genocide resistance name ("the kobold")
 *   0x88 --> Killing name ("a kobold")
 *   0x22 --> Possessive, genderized if visible ("his") or "its"
 *   0x23 --> Reflexive, genderized if visible ("himself") or "itself"
 */

#####GDescription
Return a monster description "desc" for monster "monster_type" using
flag "mode". The modes are described above.

#####GParameters
> "desc" is the returned description.
> "monster type" is the monster (monster pointer).
> "mode" is one of the modes described in the comments.

----------------------------------------------------------------------

#####R=== monster_race_desc ===

#####GDeclaration
    extern void monster_race_desc(char *desc, int r_idx,
    int ego);

#####GFile
    monster2.c

#####GComment
(none)

#####GDescription
Return the monster description "desc" for monster with monster index
"r_idx" and monster ego "ego". The monster description is made up of
the ego name (if any) and monster name, or the unique name.

#####GParameters
> "desc" is the returned description.
> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
  range checking.
> "ego" is an entry from the "re_info.txt". Beware: there is no range
  checking.

----------------------------------------------------------------------

#####R=== place_monster_aux ===

#####GDeclaration
    extern bool place_monster_aux(int y, int x, int r_idx,
    bool slp, bool grp, int status);

#####GFile
    monster2.c

#####GComment
/*
 * Attempt to place a monster of the given race at the given location
 *
 * Note that certain monsters are now marked as requiring "friends".
 * These monsters, if successfully placed, and if the "grp" parameter
 * is TRUE, will be surrounded by a "group" of identical monsters.
 *
 * Note that certain monsters are now marked as requiring an "escort",
 * which is a collection of monsters with similar "race" but lower
 * level.
 *
 * Some monsters induce a fake "group" flag on their escorts.
 *
 * Note the "bizarre" use of non-recursion to prevent annoying output
 * when running a code profiler.
 *
 * Note the use of the new "monster allocation table" code to restrict
 * the "get_mon_num()" function to "legal" escort types.
 */

#####GDescription
Attempt to place a monster at grid "y", "x". The monster has monster
index "m_idx". The monster may be asleep ("slp"). The monster may be
surrounded by a group of identical monsters ("grp"). The monster has
a status of "status" (see below). The function returns TRUE if the
monster is placed successfully, otherwise FALSE.

#####GParameters
> "y" is the y co-ordinate of the target grid.
> "x" is the x co-ordinate of the target grid.
> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
  range checking.
> "slp" is TRUE if the monster is asleep, otherwise FALSE.
> "grp" is TRUE if the monster is surrounded by a group, otherwise
  FALSE.
> "status" is the status of the monster
  *****fields.txt*0[status]

----------------------------------------------------------------------

#####R=== place_monster ===

#####GDeclaration
    extern bool place_monster(int y, int x, bool slp,
    bool grp);

#####GFile
    monster2.c

#####GComment
/*
 * Hack -- attempt to place a monster at the given location
 *
 * Attempt to find a monster appropriate to the "monster_level"
 */

#####GDescription
Attempt to place a monster at grid "y", "x". The monster may be asleep
("slp"). The monster may be surrounded by a group of identical
monsters ("grp"). The monster is of the appropriate monster level. The
function returns TRUE if the monster is placed successfully, otherwise
FALSE.

#####GParameters
> "y" is the y co-ordinate of the target grid.
> "x" is the x co-ordinate of the target grid.
> "slp" is TRUE if the monster is asleep, otherwise FALSE.
> "grp" is TRUE if the monster is surrounded by a group, otherwise
  FALSE.

----------------------------------------------------------------------

#####R=== place_monster_one ===

#####GDeclaration
    extern s16b place_monster_one(int y, int x, int r_idx,
    int ego, bool slp, int status);

#####GFile
    monster2.c

#####GComment
/*
 * Attempt to place a monster of the given race at the given location.
 *
 * To give the player a sporting chance, any monster that appears in
 * line-of-sight and is extremely dangerous can be marked as
 * "FORCE_SLEEP", which will cause them to be placed with low energy,
 * which often (but not always) lets the player move before they do.
 *
 * This routine refuses to place out-of-depth "FORCE_DEPTH" monsters.
 *
 * XXX XXX XXX Use special "here" and "dead" flags for unique monsters,
 * remove old "cur_num" and "max_num" fields.
 *
 * XXX XXX XXX Actually, do something similar for artifacts, to simplify
 * the "preserve" mode, and to make the "what artifacts" flag more useful.
 *
 * This is the only function which may place a monster in the dungeon,
 * except for the savefile loading code.
 */

#####GDescription
Attempt to place a monster at grid "y", "x". The monster has monster
index "m_idx". The monster may be asleep ("slp"). The monster may have
an ego type ("ego"). The monster has a status of "status" (see below).
The function returns TRUE if the monster is placed successfully,
otherwise FALSE.

#####GParameters
> "y" is the y co-ordinate of the target grid.
> "x" is the x co-ordinate of the target grid.
> "r_idx" is an entry from the "r_info.txt" file. Beware: there is no
  range checking.
> "slp" is TRUE if the monster is asleep, otherwise FALSE.
> "ego" is an entry from the "re_info.txt". Beware: there is no range
  checking.
> "status" is the status of the monster
  *****fields.txt*0[status]

----------------------------------------------------------------------

#####R=== is_friend ===

#####GDeclaration
    extern int is_friend(monster_type *m_ptr);

#####GFile
    monster3.c

#####GComment
/*
 * Is the monster in friendly state(pet, friend, ..)
 * -1 = enemy, 0 = neutral, 1 = friend
 */

#####GDescription
Return a value to indicate the status of monster "m_ptr".
  *****fields.txt*0[status]

#####GParameters
> "m_ptr" is a pointer to a monster.

----------------------------------------------------------------------

#####R=== is_enemy ===

#####GDeclaration
    extern bool is_enemy(monster_type *m_ptr,
    monster_type *t_ptr);

#####GFile
    monster3.c

#####GComment
/* Should they attack each others */

#####GDescription
Return TRUE if monster "m_ptr" should attack monster "t_ptr". If
"m_ptr" is stupid and "r_ptr" is a different type of monster then the
function will return TRUE. If "m_ptr" is not neutral and "r_ptr" is a
breeder, and "r_ptr" is a different type of monster then the function
will return TRUE (and vice versa). If both monsters are not neutral
and one is friendly and the other isn't then the function will return
TRUE. Otherwise the function returns FALSE.

#####GParameters
> "m_ptr" is a pointer to a monster.
> "t_ptr" is a pointer to a monster (target).

----------------------------------------------------------------------

#####R=== change_side ===

#####GDeclaration
    extern bool change_side(monster_type *m_ptr);

#####GFile
    monster3.c

#####GComment
(none)

#####GDescription
Change the status of monster "m_ptr" from friendly to unfriendly and
vice versa. Friends and pets become enemies. Neutral Ms become
neutral Ps and vice versa. Companions are unaffected. The
function returns TRUE if the status changed, otherwise FALSE.

#####GParameters
> "m_ptr" is a pointer to a monster.

----------------------------------------------------------------------

#####R=== find_position ===

#####GDeclaration
    extern void find_position(int y, int x, int *yy = 0,
    int *xx = 0);

#####GFile
    lua_bind.c

#####GComment
(none)

#####GDescription
Find a new grid "yy", "xx" within 6 grids of target grid "y", "x".
The new grid must be within line-of-sight of the target grid. A
maximum of 5000 attempts is made.

#####GParameters
> "y" is the y co-ordinate of the target grid.
> "x" is the x co-ordinate of the target grid.
> "yy" is the y co-ordinate of the new grid.
> "xx" is the x co-ordinate of the new grid.

----------------------------------------------------------------------

#####R=== can_create_companion ===

#####GDeclaration
    extern bool can_create_companion();

#####GFile
    monster3.c

#####GComment
/* Returns if a new companion is allowed */

#####GDescription
Return TRUE if a companion can be created, otherwise FALSE.

----------------------------------------------------------------------

Back to the *****lua.hlp*0[lua help index] .


                                                     [[[[[gThis file by Chris Hadgis]
tome-235-src/lib/help/gambling.txt0000644000076400017500000000207111012107760014702 0ustar  dgdg|||||oy
~~~~~01|Gambling
#####R=== Gambling Rules ===

#####GBetween : 
       Three 12-sided dice rolled; 2 black, 1 red. The red
       die must be between both black to win. If the red die
       matches a black die, you lose. Pays 3 to 1
#####GCraps: 
       Two 6-sided dice are rolled. On first roll, a 7 or 11
       wins. A 2, 3 or 12 loses. Otherwise roll until the first
       roll is matched (win) or a 7 is rolled (loss). Pays 2 to 1
#####GWheel: 
       Pick a number from 0-9. If the number shows on wheel
       after it stops spinning, you win. Pays 10 to 1

#####GSlots: 
       Three dice rolled. Matches win gold.
       Numbers are:
       1=Lemon, 2=Orange, 3=Sword, 4=Shield, 5=Plum, 6=Cherry
       Payoffs are as follows:
       Cherry Cherry Lemon  2-1   Cherry Cherry Orange  3-1
       Cherry Cherry Sword  4-1   Cherry Cherry Shield  5-1
       Cherry Cherry Plum   6-1
       Lemon Lemon Lemon    4-1   Orange Orange Orange 16-1
       Sword Sword Sword    6-1   Shield Shield Shield 25-1
       Plum Plum Plum       9-1   Cherry Cherry Cherry 36-1


tome-235-src/lib/help/g_manwe.txt0000644000076400017500000000541311012107760014542 0ustar  dgdg|||||oy
~~~~~01|Gods|Manwe
~~~~~02|Manwe
#####R === Manwe Sulimo ===

Manwe is the strongest of the Valar, next to Morgoth. His most faithful
followers are those of the class *****c_pr_man.txt*0[Priest(Manwe)].

#####GThe benefits of Worshipping Manwe Sulimo
1. As you increase your piety, Manwe will grant boosts to your speed (up to
   a maximum boost of +7 speed).
2. If you are praying, Manwe likes it when you kill monsters that are aligned
   with evil.
3. As your piety increases, Manwe will grant you the following abilities (in
   order):
     a) Levitation
     b) Free Action (while praying)
     c) Flying (while praying)
4. Manwe likes elves.

#####GThe disadvantages of Worshipping Manwe Sulimo
1. Your piety slowly decreases with time, whether you are praying or not.
2. He doesn't like it if you kill monsters that are aligned with good.
3. He will completely abandon you if you wear The One Ring.
~~~~~03|Manwe|Prayers
#####GManwe Sulimo's Magic
Worshipping Manwe Sulimo gives the adventurer access to a set of special
spells that come directly from the hands of Manwe. These spells use your piety
to cast rather than your spellpoints, and the level of spells that Manwe will
permit you to use is determined by your Prayer skill - how skillful you are
in asking for his help without offending him!

There is a special book called the "Holy Tome of Manwe Sulimo" which
contains instructions for the procedure for each of the prayers Manwe will
grant. There are four prayers all told, which are:
1. [[[[[BManwe's Blessing] (Level 1)
   Manwe's Blessing removes your fears, blesses you and surrounds you with holy
      light.
   At spell level 10 it also grants heroism.
   At spell level 20 it also grants super heroism.
   At spell level 30 it also grants holy luck and life protection.
2. [[[[[BWind Shield] (Level 10)
   It surrounds you with a shield of wind that deflects blows from evil
      monsters.
   At level 10 it increases your armour rating.
   At level 20 it retaliates against monsters that melee you.
3. [[[[[BManwe's Call] (Level 20)
   Manwe's Call summons a Great Eagle to help you battle the forces of
      Morgoth.
4. [[[[[BAvatar] (Level 35)
   It turns you into a full grown Maia.

Each of these spells can be increased in level both by improving your Prayer
skill, and by improving your Spell-power skill.

In addition to his specific magic, Manwe will also assist with your ability to
use some magic from the "standard" schools, in relation to how skilled you
are at Prayer. These schools are as follows:
    *****m_air.txt*0[Air School] at 2/3 the Prayer skill level.
    *****m_convey.txt*0[Conveyance School] at 1/2 the Prayer skill level.
    *****m_meta.txt*0[Meta School] at 1/3 the Prayer skill level.
The spells from these schools are all cast using your normal spellpoints.
tome-235-src/lib/help/m_music.txt0000644000076400017500000000570111012107760014561 0ustar  dgdg|||||oy
~~~~~01|Magic|Music
~~~~~02|Music
~~~~~03|Skills|Music - Song Info
#####R === ToME Spells - Music ===

Musical songs can have powerful effects for those who have the ability to
play instruments, chiefly *****c_bard.txt*0[Bards].

In order to continue playing a song, mana is consumed each turn, until 
either the 'Stop Singing' song is sung, or the player's mana runs out.

Each song, as well as having a school level like any other magic spell, also
has a roman numeral following its name. The higher this number, the greater the
craftmanship of the instrument required to play it.

Each musical instrument has a value assigned to it as well, between 1 and 4. The
higher the number, the better the craftmanship; hence it will be possible
for the bard to play higher level songs only with more powerful instruments.
E.g. a Harp(+1) will allow you to cast "Stop Singing(I)" and "Song of the
Sun(I)". A Harp(+2) would allow you to sing those songs, as well as "Flow of
Life(II)".

There are 3 different types of instruments: Harps, Drums and Horns. Each type 
of instrument contains a different family of musical songs:


#####vMusical Songs

#####GAll Instruments
1. [[[[[vStop Singing(I)] (school level 1)
   Stops the current song, if any.
   
#####GDrums
1. [[[[[vHolding Pattern(I)] (school level 1)
   Slows down all monsters listening the song.
   Consumes mana each turn.
2. [[[[[vIllusion Pattern(II)] (school level 5)
   Tries to confuse all monsters listening the song.
   Consumes mana each turn.
3. [[[[[vStun Pattern(IV)] (school level 10)
   Stuns all monsters listening to the song.
   Consumes mana each turn.

#####GHarps
1. [[[[[vSong of the Sun(I)] (School level 1)
   Provides light as long as you sing.
   Consumes mana each turn.
2. [[[[[vFlow of Life(II)] (School level 5)
   Heals you as long as you sing.
   Consumes mana each turn.
3. [[[[[vHeroic Ballad(II)] (School level 10)
   Increases melee accuracy.
   At level 10 it increases it even more and reduces armour a bit.
   At level 20 it increases it still more.
   At level 25 it grants protection against chaos and confusion.
   Consumes mana each turn.
4. [[[[[vHobbit Melodies(III)] (School level 20)
   Greatly increases your reflexes allowing you to block more melee blows.
   At level 15 it also makes you faster.
   Consumes mana each turn.
5. [[[[[vClairaudience(IV)] (School level 25)
   Allows you to sense monster minds as long as you sing.
   At level 10 it identifies all objects in a radius on the floor,
   as well as probing monsters in that radius.
   Consumes mana each turn.

#####GHorns
1. [[[[[vBlow(I)] (School level 4)
   Produces a powerful, blowing sound all around you.
2. [[[[[vGush of Wind (II)] (School level 14)
   Produces a outgoing gush of wind that sends monsters away.
3. [[[[[vHorns of Ylmir(III)] (School level 20)
   Produces an earth-shaking sound.
4. [[[[[vAmbarkanta(IV)] (School level 25)
   Produces a reality-shaking sound that transports you to a nearly
   identical reality.
tome-235-src/lib/help/c_druid.txt0000644000076400017500000000346511012107760014543 0ustar  dgdg|||||oy
~~~~~01|Druid
~~~~~02|Classes|Druid
~~~~~03|Yavanna|Druid
#####R=== Druids ===

#####GDescription
When Melkor first dug up Utumno and Angband, rivers were polluted and gave
birth to dark clouds of stinging insects; animals changed into dark, horrible
horned things and the forests themselves screamed in horror at their corruption.

*****g_yavann.txt*0[Yavanna] heard this scream and gave to some of the children of Eru the strength
to defend Nature; at first Ents were chosen, but later on other races were
allowed to tread the path of the Druid.

The embodiment of life itself, a Druid is a true force of nature and nothing
can prevent him from completing his final quest: returning Angband to the
grassy sunlit plain it once was.


#####GStarting Stat Modifiers
Strength         -1
Intelligence     -3
Wisdom           +3
Dexterity        -1
Constitution     +0
Charisma         +2
Hit Die          +d2
Spell Points     +0%
Exp Penalty      20%

#####GStarting Skills:
#####BSkill                   Start Level     Skill Point Gains
Combat                  2.000           [0.700]
  Weaponmastery         1.000           [0.750]
Sneakiness              1.000           [0.900]
  Stealth               0.000           [0.400]
  Disarming		0.000		[0.900]
Magic                   1.000           [0.900]
  Magic-Device          1.000           [1.050]
  Spell-power           0.000           [0.600]
Spirituality            1.000           [1.000]
  Prayer                1.000           [1.500]
  Mindcraft             0.000           [0.600]
Monster-lore            1.000           [1.200]
  Summoning             1.000           [0.700]

#####GInnate Abilities:
#####BAbility              Character level
Perfect casting             1

#####GStarting Equipment
A Druid begins the game with:
    a Spellbook of Charm Animal
    a Mace
tome-235-src/lib/help/r_elf.txt0000644000076400017500000000206111012107760014210 0ustar  dgdg~~~~~01|Elf
~~~~~02|Races|Elf
#####R=== Elves ===

#####GDescription
Elves are better magicians than humans, but not as good at fighting. They 
tend to be smarter and faster than either humans or half-elves and also 
have better wisdom. Elves are better at searching, disarming, perception, 
stealth, bows, and magic, but they are not as good at hand weapons.
They resist light effects intrinsically.

#####GStat Modifiers
Strength        -1   
Intelligence    +2   
Wisdom          +2   
Dexterity       +1   
Constitution    -2   
Charisma        +2       
Hit Dice Sides  8         
Exp Penalty     +20%

#####GRacial Skill Modifiers:
#####BSkill                Start Mod    Skill Point Gains Mod
Combat                  
  Weaponmastery        -5.000           [0.000]
  Archery		1.500           [0.000]
Sneakiness              0.800           [0.000]
  Stealth               2.000           [0.000]
  Disarming             0.500           [0.000]
Magic                   
  Magic-Device          0.600           [0.000]
Spirituality            3.000           [0.000]
tome-235-src/lib/help/c_posses.txt0000644000076400017500000000562411012107760014747 0ustar  dgdg~~~~~01|Possessor
~~~~~02|Classes|Possessor
#####R=== Possessors ===

#####GDescription
Possessors are unusual; they aren't good fighters, and they can't cast 
magic. Their special ability is that of being able to leave their 
bodies and inhabit corpses. While "in" a corpse, the Possessor gains 
the abilities of the monster, and their hit points and the monster's 
are averaged. (Most monsters have no, or very few, spell points.)  While
in the incorporeal form between bodies, they have only one hitpoint.

#####GStarting Stat Modifiers
Strength         +1
Intelligence     -2
Wisdom           +1
Dexterity        +1
Constitution     +0
Charisma         +1
Hit Die          +d8
Spell Points     +0%
Exp Penalty      40%

#####GStarting Skills:
#####BSkill                   Start Level     Skill Point Gains
Combat                  1.000           [0.600]
  Weaponmastery         1.000           [0.600]
  Archery               1.000           [0.400]
Sneakiness              1.000           [0.700]
  Stealth               1.000           [0.700]
  Disarming             1.000           [0.500]
Magic                   0.000           [0.600]
  Magic-Device          1.000           [1.000]
Spirituality            1.000           [0.500]
  Prayer                0.000           [0.500]
  Music                 0.000           [0.300]
Monster-lore            1.000           [1.100]
  Corpse-preservation   1.000           [0.900]
  Possession            1.000           [0.800]

#####GStarting Equipment
A Possessor begins the game with:
    a Potion of Healing
    a Short Sword
    a Hard Leather Armour

~~~~~03|Possessor|Possessor powers 
~~~~~04|Skills|Possession - Possessor powers 
#####GPossession
The strange art of reanimating the corpse of a monster and making
it one's own can be of extreme benefit to those skilled in it. The body
the player possesses can grant powerful abilities, such as increased
speed, summoning, healing, breathing, and various resistances, and often
gives the player a large number of hit points. Possessing uniques is
especially neat.  

Possessors leave their own body by using the 'm' command, and choosing 
"[I]incarnating powers". Lacking a life force to sustain it, a corpse may rot
immediately when a Possessor leaves it, but a high Possession skill score
may prevent this from happening. They then become a very vulnerable ghostly 
being which travels to where another corpse is lying on the floor, and 
possesses it by again using the 'm' command.  Once possessed, many 
monster corpses allow the player to perform various special actions
(such as blinking or summoning) by using the option "Use your [R]ace
powers".

All corpses alter the player's melee attacks. When they incarnate in a 
monster that allows the use of a weapon, monster blows are ignored 
[[[[[Btotally]. When they incarnate in a monster that doesn't allow use of a 
weapon (dragons for example) they use the monster blows [[[[[Band only them]!
tome-235-src/lib/help/c_axemas.txt0000644000076400017500000000326311012107760014706 0ustar  dgdg~~~~~01|Axemaster
~~~~~02|Classes|Axemaster
#####R=== Axemasters ===

#####GDescription
The Axemaster is a Warrior who specialises in axes.
The training is so intense and specific that Axemasters gain huge bonuses
when fighting with their chosen weapon, dependent on their Axe-mastery skill.
In most other respects they perform about as well as a generic Warrior.

#####GStarting Stat Modifiers
Strength         +5
Intelligence     -2
Wisdom           -2
Dexterity        +2
Constitution     +2
Charisma         -1
Hit Die          +d9
Spell Points     +0%
Exp Penalty       0%

#####GStarting Skills:
#####BSkill                   Start Level     Skill Point Gains
Combat                  2.000           [0.900]
  Weaponmastery         1.000           [0.950]
    Sword-mastery       0.000           [0.300]
    Axe-mastery         1.000           [0.700]
    Hafted-mastery      0.000           [0.300]
    Polearm-mastery     0.000           [0.300]
  Archery               1.000           [0.600]
  Antimagic             0.000           [0.550]
Sneakiness              1.000           [0.900]
  Stealth               0.000           [0.400]
  Disarming             1.000           [0.900]
Magic                   1.000           [0.300]
  Magic-Device          1.000           [1.150]
Spirituality            1.000           [0.400]
  Prayer                0.000           [0.500]
Monster-lore            0.000           [0.500]

#####GInnate Abilities:
#####BAbility              Character level
Extra Max Blow(1)           1
Extra Max Blow(2)           1
Spread blows                25

#####GStarting Equipment
An Axemaster begins the game with:
    a Ring of Fear Resistance
    a Chain Mail
    a Hatchet
tome-235-src/lib/help/g_yavann.txt0000644000076400017500000000604011012107760014724 0ustar  dgdg|||||oy
~~~~~01|Yavanna
~~~~~02|Gods|Yavanna
#####R === Yavanna Kementari===

Yavanna, the Giver of Fruits, created all plants and animals and awakened the
Ents to protect the forests of Arda. Kementari, Queen of the Earth, is her
surname. Her most faithful followers are the *****c_druid.txt*0[Druids].

#####GThe benefits of Worshipping Yavanna
1. As you increase your piety, Yavanna will grant you the ability to pass
   trees while praying.
2. She makes you regenerate faster while praying on grass.
3. She likes it when you kill nonliving creatures, undead or demons.
4. She likes it if you charm animals (except evil ones).
5. Yavanna likes Ents.

#####GThe disadvantages of Worshipping Yavanna
1. Your piety slowly decreases with time, whether you are praying or not.
2. She doesn't like it if you kill monsters while praying.
3. She hates it if you kill animals while praying.
4. She hates it if you hurt your animal pets.
5. She hates it if you burn or destroy trees with magic or allow monsters to
   do so.
6. She will completely abandon you if you wear The One Ring.
~~~~~03|Yavanna|Prayers
#####GYavanna's Magic
Worshipping Yavanna gives the adventurer access to a set of special spells
that come directly from the hands of Yavanna. These spells use your piety to
cast rather than your spellpoints, and the level of spells that Yavanna will
permit you to use is determined by your Prayer skill - how skillful you are
in asking for her help without offending her!

There is a special book called the "Forest Tome of Yavanna" which contains
instructions for the procedure for each of the prayers Yavanna will grant.
There are five prayers all told, which are:
1. [[[[[BCharm Animal] (Level 1)
   Tries to tame animals in a zone around your target.
2. [[[[[BGrow Grass] (Level 10)
   Creates a floor of grass around you. While on grass and praying,
   a worshipper of Yavanna will know a greater regeneration rate.
3. [[[[[BTree Roots] (Level 15)
   Creates roots deep in the floor from your feet, making you more stable and
   able to do better attacks, but preventing any movement (even teleportation).
   It also makes you recover from stunning almost immediately.
4. [[[[[BWater Bite] (Level 20)
   Imbues your melee weapon with a natural stream of water.
   At level 25, it spreads over a 1 radius zone around your target.
5. [[[[[BUproot] (Level 35)
   Awakes a tree to help you battle the forces of Morgoth.

Each of these spells can be increased in level both by improving your Prayer
skill, and by improving your Spell-power skill.

In addition to her specific magic, Yavanna will also assist with your ability
to use some magic from the "standard" schools, in relation to how skilled you
are at Prayer. These schools are as follows:
    *****m_earth.txt*0[Earth School] at 1/2 the Prayer skill level.
    *****m_nature.txt*0[Nature School] at 1/2 the Prayer skill level.
    *****m_water.txt*0[Water School] at 1/2 the Prayer skill level.
    *****m_tempo.txt*0[Temporal School] at 1/6 the Prayer skill level.
The spells from these schools are all cast using your normal spellpoints.
tome-235-src/lib/help/wishing.txt0000644000076400017500000000212011012107760014565 0ustar  dgdg~~~~~01|Spoilers|Wishing
#####R=== Wishes ===

Some items in ToME will grant the user the ability to "wish" for an
object that they are interested in. As such, these are generally very rare
and very powerful objects.

#####GRules for Wishes
Due to the powerful nature of wishes, there are some rules that govern 
what is able to be wished for. These rules are as follows:
1. You cannot wish for a wish, or any other item which would grant more
   wishes.
2. A wish will always generate *one* object. So, never put a number, "a"
   or "an" in front of the object you are wishing for.
3. It is not possible to wish for the magical +'s to the object (i.e. you
   cannot wish for "gloves of slaying (+10,+10)", but you can wish for 
   "gloves of slaying").
4. You cannot wish for artifacts, but you *can* wish for excellent (ego)
   items.
5. You can wish for monsters and ego monsters (e.g. "cave orc", "rogue cave
   orc").
6. You cannot wish for unique monsters.
7. You can wish the monster to have a specific flag - a pet, or a foe. 
   Possible flags include: enemy, neutral, friendly, pet, companion.
tome-235-src/lib/help/help.hlp0000644000076400017500000000240111012107760014013 0ustar  dgdg|||||oy
~~~~~01|Help|Main Menu
~~~~~02|Main Menu
#####RWelcome to the ToME Online Help System.
#####R==============================================

Please choose one of the following online help files:

    *****/ageneral.txt*0[(a) About this help system]
    *****/bnewbie.hlp*0[(b) Help for new players] Skills, magic, races, classes + more
    *****/cadvanced.hlp*0[(c) Help for more experienced players] Options, Macros, Automatizer etc
    *****/dtome_faq.txt*0[(d) ToME FAQ] Common questions
    
    *****/sspoiler.hlp*0[(s) Spoiler menu] Dungeons, fates, luck, corruptions and stuff


    *****/xindex.txt*0[(x) Alphabetical index] Trouble finding something? Try here

#####GBasic keys:
Space          | Advance 1 page (screen)
2, down arrow  | Advance 1 line
8, up arrow    | Back up 1 line
-              | Back up 1 page (screen)
6, right arrow | Advance 1 link
4, left arrow  | Back up 1 link
Return         | Activate the selected link
Escape         | Leave the Online Help
Backspace, ?   | Return to previous Help File
#              | Go to a specific line (defaults to line 0)
%              | Go to a specific help file (defaults to help.hlp)
=              | Highlight lines containing a string (e.g. "word")
/              | Search for a string (e.g. "word")

tome-235-src/lib/help/r_ent.txt0000644000076400017500000000250511012107760014233 0ustar  dgdg~~~~~01|Ent
~~~~~02|Races|Ent
#####R=== Ents ===

#####GDescription
The Ents are a powerful race dating back to the beginning of the world and
are the eldest of all animals or plants that inhabit Arda. Spirits of the land,
they were summoned to guard the forests of Middle-earth. Being much like
trees they are very slow but strong, and very susceptible to fire.
As the Shepherds of the Trees, they have the innate ability to cause trees to
rise about them for protection.

#####GStat Modifiers
Strength        +10   
Intelligence    -3   
Wisdom          +2   
Dexterity       -5   
Constitution    +11   
Charisma        -3       
Hit Dice Sides  14        
Exp Penalty     +110%

#####GRacial Skill Modifiers:
#####BSkill                Start Mod    Skill Point Gains Mod
Combat                  
  Weaponmastery        -0.300           [0.000]
  Archery	       -0.200           [0.000]
  Barehand-combat       0.000           [0.200]
  Boulder-throwing      0.000           [0.600]
Sneakiness              0.500           [0.000]
  Stealth              -6.000           [0.000]
  Disarming             0.500           [0.000]
Magic                   
  Magic-Device          0.500           [0.000]
Spirituality           10.000           [0.000]

#####GInnate Abilities:
#####BAbility              Character level
Tree-walking                1
tome-235-src/lib/help/r_drkelf.txt0000644000076400017500000000225611012107760014717 0ustar  dgdg~~~~~01|Dark Elf
~~~~~02|Races|Dark Elf
#####R=== Dark Elves ===

#####GDescription
Another dark, cave-dwelling race, likewise unhampered by darkness attacks,
the Dark Elves have a long tradition and knowledge of magic. With their 
intelligence and wisdom they can become superb mages or priests, and they
have an inherent magic missile attack available to them at a low level. With
their keen sight, they also learn to see invisible things as their relatives 
the High-Elves do, but at a higher level.

#####GStat Modifiers
Strength        -1   
Intelligence    +3   
Wisdom          +2   
Dexterity       +2   
Constitution    -2   
Charisma        +1       
Hit Dice Sides  9         
Exp Penalty     +50%

#####GRacial Skill Modifiers:
#####BSkill                Start Mod    Skill Point Gains Mod
Combat                  
  Weaponmastery        -0.500           [0.000]
  Archery		1.000           [0.000]
Sneakiness              0.800           [0.000]
  Stealth               3.000           [0.000]
  Disarming             0.500           [0.000]
Magic                   0.000           [0.200]
  Magic-Device          1.500           [0.000]
Spirituality           10.000           [0.000]
tome-235-src/lib/help/m_divin.txt0000644000076400017500000000341311012107760014550 0ustar  dgdg|||||oy
~~~~~01|Magic|Divination School
~~~~~02|Divination Magic
~~~~~03|Skills|Divination - Spell Info
#####R === ToME Magic - Divination School ===

The divination school of magic contains spells where magic is used to 
psychically gain information about things. There are rumours of a "Tome of 
Knowledge" which contains all the divination school spells within its bindings.

Worshipping the God Eru Iluvatar also gives the ability to cast spells from
the divination school at a level of 2/3 of your prayer level. E.g. if the 
skill "Spirituality: Prayer" is at level 12, you can cast up to level 8 
divination school spells.

#####sDivination Spells
There are six spells available for the divination school. These Spells are:
1. [[[[[sSense Monsters] (school level 1)
   Detects all monsters near you.
   At spell level 30 it allows you to sense monster minds for a while.
2. [[[[[sSense Hidden] (school level 5)
   Detects the traps in a certain radius around you.
   At spell level 15 it allows you to sense invisible monsters for a while.
3. [[[[[sIdentify] (school level 8)
   Asks for an object and identifies it.
   At spell level 17 it identifies all objects in the inventory.
   At spell level 27 it identifies all objects in the inventory and in a 
   radius on the floor, as well as probing monsters in that radius.
4. [[[[[sReveal Ways] (school level 9)
   Detects the doors/stairs/ways in a certain radius around you.
5. [[[[[sVision] (school level 15)
   Detects the layout of the surrounding area.
   At spell level 25 it maps and lights the whole level.
6. [[[[[sGreater Identify] (school level 35)
   Asks for an object and fully identifies it, providing the full list of 
   powers (as with a scroll of *Identify*).
   Cast at yourself, it will reveal your powers (Self Knowledge).
tome-235-src/lib/info/0000755000076400017500000000000011012107763012367 5ustar  dgdgtome-235-src/lib/info/delete.me0000644000076400017500000000000111012107760014140 0ustar  dgdgatome-235-src/lib/mods/0000755000076400017500000000000011012107764012377 5ustar  dgdgtome-235-src/lib/mods/mods_aux.lua0000644000076400017500000000776311012107761014733 0ustar  dgdg-- Ok some functions that we dont need are dangerous
--[[
execute = nil
getenv = nil
setlocale = nil
exit = nil
openfile = nil
writeto = nil
readfrom = nil
appendto = nil
remove = nil
rename = nil
tmpname = nil
]]
modules = {}

current_module = nil

function setup_module(mod)
	-- For standart game, nothing needs to be done
	if not mod.layout then return end

	for k, e in mod.layout do
		module_reset_dir(k, e)
	end
end

function init_module(i)
	setup_module(get_module(i))
end

function max_modules()
	local i = 0
	for k, e in modules do
		if type(k) == "number" and type(e) == "table" then
			i = i + 1
		end
	end
	return i
end

function get_module_name(j)
	local i = 0
	for k, e in modules do
		if type(k) == "number" and type(e) == "table" then
			if i == j then return e.name end
			i = i + 1
		end
	end
end

function get_module_desc(j)
	local i = 0
	for k, e in modules do
		if type(k) == "number" and type(e) == "table" then
			if i == j then return e.desc end
			i = i + 1
		end
	end
end

function get_module(j)
	local i = 0
	for k, e in modules do
		if type(k) == "number" and type(e) == "table" then
			if i == j then return e end
			i = i + 1
		end
	end
end

function find_module(name)
	local i = 0
	for k, e in modules do
		if type(k) == "number" and type(e) == "table" then
			if name == e.name then return i end
			i = i + 1
		end
	end
end

function assign_current_module(name)
	current_module = get_module(find_module(name))
end

function get_module_info(type, subtype)
	if subtype then
		return current_module[type][subtype]
	else
		return current_module[type]
	end
end

function exec_module_info(type, ...)
	return call(current_module[type], arg)
end

function module_savefile_loadable(savefile_mod, savefile_death)
	for _, e in current_module.mod_savefiles do
		if e[1] == savefile_mod then
			if e[2] == "all" then
				return TRUE
			elseif e[2] == "alive" and savefile_death == FALSE then
				return TRUE
			elseif e[2] == "dead" and savefile_death == TRUE then
				return TRUE
			end
		end
	end
	return FALSE
end

function scan_extra_modules()
	scansubdir(ANGBAND_DIR_MODULES)
	for i = 0, scansubdir_max - 1 do
		if (scansubdir_result[i + 1] ~= ".") and (scansubdir_result[i + 1] ~= "..") then
			local dir = path_build(ANGBAND_DIR_MODULES, scansubdir_result[i + 1])
			local file = path_build(dir, "module.lua")
			if file_exist(file) == TRUE then
				tome_dofile_anywhere(dir, "module.lua")
			end
		end
	end
end

function add_module(t)
	assert(t.name, "No module name")
	assert(type(t.version) == "table", "No module version")
	assert(t.desc, "No module desc")
	assert(t.author, "No module author")
	assert(t.mod_savefiles, "No loadable savefiles module mark")

	for _, e in modules do
		if type(e) == "table" and e.name == t.name then
			error("Module name already defined: "..t.name)
		end
	end

	if type(t.author) == "string" then
		t.author = { t.author, "unknown@unknown.net" }
	end

	for k, e in t.mod_savefiles do
		if type(e) == "string" then t.mod_savefiles[k] = { e, "all" } end
	end

	if type(t.desc) == "table" then
		local d = ""
		for k, e in t.desc do
			d = d .. e
			if k < getn(t.desc) then
				d = d .. "\n"
			end
		end
		t.desc = d
	end

	if not t.rand_quest then t.rand_quest = FALSE end
	if not t.C_quest then t.C_quest = FALSE end

	if not t.base_dungeon then t.base_dungeon = 4 end
	if not t.death_dungeon then t.death_dungeon = 28 end

	if not t.astral_dungeon then t.astral_dungeon = 8 end
	if not t.astral_wild_x then t.astral_wild_x = 45 end
	if not t.astral_wild_y then t.astral_wild_y = 19 end

	if not t.random_artifact_weapon_chance then
		t.random_artifact_weapon_chance = 30
	end
	if not t.random_artifact_armor_chance then
		t.random_artifact_armor_chance = 20
	end
	if not t.random_artifact_jewelry_chance then
		t.random_artifact_jewelry_chance = 20
	end

	if not t.max_plev then t.max_plev = 50 end
	if not t.max_skill_overage then t.max_skill_overage = 4 end
	if not t.skill_per_level then t.skill_per_level = function() return 6 end end

	if not t.allow_birth then t.allow_birth = TRUE end

	tinsert(modules, t)
end
tome-235-src/lib/mods/modules.lua0000644000076400017500000000015411012107761014547 0ustar  dgdg-- Load ToME
tome_dofile_anywhere(ANGBAND_DIR, "module.lua")

-- Look for more modules
scan_extra_modules()
tome-235-src/lib/mods/.cvsignore0000644000076400017500000000000511012107762014370 0ustar  dgdgtomk
tome-235-src/lib/note/0000755000076400017500000000000011012107763012401 5ustar  dgdgtome-235-src/lib/note/delete.me0000644000076400017500000000000111012107762014154 0ustar  dgdgatome-235-src/lib/plot/0000755000076400017500000000000011012107763012412 5ustar  dgdgtome-235-src/lib/pref/0000755000076400017500000000000011012107763012370 5ustar  dgdgtome-235-src/lib/pref/pref-win.prf0000644000076400017500000001405611012107762014635 0ustar  dgdg# File: pref-ibm.prf

#
# This file is used by Angband (when it was compiled using "main-ibm.c"
# or "main-dos.c" or "main-win.c") to specify various "user preferences",
# including "macros".
#
# This file defines some basic macros, which allow the use of the "keypad",
# alone, and with the shift and/or control modifier keys.  All "special"
# keys are translated by "main-ibm.c" (or "main-win.c") into special "macro
# triggers" of the encoded form "^_MMMxSS\r", where the "modifier" flags are
# stored in "MMM", and the two digit hexidecimal scan code of the keypress is
# stored in "SS".
#
# The "main-ibm.prf" and "main-dos.prf" files may not be able to recognize
# the "/" and "*" keys on the keypad, because it mistakenly classifies the
# "0x35" and "0x37" codes as the keycodes of "normal" keys.
#
# The "main-win.prf" file should not be using the final "control + keypad"
# section in this file, it was created for "main-ibm.c" and "main-dos.c".
#
# The "main-win.prf" file may actually send the "ascii" equivalent of some
# keypad keys after the keypad key itself, especially if "numlock" is down,
# which may cause problems.  Or it may not, it is hard to tell.  This is bad.
#
# See "main-ibm.c" and "main-dos.c" and "main-win.c" for more info.
#

#
# Macro Trigger configuration
#
# T:::::....
# '&' in  specifies location of modifier character.
# '#' in  specifies location of key code.
#
# If  is null string, all trigger difinition will be cleared.

T:&x#:CSA:control-:shift-:alt-

# T:::
# '\' in  is escape character.

# These keycodes are actually direct keyboard scan code taken from the 'dinput.h'.

?:[EQU $KEYBOARD JAPAN]
# For Japanese keyboard.
T:-:0C
T:^:0D
T:@:1A
T:[:1B
T:;:27
T:\::28
T:]:2B
T:,:33
T:.:34
T:\/:35
T:_:73
?:1

?:[EQU $KEYBOARD 0]
# For US keyboard.
T:-:0C
T:=:0D
T:[:1A
T:]:1B
T:;:27
T:\':28
T:`:29
T:\\:2B
T:,:33
T:.:34
T:\/:35
?:1

############
# Common keycodes (except NEC PC-98x1)

?:[NOT [EQU $KEYBOARD NEC98]]
T:1:02
T:2:03
T:3:04
T:4:05
T:5:06
T:6:07
T:7:08
T:8:09
T:9:0A
T:0:0B
T:Backspace:0E
T:Q:10
T:W:11
T:E:12
T:R:13
T:T:14
T:Y:15
T:U:16
T:I:17
T:O:18
T:P:19
T:Enter:1C
T:A:1E
T:S:1F
T:D:20
T:F:21
T:G:22
T:H:23
T:J:24
T:K:25
T:L:26
T:Zenkaku_Hankaku:29
T:Z:2C
T:X:2D
T:C:2E
T:V:2F
T:B:30
T:N:31
T:M:32
T:KP_Multiply:37
T:CapsLock:3A
T:F1:3B
T:F2:3C
T:F3:3D
T:F4:3E
T:F5:3F
T:F6:40
T:F7:41
T:F8:42
T:F9:43
T:F10:44
T:Numlock:45
T:Scroll:46
#T:KP_7:47
T:Home:47
#T:KP_8:48
T:Up:48
#T:KP_9:49
T:Page_Up:49
T:KP_Subtract:4A
#T:KP_4:4B
T:Left:4B
T:KP_5:4C
#T:KP_6:4D
T:Right:4D
T:KP_Add:4E
#T:KP_1:4F
T:End:4F
#T:KP_2:50
T:Down:50
#T:KP_3:51
T:Page_Down:51
#T:KP_0:52
T:Insert:52
#T:KP_Decimal:53
T:Delete:53
T:Oem_102:56
T:F11:57
T:F12:58
T:Menu:5D
T:F13:64
T:F14:65
T:F15:66
T:Hiragana_Katakana:70
T:Abnt_C1:73
T:Henkan:79
T:Muhenkan:7B
T:Yen:7D
T:Abnt_C2:7E
T:KP_equals:8D
T:Prevtrack:90
T:Kanji:94
T:Stop:95
T:Ax:96
T:Unlabeled:97
T:Nexttrack:99
T:KP_Enter:9C
T:Mute:A0
T:Calculator:A1
T:Playpause:A2
T:Mediastop:A4
T:Volumedown:AE
T:Volumeup:B0
T:Webhome:B2
T:KP_Comma:B3
T:KP_Divide:B5
T:Sys_Req:B7
T:Pause:C5
#T:Home:C7
#T:Up:C8
#T:Prior:C9
#T:Left:CB
#T:Right:CD
#T:End:CF
#T:Down:D0
#T:Next:D1
#T:Insert:D2
#T:Delete:D3
T:Lwin:DB
T:Rwin:DC
T:Apps:DD
T:Power:DE
T:Sleep:DF
T:Wake:E3
T:Websearch:E5
T:Webfavorites:E6
T:Webrefresh:E7
T:Webstop:E8
T:Webforward:E9
T:Webback:EA
T:Mycomputer:EB
T:Mail:EC
T:Mediaselect:ED
?:1


######################
# For NEC PC-98x1

?:[EQU $KEYBOARD NEC98]
T:1:01
T:2:02
T:3:03
T:4:04
T:5:05
T:6:06
T:7:07
T:8:08
T:9:09
T:0:0A
T:-:0B
T:^:0C
T:Yen:0D
T:Backspace:0E
T:Q:10
T:W:11
T:E:12
T:R:13
T:T:14
T:Y:15
T:U:16
T:I:17
T:O:18
T:P:19
T:@:1a
T:[:1b
T:Enter:1C
T:A:1D
T:S:1E
T:D:1F
T:F:20
T:G:21
T:H:22
T:J:23
T:K:24
T:L:25
T:;:26
T:\::27
T:[:28
T:Z:29
T:X:2A
T:C:2B
T:V:2C
T:B:2D
T:N:2E
T:M:2F
T:,:30
T:.:31
T:\/:32
T:_:33
T:Henkan:35
T:Page_Down:36
T:Page_Up:37
T:Insert:38
T:Delete:39
T:Up:3A
T:Left:3B
T:Right:3C
T:Down:3D
T:Home:3E
T:End:3F
T:KP_Subtract:40
T:KP_Divide:41
T:KP_7:42
T:KP_8:43
T:KP_9:44
T:KP_Multiply:45
T:KP_4:46
T:KP_5:47
T:KP_6:48
T:KP_Add:49
T:KP_1:4A
T:KP_2:4B
T:KP_3:4C
T:KP_Equal:4D
T:KP_0:4E
T:KP_Comma:4F
T:KP_Decimal:50
T:Muhenkan:51
T:F11:52
T:F12:53
T:F13:54
T:F14:55
T:F15:56
T:Pause:60
T:F1:62
T:F2:63
T:F3:64
T:F4:65
T:F5:66
T:F6:67
T:F7:68
T:F8:69
T:F9:6A
T:F10:6B
T:CapsLock:71
T:Hiragana_Katakana:72
T:Menu:79

?:[NOT [EQU $KEYBOARD NEC98]]


#
# Hack -- Some foreign keyboards have a special key on the keyboard, which
# is used to generate the "<", ">", and "|" keys (alone, shifted, alt-ed).
#

A:<
P:^_x56\r

A:>
P:^_Sx56\r

A:|
P:^_Ax56\r


#
# Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.)
#

A:/
P:^_x35\r

A:*
P:^_x37\r

A:7
P:^_x47\r

A:8
P:^_x48\r

A:9
P:^_x49\r

A:-
P:^_x4A\r

A:4
P:^_x4B\r

A:5
P:^_x4C\r

A:6
P:^_x4D\r

A:+
P:^_x4E\r

A:1
P:^_x4F\r

A:2
P:^_x50\r

A:3
P:^_x51\r

A:0
P:^_x52\r

A:.
P:^_x53\r


#
# Shift + Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.)
#

A:\e\e\e
P:^_Sx35\r

A:\e\e\e
P:^_Sx37\r

A:\e\e\\.7
P:^_Sx47\r

A:\e\e\\.8
P:^_Sx48\r

A:\e\e\\.9
P:^_Sx49\r

A:\e\e\e
P:^_Sx4A\r

A:\e\e\\.4
P:^_Sx4B\r

A:\e\e\\.5
P:^_Sx4C\r

A:\e\e\\.6
P:^_Sx4D\r

A:\e\e\e
P:^_Sx4E\r

A:\e\e\\.1
P:^_Sx4F\r

A:\e\e\\.2
P:^_Sx50\r

A:\e\e\\.3
P:^_Sx51\r

A:\e\e\e
P:^_Sx52\r

A:\e\e\e
P:^_Sx53\r


#
# Control + Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.)
#

A:\e\e\e
P:^_Cx35\r

A:\e\e\e
P:^_Cx37\r

A:\e\e\\+7
P:^_Cx47\r

A:\e\e\\+8
P:^_Cx48\r

A:\e\e\\+9
P:^_Cx49\r

A:\e\e\e
P:^_Cx4A\r

A:\e\e\\+4
P:^_Cx4B\r

A:\e\e\\+5
P:^_Cx4C\r

A:\e\e\\+6
P:^_Cx4D\r

A:\e\e\e
P:^_Cx4E\r

A:\e\e\\+1
P:^_Cx4F\r

A:\e\e\\+2
P:^_Cx50\r

A:\e\e\\+3
P:^_Cx51\r

A:\e\e\e
P:^_Cx52\r

A:\e\e\e
P:^_Cx53\r


#
# Control + Keypad (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.)
#

A:\e\e\e
P:^_Cx95\r

A:\e\e\e
P:^_Cx96\r

A:\e\e\\+7
P:^_Cx77\r

A:\e\e\\+8
P:^_Cx8D\r

A:\e\e\\+9
P:^_Cx84\r

A:\e\e\e
P:^_Cx8E\r

A:\e\e\\+4
P:^_Cx73\r

A:\e\e\\+5
P:^_Cx8F\r

A:\e\e\\+6
P:^_Cx74\r

A:\e\e\e
P:^_Cx90\r

A:\e\e\\+1
P:^_Cx75\r

A:\e\e\\+2
P:^_Cx91\r

A:\e\e\\+3
P:^_Cx76\r

A:\e\e\e
P:^_Cx92\r

A:\e\e\e
P:^_Cx93\r

tome-235-src/lib/pref/font-mac.new0000644000076400017500000000255711012107762014617 0ustar  dgdg# File: font-mac.prf

#
# This file is used by Angband (when it was compiled using "main-mac.c")
# to specify simple attr/char remappings using a standard font, allowing
# the use of the Macintosh's special characters for some things.
#


##### Feature attr/char definitions #####

# fountain
F:2:0x01/0xBA

# fountain
F:15:0x08/0xBA

# stream of shallow water
F:84:0x0E/0xC5

# pool of deep lava
F:85:0x0C/0xC5

# stream of shallow lava
F:86:0x04/0xC5

# dead tree
F:92:0x08/0xB4

# tree
F:96:0x0D/0xB4

# mountain chain
F:97:0x0F/0xC6

# high mountain chain
F:101:0x09/0xC6

# Void Jumpgate
F:160:0x0A/0xBD

# Altar of Being
F:161:0x09/0xB9

# Altar of Winds
F:162:0x0E/0xB9

# Altar of Force
F:163:0x0C/0xB9

# Altar of Darkness
F:164:0x08/0xB9

# stream of tainted water
F:174:0x07/0xC5

# Void Jumpgate
F:176:0x0A/0xBD

# Great Fire
F:178:0x0A/0xC5

# Ekkaia, the Encircling Sea
F:182:0x06/0xC5

# pool of deep water
F:187:0x06/0xC5

# small tree
F:202:0x05/0xB4

# a blazing fire
F:205:0x0B/0xC5

# condensing water
F:209:0x0E/0xC5


##### Monster attr/char definitions #####

# Old Man Willow
R:206:0x02/0xB4

# Tangleweed
R:248:0x05/0xB4

# Poison ivy
R:266:0x05/0xB4

# Giant Venus Flytrap
R:317:0x05/0xB4

# Huorn
R:329:0x05/0xB4

# Xiclotlan
R:396:0x08/0xB4

# Ent
R:708:0x0D/0xB4

# Quickbeam, the Ent
R:714:0x0D/0xB4

# Fangorn the Treebeard, Lord of the Ents
R:934:0x0D/0xB4


tome-235-src/lib/pref/font-mac.prf0000644000076400017500000000064111012107762014605 0ustar  dgdg# File: font.prf

#
# This file defines special attr/char mappings for use in "text" mode
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


## OPTION: Display "veins" (white "%") as "normal walls" (white "#") 
## This replaces the old method of setting "notice_seams" to false,
## which no longer works as of Angband 2.7.9, for various reasons.
#
#F:50:1/35
#F:51:1/35
#F:52:1/35
#F:53:1/35

tome-235-src/lib/pref/pref-iso.prf0000644000076400017500000000234211012107762014625 0ustar  dgdg# File: pref-sdl.prf

#
# This file provides some macros for use with versions of Angband compiled
# using the "main-x11.c" (or "main-xaw.c") file.
#
# Note the use of "\e\e\e\e" (four escapes) to allow the macros to work
# even if the game is not yet ready for a command.
#
# Note the use of "\\." (for "run") and "\\+" (for "alter"), to make sure
# that the macros will work regardless of the "keymap" being used.
#



# Keypad (0-9)

A:0
P:^__100\r

A:1
P:^__101\r

A:2
P:^__112\r
P:^__102\r

A:3
P:^__103\r

A:4
P:^__114\r
P:^__104\r

A:5
P:^__105\r

A:6
P:^__113\r
P:^__106\r

A:7
P:^__107\r

A:8
P:^__111\r
P:^__108\r

A:9
P:^__109\r


# Shift-Keypad (0-9)

A:\e\e\e\e\\.0
P:^_S_100\r

A:\e\e\e\e\\.1
P:^_S_101\r

A:\e\e\e\e\\.2
P:^_S_102\r

A:\e\e\e\e\\.3
P:^_S_103\r

A:\e\e\e\e\\.4
P:^_S_104\r

A:\e\e\e\e\\.5
P:^_S_105\r

A:\e\e\e\e\\.6
P:^_S_106\r

A:\e\e\e\e\\.7
P:^_S_107\r

A:\e\e\e\e\\.8
P:^_S_108\r

A:\e\e\e\e\\.9
P:^_S_109\r



# Control-Keypad (0-9)

A:\e\e\e\e\\+0
P:^_N_100\r

A:\e\e\e\e\\+1
P:^_N_101\r

A:\e\e\e\e\\+2
P:^_N_102\r

A:\e\e\e\e\\+3
P:^_N_103\r

A:\e\e\e\e\\+4
P:^_N_104\r

A:\e\e\e\e\\+5
P:^_N_105\r

A:\e\e\e\e\\+6
P:^_N_106\r

A:\e\e\e\e\\+7
P:^_N_107\r

A:\e\e\e\e\\+8
P:^_N_108\r

A:\e\e\e\e\\+9
P:^_N_109\r

tome-235-src/lib/pref/graf.prf0000644000076400017500000000126011012107762014016 0ustar  dgdg# File: graf.prf

#
# This file defines special attr/char mappings for use in "graphics" mode
#
# This file includes, if appropriate, various "sub-files"
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


##### Standard font file #####

%:font-xxx.prf


##### System Specific Subfiles #####

?:[IOR [EQU $SYS xaw] [EQU $SYS x11] [EQU $SYS gtk]]
%:graf-x11.prf

?:[EQU $SYS gcu]
%:graf-gcu.prf

?:[EQU $SYS ami]
%:graf-ami.prf

?:[EQU $SYS mac]
%:graf-mac.prf

?:[EQU $SYS dos]
%:graf-dos.prf

?:[EQU $SYS win]
%:graf-win.prf

?:[EQU $SYS ibm]
%:graf-ibm.prf

?:[EQU $SYS emx]
%:graf-emx.prf

?:[EQU $SYS acn]
%:graf-acn.prf

?:[EQU $SYS sdl]
%:graf-sdl.prf

?:1


tome-235-src/lib/pref/graf-new.prf0000644000076400017500000023417111012107762014616 0ustar  dgdg# PRF file generated by Andreas Koch`s Tile Assigner
# 23/06/2004 Edited manually

# 2460 items 
# 2312 probably mapped correctly
# 147 imported but not yet defined
# 1 defined to value(s) lower than 0x80
# Old header :
# File: graf-new.prf
#
# This file defines special attr/char mappings for use in "graphics" mode
# with Adam Bolt's 16x16 tiles.
#
# By Robert Ruehlmann < rr9@angband.org >
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#

# General Store
B:0:0x82/0x87

# Armoury
B:1:0x82/0x88

# Weaponsmith
B:2:0x82/0x89

# Temple
B:3:0x82/0x8A

# Alchemy shop
B:4:0x82/0x8B

# Magic shop
B:5:0x82/0x8C

# Black Market
B:6:0x82/0x8D

# Home
B:7:0x82/0x8E

# Book Store
B:8:0x82/0x8F

# Pet Shop
B:9:0x82/0x90

# Mayor's Office
B:10:0x86/0xA0

# Inn
B:11:0x86/0xA1

# The Soothsayer
B:12:0x86/0xA2

# Library
B:13:0x86/0xA3

# Castle
B:14:0x86/0xA4

# Casino
B:15:0x86/0xA5

# Beastmaster Shanty
B:16:0x86/0xA6

# Fighters Hall
B:17:0x86/0xA7

# Tower of Magery
B:18:0x86/0xA8

# Inner Temple
B:19:0x86/0xA9

# Paladins Guild
B:20:0x86/0xAA

# Rangers Guild
B:21:0x86/0xAB

# Thunderlords' Hide
B:22:0x86/0xAC

# The Mirror
B:23:0x86/0xAD

# Seat of Ruling
B:24:0x86/0xAE

# Wizards Spire
B:25:0x86/0xAF

# Priests Circle
B:26:0x86/0xB0

# Tower of the King
B:27:0x86/0xB1

# Library
B:28:0x86/0xA3

# The White Tree
B:29:0x86/0xB2

# Craftsmaster
B:30:0x86/0xB3

# Earth-Dome (Nature)
B:31:0x86/0xB4

# Minstrels Haven
B:32:0x86/0xB5

# Star-Dome
B:33:0x86/0xB6

# Valarin Temple
B:34:0x86/0xB7

# Sea-Dome
B:35:0x86/0xB8

# The Golden Flower
B:36:0x86/0xB9

# The Fountain
B:37:0x86/0xBA

# Axe Smith
B:38:0x86/0xBB

# Hafted Smith
B:39:0x86/0xBC

# Polearm Smith
B:40:0x86/0xBD

# Sword Smith
B:41:0x86/0xBE

# Rare Jewelry Shop
B:42:0x86/0xBF

# Jewelry Shop
B:43:0x87/0xA0

# Footwear Shop
B:44:0x87/0xA1

# Rare Footwear Shop
B:45:0x87/0xA2

# Library
B:46:0x86/0xA3

# Forbidden Library
B:47:0x87/0xA3

# Expensive Black Market
B:48:0x87/0xA4

# Common Shop
B:49:0x87/0xA5

# Dragon Hunter
B:50:0x87/0xA6

# Speed Ring Market
B:51:0x87/0xA7

# Scribe
B:52:0x87/0xA8

# Potion Store
B:53:0x87/0xA9

# Recaller
B:54:0x87/0xAA

# Master Archer
B:55:0x87/0xAB

# Merchants Guild
B:56:0x87/0xAC

# The Mathom-house
B:57:0x87/0xAD

# The Prancing Pony
B:58:0x86/0xA1

# nothing
F:0:0x80/0x80

# open floor
F:1:0x80/0x81

# fountain
F:2:0xC3/0x9A

# glyph of warding
F:3:0x8D/0x95

# open door
F:4:0x82/0x84

# broken door
F:5:0x82/0x85

# up staircase
F:6:0x80/0x96

# down staircase
F:7:0x80/0x99

# quest entrance
F:8:0x80/0x9A

# quest exit
F:9:0x80/0x97

# quest down level
F:10:0x80/0x9B

# quest up level
F:11:0x80/0x98

# town exit
F:12:0x82/0x84

# shaft down
F:13:0xC3/0x84

# shaft up
F:14:0xC3/0x85

# fountain
F:15:0xC3/0x99

# web
F:16:0x81/0x8C

# trap
F:17:0x81/0x89

# visible trap -- spiked pit
F:18:0x81/0x89

# visible trap -- poison pit
F:19:0x81/0x89

# visible trap -- rune -- summon
F:20:0x81/0x8F

# visible trap -- rune -- teleport
F:21:0x81/0x92

# visible trap -- spot -- fire
F:22:0x81/0x86

# visible trap -- spot -- acid
F:23:0x81/0x86

# visible trap -- dart -- slow
F:24:0x81/0x80

# visible trap -- dart -- lose str
F:25:0x81/0x80

# visible trap -- dart -- lose dex
F:26:0x81/0x80

# visible trap -- dart -- lose con
F:27:0x81/0x80

# visible trap -- gas -- blind
F:28:0x81/0x83

# visible trap -- gas -- confuse
F:29:0x81/0x83

# visible trap -- gas -- poison
F:30:0x81/0x83

# visible trap -- gas -- sleep
F:31:0x81/0x83

# door
F:32:0x82/0x83

# locked door
F:33:0x82/0x83
F:34:0x82/0x83
F:35:0x82/0x83
F:36:0x82/0x83
F:37:0x82/0x83
F:38:0x82/0x86
F:39:0x82/0x86

# jammed door
F:40:0x82/0x83
F:41:0x82/0x83
F:42:0x82/0x83
F:43:0x82/0x83
F:44:0x82/0x83
F:45:0x82/0x86
F:46:0x82/0x86
F:47:0x82/0x86

# secret door
F:48:0x80/0x84

# pile of rubble
F:49:0x80/0x9C

# magma vein
F:50:0x80/0x8D

# quartz vein
F:51:0x80/0x87

# magma vein
F:52:0x80/0x90

# quartz vein
F:53:0x80/0x87

# magma vein with treasure
F:54:0x80/0x90

# quartz vein with treasure
F:55:0x80/0x8A

# granite wall
F:56:0x80/0x84
F:57:0x80/0x84
F:58:0x80/0x84
F:59:0x80/0x84

# permanent wall
F:60:0x80/0x93
F:61:0x80/0x93
F:62:0x80/0x93
F:63:0x80/0x93

# explosive rune
F:64:0x8D/0x9E

# Straight Road startpoint
F:65:0x81/0x95

# section of the Straight Road
F:66:0x81/0x95
F:67:0x81/0x95
F:68:0x81/0x95
F:69:0x81/0x95
F:70:0x81/0x95

# section of the Straight Road (discharged)
F:71:0x81/0x98

# Straight Road exit
F:72:0x81/0x9B

# corrupted section of the Straight Road
F:73:0x81/0x9E

# Building
F:74:0x82/0x93

# permanent wall
F:75:0x82/0x93
F:76:0x82/0x94
F:77:0x82/0x95
F:78:0x82/0x96

# stream of shallow water
F:84:0xB4/0x97

# pool of deep lava
F:85:0x83/0x8D

# stream of shallow lava
F:86:0xB4/0x9A

# dark pit
F:87:0x80/0x80

# dirt
F:88:0xB4/0x91

# patch of grass
F:89:0xB4/0x94

# ice
F:90:0xC3/0x83

# sand
F:91:0xC3/0x88

# dead tree
F:92:0xC3/0x98

# ash
F:93:0xC3/0x97

# mud
F:94:0xC3/0x96

# ice wall
F:95:0xC5/0x92

# tree
F:96:0x82/0x9A

# mountain chain
F:97:0x8D/0x98

# sandwall
F:98:0xC3/0x86
F:99:0xC3/0x86

# sandwall with treasure
F:100:0xC3/0x87

# high mountain chain
F:101:0xC3/0x9E

# nether mist
F:102:0xC3/0x9F

# Void Jumpgate
F:160:0x91/0x84

# Altar of Being
F:161:0xC1/0x8E

# Altar of Winds
F:162:0xB5/0x8A

# Altar of Force
F:163:0xB5/0x86

# Altar of Darkness
F:164:0xB5/0x86

# Altar of Nature
F:165:0xB5/0x91

# Altar of Sun
F:166:0xB5/0x8F

# Altar of Rage
F:167:0xB5/0x8C

# Altar of Winds
F:168:0xB5/0x92

# Altar of Stars
F:169:0xC1/0x8F

# Altar of Being
F:170:0xB5/0x8D

# Altar of Randomness
F:171:0xB5/0x88

# floor
F:172:0x80/0x81

# Underground Tunnel
F:173:0x80/0x82

# stream of tainted water
F:174:0xAF/0x8E

# monster trap
F:175:0x81/0x9C

# Void Jumpgate
F:176:0xAF/0x8C

# lava wall
F:177:0xC6/0x8C

# Great Fire
F:178:0xC6/0x8A

# path to the next area
F:179:0x88/0xA1

# path to the previous area
F:180:0x88/0xA0

# field
F:181:0x88/0xA2

# Ekkaia, the Encircling Sea
F:182:0x88/0xA3

# Altar of Energy
F:183:0xB5/0x9A

# Altar of Matter
F:184:0xB5/0x9B

# Altar of Being
F:185:0xB5/0x9C

# Altar of Unbeing
F:186:0xB5/0x9D

# pool of deep water
F:187:0x83/0x80

# glass wall
F:188:0xC0/0x9F

# illusion wall
F:189:0x80/0x84

# Grass roof
F:190:0xC2/0x80

# grass roof top
F:191:0xC2/0x81

# grass roof chimney
F:192:0xC2/0x82

# brick roof
F:193:0xC3/0x80

# brick roof top
F:194:0xC3/0x81

# brick roof chimney
F:195:0xC3/0x82

# window
F:196:0xC2/0x83

# small window
F:197:0xC2/0x84

# rain barrel
F:198:0xC2/0x85

# grass with flowers
F:199:0xC2/0x86

# cobblestone road
F:200:0xC2/0x87

# cobblestone with outlet
F:201:0xC2/0x88

# small tree
F:202:0x82/0x9D

# town
F:203:0xC3/0x95

# Underground Tunnel
F:204:0x80/0x82

# a blazing fire
F:205:0xC6/0x8A

# pile of rubble
F:206:0xC6/0x8B

# ethereal wall
F:214:0x80/0x81

# glacial wall
F:215:0xC5/0x92

# Skeleton
G:M:1:0xC6/0x91

# Zombie
G:M:2:0xC6/0x92

# Lich
G:M:3:0xC6/0x93

# Spectral
G:M:4:0xC6/0x94

# Captain
G:M:5:0xC6/0x95

# Chieftain
G:M:6:0xC6/0x96

# Shaman
G:M:7:0xC6/0x97

# Priest
G:M:8:0xC6/0x98

# Mage
G:M:9:0xC6/0x99

# Archer
G:M:10:0xC6/0x9A

# Rogue
G:M:11:0xC6/0x9B

# Vampire
G:P:1:0x88/0xA4

# Spectre
G:P:2:0x88/0xA5

# Skeleton
G:P:3:0xC6/0x91

# Zombie
G:P:4:0xC6/0x92

# Barbarian
G:P:5:0x88/0xA6

# Hermit
G:P:6:0x88/0xA7

# Corrupted
G:P:7:0x88/0xA8

# LostSoul
G:P:8:0x88/0xA9

# something
K:0:0x01/0x20

# Blindness
K:1:0x85/0x94

# Paranoia
K:2:0x85/0x94

# Confusion
K:3:0x85/0x94

# Hallucination
K:4:0x85/0x94

# Cure Poison
K:5:0x85/0x94

# Cure Blindness
K:6:0x85/0x94

# Cure Paranoia
K:7:0xC6/0x83

# Cure Confusion
K:8:0x85/0x94

# Weakness
K:9:0x85/0x94

# Unhealth
K:10:0x85/0x94

# Restore Constitution
K:11:0x85/0x94

# Restoring
K:12:0x85/0x94

# Stupidity
K:13:0x85/0x94

# Naivety
K:14:0x85/0x94

# Poison
K:15:0x85/0x94

# Sickness
K:16:0x85/0x94

# Paralysis
K:17:0x85/0x94

# Restore Strength
K:18:0x85/0x94

# Disease
K:19:0x85/0x94

# Cure Serious Wounds
K:20:0x85/0x94

# & Ration~ of Food
K:21:0x8E/0x84

# & Hard Biscuit~
K:22:0x8E/0x82

# & Strip~ of Venison
K:23:0x8E/0x83

# & Slime Mold~
K:24:0x8E/0x85

# & Lembas~
K:25:0x8E/0x86

# & Pint~ of Fine Ale
K:26:0x8E/0x80

# & Pint~ of Fine Wine
K:27:0x8E/0x80

# & Mattock~
K:28:0xB6/0x8C

# & Blue Stone~
K:29:0xC5/0x93

# & Broken Dagger~
K:30:0x8A/0x8D

# & Bastard Sword~
K:31:0x8A/0x8E

# & Scimitar~
K:32:0x8A/0x97

# & Tulwar~
K:33:0x8A/0x95

# & Broad Sword~
K:34:0x8A/0x98

# & Short Sword~
K:35:0x8A/0x94

# & Blade~ of Chaos
K:36:0x8A/0x9E

# & Two-Handed Sword~
K:37:0x8A/0x9C

# & Main Gauche~
K:38:0x8A/0x90

# & Cutlass~
K:39:0x8A/0x96

# & Executioner's Sword~
K:40:0x8A/0x9D

# & Katana~
K:41:0x8A/0x9B

# & Long Sword~
K:42:0x8A/0x99

# & Dagger~
K:43:0x8A/0x8F

# & Rapier~
K:44:0x8A/0x91

# & Sabre~
K:45:0x8A/0x93

# & Small Sword~
K:46:0x8A/0x92

# & Broken Sword~
K:47:0x8A/0x8E

# & Ball-and-Chain~
K:48:0x8B/0x86

# & Whip~
K:49:0x8A/0x9F

# & Flail~
K:50:0x8B/0x83

# & Two-Handed Flail~
K:51:0x8B/0x87

# & Morning Star~
K:52:0x8B/0x84

# & Mace~
K:53:0x8B/0x81

# & Quarterstaff~
K:54:0x8B/0x82

# & War Hammer~
K:55:0x8B/0x80

# & Lead-Filled Mace~
K:56:0x8B/0x85

# & Mace~ of Disruption
K:57:0x8B/0x88

# & Lucerne Hammer~
K:58:0x8B/0x8D

# & Beaked Axe~
K:59:0x8B/0x90

# & Glaive~
K:60:0x8B/0x92

# & Halberd~
K:61:0x8B/0x93

# & Awl-Pike~
K:62:0x8B/0x8B

# & Pike~
K:63:0x8B/0x8F

# & Spear~
K:64:0x8B/0x89

# & Trident~
K:65:0x8B/0x8A

# & Lance~
K:66:0x8B/0x8C

# & Great Axe~
K:67:0x8B/0x95

# & Battle Axe~
K:68:0x8B/0x8E

# & Lochaber Axe~
K:69:0x8B/0x94

# & Broad Axe~
K:70:0x8B/0x91

# & Scythe~
K:71:0x8B/0x96

# & Scythe~ of Slicing
K:72:0x8B/0x97

# & Short Bow~
K:73:0x8B/0x98

# & Long Bow~
K:74:0x8B/0x99

# & Light Crossbow~
K:75:0x8B/0x9A

# & Heavy Crossbow~
K:76:0x8B/0x9B

# & Sling~
K:77:0x8B/0x9C

# & Arrow~
K:78:0x8C/0x80

# & Seeker Arrow~
K:79:0x8C/0x81

# & Bolt~
K:80:0x8C/0x82

# & Seeker Bolt~
K:81:0x8C/0x83

# & Rounded Pebble~
K:82:0x8C/0x84

# & Iron Shot~
K:83:0x8C/0x85

# & Shovel~
K:84:0x8E/0x8F

# & Gnomish Shovel~
K:85:0x8E/0x90

# & Dwarven Shovel~
K:86:0x8E/0x91

# & Pick~
K:87:0x8E/0x8C

# & Orcish Pick~
K:88:0x8E/0x8D

# & Dwarven Pick~
K:89:0x8E/0x91

# & Elven Cloak~
K:90:0x89/0x89

# & Pair~ of Soft Leather Boots
K:91:0x88/0x8E

# & Pair~ of Hard Leather Boots
K:92:0x88/0x8F

# & Pair~ of Metal Shod Boots
K:93:0x88/0x90

# & Hard Leather Cap~
K:94:0x87/0x98

# & Metal Cap~
K:95:0x87/0x99

# & Iron Helm~
K:96:0x87/0x9A

# & Steel Helm~
K:97:0x87/0x9B

# & Iron Crown~
K:98:0x87/0x9C

# & Golden Crown~
K:99:0x87/0x9D

# & Jewel Encrusted Crown~
K:100:0x87/0x9E

# & Robe~
K:101:0x89/0x8C

# & Filthy Rag~
K:102:0x89/0x8B

# Soft Leather Armour~
K:103:0x89/0x8D

# Soft Studded Leather~
K:104:0x89/0x8E

# Hard Leather Armour~
K:105:0x89/0x8F

# Hard Studded Leather~
K:106:0x89/0x90

# Leather Scale Mail~
K:107:0x89/0x91

# Metal Scale Mail~
K:108:0x89/0x92

# Chain Mail~
K:109:0x89/0x94

# Rusty Chain Mail~
K:110:0x89/0x93

# Augmented Chain Mail~
K:111:0x89/0x96

# Bar Chain Mail~
K:112:0x89/0x97

# Metal Brigandine Armour~
K:113:0x89/0x98

# Partial Plate Armour~
K:114:0x89/0x99

# Metal Lamellar Armour~
K:115:0x89/0x9A

# Full Plate Armour~
K:116:0x89/0x9B

# Ribbed Plate Armour~
K:117:0x89/0x9C

# Adamantite Plate Mail~
K:118:0x89/0x9F

# Mithril Plate Mail~
K:119:0x89/0x9E

# Mithril Chain Mail~
K:120:0x89/0x9D

# Double Chain Mail~
K:121:0x89/0x95

# & Shield~ of Deflection
K:122:0x88/0x98

# & Cloak~
K:123:0x89/0x88

# & Shadow Cloak~
K:124:0x89/0x89

# & Set~ of Leather Gloves
K:125:0x88/0x91

# & Set~ of Gauntlets
K:126:0x88/0x92

# & Set~ of Cesti
K:127:0x88/0x93

# & Small Leather Shield~
K:128:0x88/0x94

# & Large Leather Shield~
K:129:0x88/0x95

# & Small Metal Shield~
K:130:0x88/0x96

# & Large Metal Shield~
K:131:0x88/0x97

# Strength
K:132:0x84/0x81

# Dexterity
K:133:0x84/0x83

# Constitution
K:134:0x84/0x83

# Intelligence
K:135:0x84/0x83

# Speed
K:136:0x84/0x83

# Searching
K:137:0x84/0x83

# Teleportation
K:138:0x84/0x83

# Slow Digestion
K:139:0x84/0x83

# Fire Resistance
K:140:0x84/0x83

# Cold Resistance
K:141:0x84/0x83

# Levitation
K:142:0x84/0x83

# Poison Resistance
K:143:0x84/0x83

# Free Action
K:144:0x84/0x83

# Weakness
K:145:0x84/0x83

# Flames
K:146:0x84/0x83

# Acid
K:147:0x84/0x83

# Ice
K:148:0x84/0x83

# Woe
K:149:0x84/0x83

# Stupidity
K:150:0x84/0x83

# Damage
K:151:0x84/0x83

# Accuracy
K:152:0x84/0x83

# Protection
K:153:0x84/0x83

# Aggravate Monster
K:154:0x84/0x83

# See Invisible
K:155:0x84/0x83

# Sustain Strength
K:156:0x84/0x83

# Sustain Intelligence
K:157:0x84/0x83

# Sustain Wisdom
K:158:0x84/0x83

# Sustain Constitution
K:159:0x84/0x83

# Sustain Dexterity
K:160:0x84/0x83

# Sustain Charisma
K:161:0x84/0x83

# Slaying
K:162:0x84/0x83

# Brilliance
K:163:0x87/0x83

# Charisma
K:164:0x87/0x83

# Searching
K:165:0x87/0x83

# Teleportation
K:166:0x87/0x83

# Slow Digestion
K:167:0x87/0x83

# Acid Resistance
K:168:0x87/0x83

# Adornment
K:169:0x87/0x83

# Double Ring Mail~
K:170:0x89/0x9B

# the Magi
K:171:0x87/0x83

# Doom
K:172:0x87/0x83

# Enchant Weapon To-Hit
K:173:0x83/0x9C

# Enchant Weapon To-Dam
K:174:0x83/0x9C

# Enchant Armor
K:175:0x83/0x9C

# Identify
K:176:0x83/0x9C

# *Identify*
K:177:0x83/0x9C

# Rumour
K:178:0x83/0x9C

# Chaos
K:179:0x83/0x9C

# Remove Curse
K:180:0x83/0x9C

# Light
K:181:0x83/0x9C

# Fire
K:182:0x83/0x9C

# Ice
K:183:0x83/0x9C

# Summon Monster
K:184:0x83/0x9C

# Phase Door
K:185:0x83/0x9C

# Teleportation
K:186:0x83/0x9C

# Teleport Level
K:187:0x83/0x9C

# Monster Confusion
K:188:0x83/0x9C

# Magic Mapping
K:189:0x83/0x9C

# Rune of Protection
K:190:0x83/0x9C

# *Remove Curse*
K:191:0x83/0x9C

# Treasure Detection
K:192:0x83/0x9C

# Object Detection
K:193:0x83/0x9C

# Trap Detection
K:194:0x83/0x9C

# & Sheaf Arrow~
K:195:0x8C/0x81

# & Mithril Shot~
K:196:0x8C/0x85

# Door
K:197:0x83/0x9C

# Acquirement
K:198:0x83/0x9C

# *Acquirement*
K:199:0x83/0x9C

# Mass Genocide
K:200:0x83/0x9C

# Detect Invisible
K:201:0x83/0x9C

# Aggravate Monster
K:202:0x83/0x9C

# Trap Creation
K:203:0x83/0x9C

# Trap
K:204:0x83/0x9C

# Artifact Creation
K:205:0x83/0x9C

# Recharging
K:206:0x83/0x9C

# Genocide
K:207:0x83/0x9C

# Darkness
K:208:0x83/0x9C

# Protection from Evil
K:209:0x83/0x9C

# Satisfy Hunger
K:210:0x83/0x9C

# Dispel Undead
K:211:0x83/0x9C

# *Enchant Weapon*
K:212:0x83/0x9C

# Curse Weapon
K:213:0x83/0x9C

# *Enchant Armor*
K:214:0x83/0x9C

# Curse Armor
K:215:0x83/0x9C

# Summon Undead
K:216:0x83/0x9C

# Blessing
K:217:0x83/0x9C

# Holy Chant
K:218:0x83/0x9C

# Holy Prayer
K:219:0x83/0x9C

# Word of Recall
K:220:0x83/0x9C

# *Destruction*
K:221:0x83/0x9C

# Slime Mold Juice
K:222:0x85/0x85

# Apple Juice
K:223:0x85/0x85

# Water
K:224:0x85/0x85

# Strength
K:225:0x85/0x85

# Weakness
K:226:0x85/0x85

# Restore Strength
K:227:0x85/0x85

# Intelligence
K:228:0x85/0x85

# Stupidity
K:229:0x85/0x85

# Restore Intelligence
K:230:0x85/0x85

# Wisdom
K:231:0x85/0x85

# Naivety
K:232:0x85/0x85

# Restore Wisdom
K:233:0x85/0x85

# Charisma
K:234:0x85/0x85

# Ugliness
K:235:0x85/0x85

# Restore Charisma
K:236:0x85/0x85

# Curing
K:237:0x85/0x85

# Invulnerability
K:238:0x85/0x85

# New Life
K:239:0x85/0x85

# Cure Serious Wounds
K:240:0x85/0x85

# Cure Critical Wounds
K:241:0x85/0x85

# Healing
K:242:0x85/0x85

# Constitution
K:243:0x85/0x85

# Experience
K:244:0x85/0x85

# Sleep
K:245:0x85/0x85

# Blindness
K:246:0x85/0x85

# Booze
K:247:0x85/0x85

# Poison
K:248:0x85/0x85

# Speed
K:249:0x85/0x85

# Slowness
K:250:0x85/0x85

# Dexterity
K:251:0x85/0x85

# Restore Dexterity
K:252:0x85/0x85

# Restore Constitution
K:253:0x85/0x85

# Lose Memories
K:254:0x85/0x85

# Salt Water
K:255:0x85/0x85

# Enlightenment
K:256:0x85/0x85

# Heroism
K:257:0x85/0x85

# Berserk Strength
K:258:0x85/0x85

# Boldness
K:259:0x85/0x85

# Restore Life Levels
K:260:0x85/0x85

# Resist Heat
K:261:0x85/0x85

# Resist Cold
K:262:0x85/0x85

# Detect Invisible
K:263:0x85/0x85

# Slow Poison
K:264:0x85/0x85

# Neutralise Poison
K:265:0x85/0x85

# Restore Mana
K:266:0x85/0x85

# Infra-vision
K:267:0x85/0x85

# Resistance
K:268:0x85/0x85

# Spell
K:269:0x86/0x93

# Manathrust
K:270:0x86/0x93

# Fireflash
K:271:0x86/0x93

# Firewall
K:272:0x86/0x93

# Tidal Wave
K:273:0x86/0x93

# Ice Storm
K:274:0x86/0x93

# Noxious Cloud
K:275:0x86/0x93

# Poison Blood
K:276:0x86/0x93

# Thunderstorm
K:277:0x86/0x93

# Dig
K:278:0x86/0x93

# Stone Prison
K:279:0x86/0x93

# Strike
K:280:0x86/0x93

# Teleport Away
K:281:0x86/0x93

# Summon Animal
K:282:0x86/0x93

# Magelock
K:283:0x86/0x93

# Slow Monster
K:284:0x86/0x93

# Essence of Speed
K:285:0xB7/0x8C

# Banishment
K:286:0x86/0x93

# Disperse Magic
K:287:0x86/0x93

# Charm
K:288:0x86/0x93

# Confuse
K:289:0x86/0x93

# Demon Blade
K:290:0x86/0x93

# Heal Monster
K:291:0x86/0x93

# Haste Monster
K:292:0x86/0x93

# & Flight Arrow~
K:293:0x8C/0x81

# Acid Bolts
K:294:0x86/0x93

# Dragon's Flame
K:295:0x86/0x93

# Dragon's Frost
K:296:0x86/0x93

# Dragon's Breath
K:297:0x86/0x93

# Annihilation
K:298:0x86/0x93

# Rockets
K:299:0x86/0x93

# Spell
K:300:0x87/0x92

# Nothing
K:301:0x87/0x92

# Globe of Light
K:302:0x87/0x92

# Fiery Shield
K:303:0x87/0x92

# Remove Curses
K:304:0x87/0x92

# Wings of Winds
K:305:0x87/0x92

# Shake
K:306:0x87/0x92

# Disarm
K:307:0x87/0x92

# Teleportation
K:308:0x87/0x92

# Probability Travel
K:309:0x87/0x92

# Recovery
K:310:0x87/0x92

# Healing
K:311:0x87/0x92

# Vision
K:312:0x87/0x92

# Identify
K:313:0x87/0x92

# Sense Hidden
K:314:0x87/0x92

# Reveal Ways
K:315:0x87/0x92

# Sense Monsters
K:316:0x87/0x92

# Genocide
K:317:0x87/0x92

# Summon
K:318:0x87/0x92

# Curing
K:319:0x87/0x92

# Wish
K:320:0x87/0x92

# Mana
K:321:0x87/0x92

# Darkness
K:322:0x87/0x92

# Genocide
K:323:0x87/0x92

# Power
K:324:0x87/0x92

# the Magi
K:325:0x87/0x92

# Perception
K:326:0x87/0x92

# Holiness
K:327:0x87/0x92

# Enlightenment
K:328:0x87/0x92

# Healing
K:329:0x87/0x92

# & Tome~ of Magical Energy
K:330:0x90/0xA0

# & Tome~ of the Eternal Flame
K:331:0x90/0xA1

# & Tome~ of the Blowing Wind
K:332:0x90/0xA2

# & Tome~ of the Impenetrable Earth
K:333:0x90/0xA3

# & Tome~ of the Everrunning Wave
K:334:0x90/0xA4

# & Tome~ of Translocation
K:335:0x90/0xA5

# & Tome~ of the Tree
K:336:0x90/0xA6

# & Tome~ of Knowledge
K:337:0x90/0xA7

# & Small wooden chest~
K:338:0x84/0x99

# & Large wooden chest~
K:339:0x84/0x9A

# & Small iron chest~
K:340:0x84/0x9B

# & Large iron chest~
K:341:0x84/0x9C

# & Small steel chest~
K:342:0x84/0x9D

# & Large steel chest~
K:343:0x84/0x9E

# & Ruined chest~
K:344:0x84/0x9F

# & Iron Spike~
K:345:0x8E/0x89

# & Wooden Torch~
K:346:0x8E/0x8B

# & Brass Lantern~
K:347:0x8E/0x8A

# & Flask~ of oil
K:348:0x8E/0x88

# & Empty Bottle~
K:349:0x8E/0x87

# Havoc
K:350:0x86/0x83

# Door
K:351:0x86/0x83

# Trap Location
K:352:0x86/0x83

# Probing
K:353:0x86/0x83

# Recall
K:354:0x86/0x83

# Illumination
K:355:0x86/0x83

# Light
K:356:0x86/0x83

# Lightning Bolts
K:357:0x86/0x83

# Frost Bolts
K:358:0x86/0x83

# Fire Bolts
K:359:0x86/0x83

# Polymorph
K:360:0x86/0x83

# Slow Monster
K:361:0x86/0x83

# Sleep Monster
K:362:0x86/0x83

# Drain Life
K:363:0x86/0x83

# Teleport Other
K:364:0x86/0x83

# Disarming
K:365:0x86/0x83

# Lightning Balls
K:366:0x86/0x83

# Cold Balls
K:367:0x86/0x83

# Fire Balls
K:368:0x86/0x83

# Acid Balls
K:369:0x86/0x83

# Acid Bolts
K:370:0x86/0x83

# Enlightenment
K:371:0x86/0x83

# Perception
K:372:0x86/0x83

# Curing
K:373:0x86/0x83

# Healing
K:374:0x86/0x83

# Detection
K:375:0x86/0x83

# Restoration
K:376:0x86/0x83

# Speed
K:377:0x86/0x83

# Spell
K:378:0xC1/0x84
K:379:0x8D/0x80

# [Beings of Darkness]
K:380:0x8D/0x81

# [Material Shadow]
K:381:0x8D/0x82

# [Nature's Wrath]
K:382:0x8D/0x83

# [Sign of Chaos]
K:383:0x8C/0x98

# [Chaos Mastery]
K:384:0x8C/0x99

# [Chaos Channels]
K:385:0x8C/0x9A

# [Armageddon Tome]
K:386:0x8C/0x9B

# [Nether Openings]
K:387:0x8D/0x88

# [Unholy Blessings]
K:388:0x8D/0x89

# & Firestone~
K:389:0x8E/0x92

# & Small Firestone~
K:390:0x8E/0x93

# & Broken Skull~
K:391:0x8E/0x94

# & Broken Bone~
K:392:0x8E/0x95

# & Canine Skeleton~
K:393:0x8E/0x9A

# & Rodent Skeleton~
K:394:0x8E/0x9B

# & Human Skeleton~
K:395:0x8E/0x96

# & Dwarf Skeleton~
K:396:0x8E/0x98

# & Elf Skeleton~
K:397:0x8E/0x97

# & Gnome Skeleton~
K:398:0x8E/0x99

# & Great Hammer~
K:399:0xB6/0x8A

# Black Dragon Scale Mail~
K:400:0x8A/0x82

# Blue Dragon Scale Mail~
K:401:0x8A/0x80

# White Dragon Scale Mail~
K:402:0x8A/0x81

# Red Dragon Scale Mail~
K:403:0x8A/0x83

# Green Dragon Scale Mail~
K:404:0x8A/0x84

# Multi-Hued Dragon Scale Mail~
K:405:0x8A/0x8B

# Pseudo Dragon Scale Mail~
K:406:0x8A/0x87

# Law Dragon Scale Mail~
K:407:0x8A/0x89

# Bronze Dragon Scale Mail~
K:408:0x8A/0x85

# Gold Dragon Scale Mail~
K:409:0x8A/0x86

# Chaos Dragon Scale Mail~
K:410:0x8A/0x88

# Balance Dragon Scale Mail~
K:411:0x8A/0x8A

# Power Dragon Scale Mail~
K:412:0x8A/0x8C

# & Dragon Helm~
K:413:0x88/0x82

# & Dragon Shield~
K:414:0x88/0x9C

# Death
K:415:0x85/0x85

# Ruination
K:416:0x85/0x85

# Detonations
K:417:0x85/0x85

# Augmentation
K:418:0x85/0x85

# *Healing*
K:419:0x85/0x85

# Life
K:420:0x85/0x85

# Self Knowledge
K:421:0x85/0x85

# *Enlightenment*
K:422:0x85/0x85

# [Necromantic Incantations]
K:423:0x8D/0x8A

# [Curses of Angmar]
K:424:0x8D/0x8B

# Fear Resistance
K:425:0x84/0x83

# Light and Darkness Resistance
K:426:0x84/0x83

# Nether Resistance
K:427:0x84/0x83

# Nexus Resistance
K:428:0x84/0x83

# Sound Resistance
K:429:0x84/0x83

# Confusion Resistance
K:430:0x84/0x83

# Shard Resistance
K:431:0x84/0x83

# Disenchantment Resistance
K:432:0x84/0x83

# Chaos Resistance
K:433:0x84/0x83

# Blindness Resistance
K:434:0x84/0x83

# Lordly Protection
K:435:0x84/0x83

# Extra Attacks
K:436:0x84/0x83

# Cure Light Wounds
K:437:0x85/0x85

# Clumsiness
K:438:0x85/0x85

# Sickliness
K:439:0x85/0x85

# Map of Bree
K:440:0xC4/0x80

# Map of Gondolin
K:441:0xC4/0x80

# Map of Lothlorien
K:442:0xC4/0x80

# Map of Minas Anor
K:443:0xC4/0x80

# & Silver Arrow~
K:465:0xC6/0x81

# & Silver Bolt~
K:466:0xC6/0x82

# Lightning Resistance
K:467:0x87/0x80

# Wisdom
K:468:0x87/0x80

# Regeneration
K:469:0x87/0x80

# Infravision
K:470:0x87/0x80

# Devotion
K:471:0x87/0x80

# Weaponmastery
K:472:0x87/0x80

# Trickery
K:473:0x87/0x80

# Telepathy
K:474:0x87/0x80

# Sustenance
K:475:0x87/0x80

# & Palantir~
K:476:0xC6/0x87

# & Elfstone~
K:477:0xC6/0x83

# & Jewel~
K:478:0xC6/0x84

# & Ring~
K:479:0xC6/0x85

# copper
K:480:0x83/0x91
K:481:0x83/0x91
K:482:0x83/0x91

# silver
K:483:0x83/0x92
K:484:0x83/0x92
K:485:0x83/0x92

# garnets
K:486:0x83/0x96
K:487:0x83/0x96

# gold
K:488:0x83/0x93
K:489:0x83/0x93
K:490:0x83/0x93

# opals
K:491:0x83/0x97

# sapphires
K:492:0x83/0x98

# rubies
K:493:0x83/0x99

# diamonds
K:494:0x83/0x9A

# emeralds
K:495:0x83/0x9B

# mithril
K:496:0x83/0x94

# adamantite
K:497:0x83/0x95

# & Mighty Hammer~
K:498:0xB6/0x8A

# & Massive Iron Crown~
K:499:0x87/0x9C

# & Phial~
K:500:0x8E/0x9D

# & Star~
K:501:0x8E/0x9E

# & Arkenstone~
K:502:0x8E/0x9F

# & Amulet~
K:503:0x84/0x96
K:504:0x84/0x97

# & Necklace~
K:505:0x84/0x98

# & Ring~
K:506:0x84/0x8F
K:507:0x84/0x90
K:508:0x84/0x92
K:509:0x84/0x93
K:510:0x84/0x94
K:511:0x84/0x95

# [Rites of Initiation]
K:512:0x8D/0x90

# [Ways of War]
K:513:0x8D/0x91

# [Divine Retribution]
K:514:0x8D/0x92

# [Essence of Fury]
K:515:0x8D/0x93

# [Novice Crafts]
K:516:0x8D/0x8C

# [Arcane Channels]
K:517:0x8D/0x8D

# [Sigils of Wizardry]
K:518:0x8D/0x8E

# [Mana Focus]
K:519:0x8D/0x8F

# Reflection
K:520:0x87/0x83

# Anti-Magic
K:521:0x87/0x83

# Anti-Teleportation
K:522:0x87/0x83

# Resistance
K:523:0x87/0x83

# & Zweihander~
K:524:0xB6/0x8C

# & Dwarven Lantern~
K:525:0xC5/0x94

# Splint Mail~
K:526:0x89/0x9C

# & Everburning Torch~
K:527:0xC5/0x95

# & Trifurcate Spear~
K:528:0xB6/0x85

# & Three Piece Rod~
K:529:0xB6/0x80

# & Feanorian Lamp~
K:530:0xC5/0x96

# & Fur Cloak~
K:531:0x89/0x89

# Water Curing
K:532:0xB6/0x86

# & Hatchet~
K:533:0xB6/0x8F

# Rhino Hide Armour~
K:535:0x89/0x98

# Leather Jacket~
K:536:0x89/0x8F

# & Sickle~
K:537:0xB6/0x90

# [Psychoportation]
K:538:0xB6/0x87

# [Clairsentience]
K:539:0xB6/0x91

# [Telekinesis]
K:540:0xB6/0x93

# [Empathy]
K:541:0xB6/0x92

# & Club~
K:542:0xB6/0x92

# & Broad Spear~
K:543:0xB6/0x84

# & Khopesh~
K:544:0xB6/0x94

# & Flamberge~
K:545:0xB6/0x83

# & Claymore~
K:546:0xB6/0x8D

# & Espadon~
K:547:0xB6/0x8E

# & Great Scimitar~
K:548:0xB6/0x8B

# Arrow
K:549:0x8E/0xA0

# Bolt
K:550:0x8E/0xA1

# & Fauchard~
K:551:0xB6/0x95

# & Guisarme~
K:552:0xB6/0x96

# & Heavy Lance~
K:553:0xB6/0x82

# & Basillard~
K:554:0xB6/0x99

# Catapult
K:555:0x8E/0xA2

# Ring Mail~
K:556:0x89/0x9C

# Cord Armour~
K:557:0x89/0x90

# Paper Armour~
K:558:0x8A/0x81

# Padded Armour~
K:559:0x89/0x91

# Fumes
K:560:0x8E/0xA3

# Stone and Hide Armour~
K:561:0x89/0x97

# Magic
K:562:0x8E/0xA4

# Device
K:563:0x8E/0xA5

# Nothing
K:564:0xC6/0x9C

# Poison
K:565:0xB7/0x80

# Nothing
K:566:0xC6/0x9C
K:567:0xC6/0x9C
K:568:0xC6/0x9C
K:569:0xC6/0x9C

# Explosion
K:570:0xB7/0x81

# Teleport
K:571:0xB7/0x82

# Nothing
K:572:0xC6/0x9C

# & Blood~ of Life
K:573:0x85/0x85

# Cold
K:574:0xB7/0x83

# Fire
K:575:0xB7/0x84

# Acid
K:576:0xB7/0x85

# & Mage Staff~
K:577:0xB8/0x80

# Lightning
K:578:0x84/0x80

# Life
K:579:0xB7/0x86

# Confusion
K:580:0xB7/0x87

# Light
K:581:0xB7/0x88

# & Ring~
K:582:0x84/0x85

# Invisibility
K:583:0x85/0x85

# Chaos
K:584:0xB7/0x89

# Corruption
K:585:0x85/0x85

# Invisibility
K:586:0x85/0x85

# Time
K:587:0xB7/0x8A

# Deep Thoughts
K:588:0x83/0x9C

# More Deep Thoughts
K:589:0x83/0x9D

# Compendium of Deep Thoughts
K:590:0x83/0x9E

# Artifact Lore Vol. I
K:591:0x83/0x9C

# Artifact Lore Vol. II
K:592:0x83/0x9D

# Artifact Lore Vol. III
K:593:0x83/0x9F

# Monstrous Compendium 1
K:594:0x83/0x9F

# Monstrous Compendium 2
K:595:0x83/0x9E

# Monstrous Compendium 3
K:596:0x83/0x9D

# Monstrous Compendium 4
K:597:0x83/0x9C

# Monstrous Compendium 5
K:598:0x83/0x9F

# Monstrous Compendium 6
K:599:0x83/0x9E

# Monstrous Compendium 7
K:600:0x83/0x9D

# Monstrous Compendium 8
K:601:0x83/0x9C

# Monstrous Compendium 9
K:602:0x83/0x9D

# Monstrous Compendium 10
K:603:0x83/0x9E

# Monstrous Compendium 11
K:604:0x83/0x9F

# Abomination
K:605:0x85/0x85

# Shape of Wolf
K:606:0x85/0x85

# Shape of Ape
K:607:0x85/0x85

# Shape of Goat
K:608:0x85/0x85

# Shape of Insect
K:609:0x85/0x85

# Shape of Sparrow
K:610:0x85/0x85

# Shape of Ent
K:611:0x85/0x85

# Shape of Vampire
K:612:0x85/0x85

# Shape of Spider
K:613:0x85/0x85

# Shape of Mana ball
K:614:0x85/0x85

# Shape of Fire cloud
K:615:0x85/0x85

# Shape of Cold cloud
K:616:0x85/0x85

# Shape of Chaos cloud
K:617:0x85/0x85

# [Wolf]
K:618:0x8F/0xA0

# [Ape]
K:619:0x8F/0xA1

# [Goat]
K:620:0x8F/0xA2

# [Insect]
K:621:0x8F/0xA3

# [Sparrow]
K:622:0x8F/0xA4

# [Ent]
K:623:0x8F/0xA5

# [Vampire]
K:624:0x8F/0xA6

# [Spider]
K:625:0x8F/0xA7

# [Mana ball]
K:626:0x8F/0xA8

# [Fire cloud]
K:627:0x8F/0xA9

# [Cold cloud]
K:628:0x8F/0xAA

# [Chaos Cloud]
K:629:0x8F/0xAB

# [Ghost]
K:630:0x8F/0xAC

# [Kobold]
K:631:0x8F/0xAD

# [Dragon]
K:632:0x8F/0xAE

# [Demon]
K:633:0x8F/0xAF

# [Hound]
K:634:0x8F/0xB0

# [Quylthulg]
K:635:0x8F/0xB1

# [Maia]
K:636:0x8F/0xB2

# [Serpent]
K:637:0x8F/0xB3

# [Giant]
K:638:0x8F/0xB4

# [Vala]
K:639:0x8F/0xB5

# Magic
K:640:0xB7/0x8B

# corpse
K:641:0xB8/0x81

# skeleton
K:642:0x8E/0x96

# head
K:643:0x8E/0x94

# skull
K:644:0x8E/0x94

# raw meat
K:645:0x8E/0x83

# & Thunderlord Coat~
K:646:0x8A/0x86

# & Stone~
K:647:0x8E/0x9C

# & small wooden Boomerang~
K:648:0xB8/0x82

# & wooden Boomerang~
K:649:0xB8/0x83

# & small metal Boomerang~
K:650:0xB8/0x84

# & metal Boomerang~
K:651:0xB8/0x85

# & Anchor~
K:652:0x8D/0x9E

# & ~
K:653:0xC6/0x9C

# Summon never-moving pet
K:654:0x83/0x9D

# [Life in symbiosis]
K:655:0xB8/0x86

# [Perfect Symbiosis]
K:656:0xB8/0x86

# Cure Light Insanity
K:657:0x85/0x85

# Cure Serious Insanity
K:658:0x85/0x85

# Cure Critical Insanity
K:659:0x85/0x85

# Cure Insanity
K:660:0x85/0x85

# & Phial~
K:661:0x8E/0x9D

# Random Artifact
K:662:0xC6/0x9C

# Craftmanship
K:663:0x83/0x9F

# The One Ring
K:664:0x83/0x9E

# & Book~ of the Lays of the Heroes
K:665:0xB8/0x87

# & Book~ of Sound Patterns
K:666:0xB8/0x87

# [Harps of Rivendell]
K:667:0xB8/0x87

# [Lays of Beleriand]
K:668:0xB8/0x87

# & Flute~
K:669:0xB8/0x88

# & Drum~
K:670:0xB8/0x89

# & Harp~
K:671:0xB8/0x8A

# & Banjo~
K:672:0xB8/0x8C

# & Lute~
K:673:0xB8/0x8B

# & Mandolin~
K:674:0xB8/0x8B

# & Palantir~
K:675:0x8D/0x9F

# Egg
K:676:0xB7/0x8D

# Reset Recall
K:677:0x83/0x9D

# Divination
K:678:0x83/0x9D

# Self
K:679:0xB7/0x8E

# Ray
K:680:0xB7/0x8F

# Sphere
K:681:0xB7/0x90

# Knowledge
K:682:0xB7/0x94

# Life
K:683:0xB7/0x95

# Fire
K:684:0xB7/0x96

# Cold
K:685:0xB7/0x97

# Lightning
K:686:0xB7/0x98

# Acid
K:687:0xB7/0x99

# Element
K:688:0xB7/0x9A

# Chaos
K:689:0xB7/0x9B

# Mind
K:690:0xB7/0x9C

# Holding
K:691:0xB7/0x9D

# Arrow
K:692:0xB7/0x91

# Power Surge
K:693:0xB7/0x92

# Armageddon
K:694:0xB7/0x93

# Gravity
K:695:0xB7/0x9E

# Extra Life
K:696:0xB7/0x9F

# Undeath
K:697:0xB6/0x9B

# Protection
K:698:0xB6/0x9C

# & Horn~
K:699:0xB8/0x8D

# & Ring~ of Precognition
K:700:0x84/0x83

# & Sprig~ of Athelas
K:701:0xB8/0x8E

# [Magic for Beginners]
K:702:0xB8/0x8F

# [Conjurings and Tricks]
K:703:0xB8/0x8F

# [Incantations and Illusions]
K:704:0xB8/0x8F

# [Sorcery and Evocations]
K:705:0xB8/0x8F

# [Beginners Handbook]
K:706:0xB8/0x90

# [Words of Wisdom]
K:707:0xB8/0x90

# [Chants and Blessings]
K:708:0xB8/0x90

# [Exorcism and Dispelling]
K:709:0xB8/0x90

# [Resistance of Scarabtarices]
K:710:0xB8/0x92

# [Mordenkainen's Escapes]
K:711:0xB8/0x92

# [Kelek's Grimoire of Power]
K:712:0xB8/0x92

# [Tenser's Transformations]
K:713:0xB8/0x92

# [Raal's Tome of Destruction]
K:714:0xB8/0x92

# [Ethereal Openings]
K:715:0xB8/0x92

# [Godly Insights]
K:716:0xB8/0x91

# [Purifications and Healing]
K:717:0xB8/0x91

# [Holy Infusions]
K:718:0xB8/0x91

# [Wrath of God]
K:719:0xB8/0x91

# & Old Scroll~ of Deincarnation
K:720:0x83/0x9F

# & Dark Sword~
K:721:0xC4/0x81

# Numenorean for beginners (I)
K:722:0xC1/0x80

# Numenorean for beginners (II)
K:723:0xC1/0x81

# Advanced lessons of Numenorean
K:724:0xC1/0x80

# Advanced lessons of Sindarin
K:725:0xC1/0x81

# & Shard~ of Pottery
K:726:0x8E/0x92

# & Broken Stick~
K:727:0x8E/0x93

# Wall Creation
K:728:0x83/0x9F

# [Illusions for Beginners]
K:729:0xC1/0x82

# [Tricks and Visions]
K:730:0xC1/0x82

# [Phantasms and Illusions]
K:731:0xC1/0x82

# [Shadows and Prisms]
K:732:0xC1/0x82

# [Serten's Immunities]
K:733:0xC1/0x83

# [Knowledge of Kenault]
K:734:0xC1/0x83

# [Otiluke's Spheres]
K:735:0xC1/0x82

# [Boccob's Book of Shadows]
K:736:0xC1/0x84

# [Bigby's Handbook]
K:737:0xC1/0x84

# & Book~ of Beginner Cantrips
K:738:0xC1/0x85

# & Book~ of Teleportation
K:739:0xC1/0x86

# & Book~ of Recall
K:740:0xC1/0x87

# & Book~ of Summoning
K:741:0xC1/0x80

# & Book~ of Fireflash
K:742:0xC1/0x81

# & Potion~ of Learning
K:743:0xC1/0x82

# [Eye of Sauron]
K:744:0xC1/0x83

# [Flame of Udun]
K:745:0xC1/0x84

# [Corruptions of Melkor]
K:746:0xC1/0x85

# [Crescent of Morgul]
K:747:0xC1/0x86

# [Morgoth's Ring]
K:748:0xC1/0x87

# Spell
K:749:0x86/0x90

# Wishing
K:750:0x86/0x90

# Khuzdul - The hidden tongue of the Dwarves
K:751:0x83/0x9D

# Nandorin for dummies
K:752:0xC1/0x81

# Advanced lessons of Orcish
K:753:0xC1/0x82

# & Ancient Tome~
K:754:0xC1/0x86

# Flying
K:755:0x84/0x88

# & Tome~ of the Time
K:756:0xC1/0x80

# & Tome~ of Meta Spells
K:758:0xC1/0x81

# & Tome~ of the Mind
K:759:0xC1/0x82

# & Holy Tome~ of Eru Iluvatar
K:760:0xC1/0x83

# & Holy Tome~ of Manwe Sulimo
K:761:0xC1/0x84

# & War Tome~ of Tulkas
K:762:0xC1/0x85

# & Unholy Tome~ of the Hellflame
K:763:0xC1/0x86

# & Corrupted Tome~ of Melkor
K:764:0xC1/0x87

# [Aiding Shades]
K:765:0xC1/0x80

# [Morgoth's Space-Time Warpings]
K:766:0xC1/0x81

# [Murazor's Tome of Conjuring & Dispelling]
K:767:0xC1/0x82

# & Forest Tome~ of Yavanna
K:768:0xC1/0x83

# [Sauron's Forgotten Tome]
K:769:0xC1/0x87

# & Ring~
K:770:0x84/0x84

# [Earth]
K:771:0xC1/0x88

# [Fire]
K:772:0xC1/0x89

# [Air]
K:773:0xC1/0x8A

# [Water]
K:774:0xC1/0x8B

# [Mana]
K:775:0xC1/0x8C

# Home Summoning
K:776:0x83/0x9F

# & Shadow Blade~
K:777:0xC1/0x91

# & Bluesteel Blade~
K:778:0xC1/0x92

# the Serpents
K:779:0xC4/0x88

# Darkness
K:780:0xC4/0x89

# Knowledge
K:781:0xC4/0x8A

# Force
K:782:0xC4/0x8B

# Lightning
K:783:0xC4/0x8C

# Mana
K:784:0xC4/0x8D

# Ring~ of Power
K:785:0xC4/0x8E

# Climbing Set~
K:786:0xC1/0x93

# Adventurer's guide to Middle-earth
K:787:0x83/0x9E

# & Demonblade~
K:788:0x90/0xA8

# & Demonshield~
K:789:0x90/0xA9

# & Demonhorn~
K:790:0x90/0xAA

# [Demonthoughts]
K:791:0xC1/0x83

# [Hellfire Tome]
K:792:0xC1/0x94

# & Wooden Rod~ of#
K:793:0xC1/0x95

# & Copper Rod~ of#
K:794:0xC1/0x96

# & Iron Rod~ of#
K:795:0xC1/0x97

# & Moonstone Rod~ of#
K:796:0xC1/0x98

# & Silver Rod~ of#
K:797:0xC1/0x99

# & Golden Rod~ of#
K:798:0xC1/0x9B

# & Mithril Rod~ of#
K:799:0xC1/0x9C

# & Adamantite Rod~ of#
K:800:0xC1/0x9D

# & Greater Ration~ of Health
K:801:0xC4/0x87

# & Crumpled Scroll~ of Mass Resurrection
K:802:0x83/0x9E

# & Cleaver~
K:803:0xC4/0x82

# & Light War Axe~
K:804:0xC4/0x83

# & Slaughter Axe~
K:805:0xC4/0x84

# & Runestone~
K:806:0xC4/0x85

# & Fortune cookie~
K:807:0xC6/0x86

# Portable hole
K:808:0xC6/0x89

# Critical Hits
K:809:0xC6/0x9C

# & Wand~ of Digging of Thrain
K:810:0xC6/0x9C

# & Gnarled Staff~ of Holy Fire of Mithrandir
K:811:0xC6/0x9C

# Partial Totem
K:812:0xC6/0x9D

# True Totem
K:813:0xC6/0x9E

# Player
R:0:0x8E/0x80

# Filthy street urchin
R:1:0xAA/0x80

# Scrawny cat
R:2:0xA7/0x82

# Sparrow
R:3:0xB4/0x9E

# Chaffinch
R:4:0xB4/0x9E

# Wild rabbit
R:5:0xB4/0x9F

# Woodsman
R:6:0xAA/0x91

# Scruffy little dog
R:7:0x9D/0x9A

# Farmer Maggot
R:8:0xAA/0x81

# Blubbering idiot
R:9:0xAA/0x82

# Boil-covered wretch
R:10:0xAA/0x83

# Village idiot
R:11:0xAA/0x84

# Pitiful-looking beggar
R:12:0xAA/0x85

# Mangy-looking leper
R:13:0xAA/0x86

# Agent of the black market
R:14:0xAA/0x87

# Singing, happy drunk
R:15:0xAA/0x88

# Aimless-looking merchant
R:16:0xAA/0x89

# Mean-looking mercenary
R:17:0xAA/0x8A

# Battle-scarred veteran
R:18:0xAA/0x8B

# Martti Ihrasaari
R:19:0xB0/0x80

# Grey mold
R:20:0xA8/0x9F

# Large white snake
R:21:0xA2/0x85

# Grey mushroom patch
R:22:0xB0/0x81

# Newt
R:23:0xB0/0x82

# Giant white centipede
R:24:0xA5/0x95

# White icky thing
R:25:0xA8/0x83

# Clear icky thing
R:26:0xA8/0x84

# Giant white mouse
R:27:0xAC/0x85

# Large brown snake
R:28:0xA2/0x84

# Small kobold
R:29:0xA8/0x99

# Kobold
R:30:0xA8/0x9A

# White worm mass
R:31:0xAC/0x9D

# Floating eye
R:32:0xA6/0x9B

# Rock lizard
R:33:0xA2/0x86

# Grid bug
R:34:0xB0/0x84

# Jackal
R:35:0x9D/0x9B

# Soldier ant
R:36:0xA5/0x87

# Fruit bat
R:37:0xA5/0x8F

# Insect swarm
R:38:0xB5/0x9E

# The Greater hell-beast
R:39:0xB0/0x83

# Shrieker mushroom patch
R:40:0x9D/0x86

# Blubbering icky thing
R:41:0xA8/0x85

# Metallic green centipede
R:42:0xA5/0x96

# Novice warrior
R:43:0xAA/0x8C

# Novice rogue
R:44:0xAA/0x8D

# Novice priest
R:45:0xAA/0x8E

# Novice mage
R:46:0xAA/0x8F

# Yellow mushroom patch
R:47:0x9D/0x87

# White jelly
R:48:0xA8/0x8A

# Giant black ant
R:49:0xA5/0x88

# Salamander
R:50:0xA2/0x88

# White harpy
R:51:0xA0/0x88

# Blue yeek
R:52:0xAD/0x87

# Grip, Farmer Maggot's dog
R:53:0x9D/0x9C

# Wolf, Farmer Maggot's dog
R:54:0x9D/0x9D

# Fang, Farmer Maggot's dog
R:55:0x9D/0x9D

# Giant green frog
R:56:0xA2/0x87

# Freesia
R:57:0xB0/0x85

# Green worm mass
R:58:0xAC/0x9E

# Large yellow snake
R:59:0xA2/0x89

# Cave spider
R:60:0xA2/0x9D

# Crow
R:61:0xB5/0x9F

# Wild cat
R:62:0xA7/0x83

# Smeagol
R:63:0xAA/0x90

# Green ooze
R:64:0xA8/0x8B

# Poltergeist
R:65:0x9F/0x99

# Yellow jelly
R:66:0xA8/0x8D

# Metallic blue centipede
R:67:0xA5/0x97

# Raven
R:68:0xB5/0x9F

# Giant white louse
R:69:0xA8/0x9D

# Giant yellow centipede
R:70:0xA5/0x94

# Black naga
R:71:0xA9/0x88

# Spotted mushroom patch
R:72:0x9D/0x88

# Silver jelly
R:73:0xA8/0x8C

# Scruffy-looking hobbit
R:74:0xA7/0x93

# Giant white ant
R:75:0xA5/0x89

# Yellow mold
R:76:0xA9/0x80

# Metallic red centipede
R:77:0xA5/0x98

# Yellow worm mass
R:78:0xAC/0x9F

# Clear worm mass
R:79:0xAD/0x80

# Radiation eye
R:80:0xA6/0x9C

# Yellow light
R:81:0xB8/0x93

# Cave lizard
R:82:0xA2/0x8A

# Novice ranger
R:83:0xAA/0x91

# Blue jelly
R:84:0xA8/0x8E

# Creeping copper coins
R:85:0x9D/0x80

# Giant white rat
R:86:0xAC/0x86

# Snotling
R:87:0xB9/0x89

# Swordfish
R:88:0xB6/0x9E

# Blue worm mass
R:89:0xAD/0x81

# Large grey snake
R:90:0xA2/0x8B

# Skeleton kobold
R:91:0xAC/0x89

# Ewok
R:92:0xB0/0x86

# Novice mage
R:93:0xAA/0x8F

# Green naga
R:94:0xA9/0x89

# Giant leech
R:95:0xB8/0x94

# Barracuda
R:96:0xB6/0x9F

# Novice paladin
R:97:0xAA/0x92

# Zog
R:98:0xA1/0x80

# Blue ooze
R:99:0xA8/0x8F

# Green glutton ghost
R:100:0x9F/0x9A

# Green jelly
R:101:0xA8/0x90

# Large kobold
R:102:0xA8/0x9B

# Grey icky thing
R:103:0xA8/0x86

# Disenchanter eye
R:104:0xA6/0x9D

# Red worm mass
R:105:0xAD/0x82

# Copperhead snake
R:106:0xA2/0x8C

# Death sword
R:107:0xB0/0x87

# Purple mushroom patch
R:108:0x9D/0x89

# Novice priest
R:109:0xAA/0x8E

# Novice warrior
R:110:0xAA/0x8C

# Nibelung
R:111:0xB0/0x88

# The disembodied hand that strangled people
R:112:0xB0/0x89

# Brown mold
R:113:0xA9/0x81

# Giant brown bat
R:114:0xA5/0x90

# Rat-thing
R:115:0xAC/0x88

# Novice rogue
R:116:0xAA/0x87

# Creeping silver coins
R:117:0x9D/0x81

# Snaga
R:118:0xA9/0x8E

# Rattlesnake
R:119:0xA2/0x8D

# Giant slug
R:120:0xB8/0x94

# Giant pink frog
R:121:0xB8/0x95

# Dark elf
R:122:0x92/0x94

# Zombified kobold
R:123:0xAC/0x89

# Crypt creep
R:124:0xB0/0x8A

# Rotting corpse
R:125:0xB0/0x8B

# Cave orc
R:126:0xA9/0x8F

# Wood spider
R:127:0xA2/0x9E

# Manes
R:128:0xA0/0x91

# Bloodshot eye
R:129:0xA6/0x9E

# Red naga
R:130:0xA9/0x8A

# Red jelly
R:131:0xA8/0x91

# Green icky thing
R:132:0xA8/0x87

# Lost soul
R:133:0x9F/0x9B

# Night lizard
R:134:0xA2/0x8F

# Mughash, the Kobold Lord
R:135:0xA8/0x9C

# Skeleton orc
R:136:0xAC/0x8A

# Wormtongue, Agent of Saruman
R:137:0xAA/0x98

# Robin Hood, the Outlaw
R:138:0xB0/0x8C

# Nurgling
R:139:0xB8/0x97

# Lagduf, the Snaga
R:140:0xA9/0x90

# Brown yeek
R:141:0xAD/0x88

# Novice ranger
R:142:0xAA/0x91

# Giant salamander
R:143:0xA2/0x90

# Space monster
R:144:0xB0/0x8D

# Carnivorous flying monkey
R:145:0xB8/0x98

# Green mold
R:146:0xA9/0x82

# Novice paladin
R:147:0xAA/0x92

# Lemure
R:148:0xA0/0x92

# Hill orc
R:149:0xA9/0x91

# Bandit
R:150:0xAA/0x9B

# Hunting hawk
R:151:0xB0/0x8E

# Phantom warrior
R:152:0xB0/0x8F

# Gremlin
R:153:0xB0/0x90

# Yeti
R:154:0xA4/0x91

# Bloodshot icky thing
R:155:0xA8/0x88

# Giant grey rat
R:156:0xAC/0x87

# Black harpy
R:157:0xA0/0x89

# Skaven
R:158:0xB8/0x99

# The wounded bear
R:159:0xBA/0x80

# Cave bear
R:160:0xC4/0x8F

# Rock mole
R:161:0xBA/0x82

# Mindcrafter
R:162:0xAA/0x93

# Baby blue dragon
R:163:0xA5/0x9D

# Baby white dragon
R:164:0xA5/0x9E

# Baby green dragon
R:165:0xA5/0x9F

# Baby black dragon
R:166:0xA6/0x80

# Baby red dragon
R:167:0xA6/0x81

# Giant red ant
R:168:0xA5/0x8D

# Brodda, the Easterling
R:169:0xAA/0x9C

# Bloodfang, the Wolf
R:170:0xBA/0x83

# King cobra
R:171:0xA2/0x91

# Eagle
R:172:0xB4/0x9E

# War bear
R:173:0xB0/0x91

# Killer bee
R:174:0xB0/0x92

# Giant spider
R:175:0xA2/0x9F

# Giant white tick
R:176:0xA8/0x9D

# The Borshin
R:177:0xBA/0x84

# Dark elven mage
R:178:0xA7/0x96

# Kamikaze yeek
R:179:0xBA/0x94

# Orfax, Son of Boldor
R:180:0xAD/0x89

# Servant of Glaaki
R:181:0xBA/0x85

# Dark elven warrior
R:182:0xA7/0x97

# Sand-dweller
R:183:0xBA/0x86

# Clear mushroom patch
R:184:0xB8/0x96

# Quiver slot
R:185:0xB0/0x93

# Grishnakh, the Hill Orc
R:186:0xA9/0x93

# Giant tan bat
R:187:0xC4/0x90

# Owlbear
R:188:0xBA/0x87

# Blue horror
R:189:0xB8/0x9A

# Hairy mold
R:190:0xA9/0x83

# Grizzly bear
R:191:0xBA/0x88

# Disenchanter mold
R:192:0xA9/0x84

# Pseudo dragon
R:193:0xA6/0x82

# Tengu
R:194:0xA0/0x93

# Creeping gold coins
R:195:0x9D/0x82

# Wolf
R:196:0x9D/0x9E

# Giant fruit fly
R:197:0x9F/0x91

# Panther
R:198:0xA7/0x84

# Brigand
R:199:0xB0/0x94

# Hobbes the Tiger
R:200:0xB0/0x95

# Shadow Creature of Fiona
R:201:0xB0/0x96

# Undead mass
R:202:0xB0/0x97

# Chaos shapechanger
R:203:0xB0/0x98

# Baby multi-hued dragon
R:204:0xA6/0x83

# Vorpal bunny
R:205:0xB4/0x9F

# Old Man Willow
R:206:0xBA/0x89

# Hippocampus
R:207:0xBA/0x8A

# Zombified orc
R:208:0xAC/0x8C

# Hippogriff
R:209:0xA0/0x8A

# Black mamba
R:210:0xA2/0x92

# White wolf
R:211:0x9D/0x9F

# Grape jelly
R:212:0xA8/0x92

# Nether worm mass
R:213:0xAD/0x83

# Abyss worm mass
R:214:0xB0/0x99

# Golfimbul, the Hill Orc Chief
R:215:0xA9/0x94

# Swordsman
R:216:0x97/0x81

# Skaven shaman
R:217:0x9A/0x84

# Baby bronze dragon
R:218:0xA6/0x82

# Baby gold dragon
R:219:0xA6/0x82

# Evil eye
R:220:0xC4/0x91

# Mine-dog
R:221:0xB9/0x8B

# Hellcat
R:222:0xB0/0x9A

# Moon beast
R:223:0xB0/0x9B

# Master yeek
R:224:0xAD/0x8A

# Priest
R:225:0xAA/0x9E

# Dark elven priest
R:226:0xA7/0x99

# Air spirit
R:227:0x9E/0x9F

# Skeleton human
R:228:0xAC/0x8B

# Zombified human
R:229:0xAD/0x8E

# Tiger
R:230:0xA7/0x85

# Moaning spirit
R:231:0x9F/0x9C

# Stegocentipede
R:232:0xA5/0x99

# Spotted jelly
R:233:0xA8/0x93

# Drider
R:234:0xA3/0x80

# Mongbat
R:235:0xB0/0x9C

# Killer brown beetle
R:236:0xA0/0x9B

# Boldor, King of the Yeeks
R:237:0xAD/0x8B

# Ogre
R:238:0xA1/0x8B

# Creeping mithril coins
R:239:0x9D/0x83

# Illusionist
R:240:0xAB/0x80

# Druid
R:241:0xAB/0x81

# Pink horror
R:242:0xB8/0x9B

# Cloaker
R:243:0x89/0x88

# Black orc
R:244:0xA9/0x95

# Ochre jelly
R:245:0xA8/0x94

# Software bug
R:246:0xB0/0x9D

# Lurker
R:247:0x80/0x81

# Tangleweed
R:248:0xC4/0x92

# Vlasta
R:249:0xA5/0x84

# Giant white dragon fly
R:250:0x9F/0x93

# Snaga sapper
R:251:0xB9/0x8C

# Blue icky thing
R:252:0xA8/0x89

# Gibbering mouther
R:253:0xB0/0x9E

# Wolfhound of Flora
R:254:0xB0/0x9F

# Hill giant
R:255:0xA1/0x91

# Flesh golem
R:256:0xA7/0x89

# Warg
R:257:0x9E/0x80

# Cheerful leprechaun
R:258:0xB1/0x80

# Giant flea
R:259:0x9F/0x92

# Ufthak of Cirith Ungol
R:260:0xBA/0x8C

# Clay golem
R:261:0xB8/0x9D

# Black ogre
R:262:0xA1/0x8C

# Dweller on the threshold
R:263:0xB9/0x8D

# Half-orc
R:264:0xBA/0x8D

# Dark naga
R:265:0xB8/0x9E

# Poison ivy
R:266:0xC4/0x93

# Magic mushroom patch
R:267:0x9D/0x8B

# Plaguebearer of Nurgle
R:268:0xAD/0x8D

# Guardian naga
R:269:0xA9/0x8B

# Wererat
R:270:0xBA/0x8E

# Light hound
R:271:0xA4/0x93

# Dark hound
R:272:0xA4/0x94

# Flying skull
R:273:0xB1/0x81

# Mi-Go
R:274:0xB1/0x82

# Giant tarantula
R:275:0xA3/0x81

# Giant clear centipede
R:276:0xA5/0x9A

# Mirkwood spider
R:277:0xA3/0x82

# Frost giant
R:278:0xA1/0x92

# Griffon
R:279:0xA0/0x8B

# Homunculus
R:280:0xA0/0x94

# Gnome mage
R:281:0xA7/0x98

# Clear hound
R:282:0xA4/0x95

# Umber hulk
R:283:0xA3/0x99

# Rust monster
R:284:0xB9/0x8F

# Ogrillon
R:285:0xA9/0x98

# Gelatinous cube
R:286:0xA8/0x95

# Giant green dragon fly
R:287:0x9F/0x94

# Fire giant
R:288:0xA1/0x93

# Hummerhorn
R:289:0xBA/0x8F

# Lizard man
R:290:0xB9/0x90

# Ulfast, Son of Ulfang
R:291:0xAB/0x82

# Crebain
R:292:0xC4/0x94

# Berserker
R:293:0xA9/0x97

# Quasit
R:294:0xA0/0x95

# Sphinx
R:295:0xB9/0x91

# Imp
R:296:0xA0/0x96

# Forest troll
R:297:0xA3/0x89

# Freezing sphere
R:298:0xBA/0x91

# Jumping fireball
R:299:0xB9/0x92

# Ball lightning
R:300:0xBA/0x92

# 2-headed hydra
R:301:0xA2/0x93

# Swamp thing
R:302:0xB9/0x93

# Water spirit
R:303:0x9F/0x80

# Giant red scorpion
R:304:0xA3/0x83

# Earth spirit
R:305:0x9F/0x81

# Fire spirit
R:306:0x9F/0x82

# Fire hound
R:307:0xA4/0x96

# Cold hound
R:308:0xA4/0x97

# Energy hound
R:309:0xA4/0x98

# Lesser Mimic
R:310:0x9D/0x8E

# Door mimic
R:311:0x82/0x83

# Blink dog
R:312:0x9E/0x81

# Uruk
R:313:0xA9/0x99

# Shagrat, the Orc Captain
R:314:0xA9/0x9A

# Gorbag, the Orc Captain
R:315:0xA9/0x9B

# Shambling mound
R:316:0x9D/0x8C

# Giant Venus Flytrap
R:317:0xC4/0x95

# Chaos beastman
R:318:0xB9/0x95

# Daemonette of Slaanesh
R:319:0xB9/0x94

# Giant bronze dragon fly
R:320:0x9F/0x98

# Stone giant
R:321:0xA1/0x94

# Giant black dragon fly
R:322:0x9F/0x96

# Stone golem
R:323:0xA7/0x8B

# Red mold
R:324:0xA9/0x85

# Giant gold dragon fly
R:325:0x9F/0x97

# Stunwall
R:326:0x80/0x93

# Ghast
R:327:0xBA/0x95

# Neekerbreeker
R:328:0xC4/0x96

# Huorn
R:329:0xBA/0x96

# Bolg, Son of Azog
R:330:0xA9/0x9C

# Phase spider
R:331:0xA3/0x84

# Lizard king
R:332:0xB9/0x97

# Landmine
R:333:0xBA/0x97

# Wyvern
R:334:0xB1/0x83

# Great eagle
R:335:0xB9/0x98

# Livingstone
R:336:0xB1/0x84

# Earth hound
R:337:0xA4/0x99

# Air hound
R:338:0xA4/0x9A

# Sabre-tooth tiger
R:339:0xA7/0x86

# Acid hound
R:340:0xA4/0x9B

# Chimaera
R:341:0xA0/0x8C

# Quylthulg
R:342:0xA1/0x9A

# Sasquatch
R:343:0xA4/0x92

# Weir
R:344:0xB1/0x85

# Ranger
R:345:0xAA/0x97

# Paladin
R:346:0xAB/0x92

# Werewolf
R:347:0xBA/0x99

# Dark elven lord
R:348:0xA7/0x9C

# Cloud giant
R:349:0xA1/0x96

# Ugluk, the Uruk
R:350:0xA9/0x9D

# Blue dragon bat
R:351:0xA5/0x91

# Mimic
R:352:0x83/0x9D

# Ultimate Mimic
R:353:0x84/0x9E

# Fire vortex
R:354:0xAC/0x94

# Acid vortex
R:355:0xAC/0x95

# Lugdush, the Uruk
R:356:0xB9/0x9A

# Arch-vile
R:357:0xBA/0x9A

# Cold vortex
R:358:0xAC/0x96

# Energy vortex
R:359:0xAC/0x97

# Globefish
R:360:0xB9/0x9B

# Giant firefly
R:361:0x9F/0x95

# Mummified orc
R:362:0xA1/0x88

# Wolf chieftain
R:363:0xC4/0x97

# Serpent man
R:364:0xBA/0x9C

# Vampiric mist
R:365:0xB9/0x9D

# Killer stag beetle
R:366:0xA0/0x9D

# Iron golem
R:367:0xA7/0x8C

# Auto-roller
R:368:0xB1/0x86

# Giant yellow scorpion
R:369:0xA3/0x85

# Jade monk
R:370:0xBA/0x9D

# Black ooze
R:371:0xA8/0x96

# Hardened warrior
R:372:0xAB/0x83

# Azog, King of the Uruk-Hai
R:373:0xA9/0x9F

# Fleshhound of Khorne
R:374:0xB9/0x9E

# Dark elven warlock
R:375:0xB1/0x87

# Master rogue
R:376:0xAB/0x84

# Red dragon bat
R:377:0xA5/0x92

# Killer white beetle
R:378:0xBA/0x9E

# Ice skeleton
R:379:0xB9/0x9F

# Angamaite of Umbar
R:380:0xBB/0x80

# Forest wight
R:381:0xB1/0x88

# Khim, Son of Mim
R:382:0xB1/0x89

# Ibun, Son of Mim
R:383:0xB1/0x8A

# Meneldor the Swift
R:384:0xBB/0x81

# Phantom beast
R:385:0xB1/0x8B

# Giant silver ant
R:386:0xA0/0x9C

# 4-headed hydra
R:387:0xA2/0x95

# Lesser hell-beast
R:388:0xBB/0x83

# Tyrannosaur
R:389:0xB1/0x8C

# Mummified human
R:390:0xA1/0x89

# Vampire bat
R:391:0xA5/0x93

# Sangahyando of Umbar
R:392:0xAB/0x85

# It
R:393:0xB1/0x8D

# Banshee
R:394:0x9F/0x9D

# Carrion crawler
R:395:0xA5/0x9B

# Xiclotlan
R:396:0xBB/0x84

# Silent watcher
R:397:0xB1/0x8E

# Pukelman
R:398:0xA7/0x8D

# Disenchanter beast
R:399:0xBA/0x9F

# Dark elven druid
R:400:0xA7/0x9F

# Stone troll
R:401:0xA3/0x8A

# Black
R:402:0xB0/0x8D

# Hill troll
R:403:0xA3/0x8B

# Wereworm
R:404:0xAD/0x84

# Killer red beetle
R:405:0xA0/0x9F

# Disenchanter bat
R:406:0xC4/0x98

# Gnoph-Keh
R:407:0xBB/0x86

# Giant grey ant
R:408:0xA5/0x8C

# Khufu, the Mummified King
R:409:0xB1/0x8F

# Gwaihir the Windlord
R:410:0xBB/0x81

# Giant fire tick
R:411:0xBB/0x87

# Displacer beast
R:412:0xA7/0x87

# Ulwarth, Son of Ulfang
R:413:0xAA/0x99

# Werebear
R:414:0xC4/0x8F

# Cave ogre
R:415:0xA1/0x8D

# White wraith
R:416:0xA3/0x9F

# Angel
R:417:0x9D/0x8F

# Ghoul
R:418:0xB4/0x8F

# Mim, Betrayer of Turin
R:419:0xB1/0x90

# Hellblade
R:420:0xB1/0x91

# Killer fire beetle
R:421:0xA1/0x80

# Beast of Nurgle
R:422:0xBB/0x88

# Creeping adamantite coins
R:423:0x9D/0x84

# Algroth
R:424:0xA3/0x8C

# Flamer of Tzeentch
R:425:0xB8/0x9F

# Roper
R:426:0xB9/0x80

# Headless
R:427:0xB1/0x92

# Vibration hound
R:428:0xA4/0x9C

# Nexus hound
R:429:0xA4/0x9D

# Half-ogre
R:430:0xA1/0x8E

# Lokkak, the Ogre Chieftain
R:431:0xA1/0x90

# Vampire
R:432:0xA3/0x9A

# Gorgimaera
R:433:0xA0/0x8D

# Shantak
R:434:0xB1/0x93

# Colbran
R:435:0xA7/0x8E

# Spirit naga
R:436:0xA9/0x8C

# Corpser
R:437:0xB9/0x81

# Fiend of Slaanesh
R:438:0xA2/0x97

# Stairway to Hell
R:439:0xB1/0x94

# 5-headed hydra
R:440:0xA2/0x96

# Barney the Dinosaur
R:441:0xB1/0x95

# Black knight
R:442:0xAB/0x88

# Seahorse
R:443:0xBB/0x89

# Cyclops
R:444:0xBB/0x8A

# Clairvoyant
R:445:0xAB/0x86

# Purple worm
R:446:0xB9/0x82

# Catoblepas
R:447:0xAC/0x81

# Lesser wall monster
R:448:0xB1/0x96

# Mage
R:449:0xAB/0x8A

# Mind flayer
R:450:0xAB/0x8B

# The Ultimate Dungeon Cleaner
R:451:0xB1/0x97

# Deep one
R:452:0xA4/0x86

# Basilisk
R:453:0xA2/0x97

# Ice troll
R:454:0xA3/0x8D

# Dhole
R:455:0xB1/0x99

# Archangel
R:456:0x9D/0x90

# Greater Mimic
R:457:0xAD/0x9E

# Chaos tile
R:458:0xB1/0x9A

# Young blue dragon
R:459:0xA6/0x84

# Young white dragon
R:460:0xA6/0x85

# Young green dragon
R:461:0xA6/0x86

# Young bronze dragon
R:462:0xA6/0x87

# Aklash
R:463:0xC1/0x9E

# Mithril golem
R:464:0xA7/0x8F

# Skeleton troll
R:465:0xAC/0x8D

# Skeletal tyrannosaur 
R:466:0xBB/0x8B

# Beorn, the Shape-Changer
R:467:0xC4/0x99

# Thorondor, Lord of Eagles
R:468:0xBB/0x81

# Giant blue ant
R:469:0xA5/0x8B

# Grave wight
R:470:0xAD/0x9C

# Shadow drake
R:471:0xA6/0x88

# Manticore
R:472:0xA0/0x8E

# Giant army ant
R:473:0xAE/0x81

# Killer slicer beetle
R:474:0xA1/0x81

# Gorgon
R:475:0xBB/0x8D

# Gug
R:476:0xBB/0x8E

# Ghost
R:477:0x9F/0x9E

# Death watch beetle
R:478:0xA1/0x82

# Mountain ogre
R:479:0xA1/0x8F

# Nexus quylthulg
R:480:0xA1/0x9B

# Shelob, Spider of Darkness
R:481:0xA3/0x86

# Giant squid
R:482:0xB9/0x83

# Ghoulking
R:483:0xAD/0x8C

# Doombat
R:484:0xB9/0x84

# Ninja
R:485:0xAB/0x8C

# Memory moss
R:486:0xA9/0x86

# Storm giant
R:487:0xA1/0x95

# Spectator
R:488:0xB1/0x9B

# Bokrug
R:489:0xBB/0x8F

# Biclops
R:490:0xBB/0x90

# Half-troll
R:491:0xA9/0x9E

# Ivory monk
R:492:0xAA/0x93

# Bert the Stone Troll
R:493:0xA3/0x90

# Bill the Stone Troll
R:494:0xA3/0x91

# Tom the Stone Troll
R:495:0xA3/0x92

# Cave troll
R:496:0xA3/0x8E

# Anti-paladin
R:497:0xB1/0x9C

# Chaos master
R:498:0xB1/0x9D

# Barrow wight
R:499:0xA4/0x81

# Skeleton ettin
R:500:0xC4/0x9A

# Chaos drake
R:501:0xA6/0x89

# Law drake
R:502:0xA6/0x8A

# Balance drake
R:503:0xA6/0x8B

# Ethereal drake
R:504:0xA6/0x8C

# Groo, the Wanderer
R:505:0xB1/0x9E

# Fasolt the Giant
R:506:0xB1/0x9F

# Shade
R:507:0xA4/0x89

# Spectre
R:508:0xA0/0x80

# Water troll
R:509:0xA3/0x93

# Fire elemental
R:510:0x9F/0x83

# Cherub
R:511:0x9D/0x91

# Water elemental
R:512:0x9F/0x84

# Multi-hued hound
R:513:0xB2/0x81

# Invisible stalker
R:514:0x9F/0x85

# Carrion crawler
R:515:0xA5/0x9C

# Master thief
R:516:0xAB/0x8E

# The Watcher in the Water
R:517:0xAF/0x95

# Lich
R:518:0xA1/0x83

# Gas spore
R:519:0xB2/0x8E

# Master vampire
R:520:0xA3/0x9B

# Oriental vampire
R:521:0xB2/0x83

# Greater mummy
R:522:0xA1/0x8A

# Bloodletter of Khorne
R:523:0xA0/0x98

# Giant grey scorpion
R:524:0xA3/0x87

# Earth elemental
R:525:0x9F/0x86

# Air elemental
R:526:0x9F/0x87

# Shimmering mold
R:527:0xAF/0x81

# Gargoyle
R:528:0xBB/0x91

# Malicious leprechaun
R:529:0xB2/0x85

# Eog golem
R:530:0xA7/0x90

# Little Boy
R:531:0xB9/0x85

# Dagashi
R:532:0xAB/0x90

# Headless ghost
R:533:0xBB/0x92

# Dread
R:534:0xB9/0x87

# Leng spider
R:535:0xBB/0x93

# Gauth
R:536:0xC4/0x9B

# Smoke elemental
R:537:0x9F/0x90

# Olog
R:538:0xA3/0x94

# Halfling slinger
R:539:0xB2/0x86

# Gravity hound
R:540:0xA4/0x9E

# Acidic cytoplasm
R:541:0xA8/0x97

# Inertia hound
R:542:0xA4/0x9F

# Impact hound
R:543:0xA5/0x80

# Shardstorm
R:544:0xC4/0x9C

# Ooze elemental
R:545:0x9F/0x88

# Young black dragon
R:546:0xA6/0x8D

# Mumak
R:547:0xAC/0x84

# Giant fire ant
R:548:0xA5/0x8A

# Mature white dragon
R:549:0xA6/0x8E

# Xorn
R:550:0xA4/0x8F

# Rogrog the Black Troll
R:551:0xA3/0x8F

# Mist giant
R:552:0xA7/0x91

# Phantom
R:553:0xB2/0x87

# Grey wraith
R:554:0xA4/0x82

# Revenant
R:555:0xA4/0x88

# Young multi-hued dragon
R:556:0xA6/0x8F

# Raal's Tome of Destruction
R:557:0xB2/0x88

# Colossus
R:558:0xB2/0x89

# Young gold dragon
R:559:0xA6/0x90

# Mature blue dragon
R:560:0xA6/0x91

# Mature green dragon
R:561:0xA6/0x92

# Mature bronze dragon
R:562:0xA6/0x93

# Young red dragon
R:563:0xA6/0x94

# Nightblade
R:564:0xB2/0x8A

# Trapper
R:565:0xAD/0x9F

# Bodak
R:566:0xA0/0x98

# Time bomb
R:567:0xBB/0x96

# Mezzodaemon
R:568:0xAD/0x90

# Elder thing
R:569:0xB2/0x8B

# Ice elemental
R:570:0x9F/0x8A

# Necromancer
R:571:0xB2/0x8C

# The Greater hell magic mushroom were-quylthulg
R:572:0xB9/0x86

# Lorgan, Chief of the Easterlings
R:573:0xB2/0x8D

# Chaos spawn
R:574:0xB2/0x8E

# Mummified troll
R:575:0xBB/0x97

# Storm of Unmagic
R:576:0xC4/0x9D

# Crypt thing
R:577:0xA4/0x80

# Chaos butterfly
R:578:0xBB/0x98

# Time elemental
R:579:0xB2/0x8F

# Flying polyp
R:580:0xBB/0x99

# The Queen Ant
R:581:0xA5/0x8E

# Will o' the wisp
R:582:0x9F/0x8B

# Shan
R:583:0xBB/0x9A

# Magma elemental
R:584:0x9F/0x8C

# Black pudding
R:585:0xA8/0x98

# Killer iridescent beetle
R:586:0xB4/0x90

# Nexus vortex
R:587:0xAE/0x80

# Plasma vortex
R:588:0xAC/0x98

# Mature red dragon
R:589:0xA6/0x95

# Mature gold dragon
R:590:0xA6/0x96

# Crystal drake
R:591:0xA6/0x97

# Mature black dragon
R:592:0xA6/0x98

# Mature multi-hued dragon
R:593:0xA6/0x99

# Sky whale
R:594:0xBB/0x9B

# Draebor, the Imp
R:595:0xC1/0x9F

# Mother Hydra
R:596:0xA2/0x98

# Death knight
R:597:0xAB/0x94

# Castamir the Usurper
R:598:0xB2/0x90

# Time vortex
R:599:0xAC/0x99

# Shimmering vortex
R:600:0xAC/0x9A

# Ancient blue dragon
R:601:0x9E/0x88

# Ancient bronze dragon
R:602:0x9E/0x89

# Beholder
R:603:0xA6/0x9F

# Emperor wight
R:604:0xA4/0x83

# Seraph
R:605:0x9D/0x92

# Vargo, Tyrant of Fire
R:606:0x9F/0x8D

# Black wraith
R:607:0xA4/0x84

# Nightgaunt
R:608:0xB2/0x91

# Baron of hell
R:609:0xB2/0x92

# Scylla
R:610:0xBB/0x9C

# Monastic lich
R:611:0xA1/0x87

# Nether wraith
R:612:0xA4/0x85

# Hellhound
R:613:0xAD/0x96

# 7-headed hydra
R:614:0xA2/0x99

# Waldern, King of Water
R:615:0x9F/0x8E

# Kavlax the Many-Headed
R:616:0xA6/0x9A

# Ancient white dragon
R:617:0x9E/0x8A

# Ancient green dragon
R:618:0x9E/0x8B

# Chthonian
R:619:0xB2/0x93

# Eldrak
R:620:0xA3/0x97

# Ettin
R:621:0xA3/0x96

# Night mare
R:622:0xAC/0x83

# Vampire lord
R:623:0xA3/0x9C

# Ancient black dragon
R:624:0x9E/0x8C

# Weird fume
R:625:0xAF/0x80

# Spawn of Ubbo-Sathla
R:626:0xBB/0x9D

# Fat Man
R:627:0xB9/0x85

# Malekith the Accursed
R:628:0xA7/0x95

# Shadowfax, steed of Gandalf
R:629:0xBB/0x9E

# Spirit troll
R:630:0xA3/0x98

# War troll
R:631:0xB2/0x94

# Disenchanter worm mass
R:632:0xAD/0x86

# Rotting quylthulg
R:633:0xA1/0x9C

# Lesser titan
R:634:0xA1/0x97

# 9-headed hydra
R:635:0xA2/0x99

# Enchantress
R:636:0xAB/0x96

# Ranger chieftain
R:637:0xAB/0x97

# Sorcerer
R:638:0xAB/0x98

# Xaren
R:639:0xA4/0x90

# Giant roc
R:640:0x9D/0x97

# Minotaur
R:641:0xA0/0x8F

# Medusa, the Gorgon
R:642:0xA9/0x8D

# Death drake
R:643:0x9E/0x8D

# Ancient red dragon
R:644:0x9E/0x8E

# Ancient gold dragon
R:645:0x9E/0x8F

# Great crystal drake
R:646:0x9E/0x90

# Wyrd sister
R:647:0xA7/0x9D

# Vrock
R:648:0xB2/0x95

# Death quasit
R:649:0xA0/0x99

# Giganto, the Gargantuan
R:650:0xBB/0x9F

# Strygalldwir
R:651:0xB2/0x96

# Fallen angel
R:652:0xAA/0x8E

# Giant headless
R:653:0xBC/0x80

# Judge Fire
R:654:0xAB/0x93

# Ubbo-Sathla, the Unbegotten Source
R:655:0xBC/0x81

# Judge Mortis
R:656:0xBC/0x82

# Dark elven sorcerer
R:657:0xA8/0x81

# Master lich
R:658:0xA1/0x84

# Byakhee
R:659:0xB2/0x97

# Eol, the Dark Elf
R:660:0xB2/0x99

# Archon
R:661:0x9D/0x93

# Formless spawn of Tsathoggua
R:662:0xB2/0x9A

# Hunting horror
R:663:0xB2/0x9B

# Undead beholder
R:664:0xA7/0x80

# Shadow
R:665:0xA0/0x81

# Iron lich
R:666:0xB2/0x9C

# Dread
R:667:0xB9/0x87

# Greater basilisk
R:668:0xBC/0x83

# Charybdis
R:669:0xBC/0x84

# Jack of Shadows
R:670:0xAB/0x9C

# Zephyr Lord
R:671:0xAB/0x91

# Juggernaut of Khorne
R:672:0xBC/0x85

# Mumak
R:673:0xAC/0x82

# Judge Fear
R:674:0xA7/0x88

# Ancient multi-hued dragon
R:675:0x9E/0x91

# Ethereal dragon
R:676:0x9E/0x92

# Dark young of Shub-Niggurath
R:677:0xB2/0x9D

# Colour out of space
R:678:0x91/0x99

# Quaker, Master of Earth
R:679:0x9F/0x8F

# Death leprechaun
R:680:0xA7/0x9E

# Chaugnar Faugn, Horror from the Hills
R:681:0xBC/0x94

# Lloigor
R:682:0xBC/0x95

# Utgard-Loke
R:683:0xBC/0x96

# Quachil Uttaus, Treader of the Dust
R:684:0xBC/0x97

# Shoggoth
R:685:0xBC/0x98

# Judge Death
R:686:0xBC/0x99

# Ariel, Queen of Air
R:687:0x9F/0x91

# 11-headed hydra
R:688:0xA2/0x9A

# Patriarch
R:689:0xAB/0x9A

# Dreadmaster
R:690:0xA0/0x85

# Drolem
R:691:0xA7/0x92

# Scatha the Worm
R:692:0xAD/0x9B

# Warrior of the Dawn
R:693:0xB2/0x9E

# Lesser black reaver
R:694:0xA4/0x87

# Zoth-Ommog
R:695:0xBE/0x89

# Grand master thief
R:696:0xC2/0x8A

# Smaug the Golden
R:697:0x9E/0x93

# The Stormbringer
R:698:0xB3/0x80

# Knight Templar
R:699:0xB3/0x81

# Leprechaun fanatic
R:700:0xA8/0x80

# Dracolich
R:701:0x9E/0x95

# Greater titan
R:702:0xA1/0x98

# Dracolisk
R:703:0x9E/0x94

# Winged Horror
R:704:0xC4/0x9E

# Spectral tyrannosaur
R:705:0xB3/0x82

# Yibb-Tstll, the Patient One
R:706:0xBC/0x9B

# Ghatanothoa
R:707:0xBC/0x9C

# Ent
R:708:0xBC/0x86

# Hru
R:709:0xBC/0x9D

# Itangast the Fire Drake
R:710:0x9E/0x96

# Death mold
R:711:0xA9/0x87

# Fafner the Dragon
R:712:0xB3/0x83

# Charon, Boatman of the Styx
R:713:0xBC/0x9E

# Quickbeam, the Ent
R:714:0xBC/0x9F

# Glaurung, Father of the Dragons
R:715:0xAD/0x9A

# Behemoth
R:716:0xBD/0x80

# Garm, Guardian of Hel
R:717:0x9E/0x84

# Greater wall monster
R:718:0xB3/0x84

# Nycadaemon
R:719:0xAD/0x91

# Barbazu
R:720:0xAD/0x95

# Goat of Mendes
R:721:0xB3/0x85

# Nightwing
R:722:0xAD/0x9D

# Maulotaur
R:723:0xB3/0x86

# Nether hound
R:724:0xA5/0x81

# Time hound
R:725:0xA5/0x82

# Plasma hound
R:726:0xA5/0x83

# Demonic quylthulg
R:727:0xA1/0x9D

# Great Storm Wyrm
R:728:0x9E/0x97

# Ulik the Troll
R:729:0xBD/0x81

# Baphomet the Minotaur Lord
R:730:0xA0/0x90

# Hell knight
R:731:0xBD/0x82

# Bull Gates
R:732:0xB3/0x87

# Santa Claus
R:733:0xB3/0x88

# Eihort, the Thing in the Labyrinth
R:734:0xBE/0x8A

# The King in Yellow
R:735:0xBE/0x8B

# Great unclean one
R:736:0xBE/0x8C

# Lord of Chaos
R:737:0xB3/0x89

# Old Sorcerer
R:738:0x9C/0x8A

# Ethereal hound
R:739:0xB3/0x8A

# Lesser kraken
R:740:0xBD/0x83

# Great Ice Wyrm
R:741:0x9E/0x98

# Demilich
R:742:0xA4/0x8A

# The Phoenix
R:743:0x9D/0x98

# Nightcrawler
R:744:0xA4/0x8C

# Lord of Change
R:745:0xBC/0x87

# Keeper of Secrets
R:746:0xBE/0x8D

# Shudde M'ell
R:747:0xBE/0x8E

# Hand druj
R:748:0xAC/0x8E

# Eye druj
R:749:0xAC/0x8F

# Skull druj
R:750:0xAC/0x90

# Chaos vortex
R:751:0xAC/0x9B

# Aether vortex
R:752:0xAC/0x9C

# Nidhogg, the Hel-Drake
R:753:0xBE/0x8F

# The Lernaean Hydra
R:754:0xA2/0x9B

# Thuringwethil, the Vampire Messenger
R:755:0xA3/0x9D

# Great Hell Wyrm
R:756:0x9E/0x99

# Hastur the Unspeakable
R:757:0xB3/0x8B

# Bloodthirster
R:758:0xBD/0x84

# Draconic quylthulg
R:759:0xA1/0x9E

# Nyogtha, the Thing that Should not Be
R:760:0xB3/0x8C

# Ahtu, Avatar of Nyarlathotep
R:761:0xBE/0x90

# Fundin Bluecloak
R:762:0xBE/0x91

# Bile Demon
R:763:0xC5/0x80

# Uriel, Angel of Fire
R:764:0x9D/0x94

# Azriel, Angel of Death
R:765:0x9D/0x95

# Ancalagon the Black
R:766:0x9E/0x9A

# Daoloth, the Render of the Veils
R:767:0xBE/0x92

# Nightwalker
R:768:0xBD/0x85

# Gabriel, the Messenger
R:769:0x9D/0x96

# Artsi, the Champion of Chaos
R:770:0xBE/0x93

# Saruman of Many Colours
R:771:0xAB/0x9E

# Harowen the Black Hand
R:772:0xBE/0x94

# Osyluth
R:773:0xC5/0x81

# Dreadlord
R:774:0xA0/0x86

# Greater kraken
R:775:0xBD/0x86

# Archlich
R:776:0xA4/0x8D

# The Cat Lord
R:777:0xB3/0x8F

# Jabberwock
R:778:0xC5/0x82

# Chaos hound
R:779:0xA5/0x85

# Vlad Dracula, Prince of Darkness
R:780:0xBE/0x95

# Beholder hive-mother
R:781:0xBE/0x96

# Leviathan
R:782:0xBD/0x87

# Great Wyrm of Chaos
R:783:0x9E/0x9B

# Great Wyrm of Law
R:784:0x9E/0x9C

# Great Wyrm of Balance
R:785:0x9E/0x9D

# Shambler
R:786:0xB3/0x91

# Gelugon
R:787:0xC5/0x83

# Glaaki
R:788:0xB9/0x88

# T'ron, the Rebel Dragonrider
R:789:0xB3/0x92

# Great Wyrm of Many Colours
R:790:0xB3/0x93

# Mardra, rider of the Gold Loranth
R:791:0xB3/0x94

# Tselakus, the Dreadlord
R:792:0xA0/0x87

# Sky Drake
R:793:0xB3/0x95

# Eilinel the Entrapped
R:794:0xA0/0x83

# Horned Reaper
R:795:0xC5/0x84

# The Norsa
R:796:0xB3/0x97

# Rhan-Tegoth
R:797:0xBE/0x99

# Black reaver
R:798:0xA1/0x85

# Master mindcrafter
R:799:0xAB/0x9F

# Greater demonic quylthulg
R:800:0xA1/0x9F

# Greater draconic quylthulg
R:801:0xA2/0x80

# Greater rotting quylthulg
R:802:0xA2/0x81

# Null, the Living Void
R:803:0xBC/0x88

# Feagwath, the Undead Sorcerer
R:804:0xA1/0x86

# Omarax the Eye Tyrant
R:805:0xA7/0x81

# Tsathoggua, the Sleeper of N'kai
R:806:0xBE/0x9A

# Greater Balrog
R:807:0xAD/0x93

# Ungoliant, the Unlight
R:808:0xA3/0x88

# Atlach-Nacha, the Spider God
R:809:0xB3/0x9A

# Y'golonac
R:810:0xBE/0x9B

# Aether hound
R:811:0xA5/0x86

# Pit Fiend
R:812:0xAD/0x92

# The Serpent of Chaos
R:813:0xB4/0x8D

# Yig, Father of Serpents
R:814:0xBE/0x9C

# Unmaker
R:815:0xB3/0x9C

# Cyberdemon
R:816:0xB3/0x9D

# Hela, Queen of the Dead
R:817:0xBE/0x9D

# The Mouth of Sauron
R:818:0xBE/0x9E

# The Necromancer of Dol Guldur
R:819:0xB3/0x9E

# Lessa, rider of the Gold Ramoth
R:820:0xB3/0x9F

# Master quylthulg
R:821:0xA2/0x82

# Qlzqqlzuup, the Lord of Flesh
R:822:0xA2/0x83

# Cthugha, the Living Flame
R:823:0xBE/0x9F

# F'lar, rider of the Bronze Mnementh
R:824:0xB4/0x80

# Maeglin, the Traitor of Gondolin
R:825:0xA4/0x8E

# Cyaegha
R:826:0xBF/0x80

# Pazuzu, Lord of Air
R:827:0xBF/0x81

# Ithaqua the Windwalker
R:828:0xB4/0x81

# Greater Hellhound
R:829:0x9E/0x83

# Cantoras, the Skeletal Lord
R:830:0xAC/0x91

# Mephistopheles, Lord of Hell
R:831:0xB4/0x82

# Godzilla
R:832:0xB4/0x83

# Abhoth, Source of Uncleanness
R:833:0xBF/0x82

# Ymir, the Ice Giant
R:834:0xBF/0x83

# Loki, the Trickster
R:835:0xBF/0x84

# Star-spawn of Cthulhu
R:836:0xB4/0x84

# Surtur, the Fire Giant
R:837:0xBF/0x85

# The Tarrasque
R:838:0xBC/0x93

# Lungorthin, the Balrog of White Fire
R:839:0xBF/0x86

# Draugluin, Sire of All Werewolves
R:840:0xBF/0x87

# Shuma-Gorath
R:841:0xBF/0x88

# Tulzscha, the Green Flame
R:842:0xBC/0x92

# Oremorj, the Cyberdemon Lord
R:843:0xBC/0x91

# Vecna, the Emperor Lich
R:844:0xB4/0x85

# Yog-Sothoth, the All-in-One
R:845:0xB4/0x86

# Fenris Wolf
R:846:0xBC/0x90

# Great Wyrm of Power
R:847:0xB4/0x87

# Shub-Niggurath, Black Goat of the Woods
R:848:0xB4/0x88

# Nodens, Lord of the Great Abyss
R:849:0xAB/0x8D

# Carcharoth, the Jaws of Thirst
R:850:0x9E/0x86

# Nyarlathotep, the Crawling Chaos
R:851:0xB4/0x89

# Azathoth, the Daemon Sultan
R:852:0xB4/0x8A

# Huan, Wolfhound of the Valar
R:853:0x9E/0x87

# Jormungand the Midgard Serpent
R:854:0xBC/0x8F

# The Destroyer
R:855:0xBC/0x8E

# Gothmog, the High Captain of Balrogs
R:856:0xAD/0x98

# Great Cthulhu
R:857:0xB4/0x8B

# Sorka, rider of the Gold Faranth
R:858:0xB4/0x8C

# The Unicorn of Order
R:859:0xBC/0x8D

# Sauron, the Sorcerer
R:860:0xAC/0x80

# DarkGod, the Mighty Coder of Hell
R:861:0xC0/0x9D

# Morgoth, Lord of Darkness
R:862:0xB4/0x8E

# Human Warrior
R:863:0xB5/0x80

# Elven archer
R:864:0xB5/0x81

# Dwarven warrior
R:865:0xB5/0x82

# Elite uruk
R:866:0xB5/0x83

# The Philosophy Teacher
R:867:0xBC/0x8C

# The Variant Maintainer
R:868:0xBC/0x8B

# Random Number Generator
R:869:0xBC/0x8A

# Rocket mine
R:870:0xBD/0x88

# Bouncing mine
R:871:0xBD/0x89

# Durin's Bane
R:872:0xBF/0x89

# The Icky Queen
R:873:0xBF/0x8A

# Rot jelly
R:874:0xBD/0x8A

# Death
R:875:0xBD/0x8B

# Famine
R:876:0xBD/0x8D

# Pestilence
R:877:0xBD/0x8C

# War
R:878:0xBD/0x8E

# Pike
R:879:0xBD/0x8F

# Electric eel
R:880:0xBD/0x90

# Giant crayfish
R:881:0xBD/0x91

# Mermaid
R:882:0xBD/0x92

# Box jellyfish
R:883:0xBA/0x81

# Giant piranha
R:884:0xB6/0x9D

# Piranha
R:885:0xB6/0x9D

# Bullywug
R:886:0xBD/0x94

# Bullywug warrior
R:887:0xBD/0x95

# Bullywug shaman
R:888:0xBD/0x96

# Whale
R:889:0xBA/0x98

# Sand mite
R:890:0xBD/0x98

# Octopus
R:891:0xBD/0x99

# Giant octopus
R:892:0xBD/0x9A

# Eye of the deep
R:893:0xBD/0x9B

# Murk dweller
R:894:0xBF/0x8B

# Drowned soul
R:895:0xBF/0x8C

# Tiger shark
R:896:0xBF/0x8D

# Hammerhead shark
R:897:0xBA/0x90

# Great white shark
R:898:0xBB/0x82

# Aquatic golem
R:899:0xBF/0x8E

# Aquatic kobold
R:900:0xBF/0x8F

# White shark
R:901:0xBB/0x82

# Scrag
R:902:0xBF/0x91

# Jaws
R:903:0xBB/0x8C

# Aquatic elf
R:904:0xBF/0x93

# Aquatic elven warrior
R:905:0xBF/0x94

# Aquatic elven shaman
R:906:0xBF/0x95

# Stargazer
R:907:0xBF/0x96

# Elder stargazer
R:908:0xBF/0x97

# Flounder
R:909:0xBF/0x98

# Giant turtle
R:910:0xBF/0x99

# Baby dragon turtle
R:911:0xBF/0x9A

# Young dragon turtle
R:912:0xBF/0x9B

# Mature dragon turtle
R:913:0xBF/0x9C

# Ancient dragon turtle
R:914:0xBF/0x9D

# Fastitocalon
R:915:0xBF/0x9E

# Undead stargazer
R:916:0xBF/0x9F

# Killer whale
R:917:0xB9/0x9C

# Merrow
R:918:0xC5/0x85

# Water naga
R:919:0xC0/0x81

# Devilfish
R:920:0xC0/0x82

# Undead devilfish
R:921:0xC0/0x83

# Moby Dick, the White Whale
R:922:0xC0/0x80

# Aquatic hound
R:923:0xC0/0x85

# Water demon
R:924:0xC0/0x86

# Ixitxachitl
R:925:0xB8/0x9C

# Ixitxachitl priest
R:926:0xC0/0x88

# Vampiric ixitxachitl
R:927:0xC0/0x89

# Mathilde, the Science Student
R:928:0xBD/0x9C

# Child spirit
R:929:0xBD/0x9D

# Young spirit
R:930:0xBD/0x9E

# Mature spirit
R:931:0xBD/0x9F

# Experienced spirit
R:932:0xBE/0x80

# Wise spirit
R:933:0xBE/0x81

# Fangorn the Treebeard, Lord of the Ents
R:934:0xC0/0x8A

# Gandalf the Grey
R:935:0xC0/0x8B

# Nar, the Dwarf
R:936:0xC0/0x8C

# Novice mindcrafter
R:937:0xAA/0x9A

# Great Swamp Wyrm
R:938:0xC5/0x86

# Great Bile Wyrm
R:939:0xC5/0x87

# Blue Firelizard
R:940:0xBE/0x82

# Green Firelizard
R:941:0xBE/0x83

# Brown Firelizard
R:942:0xBE/0x84

# Bronze Firelizard
R:943:0xBE/0x85

# Gold Firelizard
R:944:0xBE/0x86

# High-elven ranger
R:945:0xBE/0x87

# Uvatha the Horseman
R:946:0xC0/0x90

# Adunaphel the Quiet
R:947:0xC0/0x91

# Akhorahil the Blind
R:948:0xC0/0x92

# Ren the Unclean
R:949:0xC0/0x93

# Ji Indur Dawndeath
R:950:0xC0/0x94

# Dwar, Dog Lord of Waw
R:951:0xC0/0x95

# Hoarmurath of Dir
R:952:0xC0/0x96

# Khamul, the Black Easterling
R:953:0xC0/0x97

# The Witch-King of Angmar
R:954:0xC0/0x98

# Green Dragonrider
R:955:0xB3/0x96

# Blue Dragonrider
R:956:0xB3/0x8E

# Brown Dragonrider
R:957:0xB3/0x98

# Bronze Dragonrider
R:958:0xB3/0x98

# Gold Dragonrider
R:959:0xB3/0x94

# Thread
R:960:0xBE/0x88

# Gorlim, Betrayer of Barahir
R:961:0xC0/0x99

# The Blubbering idiot, agent of black market, Simon the weak
R:962:0xAA/0x82

# Aranea
R:963:0xC1/0x9A

# Elder aranea
R:964:0xC0/0x9A

# Giant brown tick
R:965:0xC5/0x88

# Dolphiner
R:966:0xC0/0x9C

# Novice possessor (soul)
R:967:0xC4/0x86

# Bat of Gorgoroth
R:968:0xC5/0x97

# The Princess
R:969:0xC5/0x98

# Merton Proudfoot, the lost hobbit
R:970:0xC5/0x99

# The Wight-King of the Barrow-downs
R:971:0xC5/0x9A

# Adventurer
R:972:0xC5/0x9B

# Experienced possessor (soul)
R:973:0xC5/0x9C

# Old possessor (soul)
R:974:0xC5/0x9D

# Death orb
R:975:0xC5/0x9E

# Bronze dragon worm
R:976:0xC6/0x80

# Gold dragon worm
R:977:0xC5/0x9F

# Moldoux, the Defenceless Mold
R:978:0xBC/0x89

# The Physics Teacher
R:979:0xBE/0x97

# Ar-Pharazon the Golden
R:980:0xC0/0x9E

# Doppelganger
R:981:0x97/0x8C

# Marylene, Heartbreakeress of the Netherworld
R:982:0xC1/0x8D

# The Greater Lag Monster
R:983:0xC2/0x8D

# Hrungnir, the Stone Giant
R:984:0xA7/0x8A

# Bullroarer the Hobbit
R:985:0xA7/0x9B

# 3-headed hydra
R:986:0xA2/0x94

# Uldor the Accursed
R:987:0xAB/0x95

# Mystic
R:988:0xAB/0x9B

# Elder vampire
R:989:0xA1/0x99

# Ulfang the Black
R:990:0xAA/0x96

# Demonologist
R:991:0xA8/0x82

# Hezrou
R:992:0xA2/0x9C

# Glabrezu
R:993:0xA2/0x8E

# Nalfeshnee
R:994:0xC2/0x8E

# Marilith
R:995:0xC2/0x8F

# Lesser Balrog
R:996:0xAD/0x95

# Master mystic
R:997:0xAA/0x94

# Grand master mystic
R:998:0xAB/0x9D

# Erinyes
R:999:0xA0/0x84

# Novice mindcrafter
R:1000:0xAA/0x9A

# Polyphemus, the Blind Cyclops
R:1001:0xC5/0x89

# Great Wyrm of Perplexity
R:1002:0xC2/0x92

# Hound of Tindalos
R:1003:0xC2/0x93

# Great Wyrm of Thunder
R:1004:0xC5/0x8A

# Silver mouse
R:1005:0xC5/0x8B

# The Rat King
R:1006:0xC2/0x96

# Vort the Kobold Queen
R:1007:0xC2/0x97

# Giant black louse
R:1008:0xC2/0x98

# Fire Phantom
R:1009:0xC2/0x99

# The Insane Player
R:1010:0x92/0x81

# Glaryssa, Succubus Queen
R:1011:0xC2/0x9A

# Vermicious Knid
R:1012:0xC2/0x9B

# Bone golem
R:1013:0xC2/0x9C

# Snake of Yig
R:1014:0xC2/0x9D

# Bronze golem
R:1015:0xC5/0x8C

# Dimensional shambler
R:1016:0xC2/0x9F

# Cultist
R:1017:0x94/0x99

# Cult leader
R:1018:0x99/0x97

# Servitor of the outer gods
R:1019:0xC3/0x8A

# Avatar of Nyarlathotep
R:1020:0xC3/0x8B

# Thiazi, the Storm Giant
R:1021:0xC5/0x8D

# Hypnos, Lord of Sleep
R:1022:0xC3/0x8D

# Blue dragon worm
R:1023:0xC3/0x8E

# White dragon worm
R:1024:0xC3/0x8F

# Green dragon worm
R:1025:0xC3/0x92

# Black dragon worm
R:1026:0xC3/0x91

# Red dragon worm
R:1027:0xC3/0x90

# Multi-hued dragon worm
R:1028:0xC3/0x93

# The Minotaur of the Labyrinth
R:1029:0xC3/0x94

# The Sandworm Queen
R:1030:0xC3/0x9B

# Sandworm
R:1031:0xC3/0x9C

# Tik'srvzllat
R:1032:0xC3/0x9D

# The Glass Golem
R:1033:0xC5/0x8E

# The White Balrog
R:1034:0xC5/0x8F

# Golgarach, the Living Rock
R:1035:0x80/0x84

# Atlas, the Titan
R:1036:0xC5/0x90

# Kronos, Lord of the Titans
R:1037:0xC5/0x91

# Water hound
R:1038:0xC6/0x88

# Improv, the mighty MoLD
R:1039:0xC6/0x8E

# Emperor Mimic
R:1040:0xC6/0x9C

# Melinda Proudfoot
R:1041:0x88/0xAA

# Thrain, the King Under the Mountain
R:1042:0x88/0xAB

# Spells (*)
S:48:0x91/0x88
S:49:0x91/0x89
S:50:0x91/0x8A
S:51:0x91/0x8B
S:52:0x91/0x8C
S:53:0x91/0x8D
S:54:0x91/0x8E
S:55:0x91/0x8F
S:56:0x91/0x90
S:57:0x91/0x91
S:58:0x91/0x92
S:59:0x91/0x93
S:60:0x91/0x94
S:61:0x91/0x95
S:62:0x91/0x96
S:63:0x91/0x97

# Spells (|)
S:64:0x8F/0x80
S:65:0x8F/0x84
S:66:0x8F/0x88
S:67:0x8F/0x8C
S:68:0x8F/0x90
S:69:0x8F/0x94
S:70:0x8F/0x98
S:71:0x8F/0x9C
S:72:0x90/0x80
S:73:0x90/0x84
S:74:0x90/0x88
S:75:0x90/0x8C
S:76:0x90/0x90
S:77:0x90/0x94
S:78:0x90/0x98
S:79:0x90/0x9C

# Spells (-)
S:80:0x8F/0x81
S:81:0x8F/0x85
S:82:0x8F/0x89
S:83:0x8F/0x8D
S:84:0x8F/0x91
S:85:0x8F/0x95
S:86:0x8F/0x99
S:87:0x8F/0x9D
S:88:0x90/0x81
S:89:0x90/0x85
S:90:0x90/0x89
S:91:0x90/0x8D
S:92:0x90/0x91
S:93:0x90/0x95
S:94:0x90/0x99
S:95:0x90/0x9D

# Spells (/)
S:96:0x8F/0x82
S:97:0x8F/0x86
S:98:0x8F/0x8A
S:99:0x8F/0x8E
S:100:0x8F/0x92
S:101:0x8F/0x96
S:102:0x8F/0x9A
S:103:0x8F/0x9E
S:104:0x90/0x82
S:105:0x90/0x86
S:106:0x90/0x8A
S:107:0x90/0x8E
S:108:0x90/0x92
S:109:0x90/0x96
S:110:0x90/0x9A
S:111:0x90/0x9E

# Spells (\)
S:112:0x8F/0x83
S:113:0x8F/0x87
S:114:0x8F/0x8B
S:115:0x8F/0x8F
S:116:0x8F/0x93
S:117:0x8F/0x97
S:118:0x8F/0x9B
S:119:0x8F/0x9F
S:120:0x90/0x83
S:121:0x90/0x87
S:122:0x90/0x8B
S:123:0x90/0x8F
S:124:0x90/0x93
S:125:0x90/0x97
S:126:0x90/0x9B
S:127:0x90/0x9F

# Amulets (")
S:128:0x87/0x87
S:129:0x87/0x80
S:130:0x87/0x88
S:131:0x87/0x82
S:132:0x87/0x83
S:133:0x87/0x84
S:134:0x87/0x85
S:135:0x87/0x86
S:136:0x87/0x81
S:137:0x87/0x81
S:138:0x87/0x89
S:139:0x87/0x8A
S:140:0x87/0x8B
S:141:0x87/0x8C
S:142:0x87/0x8D
S:143:0x87/0x8E

# Rings (=)
S:144:0x84/0x87
S:145:0x84/0x80
S:146:0x84/0x88
S:147:0x84/0x82
S:148:0x84/0x83
S:149:0x84/0x84
S:150:0x84/0x85
S:151:0x84/0x86
S:152:0x84/0x81
S:153:0x84/0x81
S:154:0x84/0x89
S:155:0x84/0x8A
S:156:0x84/0x8B
S:157:0x84/0x8C
S:158:0x84/0x8D
S:159:0x84/0x8E

# Staffs (_)
S:160:0x87/0x96
S:161:0x87/0x95
S:162:0x87/0x95
S:163:0x87/0x92
S:164:0x87/0x92
S:165:0x87/0x93
S:166:0x87/0x95
S:167:0x87/0x90
S:168:0x87/0x95
S:169:0x87/0x95
S:170:0x87/0x92
S:171:0x87/0x94
S:172:0x87/0x92
S:173:0x87/0x93
S:174:0x87/0x96
S:175:0x87/0x90

# Wands (-)
S:176:0x86/0x97
S:177:0x86/0x90
S:178:0x86/0x98
S:179:0x86/0x92
S:180:0x86/0x93
S:181:0x86/0x94
S:182:0x86/0x95
S:183:0x86/0x96
S:184:0x86/0x91
S:185:0x86/0x91
S:186:0x86/0x99
S:187:0x86/0x9A
S:188:0x86/0x9B
S:189:0x86/0x9C
S:190:0x86/0x9D
S:191:0x86/0x9E

# Rods (-)
S:192:0x86/0x87
S:193:0x86/0x80
S:194:0x86/0x88
S:195:0x86/0x82
S:196:0x86/0x83
S:197:0x86/0x84
S:198:0x86/0x85
S:199:0x86/0x86
S:200:0x86/0x81
S:201:0x86/0x81
S:202:0x86/0x89
S:203:0x86/0x8A
S:204:0x86/0x8B
S:205:0x86/0x8C
S:206:0x86/0x8D
S:207:0x86/0x8E

# Scrolls (?)
S:208:0x83/0x9C
S:209:0x83/0x9D
S:210:0x83/0x9E
S:211:0x83/0x9F
S:212:0x83/0x9C
S:213:0x83/0x9D
S:214:0x83/0x9E
S:215:0x83/0x9F
S:216:0x83/0x9C
S:217:0x83/0x9D
S:218:0x83/0x9E
S:219:0x83/0x9F
S:220:0x83/0x9C
S:221:0x83/0x9D
S:222:0x83/0x9E
S:223:0x83/0x9F

# Potions (!)
S:224:0x85/0x87
S:225:0x85/0x80
S:226:0x85/0x88
S:227:0x85/0x82
S:228:0x85/0x83
S:229:0x85/0x84
S:230:0x85/0x85
S:231:0x85/0x86
S:232:0x85/0x81
S:233:0x85/0x81
S:234:0x85/0x89
S:235:0x85/0x8A
S:236:0x85/0x8B
S:237:0x85/0x8C
S:238:0x85/0x8D
S:239:0x85/0x8E

# Food (,)
S:240:0x85/0x97
S:241:0x85/0x90
S:242:0x85/0x98
S:243:0x85/0x92
S:244:0x85/0x93
S:245:0x85/0x94
S:246:0x85/0x95
S:247:0x85/0x96
S:248:0x85/0x91
S:249:0x85/0x91
S:250:0x85/0x99
S:251:0x85/0x9A
S:252:0x85/0x9B
S:253:0x85/0x9C
S:254:0x85/0x9D
S:255:0x85/0x9E

# Fire golem
R:1043:0x8C/0xA0

# Melkor, Lord of Darkness
R:1044:0x8C/0xA1

# & piece~ of a Relic of Eru
K:814:0x8C/0xA2

# & piece~ of a Relic of Manwe
K:815:0x8C/0xA3

# & piece~ of a Relic of Tulkas
K:816:0x8C/0xA4

# & piece~ of a Relic of Melkor
K:817:0x8C/0xA5

# rocky ground
F:207:0x8D/0xA0

# cloud-like vapour
F:208:0x8D/0xA1

# condensing water
F:209:0x8D/0xA2

# dense mist
F:210:0x8D/0xA3

# hail-stone wall
F:211:0x8D/0xA4

# Mining Supply store
B:59:0x87/0xAE

# & piece~ of a Relic of Yavanna
K:818:0x8C/0xA6

# Elven
G:M:12:0x91/0xA1

# Dwarven
G:M:13:0x91/0xA0

# Spirit
R:1045:0x92/0x9F
R:1046:0x92/0xA0
R:1047:0x92/0xA1
R:1048:0x92/0xA2
R:1049:0x92/0xA3
R:1050:0x92/0xA4
R:1051:0x92/0xA5
R:1052:0x92/0xA6
R:1053:0x92/0xA7
R:1054:0x92/0xA8
R:1055:0x92/0xA9
R:1056:0x92/0xAA
R:1057:0x92/0xA3
R:1058:0x92/0xAB
R:1059:0x92/0xAC
R:1060:0x92/0xAD
R:1061:0x92/0xAE
R:1062:0x92/0xAF
R:1063:0x92/0xB0
R:1064:0x92/0xB1
R:1065:0x92/0xB2
R:1066:0x92/0xB3
R:1067:0x92/0xB4
R:1068:0x92/0xB5
R:1069:0x92/0xB6
R:1070:0x92/0xB7
R:1071:0x92/0xB8
R:1072:0x92/0xB9
R:1073:0x92/0xBA
R:1074:0x92/0xBB
R:1075:0x92/0xBC

# & Spellbook~ of #
K:757:0x91/0xA4

# Weakness Trap
#G:T:1:0xFF/0xFF
#G:T:2:0xFF/0xFF
#G:T:3:0xFF/0xFF

# Intelligence Trap
#G:T:4:0xFF/0xFF
#G:T:5:0xFF/0xFF
#G:T:6:0xFF/0xFF

# Wisdom Trap
#G:T:7:0xFF/0xFF
#G:T:8:0xFF/0xFF
#G:T:9:0xFF/0xFF

# Fumbling Fingers Trap
#G:T:10:0xFF/0xFF
#G:T:11:0xFF/0xFF
#G:T:12:0xFF/0xFF

# Wasting Trap
#G:T:13:0xFF/0xFF
#G:T:14:0xFF/0xFF
#G:T:15:0xFF/0xFF

# Beauty Trap
#G:T:16:0xFF/0xFF
#G:T:17:0xFF/0xFF
#G:T:18:0xFF/0xFF

# Trap of Curse Weapon
#G:T:20:0xFF/0xFF

# Trap of Curse Armor
#G:T:21:0xFF/0xFF

# Earthquake Trap
#G:T:22:0xFF/0xFF

# Poison Needle Trap
#G:T:23:0xFF/0xFF

# Summon Monster Trap
#G:T:24:0xFF/0xFF

# Summon Undead Trap
#G:T:25:0xFF/0xFF

# Summon Greater Undead Trap
#G:T:26:0xFF/0xFF

# Teleport Trap
#G:T:27:0xFF/0xFF

# Paralyzing Trap
#G:T:28:0xFF/0xFF

# Explosive Device
#G:T:29:0xFF/0xFF

# Teleport Item Trap
#G:T:30:0xFF/0xFF

# Lose Memory Trap
#G:T:31:0xFF/0xFF

# Bitter Regret Trap
#G:T:32:0xFF/0xFF

# Bowel Cramps Trap
#G:T:33:0xFF/0xFF

# Blindness
#G:T:34:0xFF/0xFF

# Aggravation Trap
#G:T:35:0xFF/0xFF

# Multiplication Trap
#G:T:36:0xFF/0xFF

# Steal Item Trap
#G:T:37:0xFF/0xFF

# Summon Fast Quylthulgs Trap
#G:T:38:0xFF/0xFF

# Trap of Sinking
#G:T:39:0xFF/0xFF

# Trap of Mana Drain
#G:T:40:0xFF/0xFF

# Trap of Missing Money
#G:T:41:0xFF/0xFF

# Trap of No Return
#G:T:42:0xFF/0xFF

# Trap of Silent Switching
#G:T:43:0xFF/0xFF

# Trap of Walls
#G:T:44:0xFF/0xFF

# Trap of Calling Out
#G:T:45:0xFF/0xFF

# Trap of Sliding
#G:T:46:0xFF/0xFF

# Trap of Charges Drain
#G:T:47:0xFF/0xFF

# Trap of Stair Movement
#G:T:48:0xFF/0xFF

# Trap of New Trap
#G:T:49:0xFF/0xFF

# Trap of Scatter Items
#G:T:50:0xFF/0xFF

# Trap of Decay
#G:T:51:0xFF/0xFF

# Trap of Wasting Wands
#G:T:52:0xFF/0xFF

# Trap of Filling
#G:T:53:0xFF/0xFF

# Trap of Drain Speed
#G:T:54:0xFF/0xFF

# Lightning Bolt Trap
#G:T:60:0xFF/0xFF

# Poison Bolt Trap
#G:T:61:0xFF/0xFF

# Acid Bolt Trap
#G:T:62:0xFF/0xFF

# Cold Bolt Trap
#G:T:63:0xFF/0xFF

# Fire Bolt Trap
#G:T:64:0xFF/0xFF

# Plasma Bolt Trap
#G:T:65:0xFF/0xFF

# Water Bolt Trap
#G:T:66:0xFF/0xFF

# Lite Bolt Trap
#G:T:67:0xFF/0xFF

# Dark Bolt Trap
#G:T:68:0xFF/0xFF

# Shards Bolt Trap
#G:T:69:0xFF/0xFF

# Sound Bolt Trap
#G:T:70:0xFF/0xFF

# Confusion Bolt Trap
#G:T:71:0xFF/0xFF

# Force Bolt Trap
#G:T:72:0xFF/0xFF

# Inertia Bolt Trap
#G:T:73:0xFF/0xFF

# Mana Bolt Trap
#G:T:74:0xFF/0xFF

# Ice Bolt Trap
#G:T:75:0xFF/0xFF

# Chaos Bolt Trap
#G:T:76:0xFF/0xFF

# Nether Bolt Trap
#G:T:77:0xFF/0xFF

# Disenchantment Bolt Trap
#G:T:78:0xFF/0xFF

# Nexus Bolt Trap
#G:T:79:0xFF/0xFF

# Time Bolt Trap
#G:T:80:0xFF/0xFF

# Gravity Bolt Trap
#G:T:81:0xFF/0xFF

# Lightning Ball Trap
#G:T:82:0xFF/0xFF

# Poison Ball Trap
#G:T:83:0xFF/0xFF

# Acid Ball Trap
#G:T:84:0xFF/0xFF

# Cold Ball Trap
#G:T:85:0xFF/0xFF

# Fire Ball Trap
#G:T:86:0xFF/0xFF

# Plasma Ball Trap
#G:T:87:0xFF/0xFF

# Water Ball Trap
#G:T:88:0xFF/0xFF

# Light Ball Trap
#G:T:89:0xFF/0xFF

# Darkness Ball Trap
#G:T:90:0xFF/0xFF

# Shards Ball Trap
#G:T:91:0xFF/0xFF

# Sound Ball Trap
#G:T:92:0xFF/0xFF

# Confusion Ball Trap
#G:T:93:0xFF/0xFF

# Force Ball Trap
#G:T:94:0xFF/0xFF

# Inertia Ball Trap
#G:T:95:0x82/0xBF

# Mana Ball Trap
#G:T:96:0xFF/0xFF

# Ice Ball Trap
#G:T:97:0xFF/0xFF

# Chaos Ball Trap
#G:T:98:0xFF/0xFF

# Nether Ball Trap
#G:T:99:0xFF/0xFF

# Disenchantment Ball Trap
#G:T:100:0xFF/0xFF

# Nexus Ball Trap
#G:T:101:0xFF/0xFF

# Time Ball Trap
#G:T:102:0xFF/0xFF

# Gravity Ball Trap
#G:T:103:0xFF/0xFF

# Arrow Trap
#G:T:110:0xFF/0xFF

# Bolt Trap
#G:T:111:0xFF/0xFF

# Seeker Arrow Trap
#G:T:112:0xFF/0xFF

# Seeker Bolt Trap
#G:T:113:0xFF/0xFF

# Poison Arrow Trap
#G:T:114:0xFF/0xFF

# Poison Bolt Trap
#G:T:115:0xFF/0xFF

# Poison Seeker Arrow Trap
#G:T:116:0xFF/0xFF

# Poison Seeker Bolt Trap
#G:T:117:0xFF/0xFF

# Broken Dagger Trap
#G:T:118:0xFF/0xFF

# Dagger Trap
#G:T:119:0xFF/0xFF

# Poison Broken Dagger Trap
#G:T:120:0xFF/0xFF

# Poison Dagger Trap
#G:T:121:0xFF/0xFF

# Arrows Trap
#G:T:122:0xFF/0xFF

# Bolts Trap
#G:T:123:0xFF/0xFF

# Seeker Arrow Trap
#G:T:124:0xFF/0xFF

# Seeker Bolt Trap
#G:T:125:0xFF/0xFF

# Poison Arrows Trap
#G:T:126:0xFF/0xFF

# Poison Bolt Trap
#G:T:127:0xFF/0xFF

# Poison Seeker Arrows Trap
#G:T:128:0xFF/0xFF

# Poison Seeker Bolts Trap
#G:T:129:0xFF/0xFF

# Broken Daggers Trap
#G:T:130:0xFF/0xFF

# Dagger Trap
#G:T:131:0xFF/0xFF

# Poison Broken Daggers Trap
#G:T:132:0xFF/0xFF

# Poison Daggers Trap
#G:T:133:0xFF/0xFF

# Trap of Drop Item
#G:T:140:0xFF/0xFF

# Trap of Drop Items
#G:T:141:0xFF/0xFF

# Trap of Drop Everything
#G:T:142:0xFF/0xFF

# Trap of Femininity
#G:T:150:0xFF/0xFF

# Trap of Masculinity
#G:T:151:0xFF/0xFF

# Trap of Neutrality
#G:T:152:0xFF/0xFF

# Trap of Aging
#G:T:153:0xFF/0xFF

# Trap of Growing
#G:T:154:0xFF/0xFF

# Trap of Shrinking
#G:T:155:0xFF/0xFF

# Trap of Tanker Drain
#G:T:157:0xFF/0xFF

# Trap of Divine Anger
#G:T:158:0xFF/0xFF

# Trap of Divine Wrath
#G:T:159:0xFF/0xFF

# Hallucination Trap
#G:T:160:0xFF/0xFF

# Greater Magic Missile Trap
#G:T:161:0xFF/0xFF

# Foulness Trap
#G:T:162:0xFF/0xFF

# Trap of Holy Fire
#G:T:164:0xFF/0xFF

# Trap of Hell Fire
#G:T:165:0xFF/0xFF

# Psi Bolt Trap
#G:T:166:0xFF/0xFF

# Psi Drain Trap
#G:T:167:0xFF/0xFF

# Plasma Ball Trap
#G:T:168:0xFF/0xFF

# Psi Ball Trap
#G:T:169:0xFF/0xFF

# Acquirement Trap
#G:T:170:0xFF/0xFF

# Greater Lightning Bolt Trap
#G:T:171:0xFF/0xFF

# Greater Poison Bolt Trap
#G:T:172:0xFF/0xFF

# Greater Acid Bolt Trap
#G:T:173:0xFF/0xFF

# Greater Cold Bolt Trap
#G:T:174:0xFF/0xFF

# Greater Fire Bolt Trap
#G:T:175:0xFF/0xFF
# non-defines encountered :
# Load the special player pictures
%:xtra-new.prf
tome-235-src/lib/pref/xtra-xxx.prf0000644000076400017500000000756211012107762014715 0ustar  dgdg# File: xtra-xxx.prf

#
# This file defines special attr/char mappings for use in "graphics" mode
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


##### Remap the player icon #####

?:[AND [EQU $CLASS Warrior] [EQU $RACE Human] ]
R:0:0x8C/0x80
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Elf] ]
R:0:0x8C/0x81
?:[AND [EQU $CLASS Warrior] [EQU $RACE Elf] ]
R:0:0x8C/0x82
?:[AND [EQU $CLASS Warrior] [EQU $RACE Hobbit] ]
R:0:0x8C/0x83
?:[AND [EQU $CLASS Warrior] [EQU $RACE Gnome] ]
R:0:0x8C/0x84
?:[AND [EQU $CLASS Warrior] [EQU $RACE Dwarf] ]
R:0:0x8C/0x85
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Orc] ]
R:0:0x8C/0x86
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Troll] ]
R:0:0x8C/0x87
?:[AND [EQU $CLASS Warrior] [EQU $RACE Dunadan] ]
R:0:0x8C/0x88
?:[AND [EQU $CLASS Warrior] [EQU $RACE High-Elf] ]
R:0:0x8C/0x89

?:[AND [EQU $CLASS Mage] [EQU $RACE Human] ]
R:0:0x8C/0x8A
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Elf] ]
R:0:0x8C/0x8B
?:[AND [EQU $CLASS Mage] [EQU $RACE Elf] ]
R:0:0x8C/0x8C
?:[AND [EQU $CLASS Mage] [EQU $RACE Hobbit] ]
R:0:0x8C/0x8D
?:[AND [EQU $CLASS Mage] [EQU $RACE Gnome] ]
R:0:0x8C/0x8E
?:[AND [EQU $CLASS Mage] [EQU $RACE Dwarf] ]
R:0:0x8C/0x8F
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Orc] ]
R:0:0x8C/0x90
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Troll] ]
R:0:0x8C/0x91
?:[AND [EQU $CLASS Mage] [EQU $RACE Dunadan] ]
R:0:0x8C/0x92
?:[AND [EQU $CLASS Mage] [EQU $RACE High-Elf] ]
R:0:0x8C/0x93

?:[AND [EQU $CLASS Priest] [EQU $RACE Human] ]
R:0:0x8C/0x94
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Elf] ]
R:0:0x8C/0x95
?:[AND [EQU $CLASS Priest] [EQU $RACE Elf] ]
R:0:0x8C/0x96
?:[AND [EQU $CLASS Priest] [EQU $RACE Hobbit] ]
R:0:0x8C/0x97
?:[AND [EQU $CLASS Priest] [EQU $RACE Gnome] ]
R:0:0x8C/0x98
?:[AND [EQU $CLASS Priest] [EQU $RACE Dwarf] ]
R:0:0x8C/0x99
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Orc] ]
R:0:0x8C/0x9A
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Troll] ]
R:0:0x8C/0x9B
?:[AND [EQU $CLASS Priest] [EQU $RACE Dunadan] ]
R:0:0x8C/0x9C
?:[AND [EQU $CLASS Priest] [EQU $RACE High-Elf] ]
R:0:0x8C/0x9D

?:[AND [EQU $CLASS Rogue] [EQU $RACE Human] ]
R:0:0x8C/0x9E
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Elf] ]
R:0:0x8C/0x9F
?:[AND [EQU $CLASS Rogue] [EQU $RACE Elf] ]
R:0:0x8D/0x80
?:[AND [EQU $CLASS Rogue] [EQU $RACE Hobbit] ]
R:0:0x8D/0x81
?:[AND [EQU $CLASS Rogue] [EQU $RACE Gnome] ]
R:0:0x8D/0x82
?:[AND [EQU $CLASS Rogue] [EQU $RACE Dwarf] ]
R:0:0x8D/0x83
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Orc] ]
R:0:0x8D/0x84
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Troll] ]
R:0:0x8D/0x85
?:[AND [EQU $CLASS Rogue] [EQU $RACE Dunadan] ]
R:0:0x8D/0x86
?:[AND [EQU $CLASS Rogue] [EQU $RACE High-Elf] ]
R:0:0x8D/0x87

?:[AND [EQU $CLASS Ranger] [EQU $RACE Human] ]
R:0:0x8D/0x88
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Elf] ]
R:0:0x8D/0x89
?:[AND [EQU $CLASS Ranger] [EQU $RACE Elf] ]
R:0:0x8D/0x8A
?:[AND [EQU $CLASS Ranger] [EQU $RACE Hobbit] ]
R:0:0x8D/0x8B
?:[AND [EQU $CLASS Ranger] [EQU $RACE Gnome] ]
R:0:0x8D/0x8C
?:[AND [EQU $CLASS Ranger] [EQU $RACE Dwarf] ]
R:0:0x8D/0x8D
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Orc] ]
R:0:0x8D/0x8E
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Troll] ]
R:0:0x8D/0x8F
?:[AND [EQU $CLASS Ranger] [EQU $RACE Dunadan] ]
R:0:0x8D/0x90
?:[AND [EQU $CLASS Ranger] [EQU $RACE High-Elf] ]
R:0:0x8D/0x91

?:[AND [EQU $CLASS Paladin] [EQU $RACE Human] ]
R:0:0x8D/0x92
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Elf] ]
R:0:0x8D/0x93
?:[AND [EQU $CLASS Paladin] [EQU $RACE Elf] ]
R:0:0x8D/0x94
?:[AND [EQU $CLASS Paladin] [EQU $RACE Hobbit] ]
R:0:0x8D/0x95
?:[AND [EQU $CLASS Paladin] [EQU $RACE Gnome] ]
R:0:0x8D/0x96
?:[AND [EQU $CLASS Paladin] [EQU $RACE Dwarf] ]
R:0:0x8D/0x97
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Orc] ]
R:0:0x8D/0x98
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Troll] ]
R:0:0x8D/0x99
?:[AND [EQU $CLASS Paladin] [EQU $RACE Dunadan] ]
R:0:0x8D/0x9A
?:[AND [EQU $CLASS Paladin] [EQU $RACE High-Elf] ]
R:0:0x8D/0x9B

tome-235-src/lib/pref/font.prf0000644000076400017500000000151011012107762014043 0ustar  dgdg# File: font.prf

#
# This file defines special attr/char mappings for use in "text" mode
#
# This file includes, if appropriate, various "sub-files"
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


## #
## # OPTION: Display "veins" (white "%") as "normal walls" (white "#").
## #
## F:50:0x01/0x23
## F:51:0x01/0x23
## F:52:0x01/0x23
## F:53:0x01/0x23


##### Standard font file #####

%:font-xxx.prf


##### System Specific Subfiles #####

?:[IOR [EQU $SYS xaw] [EQU $SYS x11] [EQU $SYS gtk]]
%:font-x11.prf

?:[EQU $SYS glu]
%:font-glu.prf

?:[EQU $SYS gcu]
%:font-gcu.prf

?:[EQU $SYS ami]
%:font-ami.prf

?:[EQU $SYS mac]
%:font-mac.prf

?:[EQU $SYS win]
%:font-win.prf

?:[EQU $SYS dos]
%:font-dos.prf

?:[EQU $SYS ibm]
%:font-ibm.prf

?:[EQU $SYS emx]
%:font-emx.prf

?:[EQU $SYS acn]
%:font-acn.prf

?:1


tome-235-src/lib/pref/trap-iso.prf0000644000076400017500000001315611012107762014644 0ustar  dgdg# Prf file for use with the 8x8 tiles to define 
# trap image locations. Separated out from main 
# graphics definitions due to the G:T:num:y:x 
# instead of T:num:y:x  (major problems if this
# file is opened in the TileAssigner)

# Weakness Traps
G:T:1:0x8A:0xF6
G:T:2:0x8A:0xF6
G:T:3:0x8A:0xF6

# Intelligence Traps
G:T:4:0x8A:0xF6
G:T:5:0x8A:0xF6
G:T:6:0x8A:0xF6

# Wisdom Traps
G:T:7:0x8A:0xF6
G:T:8:0x8A:0xF6
G:T:9:0x8A:0xF6

# Fumbling Fingers Traps
G:T:10:0x8A:0xF6
G:T:11:0x8A:0xF6
G:T:12:0x8A:0xF6

# Wasting Traps
G:T:13:0x8A:0xF6
G:T:14:0x8A:0xF6
G:T:15:0x8A:0xF6

# Beauty Traps
G:T:16:0x8A:0xF6
G:T:17:0x8A:0xF6
G:T:18:0x8A:0xF6

# Trap of Curse Weapon
G:T:20:0x8A:0xF7

# Trap of Curse Armor
G:T:21:0x8A:0xF7

# Earthquake Trap
G:T:22:0x8A:0xFC

# Poison Needle Trap
G:T:23:0x8A:0xF8

# Summon Monster Trap
G:T:24:0x8A:0xFA

# Summon Undead Trap
G:T:25:0x8A:0xFA

# Summon Greater Undead Trap
G:T:26:0x8A:0xFA

# Teleport Trap
G:T:27:0x8A:0xFA

# Paralyzing Trap
G:T:28:0x8A:0xF8

# Explosive Device
G:T:29:0x8A:0xF8

# Teleport Item Trap
G:T:30:0x8A:0xFA

# Lose Memory Trap
G:T:31:0x8A:0xF8

# Bitter Regret Trap
G:T:32:0x8A:0xF8

# Bowel Cramps Trap
G:T:33:0x8A:0xF8

# Blindness/Confusion Trap
G:T:34:0x8A:0xF8

# Aggravation Trap
G:T:35:0x8A:0xFC

# Multiplication Trap
G:T:36:0x8A:0xFC

# Steal Item Trap
G:T:37:0x8A:0xF7

# Summon Fast Quylthulgs Trap
G:T:38:0x8A:0xFA

# Trap of Sinking
G:T:39:0x8A:0xFA

# Trap of Mana Drain
G:T:40:0x8A:0xF8

# Trap of Missing Money
#G:T:41:0x8A:0xF7
G:T:41:0x8A:0xF9

# Trap of No Return
G:T:42:0x8A:0xF7

# Trap of Silent Switching
G:T:43:0x8A:0xF7

# Trap of Walls
G:T:44:0x8A:0xFC

# Trap of Calling Out
G:T:45:0x8A:0xFA

# Trap of Sliding
G:T:46:0x8A:0xF8

# Trap of Charges Drain
G:T:47:0x8A:0xF7

# Trap of Stair Movement
G:T:48:0x8A:0xFC

# Trap of New Trap
G:T:49:0x8A:0xFC

# Trap of Scatter Items
G:T:50:0x8A:0xFA

# Trap of Decay
G:T:51:0x8A:0xF8

# Trap of Wasting Wands
G:T:52:0x8A:0xF7

# Trap of Filling
G:T:53:0x8A:0xFC

# Trap of Drain Speed
G:T:54:0x8A:0xF7

# Lightning Bolt Trap
G:T:60:0x8A:0xF9

# Poison Bolt Trap
G:T:61:0x8A:0xF9

# Acid Bolt Trap
G:T:62:0x8A:0xF9

# Cold Bolt Trap
G:T:63:0x8A:0xF9

# Fire Bolt Trap
G:T:64:0x8A:0xF9

# Plasma Bolt Trap
G:T:65:0x8A:0xF9

# Water Bolt Trap
G:T:66:0x8A:0xF9

# Lite Bolt Trap
G:T:67:0x8A:0xF9

# Dark Bolt Trap
G:T:68:0x8A:0xF9

# Shards Bolt Trap
G:T:69:0x8A:0xF9

# Sound Bolt Trap
G:T:70:0x8A:0xF9

# Confusion Bolt Trap
G:T:71:0x8A:0xF9

# Force Bolt Trap
G:T:72:0x8A:0xF9

# Inertia Bolt Trap
G:T:73:0x8A:0xF9

# Mana Bolt Trap
G:T:74:0x8A:0xF9

# Ice Bolt Trap
G:T:75:0x8A:0xF9

# Chaos Bolt Trap
G:T:76:0x8A:0xF9

# Nether Bolt Trap
G:T:77:0x8A:0xF9

# Disenchantment Bolt Trap
G:T:78:0x8A:0xF9

# Nexus  Bolt Trap
G:T:79:0x8A:0xF9

# Time Bolt Trap
G:T:80:0x8A:0xF9

# Gravity Bolt Trap
G:T:81:0x8A:0xF9

# Lightning Ball Trap
G:T:82:0x8A:0xFA

# Poison Ball Trap
G:T:83:0x8A:0xFA

# Acid Ball Trap
G:T:84:0x8A:0xFA

# Cold Ball Trap
G:T:85:0x8A:0xFA

# Fire Ball Trap
G:T:86:0x8A:0xFA

# Plasma Ball Trap
G:T:87:0x8A:0xFA

# Water Ball Trap
G:T:88:0x8A:0xFA

# Light Ball Trap
G:T:89:0x8A:0xFA

# Darkness Ball Trap
G:T:90:0x8A:0xFA

# Shards Ball Trap
G:T:91:0x8A:0xFA

# Sound Ball Trap
G:T:92:0x8A:0xFA

# Confusion Ball Trap
G:T:93:0x8A:0xFA

# Force Ball Trap
G:T:94:0x8A:0xFA

# Inertia Ball Trap
G:T:95:0x8A:0xFA

# Mana Ball Trap
G:T:96:0x8A:0xFA

# Ice Ball Trap
G:T:97:0x8A:0xFA

# Chaos Ball Trap
G:T:98:0x8A:0xFA

# Nether Ball Trap
G:T:99:0x8A:0xFA

# Disenchantment Ball Trap
G:T:100:0x8A:0xFA

# Nexus Ball Trap
G:T:101:0x8A:0xFA

# Time Ball Trap
G:T:102:0x8A:0xFA

# Gravity Ball Trap
G:T:103:0x8A:0xFA

# Arrow Trap
G:T:110:0x8A:0xFC

# Bolt Trap
G:T:111:0x8A:0xFC

# Seeker Arrow Trap
G:T:112:0x8A:0xFC

# Seeker Bolt Trap
G:T:113:0x8A:0xFC

# Poison Arrow Trap
G:T:114:0x8A:0xFC

# Poison Bolt Trap
G:T:115:0x8A:0xFC

# Poison Seeker Arrow Trap
G:T:116:0x8A:0xFC

# Poison Seeker Bolt Trap
G:T:117:0x8A:0xFC

# Broken Dagger Trap
G:T:118:0x8A:0xFC

# Dagger Trap
G:T:119:0x8A:0xFC

# Poison Broken Dagger Trap
G:T:120:0x8A:0xFC

# Poison Dagger Trap
G:T:121:0x8A:0xFC

# Arrows Trap
G:T:122:0x8A:0xFC

# Bolts Trap
G:T:123:0x8A:0xFC

# Seeker Arrow Trap
G:T:124:0x8A:0xFC

# Seeker Bolt Trap
G:T:125:0x8A:0xFC

# Poison Arrows Trap
G:T:126:0x8A:0xFC

# Poison Bolt Trap
G:T:127:0x8A:0xFC

# Poison Seeker Arrows Trap
G:T:128:0x8A:0xFC

# Poison Seeker Bolts Trap
G:T:129:0x8A:0xFC

# Broken Daggers Trap
G:T:130:0x8A:0xFC

# Dagger Trap
G:T:131:0x8A:0xFC

# Poison Broken Daggers Trap
G:T:132:0x8A:0xFC

# Poison Daggers Trap
G:T:133:0x8A:0xFC

# Trap of Drop Item
G:T:140:0x8A:0xF7

# Trap of Drop Items
G:T:141:0x8A:0xF7

# Trap of Drop Everything
G:T:142:0x8A:0xF7

# Trap of Femininity
G:T:150:0x8A:0xF8

# Trap of Masculinity
G:T:151:0x8A:0xF8

# Trap of Neutrality
G:T:152:0x8A:0xF8

# Trap of Aging
G:T:153:0x8A:0xF8

# Trap of Growing
G:T:154:0x8A:0xF8

# Trap of Shrinking
G:T:155:0x8A:0xF8

# Trap of Tanker Drain
G:T:157:0x8A:0xF8

# Trap of Divine Anger
G:T:158:0x8A:0xFB

# Trap of Divine Wrath
G:T:159:0x8A:0xFB

# Hallucination Trap
G:T:160:0x8A:0xF8

# Greater Magic Missile Trap
G:T:161:0x8A:0xF9

# Foulness Trap
G:T:162:0x8A:0xF9

# Trap of Death Ray
G:T:163:0x8A:0xF9

# Trap of Holy Fire
G:T:164:0x8A:0xF9

# Trap of Hell Fire
G:T:165:0x8A:0xF9

# Psi Bolt Trap
G:T:166:0x8A:0xF9

# Psi Drain Trap
G:T:167:0x8A:0xF8

# Plasma (Nuke) Ball Trap
G:T:168:0x8A:0xFA

# Psi Ball Trap
G:T:169:0x8A:0xFA

# Aquirement Trap
G:T:170:0x8A:0xFA

# Greater Lightning Bolt Trap
G:T:171:0x8A:0xF9

# Greater Poison Bolt Trap
G:T:172:0x8A:0xF9

# Greater Acid Bolt Trap
G:T:173:0x8A:0xF9

# Greater Cold Bolt Trap
G:T:174:0x8A:0xF9

# Greater Fire Bolt Trap
G:T:175:0x8A:0xF9
tome-235-src/lib/pref/pref-x11.prf0000644000076400017500000001220011012107762014436 0ustar  dgdg# File: pref-x11.prf

#
# This file provides some macros for use with versions of Angband compiled
# using the "main-x11.c" (or "main-xaw.c") file.
#
# Note the use of "\e\e\e\e" (four escapes) to allow the macros to work
# even if the game is not yet ready for a command.
#
# Note the use of "\\." (for "run") and "\\+" (for "alter"), to make sure
# that the macros will work regardless of the "keymap" being used.
#

#
# Macro Trigger configuration
#
# T:::::....
# '&' in  specifies location of modifier character.
# '#' in  specifies location of key code.
#
# If  is null string, all trigger difinition will be cleared.

T:&_#:NSOM:control-:shift-:alt-:mod2-

# T:::
# '\' in  is escape character.

T:Clear:FF0B
T:Pause:FF13
T:Scroll_Lock:FF14
T:Sys_Req:FF15
T:Escape:FF1B
T:Delete:FFFF
T:Multi_Key:FF20
T:Codeinput:FF37
T:SingleCandidate:FF3C
T:MultipleCandidate:FF3D
T:PreviousCandidate:FF3E
T:Kanji:FF21
T:Muhenkan:FF22
T:Henkan:FF23
T:Henkan_Mode:FF23
T:Romaji:FF24
T:Hiragana:FF25
T:Katakana:FF26
T:Hiragana_Katakana:FF27
T:Zenkaku:FF28
T:Hankaku:FF29
T:Zenkaku_Hankaku:FF2A
T:Touroku:FF2B
T:Massyo:FF2C
T:Kana_Lock:FF2D
T:Kana_Shift:FF2E
T:Eisu_Shift:FF2F
T:Eisu_Toggle:FF30
T:Kanji_Bangou:FF37
T:Zen_Koho:FF3D
T:Mae_Koho:FF3E
T:Home:FF50
T:Left:FF51
T:Up:FF52
T:Right:FF53
T:Down:FF54
T:Page_Up:FF55
T:Page_Down:FF56
T:End:FF57
T:Begin:FF58
T:Select:FF60
T:Print:FF61
T:Execute:FF62
T:Insert:FF63
T:Undo:FF65
T:Redo:FF66
T:Menu:FF67
T:Find:FF68
T:Cancel:FF69
T:Help:FF6A
T:Break:FF6B
T:Mode_Switch:FF7E
T:Num_Lock:FF7F
T:KP_Space:FF80
T:KP_Tab:FF89
T:KP_Enter:FF8D
T:KP_F1:FF91
T:KP_F2:FF92
T:KP_F3:FF93
T:KP_F4:FF94
T:KP_Home:FF95
T:KP_Left:FF96
T:KP_Up:FF97
T:KP_Right:FF98
T:KP_Down:FF99
T:KP_Page_Up:FF9A
T:KP_Page_Down:FF9B
T:KP_End:FF9C
T:KP_Begin:FF9D
T:KP_Insert:FF9E
T:KP_Delete:FF9F
T:KP_Equal:FFBD
T:KP_Multiply:FFAA
T:KP_Add:FFAB
T:KP_Comma:FFAC
T:KP_Subtract:FFAD
T:KP_Decimal:FFAE
T:KP_Divide:FFAF
T:KP_0:FFB0
T:KP_1:FFB1
T:KP_2:FFB2
T:KP_3:FFB3
T:KP_4:FFB4
T:KP_5:FFB5
T:KP_6:FFB6
T:KP_7:FFB7
T:KP_8:FFB8
T:KP_9:FFB9
T:F1:FFBE
T:F2:FFBF
T:F3:FFC0
T:F4:FFC1
T:F5:FFC2
T:F6:FFC3
T:F7:FFC4
T:F8:FFC5
T:F9:FFC6
T:F10:FFC7
T:F11:FFC8
T:F12:FFC9
T:F13:FFCA
T:F14:FFCB
T:F15:FFCC
T:F16:FFCD
T:F17:FFCE
T:F18:FFCF
T:F19:FFD0
T:F20:FFD1
T:F21:FFD2
T:F22:FFD3
T:F23:FFD4
T:F24:FFD5
T:F25:FFD6
T:F26:FFD7
T:F27:FFD8
T:F28:FFD9
T:F29:FFDA
T:F30:FFDB
T:F31:FFDC
T:F32:FFDD
T:F33:FFDE
T:F34:FFDF
T:F35:FFE0

T:\::3A:2A
T:*:3A:2A
T:;:3B:2B
T:+:3B:2B
T:,:2C:3C
T:<:2C:3C
T:-:2D:3D
T:=:2D:3D
T:.:2E:3E
T:>:2E:3E
T:\/:2F:3F
T:?:2F:3F
T:0:30:7E
T:~:30:7E
T:1:31:21
T:!:31:21
T:2:32:22
T:":32:22
T:3:33:23
T:#:33:23
T:4:34:24
T:$:34:24
T:5:35:25
T:%:35:25
T:6:36:26
T:&:36:26
T:7:37:27
T:\':37:27
T:8:38:28
T:(:38:28
T:9:39:29
T:):39:29
T:@:40:60
T:`:40:60
T:A:61:41
T:B:62:42
T:C:63:43
T:D:64:44
T:E:65:45
T:F:66:46
T:G:67:47
T:H:68:48
T:I:69:49
T:J:6A:4A
T:K:6B:4B
T:L:6C:4C
T:M:6D:4D
T:N:6E:4E
T:O:6F:4F
T:P:70:50
T:Q:71:51
T:R:72:52
T:S:73:53
T:T:74:54
T:U:75:55
T:V:76:56
T:W:77:57
T:X:78:58
T:Y:79:59
T:Z:7A:5A
T:[:5B:7B
T:{:5B:7B
T:\\:5C:5F
T:_:5C:5F
T:]:5D:7D
T:}:5D:7D
T:^:5E:7E
T:~:5E:7E
T:|:A5:7C


# Keypad (0-9)

A:0
P:^__FFB0\r
P:^__FF63\r
P:^__????\r
P:^__FF9E\r

A:1
P:^__FFB1\r
P:^__FF57\r
P:^__FFDE\r
P:^__FF9C\r

A:2
P:^__FFB2\r
P:^__FF54\r
P:^__FFDF\r
P:^__FF99\r

A:3
P:^__FFB3\r
P:^__FF56\r
P:^__FFE0\r
P:^__FF9B\r

A:4
P:^__FFB4\r
P:^__FF51\r
P:^__FFDB\r
P:^__FF96\r

A:5
P:^__FFB5\r
P:^__FF80\r
P:^__FFDC\r
P:^__FF9D\r

A:6
P:^__FFB6\r
P:^__FF53\r
P:^__FFDD\r
P:^__FF98\r

A:7
P:^__FFB7\r
P:^__FF50\r
P:^__FFD8\r
P:^__FF95\r

A:8
P:^__FFB8\r
P:^__FF52\r
P:^__FFD9\r
P:^__FF97\r

A:9
P:^__FFB9\r
P:^__FF55\r
P:^__FFDA\r
P:^__FF9A\r


# Shift-Keypad (0-9)

A:\e\e\e\e\\.0
P:^_S_FFB0\r
P:^_S_FF63\r
P:^_S_????\r
P:^_S_FF9E\r

A:\e\e\e\e\\.1
P:^_S_FFB1\r
P:^_S_FF57\r
P:^_S_FFDE\r
P:^_S_FF9C\r

A:\e\e\e\e\\.2
P:^_S_FFB2\r
P:^_S_FF54\r
P:^_S_FFDF\r
P:^_S_FF99\r

A:\e\e\e\e\\.3
P:^_S_FFB3\r
P:^_S_FF56\r
P:^_S_FFE0\r
P:^_S_FF9B\r

A:\e\e\e\e\\.4
P:^_S_FFB4\r
P:^_S_FF51\r
P:^_S_FFDB\r
P:^_S_FF96\r

A:\e\e\e\e\\.5
P:^_S_FFB5\r
P:^_S_FF80\r
P:^_S_FFDC\r
P:^_S_????\r

A:\e\e\e\e\\.6
P:^_S_FFB6\r
P:^_S_FF53\r
P:^_S_FFDD\r
P:^_S_FF98\r

A:\e\e\e\e\\.7
P:^_S_FFB7\r
P:^_S_FF50\r
P:^_S_FFD8\r
P:^_S_FF95\r

A:\e\e\e\e\\.8
P:^_S_FFB8\r
P:^_S_FF52\r
P:^_S_FFD9\r
P:^_S_FF97\r

A:\e\e\e\e\\.9
P:^_S_FFB9\r
P:^_S_FF55\r
P:^_S_FFDA\r
P:^_S_FF9A\r


# Control-Keypad (0-9)

A:\e\e\e\e\\+0
P:^_N_FFB0\r
P:^_N_FF63\r
P:^_N_????\r
P:^_N_FF9E\r

A:\e\e\e\e\\+1
P:^_N_FFB1\r
P:^_N_FF57\r
P:^_N_FFDE\r
P:^_N_FF9C\r

A:\e\e\e\e\\+2
P:^_N_FFB2\r
P:^_N_FF54\r
P:^_N_FFDF\r
P:^_N_FF99\r

A:\e\e\e\e\\+3
P:^_N_FFB3\r
P:^_N_FF56\r
P:^_N_FFE0\r
P:^_N_FF9B\r

A:\e\e\e\e\\+4
P:^_N_FFB4\r
P:^_N_FF51\r
P:^_N_FFDB\r
P:^_N_FF96\r

A:\e\e\e\e\\+5
P:^_N_FFB5\r
P:^_N_FF80\r
P:^_N_FFDC\r
P:^_N_????\r

A:\e\e\e\e\\+6
P:^_N_FFB6\r
P:^_N_FF53\r
P:^_N_FFDD\r
P:^_N_FF98\r

A:\e\e\e\e\\+7
P:^_N_FFB7\r
P:^_N_FF50\r
P:^_N_FFD8\r
P:^_N_FF95\r

A:\e\e\e\e\\+8
P:^_N_FFB8\r
P:^_N_FF52\r
P:^_N_FFD9\r
P:^_N_FF97\r

A:\e\e\e\e\\+9
P:^_N_FFB9\r
P:^_N_FF55\r
P:^_N_FFDA\r
P:^_N_FF9A\r




tome-235-src/lib/pref/pref-sdl.prf0000644000076400017500000000336311012107762014621 0ustar  dgdg# File: pref-sdl.prf

# This file implements macros for extended keyboard commands (characters not
# within the 128 character ASCII set).
# Basically, if you have to hold down control or alt or it's an arrow key,
# it will be handled here. This means that we can let SDL worry about figuring
# out what key is which; all it needs to do is give us the name and we'll map
# it here.
#
# Note the use of "\e\e\e\e" (four escapes) to allow the macros to work
# even if the game is not yet ready for a command.
#
# Note the use of "\\." (for "run") and "\\+" (for "alter"), to make sure
# that the macros will work regardless of the "keymap" being used.
#

# Basic Arrow Movement

A:8
P:\[up]

A:6
P:\[right]

A:4
P:\[left]

A:2
P:\[down]

# Basic Arrows with Shift Down

A:\e\e\e\e\\.8
P:\[shift-up]

A:\e\e\e\e\\.6
P:\[shift-right]

A:\e\e\e\e\\.4
P:\[shift-left]

A:\e\e\e\e\\.2
P:\[shift-down]

# Basic Arrows with Control Down

A:\e\e\e\e\\+8
P:\[ctrl-up]

A:\e\e\e\e\\+6
P:\[ctrl-right]

A:\e\e\e\e\\+4
P:\[ctrl-left]

A:\e\e\e\e\\+2
P:\[ctrl-down]

# Keypad

A:1
P:\[[1]]

A:2
P:\[[2]]

A:3
P:\[[3]]

A:4
P:\[[4]]

A:5
P:\[[5]]

A:6
P:\[[6]]

A:7
P:\[[7]]

A:8
P:\[[8]]

A:9
P:\[[9]]

# Keypad With Shift

A:\e\e\e\e\\.1
P:\[shift-[1]]

A:\e\e\e\e\\.2
P:\[shift-[2]]

A:\e\e\e\e\\.3
P:\[shift-[3]]

A:\e\e\e\e\\.4
P:\[shift-[4]]

A:\e\e\e\e\\.5
P:\[shift-[5]]

A:\e\e\e\e\\.6
P:\[shift-[6]]

A:\e\e\e\e\\.7
P:\[shift-[7]]

A:\e\e\e\e\\.8
P:\[shift-[8]]

A:\e\e\e\e\\.9
P:\[shift-[9]]

# Keypad With Control

A:\e\e\e\e\\+1
P:\[ctrl-[1]]

A:\e\e\e\e\\+2
P:\[ctrl-[2]]

A:\e\e\e\e\\+3
P:\[ctrl-[3]]

A:\e\e\e\e\\+4
P:\[ctrl-[4]]

A:\e\e\e\e\\+5
P:\[ctrl-[5]]

A:\e\e\e\e\\+6
P:\[ctrl-[6]]

A:\e\e\e\e\\+7
P:\[ctrl-[7]]

A:\e\e\e\e\\+8
P:\[ctrl-[8]]

A:\e\e\e\e\\+9
P:\[ctrl-[9]]
tome-235-src/lib/pref/graf-ami.prf0000644000076400017500000000217411012107762014567 0ustar  dgdg# File: graf-ami.prf

#
# This file contains color definitions and
# graphics remapping for the Amiga version.
#
# Lars Haugseth 
#


# Color palette - Graphics
V:0:0x01:0x00:0x00:0x00
V:1:0x01:0xF0:0xE0:0xD0
V:2:0x01:0x80:0x80:0x80
V:3:0x01:0x50:0x50:0x50
V:4:0x01:0xE0:0xB0:0x00
V:5:0x01:0xC0:0xA0:0x70
V:6:0x01:0x80:0x60:0x40
V:7:0x01:0x40:0x30:0x20
V:8:0x01:0x00:0xA0:0xF0
V:9:0x01:0x00:0x00:0xF0
V:10:0x01:0x00:0x00:0x70
V:11:0x01:0xF0:0x00:0x00
V:12:0x01:0x80:0x00:0x00
V:13:0x01:0x90:0x00:0xB0
V:14:0x01:0x00:0x60:0x10
V:15:0x01:0x60:0xF0:0x40


# Color palette - Text
V:16:0x01:0x00:0x00:0x00
V:17:0x01:0xFF:0xFF:0xFF
V:18:0x01:0xC7:0xC7:0xC7
V:19:0x01:0xFF:0x92:0x00
V:20:0x01:0xFF:0x00:0x00
V:21:0x01:0x00:0xCD:0x00
V:22:0x01:0x00:0x00:0xFE
V:23:0x01:0xC8:0x64:0x00
V:24:0x01:0x8A:0x8A:0x8A
V:25:0x01:0xE0:0xE0:0xE0
V:26:0x01:0xA5:0x00:0xFF
V:27:0x01:0xFF:0xFD:0x00
V:28:0x01:0xFF:0x00:0xBC
V:29:0x01:0x00:0xFF:0x00
V:30:0x01:0x00:0xC8:0xFF
V:31:0x01:0xFF:0xCC:0x80


# Standard file
%:graf-xxx.prf


### Feature attr/char definitions

# nothing
F:0:0x01/0x20

# open floor
F:1:0x81/0x8E

# invis trap
F:2:0x81/0x8E


tome-235-src/lib/pref/graf-ibm.prf0000644000076400017500000021425411012107762014574 0ustar  dgdg# File: graf-ibm.prf

# This file defines special attr/char mappings for use in the pseudo
# graphics mode using character generator font redefinitions. It can
# also be used with X11/XAW/GTK ports by generating a bdf (then pcf)
# file from lib/xtra/angband.fnt. How to do so is beyond the scope of
# this file.
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


##### Special attr/char values #####

## # Unused
## S:0x00:0x00/0x40
## S:0x01:0x01/0x40
## S:0x02:0x02/0x40
## S:0x03:0x03/0x40
## S:0x04:0x04/0x40
## S:0x05:0x05/0x40
## S:0x06:0x06/0x40
## S:0x07:0x07/0x40
## S:0x08:0x08/0x40
## S:0x09:0x09/0x40
## S:0x0A:0x0A/0x40
## S:0x0B:0x0B/0x40
## S:0x0C:0x0C/0x40
## S:0x0D:0x0D/0x40
## S:0x0E:0x0E/0x40
## S:0x0F:0x0F/0x40

## # Unused
## S:0x10:0x00/0x40
## S:0x11:0x01/0x40
## S:0x12:0x02/0x40
## S:0x13:0x03/0x40
## S:0x14:0x04/0x40
## S:0x15:0x05/0x40
## S:0x16:0x06/0x40
## S:0x17:0x07/0x40
## S:0x18:0x08/0x40
## S:0x19:0x09/0x40
## S:0x1A:0x0A/0x40
## S:0x1B:0x0B/0x40
## S:0x1C:0x0C/0x40
## S:0x1D:0x0D/0x40
## S:0x1E:0x0E/0x40
## S:0x1F:0x0F/0x40

## # Unused
## S:0x20:0x00/0x40
## S:0x21:0x01/0x40
## S:0x22:0x02/0x40
## S:0x23:0x03/0x40
## S:0x24:0x04/0x40
## S:0x25:0x05/0x40
## S:0x26:0x06/0x40
## S:0x27:0x07/0x40
## S:0x28:0x08/0x40
## S:0x29:0x09/0x40
## S:0x2A:0x0A/0x40
## S:0x2B:0x0B/0x40
## S:0x2C:0x0C/0x40
## S:0x2D:0x0D/0x40
## S:0x2E:0x0E/0x40
## S:0x2F:0x0F/0x40

# Spells (*)
S:0x30:0x00/0x2A
S:0x31:0x01/0x2A
S:0x32:0x02/0x2A
S:0x33:0x03/0x2A
S:0x34:0x04/0x2A
S:0x35:0x05/0x2A
S:0x36:0x06/0x2A
S:0x37:0x07/0x2A
S:0x38:0x08/0x2A
S:0x39:0x09/0x2A
S:0x3A:0x0A/0x2A
S:0x3B:0x0B/0x2A
S:0x3C:0x0C/0x2A
S:0x3D:0x0D/0x2A
S:0x3E:0x0E/0x2A
S:0x3F:0x0F/0x2A

# Spells (|)
S:0x40:0x00/0x7C
S:0x41:0x01/0x7C
S:0x42:0x02/0x7C
S:0x43:0x03/0x7C
S:0x44:0x04/0x7C
S:0x45:0x05/0x7C
S:0x46:0x06/0x7C
S:0x47:0x07/0x7C
S:0x48:0x08/0x7C
S:0x49:0x09/0x7C
S:0x4A:0x0A/0x7C
S:0x4B:0x0B/0x7C
S:0x4C:0x0C/0x7C
S:0x4D:0x0D/0x7C
S:0x4E:0x0E/0x7C
S:0x4F:0x0F/0x7C

# Spells (-)
S:0x50:0x00/0x2D
S:0x51:0x01/0x2D
S:0x52:0x02/0x2D
S:0x53:0x03/0x2D
S:0x54:0x04/0x2D
S:0x55:0x05/0x2D
S:0x56:0x06/0x2D
S:0x57:0x07/0x2D
S:0x58:0x08/0x2D
S:0x59:0x09/0x2D
S:0x5A:0x0A/0x2D
S:0x5B:0x0B/0x2D
S:0x5C:0x0C/0x2D
S:0x5D:0x0D/0x2D
S:0x5E:0x0E/0x2D
S:0x5F:0x0F/0x2D

# Spells (/)
S:0x60:0x00/0x2F
S:0x61:0x01/0x2F
S:0x62:0x02/0x2F
S:0x63:0x03/0x2F
S:0x64:0x04/0x2F
S:0x65:0x05/0x2F
S:0x66:0x06/0x2F
S:0x67:0x07/0x2F
S:0x68:0x08/0x2F
S:0x69:0x09/0x2F
S:0x6A:0x0A/0x2F
S:0x6B:0x0B/0x2F
S:0x6C:0x0C/0x2F
S:0x6D:0x0D/0x2F
S:0x6E:0x0E/0x2F
S:0x6F:0x0F/0x2F

# Spells (\)
S:0x70:0x00/0x5C
S:0x71:0x01/0x5C
S:0x72:0x02/0x5C
S:0x73:0x03/0x5C
S:0x74:0x04/0x5C
S:0x75:0x05/0x5C
S:0x76:0x06/0x5C
S:0x77:0x07/0x5C
S:0x78:0x08/0x5C
S:0x79:0x09/0x5C
S:0x7A:0x0A/0x5C
S:0x7B:0x0B/0x5C
S:0x7C:0x0C/0x5C
S:0x7D:0x0D/0x5C
S:0x7E:0x0E/0x5C
S:0x7F:0x0F/0x5C

# Amulets
S:0x80:0x00/0xE7
S:0x81:0x01/0xE7
S:0x82:0x02/0xE7
S:0x83:0x03/0xE7
S:0x84:0x04/0xE7
S:0x85:0x05/0xE7
S:0x86:0x06/0xE7
S:0x87:0x07/0xE7
S:0x88:0x08/0xE7
S:0x89:0x09/0xE7
S:0x8A:0x0A/0xE7
S:0x8B:0x0B/0xE7
S:0x8C:0x0C/0xE7
S:0x8D:0x0D/0xE7
S:0x8E:0x0E/0xE7
S:0x8F:0x0F/0xE7

# Rings
S:0x90:0x00/0xE8
S:0x91:0x01/0xE8
S:0x92:0x02/0xE8
S:0x93:0x03/0xE8
S:0x94:0x04/0xE8
S:0x95:0x05/0xE8
S:0x96:0x06/0xE8
S:0x97:0x07/0xE8
S:0x98:0x08/0xE8
S:0x99:0x09/0xE8
S:0x9A:0x0A/0xE8
S:0x9B:0x0B/0xE8
S:0x9C:0x0C/0xE8
S:0x9D:0x0D/0xE8
S:0x9E:0x0E/0xE8
S:0x9F:0x0F/0xE8

# Staffs
S:0xA0:0x00/0xE9
S:0xA1:0x01/0xE9
S:0xA2:0x02/0xE9
S:0xA3:0x03/0xE9
S:0xA4:0x04/0xE9
S:0xA5:0x05/0xE9
S:0xA6:0x06/0xE9
S:0xA7:0x07/0xE9
S:0xA8:0x08/0xE9
S:0xA9:0x09/0xE9
S:0xAA:0x0A/0xE9
S:0xAB:0x0B/0xE9
S:0xAC:0x0C/0xE9
S:0xAD:0x0D/0xE9
S:0xAE:0x0E/0xE9
S:0xAF:0x0F/0xE9

# Wands
S:0xB0:0x00/0xEA
S:0xB1:0x01/0xEA
S:0xB2:0x02/0xEA
S:0xB3:0x03/0xEA
S:0xB4:0x04/0xEA
S:0xB5:0x05/0xEA
S:0xB6:0x06/0xEA
S:0xB7:0x07/0xEA
S:0xB8:0x08/0xEA
S:0xB9:0x09/0xEA
S:0xBA:0x0A/0xEA
S:0xBB:0x0B/0xEA
S:0xBC:0x0C/0xEA
S:0xBD:0x0D/0xEA
S:0xBE:0x0E/0xEA
S:0xBF:0x0F/0xEA

# Rods
S:0xC0:0x00/0xEB
S:0xC1:0x01/0xEB
S:0xC2:0x02/0xEB
S:0xC3:0x03/0xEB
S:0xC4:0x04/0xEB
S:0xC5:0x05/0xEB
S:0xC6:0x06/0xEB
S:0xC7:0x07/0xEB
S:0xC8:0x08/0xEB
S:0xC9:0x09/0xEB
S:0xCA:0x0A/0xEB
S:0xCB:0x0B/0xEB
S:0xCC:0x0C/0xEB
S:0xCD:0x0D/0xEB
S:0xCE:0x0E/0xEB
S:0xCF:0x0F/0xEB

# Scrolls
S:0xD0:0x00/0xEC
S:0xD1:0x01/0xEC
S:0xD2:0x02/0xEC
S:0xD3:0x03/0xEC
S:0xD4:0x04/0xEC
S:0xD5:0x05/0xEC
S:0xD6:0x06/0xEC
S:0xD7:0x07/0xEC
S:0xD8:0x08/0xEC
S:0xD9:0x09/0xEC
S:0xDA:0x0A/0xEC
S:0xDB:0x0B/0xEC
S:0xDC:0x0C/0xEC
S:0xDD:0x0D/0xEC
S:0xDE:0x0E/0xEC
S:0xDF:0x0F/0xEC

# Potions
S:0xE0:0x00/0xED
S:0xE1:0x01/0xED
S:0xE2:0x02/0xED
S:0xE3:0x03/0xED
S:0xE4:0x04/0xED
S:0xE5:0x05/0xED
S:0xE6:0x06/0xED
S:0xE7:0x07/0xED
S:0xE8:0x08/0xED
S:0xE9:0x09/0xED
S:0xEA:0x0A/0xED
S:0xEB:0x0B/0xED
S:0xEC:0x0C/0xED
S:0xED:0x0D/0xED
S:0xEE:0x0E/0xED
S:0xEF:0x0F/0xED

# Food
S:0xF0:0x00/0xEE
S:0xF1:0x01/0xEE
S:0xF2:0x02/0xEE
S:0xF3:0x03/0xEE
S:0xF4:0x04/0xEE
S:0xF5:0x05/0xEE
S:0xF6:0x06/0xEE
S:0xF7:0x07/0xEE
S:0xF8:0x08/0xEE
S:0xF9:0x09/0xEE
S:0xFA:0x0A/0xEE
S:0xFB:0x0B/0xEE
S:0xFC:0x0C/0xEE
S:0xFD:0x0D/0xEE
S:0xFE:0x0E/0xEE
S:0xFF:0x0F/0xEE


##### Feature attr/char definitions #####

# nothing
# F:0:0x01/0x20

# open floor
F:1:0x01/0xB5

# fountain
F:2:0x0E/0xC8

# glyph of warding
F:3:0x0B/0xC6

# open door
F:4:0x0F/0xB9

# broken door
F:5:0x0F/0xBA

# up staircase
F:6:0x01/0xB6

# down staircase
F:7:0x01/0xB7

# quest entrance
F:8:0x0B/0xB7

# quest exit
F:9:0x0B/0xB6

# quest down level
F:10:0x04/0xB7

# quest up level
F:11:0x04/0xB6

# town exit
F:12:0x05/0xB7

# shaft down
F:13:0x0F/0xB7

# shaft up
F:14:0x0F/0xB6

# fountain
F:15:0x08/0xC8

# web
F:16:0x0B/0xCA

# trap
F:17:0x01/0xC7

# door
F:32:0x0F/0xB8

# locked door
F:33:0x0F/0xB8

# locked door
F:34:0x0F/0xB8

# locked door
F:35:0x0F/0xB8

# locked door
F:36:0x0F/0xB8

# locked door
F:37:0x0F/0xB8

# locked door
F:38:0x0F/0xB8

# locked door
F:39:0x0F/0xB8

# jammed door
F:40:0x0F/0xB8

# jammed door
F:41:0x0F/0xB8

# jammed door
F:42:0x0F/0xB8

# jammed door
F:43:0x0F/0xB8

# jammed door
F:44:0x0F/0xB8

# jammed door
F:45:0x0F/0xB8

# jammed door
F:46:0x0F/0xB8

# jammed door
F:47:0x0F/0xB8

# secret door
F:48:0x02/0xBC

# pile of rubble
F:49:0x02/0xBB

# magma vein
F:50:0x01/0xBC

# quartz vein
F:51:0x09/0xBC

# magma vein
F:52:0x01/0xBC

# quartz vein
F:53:0x09/0xBC

# magma vein with treasure
F:54:0x03/0xBC

# quartz vein with treasure
F:55:0x03/0xBC

# granite wall
F:56:0x02/0xBC

# granite wall
F:57:0x02/0xBC

# granite wall
F:58:0x02/0xBC

# granite wall
F:59:0x02/0xBC

# permanent wall
F:60:0x02/0xBC

# permanent wall
F:61:0x02/0xBC

# permanent wall
F:62:0x02/0xBC

# permanent wall
F:63:0x02/0xBC

# explosive rune
F:64:0x0C/0xC6

# Straight Road startpoint
F:65:0x01/0xCA

# section of the Straight Road
F:66:0x0E/0xCA

# section of the Straight Road
F:67:0x06/0xCA

# section of the Straight Road
F:68:0x0E/0xCA

# section of the Straight Road
F:69:0x06/0xCA

# section of the Straight Road
F:70:0x09/0xCA

# section of the Straight Road (discharged)
F:71:0x09/0xCA

# Straight Road exit
F:72:0x01/0xCA

# corrupted section of the Straight Road
F:73:0x08/0xCA

# Building
F:74:0x0F/0xC5

# permanent wall
F:75:0x02/0xBC

# permanent wall
F:76:0x02/0xBC

# permanent wall
F:77:0x02/0xBC

# permanent wall
F:78:0x02/0xBC

# stream of shallow water
F:84:0x0E/0xCB

# pool of deep lava
F:85:0x04/0xCB

# stream of shallow lava
F:86:0x0C/0xCB

# dark pit
F:87:0x08/0xD0

# dirt
F:88:0x07/0xB5

# patch of grass
F:89:0x0D/0xC9

# ice
F:90:0x01/0xD0

# sand
F:91:0x0F/0xB5

# dead tree
F:92:0x08/0xCC

# ash
F:93:0x02/0xB5

# mud
F:94:0x07/0xB5

# ice wall
F:95:0x01/0xCF

# tree
F:96:0x05/0xCC

# mountain chain
F:97:0x02/0xCE

# sandwall
F:98:0x0F/0xCF

# sandwall
F:99:0x0F/0xCF

# sandwall with treasure
F:100:0x03/0xCF

# high mountain chain
F:101:0x01/0xCE

# nether mist
F:102:0x0A/0xCA

# Void Jumpgate
F:160:0x0A/0xB9

# Altar of Being
F:161:0x09/0xD1

# Altar of Winds
F:162:0x0E/0xD1

# Altar of Force
F:163:0x0C/0xD1

# Altar of Darkness
F:164:0x08/0xD1

# Altar of Nature
# F:165:0x05/0x30

# floor
F:172:0x01/0xB5

# Underground Tunnel
F:173:0x02/0xB9

# stream of tainted water
F:174:0x0A/0xCB

# monster trap
F:175:0x0A/0xC6

# Void Jumpgate
F:176:0x0A/0xB9

# lava wall
F:177:0x0C/0xBC

# Great Fire
F:178:0x0C/0xCB

# path to the next area
F:179:0x01/0xB7

# path to the previous area
F:180:0x01/0xB6

# field
F:181:0x05/0xB5

# Ekkaia, the Encircling Sea
F:182:0x06/0xCB

# pool of deep water
F:187:0x06/0xCB

# glass wall
F:188:0x0E/0xD0

# illusion wall
F:189:0x02/0xBC

# Grass roof
F:190:0x0F/0xCA

# grass roof top
F:191:0x0F/0xCA

# grass roof chimney
F:192:0x0F/0xCA

# brick roof
F:193:0x04/0xCF

# brick roof top
F:194:0x04/0xCF

# brick roof chimney
F:195:0x04/0xCF

# window
F:196:0x01/0x4F

# small window
F:197:0x01/0x6F

# rain barrel
F:198:0x02/0xBC

# grass with flowers
F:199:0x04/0xC9

# cobblestone road
F:200:0x02/0xB5

# cobblestone with outlet
F:201:0x02/0xB5

# small tree
F:202:0x0D/0xCD

# town
F:203:0x01/0xC5

# Underground Tunnel
F:204:0x02/0xB9

# a blazing fire
F:205:0x0C/0xCB

# pile of rubble
F:206:0x02/0xBB

# rocky ground
F:207:0x02/0xB5

# cloud-like vapour
F:208:0x09/0xCA

# condensing water
F:209:0x0E/0xCB

# dense mist
F:210:0x01/0xCA

# hail-stone wall
F:211:0x09/0xBC


##### Building attr/char definitions #####

# General Store
B:0:0x0F/0xBD

# Armoury
B:1:0x02/0xBE

# Weaponsmith
B:2:0x01/0xBF

# Temple
B:3:0x05/0xC0

# Alchemy shop
B:4:0x06/0xC1

# Magic shop
B:5:0x04/0xC4

# Black Market
B:6:0x08/0xC3

# Home
B:7:0x0B/0xB8

# Book Store
B:8:0x03/0xC2

# Pet Shop
B:9:0x06/0xB8

# Mayor's Office
B:10:0x03/0xB8

# Inn
B:11:0x01/0xB8

# The Soothsayer
B:12:0x0E/0xB8

# Library
B:13:0x0F/0xC2

# Castle
B:14:0x03/0xB8

# Casino
B:15:0x02/0xB8

# Beastmaster Shanty
B:16:0x05/0xB8

# Fighters Hall
B:17:0x02/0xB8

# Tower of Magery
B:18:0x06/0xB8

# Inner Temple
B:19:0x0D/0xC0

# Paladins Guild
B:20:0x05/0xB8

# Rangers Guild
B:21:0x07/0xB8

# Thunderlords' Nest
B:22:0x0F/0xB8

# The Mirror
B:23:0x0F/0xB8

# Seat of Ruling
B:24:0x0F/0xCC

# Wizards Spire
B:25:0x0F/0xB8

# Priests Circle
B:26:0x03/0xB8

# Tower of the King
B:27:0x0F/0xB8

# Library
B:28:0x0F/0xC2

# The White Tree
B:29:0x01/0xCC

# Craftsmaster
B:30:0x02/0xB8

# Earth-Dome (Nature)
B:31:0x0F/0xB8

# Minstrels Haven
B:32:0x0F/0xB8

# Star-Dome
B:33:0x0F/0xB8

# Valarin Temple
B:34:0x0F/0xC0

# Sea-Dome
B:35:0x0F/0xB8

# The Golden Flower
B:36:0x0F/0xB8

# The Fountain
B:37:0x0F/0xC8

# Axe Smith
B:38:0x01/0xBF

# Hafted Smith
B:39:0x01/0xBF

# Polearm Smith
B:40:0x01/0xBF

# Sword Smith
B:41:0x01/0xBF

# Rare Jewelry Shop
B:42:0x0A/0xC4

# Jewelry Shop
B:43:0x0B/0xC4

# Footwear Shop
B:44:0x04/0xBE

# Rare Footwear Shop
B:45:0x04/0xBE

# Library
B:46:0x0B/0xC2

# Forbidden Library
B:47:0x0A/0xC2

# Expensive Black Market
B:48:0x0A/0xC3

# Common Shop
B:49:0x0F/0xBD

# Dragon Hunter
B:50:0x0A/0xBE

# Speed Ring Market
B:51:0x0D/0xC4

# Scribe
B:52:0x0E/0xC1

# Potion Store
B:53:0x0E/0xC1

# Recaller
B:54:0x06/0xB8

# Master Archer
B:55:0x05/0xBF

# Merchants Guild
B:56:0x05/0xB8

# The Mathom-house
B:57:0x05/0xB8

# The Prancing Pony
B:58:0x01/0xB8

# Mining Supply store
B:59:0x02/0xB8


##### Object attr/char definitions #####

# something
# K:0:0x01/0x26

# Blindness
K:1:0x00/0xEE

# Paranoia
K:2:0x00/0xEE

# Confusion
K:3:0x00/0xEE

# Hallucination
K:4:0x00/0xEE

# Cure Poison
K:5:0x00/0xEE

# Cure Blindness
K:6:0x00/0xEE

# Cure Paranoia
K:7:0x00/0xEE

# Cure Confusion
K:8:0x00/0xEE

# Weakness
K:9:0x00/0xEE

# Unhealth
K:10:0x00/0xEE

# Restore Constitution
K:11:0x00/0xEE

# Restoring
K:12:0x00/0xEE

# Stupidity
K:13:0x00/0xEE

# Naivety
K:14:0x00/0xEE

# Poison
K:15:0x00/0xEE

# Sickness
K:16:0x00/0xEE

# Paralysis
K:17:0x00/0xEE

# Restore Strength
K:18:0x00/0xEE

# Disease
K:19:0x00/0xEE

# Cure Serious Wounds
K:20:0x00/0xEE

# & Ration~ of Food
K:21:0x0F/0xF2

# & Hard Biscuit~
K:22:0x0F/0xF2

# & Strip~ of Venison
K:23:0x07/0xF2

# & Slime Mold~
K:24:0x05/0xF2

# & Lembas~
K:25:0x0E/0xF2

# & Pint~ of Fine Ale
K:26:0x0B/0xED

# & Pint~ of Fine Wine
K:27:0x04/0xED

# & Mattock~
K:28:0x08/0xD9

# & Blue Stone~
K:29:0x0E/0xE7

# & Broken Dagger~
K:30:0x08/0xDC

# & Bastard Sword~
K:31:0x09/0xDC

# & Scimitar~
K:32:0x09/0xDC

# & Tulwar~
K:33:0x09/0xDC

# & Broad Sword~
K:34:0x09/0xDC

# & Short Sword~
K:35:0x09/0xDC

# & Blade~ of Chaos
K:36:0x0A/0xDC

# & Two-Handed Sword~
K:37:0x09/0xDC

# & Main Gauche~
K:38:0x09/0xDC

# & Cutlass~
K:39:0x09/0xDC

# & Executioner's Sword~
K:40:0x04/0xDC

# & Katana~
K:41:0x09/0xDC

# & Long Sword~
K:42:0x09/0xDC

# & Dagger~
K:43:0x09/0xDC

# & Rapier~
K:44:0x09/0xDC

# & Sabre~
K:45:0x09/0xDC

# & Small Sword~
K:46:0x09/0xDC

# & Broken Sword~
K:47:0x08/0xDC

# & Ball-and-Chain~
K:48:0x08/0xDA

# & Whip~
K:49:0x08/0xDA

# & Flail~
K:50:0x08/0xDA

# & Two-Handed Flail~
K:51:0x0B/0xDA

# & Morning Star~
K:52:0x08/0xDA

# & Mace~
K:53:0x08/0xDA

# & Quarterstaff~
K:54:0x0F/0xDA

# & War Hammer~
K:55:0x08/0xDA

# & Lead-Filled Mace~
K:56:0x08/0xDA

# & Mace~ of Disruption
K:57:0x0A/0xDA

# & Lucerne Hammer~
K:58:0x0E/0xDA

# & Beaked Axe~
K:59:0x02/0xDB

# & Glaive~
K:60:0x02/0xDB

# & Halberd~
K:61:0x02/0xDB

# & Awl-Pike~
K:62:0x02/0xDB

# & Pike~
K:63:0x02/0xDB

# & Spear~
K:64:0x02/0xDB

# & Trident~
K:65:0x0B/0xDB

# & Lance~
K:66:0x02/0xDB

# & Great Axe~
K:67:0x02/0xDB

# & Battle Axe~
K:68:0x02/0xDB

# & Lochaber Axe~
K:69:0x08/0xDB

# & Broad Axe~
K:70:0x02/0xDB

# & Scythe~
K:71:0x02/0xDB

# & Scythe~ of Slicing
K:72:0x04/0xDB

# & Short Bow~
K:73:0x0F/0xD8

# & Long Bow~
K:74:0x0F/0xD8

# & Light Crossbow~
K:75:0x02/0xD8

# & Heavy Crossbow~
K:76:0x02/0xD8

# & Sling~
K:77:0x07/0xD8

# & Arrow~
K:78:0x0F/0xD7

# & Seeker Arrow~
K:79:0x0D/0xD7

# & Bolt~
K:80:0x02/0xD7

# & Seeker Bolt~
K:81:0x0E/0xD7

# & Rounded Pebble~
K:82:0x02/0xD6

# & Iron Shot~
K:83:0x02/0xD6

# & Shovel~
K:84:0x02/0xD9

# & Gnomish Shovel~
K:85:0x0D/0xD9

# & Dwarven Shovel~
K:86:0x0E/0xD9

# & Pick~
K:87:0x02/0xD9

# & Orcish Pick~
K:88:0x05/0xD9

# & Dwarven Pick~
K:89:0x06/0xD9

# & Elven Cloak~
K:90:0x0D/0xE2

# & Pair~ of Soft Leather Boots
K:91:0x0F/0xDD

# & Pair~ of Hard Leather Boots
K:92:0x0F/0xDD

# & Pair~ of Metal Shod Boots
K:93:0x02/0xDD

# & Hard Leather Cap~
K:94:0x07/0xDF

# & Metal Cap~
K:95:0x02/0xDF

# & Iron Helm~
K:96:0x02/0xDF

# & Steel Helm~
K:97:0x09/0xDF

# & Iron Crown~
K:98:0x02/0xE0

# & Golden Crown~
K:99:0x0B/0xE0

# & Jewel Encrusted Crown~
K:100:0x0A/0xE0

# & Robe~
K:101:0x06/0xE3

# & Filthy Rag~
K:102:0x08/0xE3

# Soft Leather Armour~
K:103:0x0F/0xE3

# Soft Studded Leather~
K:104:0x0F/0xE3

# Hard Leather Armour~
K:105:0x0F/0xE3

# Hard Studded Leather~
K:106:0x0F/0xE3

# Leather Scale Mail~
K:107:0x0F/0xE3

# Metal Scale Mail~
K:108:0x02/0xE4

# Chain Mail~
K:109:0x02/0xE4

# Rusty Chain Mail~
K:110:0x04/0xE4

# Augmented Chain Mail~
K:111:0x02/0xE4

# Bar Chain Mail~
K:112:0x02/0xE4

# Metal Brigandine Armour~
K:113:0x02/0xE4

# Partial Plate Armour~
K:114:0x09/0xE4

# Metal Lamellar Armour~
K:115:0x09/0xE4

# Full Plate Armour~
K:116:0x09/0xE4

# Ribbed Plate Armour~
K:117:0x09/0xE4

# Adamantite Plate Mail~
K:118:0x0D/0xE4

# Mithril Plate Mail~
K:119:0x0E/0xE4

# Mithril Chain Mail~
K:120:0x0E/0xE4

# Double Chain Mail~
K:121:0x02/0xE4

# & Shield~ of Deflection
K:122:0x0E/0xE1

# & Cloak~
K:123:0x05/0xE2

# & Shadow Cloak~
K:124:0x08/0xE2

# & Set~ of Leather Gloves
K:125:0x0F/0xDE

# & Set~ of Gauntlets
K:126:0x0F/0xDE

# & Set~ of Cesti
K:127:0x09/0xDE

# & Small Leather Shield~
K:128:0x0F/0xE1

# & Large Leather Shield~
K:129:0x0F/0xE1

# & Small Metal Shield~
K:130:0x02/0xE1

# & Large Metal Shield~
K:131:0x02/0xE1

# Strength
K:132:0x00/0xE8

# Dexterity
K:133:0x00/0xE8

# Constitution
K:134:0x00/0xE8

# Intelligence
K:135:0x00/0xE8

# Speed
K:136:0x00/0xE8

# Searching
K:137:0x00/0xE8

# Teleportation
K:138:0x00/0xE8

# Slow Digestion
K:139:0x00/0xE8

# Fire Resistance
K:140:0x00/0xE8

# Cold Resistance
K:141:0x00/0xE8

# Levitation
K:142:0x00/0xE8

# Poison Resistance
K:143:0x00/0xE8

# Free Action
K:144:0x00/0xE8

# Weakness
K:145:0x00/0xE8

# Flames
K:146:0x00/0xE8

# Acid
K:147:0x00/0xE8

# Ice
K:148:0x00/0xE8

# Woe
K:149:0x00/0xE8

# Stupidity
K:150:0x00/0xE8

# Damage
K:151:0x00/0xE8

# Accuracy
K:152:0x00/0xE8

# Protection
K:153:0x00/0xE8

# Aggravate Monster
K:154:0x00/0xE8

# See Invisible
K:155:0x00/0xE8

# Sustain Strength
K:156:0x00/0xE8

# Sustain Intelligence
K:157:0x00/0xE8

# Sustain Wisdom
K:158:0x00/0xE8

# Sustain Constitution
K:159:0x00/0xE8

# Sustain Dexterity
K:160:0x00/0xE8

# Sustain Charisma
K:161:0x00/0xE8

# Slaying
K:162:0x00/0xE8

# Brilliance
K:163:0x00/0xE7

# Charisma
K:164:0x00/0xE7

# Searching
K:165:0x00/0xE7

# Teleportation
K:166:0x00/0xE7

# Slow Digestion
K:167:0x00/0xE7

# Acid Resistance
K:168:0x00/0xE7

# Adornment
K:169:0x00/0xE7

# Double Ring Mail~
K:170:0x02/0xE4

# the Magi
K:171:0x00/0xE7

# Doom
K:172:0x00/0xE7

# Enchant Weapon To-Hit
K:173:0x00/0xEC

# Enchant Weapon To-Dam
K:174:0x00/0xEC

# Enchant Armor
K:175:0x00/0xEC

# Identify
K:176:0x00/0xEC

# *Identify*
K:177:0x00/0xEC

# Rumour
K:178:0x00/0xEC

# Chaos
K:179:0x00/0xEC

# Remove Curse
K:180:0x00/0xEC

# Light
K:181:0x00/0xEC

# Fire
K:182:0x00/0xEC

# Ice
K:183:0x00/0xEC

# Summon Monster
K:184:0x00/0xEC

# Phase Door
K:185:0x00/0xEC

# Teleportation
K:186:0x00/0xEC

# Teleport Level
K:187:0x00/0xEC

# Monster Confusion
K:188:0x00/0xEC

# Magic Mapping
K:189:0x00/0xEC

# Rune of Protection
K:190:0x00/0xEC

# *Remove Curse*
K:191:0x00/0xEC

# Treasure Detection
K:192:0x00/0xEC

# Object Detection
K:193:0x00/0xEC

# Trap Detection
K:194:0x00/0xEC

# & Sheaf Arrow~
K:195:0x03/0xD7

# & Mithril Shot~
K:196:0x0E/0xD6

# Door/Stair Location
K:197:0x00/0xEC

# Acquirement
K:198:0x00/0xEC

# *Acquirement*
K:199:0x00/0xEC

# Mass Genocide
K:200:0x00/0xEC

# Detect Invisible
K:201:0x00/0xEC

# Aggravate Monster
K:202:0x00/0xEC

# Trap Creation
K:203:0x00/0xEC

# Trap/Door Destruction
K:204:0x00/0xEC

# Artifact Creation
K:205:0x00/0xEC

# Recharging
K:206:0x00/0xEC

# Genocide
K:207:0x00/0xEC

# Darkness
K:208:0x00/0xEC

# Protection from Evil
K:209:0x00/0xEC

# Satisfy Hunger
K:210:0x00/0xEC

# Dispel Undead
K:211:0x00/0xEC

# *Enchant Weapon*
K:212:0x00/0xEC

# Curse Weapon
K:213:0x00/0xEC

# *Enchant Armor*
K:214:0x00/0xEC

# Curse Armor
K:215:0x00/0xEC

# Summon Undead
K:216:0x00/0xEC

# Blessing
K:217:0x00/0xEC

# Holy Chant
K:218:0x00/0xEC

# Holy Prayer
K:219:0x00/0xEC

# Word of Recall
K:220:0x00/0xEC

# *Destruction*
K:221:0x00/0xEC

# Slime Mold Juice
K:222:0x00/0xED

# Apple Juice
K:223:0x00/0xED

# Water
K:224:0x00/0xED

# Strength
K:225:0x00/0xED

# Weakness
K:226:0x00/0xED

# Restore Strength
K:227:0x00/0xED

# Intelligence
K:228:0x00/0xED

# Stupidity
K:229:0x00/0xED

# Restore Intelligence
K:230:0x00/0xED

# Wisdom
K:231:0x00/0xED

# Naivety
K:232:0x00/0xED

# Restore Wisdom
K:233:0x00/0xED

# Charisma
K:234:0x00/0xED

# Ugliness
K:235:0x00/0xED

# Restore Charisma
K:236:0x00/0xED

# Curing
K:237:0x00/0xED

# Invulnerability
K:238:0x00/0xED

# New Life
K:239:0x00/0xED

# Cure Serious Wounds
K:240:0x00/0xED

# Cure Critical Wounds
K:241:0x00/0xED

# Healing
K:242:0x00/0xED

# Constitution
K:243:0x00/0xED

# Experience
K:244:0x00/0xED

# Sleep
K:245:0x00/0xED

# Blindness
K:246:0x00/0xED

# Booze
K:247:0x00/0xED

# Poison
K:248:0x00/0xED

# Speed
K:249:0x00/0xED

# Slowness
K:250:0x00/0xED

# Dexterity
K:251:0x00/0xED

# Restore Dexterity
K:252:0x00/0xED

# Restore Constitution
K:253:0x00/0xED

# Lose Memories
K:254:0x00/0xED

# Salt Water
K:255:0x00/0xED

# Enlightenment
K:256:0x00/0xED

# Heroism
K:257:0x00/0xED

# Berserk Strength
K:258:0x00/0xED

# Boldness
K:259:0x00/0xED

# Restore Life Levels
K:260:0x00/0xED

# Resist Heat
K:261:0x00/0xED

# Resist Cold
K:262:0x00/0xED

# Detect Invisible
K:263:0x00/0xED

# Slow Poison
K:264:0x00/0xED

# Neutralise Poison
K:265:0x00/0xED

# Restore Mana
K:266:0x00/0xED

# Infra-vision
K:267:0x00/0xED

# Resistance
K:268:0x00/0xED

# Spell
K:269:0x00/0xEA

# Manathrust
K:270:0x00/0xEA

# Fireflash
K:271:0x00/0xEA

# Firewall
K:272:0x00/0xEA

# Tidal Wave
K:273:0x00/0xEA

# Ice Storm
K:274:0x00/0xEA

# Noxious Cloud
K:275:0x00/0xEA

# Poison Blood
K:276:0x00/0xEA

# Thunderstorm
K:277:0x00/0xEA

# Dig
K:278:0x00/0xEA

# Stone Prison
K:279:0x00/0xEA

# Strike
K:280:0x00/0xEA

# Teleport Away
K:281:0x00/0xEA

# Summon Animal
K:282:0x00/0xEA

# Magelock
K:283:0x00/0xEA

# Slow Monster
K:284:0x00/0xEA

# Essence of Speed
K:285:0x00/0xEA

# Banishment
K:286:0x00/0xEA

# Disperse Magic
K:287:0x00/0xEA

# Charm
K:288:0x00/0xEA

# Confuse
K:289:0x00/0xEA

# Demon Blade
K:290:0x00/0xEA

# Heal Monster
K:291:0x00/0xEA

# Haste Monster
K:292:0x00/0xEA

# & Flight Arrow~
K:293:0x0B/0xD7

# Spell
K:300:0x00/0xE9

# Nothing
K:301:0x00/0xE9

# Globe of Light
K:302:0x00/0xE9

# Fiery Shield
K:303:0x00/0xE9

# Remove Curses
K:304:0x00/0xE9

# Wings of Winds
K:305:0x00/0xE9

# Shake
K:306:0x00/0xE9

# Disarm
K:307:0x00/0xE9

# Teleportation
K:308:0x00/0xE9

# Probability Travel
K:309:0x00/0xE9

# Recovery
K:310:0x00/0xE9

# Healing
K:311:0x00/0xE9

# Vision
K:312:0x00/0xE9

# Identify
K:313:0x00/0xE9

# Sense Hidden
K:314:0x00/0xE9

# Reveal Ways
K:315:0x00/0xE9

# Sense Monsters
K:316:0x00/0xE9

# Genocide
K:317:0x00/0xE9

# Summon
K:318:0x00/0xE9

# Wish
K:320:0x00/0xE9

# Mana
K:321:0x00/0xE9

# & Tome~ of Magical Energy
K:330:0x0E/0xEF

# & Tome~ of the Eternal Flame
K:331:0x0C/0xEF

# & Tome~ of the Blowing Wind
K:332:0x06/0xEF

# & Tome~ of the Impenetrable Earth
K:333:0x0F/0xEF

# & Tome~ of the Everrunning Wave
K:334:0x0E/0xEF

# & Tome~ of Translocation
K:335:0x0E/0xEF

# & Tome~ of the Tree
K:336:0x0D/0xEF

# & Tome~ of Knowledge
K:337:0x08/0xEF

# & Small wooden chest~
K:338:0x02/0xD5

# & Large wooden chest~
K:339:0x02/0xD5

# & Small iron chest~
K:340:0x02/0xD5

# & Large iron chest~
K:341:0x02/0xD5

# & Small steel chest~
K:342:0x02/0xD5

# & Large steel chest~
K:343:0x02/0xD5

# & Ruined chest~
K:344:0x02/0xD5

# & Iron Spike~
K:345:0x09/0xD4

# & Wooden Torch~
K:346:0x07/0xF1

# & Brass Lantern~
K:347:0x0F/0xE6

# & Flask~ of oil
K:348:0x0B/0xED

# & Empty Bottle~
K:349:0x01/0xED

# Havoc
K:350:0x00/0xEB

# Door/Stair Location
K:351:0x00/0xEB

# Trap Location
K:352:0x00/0xEB

# Probing
K:353:0x00/0xEB

# Recall
K:354:0x00/0xEB

# Illumination
K:355:0x00/0xEB

# Light
K:356:0x00/0xEB

# Lightning Bolts
K:357:0x00/0xEB

# Frost Bolts
K:358:0x00/0xEB

# Fire Bolts
K:359:0x00/0xEB

# Polymorph
K:360:0x00/0xEB

# Slow Monster
K:361:0x00/0xEB

# Sleep Monster
K:362:0x00/0xEB

# Drain Life
K:363:0x00/0xEB

# Teleport Other
K:364:0x00/0xEB

# Disarming
K:365:0x00/0xEB

# Lightning Balls
K:366:0x00/0xEB

# Cold Balls
K:367:0x00/0xEB

# Fire Balls
K:368:0x00/0xEB

# Acid Balls
K:369:0x00/0xEB

# Acid Bolts
K:370:0x00/0xEB

# Enlightenment
K:371:0x00/0xEB

# Perception
K:372:0x00/0xEB

# Curing
K:373:0x00/0xEB

# Healing
K:374:0x00/0xEB

# Detection
K:375:0x00/0xEB

# Restoration
K:376:0x00/0xEB

# Speed
K:377:0x00/0xEB

# Spell
K:378:0x00/0xE8

# Spell
K:379:0x00/0xE7

# & Broken Skull~
K:391:0x01/0xD3

# & Broken Bone~
K:392:0x01/0xD3

# & Canine Skeleton~
K:393:0x01/0xD3

# & Rodent Skeleton~
K:394:0x01/0xD3

# & Human Skeleton~
K:395:0x01/0xD3

# & Dwarf Skeleton~
K:396:0x01/0xD3

# & Elf Skeleton~
K:397:0x01/0xD3

# & Gnome Skeleton~
K:398:0x01/0xD3

# & Great Hammer~
K:399:0x08/0xDA

# Black Dragon Scale Mail~
K:400:0x02/0xE5

# Blue Dragon Scale Mail~
K:401:0x06/0xE5

# White Dragon Scale Mail~
K:402:0x01/0xE5

# Red Dragon Scale Mail~
K:403:0x04/0xE5

# Green Dragon Scale Mail~
K:404:0x05/0xE5

# Multi-Hued Dragon Scale Mail~
K:405:0x0A/0xE5

# Pseudo Dragon Scale Mail~
K:406:0x0A/0xE5

# Law Dragon Scale Mail~
K:407:0x0E/0xE5

# Bronze Dragon Scale Mail~
K:408:0x0F/0xE5

# Gold Dragon Scale Mail~
K:409:0x0B/0xE5

# Chaos Dragon Scale Mail~
K:410:0x0A/0xE5

# Balance Dragon Scale Mail~
K:411:0x0A/0xE5

# Power Dragon Scale Mail~
K:412:0x0A/0xE5

# & Dragon Helm~
K:413:0x0D/0xDF

# & Dragon Shield~
K:414:0x0D/0xE1

# Death
K:415:0x00/0xED

# Ruination
K:416:0x00/0xED

# Detonations
K:417:0x00/0xED

# Augmentation
K:418:0x00/0xED

# *Healing*
K:419:0x00/0xED

# Life
K:420:0x00/0xED

# Self Knowledge
K:421:0x00/0xED

# *Enlightenment*
K:422:0x00/0xED

# Fear Resistance
K:425:0x00/0xE8

# Light and Darkness Resistance
K:426:0x00/0xE8

# Nether Resistance
K:427:0x00/0xE8

# Nexus Resistance
K:428:0x00/0xE8

# Sound Resistance
K:429:0x00/0xE8

# Confusion Resistance
K:430:0x00/0xE8

# Shard Resistance
K:431:0x00/0xE8

# Disenchantment Resistance
K:432:0x00/0xE8

# Chaos Resistance
K:433:0x00/0xE8

# Blindness Resistance
K:434:0x00/0xE8

# Lordly Protection
K:435:0x00/0xE8

# Extra Attacks
K:436:0x00/0xE8

# Cure Light Wounds
K:437:0x00/0xED

# Clumsiness
K:438:0x00/0xED

# Sickliness
K:439:0x00/0xED

# Map of Bree
K:440:0x02/0xEC

# Map of Gondolin
K:441:0x02/0xEC

# Map of Lothlorien
K:442:0x02/0xEC

# Map of Minas Anor
K:443:0x02/0xEC

# & Silver Arrow~
K:465:0x09/0xD7

# & Silver Bolt~
K:466:0x01/0xD7

# Lightning Resistance
K:467:0x00/0xE7

# Wisdom
K:468:0x00/0xE7

# Regeneration
K:469:0x00/0xE7

# Infravision
K:470:0x00/0xE7

# Devotion
K:471:0x00/0xE7

# Weaponmastery
K:472:0x00/0xE7

# Trickery
K:473:0x00/0xE7

# Telepathy
K:474:0x00/0xE7

# Sustenance
K:475:0x00/0xE7

# & Palantir~
K:476:0x0B/0xF0

# & Elfstone~
K:477:0x05/0xE7

# & Jewel~
K:478:0x01/0xE7

# & Ring~
K:479:0x00/0xE8

# copper
K:480:0x07/0xF3

# copper
K:481:0x07/0xF3

# copper
K:482:0x07/0xF3

# silver
K:483:0x02/0xF3

# silver
K:484:0x02/0xF3

# silver
K:485:0x02/0xF3

# garnets
K:486:0x04/0xF4

# garnets
K:487:0x04/0xF4

# gold
K:488:0x0B/0xF3

# gold
K:489:0x0B/0xF3

# gold
K:490:0x0B/0xF3

# opals
K:491:0x09/0xF4

# sapphires
K:492:0x06/0xF4

# rubies
K:493:0x04/0xF4

# diamonds
K:494:0x01/0xF4

# emeralds
K:495:0x05/0xF4

# mithril
K:496:0x0E/0xF3

# adamantite
K:497:0x0D/0xF3

# & Mighty Hammer~
K:498:0x08/0xDA

# & Massive Iron Crown~
K:499:0x08/0xE0

# & Phial~
K:500:0x0B/0xF0

# & Star~
K:501:0x0E/0xF0

# & Arkenstone~
K:502:0x0C/0xF0

# & Amulet~
K:503:0x00/0xE7

# & Amulet~
K:504:0x00/0xE7

# & Necklace~
K:505:0x00/0xE7

# & Ring~
K:506:0x00/0xE8

# & Ring~
K:507:0x00/0xE8

# & Ring~
K:508:0x00/0xE8

# & Ring~
K:509:0x00/0xE8

# & Ring~
K:510:0x00/0xE8

# & Ring~
K:511:0x0B/0xE8

# Reflection
K:520:0x00/0xE7

# Anti-Magic
K:521:0x00/0xE7

# Anti-Teleportation
K:522:0x00/0xE7

# Resistance
K:523:0x00/0xE7

# & Zweihander~
K:524:0x01/0xDC

# & Dwarven Lantern~
K:525:0x06/0xE6

# Splint Mail~
K:526:0x08/0xE4

# & Everburning Torch~
K:527:0x0C/0xF1

# & Trifurcate Spear~
K:528:0x03/0xDB

# & Three Piece Rod~
K:529:0x07/0xDA

# & Feanorian Lamp~
K:530:0x0E/0xE6

# & Fur Cloak~
K:531:0x09/0xE2

# Water Curing
K:532:0x00/0xED

# & Hatchet~
K:533:0x02/0xDB

# Rhino Hide Armour~
K:535:0x02/0xE3

# Leather Jacket~
K:536:0x0F/0xE3

# & Sickle~
K:537:0x02/0xDB

# & Club~
K:542:0x07/0xDA

# & Broad Spear~
K:543:0x01/0xDB

# & Khopesh~
K:544:0x09/0xDC

# & Flamberge~
K:545:0x09/0xDC

# & Claymore~
K:546:0x09/0xDC

# & Espadon~
K:547:0x09/0xDC

# & Great Scimitar~
K:548:0x09/0xDC

# Arrow
K:549:0x04/0xF8

# Bolt
K:550:0x03/0xF8

# & Fauchard~
K:551:0x02/0xDB

# & Guisarme~
K:552:0x02/0xDB

# & Heavy Lance~
K:553:0x02/0xDB

# & Basillard~
K:554:0x01/0xDC

# Catapult
K:555:0x0C/0xF8

# Ring Mail~
K:556:0x02/0xE4

# Cord Armour~
K:557:0x0B/0xE3

# Paper Armour~
K:558:0x01/0xE3

# Padded Armour~
K:559:0x0B/0xE3

# Fumes
K:560:0x0D/0xF8

# Stone and Hide Armour~
K:561:0x0F/0xE3

# Magic
K:562:0x05/0xF8

# Device
K:563:0x0A/0xF8

# Nothing
K:564:0x00/0xEC

# Poison
K:565:0x0D/0xF6

# Nothing
K:566:0x00/0xEA

# Nothing
K:567:0x00/0xE8

# Nothing
K:568:0x00/0xE9

# Nothing
K:569:0x00/0xEB

# Explosion
K:570:0x0D/0xF6

# Teleport
K:571:0x0D/0xF6

# Nothing
K:572:0x00/0xE7

# & Blood~ of Life
K:573:0x00/0xED

# Cold
K:574:0x0D/0xF6

# Fire
K:575:0x0D/0xF6

# Acid
K:576:0x0D/0xF6

# & Mage Staff~
K:577:0x0E/0xE9

# Lightning
K:578:0x00/0xE8

# Life
K:579:0x0D/0xF6

# Confusion
K:580:0x0D/0xF6

# Light
K:581:0x0D/0xF6

# & Ring~
K:582:0x0B/0xE8

# Invisibility
K:583:0x00/0xED

# Chaos
K:584:0x0D/0xF6

# Corruption
K:585:0x00/0xED

# Invisibility
K:586:0x00/0xE8

# Time
K:587:0x0D/0xF6

# Deep Thoughts
K:588:0x03/0xEC

# More Deep Thoughts
K:589:0x03/0xEC

# Compendium of Deep Thoughts
K:590:0x03/0xEC

# Artifact Lore Vol. I
K:591:0x03/0xEC

# Artifact Lore Vol. II
K:592:0x03/0xEC

# Artifact Lore Vol. III
K:593:0x03/0xEC

# Monstrous Compendium 1
K:594:0x03/0xEC

# Monstrous Compendium 2
K:595:0x03/0xEC

# Monstrous Compendium 3
K:596:0x03/0xEC

# Monstrous Compendium 4
K:597:0x03/0xEC

# Monstrous Compendium 5
K:598:0x03/0xEC

# Monstrous Compendium 6
K:599:0x03/0xEC

# Monstrous Compendium 7
K:600:0x03/0xEC

# Monstrous Compendium 8
K:601:0x03/0xEC

# Monstrous Compendium 9
K:602:0x03/0xEC

# Monstrous Compendium 10
K:603:0x03/0xEC

# Monstrous Compendium 11
K:604:0x03/0xEC

# Abomination
K:605:0x00/0xED

# Shape of Wolf
K:606:0x00/0xED

# Shape of Ape
K:607:0x00/0xED

# Shape of Goat
K:608:0x00/0xED

# Shape of Insect
K:609:0x00/0xED

# Shape of Sparrow
K:610:0x00/0xED

# Shape of Ent
K:611:0x00/0xED

# Shape of Vampire
K:612:0x00/0xED

# Shape of Spider
K:613:0x00/0xED

# Shape of Mana ball
K:614:0x00/0xED

# Shape of Fire cloud
K:615:0x00/0xED

# Shape of Cold cloud
K:616:0x00/0xED

# Shape of Chaos cloud
K:617:0x00/0xED

# [Wolf]
K:618:0x0B/0xE2

# [Ape]
K:619:0x0B/0xE2

# [Goat]
K:620:0x0B/0xE2

# [Insect]
K:621:0x0B/0xE2

# [Sparrow]
K:622:0x0B/0xE2

# [Ent]
K:623:0x0B/0xE2

# [Vampire]
K:624:0x0B/0xE2

# [Spider]
K:625:0x0B/0xE2

# [Mana ball]
K:626:0x0B/0xE2

# [Fire cloud]
K:627:0x0B/0xE2

# [Cold cloud]
K:628:0x0B/0xE2

# [Chaos Cloud]
K:629:0x0B/0xE2

# [Ghost]
K:630:0x0B/0xE2

# [Kobold]
K:631:0x0B/0xE2

# [Dragon]
K:632:0x0B/0xE2

# [Demon]
K:633:0x0B/0xE2

# [Hound]
K:634:0x0B/0xE2

# [Quylthulg]
K:635:0x0B/0xE2

# [Maia]
K:636:0x0B/0xE2

# [Serpent]
K:637:0x0B/0xE2

# [Giant]
K:638:0x0B/0xE2

# [Vala]
K:639:0x0B/0xE2

# Magic
K:640:0x0D/0xF6

# corpse
K:641:0x0F/0xD2

# skeleton
K:642:0x0F/0xD2

# head
K:643:0x0F/0xD2

# skull
K:644:0x0F/0xD2

# raw meat
K:645:0x0F/0xD2

# & Thunderlord Coat~
K:646:0x0B/0xE3

# & Stone~
K:647:0x05/0xF0

# & Small Wooden Boomerang~
K:648:0x0B/0xD8

# & Wooden Boomerang~
K:649:0x0B/0xD8

# & Small Metal Boomerang~
K:650:0x0B/0xD8

# & metal Boomerang~
K:651:0x0B/0xD8

# & Anchor~
K:652:0x0A/0xF0

# & ~
K:653:0x0B/0xD2

# Summon Never-Moving Pet
K:654:0x00/0xEC

# Cure Light Insanity
K:657:0x00/0xED

# Cure Serious Insanity
K:658:0x00/0xED

# Cure Critical Insanity
K:659:0x00/0xED

# Cure Insanity
K:660:0x00/0xED

# & Phial~
K:661:0x0B/0xF0

# Random Artifact
K:662:0x03/0xD3

# Craftmanship
K:663:0x00/0xEC

# The One Ring
K:664:0x02/0xEC

# & Book~ of the Lays of the Heroes
K:665:0x0B/0xEF

# & Book~ of Sound Patterns
K:666:0x0B/0xEF

# & Flute~
K:669:0x09/0xF7

# & Drum~
K:670:0x09/0xF7

# & Harp~
K:671:0x09/0xF7

# & Banjo~
K:672:0x09/0xF7

# & Lute~
K:673:0x09/0xF7

# & Mandolin~
K:674:0x09/0xF7

# & Palantir~
K:675:0x0B/0xF0

# Egg
K:676:0x09/0xD6

# Reset Recall
K:677:0x00/0xEC

# Divination
K:678:0x00/0xEC

# Self
K:679:0x06/0xF5

# Ray
K:680:0x06/0xF5

# Sphere
K:681:0x06/0xF5

# Knowledge
K:682:0x06/0xF5

# Life
K:683:0x08/0xF5

# Fire
K:684:0x04/0xF5

# Cold
K:685:0x06/0xF5

# Lightning
K:686:0x09/0xF5

# Acid
K:687:0x0E/0xF5

# Element
K:688:0x05/0xF5

# Chaos
K:689:0x0A/0xF5

# Mind
K:690:0x08/0xF5

# Holding
K:691:0x0E/0xF5

# Arrow
K:692:0x06/0xF5

# Power Surge
K:693:0x06/0xF5

# Armageddon
K:694:0x06/0xF5

# Gravity
K:695:0x0D/0xF5

# Extra Life
K:696:0x0D/0xF6

# Undeath
K:697:0x0D/0xF5

# Protection
K:698:0x0D/0xF5

# & Horn~
K:699:0x09/0xF7

# & Ring~ of Precognition
K:700:0x00/0xE8

# & Sprig~ of Athelas
K:701:0x05/0xF2

# & Old Scroll~ of Deincarnation
K:720:0x00/0xEC

# & Dark Sword~
K:721:0x08/0xDC

# Numenorean for Beginners (I)
K:722:0x02/0xEC

# Numenorean for Beginners (II)
K:723:0x02/0xEC

# Advanced lessons of Numenorean
K:724:0x02/0xEC

# Advanced lessons of Sindarin
K:725:0x02/0xEC

# & Shard~ of Pottery
K:726:0x04/0xD3

# & Broken Stick~
K:727:0x04/0xD3

# & Book~ of Beginner Cantrips
K:738:0x01/0xEF

# & Book~ of Teleportation
K:739:0x01/0xEF

# & Book~ of Recall
K:740:0x01/0xEF

# & Book~ of Summoning
K:741:0x01/0xEF

# & Book~ of Fireflash
K:742:0x01/0xEF

# & Potion~ of Learning
K:743:0x00/0xED

# Spell
K:749:0x00/0xEC

# Khuzdul - The Hidden Tongue of the Dwarves
K:751:0x02/0xEC

# Nandorin for Dummies
K:752:0x02/0xEC

# Advanced Lessons of Orcish
K:753:0x02/0xEC

# Flying
K:755:0x00/0xE8

# & Tome~ of the Time
K:756:0x06/0xEF

# & Spellbook~ of #
K:757:0x01/0xEF

# & Tome~ of Meta Spells
K:758:0x0A/0xEF

# & Tome~ of the Mind
K:759:0x0E/0xEF

# & Holy Tome~ of Eru Iluvatar
K:760:0x0D/0xEF

# & Holy Tome~ of Manwe Sulimo
K:761:0x0E/0xEF

# & War Tome~ of Tulkas
K:762:0x0C/0xEF

# & Unholy Tome~ of the Hellflame
K:763:0x0A/0xEF

# & Corrupted Tome~ of Melkor
K:764:0x08/0xEF

# & Forest Tome~ of Yavanna
K:768:0x0D/0xEF

# & Ring~
K:770:0x00/0xE8

# [Earth]
K:771:0x0C/0xEF

# [Fire]
K:772:0x0C/0xEF

# [Air]
K:773:0x04/0xEF

# [Water]
K:774:0x04/0xEF

# [Mana]
K:775:0x04/0xEF

# Home Summoning
K:776:0x00/0xEB

# & Shadow Blade~
K:777:0x08/0xDC

# & Bluesteel Blade~
K:778:0x06/0xDC

# the Serpents
K:779:0x0D/0xE7

# Darkness
K:780:0x0D/0xF6

# Knowledge
K:781:0x0D/0xF6

# Force
K:782:0x0D/0xF6

# Lightning
K:783:0x0D/0xF6

# Mana
K:784:0x0D/0xF6

# Ring~ of Power
K:785:0x00/0xE8

# Climbing Set~
K:786:0x0E/0xF8

# Adventurer's Guide to Middle-earth
K:787:0x03/0xEC

# & Demonblade~
K:788:0x0C/0xEF

# & Demonshield~
K:789:0x0C/0xEF

# & Demonhorn~
K:790:0x0C/0xEF

# & Wooden Rod~ of#
K:793:0x07/0xEB

# & Copper Rod~ of#
K:794:0x02/0xEB

# & Iron Rod~ of#
K:795:0x08/0xEB

# & Moonstone Rod~ of#
K:796:0x0F/0xEB

# & Silver Rod~ of#
K:797:0x02/0xEB

# & Golden Rod~ of#
K:798:0x0B/0xEB

# & Mithril Rod~ of#
K:799:0x0E/0xEB

# & Adamantite Rod~ of#
K:800:0x0A/0xEB

# & Greater Ration~ of Health
K:801:0x05/0xF2

# & Crumpled Scroll~ of Mass Resurrection
K:802:0x00/0xEC

# & Cleaver~
K:803:0x02/0xDB

# & Light War Axe~
K:804:0x02/0xDB

# & Slaughter Axe~
K:805:0x0D/0xDB

# & Runestone~
K:806:0x0A/0xF5

# & Fortune cookie~
K:807:0x0F/0xF2

# Portable hole
K:808:0x0E/0xF8

# Critical Hits
K:809:0x00/0xE8

# & Wand~ of Digging of Thrain
K:810:0x00/0xEA

# & Gnarled Staff~ of Holy Fire of Mithrandir
K:811:0x00/0xE9

# Partial Totem
K:812:0x0A/0xF8

# True Totem
K:813:0x0A/0xF8

# & Piece~ of the Relic of Eru
K:814:0x0A/0xD3

# & Piece~ of the Relic of Manwe
K:815:0x0A/0xD3

# & Piece~ of the Relic of Tulkas
K:816:0x0A/0xD3

# & Piece~ of the Relic of Melkor
K:817:0x0A/0xD3

# & Piece~ of the Relic of Yavanna
K:818:0x0A/0xD3


##### Monster attr/char definitions #####

# Player
R:0:0x01/0x80

# Filthy street urchin
R:1:0x08/0xAE

# Scrawny cat
R:2:0x0F/0xA0

# Sparrow
R:3:0x0F/0x82

# Chaffinch
R:4:0x04/0x82

# Wild rabbit
R:5:0x0F/0xAC

# Woodsman
R:6:0x05/0xAE

# Scruffy little dog
R:7:0x0F/0x83

# Farmer Maggot
R:8:0x01/0xA2

# Blubbering idiot
R:9:0x09/0xAE

# Boil-covered wretch
R:10:0x05/0xAE

# Village idiot
R:11:0x0D/0xAE

# Pitiful-looking beggar
R:12:0x0F/0xAE

# Mangy-looking leper
R:13:0x07/0xAE

# Agent of the black market
R:14:0x06/0xAE

# Singing, happy drunk
R:15:0x0B/0xAE

# Aimless-looking merchant
R:16:0x03/0xAE

# Mean-looking mercenary
R:17:0x04/0xAE

# Battle-scarred veteran
R:18:0x0E/0xAE

# Martti Ihrasaari
R:19:0x01/0x90

# Grey mold
R:20:0x02/0xA7

# Large white snake
R:21:0x01/0x8A

# Grey mushroom patch
R:22:0x02/0xEE

# Newt
R:23:0x0B/0x92

# Giant white centipede
R:24:0x01/0x9D

# White icky thing
R:25:0x01/0xA3

# Clear icky thing
R:26:0x0E/0xA3

# Giant white mouse
R:27:0x01/0xAC

# Large brown snake
R:28:0x07/0x8A

# Small kobold
R:29:0x0B/0xA5

# Kobold
R:30:0x0D/0xA5

# White worm mass
R:31:0x01/0xB1

# Floating eye
R:32:0x03/0x9F

# Rock lizard
R:33:0x0F/0x92

# Grid bug
R:34:0x0A/0x89

# Jackal
R:35:0x0F/0x83

# Soldier ant
R:36:0x07/0x9B

# Fruit bat
R:37:0x03/0x9C

# Insect swarm
R:38:0x07/0x89

# The Greater hell-beast
R:39:0x02/0x95

# Shrieker mushroom patch
R:40:0x0C/0xEE

# Blubbering icky thing
R:41:0x09/0xA3

# Metallic green centipede
R:42:0x05/0x9D

# Novice warrior
R:43:0x07/0xAA

# Novice rogue
R:44:0x06/0xAA

# Novice priest
R:45:0x05/0xAA

# Novice mage
R:46:0x04/0xAA

# Yellow mushroom patch
R:47:0x0B/0xEE

# White jelly
R:48:0x01/0xA4

# Giant black ant
R:49:0x08/0x9B

# Salamander
R:50:0x03/0x92

# White harpy
R:51:0x01/0x88

# Blue yeek
R:52:0x06/0xB3

# Grip, Farmer Maggot's dog
R:53:0x01/0x83

# Wolf, Farmer Maggot's dog
R:54:0x01/0x83

# Fang, Farmer Maggot's dog
R:55:0x01/0x83

# Giant green frog
R:56:0x05/0x92

# Freesia
R:57:0x07/0xA0

# Green worm mass
R:58:0x05/0xB1

# Large yellow snake
R:59:0x0B/0x8A

# Cave spider
R:60:0x08/0x93

# Crow
R:61:0x02/0x82

# Wild cat
R:62:0x0F/0xA0

# Smeagol
R:63:0x0E/0xA2

# Green ooze
R:64:0x05/0xA4

# Poltergeist
R:65:0x02/0x87

# Yellow jelly
R:66:0x0B/0xA4

# Metallic blue centipede
R:67:0x06/0x9D

# Raven
R:68:0x08/0x82

# Giant white louse
R:69:0x01/0x89

# Giant yellow centipede
R:70:0x0B/0x9D

# Black naga
R:71:0x08/0xA8

# Spotted mushroom patch
R:72:0x03/0xEE

# Silver jelly
R:73:0x09/0xA4

# Scruffy-looking hobbit
R:74:0x02/0xA2

# Giant white ant
R:75:0x01/0x9B

# Yellow mold
R:76:0x0B/0xA7

# Metallic red centipede
R:77:0x04/0x9D

# Yellow worm mass
R:78:0x0B/0xB1

# Clear worm mass
R:79:0x0E/0xB1

# Radiation eye
R:80:0x0C/0x9F

# Yellow light
R:81:0x0B/0xF0

# Cave lizard
R:82:0x07/0x92

# Novice ranger
R:83:0x09/0xAA

# Blue jelly
R:84:0x06/0xA4

# Creeping copper coins
R:85:0x07/0xF3

# Giant white rat
R:86:0x09/0xAC

# Snotling
R:87:0x0F/0xA9

# Swordfish
R:88:0x09/0x7E

# Blue worm mass
R:89:0x06/0xB1

# Large grey snake
R:90:0x02/0x8A

# Skeleton kobold
R:91:0x09/0xAD

# Ewok
R:92:0x0D/0xA2

# Novice mage
R:93:0x04/0xAA

# Green naga
R:94:0x05/0xA8

# Giant leech
R:95:0x07/0xB1

# Barracuda
R:96:0x0D/0x7E

# Novice paladin
R:97:0x01/0xAA

# Zog
R:98:0x06/0xA2

# Blue ooze
R:99:0x06/0xA4

# Green glutton ghost
R:100:0x05/0x87

# Green jelly
R:101:0x05/0xA4

# Large kobold
R:102:0x06/0xA5

# Grey icky thing
R:103:0x02/0xA3

# Disenchanter eye
R:104:0x0A/0x9F

# Red worm mass
R:105:0x04/0xB1

# Copperhead snake
R:106:0x03/0x8A

# Death sword
R:107:0x09/0xDC

# Purple mushroom patch
R:108:0x0A/0xEE

# Novice priest
R:109:0x05/0xAA

# Novice warrior
R:110:0x07/0xAA

# Nibelung
R:111:0x08/0xA2

# The disembodied hand that strangled people
R:112:0x05/0xB4

# Brown mold
R:113:0x07/0xA7

# Giant brown bat
R:114:0x07/0x9C

# Rat-thing
R:115:0x0C/0xAC

# Novice rogue
R:116:0x06/0xAA

# Creeping silver coins
R:117:0x02/0xF3

# Snaga
R:118:0x0F/0xA9

# Rattlesnake
R:119:0x04/0x8A

# Giant slug
R:120:0x0F/0xB1

# Giant pink frog
R:121:0x04/0x92

# Dark elf
R:122:0x08/0xA2

# Zombified kobold
R:123:0x02/0xB4

# Crypt creep
R:124:0x08/0xAD

# Rotting corpse
R:125:0x0C/0xB4

# Cave orc
R:126:0x0D/0xA9

# Wood spider
R:127:0x0F/0x93

# Manes
R:128:0x04/0xAF

# Bloodshot eye
R:129:0x04/0x9F

# Red naga
R:130:0x04/0xA8

# Red jelly
R:131:0x04/0xA4

# Green icky thing
R:132:0x05/0xA3

# Lost soul
R:133:0x09/0x87

# Night lizard
R:134:0x06/0x92

# Mughash, the Kobold Lord
R:135:0x0A/0xA5

# Skeleton orc
R:136:0x09/0xAD

# Wormtongue, Agent of Saruman
R:137:0x0E/0xAA

# Robin Hood, the Outlaw
R:138:0x0D/0xAA

# Nurgling
R:139:0x03/0xAF

# Lagduf, the Snaga
R:140:0x0B/0xA9

# Brown yeek
R:141:0x07/0xB3

# Novice ranger
R:142:0x09/0xAA

# Giant salamander
R:143:0x0C/0x92

# Space monster
R:144:0x00/0xB5

# Carnivorous flying monkey
R:145:0x0C/0x88

# Green mold
R:146:0x05/0xA7

# Novice paladin
R:147:0x01/0xAA

# Lemure
R:148:0x0F/0xAF

# Hill orc
R:149:0x07/0xA9

# Bandit
R:150:0x06/0xAA

# Hunting hawk
R:151:0x07/0x82

# Phantom warrior
R:152:0x0E/0x87

# Gremlin
R:153:0x07/0xAF

# Yeti
R:154:0x01/0x99

# Bloodshot icky thing
R:155:0x04/0xA3

# Giant grey rat
R:156:0x02/0xAC

# Black harpy
R:157:0x08/0x88

# Skaven
R:158:0x0D/0xAC

# The wounded bear
R:159:0x04/0xAB

# Cave bear
R:160:0x07/0xAB

# Rock mole
R:161:0x02/0xAC

# Mindcrafter
R:162:0x0B/0xAA

# Baby blue dragon
R:163:0x06/0x9E

# Baby white dragon
R:164:0x01/0x9E

# Baby green dragon
R:165:0x05/0x9E

# Baby black dragon
R:166:0x02/0x9E

# Baby red dragon
R:167:0x04/0x9E

# Giant red ant
R:168:0x04/0x9B

# Brodda, the Easterling
R:169:0x0F/0xAA

# Bloodfang, the Wolf
R:170:0x0C/0x83

# King cobra
R:171:0x05/0x8A

# Eagle
R:172:0x07/0x82

# War bear
R:173:0x07/0xAB

# Killer bee
R:174:0x0B/0x89

# Giant spider
R:175:0x0A/0x93

# Giant white tick
R:176:0x01/0x93

# The Borshin
R:177:0x01/0xA1

# Dark elven mage
R:178:0x04/0xA2

# Kamikaze yeek
R:179:0x04/0xB3

# Orfax, Son of Boldor
R:180:0x0E/0xB3

# Servant of Glaaki
R:181:0x0D/0xB4

# Dark elven warrior
R:182:0x07/0xA2

# Sand-dweller
R:183:0x0B/0xAF

# Clear mushroom patch
R:184:0x0E/0xEE

# Quiver slot
R:185:0x0F/0xEE

# Grishnakh, the Hill Orc
R:186:0x0B/0xA9

# Giant tan bat
R:187:0x0F/0x9C

# Owlbear
R:188:0x03/0x88

# Blue horror
R:189:0x0E/0xAF

# Hairy mold
R:190:0x03/0xA7

# Grizzly bear
R:191:0x0F/0xAB

# Disenchanter mold
R:192:0x0A/0xA7

# Pseudo dragon
R:193:0x03/0x9E

# Tengu
R:194:0x06/0xAF

# Creeping gold coins
R:195:0x0B/0xF3

# Wolf
R:196:0x07/0x83

# Giant fruit fly
R:197:0x0D/0x89

# Panther
R:198:0x08/0xA0

# Brigand
R:199:0x06/0xAA

# Hobbes the Tiger
R:200:0x0B/0xA0

# Shadow Creature of Fiona
R:201:0x02/0xA2

# Undead mass
R:202:0x07/0xA4

# Chaos shapechanger
R:203:0x0A/0x88

# Baby multi-hued dragon
R:204:0x0A/0x9E

# Vorpal bunny
R:205:0x01/0xAC

# Old Man Willow
R:206:0x02/0xCC

# Hippocampus
R:207:0x0E/0x88

# Zombified orc
R:208:0x02/0xB4

# Hippogriff
R:209:0x0F/0x88

# Black mamba
R:210:0x08/0x8A

# White wolf
R:211:0x01/0x83

# Grape jelly
R:212:0x0A/0xA4

# Nether worm mass
R:213:0x08/0xB1

# Abyss worm mass
R:214:0x08/0xB1

# Golfimbul, the Hill Orc Chief
R:215:0x0B/0xA9

# Swordsman
R:216:0x07/0xAA

# Skaven shaman
R:217:0x05/0xAC

# Baby bronze dragon
R:218:0x0F/0x9E

# Baby gold dragon
R:219:0x0B/0x9E

# Evil eye
R:220:0x08/0x9F

# Mine-dog
R:221:0x07/0x83

# Hellcat
R:222:0x0C/0xA0

# Moon beast
R:223:0x09/0xAB

# Master yeek
R:224:0x05/0xB3

# Priest
R:225:0x05/0xAA

# Dark elven priest
R:226:0x05/0xA2

# Air spirit
R:227:0x0E/0x85

# Skeleton human
R:228:0x09/0xAD

# Zombified human
R:229:0x02/0xB4

# Tiger
R:230:0x03/0xA0

# Moaning spirit
R:231:0x07/0x87

# Stegocentipede
R:232:0x07/0x9D

# Spotted jelly
R:233:0x03/0xA4

# Drider
R:234:0x06/0x93

# Mongbat
R:235:0x0F/0x9C

# Killer brown beetle
R:236:0x07/0x8B

# Boldor, King of the Yeeks
R:237:0x0A/0xB3

# Ogre
R:238:0x0F/0x8F

# Creeping mithril coins
R:239:0x0E/0xF3

# Illusionist
R:240:0x0C/0xAA

# Druid
R:241:0x0D/0xAA

# Pink horror
R:242:0x0C/0xAF

# Cloaker
R:243:0x05/0xE2

# Black orc
R:244:0x08/0xA9

# Ochre jelly
R:245:0x0F/0xA4

# Software bug
R:246:0x04/0x89

# Lurker
R:247:0x01/0xB5

# Tangleweed
R:248:0x05/0xCC

# Vlasta
R:249:0x0E/0x92

# Giant white dragon fly
R:250:0x01/0x86

# Snaga sapper
R:251:0x0F/0xA9

# Blue icky thing
R:252:0x06/0xA3

# Gibbering mouther
R:253:0x03/0xA4

# Wolfhound of Flora
R:254:0x02/0x83

# Hill giant
R:255:0x0F/0x90

# Flesh golem
R:256:0x0C/0xA1

# Warg
R:257:0x08/0x83

# Cheerful leprechaun
R:258:0x0D/0xA2

# Giant flea
R:259:0x02/0x89

# Ufthak of Cirith Ungol
R:260:0x05/0xA9

# Clay golem
R:261:0x0F/0xA1

# Black ogre
R:262:0x08/0x8F

# Dweller on the threshold
R:263:0x02/0x99

# Half-orc
R:264:0x02/0xA9

# Dark naga
R:265:0x02/0xA8

# Poison ivy
R:266:0x05/0xCC

# Magic mushroom patch
R:267:0x0E/0xEE

# Plaguebearer of Nurgle
R:268:0x03/0xB4

# Guardian naga
R:269:0x0B/0xA8

# Wererat
R:270:0x08/0xAC

# Light hound
R:271:0x03/0x9A

# Dark hound
R:272:0x08/0x9A

# Flying skull
R:273:0x02/0xAD

# Mi-Go
R:274:0x0C/0x89

# Giant tarantula
R:275:0x03/0x93

# Giant clear centipede
R:276:0x0E/0x9D

# Mirkwood spider
R:277:0x0D/0x93

# Frost giant
R:278:0x01/0x90

# Griffon
R:279:0x07/0x88

# Homunculus
R:280:0x0B/0xAF

# Gnome mage
R:281:0x0C/0xA2

# Clear hound
R:282:0x0E/0x9A

# Umber hulk
R:283:0x0F/0x98

# Rust monster
R:284:0x03/0xAB

# Ogrillon
R:285:0x09/0x8F

# Gelatinous cube
R:286:0x0D/0xA4

# Giant green dragon fly
R:287:0x0D/0x86

# Fire giant
R:288:0x04/0x90

# Hummerhorn
R:289:0x0B/0x89

# Lizard man
R:290:0x0D/0xA2

# Ulfast, Son of Ulfang
R:291:0x0F/0xAA

# Crebain
R:292:0x08/0x82

# Berserker
R:293:0x07/0xAA

# Quasit
R:294:0x03/0xAF

# Sphinx
R:295:0x03/0x88

# Imp
R:296:0x05/0xAF

# Forest troll
R:297:0x05/0x94

# Freezing sphere
R:298:0x01/0xF0

# Jumping fireball
R:299:0x04/0xF0

# Ball lightning
R:300:0x0E/0xF0

# 2-headed hydra
R:301:0x07/0x8D

# Swamp thing
R:302:0x05/0x88

# Water spirit
R:303:0x06/0x85

# Giant red scorpion
R:304:0x04/0x93

# Earth spirit
R:305:0x07/0x85

# Fire spirit
R:306:0x04/0x85

# Fire hound
R:307:0x04/0x9A

# Cold hound
R:308:0x01/0x9A

# Energy hound
R:309:0x06/0x9A

# Lesser Mimic
R:310:0x0B/0xA7

# Door mimic
R:311:0x0F/0xB8

# Blink dog
R:312:0x0E/0x83

# Uruk
R:313:0x0E/0xA9

# Shagrat, the Orc Captain
R:314:0x05/0xA9

# Gorbag, the Orc Captain
R:315:0x05/0xA9

# Shambling mound
R:316:0x05/0xEE

# Giant Venus Flytrap
R:317:0x05/0xCC

# Chaos beastman
R:318:0x07/0x88

# Daemonette of Slaanesh
R:319:0x0C/0xAF

# Giant bronze dragon fly
R:320:0x0F/0x86

# Stone giant
R:321:0x09/0x90

# Giant black dragon fly
R:322:0x02/0x86

# Stone golem
R:323:0x09/0xA1

# Red mold
R:324:0x04/0xA7

# Giant gold dragon fly
R:325:0x0B/0x86

# Stunwall
R:326:0x09/0xBC

# Ghast
R:327:0x07/0xB4

# Neekerbreeker
R:328:0x08/0x89

# Huorn
R:329:0x05/0xCC

# Bolg, Son of Azog
R:330:0x0A/0xA9

# Phase spider
R:331:0x0E/0x93

# Lizard king
R:332:0x05/0xA2

# Landmine
R:333:0x01/0xB5

# Wyvern
R:334:0x05/0x9E

# Great eagle
R:335:0x07/0x82

# Livingstone
R:336:0x09/0xBC

# Earth hound
R:337:0x07/0x9A

# Air hound
R:338:0x05/0x9A

# Sabre-tooth tiger
R:339:0x0B/0xA0

# Acid hound
R:340:0x02/0x9A

# Chimaera
R:341:0x04/0x88

# Quylthulg
R:342:0x0B/0x91

# Sasquatch
R:343:0x09/0x99

# Weir
R:344:0x09/0x83

# Ranger
R:345:0x09/0xAA

# Paladin
R:346:0x01/0xAA

# Werewolf
R:347:0x08/0x83

# Dark elven lord
R:348:0x02/0xA2

# Cloud giant
R:349:0x06/0x90

# Ugluk, the Uruk
R:350:0x0A/0xA9

# Blue dragon bat
R:351:0x06/0x9C

# Mimic
R:352:0x0B/0xA7

# Ultimate Mimic
R:353:0x0B/0xA7

# Fire vortex
R:354:0x04/0xB0

# Acid vortex
R:355:0x02/0xB0

# Lugdush, the Uruk
R:356:0x0A/0xA9

# Arch-vile
R:357:0x09/0xAF

# Cold vortex
R:358:0x01/0xB0

# Energy vortex
R:359:0x06/0xB0

# Globefish
R:360:0x01/0x7E

# Giant firefly
R:361:0x04/0x89

# Mummified orc
R:362:0x01/0xB4

# Wolf chieftain
R:363:0x08/0x83

# Serpent man
R:364:0x0D/0x8A

# Vampiric mist
R:365:0x08/0xCA

# Killer stag beetle
R:366:0x05/0x8B

# Iron golem
R:367:0x02/0xA1

# Auto-roller
R:368:0x02/0xA1

# Giant yellow scorpion
R:369:0x0B/0x93

# Jade monk
R:370:0x0D/0xAA

# Black ooze
R:371:0x08/0xA4

# Hardened warrior
R:372:0x07/0xAA

# Azog, King of the Uruk-Hai
R:373:0x0A/0xA9

# Fleshhound of Khorne
R:374:0x0C/0x83

# Dark elven warlock
R:375:0x0A/0xA2

# Master rogue
R:376:0x06/0xAA

# Red dragon bat
R:377:0x04/0x9C

# Killer white beetle
R:378:0x01/0x8B

# Ice skeleton
R:379:0x01/0xAD

# Angamaite of Umbar
R:380:0x0F/0xAA

# Forest wight
R:381:0x05/0x97

# Khim, Son of Mim
R:382:0x03/0xA2

# Ibun, Son of Mim
R:383:0x03/0xA2

# Meneldor the Swift
R:384:0x07/0x82

# Phantom beast
R:385:0x0E/0x87

# Giant silver ant
R:386:0x09/0x9B

# 4-headed hydra
R:387:0x0B/0x8D

# Lesser hell-beast
R:388:0x02/0x95

# Tyrannosaur
R:389:0x05/0x92

# Mummified human
R:390:0x01/0xB4

# Vampire bat
R:391:0x08/0x9C

# Sangahyando of Umbar
R:392:0x0F/0xAA

# It
R:393:0x09/0xB5

# Banshee
R:394:0x06/0x87

# Carrion crawler
R:395:0x03/0x9D

# Xiclotlan
R:396:0x08/0xCC

# Silent watcher
R:397:0x02/0xA1

# Pukelman
R:398:0x08/0xA1

# Disenchanter beast
R:399:0x0A/0xAB

# Dark elven druid
R:400:0x0D/0xA2

# Stone troll
R:401:0x09/0x94

# Black
R:402:0x00/0xA4

# Hill troll
R:403:0x02/0x94

# Wereworm
R:404:0x07/0xB1

# Killer red beetle
R:405:0x04/0x8B

# Disenchanter bat
R:406:0x0A/0x9C

# Gnoph-Keh
R:407:0x02/0xAB

# Giant grey ant
R:408:0x02/0x9B

# Khufu, the Mummified King
R:409:0x0A/0xB4

# Gwaihir the Windlord
R:410:0x07/0x82

# Giant fire tick
R:411:0x0C/0x93

# Displacer beast
R:412:0x06/0xA0

# Ulwarth, Son of Ulfang
R:413:0x0F/0xAA

# Werebear
R:414:0x08/0xAB

# Cave ogre
R:415:0x07/0x8F

# White wraith
R:416:0x01/0x97

# Angel
R:417:0x03/0x81

# Ghoul
R:418:0x0F/0xB4

# Mim, Betrayer of Turin
R:419:0x03/0xA2

# Hellblade
R:420:0x0A/0xDC

# Killer fire beetle
R:421:0x0C/0x8B

# Beast of Nurgle
R:422:0x0B/0xAB

# Creeping adamantite coins
R:423:0x0D/0xF3

# Algroth
R:424:0x03/0x94

# Flamer of Tzeentch
R:425:0x04/0xEE

# Roper
R:426:0x08/0xBC

# Headless
R:427:0x07/0x88

# Vibration hound
R:428:0x0B/0x9A

# Nexus hound
R:429:0x0A/0x9A

# Half-ogre
R:430:0x03/0x8F

# Lokkak, the Ogre Chieftain
R:431:0x0A/0x8F

# Vampire
R:432:0x09/0x96

# Gorgimaera
R:433:0x03/0x88

# Shantak
R:434:0x08/0x88

# Colbran
R:435:0x0B/0xA1

# Spirit naga
R:436:0x01/0xA8

# Corpser
R:437:0x08/0xEE

# Fiend of Slaanesh
R:438:0x0C/0x93

# Stairway to Hell
R:439:0x09/0xB7

# 5-headed hydra
R:440:0x05/0x8D

# Barney the Dinosaur
R:441:0x0A/0x92

# Black knight
R:442:0x02/0xAA

# Seahorse
R:443:0x03/0x7E

# Cyclops
R:444:0x07/0x90

# Clairvoyant
R:445:0x0B/0xAA

# Purple worm
R:446:0x0A/0xB1

# Catoblepas
R:447:0x05/0xAB

# Lesser wall monster
R:448:0x09/0xBC

# Mage
R:449:0x04/0xAA

# Mind flayer
R:450:0x0A/0xA2

# The Ultimate Dungeon Cleaner
R:451:0x08/0xA1

# Deep one
R:452:0x05/0xAF

# Basilisk
R:453:0x02/0x92

# Ice troll
R:454:0x01/0x94

# Dhole
R:455:0x02/0xB1

# Archangel
R:456:0x0E/0x81

# Greater Mimic
R:457:0x0B/0xA7

# Chaos tile
R:458:0x0A/0xB5

# Young blue dragon
R:459:0x06/0x9E

# Young white dragon
R:460:0x01/0x9E

# Young green dragon
R:461:0x05/0x9E

# Young bronze dragon
R:462:0x0F/0x9E

# Aklash
R:463:0x0C/0x94

# Mithril golem
R:464:0x0E/0xA1

# Skeleton troll
R:465:0x09/0xAD

# Skeletal tyrannosaur 
R:466:0x01/0x92

# Beorn, the Shape-Changer
R:467:0x08/0xAB

# Thorondor, Lord of Eagles
R:468:0x07/0x82

# Giant blue ant
R:469:0x06/0x9B

# Grave wight
R:470:0x06/0x97

# Shadow drake
R:471:0x0D/0x9E

# Manticore
R:472:0x0B/0x88

# Giant army ant
R:473:0x03/0x9B

# Killer slicer beetle
R:474:0x0B/0x8B

# Gorgon
R:475:0x06/0x88

# Gug
R:476:0x0D/0x90

# Ghost
R:477:0x01/0x87

# Death watch beetle
R:478:0x08/0x8B

# Mountain ogre
R:479:0x02/0x8F

# Nexus quylthulg
R:480:0x0A/0x91

# Shelob, Spider of Darkness
R:481:0x08/0x93

# Giant squid
R:482:0x05/0x7E

# Ghoulking
R:483:0x08/0xB4

# Doombat
R:484:0x0C/0x9C

# Ninja
R:485:0x07/0xAA

# Memory moss
R:486:0x06/0xEE

# Storm giant
R:487:0x0E/0x90

# Spectator
R:488:0x0E/0x9F

# Bokrug
R:489:0x0A/0x92

# Biclops
R:490:0x07/0x90

# Half-troll
R:491:0x0F/0x94

# Ivory monk
R:492:0x01/0xAA

# Bert the Stone Troll
R:493:0x09/0x94

# Bill the Stone Troll
R:494:0x09/0x94

# Tom the Stone Troll
R:495:0x09/0x94

# Cave troll
R:496:0x07/0x94

# Anti-paladin
R:497:0x08/0xAA

# Chaos master
R:498:0x0A/0xAA

# Barrow wight
R:499:0x0A/0x97

# Skeleton ettin
R:500:0x09/0xAD

# Chaos drake
R:501:0x0A/0x9E

# Law drake
R:502:0x0E/0x9E

# Balance drake
R:503:0x0A/0x9E

# Ethereal drake
R:504:0x03/0x9E

# Groo, the Wanderer
R:505:0x0F/0xAA

# Fasolt the Giant
R:506:0x07/0x90

# Shade
R:507:0x08/0x87

# Spectre
R:508:0x0F/0x87

# Water troll
R:509:0x0E/0x94

# Fire elemental
R:510:0x04/0x85

# Cherub
R:511:0x0D/0x81

# Water elemental
R:512:0x06/0x85

# Multi-hued hound
R:513:0x0A/0x9A

# Invisible stalker
R:514:0x0B/0x85

# Carrion crawler
R:515:0x03/0x9D

# Master thief
R:516:0x06/0xAA

# The Watcher in the Water
R:517:0x0A/0x7E

# Lich
R:518:0x03/0x8C

# Gas spore
R:519:0x05/0x9F

# Master vampire
R:520:0x05/0x96

# Oriental vampire
R:521:0x02/0x96

# Greater mummy
R:522:0x0B/0xB4

# Bloodletter of Khorne
R:523:0x04/0x95

# Giant grey scorpion
R:524:0x02/0x93

# Earth elemental
R:525:0x07/0x85

# Air elemental
R:526:0x0E/0x85

# Shimmering mold
R:527:0x06/0xA7

# Gargoyle
R:528:0x02/0xAF

# Malicious leprechaun
R:529:0x0A/0xA2

# Eog golem
R:530:0x07/0xA1

# Little Boy
R:531:0x08/0xD6

# Dagashi
R:532:0x07/0xAA

# Headless ghost
R:533:0x07/0x87

# Dread
R:534:0x03/0x87

# Leng spider
R:535:0x0A/0x93

# Gauth
R:536:0x02/0x9F

# Smoke elemental
R:537:0x0C/0x85

# Olog
R:538:0x0B/0x94

# Halfling slinger
R:539:0x0F/0xA2

# Gravity hound
R:540:0x09/0x9A

# Acidic cytoplasm
R:541:0x02/0xA4

# Inertia hound
R:542:0x09/0x9A

# Impact hound
R:543:0x07/0x9A

# Shardstorm
R:544:0x07/0xB0

# Ooze elemental
R:545:0x05/0x85

# Young black dragon
R:546:0x02/0x9E

# Mumak
R:547:0x02/0xAB

# Giant fire ant
R:548:0x0C/0x9B

# Mature white dragon
R:549:0x01/0x9E

# Xorn
R:550:0x07/0x98

# Rogrog the Black Troll
R:551:0x08/0x94

# Mist giant
R:552:0x0E/0xCA

# Phantom
R:553:0x0A/0x87

# Grey wraith
R:554:0x02/0x97

# Revenant
R:555:0x07/0x97

# Young multi-hued dragon
R:556:0x0A/0x9E

# Raal's Tome of Destruction
R:557:0x04/0xEF

# Colossus
R:558:0x0D/0xA1

# Young gold dragon
R:559:0x0B/0x9E

# Mature blue dragon
R:560:0x06/0x9E

# Mature green dragon
R:561:0x05/0x9E

# Mature bronze dragon
R:562:0x0F/0x9E

# Young red dragon
R:563:0x04/0x9E

# Nightblade
R:564:0x08/0xA2

# Trapper
R:565:0x01/0xB5

# Bodak
R:566:0x04/0xAF

# Time bomb
R:567:0x01/0xB5

# Mezzodaemon
R:568:0x03/0xAF

# Elder thing
R:569:0x0D/0xAF

# Ice elemental
R:570:0x01/0x85

# Necromancer
R:571:0x0C/0xAA

# The Greater hell magic mushroom were-quylthulg
R:572:0x02/0x91

# Lorgan, Chief of the Easterlings
R:573:0x0A/0xAA

# Chaos spawn
R:574:0x02/0x9F

# Mummified troll
R:575:0x01/0xB4

# Storm of Unmagic
R:576:0x0A/0xB0

# Crypt thing
R:577:0x0D/0x8C

# Chaos butterfly
R:578:0x0D/0x89

# Time elemental
R:579:0x0D/0x85

# Flying polyp
R:580:0x0C/0x7E

# The Queen Ant
R:581:0x0A/0x9B

# Will o' the wisp
R:582:0x09/0x85

# Shan
R:583:0x0E/0x89

# Magma elemental
R:584:0x03/0x85

# Black pudding
R:585:0x08/0xA4

# Killer iridescent beetle
R:586:0x0A/0x8B

# Nexus vortex
R:587:0x0A/0xB0

# Plasma vortex
R:588:0x0C/0xB0

# Mature red dragon
R:589:0x04/0x9E

# Mature gold dragon
R:590:0x0B/0x9E

# Crystal drake
R:591:0x07/0x9E

# Mature black dragon
R:592:0x02/0x9E

# Mature multi-hued dragon
R:593:0x0A/0x9E

# Sky whale
R:594:0x0D/0x7E

# Draebor, the Imp
R:595:0x0A/0xAF

# Mother Hydra
R:596:0x0A/0xAF

# Death knight
R:597:0x08/0xAA

# Castamir the Usurper
R:598:0x0C/0xAA

# Time vortex
R:599:0x0E/0xB0

# Shimmering vortex
R:600:0x03/0xB0

# Ancient blue dragon
R:601:0x06/0x84

# Ancient bronze dragon
R:602:0x0F/0x84

# Beholder
R:603:0x0F/0x9F

# Emperor wight
R:604:0x04/0x97

# Seraph
R:605:0x04/0x81

# Vargo, Tyrant of Fire
R:606:0x04/0x85

# Black wraith
R:607:0x08/0x97

# Nightgaunt
R:608:0x08/0x95

# Baron of hell
R:609:0x0F/0x95

# Scylla
R:610:0x0E/0x8D

# Monastic lich
R:611:0x07/0x8C

# Nether wraith
R:612:0x0D/0x97

# Hellhound
R:613:0x04/0x83

# 7-headed hydra
R:614:0x0D/0x8D

# Waldern, King of Water
R:615:0x06/0x85

# Kavlax the Many-Headed
R:616:0x0A/0x9E

# Ancient white dragon
R:617:0x01/0x84

# Ancient green dragon
R:618:0x05/0x84

# Chthonian
R:619:0x08/0xB1

# Eldrak
R:620:0x04/0x94

# Ettin
R:621:0x06/0x94

# Night mare
R:622:0x0D/0xAB

# Vampire lord
R:623:0x06/0x96

# Ancient black dragon
R:624:0x02/0x84

# Weird fume
R:625:0x0A/0xCA

# Spawn of Ubbo-Sathla
R:626:0x0A/0xA4

# Fat Man
R:627:0x08/0xD6

# Malekith the Accursed
R:628:0x0A/0xA2

# Shadowfax, steed of Gandalf
R:629:0x0A/0xAB

# Spirit troll
R:630:0x0D/0x87

# War troll
R:631:0x06/0x94

# Disenchanter worm mass
R:632:0x0A/0xB1

# Rotting quylthulg
R:633:0x07/0x91

# Lesser titan
R:634:0x0B/0x90

# 9-headed hydra
R:635:0x04/0x8D

# Enchantress
R:636:0x0C/0xAA

# Ranger chieftain
R:637:0x09/0xAA

# Sorcerer
R:638:0x0C/0xAA

# Xaren
R:639:0x02/0x98

# Giant roc
R:640:0x07/0x82

# Minotaur
R:641:0x0F/0x88

# Medusa, the Gorgon
R:642:0x0A/0xA8

# Death drake
R:643:0x0D/0x84

# Ancient red dragon
R:644:0x04/0x84

# Ancient gold dragon
R:645:0x0B/0x84

# Great crystal drake
R:646:0x0F/0x84

# Wyrd sister
R:647:0x0A/0xAA

# Vrock
R:648:0x02/0x95

# Death quasit
R:649:0x08/0xAF

# Giganto, the Gargantuan
R:650:0x02/0x7E

# Strygalldwir
R:651:0x09/0x95

# Fallen angel
R:652:0x02/0x81

# Giant headless
R:653:0x07/0x88

# Judge Fire
R:654:0x0C/0xAD

# Ubbo-Sathla, the Unbegotten Source
R:655:0x09/0xA4

# Judge Mortis
R:656:0x0D/0xB4

# Dark elven sorcerer
R:657:0x0C/0xA2

# Master lich
R:658:0x04/0x8C

# Byakhee
R:659:0x08/0x95

# Eol, the Dark Elf
R:660:0x08/0xA2

# Archon
R:661:0x0B/0x81

# Formless spawn of Tsathoggua
R:662:0x08/0x95

# Hunting horror
R:663:0x08/0x95

# Undead beholder
R:664:0x07/0x9F

# Shadow
R:665:0x08/0x87

# Iron lich
R:666:0x02/0x8C

# Dread
R:667:0x03/0x87

# Greater basilisk
R:668:0x08/0x92

# Charybdis
R:669:0x04/0x7E

# Jack of Shadows
R:670:0x02/0xAA

# Zephyr Lord
R:671:0x0A/0x97

# Juggernaut of Khorne
R:672:0x08/0xA1

# Mumak
R:673:0x02/0xAB

# Judge Fear
R:674:0x08/0x97

# Ancient multi-hued dragon
R:675:0x0A/0x84

# Ethereal dragon
R:676:0x03/0x84

# Dark young of Shub-Niggurath
R:677:0x05/0x95

# Colour out of space
R:678:0x0A/0xB5

# Quaker, Master of Earth
R:679:0x07/0x85

# Death leprechaun
R:680:0x08/0xA2

# Chaugnar Faugn, Horror from the Hills
R:681:0x08/0xAB

# Lloigor
R:682:0x0E/0xB0

# Utgard-Loke
R:683:0x0A/0x90

# Quachil Uttaus, Treader of the Dust
R:684:0x08/0xB4

# Shoggoth
R:685:0x08/0xA4

# Judge Death
R:686:0x08/0x97

# Ariel, Queen of Air
R:687:0x0E/0x85

# 11-headed hydra
R:688:0x0C/0x8D

# Patriarch
R:689:0x0D/0xAA

# Dreadmaster
R:690:0x0B/0x87

# Drolem
R:691:0x05/0xA1

# Scatha the Worm
R:692:0x09/0x84

# Warrior of the Dawn
R:693:0x0C/0xAA

# Lesser black reaver
R:694:0x08/0x8C

# Zoth-Ommog
R:695:0x0A/0x92

# Grand master thief
R:696:0x06/0xAA

# Smaug the Golden
R:697:0x0C/0x84

# The Stormbringer
R:698:0x08/0xDC

# Knight Templar
R:699:0x01/0xAA

# Leprechaun fanatic
R:700:0x04/0xA2

# Dracolich
R:701:0x0D/0x84

# Greater titan
R:702:0x03/0x90

# Dracolisk
R:703:0x0C/0x84

# Winged Horror
R:704:0x08/0x82

# Spectral tyrannosaur
R:705:0x0D/0x92

# Yibb-Tstll, the Patient One
R:706:0x08/0x90

# Ghatanothoa
R:707:0x08/0xB0

# Ent
R:708:0x0D/0xCC

# Hru
R:709:0x02/0x90

# Itangast the Fire Drake
R:710:0x0C/0x84

# Death mold
R:711:0x08/0xA7

# Fafner the Dragon
R:712:0x0D/0x84

# Charon, Boatman of the Styx
R:713:0x0E/0x97

# Quickbeam, the Ent
R:714:0x0D/0xCC

# Glaurung, Father of the Dragons
R:715:0x0C/0x84

# Behemoth
R:716:0x0E/0x88

# Garm, Guardian of Hel
R:717:0x06/0x83

# Greater wall monster
R:718:0x09/0xBC

# Nycadaemon
R:719:0x03/0x95

# Barbazu
R:720:0x0D/0x95

# Goat of Mendes
R:721:0x08/0xAB

# Nightwing
R:722:0x08/0x97

# Maulotaur
R:723:0x02/0x88

# Nether hound
R:724:0x0D/0x9A

# Time hound
R:725:0x0E/0x9A

# Plasma hound
R:726:0x0C/0x9A

# Demonic quylthulg
R:727:0x04/0x91

# Great Storm Wyrm
R:728:0x06/0x84

# Ulik the Troll
R:729:0x0A/0x94

# Baphomet the Minotaur Lord
R:730:0x0A/0x88

# Hell knight
R:731:0x08/0xAA

# Bull Gates
R:732:0x08/0xAA

# Santa Claus
R:733:0x04/0xA2

# Eihort, the Thing in the Labyrinth
R:734:0x0C/0xA4

# The King in Yellow
R:735:0x0B/0x8C

# Great unclean one
R:736:0x05/0x95

# Lord of Chaos
R:737:0x0A/0xAA

# Old Sorcerer
R:738:0x0C/0xAA

# Ethereal hound
R:739:0x0D/0x9A

# Lesser kraken
R:740:0x0D/0x7E

# Great Ice Wyrm
R:741:0x01/0x84

# Demilich
R:742:0x0F/0x8C

# The Phoenix
R:743:0x04/0x82

# Nightcrawler
R:744:0x08/0x97

# Lord of Change
R:745:0x0A/0x95

# Keeper of Secrets
R:746:0x0D/0x88

# Shudde M'ell
R:747:0x02/0xB1

# Hand druj
R:748:0x0B/0xAD

# Eye druj
R:749:0x04/0xAD

# Skull druj
R:750:0x03/0xAD

# Chaos vortex
R:751:0x0A/0xB0

# Aether vortex
R:752:0x0A/0xB0

# Nidhogg, the Hel-Drake
R:753:0x08/0x84

# The Lernaean Hydra
R:754:0x0A/0x8D

# Thuringwethil, the Vampire Messenger
R:755:0x0A/0x96

# Great Hell Wyrm
R:756:0x04/0x84

# Hastur the Unspeakable
R:757:0x06/0x88

# Bloodthirster
R:758:0x04/0x95

# Draconic quylthulg
R:759:0x05/0x91

# Nyogtha, the Thing that Should not Be
R:760:0x08/0xA4

# Ahtu, Avatar of Nyarlathotep
R:761:0x08/0xBC

# Fundin Bluecloak
R:762:0x0E/0xA2

# Bile Demon
R:763:0x0C/0x95

# Uriel, Angel of Fire
R:764:0x0C/0x81

# Azriel, Angel of Death
R:765:0x08/0x81

# Ancalagon the Black
R:766:0x08/0x84

# Daoloth, the Render of the Veils
R:767:0x02/0x95

# Nightwalker
R:768:0x08/0x97

# Gabriel, the Messenger
R:769:0x01/0x81

# Artsi, the Champion of Chaos
R:770:0x0A/0xA2

# Saruman of Many Colours
R:771:0x0A/0xAA

# Harowen the Black Hand
R:772:0x0E/0xAA

# Osyluth
R:773:0x09/0x95

# Dreadlord
R:774:0x04/0x87

# Greater kraken
R:775:0x0D/0x7E

# Archlich
R:776:0x0E/0x8C

# The Cat Lord
R:777:0x0A/0xA0

# Jabberwock
R:778:0x0A/0x88

# Chaos hound
R:779:0x0A/0x9A

# Vlad Dracula, Prince of Darkness
R:780:0x08/0x96

# Beholder hive-mother
R:781:0x0B/0x9F

# Leviathan
R:782:0x0A/0x7E

# Great Wyrm of Chaos
R:783:0x0A/0x84

# Great Wyrm of Law
R:784:0x0E/0x84

# Great Wyrm of Balance
R:785:0x0A/0x84

# Shambler
R:786:0x09/0x85

# Gelugon
R:787:0x01/0x95

# Glaaki
R:788:0x0A/0x7E

# Trone, the Rebel Thunderlord
R:789:0x08/0x82

# Great Wyrm of Many Colours
R:790:0x0A/0x84

# Marda, rider of gold Laronth
R:791:0x0B/0x82

# Tselakus, the Dreadlord
R:792:0x0C/0x87

# Sky Drake
R:793:0x0E/0x84

# Eilinel the Entrapped
R:794:0x08/0xAA

# Horned Reaper
R:795:0x0E/0x95

# The Norsa
R:796:0x0E/0x88

# Rhan-Tegoth
R:797:0x06/0x93

# Black reaver
R:798:0x08/0x8C

# Master mindcrafter
R:799:0x0B/0xAA

# Greater demonic quylthulg
R:800:0x0C/0x91

# Greater draconic quylthulg
R:801:0x0D/0x91

# Greater rotting quylthulg
R:802:0x0F/0x91

# Null, the Living Void
R:803:0x00/0xB5

# Feagwath, the Undead Sorcerer
R:804:0x0B/0x8C

# Omarax the Eye Tyrant
R:805:0x0A/0x9F

# Tsathoggua, the Sleeper of N'kai
R:806:0x08/0x92

# Greater Balrog
R:807:0x0A/0x95

# Ungoliant, the Unlight
R:808:0x08/0x93

# Atlach-Nacha, the Spider God
R:809:0x08/0x93

# Y'golonac
R:810:0x0C/0x88

# Aether hound
R:811:0x0A/0x9A

# Pit Fiend
R:812:0x03/0x95

# The Serpent of Chaos
R:813:0x0A/0x8A

# Yig, Father of Serpents
R:814:0x06/0x8A

# Unmaker
R:815:0x0A/0x85

# Cyberdemon
R:816:0x07/0x95

# Hela, Queen of the Dead
R:817:0x0D/0xAA

# The Mouth of Sauron
R:818:0x0A/0xAA

# The Necromancer of Dol Guldur
R:819:0x0A/0xAA

# Lisa, rider of gold Romth
R:820:0x0B/0x82

# Master quylthulg
R:821:0x0E/0x91

# Qlzqqlzuup, the Lord of Flesh
R:822:0x0A/0x91

# Cthugha, the Living Flame
R:823:0x0C/0x85

# Flare, rider of bronze Moonth
R:824:0x0F/0x82

# Maeglin, the Traitor of Gondolin
R:825:0x08/0xA2

# Cyaegha
R:826:0x0D/0x9F

# Pazuzu, Lord of Air
R:827:0x06/0x95

# Ithaqua the Windwalker
R:828:0x0E/0x99

# Greater Hellhound
R:829:0x04/0x83

# Cantoras, the Skeletal Lord
R:830:0x0A/0xAD

# Mephistopheles, Lord of Hell
R:831:0x04/0x95

# Godzilla
R:832:0x0A/0x92

# Abhoth, Source of Uncleanness
R:833:0x0D/0xA4

# Ymir, the Ice Giant
R:834:0x01/0x90

# Loki, the Trickster
R:835:0x08/0x90

# Star-spawn of Cthulhu
R:836:0x0D/0x95

# Surtur, the Fire Giant
R:837:0x04/0x90

# The Tarrasque
R:838:0x0A/0x92

# Lungorthin, the Balrog of White Fire
R:839:0x0A/0x95

# Draugluin, Sire of All Werewolves
R:840:0x0A/0x83

# Shuma-Gorath
R:841:0x0D/0x9F

# Tulzscha, the Green Flame
R:842:0x0D/0x85

# Oremorj, the Cyberdemon Lord
R:843:0x07/0x95

# Vecna, the Emperor Lich
R:844:0x0A/0x8C

# Yog-Sothoth, the All-in-One
R:845:0x0A/0xA4

# Fenris Wolf
R:846:0x08/0x83

# Great Wyrm of Power
R:847:0x0A/0x84

# Shub-Niggurath, Black Goat of the Woods
R:848:0x08/0x95

# Nodens, Lord of the Great Abyss
R:849:0x09/0x90

# Carcharoth, the Jaws of Thirst
R:850:0x08/0x83

# Nyarlathotep, the Crawling Chaos
R:851:0x04/0x95

# Azathoth, the Daemon Sultan
R:852:0x0E/0x85

# Huan, Wolfhound of the Valar
R:853:0x09/0x83

# Jormungand the Midgard Serpent
R:854:0x0A/0x8A

# The Destroyer
R:855:0x0A/0xA1

# Gothmog, the High Captain of Balrogs
R:856:0x0A/0x95

# Great Cthulhu
R:857:0x05/0x95

# Sarko, rider of gold Foronth
R:858:0x0B/0x82

# The Unicorn of Order
R:859:0x01/0xAB

# Sauron, the Sorcerer
R:860:0x0A/0xAA

# DarkGod, the Mighty Coder of Hell
R:861:0x0E/0x90

# Morgoth, Lord of Darkness
R:862:0x08/0x90

# Human Warrior
R:863:0x07/0xAA

# Elven archer
R:864:0x09/0xA2

# Dwarven warrior
R:865:0x0F/0xA2

# Elite uruk
R:866:0x01/0xA9

# The Philosophy Teacher
R:867:0x04/0xAA

# The Variant Maintainer
R:868:0x0E/0xAA

# Random Number Generator
R:869:0x06/0x89

# Rocket mine
R:870:0x0C/0xB5

# Bouncing mine
R:871:0x0E/0xB5

# Durin's Bane
R:872:0x0A/0x95

# The Icky Queen
R:873:0x0A/0xA3

# Rot jelly
R:874:0x07/0xA4

# Death
R:875:0x08/0x87

# Famine
R:876:0x0F/0x87

# Pestilence
R:877:0x0D/0x87

# War
R:878:0x04/0x87

# Pike
R:879:0x02/0x7E

# Electric eel
R:880:0x0E/0x8A

# Giant crayfish
R:881:0x0C/0x7E

# Mermaid
R:882:0x0D/0xA2

# Box jellyfish
R:883:0x0E/0x7E

# Giant piranha
R:884:0x05/0x7E

# Piranha
R:885:0x05/0x7E

# Bullywug
R:886:0x05/0xA2

# Bullywug warrior
R:887:0x05/0xA2

# Bullywug shaman
R:888:0x05/0xA2

# Whale
R:889:0x0D/0x7E

# Sand mite
R:890:0x0E/0x7E

# Octopus
R:891:0x05/0x7E

# Giant octopus
R:892:0x05/0x7E

# Eye of the deep
R:893:0x06/0x9F

# Murk dweller
R:894:0x02/0x93

# Drowned soul
R:895:0x0E/0x87

# Tiger shark
R:896:0x05/0x7E

# Hammerhead shark
R:897:0x05/0x7E

# Great white shark
R:898:0x01/0x7E

# Aquatic golem
R:899:0x06/0xA1

# Aquatic kobold
R:900:0x0E/0xA5

# White shark
R:901:0x09/0x7E

# Scrag
R:902:0x0E/0x94

# Jaws
R:903:0x01/0x7E

# Aquatic elf
R:904:0x06/0xA2

# Aquatic elven warrior
R:905:0x06/0xA2

# Aquatic elven shaman
R:906:0x06/0xA2

# Stargazer
R:907:0x0B/0x7E

# Elder stargazer
R:908:0x0B/0x7E

# Flounder
R:909:0x02/0x7E

# Giant turtle
R:910:0x0D/0x92

# Baby dragon turtle
R:911:0x09/0x9E

# Young dragon turtle
R:912:0x09/0x9E

# Mature dragon turtle
R:913:0x09/0x9E

# Ancient dragon turtle
R:914:0x09/0x84

# Fastitocalon
R:915:0x05/0x84

# Undead stargazer
R:916:0x0B/0x7E

# Killer whale
R:917:0x01/0x7E

# Merrow
R:918:0x0E/0x8F

# Water naga
R:919:0x0E/0xA8

# Devilfish
R:920:0x02/0x7E

# Undead devilfish
R:921:0x08/0x7E

# Moby Dick, the White Whale
R:922:0x01/0x7E

# Aquatic hound
R:923:0x0E/0x9A

# Water demon
R:924:0x0E/0x95

# Ixitxachitl
R:925:0x02/0x7E

# Ixitxachitl priest
R:926:0x02/0x7E

# Vampiric ixitxachitl
R:927:0x08/0x7E

# Mathilde, the Science Student
R:928:0x0B/0xA2

# Child spirit
R:929:0x09/0x87

# Young spirit
R:930:0x09/0x87

# Mature spirit
R:931:0x09/0x87

# Experienced spirit
R:932:0x09/0x87

# Wise spirit
R:933:0x09/0x87

# Fangorn the Treebeard, Lord of the Ents
R:934:0x0D/0xCC

# Gandalf the Grey
R:935:0x02/0xAA

# Nar, the Dwarf
R:936:0x0B/0xA2

# Novice mindcrafter
R:937:0x0B/0xAA

# Great Swamp Wyrm
R:938:0x05/0x84

# Great Bile Wyrm
R:939:0x02/0x84

# Blue Firebird
R:940:0x0E/0x82

# Green Firebird
R:941:0x0D/0x82

# Brown Firebird
R:942:0x07/0x82

# Bronze Firebird
R:943:0x0F/0x82

# Gold Firebird
R:944:0x0B/0x82

# High-elven ranger
R:945:0x0D/0xA2

# Uvatha the Horseman
R:946:0x08/0x97

# Adunaphel the Quiet
R:947:0x08/0x97

# Akhorahil the Blind
R:948:0x08/0x97

# Ren the Unclean
R:949:0x08/0x97

# Ji Indur Dawndeath
R:950:0x08/0x97

# Dwar, Dog Lord of Waw
R:951:0x08/0x97

# Hoarmurath of Dir
R:952:0x08/0x97

# Khamul, the Black Easterling
R:953:0x08/0x97

# The Witch-King of Angmar
R:954:0x08/0x97

# Green Thunderlord
R:955:0x05/0x82

# Blue Thunderlord
R:956:0x06/0x82

# Brown Thunderlord
R:957:0x07/0x82

# Bronze Thunderlord
R:958:0x0F/0x82

# Gold Thunderlord
R:959:0x0B/0x82

# Blood Sprout
R:960:0x05/0xEE

# Gorlim, Betrayer of Barahir
R:961:0x02/0xAA

# The Blubbering idiot, agent of black market, Simon the weak
R:962:0x09/0xAE

# Aranea
R:963:0x04/0x93

# Elder aranea
R:964:0x0A/0x93

# Giant brown tick
R:965:0x07/0x93

# Wavelord
R:966:0x06/0xAA

# Novice possessor (soul)
R:967:0x08/0x87

# Bat of Gorgoroth
R:968:0x05/0x9C

# The Princess
R:969:0x0B/0xAA

# Merton Proudfoot, the lost hobbit
R:970:0x0A/0xA2

# The Wight-King of the Barrow-downs
R:971:0x0A/0x97

# Adventurer
R:972:0x0F/0x80

# Experienced possessor (soul)
R:973:0x08/0x87

# Old possessor (soul)
R:974:0x08/0x87

# Death orb
R:975:0x08/0x85

# Bronze dragon worm
R:976:0x0F/0xB1

# Gold dragon worm
R:977:0x0B/0xB1

# Moldoux, the Defenceless Mold
R:978:0x0A/0xA7

# The Physics Teacher
R:979:0x01/0xAA

# Ar-Pharazon the Golden
R:980:0x0B/0xAA

# Doppelganger
R:981:0x01/0x80

# Marylene, Heartbreakeress of the Netherworld
R:982:0x09/0x90

# The Greater Lag Monster
R:983:0x0A/0x95

# Hrungnir, the Stone Giant
R:984:0x09/0x90

# Bullroarer the Hobbit
R:985:0x0F/0xA2

# 3-headed hydra
R:986:0x03/0x8D

# Uldor the Accursed
R:987:0x0F/0xAA

# Mystic
R:988:0x03/0xAA

# Elder vampire
R:989:0x04/0x96

# Ulfang the Black
R:990:0x0F/0xAA

# Demonologist
R:991:0x0C/0xAA

# Hezrou
R:992:0x05/0x95

# Glabrezu
R:993:0x0F/0x95

# Nalfeshnee
R:994:0x04/0x95

# Marilith
R:995:0x0B/0x95

# Lesser Balrog
R:996:0x0A/0x95

# Master mystic
R:997:0x03/0xAA

# Grand master mystic
R:998:0x03/0xAA

# Erinyes
R:999:0x07/0x95

# Novice mindcrafter
R:1000:0x0B/0xAA

# Polyphemus, the Blind Cyclops
R:1001:0x05/0x90

# Great Wyrm of Perplexity
R:1002:0x0F/0x84

# Hound of Tindalos
R:1003:0x02/0x9A

# Great Wyrm of Thunder
R:1004:0x0B/0x84

# Silver mouse
R:1005:0x09/0xAC

# The Rat King
R:1006:0x0A/0xAC

# Vort the Kobold Queen
R:1007:0x0A/0xA5

# Giant black louse
R:1008:0x08/0x89

# Fire Phantom
R:1009:0x04/0x87

# The Insane Player
R:1010:0x0A/0xAA

# Glaryssa, Succubus Queen
R:1011:0x09/0x95

# Vermicious Knid
R:1012:0x02/0xA4

# Bone golem
R:1013:0x01/0xA1

# Snake of Yig
R:1014:0x06/0x8A

# Bronze golem
R:1015:0x03/0xA1

# Dimensional shambler
R:1016:0x0E/0xA2

# Cultist
R:1017:0x0D/0xAA

# Cult leader
R:1018:0x0D/0xAA

# Servitor of the outer gods
R:1019:0x0B/0x88

# Avatar of Nyarlathotep
R:1020:0x0C/0xAA

# Thiazi, the Storm Giant
R:1021:0x0E/0x90

# Hypnos, Lord of Sleep
R:1022:0x0D/0xAA

# Blue dragon worm
R:1023:0x0E/0xB1

# White dragon worm
R:1024:0x09/0xB1

# Green dragon worm
R:1025:0x0D/0xB1

# Black dragon worm
R:1026:0x02/0xB1

# Red dragon worm
R:1027:0x0C/0xB1

# Multi-hued dragon worm
R:1028:0x0A/0xB1

# The Minotaur of the Labyrinth
R:1029:0x02/0x88

# The Sandworm Queen
R:1030:0x0A/0xB1

# Sandworm
R:1031:0x0B/0xB1

# Tik'srvzllat
R:1032:0x0A/0x87

# The Glass Golem
R:1033:0x09/0xBC

# The White Balrog
R:1034:0x09/0x95

# Golgarach, the Living Rock
R:1035:0x09/0xBC

# Atlas, the Titan
R:1036:0x02/0x90

# Kronos, Lord of the Titans
R:1037:0x0A/0x90

# Water hound
R:1038:0x04/0x9A

# Improv, the mighty MoLD
R:1039:0x0A/0xA7

# Emperor Mimic
R:1040:0x0B/0xA7

# Melinda Proudfoot
R:1041:0x0A/0xA2

# Thrain, the King Under the Mountain
R:1042:0x0E/0xA2

# Fire golem
R:1043:0x04/0xA1

# Melkor, Lord of Darkness
R:1044:0x0A/0x87

# Spirit
R:1045:0x0A/0x87

# Spirit
R:1046:0x0E/0x87

# Spirit
R:1047:0x0E/0x87

# Spirit
R:1048:0x0A/0x87

# Spirit
R:1049:0x0F/0x87

# Spirit
R:1050:0x0A/0x87

# Spirit
R:1051:0x05/0x87

# Spirit
R:1052:0x0A/0x87

# Spirit
R:1053:0x09/0xB5

# Spirit
R:1054:0x05/0x87

# Spirit
R:1055:0x09/0x87

# Spirit
R:1056:0x00/0x87

# Spirit
R:1057:0x07/0x87

# Spirit
R:1058:0x04/0x87

# Spirit
R:1059:0x0D/0x87

# Spirit
R:1060:0x09/0x87

# Spirit
R:1061:0x02/0x87

# Spirit
R:1062:0x06/0x87

# Spirit
R:1063:0x04/0x87

# Spirit
R:1064:0x01/0x87

# Spirit
R:1065:0x02/0x87

# Spirit
R:1066:0x06/0x87

# Spirit
R:1067:0x0A/0x87

# Spirit
R:1068:0x00/0x87

# Spirit
R:1069:0x09/0x87

# Spirit
R:1070:0x0A/0x87

# Spirit
R:1071:0x0D/0x87

# Spirit
R:1072:0x0B/0x87

# Spirit
R:1073:0x08/0x87

# Spirit
R:1074:0x03/0x87

# Spirit
R:1075:0x0A/0x87


tome-235-src/lib/pref/pref-mac.prf0000644000076400017500000000442111012107762014573 0ustar  dgdg# File: pref-mac.prf

#
# This file is included by "pref.prf" when "main-mac.c" is used.
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


#
# Macro Trigger configuration
#
# T:::::....
# '&' in  specifies location of modifier character.
# '#' in  specifies location of key code.
#
# If  is null string, all trigger difinition will be cleared.

T:&#:CSOX:control-:shift-:option-:command-

# T:::
# '\' in  is escape character.

T:KP_Decimal:1
T:KP_Multiply:3
T:KP_Add:5
T:KP_Clear:7
T:KP_Divide:11
T:KP_Enter:12
T:KP_Subtract:14
T:KP_Equal:17
T:KP_0:18
T:KP_1:19
T:KP_2:20
T:KP_3:21
T:KP_4:22
T:KP_5:23
T:KP_6:24
T:KP_7:25
T:KP_8:27
T:KP_9:28
T:F5:32
T:F6:33
T:F7:34
T:F3:35
T:F8:36
T:F10:37
T:F11:39
T:F13:41
T:F14:43
T:F9:45
T:F12:47
T:F15:49
T:Help:50
T:Home:51
T:Page_Up:52
T:Delete:53
T:F4:54
T:End:55
T:F2:56
T:Page_Down:57
T:F1:58
T:Left:59
T:Right:60
T:Down:61
T:Up:62

##### Simple Macros #####


#
# Keypad -- (/,*,7,8,9,-,4,5,6,+,1,2,3,0,.)
#

A:/
P:^_K/\r

A:*
P:^_K*\r

A:7
P:^_K7\r

A:8
P:^_K8\r

A:9
P:^_K9\r

A:-
P:^_K-\r

A:4
P:^_K4\r

A:5
P:^_K5\r

A:6
P:^_K6\r

A:+
P:^_K+\r

A:1
P:^_K1\r

A:2
P:^_K2\r

A:3
P:^_K3\r

A:0
P:^_K0\r

A:.
P:^_K.\r


#
# Shift-Keypad -- Directed running
#

A:\e\e\\.1
P:^_S19\r

A:\e\e\\.2
P:^_S20\r

A:\e\e\\.3
P:^_S21\r

A:\e\e\\.4
P:^_S22\r

A:\e\e\\.5
P:^_S23\r

A:\e\e\\.6
P:^_S24\r

A:\e\e\\.7
P:^_S25\r

A:\e\e\\.8
P:^_S27\r

A:\e\e\\.9
P:^_S28\r


#
# Control-Keypad -- Directed tunneling
#

A:\e\e\\+1
P:^_C19\r

A:\e\e\\+2
P:^_C20\r

A:\e\e\\+3
P:^_C21\r

A:\e\e\\+4
P:^_C22\r

A:\e\e\\+5
P:^_C23\r

A:\e\e\\+6
P:^_C24\r

A:\e\e\\+7
P:^_C25\r

A:\e\e\\+8
P:^_C27\r

A:\e\e\\+9
P:^_C28\r



#
# Option-Control-Keypad -- wield {@0} and tunnel
#

A:\e\ew0\s\s\\+1
P:^_CO19\r

A:\e\ew0\s\s\\+2
P:^_CO20\r

A:\e\ew0\s\s\\+3
P:^_CO21\r

A:\e\ew0\s\s\\+4
P:^_CO22\r

A:\e\ew0\s\s\\+5
P:^_CO23\r

A:\e\ew0\s\s\\+6
P:^_CO24\r

A:\e\ew0\s\s\\+7
P:^_CO25\r

A:\e\ew0\s\s\\+8
P:^_CO27\r

A:\e\ew0\s\s\\+9
P:^_CO28\r


#
# Option-Control-Keypad-Zero -- wield {@0}
#

A:\e\ew0\s
P:^_CO18\r



#
# Hack -- Arrow-Keys
#

A:4
P:^_59\r

A:6
P:^_60\r

A:2
P:^_61\r

A:8
P:^_62\r


tome-235-src/lib/pref/422color.prf0000644000076400017500000002413011012107762014446 0ustar  dgdg# Agent of the black market
R:14:0x08:0x74

# Mean-looking mercenary
R:17:0x0c:0x74

# Battle-scarred veteran
R:18:0x04:0x74

# Small kobold
R:29:0x0d:0x6b

# Kobold
R:30:0x05:0x6b

# Floating eye
R:32:0x06:0x65

# Fruit bat
R:37:0x0a:0x62

# Blubbering icky thing
R:41:0x05:0x69

# Metallic green centipede
R:42:0x0d:0x63

# Novice warrior
R:43:0x0f:0x70

# Novice rogue
R:44:0x08:0x70

# Novice priest
R:45:0x0e:0x70

# Novice mage
R:46:0x0c:0x70

# Smeagol
R:63:0x07:0x68

# Metallic blue centipede
R:67:0x0e:0x63

# Metallic red centipede
R:77:0x0c:0x63

# Novice ranger
R:83:0x05:0x70

# Snotling
R:87:0x0d:0x6f

# Skeleton kobold
R:91:0x01:0x73

# Novice mage
R:93:0x0c:0x70

# Giant leech
R:95:0x0a:0x77

# Large kobold
R:102:0x01:0x6b

# Novice priest
R:109:0x0e:0x70

# Novice warrior
R:110:0x0f:0x70

# Novice rogue
R:116:0x08:0x70

# Snaga
R:118:0x0d:0x6f

# Giant pink frog
R:121:0x0c:0x52

# Cave orc
R:126:0x0f:0x6f

# Manes
R:128:0x0c:0x75

# Red naga
R:130:0x0c:0x6e

# Red jelly
R:131:0x0c:0x6a

# Green icky thing
R:132:0x0d:0x69

# Lost soul
R:133:0x07:0x47

# Mughash, the Kobold Lord
R:135:0x06:0x6b

# Skeleton orc
R:136:0x01:0x73

# Wormtongue, Agent of Saruman
R:137:0x08:0x70

# Nurgling
R:139:0x0f:0x75

# Lagduf, the Snaga
R:140:0x07:0x6f

# Novice ranger
R:142:0x05:0x70

# Giant salamander
R:143:0x04:0x52

# Lemure
R:148:0x03:0x75

# Hill orc
R:149:0x02:0x6f

# Bandit
R:150:0x08:0x70

# Orc shaman
R:162:0x06:0x6f

# Baby blue dragon
R:163:0x0e:0x64

# Baby white dragon
R:164:0x09:0x64

# Baby green dragon
R:165:0x0d:0x64

# Baby red dragon
R:167:0x0c:0x64

# Giant red ant
R:168:0x0c:0x61

# Brodda, the Easterling
R:169:0x03:0x70

# Giant spider
R:175:0x02:0x53

# Dark elven mage
R:178:0x0a:0x68

# Kamikaze yeek
R:179:0x07:0x79

# Dark elven warrior
R:182:0x08:0x68

# Sand-dweller
R:183:0x0f:0x75

# Clear mushroom patch
R:184:0x01:0x2c

# Grishnakh, the Hill Orc
R:186:0x07:0x6f

# Hairy mold
R:190:0x0f:0x6d

# Grizzly bear
R:191:0x07:0x71

# Pseudo dragon
R:193:0x0a:0x64

# Giant fruit fly
R:197:0x0f:0x49

# Golfimbul, the Hill Orc Chief
R:215:0x07:0x6f

# Swordsman
R:216:0x0f:0x70

# Priest
R:225:0x0e:0x70

# Dark elven priest
R:226:0x06:0x68

# Skeleton human
R:228:0x01:0x73

# Moaning spirit
R:231:0x0f:0x47

# Stegocentipede
R:232:0x06:0x63

# Spotted jelly
R:233:0x02:0x6a

# Illusionist
R:240:0x0a:0x70

# Druid
R:241:0x05:0x70

# Ochre jelly
R:245:0x0b:0x6a

# Vlasta
R:249:0x06:0x52

# Snaga sapper
R:251:0x0d:0x6f

# Flesh golem
R:256:0x03:0x67

# Dark naga
R:265:0x08:0x6e

# Giant tarantula
R:275:0x0d:0x53

# Giant clear centipede
R:276:0x01:0x63

# Mirkwood spider
R:277:0x07:0x53

# Umber hulk
R:283:0x07:0x58

# Orc captain
R:285:0x05:0x6f

# Gelatinous cube
R:286:0x0e:0x6a

# Lizard man
R:290:0x0c:0x68

# Ulfast, Son of Ulfang
R:291:0x03:0x70

# Quasit
R:294:0x09:0x75

# Imp
R:296:0x04:0x75

# Forest troll
R:297:0x0d:0x54

# Giant red scorpion
R:304:0x0c:0x53

# Earth spirit
R:305:0x0f:0x45

# Fire spirit
R:306:0x0c:0x45

# Cold hound
R:308:0x09:0x5a

# Energy hound
R:309:0x0b:0x5a

# Uruk
R:313:0x01:0x6f

# Shagrat, the Orc Captain
R:314:0x07:0x6f

# Gorbag, the Orc Captain
R:315:0x07:0x6f

# Stone giant
R:321:0x02:0x50

# Giant black dragon fly
R:322:0x08:0x46

# Stone golem
R:323:0x02:0x67

# Ghast
R:327:0x0f:0x7a

# Bolg, Son of Azog
R:330:0x0c:0x6f

# Lizard king
R:332:0x0c:0x68

# Wyvern
R:334:0x0d:0x64

# Air hound
R:338:0x0e:0x5a

# Quylthulg
R:342:0x09:0x51

# Dark elven lord
R:348:0x08:0x68

# Cloud giant
R:349:0x0e:0x50

# Ugluk, the Uruk
R:350:0x07:0x6f

# Blue dragon bat
R:351:0x0e:0x62

# Water vortex
R:355:0x06:0x76

# Cold vortex
R:358:0x09:0x76

# Energy vortex
R:359:0x0b:0x76

# Mummified orc
R:362:0x07:0x7a

# Serpent man
R:364:0x05:0x4a

# Killer stag beetle
R:366:0x02:0x4b

# Iron golem
R:367:0x09:0x67

# Azog, King of the Uruk-Hai
R:373:0x04:0x6f

# Master rogue
R:376:0x08:0x70

# Angamaite of Umbar
R:380:0x07:0x70

# Forest wight
R:381:0x0d:0x57

# 4-headed hydra
R:387:0x0f:0x4d

# Mummified human
R:390:0x0f:0x7a

# Sangahyando of Umbar
R:392:0x03:0x70

# Banshee
R:394:0x09:0x47

# Pukelman
R:398:0x07:0x67

# Disenchanter beast
R:399:0x01:0x71

# Stone troll
R:401:0x08:0x54

# Troll priest
R:403:0x06:0x54

# Khufu, the Mummified King
R:409:0x07:0x7a

# Beast of Nurgle
R:422:0x03:0x71

# Creeping adamantite coins
R:423:0x0a:0x24

# Algroth
R:424:0x02:0x54

# Flamer of Tzeentch
R:425:0x0c:0x2c

# Vibration hound
R:428:0x0f:0x5a

# Ogre mage
R:430:0x03:0x4f

# Lokkak, the Ogre Chieftain
R:431:0x05:0x4f

# Colbran
R:435:0x06:0x67

# Spirit naga
R:436:0x0e:0x6e

# Corpser
R:437:0x05:0x2c

# Black knight
R:442:0x08:0x70

# Clairvoyant
R:445:0x0e:0x70

# Basilisk
R:453:0x08:0x52

# Aklash
R:463:0x09:0x54

# Skeleton troll
R:465:0x01:0x73

# Shadow drake
R:471:0x08:0x64

# Manticore
R:472:0x03:0x48

# Killer slicer beetle
R:474:0x03:0x4b

# Gug
R:476:0x08:0x50

# Death watch beetle
R:478:0x0e:0x4b

# Doombat
R:484:0x06:0x62

# Ninja
R:485:0x08:0x70

# Storm giant
R:487:0x06:0x50

# Bokrug
R:489:0x05:0x52

# Half-troll
R:491:0x03:0x54

# Bert the Stone Troll
R:493:0x09:0x54

# Bill the Stone Troll
R:494:0x09:0x54

# Tom the Stone Troll
R:495:0x09:0x54

# Barrow wight
R:499:0x09:0x57

# Law drake
R:502:0x09:0x64

# Balance drake
R:503:0x02:0x64

# Groo, the Wanderer
R:505:0x03:0x70

# Spectre
R:508:0x0d:0x47

# Cherub
R:511:0x09:0x41

# Master thief
R:516:0x08:0x70

# Lich
R:518:0x01:0x4c

# Master vampire
R:520:0x02:0x56

# Oriental vampire
R:521:0x05:0x56

# Greater mummy
R:522:0x09:0x7a

# Eog golem
R:530:0x08:0x67

# Dagashi
R:532:0x0b:0x70

# Smoke elemental
R:537:0x08:0x45

# Olog
R:538:0x05:0x54

# Gravity hound
R:540:0x02:0x5a

# Acidic cytoplasm
R:541:0x0d:0x6a

# Ooze elemental
R:545:0x0f:0x45

# Young black dragon
R:546:0x08:0x64

# Xorn
R:550:0x03:0x58

# Colossus
R:558:0x0b:0x67

# Bodak
R:566:0x08:0x75

# Lorgan, Chief of the Easterlings
R:573:0x0c:0x70

# Chaos spawn
R:574:0x07:0x65

# Crypt thing
R:577:0x0e:0x4c

# Will o' the wisp
R:582:0x0b:0x45

# Crystal drake
R:591:0x0e:0x64

# Mature black dragon
R:592:0x08:0x64

# Draebor, the Imp
R:595:0x05:0x75

# Mother Hydra
R:596:0x05:0x75

# Death knight
R:597:0x02:0x70

# Time vortex
R:599:0x0d:0x76

# Shimmering vortex
R:600:0x0a:0x76

# Beholder
R:603:0x05:0x65

# Emperor wight
R:604:0x0b:0x57

# Vargo, Tyrant of Fire
R:606:0x0c:0x45

# Nether wraith
R:612:0x0c:0x57

# Waldern, King of Water
R:615:0x02:0x45

# Ettin
R:621:0x0b:0x54

# Night mare
R:622:0x0a:0x71

# Ancient black dragon
R:624:0x08:0x44

# Shadowfax, steed of Gandalf
R:629:0x09:0x71

# Spirit troll
R:630:0x0a:0x47

# War troll
R:631:0x05:0x54

# Rotting quylthulg
R:633:0x0f:0x51

# 9-headed hydra
R:635:0x03:0x4d

# Enchantress
R:636:0x0b:0x70

# Sorcerer
R:638:0x03:0x70

# Xaren
R:639:0x0b:0x58

# Medusa, the Gorgon
R:642:0x03:0x6e

# Death drake
R:643:0x07:0x44

# Great crystal drake
R:646:0x0e:0x44

# Wyrd sister
R:647:0x0b:0x70

# Death quasit
R:649:0x01:0x75

# Fallen angel
R:652:0x08:0x41

# Judge Fire
R:654:0x04:0x73

# Master lich
R:658:0x09:0x4c

# Eol, the Dark Elf
R:660:0x02:0x68

# Undead beholder
R:664:0x02:0x65

# Dark young of Shub-Niggurath
R:677:0x08:0x55

# Dreadmaster
R:690:0x03:0x47

# Scatha the Worm
R:692:0x01:0x44

# Zoth-Ommog
R:695:0x07:0x52

# Grand master thief
R:696:0x0e:0x70

# Leprechaun fanatic
R:700:0x08:0x68

# Dracolich
R:701:0x0e:0x44

# Greater titan
R:702:0x0a:0x50

# Dracolisk
R:703:0x04:0x44

# Itangast the Fire Drake
R:710:0x04:0x44

# Glaurung, Father of the Dragons
R:715:0x04:0x44

# Behemoth
R:716:0x05:0x48

# Garm, Guardian of Hel
R:717:0x07:0x43

# Maulotaur
R:723:0x07:0x48

# Nether hound
R:724:0x08:0x5a

# Time hound
R:725:0x0d:0x5a

# Demonic quylthulg
R:727:0x0c:0x51

# Ulik the Troll
R:729:0x03:0x54

# Baphomet the Minotaur Lord
R:730:0x08:0x48

# Hell knight
R:731:0x02:0x70

# Old Sorcerer
R:738:0x0a:0x70

# Keeper of Secrets
R:746:0x0a:0x48

# Hand druj
R:748:0x08:0x73

# Eye druj
R:749:0x08:0x73

# Skull druj
R:750:0x08:0x73

# Aether vortex
R:752:0x0e:0x76

# Draconic quylthulg
R:759:0x0d:0x51

# Fundin Bluecloak
R:762:0x0d:0x68

# Gabriel, the Messenger
R:769:0x0a:0x41

# Artsi, the Champion of Chaos
R:770:0x0d:0x68

# The Cat Lord
R:777:0x04:0x66

# Vlad Dracula, Prince of Darkness
R:780:0x06:0x56

# Great Wyrm of Law
R:784:0x09:0x44

# Great Wyrm of Balance
R:785:0x02:0x44

# Glaaki
R:788:0x05:0x7e

# Greater draconic quylthulg
R:801:0x05:0x51

# Greater rotting quylthulg
R:802:0x07:0x51

# Omarax the Eye Tyrant
R:805:0x0b:0x65

# Greater Balrog
R:807:0x0c:0x55

# Aether hound
R:811:0x0e:0x5a

# Yig, Father of Serpents
R:814:0x05:0x4a

# Hela, Queen of the Dead
R:817:0x05:0x70

# Master quylthulg
R:821:0x06:0x51

# Qlzqqlzuup, the Lord of Flesh
R:822:0x0e:0x51

# F'lar, rider of the Bronze Mnementh
R:824:0x08:0x44

# Cyaegha
R:826:0x08:0x65

# Pazuzu, Lord of Air
R:827:0x01:0x55

# Cantoras, the Skeletal Lord
R:830:0x0e:0x73

# Godzilla
R:832:0x05:0x52

# Loki, the Trickster
R:835:0x05:0x50

# Lungorthin, the Balrog of White Fire
R:839:0x01:0x55

# Draugluin, Sire of All Werewolves
R:840:0x07:0x43

# Vecna, the Emperor Lich
R:844:0x0b:0x4c

# Great Wyrm of Power
R:847:0x0b:0x44

# Nodens, Lord of the Great Abyss
R:849:0x01:0x50

# Jormungand the Midgard Serpent
R:854:0x05:0x4a

# The Destroyer
R:855:0x09:0x67

# Gothmog, the High Captain of Balrogs
R:856:0x0c:0x55

# Sauron, the Sorcerer
R:860:0x03:0x70

# Human Warrior
R:863:0x01:0x70

# Elven archer
R:864:0x0d:0x68

# Death
R:875:0x02:0x47

# Famine
R:876:0x02:0x47

# Pestilence
R:877:0x02:0x47

# War
R:878:0x02:0x47

# Giant piranha
R:884:0x0d:0x7e

# Octopus
R:891:0x02:0x7e

# Giant octopus
R:892:0x0a:0x7e

# Drowned soul
R:895:0x02:0x47

# Devilfish
R:920:0x0a:0x7e

# Undead devilfish
R:921:0x0a:0x7e

# Gandalf the Grey
R:935:0x0a:0x70

# Brown Firelizard
R:942:0x0f:0x64

# Bronze Firelizard
R:943:0x01:0x64

# Elder aranea
R:964:0x04:0x53

# Bullroarer the Hobbit
R:985:0x06:0x68

# Hezrou
R:992:0x0a:0x55

# Glabrezu
R:993:0x03:0x55

# Lesser Balrog
R:996:0x0c:0x55

# The Rat King
R:1006:0x07:0x72

# Vort the Kobold Queen
R:1007:0x06:0x6b

# Fire Phantom
R:1009:0x0c:0x47

# Bone golem
R:1013:0x08:0x67

# Snake of Yig
R:1014:0x04:0x4a

# Cultist
R:1017:0x0e:0x70

# Cult leader
R:1018:0x06:0x70

# Green dragon worm
R:1025:0x05:0x77

# Red dragon worm
R:1027:0x04:0x77

tome-235-src/lib/pref/pref-emx.prf0000644000076400017500000000055411012107762014627 0ustar  dgdg# File: pref-emx.prf

#
# Include "pref-ibm.prf" to get the default macros.
#
# Note that, while most key-to-trigger mappings are the same as DOS/Win,
# some few odd keys will be different or not available at all.
#
# Examples: Ctrl-Escape, Alt-PrintScreen
#
# What's NOT working: color palette redefinitions.
#

%:pref-win.prf


# shift-5 - rest
A:R\r
P:^_Sx4C\r
tome-235-src/lib/pref/xtra-gcu.prf0000644000076400017500000000102011012107762014623 0ustar  dgdg# File: xtra-gcu.prf

# Rename this file to "pref-gcu.prf" to allow the VT100 cursor keys
# to be recognized by Angband.  This will also make the "escape" key
# take a few seconds to recognize, so you may want to use the "`" key
# instead, or make a macro from escape+escape to escape.

### VT100 Keypad ###

# Special keypad keys (delete, insert)
A:.
P:\e[3~
A:0
P:\e[2~

# Numerical keypad keys (map to appropriate number)
A:1
P:\e[4~
A:2
P:\e[B
A:3
P:\e[6~
A:4
P:\e[D
A:5
P:\e[G
A:6
P:\e[C
A:7
P:\e[1~
A:8
P:\e[A
A:9
P:\e[5~
tome-235-src/lib/pref/font-ami.prf0000644000076400017500000000106111012107762014610 0ustar  dgdg# File: font-ami.prf

#
# This file contains text remapping data
# currently used in the Amiga version.
#
# Lars Haugseth 
#


# Color palette - Text
V:0:0x01:0x00:0x00:0x00
V:1:0x01:0xFF:0xFF:0xFF
V:2:0x01:0xC7:0xC7:0xC7
V:3:0x01:0xFF:0x92:0x00
V:4:0x01:0xFF:0x00:0x00
V:5:0x01:0x00:0xCD:0x00
V:6:0x01:0x00:0x00:0xFE
V:7:0x01:0xC8:0x64:0x00
V:8:0x01:0x8A:0x8A:0x8A
V:9:0x01:0xE0:0xE0:0xE0
V:10:0x01:0xA5:0x00:0xFF
V:11:0x01:0xFF:0xFD:0x00
V:12:0x01:0xFF:0x00:0xBC
V:13:0x01:0x00:0xFF:0x00
V:14:0x01:0x00:0xC8:0xFF
V:15:0x01:0xFF:0xCC:0x80

tome-235-src/lib/pref/xtra-new.prf0000644000076400017500000010456411012107762014657 0ustar  dgdg# File: xtra-new.prf

#
# This file defines special attr/char mappings for use in "graphics" mode
#
# Edited for use with Adam Bolt's new graphics by Robert Ruehlmann < rr9@angband.org >
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


##### AK 20011216 Default pictures for all races that
#     are not handled below, without caring for class


?:[EQU $RACE Human]
R:0:0x89/0xA0
?:[EQU $RACE Half-Elf]
R:0:0x89/0xA1
?:[EQU $RACE Elf]
R:0:0x89/0xA2
?:[EQU $RACE Hobbit]
R:0:0x89/0xA3
?:[EQU $RACE Gnome]
R:0:0x89/0xA4
?:[EQU $RACE Dwarf]
R:0:0x89/0xA5
?:[EQU $RACE Orc]
R:0:0x89/0xA6
?:[EQU $RACE Troll]
R:0:0x89/0xA7
?:[EQU $RACE Dunadan]
R:0:0x89/0xA8
?:[EQU $RACE High-Elf]
R:0:0x89/0xA9
?:[EQU $RACE Half-Ogre]
R:0:0x89/0xAA
?:[EQU $RACE Beorning]
R:0:0x89/0xAB
?:[EQU $RACE Kobold]
R:0:0x89/0xAC
?:[EQU $RACE Petty-Dwarf]
R:0:0x89/0xAD
?:[EQU $RACE Dark-Elf]
R:0:0x89/0xAE
?:[EQU $RACE Ent]
R:0:0x89/0xAF
?:[EQU $RACE RohanKnight]
R:0:0x89/0xB0
?:[EQU $RACE Thunderlord]
R:0:0x89/0xB1
?:[EQU $RACE DeathMold]
R:0:0x89/0xB2
?:[EQU $RACE Yeek]
R:0:0x89/0xB3
?:[EQU $RACE Wood-Elf]
R:0:0x89/0xB4
?:[EQU $RACE Maia]
R:0:0x89/0xB5

##### Remap the player icon #####

?:[AND [EQU $CLASS Warrior] [EQU $RACE Human] ]
R:0:0x92/0x80
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Elf] ]
R:0:0x92/0x81
?:[AND [EQU $CLASS Warrior] [EQU $RACE Elf] ]
R:0:0x92/0x82
?:[AND [EQU $CLASS Warrior] [EQU $RACE Hobbit] ]
R:0:0x92/0x83
?:[AND [EQU $CLASS Warrior] [EQU $RACE Gnome] ]
R:0:0x92/0x84
?:[AND [EQU $CLASS Warrior] [EQU $RACE Dwarf] ]
R:0:0x92/0x85
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Orc] ]
R:0:0x92/0x86
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Troll] ]
R:0:0x92/0x87
?:[AND [EQU $CLASS Warrior] [EQU $RACE Dunadan] ]
R:0:0x92/0x88
?:[AND [EQU $CLASS Warrior] [EQU $RACE High-Elf] ]
R:0:0x92/0x89
?:[AND [EQU $CLASS Warrior] [EQU $RACE Dunadan] ]
R:0:0x92/0x8A
?:[AND [EQU $CLASS Warrior] [EQU $RACE Barbarian] ]
R:0:0x92/0x8B
?:[AND [EQU $CLASS Warrior] [EQU $RACE Ogre] ]
R:0:0x92/0x8C
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Giant] ]
R:0:0x92/0x8D
?:[AND [EQU $CLASS Warrior] [EQU $RACE Half-Titan] ]
R:0:0x92/0x8E
?:[AND [EQU $CLASS Warrior] [EQU $RACE Kobold] ]
R:0:0x92/0x92
?:[AND [EQU $CLASS Warrior] [EQU $RACE Nibelung] ]
R:0:0x92/0x93
?:[AND [EQU $CLASS Warrior] [EQU $RACE Dark Elf] ]
R:0:0x92/0x94
?:[AND [EQU $CLASS Warrior] [EQU $RACE RohanKnight] ]
R:0:0x93/0x91
?:[AND [EQU $CLASS Warrior] [EQU $RACE Thunderlord] ]
R:0:0x92/0x95
?:[AND [EQU $CLASS Warrior] [EQU $RACE Mindflayer] ]
R:0:0x92/0x96
?:[AND [EQU $CLASS Warrior] [EQU $RACE Imp] ]
R:0:0x92/0x97
?:[AND [EQU $CLASS Warrior] [EQU $RACE Ent] ]
R:0:0x92/0x98
?:[AND [EQU $CLASS Warrior] [EQU $RACE Skeleton] ]
R:0:0x92/0x99
?:[AND [EQU $CLASS Warrior] [EQU $RACE Zombie] ]
R:0:0x92/0x9A
?:[AND [EQU $CLASS Warrior] [EQU $RACE Vampire] ]
R:0:0x92/0x9B
?:[AND [EQU $CLASS Warrior] [EQU $RACE Spectre] ]
R:0:0x92/0x9C
?:[AND [EQU $CLASS Warrior] [EQU $RACE Sprite] ]
R:0:0x92/0x9D
?:[AND [EQU $CLASS Warrior] [EQU $RACE DeathMold] ]
R:0:0x92/0x9E

?:[AND [EQU $CLASS Mage] [EQU $RACE Human] ]
R:0:0x93/0x80
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Elf] ]
R:0:0x93/0x81
?:[AND [EQU $CLASS Mage] [EQU $RACE Elf] ]
R:0:0x93/0x82
?:[AND [EQU $CLASS Mage] [EQU $RACE Hobbit] ]
R:0:0x93/0x83
?:[AND [EQU $CLASS Mage] [EQU $RACE Gnome] ]
R:0:0x93/0x84
?:[AND [EQU $CLASS Mage] [EQU $RACE Dwarf] ]
R:0:0x93/0x85
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Orc] ]
R:0:0x93/0x86
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Troll] ]
R:0:0x93/0x87
?:[AND [EQU $CLASS Mage] [EQU $RACE Dunadan] ]
R:0:0x93/0x88
?:[AND [EQU $CLASS Mage] [EQU $RACE High-Elf] ]
R:0:0x93/0x89
?:[AND [EQU $CLASS Mage] [EQU $RACE Dunadan] ]
R:0:0x93/0x8A
?:[AND [EQU $CLASS Mage] [EQU $RACE Barbarian] ]
R:0:0x93/0x8B
?:[AND [EQU $CLASS Mage] [EQU $RACE Ogre] ]
R:0:0x93/0x8C
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Giant] ]
R:0:0x93/0x8D
?:[AND [EQU $CLASS Mage] [EQU $RACE Half-Titan] ]
R:0:0x93/0x8E
?:[AND [EQU $CLASS Mage] [EQU $RACE Cyclops] ]
R:0:0x93/0x8F
?:[AND [EQU $CLASS Mage] [EQU $RACE Yeek] ]
R:0:0x93/0x90
?:[AND [EQU $CLASS Mage] [EQU $RACE RohanKnight] ]
R:0:0x93/0x91
?:[AND [EQU $CLASS Mage] [EQU $RACE Kobold] ]
R:0:0x93/0x92
?:[AND [EQU $CLASS Mage] [EQU $RACE Nibelung] ]
R:0:0x93/0x93
?:[AND [EQU $CLASS Mage] [EQU $RACE Dark Elf] ]
R:0:0x93/0x94
?:[AND [EQU $CLASS Mage] [EQU $RACE Thunderlord] ]
R:0:0x93/0x95
?:[AND [EQU $CLASS Mage] [EQU $RACE Mindflayer] ]
R:0:0x93/0x96
?:[AND [EQU $CLASS Mage] [EQU $RACE Imp] ]
R:0:0x93/0x97
?:[AND [EQU $CLASS Mage] [EQU $RACE Ent] ]
R:0:0x93/0x98
?:[AND [EQU $CLASS Mage] [EQU $RACE Skeleton] ]
R:0:0x93/0x99
?:[AND [EQU $CLASS Mage] [EQU $RACE Zombie] ]
R:0:0x93/0x9A
?:[AND [EQU $CLASS Mage] [EQU $RACE Vampire] ]
R:0:0x93/0x9B
?:[AND [EQU $CLASS Mage] [EQU $RACE Spectre] ]
R:0:0x93/0x9C
?:[AND [EQU $CLASS Mage] [EQU $RACE Sprite] ]
R:0:0x93/0x9D
?:[AND [EQU $CLASS Mage] [EQU $RACE DeathMold] ]
R:0:0x93/0x9E

?:[AND [EQU $CLASS Priest] [EQU $RACE Human] ]
R:0:0x94/0x80
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Elf] ]
R:0:0x94/0x81
?:[AND [EQU $CLASS Priest] [EQU $RACE Elf] ]
R:0:0x94/0x82
?:[AND [EQU $CLASS Priest] [EQU $RACE Hobbit] ]
R:0:0x94/0x83
?:[AND [EQU $CLASS Priest] [EQU $RACE Gnome] ]
R:0:0x94/0x84
?:[AND [EQU $CLASS Priest] [EQU $RACE Dwarf] ]
R:0:0x94/0x85
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Orc] ]
R:0:0x94/0x86
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Troll] ]
R:0:0x94/0x87
?:[AND [EQU $CLASS Priest] [EQU $RACE Dunadan] ]
R:0:0x94/0x88
?:[AND [EQU $CLASS Priest] [EQU $RACE High-Elf] ]
R:0:0x94/0x89
?:[AND [EQU $CLASS Priest] [EQU $RACE Dunadan] ]
R:0:0x94/0x8A
?:[AND [EQU $CLASS Priest] [EQU $RACE Barbarian] ]
R:0:0x94/0x8B
?:[AND [EQU $CLASS Priest] [EQU $RACE Ogre] ]
R:0:0x94/0x8C
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Giant] ]
R:0:0x94/0x8D
?:[AND [EQU $CLASS Priest] [EQU $RACE Half-Titan] ]
R:0:0x94/0x8E
?:[AND [EQU $CLASS Priest] [EQU $RACE Cyclops] ]
R:0:0x94/0x8F
?:[AND [EQU $CLASS Priest] [EQU $RACE Yeek] ]
R:0:0x94/0x90
?:[AND [EQU $CLASS Priest] [EQU $RACE RohanKnight] ]
R:0:0x94/0x91
?:[AND [EQU $CLASS Priest] [EQU $RACE Kobold] ]
R:0:0x94/0x92
?:[AND [EQU $CLASS Priest] [EQU $RACE Nibelung] ]
R:0:0x94/0x93
?:[AND [EQU $CLASS Priest] [EQU $RACE Dark Elf] ]
R:0:0x94/0x94
?:[AND [EQU $CLASS Priest] [EQU $RACE Thunderlord] ]
R:0:0x94/0x95
?:[AND [EQU $CLASS Priest] [EQU $RACE Mindflayer] ]
R:0:0x94/0x96
?:[AND [EQU $CLASS Priest] [EQU $RACE Imp] ]
R:0:0x94/0x97
?:[AND [EQU $CLASS Priest] [EQU $RACE Ent] ]
R:0:0x94/0x98
?:[AND [EQU $CLASS Priest] [EQU $RACE Skeleton] ]
R:0:0x94/0x99
?:[AND [EQU $CLASS Priest] [EQU $RACE Zombie] ]
R:0:0x94/0x9A
?:[AND [EQU $CLASS Priest] [EQU $RACE Vampire] ]
R:0:0x94/0x9B
?:[AND [EQU $CLASS Priest] [EQU $RACE Spectre] ]
R:0:0x94/0x9C
?:[AND [EQU $CLASS Priest] [EQU $RACE Sprite] ]
R:0:0x94/0x9D
?:[AND [EQU $CLASS Priest] [EQU $RACE DeathMold] ]
R:0:0x94/0x9E

?:[AND [EQU $CLASS Rogue] [EQU $RACE Human] ]
R:0:0x95/0x80
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Elf] ]
R:0:0x95/0x81
?:[AND [EQU $CLASS Rogue] [EQU $RACE Elf] ]
R:0:0x95/0x82
?:[AND [EQU $CLASS Rogue] [EQU $RACE Hobbit] ]
R:0:0x95/0x83
?:[AND [EQU $CLASS Rogue] [EQU $RACE Gnome] ]
R:0:0x95/0x84
?:[AND [EQU $CLASS Rogue] [EQU $RACE Dwarf] ]
R:0:0x95/0x85
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Orc] ]
R:0:0x95/0x86
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Troll] ]
R:0:0x95/0x87
?:[AND [EQU $CLASS Rogue] [EQU $RACE Dunadan] ]
R:0:0x95/0x88
?:[AND [EQU $CLASS Rogue] [EQU $RACE High-Elf] ]
R:0:0x95/0x89
?:[AND [EQU $CLASS Rogue] [EQU $RACE Dunadan] ]
R:0:0x95/0x8A
?:[AND [EQU $CLASS Rogue] [EQU $RACE Barbarian] ]
R:0:0x95/0x8B
?:[AND [EQU $CLASS Rogue] [EQU $RACE Ogre] ]
R:0:0x95/0x8C
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Giant] ]
R:0:0x95/0x8D
?:[AND [EQU $CLASS Rogue] [EQU $RACE Half-Titan] ]
R:0:0x95/0x8E
?:[AND [EQU $CLASS Rogue] [EQU $RACE Cyclops] ]
R:0:0x95/0x8F
?:[AND [EQU $CLASS Rogue] [EQU $RACE Yeek] ]
R:0:0x95/0x90
?:[AND [EQU $CLASS Rogue] [EQU $RACE RohanKnight] ]
R:0:0x95/0x91
?:[AND [EQU $CLASS Rogue] [EQU $RACE Kobold] ]
R:0:0x95/0x92
?:[AND [EQU $CLASS Rogue] [EQU $RACE Nibelung] ]
R:0:0x95/0x93
?:[AND [EQU $CLASS Rogue] [EQU $RACE Dark Elf] ]
R:0:0x95/0x94
?:[AND [EQU $CLASS Rogue] [EQU $RACE Thunderlord] ]
R:0:0x95/0x95
?:[AND [EQU $CLASS Rogue] [EQU $RACE Mindflayer] ]
R:0:0x95/0x96
?:[AND [EQU $CLASS Rogue] [EQU $RACE Imp] ]
R:0:0x95/0x97
?:[AND [EQU $CLASS Rogue] [EQU $RACE Ent] ]
R:0:0x95/0x98
?:[AND [EQU $CLASS Rogue] [EQU $RACE Skeleton] ]
R:0:0x95/0x99
?:[AND [EQU $CLASS Rogue] [EQU $RACE Zombie] ]
R:0:0x95/0x9A
?:[AND [EQU $CLASS Rogue] [EQU $RACE Vampire] ]
R:0:0x95/0x9B
?:[AND [EQU $CLASS Rogue] [EQU $RACE Spectre] ]
R:0:0x95/0x9C
?:[AND [EQU $CLASS Rogue] [EQU $RACE Sprite] ]
R:0:0x95/0x9D
?:[AND [EQU $CLASS Rogue] [EQU $RACE DeathMold] ]
R:0:0x95/0x9E

?:[AND [EQU $CLASS Ranger] [EQU $RACE Human] ]
R:0:0x96/0x80
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Elf] ]
R:0:0x96/0x81
?:[AND [EQU $CLASS Ranger] [EQU $RACE Elf] ]
R:0:0x96/0x82
?:[AND [EQU $CLASS Ranger] [EQU $RACE Hobbit] ]
R:0:0x96/0x83
?:[AND [EQU $CLASS Ranger] [EQU $RACE Gnome] ]
R:0:0x96/0x84
?:[AND [EQU $CLASS Ranger] [EQU $RACE Dwarf] ]
R:0:0x96/0x85
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Orc] ]
R:0:0x96/0x86
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Troll] ]
R:0:0x96/0x87
?:[AND [EQU $CLASS Ranger] [EQU $RACE Dunadan] ]
R:0:0x96/0x88
?:[AND [EQU $CLASS Ranger] [EQU $RACE High-Elf] ]
R:0:0x96/0x89
?:[AND [EQU $CLASS Ranger] [EQU $RACE Dunadan] ]
R:0:0x96/0x8A
?:[AND [EQU $CLASS Ranger] [EQU $RACE Barbarian] ]
R:0:0x96/0x8B
?:[AND [EQU $CLASS Ranger] [EQU $RACE Ogre] ]
R:0:0x96/0x8C
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Giant] ]
R:0:0x96/0x8D
?:[AND [EQU $CLASS Ranger] [EQU $RACE Half-Titan] ]
R:0:0x96/0x8E
?:[AND [EQU $CLASS Ranger] [EQU $RACE Cyclops] ]
R:0:0x96/0x8F
?:[AND [EQU $CLASS Ranger] [EQU $RACE Yeek] ]
R:0:0x96/0x90
?:[AND [EQU $CLASS Ranger] [EQU $RACE RohanKnight] ]
R:0:0x96/0x91
?:[AND [EQU $CLASS Ranger] [EQU $RACE Kobold] ]
R:0:0x96/0x92
?:[AND [EQU $CLASS Ranger] [EQU $RACE Nibelung] ]
R:0:0x96/0x93
?:[AND [EQU $CLASS Ranger] [EQU $RACE Dark Elf] ]
R:0:0x96/0x94
?:[AND [EQU $CLASS Ranger] [EQU $RACE Thunderlord] ]
R:0:0x96/0x95
?:[AND [EQU $CLASS Ranger] [EQU $RACE Mindflayer] ]
R:0:0x96/0x96
?:[AND [EQU $CLASS Ranger] [EQU $RACE Imp] ]
R:0:0x96/0x97
?:[AND [EQU $CLASS Ranger] [EQU $RACE Ent] ]
R:0:0x96/0x98
?:[AND [EQU $CLASS Ranger] [EQU $RACE Skeleton] ]
R:0:0x96/0x99
?:[AND [EQU $CLASS Ranger] [EQU $RACE Zombie] ]
R:0:0x96/0x9A
?:[AND [EQU $CLASS Ranger] [EQU $RACE Vampire] ]
R:0:0x96/0x9B
?:[AND [EQU $CLASS Ranger] [EQU $RACE Spectre] ]
R:0:0x96/0x9C
?:[AND [EQU $CLASS Ranger] [EQU $RACE Sprite] ]
R:0:0x96/0x9D
?:[AND [EQU $CLASS Ranger] [EQU $RACE DeathMold] ]
R:0:0x96/0x9E

?:[AND [EQU $CLASS Paladin] [EQU $RACE Human] ]
R:0:0x97/0x80
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Elf] ]
R:0:0x97/0x81
?:[AND [EQU $CLASS Paladin] [EQU $RACE Elf] ]
R:0:0x97/0x82
?:[AND [EQU $CLASS Paladin] [EQU $RACE Hobbit] ]
R:0:0x97/0x83
?:[AND [EQU $CLASS Paladin] [EQU $RACE Gnome] ]
R:0:0x97/0x84
?:[AND [EQU $CLASS Paladin] [EQU $RACE Dwarf] ]
R:0:0x97/0x85
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Orc] ]
R:0:0x97/0x86
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Troll] ]
R:0:0x97/0x87
?:[AND [EQU $CLASS Paladin] [EQU $RACE Dunadan] ]
R:0:0x97/0x88
?:[AND [EQU $CLASS Paladin] [EQU $RACE High-Elf] ]
R:0:0x97/0x89
?:[AND [EQU $CLASS Paladin] [EQU $RACE Dunadan] ]
R:0:0x97/0x8A
?:[AND [EQU $CLASS Paladin] [EQU $RACE Barbarian] ]
R:0:0x97/0x8B
?:[AND [EQU $CLASS Paladin] [EQU $RACE Ogre] ]
R:0:0x97/0x8C
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Giant] ]
R:0:0x97/0x8D
?:[AND [EQU $CLASS Paladin] [EQU $RACE Half-Titan] ]
R:0:0x97/0x8E
?:[AND [EQU $CLASS Paladin] [EQU $RACE Cyclops] ]
R:0:0x97/0x8F
?:[AND [EQU $CLASS Paladin] [EQU $RACE Yeek] ]
R:0:0x97/0x90
?:[AND [EQU $CLASS Paladin] [EQU $RACE RohanKnight] ]
R:0:0x97/0x91
?:[AND [EQU $CLASS Paladin] [EQU $RACE Kobold] ]
R:0:0x97/0x92
?:[AND [EQU $CLASS Paladin] [EQU $RACE Nibelung] ]
R:0:0x97/0x93
?:[AND [EQU $CLASS Paladin] [EQU $RACE Dark Elf] ]
R:0:0x97/0x94
?:[AND [EQU $CLASS Paladin] [EQU $RACE Thunderlord] ]
R:0:0x97/0x95
?:[AND [EQU $CLASS Paladin] [EQU $RACE Mindflayer] ]
R:0:0x97/0x96
?:[AND [EQU $CLASS Paladin] [EQU $RACE Imp] ]
R:0:0x97/0x97
?:[AND [EQU $CLASS Paladin] [EQU $RACE Ent] ]
R:0:0x97/0x98
?:[AND [EQU $CLASS Paladin] [EQU $RACE Skeleton] ]
R:0:0x97/0x99
?:[AND [EQU $CLASS Paladin] [EQU $RACE Zombie] ]
R:0:0x97/0x9A
?:[AND [EQU $CLASS Paladin] [EQU $RACE Vampire] ]
R:0:0x97/0x9B
?:[AND [EQU $CLASS Paladin] [EQU $RACE Spectre] ]
R:0:0x97/0x9C
?:[AND [EQU $CLASS Paladin] [EQU $RACE Sprite] ]
R:0:0x97/0x9D
?:[AND [EQU $CLASS Paladin] [EQU $RACE DeathMold] ]
R:0:0x97/0x9E

?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Human] ]
R:0:0x98/0x80
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Half-Elf] ]
R:0:0x98/0x81
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Elf] ]
R:0:0x98/0x82
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Hobbit] ]
R:0:0x98/0x83
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Gnome] ]
R:0:0x98/0x84
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Dwarf] ]
R:0:0x98/0x85
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Half-Orc] ]
R:0:0x98/0x86
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Half-Troll] ]
R:0:0x98/0x87
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Dunadan] ]
R:0:0x98/0x88
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE High-Elf] ]
R:0:0x98/0x89
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Dunadan] ]
R:0:0x98/0x8A
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Barbarian] ]
R:0:0x98/0x8B
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Ogre] ]
R:0:0x98/0x8C
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Half-Giant] ]
R:0:0x98/0x8D
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Half-Titan] ]
R:0:0x98/0x8E
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Cyclops] ]
R:0:0x98/0x8F
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Yeek] ]
R:0:0x98/0x90
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE RohanKnight] ]
R:0:0x98/0x91
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Kobold] ]
R:0:0x98/0x92
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Nibelung] ]
R:0:0x98/0x93
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Dark Elf] ]
R:0:0x98/0x94
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Thunderlord] ]
R:0:0x98/0x95
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Mindflayer] ]
R:0:0x98/0x96
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Imp] ]
R:0:0x98/0x97
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Ent] ]
R:0:0x98/0x98
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Skeleton] ]
R:0:0x98/0x99
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Zombie] ]
R:0:0x98/0x9A
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Vampire] ]
R:0:0x98/0x9B
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Spectre] ]
R:0:0x98/0x9C
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE Sprite] ]
R:0:0x98/0x9D
?:[AND [EQU $CLASS Warrior-Mage] [EQU $RACE DeathMold] ]
R:0:0x98/0x9E

?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Human] ]
R:0:0x99/0x80
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Half-Elf] ]
R:0:0x99/0x81
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Elf] ]
R:0:0x99/0x82
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Hobbit] ]
R:0:0x99/0x83
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Gnome] ]
R:0:0x99/0x84
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Dwarf] ]
R:0:0x99/0x85
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Half-Orc] ]
R:0:0x99/0x86
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Half-Troll] ]
R:0:0x99/0x87
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Dunadan] ]
R:0:0x99/0x88
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE High-Elf] ]
R:0:0x99/0x89
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Dunadan] ]
R:0:0x99/0x8A
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Barbarian] ]
R:0:0x99/0x8B
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Ogre] ]
R:0:0x99/0x8C
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Half-Giant] ]
R:0:0x99/0x8D
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Half-Titan] ]
R:0:0x99/0x8E
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Cyclops] ]
R:0:0x99/0x8F
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Yeek] ]
R:0:0x99/0x90
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE RohanKnight] ]
R:0:0x99/0x91
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Kobold] ]
R:0:0x99/0x92
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Nibelung] ]
R:0:0x99/0x93
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Dark Elf] ]
R:0:0x99/0x94
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Thunderlord] ]
R:0:0x99/0x95
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Mindflayer] ]
R:0:0x99/0x96
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Imp] ]
R:0:0x99/0x97
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Ent] ]
R:0:0x99/0x98
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Skeleton] ]
R:0:0x99/0x99
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Zombie] ]
R:0:0x99/0x9A
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Vampire] ]
R:0:0x99/0x9B
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Spectre] ]
R:0:0x99/0x9C
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE Sprite] ]
R:0:0x99/0x9D
?:[AND [EQU $CLASS Chaos-Warrior] [EQU $RACE DeathMold] ]
R:0:0x99/0x9E

?:[AND [EQU $CLASS Monk] [EQU $RACE Human] ]
R:0:0x9A/0x80
?:[AND [EQU $CLASS Monk] [EQU $RACE Half-Elf] ]
R:0:0x9A/0x81
?:[AND [EQU $CLASS Monk] [EQU $RACE Elf] ]
R:0:0x9A/0x82
?:[AND [EQU $CLASS Monk] [EQU $RACE Hobbit] ]
R:0:0x9A/0x83
?:[AND [EQU $CLASS Monk] [EQU $RACE Gnome] ]
R:0:0x9A/0x84
?:[AND [EQU $CLASS Monk] [EQU $RACE Dwarf] ]
R:0:0x9A/0x85
?:[AND [EQU $CLASS Monk] [EQU $RACE Half-Orc] ]
R:0:0x9A/0x86
?:[AND [EQU $CLASS Monk] [EQU $RACE Half-Troll] ]
R:0:0x9A/0x87
?:[AND [EQU $CLASS Monk] [EQU $RACE Dunadan] ]
R:0:0x9A/0x88
?:[AND [EQU $CLASS Monk] [EQU $RACE High-Elf] ]
R:0:0x9A/0x89
?:[AND [EQU $CLASS Monk] [EQU $RACE Dunadan] ]
R:0:0x9A/0x8A
?:[AND [EQU $CLASS Monk] [EQU $RACE Barbarian] ]
R:0:0x9A/0x8B
?:[AND [EQU $CLASS Monk] [EQU $RACE Ogre] ]
R:0:0x9A/0x8C
?:[AND [EQU $CLASS Monk] [EQU $RACE Half-Giant] ]
R:0:0x9A/0x8D
?:[AND [EQU $CLASS Monk] [EQU $RACE Half-Titan] ]
R:0:0x9A/0x8E
?:[AND [EQU $CLASS Monk] [EQU $RACE Cyclops] ]
R:0:0x9A/0x8F
?:[AND [EQU $CLASS Monk] [EQU $RACE Yeek] ]
R:0:0x9A/0x90
?:[AND [EQU $CLASS Monk] [EQU $RACE RohanKnight] ]
R:0:0x9A/0x91
?:[AND [EQU $CLASS Monk] [EQU $RACE Kobold] ]
R:0:0x9A/0x92
?:[AND [EQU $CLASS Monk] [EQU $RACE Nibelung] ]
R:0:0x9A/0x93
?:[AND [EQU $CLASS Monk] [EQU $RACE Dark Elf] ]
R:0:0x9A/0x94
?:[AND [EQU $CLASS Monk] [EQU $RACE Thunderlord] ]
R:0:0x9A/0x95
?:[AND [EQU $CLASS Monk] [EQU $RACE Mindflayer] ]
R:0:0x9A/0x96
?:[AND [EQU $CLASS Monk] [EQU $RACE Imp] ]
R:0:0x9A/0x97
?:[AND [EQU $CLASS Monk] [EQU $RACE Ent] ]
R:0:0x9A/0x98
?:[AND [EQU $CLASS Monk] [EQU $RACE Skeleton] ]
R:0:0x9A/0x99
?:[AND [EQU $CLASS Monk] [EQU $RACE Zombie] ]
R:0:0x9A/0x9A
?:[AND [EQU $CLASS Monk] [EQU $RACE Vampire] ]
R:0:0x9A/0x9B
?:[AND [EQU $CLASS Monk] [EQU $RACE Spectre] ]
R:0:0x9A/0x9C
?:[AND [EQU $CLASS Monk] [EQU $RACE Sprite] ]
R:0:0x9A/0x9D
?:[AND [EQU $CLASS Monk] [EQU $RACE DeathMold] ]
R:0:0x9A/0x9E

?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Human] ]
R:0:0x9B/0x80
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Half-Elf] ]
R:0:0x9B/0x81
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Elf] ]
R:0:0x9B/0x82
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Hobbit] ]
R:0:0x9B/0x83
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Gnome] ]
R:0:0x9B/0x84
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Dwarf] ]
R:0:0x9B/0x85
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Half-Orc] ]
R:0:0x9B/0x86
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Half-Troll] ]
R:0:0x9B/0x87
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Dunadan] ]
R:0:0x9B/0x88
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE High-Elf] ]
R:0:0x9B/0x89
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Dunadan] ]
R:0:0x9B/0x8A
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Barbarian] ]
R:0:0x9B/0x8B
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Ogre] ]
R:0:0x9B/0x8C
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Half-Giant] ]
R:0:0x9B/0x8D
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Half-Titan] ]
R:0:0x9B/0x8E
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Cyclops] ]
R:0:0x9B/0x8F
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Yeek] ]
R:0:0x9B/0x90
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE RohanKnight] ]
R:0:0x9B/0x91
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Kobold] ]
R:0:0x9B/0x92
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Nibelung] ]
R:0:0x9B/0x93
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Dark Elf] ]
R:0:0x9B/0x94
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Thunderlord] ]
R:0:0x9B/0x95
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Mindflayer] ]
R:0:0x9B/0x96
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Imp] ]
R:0:0x9B/0x97
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Ent] ]
R:0:0x9B/0x98
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Skeleton] ]
R:0:0x9B/0x99
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Zombie] ]
R:0:0x9B/0x9A
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Vampire] ]
R:0:0x9B/0x9B
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Spectre] ]
R:0:0x9B/0x9C
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE Sprite] ]
R:0:0x9B/0x9D
?:[AND [EQU $CLASS Mindcrafter] [EQU $RACE DeathMold] ]
R:0:0x9B/0x9E

?:[AND [EQU $CLASS High-Mage] [EQU $RACE Human] ]
R:0:0x9C/0x80
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Half-Elf] ]
R:0:0x9C/0x81
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Elf] ]
R:0:0x9C/0x82
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Hobbit] ]
R:0:0x9C/0x83
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Gnome] ]
R:0:0x9C/0x84
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Dwarf] ]
R:0:0x9C/0x85
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Half-Orc] ]
R:0:0x9C/0x86
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Half-Troll] ]
R:0:0x9C/0x87
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Dunadan] ]
R:0:0x9C/0x88
?:[AND [EQU $CLASS High-Mage] [EQU $RACE High-Elf] ]
R:0:0x9C/0x89
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Dunadan] ]
R:0:0x9C/0x8A
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Barbarian] ]
R:0:0x9C/0x8B
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Ogre] ]
R:0:0x9C/0x8C
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Half-Giant] ]
R:0:0x9C/0x8D
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Half-Titan] ]
R:0:0x9C/0x8E
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Cyclops] ]
R:0:0x9C/0x8F
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Yeek] ]
R:0:0x9C/0x90
?:[AND [EQU $CLASS High-Mage] [EQU $RACE RohanKnight] ]
R:0:0x9C/0x91
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Kobold] ]
R:0:0x9C/0x92
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Nibelung] ]
R:0:0x9C/0x93
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Dark Elf] ]
R:0:0x9C/0x94
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Thunderlord] ]
R:0:0x9C/0x95
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Mindflayer] ]
R:0:0x9C/0x96
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Imp] ]
R:0:0x9C/0x97
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Ent] ]
R:0:0x9C/0x98
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Skeleton] ]
R:0:0x9C/0x99
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Zombie] ]
R:0:0x9C/0x9A
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Vampire] ]
R:0:0x9C/0x9B
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Spectre] ]
R:0:0x9C/0x9C
?:[AND [EQU $CLASS High-Mage] [EQU $RACE Sprite] ]
R:0:0x9C/0x9D
?:[AND [EQU $CLASS High-Mage] [EQU $RACE DeathMold] ]
R:0:0x9C/0x9E

?:[AND [EQU $CLASS Alchemist] [EQU $RACE Human] ]
R:0:0x9C/0x80
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Elf] ]
R:0:0x9C/0x81
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Elf] ]
R:0:0x9C/0x82
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Hobbit] ]
R:0:0x9C/0x83
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Gnome] ]
R:0:0x9C/0x84
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dwarf] ]
R:0:0x9C/0x85
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Orc] ]
R:0:0x9C/0x86
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Troll] ]
R:0:0x9C/0x87
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dunadan] ]
R:0:0x9C/0x88
?:[AND [EQU $CLASS Alchemist] [EQU $RACE High-Elf] ]
R:0:0x9C/0x89
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dunadan] ]
R:0:0x9C/0x8A
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Barbarian] ]
R:0:0x9C/0x8B
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Ogre] ]
R:0:0x9C/0x8C
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Giant] ]
R:0:0x9C/0x8D
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Titan] ]
R:0:0x9C/0x8E
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Cyclops] ]
R:0:0x9C/0x8F
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Yeek] ]
R:0:0x9C/0x90
?:[AND [EQU $CLASS Alchemist] [EQU $RACE RohanKnight] ]
R:0:0x9C/0x91
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Kobold] ]
R:0:0x9C/0x92
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Nibelung] ]
R:0:0x9C/0x93
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dark Elf] ]
R:0:0x9C/0x94
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Thunderlord] ]
R:0:0x9C/0x95
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Mindflayer] ]
R:0:0x9C/0x96
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Imp] ]
R:0:0x9C/0x97
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Ent] ]
R:0:0x9C/0x98
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Skeleton] ]
R:0:0x9C/0x99
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Zombie] ]
R:0:0x9C/0x9A
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Vampire] ]
R:0:0x9C/0x9B
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Spectre] ]
R:0:0x9C/0x9C
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Sprite] ]
R:0:0x9C/0x9D
?:[AND [EQU $CLASS Alchemist] [EQU $RACE DeathMold] ]
R:0:0x9C/0x9E

?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Human] ]
R:0:0x96/0x80
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Half-Elf] ]
R:0:0x96/0x81
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Elf] ]
R:0:0x96/0x82
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Hobbit] ]
R:0:0x96/0x83
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Gnome] ]
R:0:0x96/0x84
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Dwarf] ]
R:0:0x96/0x85
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Half-Orc] ]
R:0:0x96/0x86
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Half-Troll] ]
R:0:0x96/0x87
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Dunadan] ]
R:0:0x96/0x88
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE High-Elf] ]
R:0:0x96/0x89
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Dunadan] ]
R:0:0x96/0x8A
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Barbarian] ]
R:0:0x96/0x8B
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Ogre] ]
R:0:0x96/0x8C
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Half-Giant] ]
R:0:0x96/0x8D
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Half-Titan] ]
R:0:0x96/0x8E
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Cyclops] ]
R:0:0x96/0x8F
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Yeek] ]
R:0:0x96/0x90
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE RohanKnight] ]
R:0:0x96/0x91
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Kobold] ]
R:0:0x96/0x92
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Nibelung] ]
R:0:0x96/0x93
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Dark Elf] ]
R:0:0x96/0x94
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Thunderlord] ]
R:0:0x96/0x95
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Mindflayer] ]
R:0:0x96/0x96
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Imp] ]
R:0:0x96/0x97
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Ent] ]
R:0:0x96/0x98
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Skeleton] ]
R:0:0x96/0x99
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Zombie] ]
R:0:0x96/0x9A
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Vampire] ]
R:0:0x96/0x9B
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Spectre] ]
R:0:0x96/0x9C
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE Sprite] ]
R:0:0x96/0x9D
?:[AND [EQU $CLASS BeastMaster] [EQU $RACE DeathMold] ]
R:0:0x96/0x9E

?:[EQU $CLASS Mimic]
R:0:0x91/0x95

?:[AND [EQU $CLASS Alchemist] [EQU $RACE Human] ]
R:0:0x93/0x80
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Elf] ]
R:0:0x93/0x81
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Elf] ]
R:0:0x93/0x82
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Hobbit] ]
R:0:0x93/0x83
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Gnome] ]
R:0:0x93/0x84
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dwarf] ]
R:0:0x93/0x85
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Orc] ]
R:0:0x93/0x86
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Troll] ]
R:0:0x93/0x87
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dunadan] ]
R:0:0x93/0x88
?:[AND [EQU $CLASS Alchemist] [EQU $RACE High-Elf] ]
R:0:0x93/0x89
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dunadan] ]
R:0:0x93/0x8A
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Barbarian] ]
R:0:0x93/0x8B
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Ogre] ]
R:0:0x93/0x8C
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Giant] ]
R:0:0x93/0x8D
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Half-Titan] ]
R:0:0x93/0x8E
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Cyclops] ]
R:0:0x93/0x8F
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Yeek] ]
R:0:0x93/0x90
?:[AND [EQU $CLASS Alchemist] [EQU $RACE RohanKnight] ]
R:0:0x93/0x91
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Kobold] ]
R:0:0x93/0x92
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Nibelung] ]
R:0:0x93/0x93
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Dark Elf] ]
R:0:0x93/0x94
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Thunderlord] ]
R:0:0x93/0x95
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Mindflayer] ]
R:0:0x93/0x96
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Imp] ]
R:0:0x93/0x97
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Ent] ]
R:0:0x93/0x98
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Skeleton] ]
R:0:0x93/0x99
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Zombie] ]
R:0:0x93/0x9A
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Vampire] ]
R:0:0x93/0x9B
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Spectre] ]
R:0:0x93/0x9C
?:[AND [EQU $CLASS Alchemist] [EQU $RACE Sprite] ]
R:0:0x93/0x9D
?:[AND [EQU $CLASS Alchemist] [EQU $RACE DeathMold] ]
R:0:0x93/0x9E

?:[AND [EQU $CLASS Wizard] [EQU $RACE Human] ]
R:0:0x93/0x80
?:[AND [EQU $CLASS Wizard] [EQU $RACE Half-Elf] ]
R:0:0x93/0x81
?:[AND [EQU $CLASS Wizard] [EQU $RACE Elf] ]
R:0:0x93/0x82
?:[AND [EQU $CLASS Wizard] [EQU $RACE Hobbit] ]
R:0:0x93/0x83
?:[AND [EQU $CLASS Wizard] [EQU $RACE Gnome] ]
R:0:0x93/0x84
?:[AND [EQU $CLASS Wizard] [EQU $RACE Dwarf] ]
R:0:0x93/0x85
?:[AND [EQU $CLASS Wizard] [EQU $RACE Half-Orc] ]
R:0:0x93/0x86
?:[AND [EQU $CLASS Wizard] [EQU $RACE Half-Troll] ]
R:0:0x93/0x87
?:[AND [EQU $CLASS Wizard] [EQU $RACE Dunadan] ]
R:0:0x93/0x88
?:[AND [EQU $CLASS Wizard] [EQU $RACE High-Elf] ]
R:0:0x93/0x89
?:[AND [EQU $CLASS Wizard] [EQU $RACE Dunadan] ]
R:0:0x93/0x8A
?:[AND [EQU $CLASS Wizard] [EQU $RACE Barbarian] ]
R:0:0x93/0x8B
?:[AND [EQU $CLASS Wizard] [EQU $RACE Ogre] ]
R:0:0x93/0x8C
?:[AND [EQU $CLASS Wizard] [EQU $RACE Half-Giant] ]
R:0:0x93/0x8D
?:[AND [EQU $CLASS Wizard] [EQU $RACE Half-Titan] ]
R:0:0x93/0x8E
?:[AND [EQU $CLASS Wizard] [EQU $RACE Cyclops] ]
R:0:0x93/0x8F
?:[AND [EQU $CLASS Wizard] [EQU $RACE Yeek] ]
R:0:0x93/0x90
?:[AND [EQU $CLASS Wizard] [EQU $RACE RohanKnight] ]
R:0:0x93/0x91
?:[AND [EQU $CLASS Wizard] [EQU $RACE Kobold] ]
R:0:0x93/0x92
?:[AND [EQU $CLASS Wizard] [EQU $RACE Nibelung] ]
R:0:0x93/0x93
?:[AND [EQU $CLASS Wizard] [EQU $RACE Dark Elf] ]
R:0:0x93/0x94
?:[AND [EQU $CLASS Wizard] [EQU $RACE Thunderlord] ]
R:0:0x93/0x95
?:[AND [EQU $CLASS Wizard] [EQU $RACE Mindflayer] ]
R:0:0x93/0x96
?:[AND [EQU $CLASS Wizard] [EQU $RACE Imp] ]
R:0:0x93/0x97
?:[AND [EQU $CLASS Wizard] [EQU $RACE Ent] ]
R:0:0x93/0x98
?:[AND [EQU $CLASS Wizard] [EQU $RACE Skeleton] ]
R:0:0x93/0x99
?:[AND [EQU $CLASS Wizard] [EQU $RACE Zombie] ]
R:0:0x93/0x9A
?:[AND [EQU $CLASS Wizard] [EQU $RACE Vampire] ]
R:0:0x93/0x9B
?:[AND [EQU $CLASS Wizard] [EQU $RACE Spectre] ]
R:0:0x93/0x9C
?:[AND [EQU $CLASS Wizard] [EQU $RACE Sprite] ]
R:0:0x93/0x9D
?:[AND [EQU $CLASS Wizard] [EQU $RACE DeathMold] ]
R:0:0x93/0x9E

?:[AND [EQU $CLASS Prior] [EQU $RACE Human] ]
R:0:0x94/0x80
?:[AND [EQU $CLASS Prior] [EQU $RACE Half-Elf] ]
R:0:0x94/0x81
?:[AND [EQU $CLASS Prior] [EQU $RACE Elf] ]
R:0:0x94/0x82
?:[AND [EQU $CLASS Prior] [EQU $RACE Hobbit] ]
R:0:0x94/0x83
?:[AND [EQU $CLASS Prior] [EQU $RACE Gnome] ]
R:0:0x94/0x84
?:[AND [EQU $CLASS Prior] [EQU $RACE Dwarf] ]
R:0:0x94/0x85
?:[AND [EQU $CLASS Prior] [EQU $RACE Half-Orc] ]
R:0:0x94/0x86
?:[AND [EQU $CLASS Prior] [EQU $RACE Half-Troll] ]
R:0:0x94/0x87
?:[AND [EQU $CLASS Prior] [EQU $RACE Dunadan] ]
R:0:0x94/0x88
?:[AND [EQU $CLASS Prior] [EQU $RACE High-Elf] ]
R:0:0x94/0x89
?:[AND [EQU $CLASS Prior] [EQU $RACE Dunadan] ]
R:0:0x94/0x8A
?:[AND [EQU $CLASS Prior] [EQU $RACE Barbarian] ]
R:0:0x94/0x8B
?:[AND [EQU $CLASS Prior] [EQU $RACE Ogre] ]
R:0:0x94/0x8C
?:[AND [EQU $CLASS Prior] [EQU $RACE Half-Giant] ]
R:0:0x94/0x8D
?:[AND [EQU $CLASS Prior] [EQU $RACE Half-Titan] ]
R:0:0x94/0x8E
?:[AND [EQU $CLASS Prior] [EQU $RACE Cyclops] ]
R:0:0x94/0x8F
?:[AND [EQU $CLASS Prior] [EQU $RACE Yeek] ]
R:0:0x94/0x90
?:[AND [EQU $CLASS Prior] [EQU $RACE RohanKnight] ]
R:0:0x94/0x91
?:[AND [EQU $CLASS Prior] [EQU $RACE Kobold] ]
R:0:0x94/0x92
?:[AND [EQU $CLASS Prior] [EQU $RACE Nibelung] ]
R:0:0x94/0x93
?:[AND [EQU $CLASS Prior] [EQU $RACE Dark Elf] ]
R:0:0x94/0x94
?:[AND [EQU $CLASS Prior] [EQU $RACE Thunderlord] ]
R:0:0x94/0x95
?:[AND [EQU $CLASS Prior] [EQU $RACE Mindflayer] ]
R:0:0x94/0x96
?:[AND [EQU $CLASS Prior] [EQU $RACE Imp] ]
R:0:0x94/0x97
?:[AND [EQU $CLASS Prior] [EQU $RACE Ent] ]
R:0:0x94/0x98
?:[AND [EQU $CLASS Prior] [EQU $RACE Skeleton] ]
R:0:0x94/0x99
?:[AND [EQU $CLASS Prior] [EQU $RACE Zombie] ]
R:0:0x94/0x9A
?:[AND [EQU $CLASS Prior] [EQU $RACE Vampire] ]
R:0:0x94/0x9B
?:[AND [EQU $CLASS Prior] [EQU $RACE Spectre] ]
R:0:0x94/0x9C
?:[AND [EQU $CLASS Prior] [EQU $RACE Sprite] ]
R:0:0x94/0x9D
?:[AND [EQU $CLASS Prior] [EQU $RACE DeathMold] ]
R:0:0x94/0x9E

?:[AND [EQU $CLASS Possessor] [EQU $RACE Human] ]
R:0:0x92/0x80
?:[AND [EQU $CLASS Possessor] [EQU $RACE Half-Elf] ]
R:0:0x92/0x81
?:[AND [EQU $CLASS Possessor] [EQU $RACE Elf] ]
R:0:0x92/0x82
?:[AND [EQU $CLASS Possessor] [EQU $RACE Hobbit] ]
R:0:0x92/0x83
?:[AND [EQU $CLASS Possessor] [EQU $RACE Gnome] ]
R:0:0x92/0x84
?:[AND [EQU $CLASS Possessor] [EQU $RACE Dwarf] ]
R:0:0x92/0x85
?:[AND [EQU $CLASS Possessor] [EQU $RACE Half-Orc] ]
R:0:0x92/0x86
?:[AND [EQU $CLASS Possessor] [EQU $RACE Half-Troll] ]
R:0:0x92/0x87
?:[AND [EQU $CLASS Possessor] [EQU $RACE Dunadan] ]
R:0:0x92/0x88
?:[AND [EQU $CLASS Possessor] [EQU $RACE High-Elf] ]
R:0:0x92/0x89
?:[AND [EQU $CLASS Possessor] [EQU $RACE Dunadan] ]
R:0:0x92/0x8A
?:[AND [EQU $CLASS Possessor] [EQU $RACE Barbarian] ]
R:0:0x92/0x8B
?:[AND [EQU $CLASS Possessor] [EQU $RACE Ogre] ]
R:0:0x92/0x8C
?:[AND [EQU $CLASS Possessor] [EQU $RACE Half-Giant] ]
R:0:0x92/0x8D
?:[AND [EQU $CLASS Possessor] [EQU $RACE Half-Titan] ]
R:0:0x92/0x8E
?:[AND [EQU $CLASS Possessor] [EQU $RACE Kobold] ]
R:0:0x92/0x92
?:[AND [EQU $CLASS Possessor] [EQU $RACE Nibelung] ]
R:0:0x92/0x93
?:[AND [EQU $CLASS Possessor] [EQU $RACE Dark Elf] ]
R:0:0x92/0x94
?:[AND [EQU $CLASS Possessor] [EQU $RACE RohanKnight] ]
R:0:0x93/0x91
?:[AND [EQU $CLASS Possessor] [EQU $RACE Thunderlord] ]
R:0:0x92/0x95
?:[AND [EQU $CLASS Possessor] [EQU $RACE Mindflayer] ]
R:0:0x92/0x96
?:[AND [EQU $CLASS Possessor] [EQU $RACE Imp] ]
R:0:0x92/0x97
?:[AND [EQU $CLASS Possessor] [EQU $RACE Ent] ]
R:0:0x92/0x98
?:[AND [EQU $CLASS Possessor] [EQU $RACE Skeleton] ]
R:0:0x92/0x99
?:[AND [EQU $CLASS Possessor] [EQU $RACE Zombie] ]
R:0:0x92/0x9A
?:[AND [EQU $CLASS Possessor] [EQU $RACE Vampire] ]
R:0:0x92/0x9B
?:[AND [EQU $CLASS Possessor] [EQU $RACE Spectre] ]
R:0:0x92/0x9C
?:[AND [EQU $CLASS Possessor] [EQU $RACE Sprite] ]
R:0:0x92/0x9D
?:[AND [EQU $CLASS Possessor] [EQU $RACE DeathMold] ]
R:0:0x92/0x9E

tome-235-src/lib/pref/font-ibm.prf0000644000076400017500000001021611012107762014613 0ustar  dgdg# File: font-ibm.prf

#
# This file is used by Angband (when it was compiled using "main-ibm.c")
# to specify simple attr/char remappings using a standard font, allowing
# the use of the IBM's built in pseudo-graphic pictures for walls and such.
#


##### Feature attr/char definitions #####

# open floor
F:1:0x01/0xF9

# fountain
F:2:0x01/0xF4

# fountain
F:15:0x08/0xF4

# web
F:16:0x0B/0xB2

# secret door
F:48:0x01/0xB1

# magma vein
F:50:0x02/0xB0

# quartz vein
F:51:0x01/0xB0

# magma vein
F:52:0x02/0xB0

# quartz vein
F:53:0x01/0xB0

# magma vein with treasure
F:54:0x03/0xB0

# quartz vein with treasure
F:55:0x03/0xB0

# granite wall
F:56:0x01/0xB1

# granite wall
F:57:0x01/0xB1

# granite wall
F:58:0x01/0xB1

# granite wall
F:59:0x01/0xB1

# permanent wall
F:60:0x01/0xB1

# permanent wall
F:61:0x01/0xB1

# permanent wall
F:62:0x01/0xB1

# permanent wall
F:63:0x01/0xB1

# Straight Road startpoint
F:65:0x01/0xB2

# section of the Straight Road
F:66:0x0E/0xB2

# section of the Straight Road
F:67:0x06/0xB2

# section of the Straight Road
F:68:0x0E/0xB2

# section of the Straight Road
F:69:0x06/0xB2

# section of the Straight Road
F:70:0x09/0xB2

# section of the Straight Road (discharged)
F:71:0x09/0xB2

# Straight Road exit
F:72:0x01/0xB2

# corrupted section of the Straight Road
F:73:0x08/0xB2

# permanent wall
F:75:0x01/0xB1

# permanent wall
F:76:0x01/0xB1

# permanent wall
F:77:0x01/0xB1

# permanent wall
F:78:0x01/0xB1

# stream of shallow water
F:84:0x0E/0xF7

# pool of deep lava
F:85:0x0C/0xF7

# stream of shallow lava
F:86:0x04/0xF7

# dark pit
F:87:0x08/0xDB

# dirt
F:88:0x0F/0xF9

# patch of grass
F:89:0x0D/0xF9

# ice
F:90:0x09/0xDB

# sand
F:91:0x0B/0xF9

# dead tree
F:92:0x08/0x9D

# ash
F:93:0x02/0xF9

# mud
F:94:0x07/0xF9

# ice wall
F:95:0x09/0xB1

# tree
F:96:0x0D/0x9D

# sandwall
F:98:0x0B/0xB1

# sandwall
F:99:0x0B/0xB1

# sandwall with treasure
F:100:0x03/0xB1

# nether mist
F:102:0x0A/0xB2

# Void Jumpgate
F:160:0x0A/0xEF

# Altar of Being
F:161:0x09/0xD2

# Altar of Winds
F:162:0x0E/0xD2

# Altar of Force
F:163:0x0C/0xD2

# Altar of Darkness
F:164:0x08/0xD2

# floor
F:172:0x01/0xF9

# Underground Tunnel
F:173:0x02/0xB0

# stream of tainted water
F:174:0x07/0xF7

# Void Jumpgate
F:176:0x0A/0xEF

# lava wall
F:177:0x0C/0xB1

# Great Fire
F:178:0x0A/0xF7

# field
F:181:0x05/0xF9

# Ekkaia, the Encircling Sea
F:182:0x06/0xF7

# pool of deep water
F:187:0x06/0xF7

# glass wall
F:188:0x0E/0xDB

# illusion wall
F:189:0x01/0xB1

# Grass roof
F:190:0x0B/0xB1

# grass roof top
F:191:0x0B/0xB1

# grass roof chimney
F:192:0x0B/0xB1

# brick roof
F:193:0x04/0xB1

# brick roof top
F:194:0x04/0xB1

# brick roof chimney
F:195:0x04/0xB1

# window
F:196:0x01/0x4F

# small window
F:197:0x01/0x6F

# rain barrel
F:198:0x01/0xB1

# cobblestone road
F:200:0x01/0xF9

# cobblestone with outlet
F:201:0x01/0xF9

# small tree
F:202:0x05/0x9D

# Underground Tunnel
F:204:0x0F/0xB0

# a blazing fire
F:205:0x0B/0xF7

# rocky ground
F:207:0x02/0xF9

# cloud-like vapour
F:208:0x09/0xB2

# condensing water
F:209:0x0E/0xF7

# dense mist
F:210:0x01/0xB2

# hail-stone wall
F:211:0x09/0xB1


##### Monster attr/char definitions #####

# Space monster
R:144:0x00/0xF9

# Old Man Willow
R:206:0x02/0x9D

# Lurker
R:247:0x01/0xF9

# Tangleweed
R:248:0x05/0x9D

# Poison ivy
R:266:0x05/0x9D

# Giant Venus Flytrap
R:317:0x05/0x9D

# Stunwall
R:326:0x09/0xB1

# Huorn
R:329:0x05/0x9D

# Landmine
R:333:0x01/0xF9

# Livingstone
R:336:0x09/0xB1

# Vampiric mist
R:365:0x08/0xB2

# It
R:393:0x09/0xF9

# Xiclotlan
R:396:0x08/0x9D

# Roper
R:426:0x08/0xB1

# Lesser wall monster
R:448:0x09/0xB1

# Chaos tile
R:458:0x0A/0xF9

# Mist giant
R:552:0x0E/0xB2

# Trapper
R:565:0x01/0xF9

# Time bomb
R:567:0x01/0xF9

# Weird fume
R:625:0x0A/0xB2

# Colour out of space
R:678:0x0A/0xF9

# Ent
R:708:0x0D/0x9D

# Quickbeam, the Ent
R:714:0x0D/0x9D

# Greater wall monster
R:718:0x09/0xB1

# Ahtu, Avatar of Nyarlathotep
R:761:0x08/0xB1

# Null, the Living Void
R:803:0x00/0xF9

# Rocket mine
R:870:0x0C/0xF9

# Bouncing mine
R:871:0x0E/0xF9

# Fangorn the Treebeard, Lord of the Ents
R:934:0x0D/0x9D

# The Glass Golem
R:1033:0x09/0xB1

# Golgarach, the Living Rock
R:1035:0x09/0xB1

# Spirit
R:1053:0x09/0xF9


tome-235-src/lib/pref/graf-win.prf0000644000076400017500000000041411012107762014611 0ustar  dgdg# File: graf-win.prf

#
# This file defines special attr/char mappings for use in "graphics" mode
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


# Standard file
?:[EQU $GRAF old]
%:graf-xxx.prf

# New tiles
?:[EQU $GRAF new]
%:graf-new.prf
tome-235-src/lib/pref/trap-xxx.prf0000644000076400017500000001313311012107762014674 0ustar  dgdg# Prf file for use with the 8x8 tiles to define 
# trap image locations. Separated out from main 
# graphics definitions due to the G:T:num:y:x 
# instead of T:num:y:x  (major problems if this
# file is opened in the TileAssigner)

# Weakness Traps
G:T:1:0x82:0x9E
G:T:2:0x82:0x9E
G:T:3:0x82:0x9E

# Intelligence Traps
G:T:4:0x82:0x9E
G:T:5:0x82:0x9E
G:T:6:0x82:0x9E

# Wisdom Traps
G:T:7:0x82:0x9E
G:T:8:0x82:0x9E
G:T:9:0x82:0x9E

# Fumbling Fingers Traps
G:T:10:0x82:0x9E
G:T:11:0x82:0x9E
G:T:12:0x82:0x9E

# Wasting Traps
G:T:13:0x82:0x9E
G:T:14:0x82:0x9E
G:T:15:0x82:0x9E

# Beauty Traps
G:T:16:0x82:0x9E
G:T:17:0x82:0x9E
G:T:18:0x82:0x9E

# Trap of Curse Weapon
G:T:20:0xA2:0x92

# Trap of Curse Armor
G:T:21:0xA2:0x92

# Earthquake Trap
G:T:22:0xA2:0x87

# Poison Needle Trap
G:T:23:0xA2:0x8B

# Summon Monster Trap
G:T:24:0xA2:0x89

# Summon Undead Trap
G:T:25:0xA2:0x89

# Summon Greater Undead Trap
G:T:26:0xA2:0x89

# Teleport Trap
G:T:27:0x8A:0x9C

# Paralyzing Trap
G:T:28:0xA2:0x8B

# Explosive Device
G:T:29:0xA2:0x8B

# Teleport Item Trap
G:T:30:0x8A:0x9C

# Lose Memory Trap
G:T:31:0xA2:0x8B

# Bitter Regret Trap
G:T:32:0xA2:0x8B

# Bowel Cramps Trap
G:T:33:0xA2:0x8B

# Blindness/Confusion Trap
G:T:34:0xA2:0x8B

# Aggravation Trap
G:T:35:0xA2:0x87

# Multiplication Trap
G:T:36:0xA2:0x87

# Steal Item Trap
G:T:37:0xA2:0x92

# Summon Fast Quylthulgs Trap
G:T:38:0xA2:0x89

# Trap of Sinking
G:T:39:0x8A:0x9C

# Trap of Mana Drain
G:T:40:0xA2:0x8B

# Trap of Missing Money
G:T:41:0xA2:0x92

# Trap of No Return
G:T:42:0xA2:0x92

# Trap of Silent Switching
G:T:43:0xA2:0x92

# Trap of Walls
G:T:44:0xA2:0x87

# Trap of Calling Out
G:T:45:0xA2:0x89

# Trap of Sliding
G:T:46:0xA2:0x8B

# Trap of Charges Drain
G:T:47:0xA2:0x92

# Trap of Stair Movement
G:T:48:0xA2:0x87

# Trap of New Trap
G:T:49:0xA2:0x87

# Trap of Scatter Items
G:T:50:0x8A:0x9C

# Trap of Decay
G:T:51:0xA2:0x8B

# Trap of Wasting Wands
G:T:52:0xA2:0x92

# Trap of Filling
G:T:53:0xA2:0x87

# Trap of Drain Speed
G:T:54:0xA2:0x92

# Lightning Bolt Trap
G:T:60:0xA2:0x8C

# Poison Bolt Trap
G:T:61:0xA2:0x8C

# Acid Bolt Trap
G:T:62:0xA2:0x8C

# Cold Bolt Trap
G:T:63:0xA2:0x8C

# Fire Bolt Trap
G:T:64:0xA2:0x8C

# Plasma Bolt Trap
G:T:65:0xA2:0x8C

# Water Bolt Trap
G:T:66:0xA2:0x8C

# Lite Bolt Trap
G:T:67:0xA2:0x8C

# Dark Bolt Trap
G:T:68:0xA2:0x8C

# Shards Bolt Trap
G:T:69:0xA2:0x8C

# Sound Bolt Trap
G:T:70:0xA2:0x8C

# Confusion Bolt Trap
G:T:71:0xA2:0x8C

# Force Bolt Trap
G:T:72:0xA2:0x8C

# Inertia Bolt Trap
G:T:73:0xA2:0x8C

# Mana Bolt Trap
G:T:74:0xA2:0x8C

# Ice Bolt Trap
G:T:75:0xA2:0x8C

# Chaos Bolt Trap
G:T:76:0xA2:0x8C

# Nether Bolt Trap
G:T:77:0xA2:0x8C

# Disenchantment Bolt Trap
G:T:78:0xA2:0x8C

# Nexus  Bolt Trap
G:T:79:0xA2:0x8C

# Time Bolt Trap
G:T:80:0xA2:0x8C

# Gravity Bolt Trap
G:T:81:0xA2:0x8C

# Lightning Ball Trap
G:T:82:0xA2:0x8D

# Poison Ball Trap
G:T:83:0xA2:0x8D

# Acid Ball Trap
G:T:84:0xA2:0x8D

# Cold Ball Trap
G:T:85:0xA2:0x8D

# Fire Ball Trap
G:T:86:0xA2:0x8D

# Plasma Ball Trap
G:T:87:0xA2:0x8D

# Water Ball Trap
G:T:88:0xA2:0x8D

# Light Ball Trap
G:T:89:0xA2:0x8D

# Darkness Ball Trap
G:T:90:0xA2:0x8D

# Shards Ball Trap
G:T:91:0xA2:0x8D

# Sound Ball Trap
G:T:92:0xA2:0x8D

# Confusion Ball Trap
G:T:93:0xA2:0x8D

# Force Ball Trap
G:T:94:0xA2:0x8D

# Inertia Ball Trap
G:T:95:0xA2:0x8D

# Mana Ball Trap
G:T:96:0xA2:0x8D

# Ice Ball Trap
G:T:97:0xA2:0x8D

# Chaos Ball Trap
G:T:98:0xA2:0x8D

# Nether Ball Trap
G:T:99:0xA2:0x8D

# Disenchantment Ball Trap
G:T:100:0xA2:0x8D

# Nexus Ball Trap
G:T:101:0xA2:0x8D

# Time Ball Trap
G:T:102:0xA2:0x8D

# Gravity Ball Trap
G:T:103:0xA2:0x8D

# Arrow Trap
G:T:110:0xA2:0x8E

# Bolt Trap
G:T:111:0xA2:0x8E

# Seeker Arrow Trap
G:T:112:0xA2:0x8E

# Seeker Bolt Trap
G:T:113:0xA2:0x8E

# Poison Arrow Trap
G:T:114:0xA2:0x8E

# Poison Bolt Trap
G:T:115:0xA2:0x8E

# Poison Seeker Arrow Trap
G:T:116:0xA2:0x8E

# Poison Seeker Bolt Trap
G:T:117:0xA2:0x8E

# Broken Dagger Trap
G:T:118:0xA2:0x8E

# Dagger Trap
G:T:119:0xA2:0x8E

# Poison Broken Dagger Trap
G:T:120:0xA2:0x8E

# Poison Dagger Trap
G:T:121:0xA2:0x8E

# Arrows Trap
G:T:122:0xA2:0x8E

# Bolts Trap
G:T:123:0xA2:0x8E

# Seeker Arrow Trap
G:T:124:0xA2:0x8E

# Seeker Bolt Trap
G:T:125:0xA2:0x8E

# Poison Arrows Trap
G:T:126:0xA2:0x8E

# Poison Bolt Trap
G:T:127:0xA2:0x8E

# Poison Seeker Arrows Trap
G:T:128:0xA2:0x8E

# Poison Seeker Bolts Trap
G:T:129:0xA2:0x8E

# Broken Daggers Trap
G:T:130:0xA2:0x8E

# Dagger Trap
G:T:131:0xA2:0x8E

# Poison Broken Daggers Trap
G:T:132:0xA2:0x8E

# Poison Daggers Trap
G:T:133:0xA2:0x8E

# Trap of Drop Item
G:T:140:0xA2:0x92

# Trap of Drop Items
G:T:141:0xA2:0x92

# Trap of Drop Everything
G:T:142:0xA2:0x92

# Trap of Femininity
G:T:150:0xA2:0x8B

# Trap of Masculinity
G:T:151:0xA2:0x8B

# Trap of Neutrality
G:T:152:0xA2:0x8B

# Trap of Aging
G:T:153:0xA2:0x8B

# Trap of Growing
G:T:154:0xA2:0x8B

# Trap of Shrinking
G:T:155:0xA2:0x8B

# Trap of Tanker Drain
G:T:157:0xA2:0x8B

# Trap of Divine Anger
G:T:158:0xA2:0x88

# Trap of Divine Wrath
G:T:159:0xA2:0x88

# Hallucination Trap
G:T:160:0xA2:0x8B

# Greater Magic Missile Trap
G:T:161:0xA2:0x8C

# Foulness Trap
G:T:162:0xA2:0x8C

# Trap of Death Ray
G:T:163:0xA2:0x8C

# Trap of Holy Fire
G:T:164:0xA2:0x8C

# Trap of Hell Fire
G:T:165:0xA2:0x8C

# Psi Bolt Trap
G:T:166:0xA2:0x8C

# Psi Drain Trap
G:T:167:0xA2:0x8B

# Plasma (Nuke) Ball Trap
G:T:168:0xA2:0x8D

# Psi Ball Trap
G:T:169:0xA2:0x8D

# Aquirement Trap
G:T:170:0xA2:0x89

# Greater Lightning Bolt Trap
G:T:171:0xA2:0x8C

# Greater Poison Bolt Trap
G:T:172:0xA2:0x8C

# Greater Acid Bolt Trap
G:T:173:0xA2:0x8C

# Greater Cold Bolt Trap
G:T:174:0xA2:0x8C

# Greater Fire Bolt Trap
G:T:175:0xA2:0x8Ctome-235-src/lib/pref/pref-gcu.prf0000644000076400017500000000123311012107762014607 0ustar  dgdg# File: pref-gcu.prf

#
# This file may be included by "pref.prf", when using "main-gcu.prf".
#
# It contains macro definitions to allow the VT100 cursor keys to be
# recognized by Angband.  This will also make the "escape" key take a
# few seconds to recognize, so you may want to use the "`" key instead.
#


### VT100 Keypad ###


# Special keypad keys (delete, insert)

A:.
P:\e[3~

A:0
P:\e[2~


# Numerical keypad keys (map to appropriate number)

A:1
P:\e[4~
P:\e[F

A:2
P:\e[B

A:3
P:\e[6~

A:4
P:\e[D

A:5
P:\e[G

A:6
P:\e[C

A:7
P:\e[1~
P:\e[H

A:8
P:\e[A

A:9
P:\e[5~


# Basic function keys (F1 - F4)

A:\e
P:\eOP

A:\e
P:\eOQ

A:\e
P:\eOR

A:\e
P:\eOS


tome-235-src/lib/pref/graf-iso.prf0000644000076400017500000022610611012107762014616 0ustar  dgdg%:trap-iso.prf

# General Store
B:0:0x80:0xB1

# Armoury
B:1:0x80:0xB2

# Weapon Smiths
B:2:0x80:0xB3

# Temple
B:3:0x80:0xB4

# Alchemy Shop
B:4:0x80:0xB5

# Magic Shop
B:5:0x80:0xB6

# Black Market
B:6:0x80:0xB7

# Home
B:7:0x80:0xB8

# Bookstore
B:8:0x80:0xB9

# Pet shop
B:9:0x80:0xAB

# Mayors office
B:10:0x80:0xAB

# Inn
B:11:0x80:0xB0

# The Soothsayer
B:12:0x80:0xAB

# Library
B:13:0x80:0xAB

# Castle
B:14:0x80:0xAB

# Casino
B:15:0x80:0xAB

# Beastmaster Shanty
B:16:0x80:0xAB

# Fighters Hall
B:17:0x80:0xAB

# Tower of Magery
B:18:0x80:0xAB

# Inner Temple
B:19:0x80:0xAB

# Paladins Guild
B:20:0x80:0xAB

# Rangers Guild
B:21:0x80:0xAB

# Thunderlords' Hide
B:22:0x80:0xAB

# The Mirror
B:23:0x80:0xAB

# Seat of Ruling
B:24:0x80:0xAB

# Wizards Spire
B:25:0x80:0xAB

# Priests Circle
B:26:0x80:0xAB

# Tower of the King
B:27:0x80:0xAB

# Library
B:28:0x80:0xAB

# The White Tree
B:29:0x80:0xAB

# Craftsmaster
B:30:0x80:0xAB

# Earth-Dome (Nature)
B:31:0x80:0xAB

# Minstrels Haven
B:32:0x80:0xAB

# Star-Dome
B:33:0x80:0xAB

# Valarin Temple
B:34:0x80:0xAB

# Sea-Dome
B:35:0x80:0xAB

# The Golden Flower
B:36:0x80:0xAB

# The Fountain
B:37:0x80:0xAB

# Axe Smith
B:38:0x80:0xAB

# Hafted Smith
B:39:0x80:0xAB

# Polearm Smith
B:40:0x80:0xAB

# Sword Smith
B:41:0x80:0xAB

# Rare Jewelry Shop
B:42:0x80:0xAB

# Jewelry Shop
B:43:0x80:0xAB

# Footwear Shop
B:44:0x80:0xAB

# Rare Footwear Shop
B:45:0x80:0xAB

# Library
B:46:0x80:0xAB

# Forbidden Library
B:47:0x80:0xAB

# Expensive Black Market
B:48:0x80:0xAB

# Common Shop
B:49:0x80:0xAB

# Dragon Hunter
B:50:0x80:0xAB

# Speed Ring Market
B:51:0x80:0xAB

# Scribe
B:52:0x80:0xAB

# Potion Store
B:53:0x80:0xAB

# Recaller
B:54:0x80:0xAB

# Master Archer
B:55:0x80:0xAB

# Merchants Guild
B:56:0x80:0xAB

# The Mathom-house
B:57:0x80:0xAB

# The Prancing Pony
B:58:0x80:0xAB

# nothing
F:0:0x80:0xA0

# open floor
F:1:0x82:0xBC

# fountain
F:2:0x81:0x8D

# glyph of warding
F:3:0x8A:0xE1

# open door
F:4:0x80:0xA7

# broken door
F:5:0x80:0xA7

# up staircase
F:6:0x80:0xBC

# down staircase
F:7:0x80:0xBE

# quest entrance
F:8:0x80:0xBE

# quest exit
F:9:0x80:0xBC

# quest down level
F:10:0x80:0xBE

# quest up level
F:11:0x80:0xBC

# town exit
F:12:0x80:0xBE

# shaft down
F:13:0x80:0xBE

# shaft up
F:14:0x80:0xBC

# fountain
F:15:0x81:0x8D

# web
F:15:0x81:0x8D

# trap
F:17:0x8A:0xF9

# visible trap -- spiked pit
F:18:0x8A:0xF9

# visible trap -- poison pit
F:19:0x8A:0xF8

# visible trap -- rune -- summon
F:20:0x8A:0xF8

# visible trap -- rune -- teleport
F:21:0x8A:0xF8

# visible trap -- spot -- fire
F:22:0x8A:0xFD

# visible trap -- spot -- acid
F:23:0x8A:0xFA

# visible trap -- dart -- slow
F:24:0x8A:0xF3

# visible trap -- dart -- lose str
F:25:0x8A:0xF3

# visible trap -- dart -- lose dex
F:26:0x8A:0xF3

# visible trap -- dart -- lose con
F:27:0x8A:0xF3

# visible trap -- gas -- blind
F:28:0x8A:0xF6

# visible trap -- gas -- confuse
F:29:0x8A:0xF6

# visible trap -- gas -- poison
F:30:0x8A:0xF6

# visible trap -- gas -- sleep
F:31:0x8A:0xF6

# door
F:32:0x80:0xAB

# locked door
F:33:0x80:0xAB

# locked door
F:34:0x80:0xAB

# locked door
F:35:0x80:0xAB

# locked door
F:36:0x80:0xAB

# locked door
F:37:0x80:0xAB

# locked door
F:38:0x80:0xAB

# locked door
F:39:0x80:0xAB

# jammed door
F:40:0x80:0xAB

# jammed door
F:41:0x80:0xAB

# jammed door
F:42:0x80:0xAB

# jammed door
F:43:0x80:0xAB

# jammed door
F:44:0x80:0xAB

# jammed door
F:45:0x80:0xAB

# jammed door
F:46:0x80:0xAB

# jammed door
F:47:0x80:0xAB

# secret door
F:48:0x80:0xA3

# pile of rubble
F:49:0x8A:0xEF

# magma vein
F:50:0x80:0xA5

# quartz vein
F:51:0x81:0xF3

# magma vein
F:52:0x81:0xF3

# quartz vein
F:53:0x81:0xF3

# magma vein with treasure
F:54:0x80:0xAA

# quartz vein with treasure
F:55:0x80:0xAA

# granite wall
F:56:0x81:0xF0

# granite wall
F:57:0x81:0xF0

# granite wall
F:58:0x81:0xF0

# granite wall
F:59:0x81:0xF0

# permanent wall
F:60:0x81:0xF3

# permanent wall
F:61:0x81:0xF3

# permanent wall
F:62:0x81:0xF3

# permanent wall
F:63:0x81:0xF3

# explosive rune
F:64:0x80:0xAA

# Straight Road startpoint
F:65:0x80:0xAA

# section of the Straight Road
F:66:0x80:0xAA

# section of the Straight Road
F:67:0x80:0xAA

# section of the Straight Road
F:68:0x80:0xAA

# section of the Straight Road
F:69:0x80:0xAA

# section of the Straight Road
F:70:0x80:0xAA

# section of the Straight Road (discharged)
F:71:0x80:0xAA

# Straight Road exit
F:72:0x80:0xAA

# corrupted section of the Straight Road
F:73:0x80:0xAA

# Building
F:74:0x80:0xB1

# permanent wall
F:75:0x81:0xF3

# permanent wall
F:76:0x81:0xF3

# permanent wall
F:77:0x81:0xF3

# permanent wall
F:78:0x81:0xF3

# stream of shallow water
F:84:0x82:0xEB

# pool of deep lava
F:85:0x82:0xAB

# stream of shallow lava
F:86:0x82:0xAB

# dark pit
F:87:0x83:0x8B

# dirt
F:88:0x82:0xF3

# patch of grass
F:89:0x82:0xE8

# ice
F:90:0x80:0xAE

# sand
F:91:0x80:0xAE

# dead tree
F:92:0x80:0xA3

# ash
F:93:0x80:0xAE

# mud
F:94:0x80:0xAE

# ice wall
F:95:0x80:0x80

# tree
F:96:0x83:0x88

# mountain chain
F:97:0x81:0x9D

# sandwall
F:98:0x80:0xA3

# sandwall
F:99:0x80:0xA5

# sandwall with treasure
F:100:0x80:0xAA

# high mountain chain
F:101:0x80:0xDE

# nether mist
F:102:0x80:0x80

# Void Jumpgate
F:160:0x81:0x8C

# Altar of Being
F:161:0x81:0x94

# Altar of Winds
F:162:0x81:0x94

# Altar of Force
F:163:0x81:0x94

# Altar of Darkness
F:164:0x81:0x94

# Altar of Nature
F:165:0x81:0x94

# Altar of Sun
F:166:0x81:0x94

# Altar of Rage
F:167:0x81:0x94

# Altar of Winds
F:168:0x81:0x94

# Altar of Stars
F:169:0x81:0x94

# Altar of Being
F:170:0x81:0x94

# Altar of Randomness
F:171:0x81:0x94

# floor
F:172:0x80:0x81

# Underground Tunnel
F:173:0x80:0x82

# stream of tainted water
F:174:0x80:0x80

# monster trap
F:175:0x81:0x9C

# Void Jumpgate
F:176:0x80:0x80

# lava wall
F:177:0x80:0x80

# Great Fire
F:178:0x80:0x80

# Path to next area
F:179:0x80:0xBE

# Path to previous area
F:180:0x80:0xBC

# field
F:181:0x80:0x80

# Ekkaia, the Encircling Sea
F:182:0x80:0x80

# Altar of Energy
F:183:0x80:0x80

# Altar of Matter
F:184:0x80:0x80

# Altar of Being
F:185:0x80:0x80

# Altar of Unbeing
F:186:0x80:0x80

# pool of deep water
F:187:0x82:0xF0

# glass wall
F:188:0x80:0xAE

# illusion wall
F:189:0x80:0xA3

# Grass roof
F:190:0x82:0xF6

# grass roof top
F:191:0x82:0xF6

# grass roof chimney
F:192:0x82:0xF7

# brick roof
F:193:0x82:0xEE

# brick roof top
F:194:0x82:0xEE

# brick roof chimney
F:195:0x82:0xF7

# window
F:196:0x80:0xA3

# small window
F:197:0x80:0xA3

# rain barrel
F:198:0x80:0xA3

# grass with flowers
F:199:0x82:0xF8

# cobblestone road
F:200:0x83:0x83

# cobblestone with outlet
F:201:0x80:0xAE

# small tree
F:202:0x83:0x88

# town
F:203:0x80:0xAA

# Underground Tunnel
F:204:0x80:0x82

# a blazing fire
F:205:0x80:0x80

# pile of rubble
F:206:0x8A:0xEF

# rocky ground
F:207:0x80:0x80

# cloud-like vapour
F:208:0x80:0x80

# condensing water
F:209:0x80:0x80

# dense mist
F:210:0x80:0x80

# hail-stone wall
F:211:0x80:0x80

# dead small tree
F:212:0x80:0x80

# something
K:0:0x80:0x80

# Blindness
K:1:0x86:0x8C

# Paranoia
K:2:0x86:0x8C

# Confusion
K:3:0x86:0x8C

# Hallucination
K:4:0x86:0x8C

# Cure Poison
K:5:0x86:0x8C

# Cure Blindness
K:6:0x86:0x8C

# Cure Paranoia
K:7:0xA6:0xBB

# Cure Confusion
K:8:0x86:0x8C

# Weakness
K:9:0x86:0x8C

# Unhealth
K:10:0x86:0x8C

# Restore Constitution
K:11:0x86:0x8C

# Restoring
K:12:0x86:0x8C

# Stupidity
K:13:0x86:0x8C

# Naivety
K:14:0x86:0x8C

# Poison
K:15:0x86:0x8C

# Sickness
K:16:0x86:0x8C

# Paralysis
K:17:0x86:0x8C

# Restore Strength
K:18:0x86:0x8C

# Disease
K:19:0x86:0x8C

# Cure Serious Wounds
K:20:0x86:0x8C

# & Ration~ of Food
K:21:0x8A:0xBC

# & Hard Biscuit~
K:22:0x8A:0xBA

# & Strip~ of Venison
K:23:0x8A:0xBB

# & Slime Mold~
K:24:0x8A:0xBD

# & Lembas~
K:25:0x8A:0xBE

# & Pint~ of Fine Ale
K:26:0x8A:0xB8

# & Pint~ of Fine Wine
K:27:0x8A:0xB8

# & Mattock~
K:28:0x9E:0xC4

# & Blue Stone~
K:29:0xA6:0x8B

# & Broken Dagger~
K:30:0x88:0xC5

# & Bastard Sword~
K:31:0x88:0xC6

# & Scimitar~
K:32:0x88:0xCF

# & Tulwar~
K:33:0x88:0xCD

# & Broad Sword~
K:34:0x88:0xD0

# & Short Sword~
K:35:0x88:0xCC

# & Blade~ of Chaos
K:36:0x88:0xD6

# & Two-Handed Sword~
K:37:0x88:0xD4

# & Main Gauche~
K:38:0x88:0xC8

# & Cutlass~
K:39:0x88:0xCE

# & Executioner's Sword~
K:40:0x88:0xD5

# & Katana~
K:41:0x88:0xD3

# & Long Sword~
K:42:0x88:0xD1

# & Dagger~
K:43:0x88:0xC7

# & Rapier~
K:44:0x88:0xC9

# & Sabre~
K:45:0x88:0xCB

# & Small Sword~
K:46:0x88:0xCA

# & Broken Sword~
K:47:0x88:0xC6

# & Ball-and-Chain~
K:48:0x88:0xFE

# & Whip~
K:49:0x88:0xD7

# & Flail~
K:50:0x88:0xFB

# & Two-Handed Flail~
K:51:0x88:0xFF

# & Morning Star~
K:52:0x88:0xFC

# & Mace~
K:53:0x88:0xF9

# & Quarterstaff~
K:54:0x88:0xFA

# & War Hammer~
K:55:0x88:0xF8

# & Lead-Filled Mace~
K:56:0x88:0xFD

# & Mace~ of Disruption
K:57:0x89:0x80

# & Lucerne Hammer~
K:58:0x89:0x85

# & Beaked Axe~
K:59:0x89:0x88

# & Glaive~
K:60:0x89:0x8A

# & Halberd~
K:61:0x89:0x8B

# & Awl-Pike~
K:62:0x89:0x83

# & Pike~
K:63:0x89:0x87

# & Spear~
K:64:0x89:0x81

# & Trident~
K:65:0x89:0x82

# & Lance~
K:66:0x89:0x84

# & Great Axe~
K:67:0x89:0x8D

# & Battle Axe~
K:68:0x89:0x86

# & Lochaber Axe~
K:69:0x89:0x8C

# & Broad Axe~
K:70:0x89:0x89

# & Scythe~
K:71:0x89:0x8E

# & Scythe~ of Slicing
K:72:0x89:0x8F

# & Short Bow~
K:73:0x89:0x90

# & Long Bow~
K:74:0x89:0x91

# & Light Crossbow~
K:75:0x89:0x92

# & Heavy Crossbow~
K:76:0x89:0x93

# & Sling~
K:77:0x89:0x94

# & Arrow~
K:78:0x89:0xB8

# & Seeker Arrow~
K:79:0x89:0xB9

# & Bolt~
K:80:0x89:0xBA

# & Seeker Bolt~
K:81:0x89:0xBB

# & Rounded Pebble~
K:82:0x89:0xBC

# & Iron Shot~
K:83:0x89:0xBD

# & Shovel~
K:84:0x8A:0xC7

# & Gnomish Shovel~
K:85:0x8A:0xC8

# & Dwarven Shovel~
K:86:0x8A:0xC9

# & Pick~
K:87:0x8A:0xC4

# & Orcish Pick~
K:88:0x8A:0xC5

# & Dwarven Pick~
K:89:0x8A:0xC9

# & Elven Cloak~
K:90:0x88:0x81

# & Pair~ of Soft Leather Boots
K:91:0x87:0xC6

# & Pair~ of Hard Leather Boots
K:92:0x87:0xC7

# & Pair~ of Metal Shod Boots
K:93:0x87:0xC8

# & Hard Leather Cap~
K:94:0x87:0x90

# & Metal Cap~
K:95:0x87:0x91

# & Iron Helm~
K:96:0x87:0x92

# & Steel Helm~
K:97:0x87:0x93

# & Iron Crown~
K:98:0x87:0x94

# & Golden Crown~
K:99:0x87:0x95

# & Jewel Encrusted Crown~
K:100:0x87:0x96

# & Robe~
K:101:0x88:0x84

# & Filthy Rag~
K:102:0x88:0x83

# Soft Leather Armour~
K:103:0x88:0x85

# Soft Studded Leather~
K:104:0x88:0x86

# Hard Leather Armour~
K:105:0x88:0x87

# Hard Studded Leather~
K:106:0x88:0x88

# Leather Scale Mail~
K:107:0x88:0x89

# Metal Scale Mail~
K:108:0x88:0x8A

# Chain Mail~
K:109:0x88:0x8C

# Rusty Chain Mail~
K:110:0x88:0x8B

# Augmented Chain Mail~
K:111:0x88:0x8E

# Bar Chain Mail~
K:112:0x88:0x8F

# Metal Brigandine Armour~
K:113:0x88:0x90

# Partial Plate Armour~
K:114:0x88:0x91

# Metal Lamellar Armour~
K:115:0x88:0x92

# Full Plate Armour~
K:116:0x88:0x93

# Ribbed Plate Armour~
K:117:0x88:0x94

# Adamantite Plate Mail~
K:118:0x88:0x97

# Mithril Plate Mail~
K:119:0x88:0x96

# Mithril Chain Mail~
K:120:0x88:0x95

# Double Chain Mail~
K:121:0x88:0x8D

# & Shield~ of Deflection
K:122:0x87:0xD0

# & Cloak~
K:123:0x88:0x80

# & Shadow Cloak~
K:124:0x88:0x81

# & Set~ of Leather Gloves
K:125:0x87:0xC9

# & Set~ of Gauntlets
K:126:0x87:0xCA

# & Set~ of Cesti
K:127:0x87:0xCB

# & Small Leather Shield~
K:128:0x87:0xCC

# & Large Leather Shield~
K:129:0x87:0xCD

# & Small Metal Shield~
K:130:0x87:0xCE

# & Large Metal Shield~
K:131:0x87:0xCF

# Strength
K:132:0x85:0xB9

# Dexterity
K:133:0x85:0xBB

# Constitution
K:134:0x85:0xBB

# Intelligence
K:135:0x85:0xBB

# Speed
K:136:0x85:0xBB

# Searching
K:137:0x85:0xBB

# Teleportation
K:138:0x85:0xBB

# Slow Digestion
K:139:0x85:0xBB

# Fire Resistance
K:140:0x85:0xBB

# Cold Resistance
K:141:0x85:0xBB

# Levitation
K:142:0x85:0xBB

# Poison Resistance
K:143:0x85:0xBB

# Free Action
K:144:0x85:0xBB

# Weakness
K:145:0x85:0xBB

# Flames
K:146:0x85:0xBB

# Acid
K:147:0x85:0xBB

# Ice
K:148:0x85:0xBB

# Woe
K:149:0x85:0xBB

# Stupidity
K:150:0x85:0xBB

# Damage
K:151:0x85:0xBB

# Accuracy
K:152:0x85:0xBB

# Protection
K:153:0x85:0xBB

# Aggravate Monster
K:154:0x85:0xBB

# See Invisible
K:155:0x85:0xBB

# Sustain Strength
K:156:0x85:0xBB

# Sustain Intelligence
K:157:0x85:0xBB

# Sustain Wisdom
K:158:0x85:0xBB

# Sustain Constitution
K:159:0x85:0xBB

# Sustain Dexterity
K:160:0x85:0xBB

# Sustain Charisma
K:161:0x85:0xBB

# Slaying
K:162:0x85:0xBB

# Brilliance
K:163:0x86:0xFB

# Charisma
K:164:0x86:0xFB

# Searching
K:165:0x86:0xFB

# Teleportation
K:166:0x86:0xFB

# Slow Digestion
K:167:0x86:0xFB

# Acid Resistance
K:168:0x86:0xFB

# Adornment
K:169:0x86:0xFB

# Double Ring Mail~
K:170:0x88:0x93

# the Magi
K:171:0x86:0xFB

# Doom
K:172:0x86:0xFB

# Enchant Weapon To-Hit
K:173:0x85:0x94

# Enchant Weapon To-Dam
K:174:0x85:0x94

# Enchant Armor
K:175:0x85:0x94

# Identify
K:176:0x85:0x94

# *Identify*
K:177:0x85:0x94

# Rumour
K:178:0x85:0x94

# Chaos
K:179:0x85:0x94

# Remove Curse
K:180:0x85:0x94

# Light
K:181:0x85:0x94

# Fire
K:182:0x85:0x94

# Ice
K:183:0x85:0x94

# Summon Monster
K:184:0x85:0x94

# Phase Door
K:185:0x85:0x94

# Teleportation
K:186:0x85:0x94

# Teleport Level
K:187:0x85:0x94

# Monster Confusion
K:188:0x85:0x94

# Magic Mapping
K:189:0x85:0x94

# Rune of Protection
K:190:0x85:0x94

# *Remove Curse*
K:191:0x85:0x94

# Treasure Detection
K:192:0x85:0x94

# Object Detection
K:193:0x85:0x94

# Trap Detection
K:194:0x85:0x94

# & Sheaf Arrow~
K:195:0x89:0xB9

# & Mithril Shot~
K:196:0x89:0xBD

# Door
K:197:0x85:0x94

# Acquirement
K:198:0x85:0x94

# *Acquirement*
K:199:0x85:0x94

# Mass Genocide
K:200:0x85:0x94

# Detect Invisible
K:201:0x85:0x94

# Aggravate Monster
K:202:0x85:0x94

# Trap Creation
K:203:0x85:0x94

# Trap
K:204:0x85:0x94

# Artifact Creation
K:205:0x85:0x94

# Recharging
K:206:0x85:0x94

# Genocide
K:207:0x85:0x94

# Darkness
K:208:0x85:0x94

# Protection from Evil
K:209:0x85:0x94

# Satisfy Hunger
K:210:0x85:0x94

# Dispel Undead
K:211:0x85:0x94

# *Enchant Weapon*
K:212:0x85:0x94

# Curse Weapon
K:213:0x85:0x94

# *Enchant Armor*
K:214:0x85:0x94

# Curse Armor
K:215:0x85:0x94

# Summon Undead
K:216:0x85:0x94

# Blessing
K:217:0x85:0x94

# Holy Chant
K:218:0x85:0x94

# Holy Prayer
K:219:0x85:0x94

# Word of Recall
K:220:0x85:0x94

# *Destruction*
K:221:0x85:0x94

# Slime Mold Juice
K:222:0x85:0xFD

# Apple Juice
K:223:0x85:0xFD

# Water
K:224:0x85:0xFD

# Strength
K:225:0x85:0xFD

# Weakness
K:226:0x85:0xFD

# Restore Strength
K:227:0x85:0xFD

# Intelligence
K:228:0x85:0xFD

# Stupidity
K:229:0x85:0xFD

# Restore Intelligence
K:230:0x85:0xFD

# Wisdom
K:231:0x85:0xFD

# Naivety
K:232:0x85:0xFD

# Restore Wisdom
K:233:0x85:0xFD

# Charisma
K:234:0x85:0xFD

# Ugliness
K:235:0x85:0xFD

# Restore Charisma
K:236:0x85:0xFD

# Curing
K:237:0x85:0xFD

# Invulnerability
K:238:0x85:0xFD

# New Life
K:239:0x85:0xFD

# Cure Serious Wounds
K:240:0x85:0xFD

# Cure Critical Wounds
K:241:0x85:0xFD

# Healing
K:242:0x85:0xFD

# Constitution
K:243:0x85:0xFD

# Experience
K:244:0x85:0xFD

# Sleep
K:245:0x85:0xFD

# Blindness
K:246:0x85:0xFD

# Booze
K:247:0x85:0xFD

# Poison
K:248:0x85:0xFD

# Speed
K:249:0x85:0xFD

# Slowness
K:250:0x85:0xFD

# Dexterity
K:251:0x85:0xFD

# Restore Dexterity
K:252:0x85:0xFD

# Restore Constitution
K:253:0x85:0xFD

# Lose Memories
K:254:0x85:0xFD

# Salt Water
K:255:0x85:0xFD

# Enlightenment
K:256:0x85:0xFD

# Heroism
K:257:0x85:0xFD

# Berserk Strength
K:258:0x85:0xFD

# Boldness
K:259:0x85:0xFD

# Restore Life Levels
K:260:0x85:0xFD

# Resist Heat
K:261:0x85:0xFD

# Resist Cold
K:262:0x85:0xFD

# Detect Invisible
K:263:0x85:0xFD

# Slow Poison
K:264:0x85:0xFD

# Neutralise Poison
K:265:0x85:0xFD

# Restore Mana
K:266:0x85:0xFD

# Infra-vision
K:267:0x85:0xFD

# Resistance
K:268:0x85:0xFD

# Spell
K:269:0x86:0xCB

# Manathrust
K:270:0x86:0xCB

# Fireflash
K:271:0x86:0xCB

# Firewall
K:272:0x86:0xCB

# Tidal Wave
K:273:0x86:0xCB

# Ice Storm
K:274:0x86:0xCB

# Noxious Cloud
K:275:0x86:0xCB

# Poison Blood
K:276:0x86:0xCB

# Thunderstorm
K:277:0x86:0xCB

# Dig
K:278:0x86:0xCB

# Stone Prison
K:279:0x86:0xCB

# Strike
K:280:0x86:0xCB

# Teleport Away
K:281:0x86:0xCB

# Summon Animal
K:282:0x86:0xCB

# Magelock
K:283:0x86:0xCB

# Slow Monster
K:284:0x86:0xCB

# Essence of Speed
K:285:0x9F:0x84

# Banishment
K:286:0x86:0xCB

# Disperse Magic
K:287:0x86:0xCB

# Charm
K:288:0x86:0xCB

# Confuse
K:289:0x86:0xCB

# Demon Blade
K:290:0x86:0xCB

# Heal Monster
K:291:0x86:0xCB

# Haste Monster
K:292:0x86:0xCB

# & Flight Arrow~
K:293:0x89:0xB9

# Acid Bolts
K:294:0x86:0xCB

# Dragon's Flame
K:295:0x86:0xCB

# Dragon's Frost
K:296:0x86:0xCB

# Dragon's Breath
K:297:0x86:0xCB

# Annihilation
K:298:0x86:0xCB

# Rockets
K:299:0x86:0xCB

# Spell
K:300:0x87:0x8A

# Nothing
K:301:0x87:0x8A

# Globe of Light
K:302:0x87:0x8A

# Fiery Shield
K:303:0x87:0x8A

# Remove Curses
K:304:0x87:0x8A

# Wings of Winds
K:305:0x87:0x8A

# Shake
K:306:0x87:0x8A

# Disarm
K:307:0x87:0x8A

# Teleportation
K:308:0x87:0x8A

# Probability Travel
K:309:0x87:0x8A

# Recovery
K:310:0x87:0x8A

# Healing
K:311:0x87:0x8A

# Vision
K:312:0x87:0x8A

# Identify
K:313:0x87:0x8A

# Sense Hidden
K:314:0x87:0x8A

# Reveal Ways
K:315:0x87:0x8A

# Sense Monsters
K:316:0x87:0x8A

# Genocide
K:317:0x87:0x8A

# Summon
K:318:0x87:0x8A

# Curing
K:319:0x87:0x8A

# Wish
K:320:0x87:0x8A

# Mana
K:321:0x87:0x8A

# Darkness
K:322:0x87:0x8A

# Genocide
K:323:0x87:0x8A

# Power
K:324:0x87:0x8A

# the Magi
K:325:0x87:0x8A

# Perception
K:326:0x87:0x8A

# Holiness
K:327:0x87:0x8A

# Enlightenment
K:328:0x87:0x8A

# Healing
K:329:0x87:0x8A

# & Tome~ of Magical Energy
K:330:0x8B:0xD8

# & Tome~ of the Eternal Flame
K:331:0x8B:0xD9

# & Tome~ of the Blowing Wind
K:332:0x8B:0xDA

# & Tome~ of the Impenetrable Earth
K:333:0x8B:0xDB

# & Tome~ of the Everrunning Wave
K:334:0x8B:0xDC

# & Tome~ of Translocation
K:335:0x8B:0xDD

# & Tome~ of the Tree
K:336:0x8B:0xDE

# & Tome~ of Knowledge
K:337:0x8B:0xDF

# & Small wooden chest~
K:338:0x85:0xD1

# & Large wooden chest~
K:339:0x85:0xD2

# & Small iron chest~
K:340:0x85:0xD3

# & Large iron chest~
K:341:0x85:0xD4

# & Small steel chest~
K:342:0x85:0xD5

# & Large steel chest~
K:343:0x85:0xD6

# & Ruined chest~
K:344:0x85:0xD7

# & Iron Spike~
K:345:0x8A:0xC1

# & Wooden Torch~
K:346:0x8A:0xC3

# & Brass Lantern~
K:347:0x8A:0xC2

# & Flask~ of oil
K:348:0x8A:0xC0

# & Empty Bottle~
K:349:0x8A:0xBF

# Havoc
K:350:0x86:0xBB

# Door
K:351:0x86:0xBB

# Trap Location
K:352:0x86:0xBB

# Probing
K:353:0x86:0xBB

# Recall
K:354:0x86:0xBB

# Illumination
K:355:0x86:0xBB

# Light
K:356:0x86:0xBB

# Lightning Bolts
K:357:0x86:0xBB

# Frost Bolts
K:358:0x86:0xBB

# Fire Bolts
K:359:0x86:0xBB

# Polymorph
K:360:0x86:0xBB

# Slow Monster
K:361:0x86:0xBB

# Sleep Monster
K:362:0x86:0xBB

# Drain Life
K:363:0x86:0xBB

# Teleport Other
K:364:0x86:0xBB

# Disarming
K:365:0x86:0xBB

# Lightning Balls
K:366:0x86:0xBB

# Cold Balls
K:367:0x86:0xBB

# Fire Balls
K:368:0x86:0xBB

# Acid Balls
K:369:0x86:0xBB

# Acid Bolts
K:370:0x86:0xBB

# Enlightenment
K:371:0x86:0xBB

# Perception
K:372:0x86:0xBB

# Curing
K:373:0x86:0xBB

# Healing
K:374:0x86:0xBB

# Detection
K:375:0x86:0xBB

# Restoration
K:376:0x86:0xBB

# Speed
K:377:0x86:0xBB

# Spell
K:378:0xA3:0xFC

# Spell
K:379:0x89:0xF8

# [Beings of Darkness]
K:380:0x89:0xF9

# [Material Shadow]
K:381:0x89:0xFA

# [Nature's Wrath]
K:382:0x89:0xFB

# [Sign of Chaos]
K:383:0x89:0xD0

# [Chaos Mastery]
K:384:0x89:0xD1

# [Chaos Channels]
K:385:0x89:0xD2

# [Armageddon Tome]
K:386:0x89:0xD3

# [Nether Openings]
K:387:0x8A:0x80

# [Unholy Blessings]
K:388:0x8A:0x81

# & Firestone~
K:389:0x8A:0xCA

# & Small Firestone~
K:390:0x8A:0xCB

# & Broken Skull~
K:391:0x8A:0xCC

# & Broken Bone~
K:392:0x8A:0xCD

# & Canine Skeleton~
K:393:0x8A:0xD2

# & Rodent Skeleton~
K:394:0x8A:0xD3

# & Human Skeleton~
K:395:0x8A:0xCE

# & Dwarf Skeleton~
K:396:0x8A:0xD0

# & Elf Skeleton~
K:397:0x8A:0xCF

# & Gnome Skeleton~
K:398:0x8A:0xD1

# & Great Hammer~
K:399:0x9E:0xC2

# Black Dragon Scale Mail~
K:400:0x88:0xBA

# Blue Dragon Scale Mail~
K:401:0x88:0xB8

# White Dragon Scale Mail~
K:402:0x88:0xB9

# Red Dragon Scale Mail~
K:403:0x88:0xBB

# Green Dragon Scale Mail~
K:404:0x88:0xBC

# Multi-Hued Dragon Scale Mail~
K:405:0x88:0xC3

# Pseudo Dragon Scale Mail~
K:406:0x88:0xBF

# Law Dragon Scale Mail~
K:407:0x88:0xC1

# Bronze Dragon Scale Mail~
K:408:0x88:0xBD

# Gold Dragon Scale Mail~
K:409:0x88:0xBE

# Chaos Dragon Scale Mail~
K:410:0x88:0xC0

# Balance Dragon Scale Mail~
K:411:0x88:0xC2

# Power Dragon Scale Mail~
K:412:0x88:0xC4

# & Dragon Helm~
K:413:0x87:0xBA

# & Dragon Shield~
K:414:0x87:0xD4

# Death
K:415:0x85:0xFD

# Ruination
K:416:0x85:0xFD

# Detonations
K:417:0x85:0xFD

# Augmentation
K:418:0x85:0xFD

# *Healing*
K:419:0x85:0xFD

# Life
K:420:0x85:0xFD

# Self Knowledge
K:421:0x85:0xFD

# *Enlightenment*
K:422:0x85:0xFD

# [Necromantic Incantations]
K:423:0x8A:0x82

# [Curses of Angmar]
K:424:0x8A:0x83

# Fear Resistance
K:425:0x85:0xBB

# Light and Darkness Resistance
K:426:0x85:0xBB

# Nether Resistance
K:427:0x85:0xBB

# Nexus Resistance
K:428:0x85:0xBB

# Sound Resistance
K:429:0x85:0xBB

# Confusion Resistance
K:430:0x85:0xBB

# Shard Resistance
K:431:0x85:0xBB

# Disenchantment Resistance
K:432:0x85:0xBB

# Chaos Resistance
K:433:0x85:0xBB

# Blindness Resistance
K:434:0x85:0xBB

# Lordly Protection
K:435:0x85:0xBB

# Extra Attacks
K:436:0x85:0xBB

# Cure Light Wounds
K:437:0x85:0xFD

# Clumsiness
K:438:0x85:0xFD

# Sickliness
K:439:0x85:0xFD

# Map of Bree
K:440:0xA5:0xB8

# Map of Gondolin
K:441:0xA5:0xB8

# Map of Lothlorien
K:442:0xA5:0xB8

# Map of Minas Anor
K:443:0xA5:0xB8

# & Silver Arrow~
K:465:0xA6:0xB9

# & Silver Bolt~
K:466:0xA6:0xBA

# Lightning Resistance
K:467:0x86:0xF8

# Wisdom
K:468:0x86:0xF8

# Regeneration
K:469:0x86:0xF8

# Infravision
K:470:0x86:0xF8

# Devotion
K:471:0x86:0xF8

# Weaponmastery
K:472:0x86:0xF8

# Trickery
K:473:0x86:0xF8

# Telepathy
K:474:0x86:0xF8

# Sustenance
K:475:0x86:0xF8

# & Palantir~
K:476:0xA6:0xBF

# & Elfstone~
K:477:0xA6:0xBB

# & Jewel~
K:478:0xA6:0xBC

# & Ring~
K:479:0xA6:0xBD

# copper
K:480:0x85:0x89

# copper
K:481:0x85:0x89

# copper
K:482:0x85:0x89

# silver
K:483:0x85:0x8A

# silver
K:484:0x85:0x8A

# silver
K:485:0x85:0x8A

# garnets
K:486:0x85:0x8E

# garnets
K:487:0x85:0x8E

# gold
K:488:0x85:0x8B

# gold
K:489:0x85:0x8B

# gold
K:490:0x85:0x8B

# opals
K:491:0x85:0x8F

# sapphires
K:492:0x85:0x90

# rubies
K:493:0x85:0x91

# diamonds
K:494:0x85:0x92

# emeralds
K:495:0x85:0x93

# mithril
K:496:0x85:0x8C

# adamantite
K:497:0x85:0x8D

# & Mighty Hammer~
K:498:0x9E:0xC2

# & Massive Iron Crown~
K:499:0x87:0x94

# & Phial~
K:500:0x8A:0xD5

# & Star~
K:501:0x8A:0xD6

# & Arkenstone~
K:502:0x8A:0xD7

# & Amulet~
K:503:0x85:0xCE

# & Amulet~
K:504:0x85:0xCF

# & Necklace~
K:505:0x85:0xD0

# & Ring~
K:506:0x85:0xC7

# & Ring~
K:507:0x85:0xC8

# & Ring~
K:508:0x85:0xCA

# & Ring~
K:509:0x85:0xCB

# & Ring~
K:510:0x85:0xCC

# & Ring~
K:511:0x85:0xCD

# [Rites of Initiation]
K:512:0x8A:0x88

# [Ways of War]
K:513:0x8A:0x89

# [Divine Retribution]
K:514:0x8A:0x8A

# [Essence of Fury]
K:515:0x8A:0x8B

# [Novice Crafts]
K:516:0x8A:0x84

# [Arcane Channels]
K:517:0x8A:0x85

# [Sigils of Wizardry]
K:518:0x8A:0x86

# [Mana Focus]
K:519:0x8A:0x87

# Reflection
K:520:0x86:0xFB

# Anti-Magic
K:521:0x86:0xFB

# Anti-Teleportation
K:522:0x86:0xFB

# Resistance
K:523:0x86:0xFB

# & Zweihander~
K:524:0x9E:0xC4

# & Dwarven Lantern~
K:525:0xA6:0x8C

# Splint Mail~
K:526:0x88:0x94

# & Everburning Torch~
K:527:0xA6:0x8D

# & Trifurcate Spear~
K:528:0x9E:0xBD

# & Three Piece Rod~
K:529:0x9E:0xB8

# & Feanorian Lamp~
K:530:0xA6:0x8E

# & Fur Cloak~
K:531:0x88:0x81

# Water Curing
K:532:0x9E:0xBE

# & Hatchet~
K:533:0x9E:0xC7

# Rhino Hide Armour~
K:535:0x88:0x90

# Leather Jacket~
K:536:0x88:0x87

# & Sickle~
K:537:0x9E:0xC8

# [Psychoportation]
K:538:0x9E:0xBF

# [Clairsentience]
K:539:0x9E:0xC9

# [Telekinesis]
K:540:0x9E:0xCB

# [Empathy]
K:541:0x9E:0xCA

# & Club~
K:542:0x9E:0xCA

# & Broad Spear~
K:543:0x9E:0xBC

# & Khopesh~
K:544:0x9E:0xCC

# & Flamberge~
K:545:0x9E:0xBB

# & Claymore~
K:546:0x9E:0xC5

# & Espadon~
K:547:0x9E:0xC6

# & Great Scimitar~
K:548:0x9E:0xC3

# Arrow
K:549:0x8A:0xD8

# Bolt
K:550:0x8A:0xD9

# & Fauchard~
K:551:0x9E:0xCD

# & Guisarme~
K:552:0x9E:0xCE

# & Heavy Lance~
K:553:0x9E:0xBA

# & Basillard~
K:554:0x9E:0xD1

# Catapult
K:555:0x8A:0xDA

# Ring Mail~
K:556:0x88:0x94

# Cord Armour~
K:557:0x88:0x88

# Paper Armour~
K:558:0x88:0xB9

# Padded Armour~
K:559:0x88:0x89

# Fumes
K:560:0x8A:0xDB

# Stone and Hide Armour~
K:561:0x88:0x8F

# Magic
K:562:0x8A:0xDC

# Device
K:563:0x8A:0xDD

# Nothing
K:564:0xA6:0xD4

# Poison
K:565:0x9E:0xF8

# Nothing
K:566:0xA6:0xD4

# Nothing
K:567:0xA6:0xD4

# Nothing
K:568:0xA6:0xD4

# Nothing
K:569:0xA6:0xD4

# Explosion
K:570:0x9E:0xF9

# Teleport
K:571:0x9E:0xFA

# Nothing
K:572:0xA6:0xD4

# & Blood~ of Life
K:573:0x85:0xFD

# Cold
K:574:0x9E:0xFB

# Fire
K:575:0x9E:0xFC

# Acid
K:576:0x9E:0xFD

# & Mage Staff~
K:577:0x9F:0xB8

# Lightning
K:578:0x85:0xB8

# Life
K:579:0x9E:0xFE

# Confusion
K:580:0x9E:0xFF

# Light
K:581:0x9F:0x80

# & Ring~
K:582:0x85:0xBD

# Invisibility
K:583:0x85:0xFD

# Chaos
K:584:0x9F:0x81

# Corruption
K:585:0x85:0xFD

# Invisibility
K:586:0x85:0xFD

# Time
K:587:0x9F:0x82

# Deep Thoughts
K:588:0x85:0x94

# More Deep Thoughts
K:589:0x85:0x95

# Compendium of Deep Thoughts
K:590:0x85:0x96

# Artifact Lore Vol. I
K:591:0x85:0x94

# Artifact Lore Vol. II
K:592:0x85:0x95

# Artifact Lore Vol. III
K:593:0x85:0x97

# Monstrous Compendium 1
K:594:0x85:0x97

# Monstrous Compendium 2
K:595:0x85:0x96

# Monstrous Compendium 3
K:596:0x85:0x95

# Monstrous Compendium 4
K:597:0x85:0x94

# Monstrous Compendium 5
K:598:0x85:0x97

# Monstrous Compendium 6
K:599:0x85:0x96

# Monstrous Compendium 7
K:600:0x85:0x95

# Monstrous Compendium 8
K:601:0x85:0x94

# Monstrous Compendium 9
K:602:0x85:0x95

# Monstrous Compendium 10
K:603:0x85:0x96

# Monstrous Compendium 11
K:604:0x85:0x97

# Abomination
K:605:0x85:0xFD

# Shape of Wolf
K:606:0x85:0xFD

# Shape of Ape
K:607:0x85:0xFD

# Shape of Goat
K:608:0x85:0xFD

# Shape of Insect
K:609:0x85:0xFD

# Shape of Sparrow
K:610:0x85:0xFD

# Shape of Ent
K:611:0x85:0xFD

# Shape of Vampire
K:612:0x85:0xFD

# Shape of Spider
K:613:0x85:0xFD

# Shape of Mana ball
K:614:0x85:0xFD

# Shape of Fire cloud
K:615:0x85:0xFD

# Shape of Cold cloud
K:616:0x85:0xFD

# Shape of Chaos cloud
K:617:0x85:0xFD

# [Wolf]
K:618:0x8B:0x98

# [Ape]
K:619:0x8B:0x99

# [Goat]
K:620:0x8B:0x9A

# [Insect]
K:621:0x8B:0x9B

# [Sparrow]
K:622:0x8B:0x9C

# [Ent]
K:623:0x8B:0x9D

# [Vampire]
K:624:0x8B:0x9E

# [Spider]
K:625:0x8B:0x9F

# [Mana ball]
K:626:0x8B:0xA0

# [Fire cloud]
K:627:0x8B:0xA1

# [Cold cloud]
K:628:0x8B:0xA2

# [Chaos Cloud]
K:629:0x8B:0xA3

# [Ghost]
K:630:0x8B:0xA4

# [Kobold]
K:631:0x8B:0xA5

# [Dragon]
K:632:0x8B:0xA6

# [Demon]
K:633:0x8B:0xA7

# [Hound]
K:634:0x8B:0xA8

# [Quylthulg]
K:635:0x8B:0xA9

# [Maia]
K:636:0x8B:0xAA

# [Serpent]
K:637:0x8B:0xAB

# [Giant]
K:638:0x8B:0xAC

# [Vala]
K:639:0x8B:0xAD

# Magic
K:640:0x9F:0x83

# corpse
K:641:0x9F:0xB9

# skeleton
K:642:0x8A:0xCE

# head
K:643:0x8A:0xCC

# skull
K:644:0x8A:0xCC

# raw meat
K:645:0x8A:0xBB

# & Thunderlord Coat~
K:646:0x88:0xBE

# & Stone~
K:647:0x8A:0xD4

# & small wooden Boomerang~
K:648:0x9F:0xBA

# & wooden Boomerang~
K:649:0x9F:0xBB

# & small metal Boomerang~
K:650:0x9F:0xBC

# & metal Boomerang~
K:651:0x9F:0xBD

# & Anchor~
K:652:0x8A:0x96

# & ~
K:653:0xA6:0xD4

# Summon never-moving pet
K:654:0x85:0x95

# [Life in symbiosis]
K:655:0x9F:0xBE

# [Perfect Symbiosis]
K:656:0x9F:0xBE

# Cure Light Insanity
K:657:0x85:0xFD

# Cure Serious Insanity
K:658:0x85:0xFD

# Cure Critical Insanity
K:659:0x85:0xFD

# Cure Insanity
K:660:0x85:0xFD

# & Phial~
K:661:0x8A:0xD5

# Random Artifact
K:662:0xA6:0xD4

# Craftmanship
K:663:0x85:0x97

# The One Ring
K:664:0x85:0x96

# & Book~ of the Lays of the Heroes
K:665:0x9F:0xBF

# & Book~ of Sound Patterns
K:666:0x9F:0xBF

# [Harps of Rivendell]
K:667:0x9F:0xBF

# [Lays of Beleriand]
K:668:0x9F:0xBF

# & Flute~
K:669:0x9F:0xC0

# & Drum~
K:670:0x9F:0xC1

# & Harp~
K:671:0x9F:0xC2

# & Banjo~
K:672:0x9F:0xC4

# & Lute~
K:673:0x9F:0xC3

# & Mandolin~
K:674:0x9F:0xC3

# & Palantir~
K:675:0x8A:0x97

# Egg
K:676:0x9F:0x85

# Reset Recall
K:677:0x85:0x95

# Divination
K:678:0x85:0x95

# Self
K:679:0x9F:0x86

# Ray
K:680:0x9F:0x87

# Sphere
K:681:0x9F:0x88

# Knowledge
K:682:0x9F:0x8C

# Life
K:683:0x9F:0x8D

# Fire
K:684:0x9F:0x8E

# Cold
K:685:0x9F:0x8F

# Lightning
K:686:0x9F:0x90

# Acid
K:687:0x9F:0x91

# Element
K:688:0x9F:0x92

# Chaos
K:689:0x9F:0x93

# Mind
K:690:0x9F:0x94

# Holding
K:691:0x9F:0x95

# Arrow
K:692:0x9F:0x89

# Power Surge
K:693:0x9F:0x8A

# Armageddon
K:694:0x9F:0x8B

# Gravity
K:695:0x9F:0x96

# Extra Life
K:696:0x9F:0x97

# Undeath
K:697:0x9E:0xD3

# Protection
K:698:0x9E:0xD4

# & Horn~
K:699:0x9F:0xC5

# & Ring~ of Precognition
K:700:0x85:0xBB

# & Sprig~ of Athelas
K:701:0x9F:0xC6

# [Magic for Beginners]
K:702:0x9F:0xC7

# [Conjurings and Tricks]
K:703:0x9F:0xC7

# [Incantations and Illusions]
K:704:0x9F:0xC7

# [Sorcery and Evocations]
K:705:0x9F:0xC7

# [Beginners Handbook]
K:706:0x9F:0xC8

# [Words of Wisdom]
K:707:0x9F:0xC8

# [Chants and Blessings]
K:708:0x9F:0xC8

# [Exorcism and Dispelling]
K:709:0x9F:0xC8

# [Resistance of Scarabtarices]
K:710:0x9F:0xCA

# [Mordenkainen's Escapes]
K:711:0x9F:0xCA

# [Kelek's Grimoire of Power]
K:712:0x9F:0xCA

# [Tenser's Transformations]
K:713:0x9F:0xCA

# [Raal's Tome of Destruction]
K:714:0x9F:0xCA

# [Ethereal Openings]
K:715:0x9F:0xCA

# [Godly Insights]
K:716:0x9F:0xC9

# [Purifications and Healing]
K:717:0x9F:0xC9

# [Holy Infusions]
K:718:0x9F:0xC9

# [Wrath of God]
K:719:0x9F:0xC9

# & Old Scroll~ of Deincarnation
K:720:0x85:0x97

# & Dark Sword~
K:721:0xA5:0xB9

# Numenorean for beginners (I)
K:722:0xA3:0xF8

# Numenorean for beginners (II)
K:723:0xA3:0xF9

# Advanced lessons of Numenorean
K:724:0xA3:0xF8

# Advanced lessons of Sindarin
K:725:0xA3:0xF9

# & Shard~ of Pottery
K:726:0x8A:0xCA

# & Broken Stick~
K:727:0x8A:0xCB

# Wall Creation
K:728:0x85:0x97

# [Illusions for Beginners]
K:729:0xA3:0xFA

# [Tricks and Visions]
K:730:0xA3:0xFA

# [Phantasms and Illusions]
K:731:0xA3:0xFA

# [Shadows and Prisms]
K:732:0xA3:0xFA

# [Serten's Immunities]
K:733:0xA3:0xFB

# [Knowledge of Kenault]
K:734:0xA3:0xFB

# [Otiluke's Spheres]
K:735:0xA3:0xFA

# [Boccob's Book of Shadows]
K:736:0xA3:0xFC

# [Bigby's Handbook]
K:737:0xA3:0xFC

# & Book~ of Beginner Cantrips
K:738:0xA3:0xFD

# & Book~ of Teleportation
K:739:0xA3:0xFE

# & Book~ of Recall
K:740:0xA3:0xFF

# & Book~ of Summoning
K:741:0xA3:0xF8

# & Book~ of Fireflash
K:742:0xA3:0xF9

# & Potion~ of Learning
K:743:0xA3:0xFA

# [Eye of Sauron]
K:744:0xA3:0xFB

# [Flame of Udun]
K:745:0xA3:0xFC

# [Corruptions of Melkor]
K:746:0xA3:0xFD

# [Crescent of Morgul]
K:747:0xA3:0xFE

# [Morgoth's Ring]
K:748:0xA3:0xFF

# Spell
K:749:0x86:0xC8

# Wishing
K:750:0x86:0xC8

# Khuzdul - The hidden tongue of the Dwarves
K:751:0x85:0x95

# Nandorin for dummies
K:752:0xA3:0xF9

# Advanced lessons of Orcish
K:753:0xA3:0xFA

# & Ancient Tome~
K:754:0xA3:0xFE

# Flying
K:755:0x85:0xC0

# & Tome~ of the Time
K:756:0xA3:0xF8

# & Spellbook~ of #
K:757:0x8C:0x9C

# & Tome~ of Meta Spells
K:758:0xA3:0xF9

# & Tome~ of the Mind
K:759:0xA3:0xFA

# & Holy Tome~ of Eru Iluvatar
K:760:0xA3:0xFB

# & Holy Tome~ of Manwe Sulimo
K:761:0xA3:0xFC

# & War Tome~ of Tulkas
K:762:0xA3:0xFD

# & Unholy Tome~ of the Hellflame
K:763:0xA3:0xFE

# & Corrupted Tome~ of Melkor
K:764:0xA3:0xFF

# [Aiding Shades]
K:765:0xA3:0xF8

# [Morgoth's Space-Time Warpings]
K:766:0xA3:0xF9

# [Murazor's Tome of Conjuring & Dispelling]
K:767:0xA3:0xFA

# & Forest Tome~ of Yavanna
K:768:0xA3:0xFB

# [Sauron's Forgotten Tome]
K:769:0xA3:0xFF

# & Ring~
K:770:0x85:0xBC

# [Earth]
K:771:0xA4:0x80

# [Fire]
K:772:0xA4:0x81

# [Air]
K:773:0xA4:0x82

# [Water]
K:774:0xA4:0x83

# [Mana]
K:775:0xA4:0x84

# Home Summoning
K:776:0x85:0x97

# & Shadow Blade~
K:777:0xA4:0x89

# & Bluesteel Blade~
K:778:0xA4:0x8A

# the Serpents
K:779:0xA5:0xC0

# Darkness
K:780:0xA5:0xC1

# Knowledge
K:781:0xA5:0xC2

# Force
K:782:0xA5:0xC3

# Lightning
K:783:0xA5:0xC4

# Mana
K:784:0xA5:0xC5

# Ring~ of Power
K:785:0xA5:0xC6

# Climbing Set~
K:786:0xA4:0x8B

# Adventurer's guide to Middle-earth
K:787:0x85:0x96

# & Demonblade~
K:788:0x8B:0xE0

# & Demonshield~
K:789:0x8B:0xE1

# & Demonhorn~
K:790:0x8B:0xE2

# [Demonthoughts]
K:791:0xA3:0xFB

# [Hellfire Tome]
K:792:0xA4:0x8C

# & Wooden Rod~ of#
K:793:0xA4:0x8D

# & Copper Rod~ of#
K:794:0xA4:0x8E

# & Iron Rod~ of#
K:795:0xA4:0x8F

# & Moonstone Rod~ of#
K:796:0xA4:0x90

# & Silver Rod~ of#
K:797:0xA4:0x91

# & Golden Rod~ of#
K:798:0xA4:0x93

# & Mithril Rod~ of#
K:799:0xA4:0x94

# & Adamantite Rod~ of#
K:800:0xA4:0x95

# & Greater Ration~ of Health
K:801:0xA5:0xBF

# & Crumpled Scroll~ of Mass Resurrection
K:802:0x85:0x96

# & Cleaver~
K:803:0xA5:0xBA

# & Light War Axe~
K:804:0xA5:0xBB

# & Slaughter Axe~
K:805:0xA5:0xBC

# & Runestone~
K:806:0xA5:0xBD

# & Fortune cookie~
K:807:0xA6:0xBE

# Portable hole
K:808:0xA6:0xC1

# Critical Hits
K:809:0xA6:0xD4

# & Wand~ of Digging of Thrain
K:810:0xA6:0xD4

# & Gnarled Staff~ of Holy Fire of Mithrandir
K:811:0xA6:0xD4

# Partial Totem
K:812:0xA6:0xD5

# True Totem
K:813:0xA6:0xD6

# & piece~ of a Relic of Eru
K:814:0x89:0xDA

# & piece~ of a Relic of Manwe
K:815:0x89:0xDB

# & piece~ of a Relic of Tulkas
K:816:0x89:0xDC

# & piece~ of a Relic of Melkor
K:817:0x89:0xDD

# & piece~ of a Relic of Yavanna
K:818:0x89:0xDE

# Player
R:0:0x80:0xC0

# Filthy street urchin
R:1:0x98:0xB8

# Scrawny cat
R:2:0x96:0xFA

# Sparrow
R:3:0x9D:0xD6

# Chaffinch
R:4:0x9D:0xD6

# Wild rabbit
R:5:0x9D:0xD7

# Woodsman
R:6:0x98:0xC9

# Scruffy little dog
R:7:0x92:0x92

# Farmer Maggot
R:8:0x98:0xB9

# Blubbering idiot
R:9:0x98:0xBA

# Boil-covered wretch
R:10:0x98:0xBB

# Village idiot
R:11:0x98:0xBC

# Pitiful-looking beggar
R:12:0x98:0xBD

# Mangy-looking leper
R:13:0x98:0xBE

# Agent of the black market
R:14:0x98:0xBF

# Singing, happy drunk
R:15:0x98:0xC0

# Aimless-looking merchant
R:16:0x98:0xC1

# Mean-looking mercenary
R:17:0x98:0xC2

# Battle-scarred veteran
R:18:0x98:0xC3

# Martti Ihrasaari
R:19:0x9B:0xB8

# Grey mold
R:20:0x97:0xD7

# Large white snake
R:21:0x94:0xBD

# Grey mushroom patch
R:22:0x9B:0xB9

# Newt
R:23:0x9B:0xBA

# Giant white centipede
R:24:0x96:0x8D

# White icky thing
R:25:0x97:0xBB

# Clear icky thing
R:26:0x97:0xBC

# Giant white mouse
R:27:0x99:0xBD

# Large brown snake
R:28:0x94:0xBC

# Small kobold
R:29:0x97:0xD1

# Kobold
R:30:0x97:0xD2

# White worm mass
R:31:0x99:0xD5

# Floating eye
R:32:0x96:0xD3

# Rock lizard
R:33:0x94:0xBE

# Grid bug
R:34:0x9B:0xBC

# Jackal
R:35:0x92:0x93

# Soldier ant
R:36:0x95:0xFF

# Fruit bat
R:37:0x96:0x87

# Insect swarm
R:38:0x9E:0x96

# The Greater hell-beast
R:39:0x9B:0xBB

# Shrieker mushroom patch
R:40:0x91:0xFE

# Blubbering icky thing
R:41:0x97:0xBD

# Metallic green centipede
R:42:0x96:0x8E

# Novice warrior
R:43:0x98:0xC4

# Novice rogue
R:44:0x98:0xC5

# Novice priest
R:45:0x98:0xC6

# Novice mage
R:46:0x98:0xC7

# Yellow mushroom patch
R:47:0x91:0xFF

# White jelly
R:48:0x97:0xC2

# Giant black ant
R:49:0x96:0x80

# Salamander
R:50:0x94:0xC0

# White harpy
R:51:0x93:0xC0

# Blue yeek
R:52:0x99:0xFF

# Grip, Farmer Maggot's dog
R:53:0x92:0x94

# Wolf, Farmer Maggot's dog
R:54:0x92:0x95

# Fang, Farmer Maggot's dog
R:55:0x92:0x95

# Giant green frog
R:56:0x94:0xBF

# Freesia
R:57:0x9B:0xBD

# Green worm mass
R:58:0x99:0xD6

# Large yellow snake
R:59:0x94:0xC1

# Cave spider
R:60:0x94:0xD5

# Crow
R:61:0x9E:0x97

# Wild cat
R:62:0x96:0xFB

# Smeagol
R:63:0x98:0xC8

# Green ooze
R:64:0x97:0xC3

# Poltergeist
R:65:0x93:0x91

# Yellow jelly
R:66:0x97:0xC5

# Metallic blue centipede
R:67:0x96:0x8F

# Raven
R:68:0x9E:0x97

# Giant white louse
R:69:0x97:0xD5

# Giant yellow centipede
R:70:0x96:0x8C

# Black naga
R:71:0x98:0x80

# Spotted mushroom patch
R:72:0x92:0x80

# Silver jelly
R:73:0x97:0xC4

# Scruffy-looking hobbit
R:74:0x97:0x8B

# Giant white ant
R:75:0x96:0x81

# Yellow mold
R:76:0x97:0xF8

# Metallic red centipede
R:77:0x96:0x90

# Yellow worm mass
R:78:0x99:0xD7

# Clear worm mass
R:79:0x99:0xF8

# Radiation eye
R:80:0x96:0xD4

# Yellow light
R:81:0x9F:0xCB

# Cave lizard
R:82:0x94:0xC2

# Novice ranger
R:83:0x98:0xC9

# Blue jelly
R:84:0x97:0xC6

# Creeping copper coins
R:85:0x91:0xF8

# Giant white rat
R:86:0x99:0xBE

# Snotling
R:87:0xA0:0x81

# Swordfish
R:88:0x9E:0xD6

# Blue worm mass
R:89:0x99:0xF9

# Large grey snake
R:90:0x94:0xC3

# Skeleton kobold
R:91:0x99:0xC1

# Ewok
R:92:0x9B:0xBE

# Novice mage
R:93:0x98:0xC7

# Green naga
R:94:0x98:0x81

# Giant leech
R:95:0x9F:0xCC

# Barracuda
R:96:0x9E:0xD7

# Novice paladin
R:97:0x98:0xCA

# Zog
R:98:0x93:0xF8

# Blue ooze
R:99:0x97:0xC7

# Green glutton ghost
R:100:0x93:0x92

# Green jelly
R:101:0x97:0xC8

# Large kobold
R:102:0x97:0xD3

# Grey icky thing
R:103:0x97:0xBE

# Disenchanter eye
R:104:0x96:0xD5

# Red worm mass
R:105:0x99:0xFA

# Copperhead snake
R:106:0x94:0xC4

# Death sword
R:107:0x9B:0xBF

# Purple mushroom patch
R:108:0x92:0x81

# Novice priest
R:109:0x98:0xC6

# Novice warrior
R:110:0x98:0xC4

# Nibelung
R:111:0x9B:0xC0

# The disembodied hand that strangled people
R:112:0x9B:0xC1

# Brown mold
R:113:0x97:0xF9

# Giant brown bat
R:114:0x96:0x88

# Rat-thing
R:115:0x99:0xC0

# Novice rogue
R:116:0x98:0xBF

# Creeping silver coins
R:117:0x91:0xF9

# Snaga
R:118:0x98:0x86

# Rattlesnake
R:119:0x94:0xC5

# Giant slug
R:120:0x9F:0xCC

# Giant pink frog
R:121:0x9F:0xCD

# Dark elf
R:122:0x8C:0xCC

# Zombified kobold
R:123:0x99:0xC1

# Crypt creep
R:124:0x9B:0xC2

# Rotting corpse
R:125:0x9B:0xC3

# Cave orc
R:126:0x98:0x87

# Wood spider
R:127:0x94:0xD6

# Manes
R:128:0x93:0xC9

# Bloodshot eye
R:129:0x96:0xD6

# Red naga
R:130:0x98:0x82

# Red jelly
R:131:0x97:0xC9

# Green icky thing
R:132:0x97:0xBF

# Lost soul
R:133:0x93:0x93

# Night lizard
R:134:0x94:0xC7

# Mughash, the Kobold Lord
R:135:0x97:0xD4

# Skeleton orc
R:136:0x99:0xC2

# Wormtongue, Agent of Saruman
R:137:0x98:0xD0

# Robin Hood, the Outlaw
R:138:0x9B:0xC4

# Nurgling
R:139:0x9F:0xCF

# Lagduf, the Snaga
R:140:0x98:0x88

# Brown yeek
R:141:0x9A:0x80

# Novice ranger
R:142:0x98:0xC9

# Giant salamander
R:143:0x94:0xC8

# Space monster
R:144:0x9B:0xC5

# Carnivorous flying monkey
R:145:0x9F:0xD0

# Green mold
R:146:0x97:0xFA

# Novice paladin
R:147:0x98:0xCA

# Lemure
R:148:0x93:0xCA

# Hill orc
R:149:0x98:0x89

# Bandit
R:150:0x98:0xD3

# Hunting hawk
R:151:0x9B:0xC6

# Phantom warrior
R:152:0x9B:0xC7

# Gremlin
R:153:0x9B:0xC8

# Yeti
R:154:0x95:0xC9

# Bloodshot icky thing
R:155:0x97:0xC0

# Giant grey rat
R:156:0x99:0xBF

# Black harpy
R:157:0x93:0xC1

# Skaven
R:158:0x9F:0xD1

# The wounded bear
R:159:0xA0:0xB8

# Cave bear
R:160:0xA5:0xC7

# Rock mole
R:161:0xA0:0xBA

# Mindcrafter
R:162:0x98:0xCB

# Baby blue dragon
R:163:0x96:0x95

# Baby white dragon
R:164:0x96:0x96

# Baby green dragon
R:165:0x96:0x97

# Baby black dragon
R:166:0x96:0xB8

# Baby red dragon
R:167:0x96:0xB9

# Giant red ant
R:168:0x96:0x85

# Brodda, the Easterling
R:169:0x98:0xD4

# Bloodfang, the Wolf
R:170:0xA0:0xBB

# King cobra
R:171:0x94:0xC9

# Eagle
R:172:0x9D:0xD6

# War bear
R:173:0x9B:0xC9

# Killer bee
R:174:0x9B:0xCA

# Giant spider
R:175:0x94:0xD7

# Giant white tick
R:176:0x97:0xD5

# The Borshin
R:177:0xA0:0xBC

# Dark elven mage
R:178:0x97:0x8E

# Kamikaze yeek
R:179:0xA0:0xCC

# Orfax, Son of Boldor
R:180:0x9A:0x81

# Servant of Glaaki
R:181:0xA0:0xBD

# Dark elven warrior
R:182:0x97:0x8F

# Sand-dweller
R:183:0xA0:0xBE

# Clear mushroom patch
R:184:0x9F:0xCE

# Quiver slot
R:185:0x9B:0xCB

# Grishnakh, the Hill Orc
R:186:0x98:0x8B

# Giant tan bat
R:187:0xA5:0xC8

# Owlbear
R:188:0xA0:0xBF

# Blue horror
R:189:0x9F:0xD2

# Hairy mold
R:190:0x97:0xFB

# Grizzly bear
R:191:0xA0:0xC0

# Disenchanter mold
R:192:0x97:0xFC

# Pseudo dragon
R:193:0x96:0xBA

# Tengu
R:194:0x93:0xCB

# Creeping gold coins
R:195:0x91:0xFA

# Wolf
R:196:0x92:0x96

# Giant fruit fly
R:197:0x93:0x89

# Panther
R:198:0x96:0xFC

# Brigand
R:199:0x9B:0xCC

# Hobbes the Tiger
R:200:0x9B:0xCD

# Shadow Creature of Fiona
R:201:0x9B:0xCE

# Undead mass
R:202:0x9B:0xCF

# Chaos shapechanger
R:203:0x9B:0xD0

# Baby multi-hued dragon
R:204:0x96:0xBB

# Vorpal bunny
R:205:0x9D:0xD7

# Old Man Willow
R:206:0xA0:0xC1

# Hippocampus
R:207:0xA0:0xC2

# Zombified orc
R:208:0x99:0xC4

# Hippogriff
R:209:0x93:0xC2

# Black mamba
R:210:0x94:0xCA

# White wolf
R:211:0x92:0x97

# Grape jelly
R:212:0x97:0xCA

# Nether worm mass
R:213:0x99:0xFB

# Abyss worm mass
R:214:0x9B:0xD1

# Golfimbul, the Hill Orc Chief
R:215:0x98:0x8C

# Swordsman
R:216:0x8E:0xF9

# Skaven shaman
R:217:0x90:0xBC

# Baby bronze dragon
R:218:0x96:0xBA

# Baby gold dragon
R:219:0x96:0xBA

# Evil eye
R:220:0xA5:0xC9

# Mine-dog
R:221:0xA0:0x83

# Hellcat
R:222:0x9B:0xD2

# Moon beast
R:223:0x9B:0xD3

# Master yeek
R:224:0x9A:0x82

# Priest
R:225:0x98:0xD6

# Dark elven priest
R:226:0x97:0x91

# Air spirit
R:227:0x92:0xD7

# Skeleton human
R:228:0x99:0xC3

# Zombified human
R:229:0x9A:0x86

# Tiger
R:230:0x96:0xFD

# Moaning spirit
R:231:0x93:0x94

# Stegocentipede
R:232:0x96:0x91

# Spotted jelly
R:233:0x97:0xCB

# Drider
R:234:0x94:0xF8

# Mongbat
R:235:0x9B:0xD4

# Killer brown beetle
R:236:0x93:0xD3

# Boldor, King of the Yeeks
R:237:0x9A:0x83

# Ogre
R:238:0x94:0x83

# Creeping mithril coins
R:239:0x91:0xFB

# Illusionist
R:240:0x98:0xF8

# Druid
R:241:0x98:0xF9

# Pink horror
R:242:0x9F:0xD3

# Cloaker
R:243:0x88:0x80

# Black orc
R:244:0x98:0x8D

# Ochre jelly
R:245:0x97:0xCC

# Software bug
R:246:0x9B:0xD5

# Lurker
R:247:0x83:0xB9

# Tangleweed
R:248:0xA5:0xCA

# Vlasta
R:249:0x95:0xFC

# Giant white dragon fly
R:250:0x93:0x8B

# Snaga sapper
R:251:0xA0:0x84

# Blue icky thing
R:252:0x97:0xC1

# Gibbering mouther
R:253:0x9B:0xD6

# Wolfhound of Flora
R:254:0x9B:0xD7

# Hill giant
R:255:0x94:0x89

# Flesh golem
R:256:0x97:0x81

# Warg
R:257:0x92:0xB8

# Cheerful leprechaun
R:258:0x9B:0xF8

# Giant flea
R:259:0x93:0x8A

# Ufthak of Cirith Ungol
R:260:0xA0:0xC4

# Clay golem
R:261:0x9F:0xD5

# Black ogre
R:262:0x94:0x84

# Dweller on the threshold
R:263:0xA0:0x85

# Half-orc
R:264:0xA0:0xC5

# Dark naga
R:265:0x9F:0xD6

# Poison ivy
R:266:0xA5:0xCB

# Magic mushroom patch
R:267:0x92:0x83

# Plaguebearer of Nurgle
R:268:0x9A:0x85

# Guardian naga
R:269:0x98:0x83

# Wererat
R:270:0xA0:0xC6

# Light hound
R:271:0x95:0xCB

# Dark hound
R:272:0x95:0xCC

# Flying skull
R:273:0x9B:0xF9

# Mi-Go
R:274:0x9B:0xFA

# Giant tarantula
R:275:0x94:0xF9

# Giant clear centipede
R:276:0x96:0x92

# Mirkwood spider
R:277:0x94:0xFA

# Frost giant
R:278:0x94:0x8A

# Griffon
R:279:0x93:0xC3

# Homunculus
R:280:0x93:0xCC

# Gnome mage
R:281:0x97:0x90

# Clear hound
R:282:0x95:0xCD

# Umber hulk
R:283:0x95:0x91

# Rust monster
R:284:0xA0:0x87

# Ogrillon
R:285:0x98:0x90

# Gelatinous cube
R:286:0x97:0xCD

# Giant green dragon fly
R:287:0x93:0x8C

# Fire giant
R:288:0x94:0x8B

# Hummerhorn
R:289:0xA0:0xC7

# Lizard man
R:290:0xA0:0x88

# Ulfast, Son of Ulfang
R:291:0x98:0xFA

# Crebain
R:292:0xA5:0xCC

# Berserker
R:293:0x98:0x8F

# Quasit
R:294:0x93:0xCD

# Sphinx
R:295:0xA0:0x89

# Imp
R:296:0x93:0xCE

# Forest troll
R:297:0x95:0x81

# Freezing sphere
R:298:0xA0:0xC9

# Jumping fireball
R:299:0xA0:0x8A

# Ball lightning
R:300:0xA0:0xCA

# 2-headed hydra
R:301:0x94:0xCB

# Swamp thing
R:302:0xA0:0x8B

# Water spirit
R:303:0x92:0xF8

# Giant red scorpion
R:304:0x94:0xFB

# Earth spirit
R:305:0x92:0xF9

# Fire spirit
R:306:0x92:0xFA

# Fire hound
R:307:0x95:0xCE

# Cold hound
R:308:0x95:0xCF

# Energy hound
R:309:0x95:0xD0

# Lesser Mimic
R:310:0x92:0x86

# Door mimic
R:311:0x84:0xBB

# Blink dog
R:312:0x92:0xB9

# Uruk
R:313:0x98:0x91

# Shagrat, the Orc Captain
R:314:0x98:0x92

# Gorbag, the Orc Captain
R:315:0x98:0x93

# Shambling mound
R:316:0x92:0x84

# Giant Venus Flytrap
R:317:0xA5:0xCD

# Chaos beastman
R:318:0xA0:0x8D

# Daemonette of Slaanesh
R:319:0xA0:0x8C

# Giant bronze dragon fly
R:320:0x93:0x90

# Stone giant
R:321:0x94:0x8C

# Giant black dragon fly
R:322:0x93:0x8E

# Stone golem
R:323:0x97:0x83

# Red mold
R:324:0x97:0xFD

# Giant gold dragon fly
R:325:0x93:0x8F

# Stunwall
R:326:0x83:0xCB

# Ghast
R:327:0xA0:0xCD

# Neekerbreeker
R:328:0xA5:0xCE

# Huorn
R:329:0xA0:0xCE

# Bolg, Son of Azog
R:330:0x98:0x94

# Phase spider
R:331:0x94:0xFC

# Lizard king
R:332:0xA0:0x8F

# Landmine
R:333:0xA0:0xCF

# Wyvern
R:334:0x9B:0xFB

# Great eagle
R:335:0xA0:0x90

# Livingstone
R:336:0x9B:0xFC

# Earth hound
R:337:0x95:0xD1

# Air hound
R:338:0x95:0xD2

# Sabre-tooth tiger
R:339:0x96:0xFE

# Acid hound
R:340:0x95:0xD3

# Chimaera
R:341:0x93:0xC4

# Quylthulg
R:342:0x94:0x92

# Sasquatch
R:343:0x95:0xCA

# Weir
R:344:0x9B:0xFD

# Ranger
R:345:0x98:0xCF

# Paladin
R:346:0x99:0x8A

# Werewolf
R:347:0xA0:0xD1

# Dark elven lord
R:348:0x97:0x94

# Cloud giant
R:349:0x94:0x8E

# Ugluk, the Uruk
R:350:0x98:0x95

# Blue dragon bat
R:351:0x96:0x89

# Mimic
R:352:0x85:0x95

# Ultimate Mimic
R:353:0x85:0xD6

# Fire vortex
R:354:0x99:0xCC

# Acid vortex
R:355:0x99:0xCD

# Lugdush, the Uruk
R:356:0xA0:0x92

# Arch-vile
R:357:0xA0:0xD2

# Cold vortex
R:358:0x99:0xCE

# Energy vortex
R:359:0x99:0xCF

# Globefish
R:360:0xA0:0x93

# Giant firefly
R:361:0x93:0x8D

# Mummified orc
R:362:0x94:0x80

# Wolf chieftain
R:363:0xA5:0xCF

# Serpent man
R:364:0xA0:0xD4

# Vampiric mist
R:365:0xA0:0x95

# Killer stag beetle
R:366:0x93:0xD5

# Iron golem
R:367:0x97:0x84

# Auto-roller
R:368:0x9B:0xFE

# Giant yellow scorpion
R:369:0x94:0xFD

# Jade monk
R:370:0xA0:0xD5

# Black ooze
R:371:0x97:0xCE

# Hardened warrior
R:372:0x98:0xFB

# Azog, King of the Uruk-Hai
R:373:0x98:0x97

# Fleshhound of Khorne
R:374:0xA0:0x96

# Dark elven warlock
R:375:0x9B:0xFF

# Master rogue
R:376:0x98:0xFC

# Red dragon bat
R:377:0x96:0x8A

# Killer white beetle
R:378:0xA0:0xD6

# Ice skeleton
R:379:0xA0:0x97

# Angamaite of Umbar
R:380:0xA0:0xF8

# Forest wight
R:381:0x9C:0x80

# Khim, Son of Mim
R:382:0x9C:0x81

# Ibun, Son of Mim
R:383:0x9C:0x82

# Meneldor the Swift
R:384:0xA0:0xF9

# Phantom beast
R:385:0x9C:0x83

# Giant silver ant
R:386:0x93:0xD4

# 4-headed hydra
R:387:0x94:0xCD

# Lesser hell-beast
R:388:0xA0:0xFB

# Tyrannosaur
R:389:0x9C:0x84

# Mummified human
R:390:0x94:0x81

# Vampire bat
R:391:0x96:0x8B

# Sangahyando of Umbar
R:392:0x98:0xFD

# It
R:393:0x9C:0x85

# Banshee
R:394:0x93:0x95

# Carrion crawler
R:395:0x96:0x93

# Xiclotlan
R:396:0xA0:0xFC

# Silent watcher
R:397:0x9C:0x86

# Pukelman
R:398:0x97:0x85

# Disenchanter beast
R:399:0xA0:0xD7

# Dark elven druid
R:400:0x97:0x97

# Stone troll
R:401:0x95:0x82

# Black
R:402:0x9B:0xC5

# Hill troll
R:403:0x95:0x83

# Wereworm
R:404:0x99:0xFC

# Killer red beetle
R:405:0x93:0xD7

# Disenchanter bat
R:406:0xA5:0xD0

# Gnoph-Keh
R:407:0xA0:0xFE

# Giant grey ant
R:408:0x96:0x84

# Khufu, the Mummified King
R:409:0x9C:0x87

# Gwaihir the Windlord
R:410:0xA0:0xF9

# Giant fire tick
R:411:0xA0:0xFF

# Displacer beast
R:412:0x96:0xFF

# Ulwarth, Son of Ulfang
R:413:0x98:0xD1

# Werebear
R:414:0xA5:0xC7

# Cave ogre
R:415:0x94:0x85

# White wraith
R:416:0x95:0x97

# Angel
R:417:0x92:0x87

# Ghoul
R:418:0x9D:0xC7

# Mim, Betrayer of Turin
R:419:0x9C:0x88

# Hellblade
R:420:0x9C:0x89

# Killer fire beetle
R:421:0x93:0xF8

# Beast of Nurgle
R:422:0xA1:0x80

# Creeping adamantite coins
R:423:0x91:0xFC

# Algroth
R:424:0x95:0x84

# Flamer of Tzeentch
R:425:0x9F:0xD7

# Roper
R:426:0x9F:0xF8

# Headless
R:427:0x9C:0x8A

# Vibration hound
R:428:0x95:0xD4

# Nexus hound
R:429:0x95:0xD5

# Half-ogre
R:430:0x94:0x86

# Lokkak, the Ogre Chieftain
R:431:0x94:0x88

# Vampire
R:432:0x95:0x92

# Gorgimaera
R:433:0x93:0xC5

# Shantak
R:434:0x9C:0x8B

# Colbran
R:435:0x97:0x86

# Spirit naga
R:436:0x98:0x84

# Corpser
R:437:0x9F:0xF9

# Fiend of Slaanesh
R:438:0x94:0xCF

# Stairway to Hell
R:439:0x9C:0x8C

# 5-headed hydra
R:440:0x94:0xCE

# Barney the Dinosaur
R:441:0x9C:0x8D

# Black knight
R:442:0x99:0x80

# Seahorse
R:443:0xA1:0x81

# Cyclops
R:444:0xA1:0x82

# Clairvoyant
R:445:0x98:0xFE

# Purple worm
R:446:0x9F:0xFA

# Catoblepas
R:447:0x99:0xB9

# Lesser wall monster
R:448:0x9C:0x8E

# Mage
R:449:0x99:0x82

# Mind flayer
R:450:0x99:0x83

# The Ultimate Dungeon Cleaner
R:451:0x9C:0x8F

# Deep one
R:452:0x95:0xBE

# Basilisk
R:453:0x94:0xCF

# Ice troll
R:454:0x95:0x85

# Dhole
R:455:0x9C:0x91

# Archangel
R:456:0x92:0x88

# Greater Mimic
R:457:0x9A:0x96

# Chaos tile
R:458:0x9C:0x92

# Young blue dragon
R:459:0x96:0xBC

# Young white dragon
R:460:0x96:0xBD

# Young green dragon
R:461:0x96:0xBE

# Young bronze dragon
R:462:0x96:0xBF

# Aklash
R:463:0xA4:0x96

# Mithril golem
R:464:0x97:0x87

# Skeleton troll
R:465:0x99:0xC5

# Skeletal tyrannosaur
R:466:0xA1:0x83

# Beorn, the Shape-Changer
R:467:0xA5:0xD1

# Thorondor, Lord of Eagles
R:468:0xA0:0xF9

# Giant blue ant
R:469:0x96:0x83

# Grave wight
R:470:0x9A:0x94

# Shadow drake
R:471:0x96:0xC0

# Manticore
R:472:0x93:0xC6

# Giant army ant
R:473:0x9A:0xB9

# Killer slicer beetle
R:474:0x93:0xF9

# Gorgon
R:475:0xA1:0x85

# Gug
R:476:0xA1:0x86

# Ghost
R:477:0x93:0x96

# Death watch beetle
R:478:0x93:0xFA

# Mountain ogre
R:479:0x94:0x87

# Nexus quylthulg
R:480:0x94:0x93

# Shelob, Spider of Darkness
R:481:0x94:0xFE

# Giant squid
R:482:0x9F:0xFB

# Ghoulking
R:483:0x9A:0x84

# Doombat
R:484:0x9F:0xFC

# Ninja
R:485:0x99:0x84

# Memory moss
R:486:0x97:0xFE

# Storm giant
R:487:0x94:0x8D

# Spectator
R:488:0x9C:0x93

# Bokrug
R:489:0xA1:0x87

# Biclops
R:490:0xA1:0x88

# Half-troll
R:491:0x98:0x96

# Ivory monk
R:492:0x98:0xCB

# Bert the Stone Troll
R:493:0x95:0x88

# Bill the Stone Troll
R:494:0x95:0x89

# Tom the Stone Troll
R:495:0x95:0x8A

# Cave troll
R:496:0x95:0x86

# Anti-paladin
R:497:0x9C:0x94

# Chaos master
R:498:0x9C:0x95

# Barrow wight
R:499:0x95:0xB9

# Skeleton ettin
R:500:0xA5:0xD2

# Chaos drake
R:501:0x96:0xC1

# Law drake
R:502:0x96:0xC2

# Balance drake
R:503:0x96:0xC3

# Ethereal drake
R:504:0x96:0xC4

# Groo, the Wanderer
R:505:0x9C:0x96

# Fasolt the Giant
R:506:0x9C:0x97

# Shade
R:507:0x95:0xC1

# Spectre
R:508:0x93:0xB8

# Water troll
R:509:0x95:0x8B

# Fire elemental
R:510:0x92:0xFB

# Cherub
R:511:0x92:0x89

# Water elemental
R:512:0x92:0xFC

# Multi-hued hound
R:513:0x9C:0xB9

# Invisible stalker
R:514:0x92:0xFD

# Carrion crawler
R:515:0x96:0x94

# Master thief
R:516:0x99:0x86

# The Watcher in the Water
R:517:0x9B:0x8D

# Lich
R:518:0x93:0xFB

# Gas spore
R:519:0x9C:0xC6

# Master vampire
R:520:0x95:0x93

# Oriental vampire
R:521:0x9C:0xBB

# Greater mummy
R:522:0x94:0x82

# Bloodletter of Khorne
R:523:0x93:0xD0

# Giant grey scorpion
R:524:0x94:0xFF

# Earth elemental
R:525:0x92:0xFE

# Air elemental
R:526:0x92:0xFF

# Shimmering mold
R:527:0x9A:0xF9

# Gargoyle
R:528:0xA1:0x89

# Malicious leprechaun
R:529:0x9C:0xBD

# Eog golem
R:530:0x97:0x88

# Little Boy
R:531:0x9F:0xFD

# Dagashi
R:532:0x99:0x88

# Headless ghost
R:533:0xA1:0x8A

# Dread
R:534:0x9F:0xFF

# Leng spider
R:535:0xA1:0x8B

# Gauth
R:536:0xA5:0xD3

# Smoke elemental
R:537:0x93:0x88

# Olog
R:538:0x95:0x8C

# Halfling slinger
R:539:0x9C:0xBE

# Gravity hound
R:540:0x95:0xD6

# Acidic cytoplasm
R:541:0x97:0xCF

# Inertia hound
R:542:0x95:0xD7

# Impact hound
R:543:0x95:0xF8

# Shardstorm
R:544:0xA5:0xD4

# Ooze elemental
R:545:0x93:0x80

# Young black dragon
R:546:0x96:0xC5

# Mumak
R:547:0x99:0xBC

# Giant fire ant
R:548:0x96:0x82

# Mature white dragon
R:549:0x96:0xC6

# Xorn
R:550:0x95:0xC7

# Rogrog the Black Troll
R:551:0x95:0x87

# Mist giant
R:552:0x97:0x89

# Phantom
R:553:0x9C:0xBF

# Grey wraith
R:554:0x95:0xBA

# Revenant
R:555:0x95:0xC0

# Young multi-hued dragon
R:556:0x96:0xC7

# Raal's Tome of Destruction
R:557:0x9C:0xC0

# Colossus
R:558:0x9C:0xC1

# Young gold dragon
R:559:0x96:0xC8

# Mature blue dragon
R:560:0x96:0xC9

# Mature green dragon
R:561:0x96:0xCA

# Mature bronze dragon
R:562:0x96:0xCB

# Young red dragon
R:563:0x96:0xCC

# Nightblade
R:564:0x9C:0xC2

# Trapper
R:565:0x9A:0x97

# Bodak
R:566:0x93:0xD0

# Time bomb
R:567:0xA1:0x8E

# Mezzodaemon
R:568:0x9A:0x88

# Elder thing
R:569:0x9C:0xC3

# Ice elemental
R:570:0x93:0x82

# Necromancer
R:571:0x9C:0xC4

# The Greater hell magic mushroom were-quylthulg
R:572:0x9F:0xFE

# Lorgan, Chief of the Easterlings
R:573:0x9C:0xC5

# Chaos spawn
R:574:0x9C:0xC6

# Mummified troll
R:575:0xA1:0x8F

# Storm of Unmagic
R:576:0xA5:0xD5

# Crypt thing
R:577:0x95:0xB8

# Chaos butterfly
R:578:0x80:0x80

# Time elemental
R:579:0x9C:0xC7

# Flying polyp
R:580:0xA1:0x91

# The Queen Ant
R:581:0x96:0x86

# Will o' the wisp
R:582:0x93:0x83

# Shan
R:583:0xA1:0x92

# Magma elemental
R:584:0x93:0x84

# Black pudding
R:585:0x97:0xD0

# Killer iridescent beetle
R:586:0x9D:0xC8

# Nexus vortex
R:587:0x9A:0xB8

# Plasma vortex
R:588:0x99:0xD0

# Mature red dragon
R:589:0x96:0xCD

# Mature gold dragon
R:590:0x96:0xCE

# Crystal drake
R:591:0x96:0xCF

# Mature black dragon
R:592:0x96:0xD0

# Mature multi-hued dragon
R:593:0x96:0xD1

# Sky whale
R:594:0xA1:0x93

# Draebor, the Imp
R:595:0xA4:0x97

# Mother Hydra
R:596:0x94:0xD0

# Death knight
R:597:0x99:0x8C

# Castamir the Usurper
R:598:0x9C:0xC8

# Time vortex
R:599:0x99:0xD1

# Shimmering vortex
R:600:0x99:0xD2

# Ancient blue dragon
R:601:0x92:0xC0

# Ancient bronze dragon
R:602:0x92:0xC1

# Beholder
R:603:0x96:0xD7

# Emperor wight
R:604:0x95:0xBB

# Seraph
R:605:0x92:0x8A

# Vargo, Tyrant of Fire
R:606:0x93:0x85

# Black wraith
R:607:0x95:0xBC

# Nightgaunt
R:608:0x9C:0xC9

# Baron of hell
R:609:0x9C:0xCA

# Scylla
R:610:0xA1:0x94

# Monastic lich
R:611:0x93:0xFF

# Nether wraith
R:612:0x95:0xBD

# Hellhound
R:613:0x9A:0x8E

# 7-headed hydra
R:614:0x94:0xD1

# Waldern, King of Water
R:615:0x93:0x86

# Kavlax the Many-Headed
R:616:0x96:0xD2

# Ancient white dragon
R:617:0x92:0xC2

# Ancient green dragon
R:618:0x92:0xC3

# Chthonian
R:619:0x9C:0xCB

# Eldrak
R:620:0x95:0x8F

# Ettin
R:621:0x95:0x8E

# Night mare
R:622:0x99:0xBB

# Vampire lord
R:623:0x95:0x94

# Ancient black dragon
R:624:0x92:0xC4

# Weird fume
R:625:0x9A:0xF8

# Spawn of Ubbo-Sathla
R:626:0xA1:0x95

# Fat Man
R:627:0x9F:0xFD

# Malekith the Accursed
R:628:0x97:0x8D

# Shadowfax, steed of Gandalf
R:629:0xA1:0x96

# Spirit troll
R:630:0x95:0x90

# War troll
R:631:0x9C:0xCC

# Disenchanter worm mass
R:632:0x99:0xFE

# Rotting quylthulg
R:633:0x94:0x94

# Lesser titan
R:634:0x94:0x8F

# 9-headed hydra
R:635:0x94:0xD1

# Enchantress
R:636:0x99:0x8E

# Ranger chieftain
R:637:0x99:0x8F

# Sorcerer
R:638:0x99:0x90

# Xaren
R:639:0x95:0xC8

# Giant roc
R:640:0x92:0x8F

# Minotaur
R:641:0x93:0xC7

# Medusa, the Gorgon
R:642:0x98:0x85

# Death drake
R:643:0x92:0xC5

# Ancient red dragon
R:644:0x92:0xC6

# Ancient gold dragon
R:645:0x92:0xC7

# Great crystal drake
R:646:0x92:0xC8

# Wyrd sister
R:647:0x97:0x95

# Vrock
R:648:0x9C:0xCD

# Death quasit
R:649:0x93:0xD1

# Giganto, the Gargantuan
R:650:0xA1:0x97

# Strygalldwir
R:651:0x9C:0xCE

# Fallen angel
R:652:0x98:0xC6

# Giant headless
R:653:0xA1:0xB8

# Judge Fire
R:654:0x99:0x8B

# Ubbo-Sathla, the Unbegotten Source
R:655:0xA1:0xB9

# Judge Mortis
R:656:0xA1:0xBA

# Dark elven sorcerer
R:657:0x97:0xB9

# Master lich
R:658:0x93:0xFC

# Byakhee
R:659:0x9C:0xCF

# Eol, the Dark Elf
R:660:0x9C:0xD1

# Archon
R:661:0x92:0x8B

# Formless spawn of Tsathoggua
R:662:0x9C:0xD2

# Hunting horror
R:663:0x9C:0xD3

# Undead beholder
R:664:0x96:0xF8

# Shadow
R:665:0x93:0xB9

# Iron lich
R:666:0x9C:0xD4

# Dread
R:667:0x9F:0xFF

# Greater basilisk
R:668:0xA1:0xBB

# Charybdis
R:669:0xA1:0xBC

# Jack of Shadows
R:670:0x99:0x94

# Zephyr Lord
R:671:0x99:0x89

# Juggernaut of Khorne
R:672:0xA1:0xBD

# Mumak
R:673:0x99:0xBA

# Judge Fear
R:674:0x97:0x80

# Ancient multi-hued dragon
R:675:0x92:0xC9

# Ethereal dragon
R:676:0x92:0xCA

# Dark young of Shub-Niggurath
R:677:0x9C:0xD5

# Colour out of space
R:678:0x8C:0x91

# Quaker, Master of Earth
R:679:0x93:0x87

# Death leprechaun
R:680:0x97:0x96

# Chaugnar Faugn, Horror from the Hills
R:681:0xA1:0xCC

# Lloigor
R:682:0xA1:0xCD

# Utgard-Loke
R:683:0xA1:0xCE

# Quachil Uttaus, Treader of the Dust
R:684:0xA1:0xCF

# Shoggoth
R:685:0xA1:0xD0

# Judge Death
R:686:0xA1:0xD1

# Ariel, Queen of Air
R:687:0x93:0x89

# 11-headed hydra
R:688:0x94:0xD2

# Patriarch
R:689:0x99:0x92

# Dreadmaster
R:690:0x93:0xBD

# Drolem
R:691:0x97:0x8A

# Scatha the Worm
R:692:0x9A:0x93

# Warrior of the Dawn
R:693:0x9C:0xD6

# Lesser black reaver
R:694:0x95:0xBF

# Zoth-Ommog
R:695:0xA2:0xC1

# Grand master thief
R:696:0xA4:0xC2

# Smaug the Golden
R:697:0x92:0xCB

# The Stormbringer
R:698:0x9C:0xF8

# Knight Templar
R:699:0x9C:0xF9

# Leprechaun fanatic
R:700:0x97:0xB8

# Dracolich
R:701:0x92:0xCD

# Greater titan
R:702:0x94:0x90

# Dracolisk
R:703:0x92:0xCC

# Winged Horror
R:704:0xA5:0xD6

# Spectral tyrannosaur
R:705:0x9C:0xFA

# Yibb-Tstll, the Patient One
R:706:0xA1:0xD3

# Ghatanothoa
R:707:0xA1:0xD4

# Ent
R:708:0xA1:0xBE

# Hru
R:709:0xA1:0xD5

# Itangast the Fire Drake
R:710:0x92:0xCE

# Death mold
R:711:0x97:0xFF

# Fafner the Dragon
R:712:0x9C:0xFB

# Charon, Boatman of the Styx
R:713:0xA1:0xD6

# Quickbeam, the Ent
R:714:0xA1:0xD7

# Glaurung, Father of the Dragons
R:715:0x9A:0x92

# Behemoth
R:716:0xA1:0xF8

# Garm, Guardian of Hel
R:717:0x92:0xBC

# Greater wall monster
R:718:0x9C:0xFC

# Nycadaemon
R:719:0x9A:0x89

# Barbazu
R:720:0x9A:0x8D

# Goat of Mendes
R:721:0x9C:0xFD

# Nightwing
R:722:0x9A:0x95

# Maulotaur
R:723:0x9C:0xFE

# Nether hound
R:724:0x95:0xF9

# Time hound
R:725:0x95:0xFA

# Plasma hound
R:726:0x95:0xFB

# Demonic quylthulg
R:727:0x94:0x95

# Great Storm Wyrm
R:728:0x92:0xCF

# Ulik the Troll
R:729:0xA1:0xF9

# Baphomet the Minotaur Lord
R:730:0x93:0xC8

# Hell knight
R:731:0xA1:0xFA

# Bull Gates
R:732:0x9C:0xFF

# Santa Claus
R:733:0x9D:0x80

# Eihort, the Thing in the Labyrinth
R:734:0xA2:0xC2

# The King in Yellow
R:735:0xA2:0xC3

# Great unclean one
R:736:0xA2:0xC4

# Lord of Chaos
R:737:0x9D:0x81

# Old Sorcerer
R:738:0x91:0xC2

# Ethereal hound
R:739:0x9D:0x82

# Lesser kraken
R:740:0xA1:0xFB

# Great Ice Wyrm
R:741:0x92:0xD0

# Demilich
R:742:0x95:0xC2

# The Phoenix
R:743:0x92:0x90

# Nightcrawler
R:744:0x95:0xC4

# Lord of Change
R:745:0xA1:0xBF

# Keeper of Secrets
R:746:0xA2:0xC5

# Shudde M'ell
R:747:0xA2:0xC6

# Hand druj
R:748:0x99:0xC6

# Eye druj
R:749:0x99:0xC7

# Skull druj
R:750:0x99:0xC8

# Chaos vortex
R:751:0x99:0xD3

# Aether vortex
R:752:0x99:0xD4

# Nidhogg, the Hel-Drake
R:753:0xA2:0xC7

# The Lernaean Hydra
R:754:0x94:0xD3

# Thuringwethil, the Vampire Messenger
R:755:0x95:0x95

# Great Hell Wyrm
R:756:0x92:0xD1

# Hastur the Unspeakable
R:757:0x9D:0x83

# Bloodthirster
R:758:0xA1:0xFC

# Draconic quylthulg
R:759:0x94:0x96

# Nyogtha, the Thing that Should not Be
R:760:0x9D:0x84

# Ahtu, Avatar of Nyarlathotep
R:761:0xA2:0xC8

# Fundin Bluecloak
R:762:0xA2:0xC9

# Bile Demon
R:763:0xA5:0xF8

# Uriel, Angel of Fire
R:764:0x92:0x8C

# Azriel, Angel of Death
R:765:0x92:0x8D

# Ancalagon the Black
R:766:0x92:0xD2

# Daoloth, the Render of the Veils
R:767:0xA2:0xCA

# Nightwalker
R:768:0xA1:0xFD

# Gabriel, the Messenger
R:769:0x92:0x8E

# Artsi, the Champion of Chaos
R:770:0xA2:0xCB

# Saruman of Many Colours
R:771:0x99:0x96

# Harowen the Black Hand
R:772:0xA2:0xCC

# Osyluth
R:773:0xA5:0xF9

# Dreadlord
R:774:0x93:0xBE

# Greater kraken
R:775:0xA1:0xFE

# Archlich
R:776:0x95:0xC5

# The Cat Lord
R:777:0x9D:0x87

# Jabberwock
R:778:0xA5:0xFA

# Chaos hound
R:779:0x95:0xFD

# Vlad Dracula, Prince of Darkness
R:780:0xA2:0xCD

# Beholder hive-mother
R:781:0xA2:0xCE

# Leviathan
R:782:0xA1:0xFF

# Great Wyrm of Chaos
R:783:0x92:0xD3

# Great Wyrm of Law
R:784:0x92:0xD4

# Great Wyrm of Balance
R:785:0x92:0xD5

# Shambler
R:786:0x9D:0x89

# Gelugon
R:787:0xA5:0xFB

# Glaaki
R:788:0xA0:0x80

# T'ron, the Rebel Dragonrider
R:789:0x9D:0x8A

# Great Wyrm of Many Colours
R:790:0x9D:0x8B

# Mardra, rider of the Gold Loranth
R:791:0x9D:0x8C

# Tselakus, the Dreadlord
R:792:0x93:0xBF

# Sky Drake
R:793:0x9D:0x8D

# Eilinel the Entrapped
R:794:0x93:0xBB

# Horned Reaper
R:795:0xA5:0xFC

# The Norsa
R:796:0x9D:0x8F

# Rhan-Tegoth
R:797:0xA2:0xD1

# Black reaver
R:798:0x93:0xFD

# Master mindcrafter
R:799:0x99:0x97

# Greater demonic quylthulg
R:800:0x94:0x97

# Greater draconic quylthulg
R:801:0x94:0xB8

# Greater rotting quylthulg
R:802:0x94:0xB9

# Null, the Living Void
R:803:0xA1:0xC0

# Feagwath, the Undead Sorcerer
R:804:0x93:0xFE

# Omarax the Eye Tyrant
R:805:0x96:0xF9

# Tsathoggua, the Sleeper of N'kai
R:806:0xA2:0xD2

# Greater Balrog
R:807:0x9A:0x8B

# Ungoliant, the Unlight
R:808:0x95:0x80

# Atlach-Nacha, the Spider God
R:809:0x9D:0x92

# Y'golonac
R:810:0xA2:0xD3

# Aether hound
R:811:0x95:0xFE

# Pit Fiend
R:812:0x9A:0x8A

# The Serpent of Chaos
R:813:0x9D:0xC5

# Yig, Father of Serpents
R:814:0xA2:0xD4

# Unmaker
R:815:0x9D:0x94

# Cyberdemon
R:816:0x9D:0x95

# Hela, Queen of the Dead
R:817:0xA2:0xD5

# The Mouth of Sauron
R:818:0xA2:0xD6

# The Necromancer of Dol Guldur
R:819:0x9D:0x96

# Lessa, rider of the Gold Ramoth
R:820:0x9D:0x97

# Master quylthulg
R:821:0x94:0xBA

# Qlzqqlzuup, the Lord of Flesh
R:822:0x94:0xBB

# Cthugha, the Living Flame
R:823:0xA2:0xD7

# F'lar, rider of the Bronze Mnementh
R:824:0x9D:0xB8

# Maeglin, the Traitor of Gondolin
R:825:0x95:0xC6

# Cyaegha
R:826:0xA2:0xF8

# Pazuzu, Lord of Air
R:827:0xA2:0xF9

# Ithaqua the Windwalker
R:828:0x9D:0xB9

# Greater Hellhound
R:829:0x92:0xBB

# Cantoras, the Skeletal Lord
R:830:0x99:0xC9

# Mephistopheles, Lord of Hell
R:831:0x9D:0xBA

# Godzilla
R:832:0x9D:0xBB

# Abhoth, Source of Uncleanness
R:833:0xA2:0xFA

# Ymir, the Ice Giant
R:834:0xA2:0xFB

# Loki, the Trickster
R:835:0xA2:0xFC

# Star-spawn of Cthulhu
R:836:0x9D:0xBC

# Surtur, the Fire Giant
R:837:0xA2:0xFD

# The Tarrasque
R:838:0xA1:0xCB

# Lungorthin, the Balrog of White Fire
R:839:0xA2:0xFE

# Draugluin, Sire of All Werewolves
R:840:0xA2:0xFF

# Shuma-Gorath
R:841:0xA3:0x80

# Tulzscha, the Green Flame
R:842:0xA1:0xCA

# Oremorj, the Cyberdemon Lord
R:843:0xA1:0xC9

# Vecna, the Emperor Lich
R:844:0x9D:0xBD

# Yog-Sothoth, the All-in-One
R:845:0x9D:0xBE

# Fenris Wolf
R:846:0xA1:0xC8

# Great Wyrm of Power
R:847:0x9D:0xBF

# Shub-Niggurath, Black Goat of the Woods
R:848:0x9D:0xC0

# Nodens, Lord of the Great Abyss
R:849:0x99:0x85

# Carcharoth, the Jaws of Thirst
R:850:0x92:0xBE

# Nyarlathotep, the Crawling Chaos
R:851:0x9D:0xC1

# Azathoth, the Daemon Sultan
R:852:0x9D:0xC2

# Huan, Wolfhound of the Valar
R:853:0x92:0xBF

# Jormungand the Midgard Serpent
R:854:0xA1:0xC7

# The Destroyer
R:855:0xA1:0xC6

# Gothmog, the High Captain of Balrogs
R:856:0x9A:0x90

# Great Cthulhu
R:857:0x9D:0xC3

# Sorka, rider of the Gold Faranth
R:858:0x9D:0xC4

# The Unicorn of Order
R:859:0xA1:0xC5

# Sauron, the Sorcerer
R:860:0x99:0xB8

# DarkGod, the Mighty Coder of Hell
R:861:0xA3:0xD5

# Morgoth, Lord of Darkness
R:862:0x9D:0xC6

# Human Warrior
R:863:0x9D:0xF8

# Elven archer
R:864:0x9D:0xF9

# Dwarven warrior
R:865:0x9D:0xFA

# Elite uruk
R:866:0x9D:0xFB

# The Philosophy Teacher
R:867:0xA1:0xC4

# The Variant Maintainer
R:868:0xA1:0xC3

# Random Number Generator
R:869:0xA1:0xC2

# Rocket mine
R:870:0xA2:0x80

# Bouncing mine
R:871:0xA2:0x81

# Durin's Bane
R:872:0xA3:0x81

# The Icky Queen
R:873:0xA3:0x82

# Rot jelly
R:874:0xA2:0x82

# Death
R:875:0xA2:0x83

# Famine
R:876:0xA2:0x85

# Pestilence
R:877:0xA2:0x84

# War
R:878:0xA2:0x86

# Pike
R:879:0xA2:0x87

# Electric eel
R:880:0xA2:0x88

# Giant crayfish
R:881:0xA2:0x89

# Mermaid
R:882:0xA2:0x8A

# Box jellyfish
R:883:0xA0:0xB9

# Giant piranha
R:884:0x9E:0xD5

# Piranha
R:885:0x9E:0xD5

# Bullywug
R:886:0xA2:0x8C

# Bullywug warrior
R:887:0xA2:0x8D

# Bullywug shaman
R:888:0xA2:0x8E

# Whale
R:889:0xA0:0xD0

# Sand mite
R:890:0xA2:0x90

# Octopus
R:891:0xA2:0x91

# Giant octopus
R:892:0xA2:0x92

# Eye of the deep
R:893:0xA2:0x93

# Murk dweller
R:894:0xA3:0x83

# Drowned soul
R:895:0xA3:0x84

# Tiger shark
R:896:0xA3:0x85

# Hammerhead shark
R:897:0xA0:0xC8

# Great white shark
R:898:0xA0:0xFA

# Aquatic golem
R:899:0xA3:0x86

# Aquatic kobold
R:900:0xA3:0x87

# White shark
R:901:0xA0:0xFA

# Scrag
R:902:0xA3:0x89

# Jaws
R:903:0xA1:0x84

# Aquatic elf
R:904:0xA3:0x8B

# Aquatic elven warrior
R:905:0xA3:0x8C

# Aquatic elven shaman
R:906:0xA3:0x8D

# Stargazer
R:907:0xA3:0x8E

# Elder stargazer
R:908:0xA3:0x8F

# Flounder
R:909:0xA3:0x90

# Giant turtle
R:910:0xA3:0x91

# Baby dragon turtle
R:911:0xA3:0x92

# Young dragon turtle
R:912:0xA3:0x93

# Mature dragon turtle
R:913:0xA3:0x94

# Ancient dragon turtle
R:914:0xA3:0x95

# Fastitocalon
R:915:0xA3:0x96

# Undead stargazer
R:916:0xA3:0x97

# Killer whale
R:917:0xA0:0x94

# Merrow
R:918:0xA5:0xFD

# Water naga
R:919:0xA3:0xB9

# Devilfish
R:920:0xA3:0xBA

# Undead devilfish
R:921:0xA3:0xBB

# Moby Dick, the White Whale
R:922:0xA3:0xB8

# Aquatic hound
R:923:0xA3:0xBD

# Water demon
R:924:0xA3:0xBE

# Ixitxachitl
R:925:0x9F:0xD4

# Ixitxachitl priest
R:926:0xA3:0xC0

# Vampiric ixitxachitl
R:927:0xA3:0xC1

# Mathilde, the Science Student
R:928:0xA2:0x94

# Child spirit
R:929:0xA2:0x95

# Young spirit
R:930:0xA2:0x96

# Mature spirit
R:931:0xA2:0x97

# Experienced spirit
R:932:0xA2:0xB8

# Wise spirit
R:933:0xA2:0xB9

# Fangorn the Treebeard, Lord of the Ents
R:934:0xA3:0xC2

# Gandalf the Grey
R:935:0xA3:0xC3

# Nar, the Dwarf
R:936:0xA3:0xC4

# Novice mindcrafter
R:937:0x98:0xD2

# Great Swamp Wyrm
R:938:0xA5:0xFE

# Great Bile Wyrm
R:939:0xA5:0xFF

# Blue Firelizard
R:940:0xA2:0xBA

# Green Firelizard
R:941:0xA2:0xBB

# Brown Firelizard
R:942:0xA2:0xBC

# Bronze Firelizard
R:943:0xA2:0xBD

# Gold Firelizard
R:944:0xA2:0xBE

# High-elven ranger
R:945:0xA2:0xBF

# Uvatha the Horseman
R:946:0xA3:0xC8

# Adunaphel the Quiet
R:947:0xA3:0xC9

# Akhorahil the Blind
R:948:0xA3:0xCA

# Ren the Unclean
R:949:0xA3:0xCB

# Ji Indur Dawndeath
R:950:0xA3:0xCC

# Dwar, Dog Lord of Waw
R:951:0xA3:0xCD

# Hoarmurath of Dir
R:952:0xA3:0xCE

# Khamul, the Black Easterling
R:953:0xA3:0xCF

# The Witch-King of Angmar
R:954:0xA3:0xD0

# Green Dragonrider
R:955:0x9D:0x8E

# Blue Dragonrider
R:956:0x9D:0x86

# Brown Dragonrider
R:957:0x9D:0x90

# Bronze Dragonrider
R:958:0x9D:0x90

# Gold Dragonrider
R:959:0x9D:0x8C

# Thread
R:960:0xA2:0xC0

# Gorlim, Betrayer of Barahir
R:961:0xA3:0xD1

# The Blubbering idiot, agent of black market, Simon the weak
R:962:0x98:0xBA

# Aranea
R:963:0xA4:0x92

# Elder aranea
R:964:0xA3:0xD2

# Giant brown tick
R:965:0xA6:0x80

# Dolphiner
R:966:0xA3:0xD4

# Novice possessor (soul)
R:967:0xA5:0xBE

# Bat of Gorgoroth
R:968:0xA6:0x8F

# The Princess
R:969:0xA6:0x90

# Merton Proudfoot, the lost hobbit
R:970:0xA6:0x91

# The Wight-King of the Barrow-downs
R:971:0xA6:0x92

# Adventurer
R:972:0xA6:0x93

# Experienced possessor (soul)
R:973:0xA6:0x94

# Old possessor (soul)
R:974:0xA6:0x95

# Death orb
R:975:0xA6:0x96

# Bronze dragon worm
R:976:0xA6:0xB8

# Gold dragon worm
R:977:0xA6:0x97

# Moldoux, the Defenceless Mold
R:978:0xA1:0xC1

# The Physics Teacher
R:979:0xA2:0xCF

# Ar-Pharazon the Golden
R:980:0xA3:0xD6

# Doppelganger
R:981:0x8F:0x84

# Marylene, Heartbreakeress of the Netherworld
R:982:0xA4:0x85

# The Greater Lag Monster
R:983:0xA4:0xC5

# Hrungnir, the Stone Giant
R:984:0x97:0x82

# Bullroarer the Hobbit
R:985:0x97:0x93

# 3-headed hydra
R:986:0x94:0xCC

# Uldor the Accursed
R:987:0x99:0x8D

# Mystic
R:988:0x99:0x93

# Elder vampire
R:989:0x94:0x91

# Ulfang the Black
R:990:0x98:0xCE

# Demonologist
R:991:0x97:0xBA

# Hezrou
R:992:0x94:0xD4

# Glabrezu
R:993:0x94:0xC6

# Nalfeshnee
R:994:0xA4:0xC6

# Marilith
R:995:0xA4:0xC7

# Lesser Balrog
R:996:0x9A:0x8D

# Master mystic
R:997:0x98:0xCC

# Grand master mystic
R:998:0x99:0x95

# Erinyes
R:999:0x93:0xBC

# Novice mindcrafter
R:1000:0x98:0xD2

# Polyphemus, the Blind Cyclops
R:1001:0xA6:0x81

# Great Wyrm of Perplexity
R:1002:0xA4:0xCA

# Hound of Tindalos
R:1003:0xA4:0xCB

# Great Wyrm of Thunder
R:1004:0xA6:0x82

# Silver mouse
R:1005:0xA6:0x83

# The Rat King
R:1006:0xA4:0xCE

# Vort the Kobold Queen
R:1007:0xA4:0xCF

# Giant black louse
R:1008:0xA4:0xD0

# Fire Phantom
R:1009:0xA4:0xD1

# The Insane Player
R:1010:0x8C:0xB9

# Glaryssa, Succubus Queen
R:1011:0xA4:0xD2

# Vermicious Knid
R:1012:0xA4:0xD3

# Bone golem
R:1013:0xA4:0xD4

# Snake of Yig
R:1014:0xA4:0xD5

# Bronze golem
R:1015:0xA6:0x84

# Dimensional shambler
R:1016:0xA4:0xD7

# Cultist
R:1017:0x8D:0xD1

# Cult leader
R:1018:0x90:0x8F

# Servitor of the outer gods
R:1019:0xA5:0x82

# Avatar of Nyarlathotep
R:1020:0xA5:0x83

# Thiazi, the Storm Giant
R:1021:0xA6:0x85

# Hypnos, Lord of Sleep
R:1022:0xA5:0x85

# Blue dragon worm
R:1023:0xA5:0x86

# White dragon worm
R:1024:0xA5:0x87

# Green dragon worm
R:1025:0xA5:0x8A

# Black dragon worm
R:1026:0xA5:0x89

# Red dragon worm
R:1027:0xA5:0x88

# Multi-hued dragon worm
R:1028:0xA5:0x8B

# The Minotaur of the Labyrinth
R:1029:0xA5:0x8C

# The Sandworm Queen
R:1030:0xA5:0x93

# Sandworm
R:1031:0xA5:0x94

# Tik'srvzllat
R:1032:0xA5:0x95

# The Glass Golem
R:1033:0xA6:0x86

# The White Balrog
R:1034:0xA6:0x87

# Golgarach, the Living Rock
R:1035:0x83:0xBC

# Atlas, the Titan
R:1036:0xA6:0x88

# Kronos, Lord of the Titans
R:1037:0xA6:0x89

# Water hound
R:1038:0xA6:0xC0

# Improv, the mighty MoLD
R:1039:0xA6:0xC6

# Emperor Mimic
R:1040:0xA6:0xD4

# Melinda Proudfoot
R:1041:0x87:0xE2

# Thrain, the King Under the Mountain
R:1042:0x87:0xE3

# Fire golem
R:1043:0x89:0xD8

# Melkor, Lord of Darkness
R:1044:0x89:0xD9

# Spirit
R:1045:0x8C:0xD7

# Spirit
R:1046:0x8C:0xD8

# Spirit
R:1047:0x8C:0xD9

# Spirit
R:1048:0x8C:0xDA

# Spirit
R:1049:0x8C:0xDB

# Spirit
R:1050:0x8C:0xDC

# Spirit
R:1051:0x8C:0xDD

# Spirit
R:1052:0x8C:0xDE

# Spirit
R:1053:0x8C:0xDF

# Spirit
R:1054:0x8C:0xE0

# Spirit
R:1055:0x8C:0xE1

# Spirit
R:1056:0x8C:0xE2

# Spirit
R:1057:0x8C:0xDB

# Spirit
R:1058:0x8C:0xE3

# Spirit
R:1059:0x8C:0xE4

# Spirit
R:1060:0x8C:0xE5

# Spirit
R:1061:0x8C:0xE6

# Spirit
R:1062:0x8C:0xE7

# Spirit
R:1063:0x8C:0xE8

# Spirit
R:1064:0x8C:0xE9

# Spirit
R:1065:0x8C:0xEA

# Spirit
R:1066:0x8C:0xEB

# Spirit
R:1067:0x8C:0xEC

# Spirit
R:1068:0x8C:0xED

# Spirit
R:1069:0x8C:0xEE

# Spirit
R:1070:0x8C:0xEF

# Spirit
R:1071:0x8C:0xF0

# Spirit
R:1072:0x8C:0xF1

# Spirit
R:1073:0x8C:0xF2

# Spirit
R:1074:0x8C:0xF3

# Spirit
R:1075:0x8C:0xF4

# Spells (*)
S:48:0x8C:0x80

# Spells (*)
S:49:0x8C:0x81

# Spells (*)
S:50:0x8C:0x82

# Spells (*)
S:51:0x8C:0x83

# Spells (*)
S:52:0x8C:0x84

# Spells (*)
S:53:0x8C:0x85

# Spells (*)
S:54:0x8C:0x86

# Spells (*)
S:55:0x8C:0x87

# Spells (*)
S:56:0x8C:0x88

# Spells (*)
S:57:0x8C:0x89

# Spells (*)
S:58:0x8C:0x8A

# Spells (*)
S:59:0x8C:0x8B

# Spells (*)
S:60:0x8C:0x8C

# Spells (*)
S:61:0x8C:0x8D

# Spells (*)
S:62:0x8C:0x8E

# Spells (*)
S:63:0x8C:0x8F

# Spells (|)
S:64:0x8A:0xF8

# Spells (|)
S:65:0x8A:0xFC

# Spells (|)
S:66:0x8B:0x80

# Spells (|)
S:67:0x8B:0x84

# Spells (|)
S:68:0x8B:0x88

# Spells (|)
S:69:0x8B:0x8C

# Spells (|)
S:70:0x8B:0x90

# Spells (|)
S:71:0x8B:0x94

# Spells (|)
S:72:0x8B:0xB8

# Spells (|)
S:73:0x8B:0xBC

# Spells (|)
S:74:0x8B:0xC0

# Spells (|)
S:75:0x8B:0xC4

# Spells (|)
S:76:0x8B:0xC8

# Spells (|)
S:77:0x8B:0xCC

# Spells (|)
S:78:0x8B:0xD0

# Spells (|)
S:79:0x8B:0xD4

# Spells (-)
S:80:0x8A:0xF9

# Spells (-)
S:81:0x8A:0xFD

# Spells (-)
S:82:0x8B:0x81

# Spells (-)
S:83:0x8B:0x85

# Spells (-)
S:84:0x8B:0x89

# Spells (-)
S:85:0x8B:0x8D

# Spells (-)
S:86:0x8B:0x91

# Spells (-)
S:87:0x8B:0x95

# Spells (-)
S:88:0x8B:0xB9

# Spells (-)
S:89:0x8B:0xBD

# Spells (-)
S:90:0x8B:0xC1

# Spells (-)
S:91:0x8B:0xC5

# Spells (-)
S:92:0x8B:0xC9

# Spells (-)
S:93:0x8B:0xCD

# Spells (-)
S:94:0x8B:0xD1

# Spells (-)
S:95:0x8B:0xD5

# Spells (:)
S:96:0x8A:0xFA

# Spells (:)
S:97:0x8A:0xFE

# Spells (:)
S:98:0x8B:0x82

# Spells (:)
S:99:0x8B:0x86

# Spells (:)
S:100:0x8B:0x8A

# Spells (:)
S:101:0x8B:0x8E

# Spells (:)
S:102:0x8B:0x92

# Spells (:)
S:103:0x8B:0x96

# Spells (:)
S:104:0x8B:0xBA

# Spells (:)
S:105:0x8B:0xBE

# Spells (:)
S:106:0x8B:0xC2

# Spells (:)
S:107:0x8B:0xC6

# Spells (:)
S:108:0x8B:0xCA

# Spells (:)
S:109:0x8B:0xCE

# Spells (:)
S:110:0x8B:0xD2

# Spells (:)
S:111:0x8B:0xD6

# Spells (\)
S:112:0x8A:0xFB

# Spells (\)
S:113:0x8A:0xFF

# Spells (\)
S:114:0x8B:0x83

# Spells (\)
S:115:0x8B:0x87

# Spells (\)
S:116:0x8B:0x8B

# Spells (\)
S:117:0x8B:0x8F

# Spells (\)
S:118:0x8B:0x93

# Spells (\)
S:119:0x8B:0x97

# Spells (\)
S:120:0x8B:0xBB

# Spells (\)
S:121:0x8B:0xBF

# Spells (\)
S:122:0x8B:0xC3

# Spells (\)
S:123:0x8B:0xC7

# Spells (\)
S:124:0x8B:0xCB

# Spells (\)
S:125:0x8B:0xCF

# Spells (\)
S:126:0x8B:0xD3

# Spells (\)
S:127:0x8B:0xD7

# Amulets (
S:128:0x86:0xFF

# Amulets (
S:129:0x86:0xF8

# Amulets (
S:130:0x87:0x80

# Amulets (
S:131:0x86:0xFA

# Amulets (
S:132:0x86:0xFB

# Amulets (
S:133:0x86:0xFC

# Amulets (
S:134:0x86:0xFD

# Amulets (
S:135:0x86:0xFE

# Amulets (
S:136:0x86:0xF9

# Amulets (
S:137:0x86:0xF9

# Amulets (
S:138:0x87:0x81

# Amulets (
S:139:0x87:0x82

# Amulets (
S:140:0x87:0x83

# Amulets (
S:141:0x87:0x84

# Amulets (
S:142:0x87:0x85

# Amulets (
S:143:0x87:0x86

# Rings (=)
S:144:0x85:0xBF

# Rings (=)
S:145:0x85:0xB8

# Rings (=)
S:146:0x85:0xC0

# Rings (=)
S:147:0x85:0xBA

# Rings (=)
S:148:0x85:0xBB

# Rings (=)
S:149:0x85:0xBC

# Rings (=)
S:150:0x85:0xBD

# Rings (=)
S:151:0x85:0xBE

# Rings (=)
S:152:0x85:0xB9

# Rings (=)
S:153:0x85:0xB9

# Rings (=)
S:154:0x85:0xC1

# Rings (=)
S:155:0x85:0xC2

# Rings (=)
S:156:0x85:0xC3

# Rings (=)
S:157:0x85:0xC4

# Rings (=)
S:158:0x85:0xC5

# Rings (=)
S:159:0x85:0xC6

# Staffs (_)
S:160:0x87:0x8E

# Staffs (_)
S:161:0x87:0x8D

# Staffs (_)
S:162:0x87:0x8D

# Staffs (_)
S:163:0x87:0x8A

# Staffs (_)
S:164:0x87:0x8A

# Staffs (_)
S:165:0x87:0x8B

# Staffs (_)
S:166:0x87:0x8D

# Staffs (_)
S:167:0x87:0x88

# Staffs (_)
S:168:0x87:0x8D

# Staffs (_)
S:169:0x87:0x8D

# Staffs (_)
S:170:0x87:0x8A

# Staffs (_)
S:171:0x87:0x8C

# Staffs (_)
S:172:0x87:0x8A

# Staffs (_)
S:173:0x87:0x8B

# Staffs (_)
S:174:0x87:0x8E

# Staffs (_)
S:175:0x87:0x88

# Wands (-)
S:176:0x86:0xCF

# Wands (-)
S:177:0x86:0xC8

# Wands (-)
S:178:0x86:0xD0

# Wands (-)
S:179:0x86:0xCA

# Wands (-)
S:180:0x86:0xCB

# Wands (-)
S:181:0x86:0xCC

# Wands (-)
S:182:0x86:0xCD

# Wands (-)
S:183:0x86:0xCE

# Wands (-)
S:184:0x86:0xC9

# Wands (-)
S:185:0x86:0xC9

# Wands (-)
S:186:0x86:0xD1

# Wands (-)
S:187:0x86:0xD2

# Wands (-)
S:188:0x86:0xD3

# Wands (-)
S:189:0x86:0xD4

# Wands (-)
S:190:0x86:0xD5

# Wands (-)
S:191:0x86:0xD6

# Rods (-)
S:192:0x86:0xBF

# Rods (-)
S:193:0x86:0xB8

# Rods (-)
S:194:0x86:0xC0

# Rods (-)
S:195:0x86:0xBA

# Rods (-)
S:196:0x86:0xBB

# Rods (-)
S:197:0x86:0xBC

# Rods (-)
S:198:0x86:0xBD

# Rods (-)
S:199:0x86:0xBE

# Rods (-)
S:200:0x86:0xB9

# Rods (-)
S:201:0x86:0xB9

# Rods (-)
S:202:0x86:0xC1

# Rods (-)
S:203:0x86:0xC2

# Rods (-)
S:204:0x86:0xC3

# Rods (-)
S:205:0x86:0xC4

# Rods (-)
S:206:0x86:0xC5

# Rods (-)
S:207:0x86:0xC6

# Scrolls (?)
S:208:0x85:0x94

# Scrolls (?)
S:209:0x85:0x95

# Scrolls (?)
S:210:0x85:0x96

# Scrolls (?)
S:211:0x85:0x97

# Scrolls (?)
S:212:0x85:0x94

# Scrolls (?)
S:213:0x85:0x95

# Scrolls (?)
S:214:0x85:0x96

# Scrolls (?)
S:215:0x85:0x97

# Scrolls (?)
S:216:0x85:0x94

# Scrolls (?)
S:217:0x85:0x95

# Scrolls (?)
S:218:0x85:0x96

# Scrolls (?)
S:219:0x85:0x97

# Scrolls (?)
S:220:0x85:0x94

# Scrolls (?)
S:221:0x85:0x95

# Scrolls (?)
S:222:0x85:0x96

# Scrolls (?)
S:223:0x85:0x97

# Potions (!)
S:224:0x85:0xFF

# Potions (!)
S:225:0x85:0xF8

# Potions (!)
S:226:0x86:0x80

# Potions (!)
S:227:0x85:0xFA

# Potions (!)
S:228:0x85:0xFB

# Potions (!)
S:229:0x85:0xFC

# Potions (!)
S:230:0x85:0xFD

# Potions (!)
S:231:0x85:0xFE

# Potions (!)
S:232:0x85:0xF9

# Potions (!)
S:233:0x85:0xF9

# Potions (!)
S:234:0x86:0x81

# Potions (!)
S:235:0x86:0x82

# Potions (!)
S:236:0x86:0x83

# Potions (!)
S:237:0x86:0x84

# Potions (!)
S:238:0x86:0x85

# Potions (!)
S:239:0x86:0x86

# Food (,)
S:240:0x86:0x8F

# Food (,)
S:241:0x86:0x88

# Food (,)
S:242:0x86:0x90

# Food (,)
S:243:0x86:0x8A

# Food (,)
S:244:0x86:0x8B

# Food (,)
S:245:0x86:0x8C

# Food (,)
S:246:0x86:0x8D

# Food (,)
S:247:0x86:0x8E

# Food (,)
S:248:0x86:0x89

# Food (,)
S:249:0x86:0x89

# Food (,)
S:250:0x86:0x91

# Food (,)
S:251:0x86:0x92

# Food (,)
S:252:0x86:0x93

# Food (,)
S:253:0x86:0x94

# Food (,)
S:254:0x86:0x95

# Food (,)
S:255:0x86:0x96

tome-235-src/lib/pref/font-win.prf0000644000076400017500000000675711012107762014660 0ustar  dgdg# File: font-win.prf

#
# This file is used by Angband (when it was compiled using "main-win.c")
# to specify simple attr/char remappings using a standard font, allowing
# the use of special pseudo-graphic pictures for walls and such.
#
# Note that this file is extremely similar to the file "font-ibm.prf",
# but it uses different codes, since it uses the special pseudo-graphic
# symbols defined in the "lib/xtra/font/*.FON" files, and there is only
# one special wall type, so we have to use special "colors".
#


##### Feature attr/char definitions #####

# open floor
F:1:0x01/0x1F

# web
F:16:0x0B/0x7F

# secret door
F:48:0x01/0x7F

# magma vein
F:50:0x02/0x7F

# quartz vein
F:51:0x09/0x7F

# magma vein
F:52:0x02/0x7F

# quartz vein
F:53:0x09/0x7F

# granite wall
F:56:0x01/0x7F

# granite wall
F:57:0x01/0x7F

# granite wall
F:58:0x01/0x7F

# granite wall
F:59:0x01/0x7F

# permanent wall
F:60:0x01/0x7F

# permanent wall
F:61:0x01/0x7F

# permanent wall
F:62:0x01/0x7F

# permanent wall
F:63:0x01/0x7F

# permanent wall
F:75:0x01/0x7F

# permanent wall
F:76:0x01/0x7F

# permanent wall
F:77:0x01/0x7F

# permanent wall
F:78:0x01/0x7F

# pool of deep lava
F:85:0x0C/0x1F

# stream of shallow lava
F:86:0x04/0x1F

# dark pit
F:87:0x08/0x7F

# dirt
F:88:0x0F/0x1F

# patch of grass
F:89:0x0D/0x1F

# ice
F:90:0x09/0x1F

# sand
F:91:0x0B/0x1F

# dead tree
F:92:0x08/0x7F

# ash
F:93:0x02/0x1F

# mud
F:94:0x07/0x1F

# ice wall
F:95:0x09/0x7F

# tree
F:96:0x0D/0x7F

# sandwall
F:98:0x0B/0x7F

# sandwall
F:99:0x0B/0x7F

# sandwall with treasure
F:100:0x03/0x7F

# nether mist
F:102:0x0A/0x7F

# Underground Tunnel
F:173:0x02/0x7F

# lava wall
F:177:0x0C/0x7F

# Great Fire
F:178:0x0A/0x7F

# field
F:181:0x05/0x1F

# glass wall
F:188:0x0E/0x1F

# illusion wall
F:189:0x01/0x7F

# Grass roof
F:190:0x0B/0x7F

# grass roof top
F:191:0x0B/0x7F

# grass roof chimney
F:192:0x0B/0x7F

# brick roof
F:193:0x04/0x7F

# brick roof top
F:194:0x04/0x7F

# brick roof chimney
F:195:0x04/0x7F

# rain barrel
F:198:0x01/0x7F

# cobblestone road
F:200:0x01/0x1F

# cobblestone with outlet
F:201:0x01/0x1F

# small tree
F:202:0x05/0x7F

# Underground Tunnel
F:204:0x0F/0x7F

# a blazing fire
F:205:0x0B/0x7F

# rocky ground
F:207:0x02/0x1F

# cloud-like vapour
F:208:0x09/0x1F

# dense mist
F:210:0x01/0x7F

# hail-stone wall
F:211:0x09/0x7F

# copper pillar
F:213:0x07/0x7F

# ethereal wall
F:214:0x01/0x1F

# glacial wall
F:215:0x0E/0x7F

# battlement
F:216:0x01/0x7F

##### Monster attr/char definitions #####

# Space monster
R:144:0x00/0x1F

# Old Man Willow
R:206:0x02/0x7F

# Lurker
R:247:0x01/0x1F

# Tangleweed
R:248:0x05/0x7F

# Poison ivy
R:266:0x05/0x7F

# Giant Venus Flytrap
R:317:0x05/0x7F

# Stunwall
R:326:0x09/0x7F

# Huorn
R:329:0x05/0x7F

# Landmine
R:333:0x01/0x1F

# Livingstone
R:336:0x09/0x7F

# Vampiric mist
R:365:0x08/0x7F

# It
R:393:0x09/0x1F

# Xiclotlan
R:396:0x08/0x7F

# Roper
R:426:0x08/0x7F

# Lesser wall monster
R:448:0x09/0x7F

# Chaos tile
R:458:0x0A/0x1F

# Mist giant
R:552:0x0E/0x7F

# Trapper
R:565:0x01/0x1F

# Time bomb
R:567:0x01/0x1F

# Weird fume
R:625:0x0A/0x7F

# Colour out of space
R:678:0x0A/0x1F

# Ent
R:708:0x0D/0x7F

# Quickbeam, the Ent
R:714:0x0D/0x7F

# Greater wall monster
R:718:0x09/0x7F

# Ahtu, Avatar of Nyarlathotep
R:761:0x08/0x7F

# Null, the Living Void
R:803:0x00/0x1F

# Rocket mine
R:870:0x0C/0x1F

# Bouncing mine
R:871:0x0E/0x1F

# Fangorn the Treebeard, Lord of the Ents
R:934:0x0D/0x7F

# The Glass Golem
R:1033:0x09/0x7F

# Golgarach, the Living Rock
R:1035:0x09/0x7F

# Spirit
R:1053:0x09/0x1F


tome-235-src/lib/pref/pref.prf0000644000076400017500000000643211012107762014041 0ustar  dgdg# File: pref.prf

#
# This file defines "default" actions of various kinds
#
# This file includes, if appropriate, various "sub-files"
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#
# Note that the "X" key is mapped in both keysets to the key sequence
# "w0", which will "swap weapons" as long as both weapons contain the
# inscription "@0".  For example, inscribe your main weapon as "@1@0"
# and your digger (or secondary weapon) as "@2@0".
#


##### Force certain options #####

## # Option -- Default to original commands
## X:rogue_like_commands

## # Option -- Default to roguelike commands
## Y:rogue_like_commands


##### Original Keyset Mappings #####

# Stay still
A:,
C:0:5

# Movement
A:;1
C:0:1
A:;2
C:0:2
A:;3
C:0:3
A:;4
C:0:4
A:;6
C:0:6
A:;7
C:0:7
A:;8
C:0:8
A:;9
C:0:9

# Hack -- Return
A:\r
C:0:^J

# Hack -- Commit suicide
A:Q
C:0:^K

# Hack -- Commit suicide
A:Q
C:0:^C


##### Roguelike Keyset Mappings #####

# Run
A:.
C:1:,

# Stay still
A:,
C:1:.

# Stay still
A:,
C:1:5

# Movement
A:;1
C:1:1
A:;2
C:1:2
A:;3
C:1:3
A:;4
C:1:4
A:;6
C:1:6
A:;7
C:1:7
A:;8
C:1:8
A:;9
C:1:9

# Movement (rogue keys)
A:;1
C:1:b
A:;2
C:1:j
A:;3
C:1:n
A:;4
C:1:h
A:;6
C:1:l
A:;7
C:1:y
A:;8
C:1:k
A:;9
C:1:u

# Running (shift + rogue keys)
A:.1
C:1:B
A:.2
C:1:J
A:.3
C:1:N
A:.4
C:1:H
A:.6
C:1:L
A:.7
C:1:Y
A:.8
C:1:K
A:.9
C:1:U

# Altering (control + rogue keys)
A:+1
C:1:^B
A:+2
C:1:^J
A:+3
C:1:^N
A:+4
C:1:^H
A:+6
C:1:^L
A:+7
C:1:^Y
A:+8
C:1:^K
A:+9
C:1:^U

# Allow use of the "tunnel" command
A:T
C:1:^T

# Allow use of the "destroy" command
A:k
C:1:^D

# Locate player on map
A:L
C:1:W

# Browse a book (Peruse)
A:b
C:1:P

# Toggle search mode
A:S
C:1:#

# Use a staff (Zap)
A:u
C:1:Z

# Take off equipment
A:t
C:1:T

# Fire an item
A:f
C:1:t

# Bash a door (Force)
A:B
C:1:f

# Look around (examine)
A:l
C:1:x

# Aim a wand (Zap)
A:a
C:1:z

# Zap a rod (Activate)
A:z
C:1:a

# Hack -- Commit suicide
A:Q
C:1:^C

# Hack - race/mutation power activation
A:U
C:1:O

# Sacrifice at an altar
A:O
C:1:^g

# Hack up a corpse
A:h
C:1:$

# Cure meat
A:K
C:1:^O

# Pet commands
A:P
C:1:X

# Engrave
A:x
C:1:]

# Steal
A:Z
C:1:[

# Drink from a fountain
A:H
C:1:V

# Give item
A:y
C:1:'

# Chat
A:Y
C:1:(

# Command line
A:#
C:1:)

# Record command
A:$
C:1:S


### Extended macros ###

# Note that : and ' can only be included in triggers if they are
# within quotes (i.e. as ':' or ''').

L:-8192:help:Show this help
L:-8192:?
L:-8192:'''
L:-8191:irc_on:Connect to IRC
L:-8191:C
L:-8190:irc_say:Speak on IRC
L:-8190:@
L:-8190:':'
L:-8189:irc_off:Disconnect from IRC
L:-8188:time:Get the current game time
L:-8188:T
L:-8187:skills:Check skills
L:-8187:S
L:-8186:html-dump:Save an html screenshot
L:-8186:D
L:-8184:quest:Show quest list
L:-8184:Q
L:-8183:blunder:Walk without disarming
L:-8183:B
L:-8182:ability:Check abilities
L:-8182:A
L:y:give:Give an object to a monster
L:Y:chat:Talk to a monster
L:j:jam:Jam a door

##### System Specific Subfiles #####

?:[IOR [EQU $SYS xaw] [EQU $SYS x11] [EQU $SYS gtk2]]
%:pref-x11.prf

?:[EQU $SYS gcu]
%:pref-gcu.prf

?:[EQU $SYS ami]
%:pref-ami.prf

?:[EQU $SYS mac]
%:pref-mac.prf

?:[IOR [EQU $SYS win] [EQU $SYS dos] [EQU $SYS ibm]]
%:pref-win.prf

?:[EQU $SYS emx]
%:pref-emx.prf

?:[EQU $SYS acn]
%:pref-acn.prf

?:[EQU $SYS sdl]
%:pref-sdl.prf

?:[EQU $SYS pgu]
%:pref-pgu.prf

?:1


tome-235-src/lib/pref/colors.prf0000644000076400017500000000125211012107762014401 0ustar  dgdg

# Color redefinitions

# Color 'White'
V:1:0x07:0xFF:0xFF:0xFF

# Color 'Slate'
V:2:0x03:0x8C:0x8C:0x8C

# Color 'Orange'
V:3:0x0C:0xFF:0x77:0x00

# Color 'Red'
V:4:0x04:0xC9:0x00:0x00

# Color 'Green'
V:5:0x02:0x00:0x86:0x45

# Color 'Blue'
V:6:0x01:0x00:0x00:0xE3

# Color 'Umber'
V:7:0x06:0x8E:0x45:0x00

# Color 'Light Dark'
V:8:0x08:0x50:0x50:0x50

# Color 'Light Slate'
V:9:0x0B:0xD1:0xD1:0xD1

# Color 'Violet'
V:10:0x05:0xC0:0x00:0xAF

# Color 'Yellow'
V:11:0x0E:0xFF:0xFF:0x00

# Color 'Light Red'
V:12:0x0D:0xFF:0x00:0x68

# Color 'Light Green'
V:13:0x0A:0x00:0xFF:0x00

# Color 'Light Blue'
V:14:0x09:0x51:0xDD:0xFF

# Color 'Light Umber'
V:15:0x06:0xD7:0x8E:0x45





tome-235-src/lib/pref/pref-acn.prf0000644000076400017500000000033011012107762014567 0ustar  dgdg# File: pref-acn.prf

# This is a minimal "pref" file for RISC OS


# Map cursor keys onto keypad

A:4
P:^_18C\r

A:6
P:^_18D\r

A:2
P:^_18E\r

A:8
P:^_18F\r


# Map F3 to ^S (to be a bit RISC OS-ey)

A:^S
P:^_183\r
tome-235-src/lib/pref/user.prf0000644000076400017500000000131711012107762014060 0ustar  dgdg# File: user.prf

#
# This file defines "override" actions of various kinds
#
# This file includes, if appropriate, various "sub-files"
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


## Option -- Force the use of original commands
#X:rogue_like_commands

## Option -- Force the use of roguelike commands
#Y:rogue_like_commands


##### System Specific Subfiles #####

?:[IOR [EQU $SYS xaw] [EQU $SYS x11]]
%:user-x11.prf

?:[EQU $SYS gcu]
%:user-gcu.prf

?:[EQU $SYS ami]
%:user-ami.prf

?:[EQU $SYS mac]
%:user-mac.prf

?:[EQU $SYS dos]
%:user-dos.prf

?:[EQU $SYS ibm]
%:user-ibm.prf

?:[EQU $SYS win]
%:user-win.prf

?:[EQU $SYS emx]
%:user-emx.prf

?:[EQU $SYS acn]
%:user-acn.prf

?:1


tome-235-src/lib/pref/pref-ami.prf0000644000076400017500000000017611012107762014604 0ustar  dgdg# File: pref-ami.prf

#
# This file contains various default macros for use with
# the executable built from "main-ami.c".
#

tome-235-src/lib/pref/graf-dos.prf0000644000076400017500000000041311012107762014600 0ustar  dgdg# File: graf-win.prf

#
# This file defines special attr/char mappings for use in "graphics" mode
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#

# Standard file
?:[EQU $GRAF old]
%:graf-xxx.prf

# New tiles
?:[EQU $GRAF new]
%:graf-new.prf
tome-235-src/lib/pref/graf-x11.prf0000644000076400017500000000113011012107762014421 0ustar  dgdg# File: graf-x11.prf


# Font stuff
%:font-x11.prf


# Color palette - Graphics

#V:16:0x01:0x00:0x00:0x00
#V:17:0x01:0xF0:0xE0:0xD0
#V:18:0x01:0x80:0x80:0x80
#V:19:0x01:0x50:0x50:0x50
#V:20:0x01:0xE0:0xB0:0x00
#V:21:0x01:0xC0:0xA0:0x70
#V:22:0x01:0x80:0x60:0x40
#V:23:0x01:0x50:0x3C:0x28
#V:24:0x01:0x00:0xA0:0xF0
#V:25:0x01:0x00:0x00:0xF0
#V:26:0x01:0x00:0x00:0x70
#V:27:0x01:0xF0:0x00:0x00
#V:28:0x01:0x80:0x00:0x00
#V:29:0x01:0x90:0x00:0xB0
#V:30:0x01:0x00:0x60:0x10
#V:31:0x01:0x60:0xF0:0x40


# Standard file
?:[EQU $GRAF old]
%:graf-xxx.prf

# New tiles
?:[EQU $GRAF new]
%:graf-new.prf

?:1

tome-235-src/lib/pref/graf-sdl.prf0000644000076400017500000000113011012107762014572 0ustar  dgdg# File: graf-x11.prf


# Font stuff
%:font-x11.prf


# Color palette - Graphics

#V:16:0x01:0x00:0x00:0x00
#V:17:0x01:0xF0:0xE0:0xD0
#V:18:0x01:0x80:0x80:0x80
#V:19:0x01:0x50:0x50:0x50
#V:20:0x01:0xE0:0xB0:0x00
#V:21:0x01:0xC0:0xA0:0x70
#V:22:0x01:0x80:0x60:0x40
#V:23:0x01:0x50:0x3C:0x28
#V:24:0x01:0x00:0xA0:0xF0
#V:25:0x01:0x00:0x00:0xF0
#V:26:0x01:0x00:0x00:0x70
#V:27:0x01:0xF0:0x00:0x00
#V:28:0x01:0x80:0x00:0x00
#V:29:0x01:0x90:0x00:0xB0
#V:30:0x01:0x00:0x60:0x10
#V:31:0x01:0x60:0xF0:0x40


# Standard file
?:[EQU $GRAF old]
%:graf-xxx.prf

# New tiles
?:[EQU $GRAF new]
%:graf-new.prf

?:1

tome-235-src/lib/pref/graf-xxx.prf0000644000076400017500000022024211012107762014646 0ustar  dgdg# PRF file generated by Andreas Koch`s Tile Assigner
# 23/06/2004 : Edited manually

# 2185 items 
# 2185 probably mapped correctly
# 0 imported but not yet defined
# 0 defined to value(s) lower than 0x80
# Old header :
### Special attr:char values ###
# # Unused (@)
# S:0x00:0x00:0x40
# S:0x01:0x01:0x40
# S:0x02:0x02:0x40
# S:0x03:0x03:0x40
# S:0x04:0x04:0x40
# S:0x05:0x05:0x40
# S:0x06:0x06:0x40
# S:0x07:0x07:0x40
# S:0x08:0x08:0x40
# S:0x09:0x09:0x40
# S:0x0A:0x0A:0x40
# S:0x0B:0x0B:0x40
# S:0x0C:0x0C:0x40
# S:0x0D:0x0D:0x40
# S:0x0E:0x0E:0x40
# S:0x0F:0x0F:0x40
# # Unused (@)
# S:0x10:0x00:0x40
# S:0x11:0x01:0x40
# S:0x12:0x02:0x40
# S:0x13:0x03:0x40
# S:0x14:0x04:0x40
# S:0x15:0x05:0x40
# S:0x16:0x06:0x40
# S:0x17:0x07:0x40
# S:0x18:0x08:0x40
# S:0x19:0x09:0x40
# S:0x1A:0x0A:0x40
# S:0x1B:0x0B:0x40
# S:0x1C:0x0C:0x40
# S:0x1D:0x0D:0x40
# S:0x1E:0x0E:0x40
# S:0x1F:0x0F:0x40
# # Unused (@)
# S:0x20:0x00:0x40
# S:0x21:0x01:0x40
# S:0x22:0x02:0x40
# S:0x23:0x03:0x40
# S:0x24:0x04:0x40
# S:0x25:0x05:0x40
# S:0x26:0x06:0x40
# S:0x27:0x07:0x40
# S:0x28:0x08:0x40
# S:0x29:0x09:0x40
# S:0x2A:0x0A:0x40
# S:0x2B:0x0B:0x40
# S:0x2C:0x0C:0x40
# S:0x2D:0x0D:0x40
# S:0x2E:0x0E:0x40
# S:0x2F:0x0F:0x40

# General Store
B:0:0x81/0x91

# Armoury
B:1:0x81/0x92

# Weapon Smiths
B:2:0x81/0x93

# Temple
B:3:0x81/0x94

# Alchemy Shop
B:4:0x81/0x95

# Magic Shop
B:5:0x81/0x96

# Black Market
B:6:0x81/0x97

# Home
B:7:0x81/0x98

# Bookstore
B:8:0x82/0x93

# Pet Shop
B:9:0xCB/0x96

# Mayor's Office
B:10:0xCB/0x92

# Inn
B:11:0xCB/0x95

# The Soothsayer
B:12:0xD4/0x85

# Library
B:13:0xD4/0x89

# Castle
B:14:0xCB/0x92

# Casino
B:15:0xD5/0x81

# Beastmaster Shanty
B:16:0xD3/0x8B

# Fighters Hall
B:17:0xD3/0x8C

# Tower of Magery
B:18:0xD4/0x8B

# Inner Temple
B:19:0xD4/0x9D

# Paladins Guild
B:20:0xCB/0x8F

# Rangers Guild
B:21:0xD3/0x83

# Weyr
B:22:0xCB/0x93

# The Mirror
B:23:0xD4/0x89

# Seat of Ruling
B:24:0xCB/0x92

# Wizards Spire
B:25:0xD4/0x8A

# Priests Circle
B:26:0xD4/0x92

# Tower of the King
B:27:0xCB/0x92

# Library
B:28:0xD4/0x89

# The White Tree
B:29:0xCB/0x95

# Craftsmaster
B:30:0xCB/0x97

# Earth-Dome (Nature)
B:31:0xCB/0x9A

# Minstrels Haven
B:32:0xD3/0x9F

# Star-Dome
B:33:0xD4/0x8C

# Valarin Temple
B:34:0xD4/0x90

# Sea-Dome
B:35:0xD4/0x91

# The Golden Flower
B:36:0xD3/0x83

# The Fountain
B:37:0xD4/0x9D

# Axe Smith
B:38:0xCC/0x96

# Hafted Smith
B:39:0xCC/0x97

# Polearm Smith
B:40:0xCC/0x98

# Sword Smith
B:41:0xCC/0x80

# Rare Jewelry Shop
B:42:0xD3/0x96

# Jewelry Shop
B:43:0xD3/0x93

# Footwear Shop
B:44:0xD3/0x9D

# Rare Footwear Shop
B:45:0xD3/0x9E

# Library
B:46:0xD3/0x9C

# Forbidden Library
B:47:0xD4/0x8F

# Expensive Black Market
B:48:0xD4/0x95

# Common Shop
B:49:0xD4/0x93

# Dragon Hunter
B:50:0xCC/0x89

# Speed Ring Market
B:51:0xD3/0x97

# Scribe
B:52:0xD4/0x86

# Potion Store
B:53:0xD4/0x80

# Recaller
B:54:0xD4/0x88

# Master Archer
B:55:0xD3/0x85

# Merchants Guild
B:56:0xD4/0x9B

# The Mathom-house
B:57:0xCB/0x9B

# The Prancing Pony
B:58:0xCB/0x95

# nothing
F:0:0x81/0x80

# open floor
F:1:0x80/0x80

# fountain - wet
F:2:0xD1/0x83

# glyph of warding
F:3:0xA2/0x88

# open door
F:4:0x81/0x87

# broken door
F:5:0x81/0x87

# up staircase
F:6:0x81/0x9C

# down staircase
F:7:0x81/0x9E

# quest entrance
F:8:0x82/0x8E

# quest exit
F:9:0x82/0x8B

# quest down level
F:10:0x82/0x8F

# quest up level
F:11:0x82/0x8C

# town exit
F:12:0x82/0x91

# shaft down
F:13:0x82/0x90

# shaft up
F:14:0x82/0x8D

# fountain
F:15:0xD1/0x82

# web
F:16:0x82/0x92

# Open pit
F:17:0xA2/0x96

# Spiked Pit
F:18:0xA2/0x96

# Poison Pit
F:19:0xA2/0x96

# Summon Rune
F:20:0x8A/0x9C

# Teleport Rune
F:21:0x8A/0x9C

# Fire spot
F:22:0x8A/0x9B

# Acid spot
F:23:0x8A/0x9B

# Slow dart trap
F:24:0x82/0x9E

# Lose str dart
F:25:0xA2/0x89

# Lose dex dart
F:26:0xA2/0x8D

# Lose con dart
F:27:0xA2/0x92

# gas trap - blind
F:28:0xA2/0x8E

# gas trap - confuse
F:29:0xA2/0x8F

# gas trap - poison
F:30:0xA2/0x90

# gas trap - sleep
F:31:0xA2/0x91

# door
F:32:0x81/0x8B

# locked door
F:33:0x81/0x8B
F:34:0x81/0x8B
F:35:0x81/0x8B
F:36:0x81/0x8B
F:37:0x81/0x8B
F:38:0x81/0x8B
F:39:0x81/0x8B

# jammed door
F:40:0x81/0x8B
F:41:0x81/0x8B
F:42:0x81/0x8B
F:43:0x81/0x8B
F:44:0x81/0x8B
F:45:0x81/0x8B
F:46:0x81/0x8B
F:47:0x81/0x8B

# secret door
F:48:0x80/0x82

# pile of rubble
F:49:0x81/0x9A

# magma vein
F:50:0x81/0x83

# quartz vein
F:51:0x80/0x83

# magma vein
F:52:0x81/0x83

# quartz vein
F:53:0x80/0x83

# magma vein with treasure
F:54:0x80/0x84

# quartz vein with treasure
F:55:0x80/0x84

# granite wall
F:56:0x80/0x82
F:57:0x80/0x82
F:58:0x80/0x82
F:59:0x80/0x82

# permanent wall
F:60:0x80/0x95
F:61:0x80/0x95
F:62:0x80/0x95
F:63:0x80/0x95

# explosive rune
F:64:0xA2/0x87

# Straight Road startpoint
F:65:0xA3/0x9D

# section of the Straight Road
F:66:0xA3/0x97
F:67:0xA3/0x9C
F:68:0xA3/0x9B
F:69:0xA3/0x9A
F:70:0xA3/0x98

# section of the Straight Road (discharged)
F:71:0xA3/0x98

# Straight Road exit
F:72:0xA3/0x9D

# corrupted section of the Straight Road
F:73:0xA3/0x99

# Building
F:74:0x81/0x91

# permanent wall
F:75:0x80/0x95
F:76:0x80/0x95
F:77:0x80/0x95
F:78:0x80/0x95

# Deep water
F:83:0xD2/0x83

# stream of shallow water
F:84:0xD2/0x81

# pool of deep lava
F:85:0xCB/0x89

# stream of shallow lava
F:86:0xCB/0x88

# dark pit
F:87:0x81/0x80

# dirt
F:88:0xCB/0x84

# patch of grass
F:89:0xD0/0x8E

# ice
F:90:0xCF/0x81

# sand
F:91:0xCF/0x8E

# dead tree
F:92:0xCF/0x85

# ash
F:93:0xCF/0x95

# mud
F:94:0xCF/0x8D

# ice wall
F:95:0xD0/0x88

# tree
F:96:0xCB/0x86

# mountain chain
F:97:0xCB/0x87

# sandwall
F:98:0xD0/0x87
F:99:0xD0/0x87

# sandwall with treasure
F:100:0xD0/0x8A

# high mountain chain
F:101:0xCB/0x87

# nether mist
F:102:0xC5/0x8C

# Between gate
F:160:0x8A/0x9D

# Altar of Forests
F:161:0xD1/0x85

# Altar of Water
F:162:0xD1/0x86

# Altar of Earth
F:163:0xD1/0x8E

# Altar of Darkness
F:164:0xD1/0x88

# Altar of Moon
F:165:0xD1/0x89

# Altar of Sun
F:166:0xD1/0x8C

# Altar of Rage
F:167:0xD1/0x8A

# Altar of Winds
F:168:0xD1/0x8B

# Altar of Stars
F:169:0xD1/0x8D

# Altar of Being
F:170:0xD1/0x87

# Altar of Randomness
F:171:0xD1/0x8F

# floor
F:172:0x80/0x80

# Underground Tunnel
F:173:0xCF/0x97

# stream of tainted water
F:174:0xD2/0x82

# monster trap
F:175:0x82/0x94

# Between gate
F:176:0x8A/0x9D

# lava wall
F:177:0xD0/0x86

# Great Fire
F:178:0xD1/0x90

# Path to next area
F:179:0xCF/0x9C

# Path to previous area
F:180:0xCF/0x9B

# field
F:181:0xCF/0x8A

# Ekkaia, the Encircling Sea
F:182:0xD2/0x84

# pool of deep water
F:187:0xD2/0x80

# glass wall
F:188:0xD0/0x89

# illusion wall
F:189:0xD0/0x8C

# Grass roof
F:190:0xD0/0x8F

# grass roof top
F:191:0xD0/0x8F

# grass roof chimney
F:192:0xD0/0x8F

# brick roof
F:193:0xD0/0x90

# brick roof top
F:194:0xD0/0x90

# brick roof chimney
F:195:0xD0/0x90

# window
F:196:0xD0/0x91

# small window
F:197:0xD0/0x92

# rain barrel
F:198:0xD0/0x93

# grass with flowers
F:199:0xD0/0x8D

# cobblestone road
F:200:0x82/0x8A

# cobblestone with outlet
F:201:0x82/0x8A

# small tree
F:202:0xD0/0x8B

# town
F:203:0xD0/0x94

# Underground Tunnel
F:204:0xD0/0x95

# a blazing fire
F:205:0xD1/0x84

# pile of rubble
F:206:0x81/0x9A

# ethereal wall
F:214:0x80/0x80

# glacial wall
F:215:0xD0/0x88

# something
K:0:0x80/0x80

# Blindness
K:1:0xBA/0x81

# Paranoia
K:2:0xBA/0x81

# Confusion
K:3:0xBA/0x81

# Hallucination
K:4:0xBA/0x81

# Cure Poison
K:5:0xBA/0x81

# Cure Blindness
K:6:0xBA/0x81

# Cure Paranoia
K:7:0xBA/0x81

# Cure Confusion
K:8:0xBA/0x81

# Weakness
K:9:0xBA/0x81

# Unhealth
K:10:0xBA/0x81

# Restore Constitution
K:11:0xBA/0x81

# Restoring
K:12:0xBA/0x81

# Stupidity
K:13:0xBA/0x81

# Naivety
K:14:0xBA/0x81

# Poison
K:15:0xBA/0x81

# Sickness
K:16:0xBA/0x81

# Paralysis
K:17:0xBA/0x81

# Restore Strength
K:18:0xBA/0x81

# Disease
K:19:0xBA/0x81

# Cure Serious Wounds
K:20:0xBA/0x81

# & Ration~ of Food
K:21:0x8B/0x82

# & Hard Biscuit~
K:22:0x8B/0x82

# & Strip~ of Venison
K:23:0x8B/0x82

# & Slime Mold~
K:24:0x8A/0x9F

# & Piece~ of Elvish Waybread
K:25:0x8B/0x80

# & Pint~ of Fine Ale
K:26:0x8A/0x95

# & Pint~ of Fine Wine
K:27:0x8A/0x96

# & Mattock~
K:28:0xCD/0x80

# The Blue Stone 'Toris Mejistos'
K:29:0xB6/0x89

# & Broken Dagger~
K:30:0x89/0x83

# & Bastard Sword~
K:31:0x89/0x85

# & Scimitar~
K:32:0x89/0x85

# & Tulwar~
K:33:0x89/0x84

# & Broad Sword~
K:34:0x89/0x85

# & Short Sword~
K:35:0x89/0x84

# & Blade~ of Chaos
K:36:0x89/0x87

# & Two-Handed Sword~
K:37:0x89/0x85

# & Main Gauche~
K:38:0x89/0x83

# & Cutlass~
K:39:0x89/0x84

# & Executioner's Sword~
K:40:0x89/0x86

# & Katana~
K:41:0x89/0x85

# & Long Sword~
K:42:0x89/0x85

# & Dagger~
K:43:0x89/0x83

# & Rapier~
K:44:0x89/0x84

# & Sabre~
K:45:0x89/0x84

# & Small Sword~
K:46:0x89/0x84

# & Broken Sword~
K:47:0x89/0x83

# & Ball-and-Chain~
K:48:0x89/0x88

# & Whip~
K:49:0x89/0x89

# & Flail~
K:50:0x89/0x8B

# & Two-Handed Flail~
K:51:0x89/0x8B

# & Morning Star~
K:52:0x89/0x8B

# & Mace~
K:53:0x89/0x8C

# & Quarterstaff~
K:54:0x89/0x8E

# & War Hammer~
K:55:0x89/0x8F

# & Lead-Filled Mace~
K:56:0x89/0x8C

# & Mace~ of Disruption
K:57:0x89/0x8D

# & Lucerne Hammer~
K:58:0x89/0x90

# & Beaked Axe~
K:59:0x89/0x90

# & Glaive~
K:60:0x89/0x90

# & Halberd~
K:61:0x89/0x90

# & Awl-Pike~
K:62:0x89/0x91

# & Pike~
K:63:0x89/0x91

# & Spear~
K:64:0x89/0x91

# & Trident~
K:65:0x89/0x92

# & Lance~
K:66:0x89/0x93

# & Great Axe~
K:67:0x89/0x90

# & Battle Axe~
K:68:0x89/0x90

# & Lochaber Axe~
K:69:0x89/0x90

# & Broad Axe~
K:70:0x89/0x90

# & Scythe~
K:71:0x89/0x94

# & Scythe~ of Slicing
K:72:0x89/0x94

# & Short Bow~
K:73:0x89/0x95

# & Long Bow~
K:74:0x89/0x96

# & Light Crossbow~
K:75:0x89/0x97

# & Heavy Crossbow~
K:76:0x89/0x98

# & Sling~
K:77:0x89/0x99

# & Arrow~
K:78:0x89/0x9A

# & Seeker Arrow~
K:79:0x89/0x9B

# & Bolt~
K:80:0x89/0x9C

# & Seeker Bolt~
K:81:0x89/0x9D

# & Rounded Pebble~
K:82:0x89/0x9E

# & Iron Shot~
K:83:0x89/0x9F

# & Shovel~
K:84:0x8A/0x98

# & Gnomish Shovel~
K:85:0x8B/0x8F

# & Dwarven Shovel~
K:86:0x8B/0x90

# & Pick~
K:87:0x8A/0x97

# & Orcish Pick~
K:88:0x8B/0x8D

# & Dwarven Pick~
K:89:0x8B/0x8E

# & Elven Cloak~
K:90:0x88/0x81

# & Pair~ of Soft Leather Boots
K:91:0x88/0x89

# & Pair~ of Hard Leather Boots
K:92:0x88/0x8A

# & Pair~ of Metal Shod Boots
K:93:0x88/0x8B

# & Hard Leather Cap~
K:94:0x88/0x82

# & Metal Cap~
K:95:0x88/0x83

# & Iron Helm~
K:96:0x88/0x84

# & Steel Helm~
K:97:0x88/0x85

# & Iron Crown~
K:98:0x88/0x86

# & Golden Crown~
K:99:0x88/0x87

# & Jewel Encrusted Crown~
K:100:0x88/0x88

# & Robe~
K:101:0x88/0x95

# & Filthy Rag~
K:102:0x88/0x94

# Soft Leather Armour~
K:103:0x88/0x96

# Soft Studded Leather~
K:104:0x88/0x96

# Hard Leather Armour~
K:105:0x88/0x97

# Hard Studded Leather~
K:106:0x88/0x97

# Leather Scale Mail~
K:107:0x88/0x98

# Metal Scale Mail~
K:108:0x88/0x98

# Chain Mail~
K:109:0x88/0x99

# Rusty Chain Mail~
K:110:0x88/0x9A

# Augmented Chain Mail~
K:111:0x88/0x99

# Bar Chain Mail~
K:112:0x88/0x99

# Metal Brigandine Armour~
K:113:0x88/0x99

# Partial Plate Armour~
K:114:0x88/0x9B

# Metal Lamellar Armour~
K:115:0x88/0x9B

# Full Plate Armour~
K:116:0xCD/0x82

# Ribbed Plate Armour~
K:117:0x88/0x9B

# Adamantite Plate Mail~
K:118:0xA3/0x96

# Mithril Plate Mail~
K:119:0x88/0x9C

# Mithril Chain Mail~
K:120:0x88/0x9C

# Double Chain Mail~
K:121:0x88/0x99

# & Shield~ of Deflection
K:122:0x88/0x93

# & Cloak~
K:123:0x88/0x80

# & Shadow Cloak~
K:124:0x88/0x81

# & Set~ of Leather Gloves
K:125:0x88/0x8C

# & Set~ of Gauntlets
K:126:0x88/0x8D

# & Set~ of Cesti
K:127:0x88/0x8E

# & Small Leather Shield~
K:128:0x88/0x8F

# & Large Leather Shield~
K:129:0x88/0x90

# & Small Metal Shield~
K:130:0x88/0x91

# & Large Metal Shield~
K:131:0x88/0x92

# Strength
K:132:0xB5/0x81

# Dexterity
K:133:0xB5/0x81

# Constitution
K:134:0xB5/0x81

# Intelligence
K:135:0xB5/0x81

# Speed
K:136:0xB5/0x83

# Searching
K:137:0xB5/0x80

# Teleportation
K:138:0xB5/0x80

# Slow Digestion
K:139:0xB5/0x80

# Fire Resistance
K:140:0xB5/0x80

# Cold Resistance
K:141:0xB5/0x80

# Levitation
K:142:0xB5/0x80

# Poison Resistance
K:143:0xB5/0x82

# Free Action
K:144:0xB5/0x80

# Weakness
K:145:0xB5/0x80

# Flames
K:146:0xB5/0x82

# Acid
K:147:0xB5/0x82

# Ice
K:148:0xB5/0x82

# Woe
K:149:0xB5/0x82

# Stupidity
K:150:0xB5/0x80

# Damage
K:151:0xB5/0x81

# Accuracy
K:152:0xB5/0x81

# Protection
K:153:0xB5/0x80

# Aggravate Monster
K:154:0xB5/0x80

# See Invisible
K:155:0xB5/0x81

# Sustain Strength
K:156:0xB5/0x81

# Sustain Intelligence
K:157:0xB5/0x81

# Sustain Wisdom
K:158:0xB5/0x81

# Sustain Constitution
K:159:0xB5/0x81

# Sustain Dexterity
K:160:0xB5/0x81

# Sustain Charisma
K:161:0xB5/0x81

# Slaying
K:162:0xB5/0x81

# Brilliance
K:163:0xB6/0x9F

# Charisma
K:164:0xB6/0x9F

# Searching
K:165:0xB6/0x9E

# Teleportation
K:166:0xB6/0x9E

# Slow Digestion
K:167:0xB6/0x9E

# Acid Resistance
K:168:0xB6/0x9E

# Adornment
K:169:0xB6/0x9E

# Double Ring Mail~
K:170:0xCD/0x83

# the Magi
K:171:0xB6/0x80

# Doom
K:172:0xB6/0x80

# Enchant Weapon To-Hit
K:173:0x86/0x80

# Enchant Weapon To-Dam
K:174:0x86/0x80

# Enchant Armor
K:175:0x86/0x80

# Identify
K:176:0x86/0x80

# *Identify*
K:177:0x86/0x82

# Rumour
K:178:0x86/0x80

# Chaos
K:179:0x86/0x80

# Remove Curse
K:180:0x86/0x80

# Light
K:181:0x86/0x80

# Fire
K:182:0x86/0x80

# Ice
K:183:0x86/0x80

# Summon Monster
K:184:0x86/0x80

# Phase Door
K:185:0x86/0x80

# Teleportation
K:186:0x86/0x80

# Teleport Level
K:187:0x86/0x80

# Monster Confusion
K:188:0x86/0x80

# Magic Mapping
K:189:0x86/0x80

# Rune of Protection
K:190:0x86/0x82

# *Remove Curse*
K:191:0x86/0x82

# Treasure Detection
K:192:0x86/0x80

# Object Detection
K:193:0x86/0x80

# Trap Detection
K:194:0x86/0x80

# & Sheaf Arrow~
K:195:0xCD/0x84

# & Mithril Shot~
K:196:0xCD/0x85

# Door
K:197:0x86/0x80

# Acquirement
K:198:0x86/0x80

# *Acquirement*
K:199:0x86/0x82

# Mass Genocide
K:200:0x86/0x82

# Detect Invisible
K:201:0x86/0x80

# Aggravate Monster
K:202:0x86/0x80

# Trap Creation
K:203:0x86/0x80

# Trap
K:204:0x86/0x80

# Artifact Creation
K:205:0x86/0x82

# Recharging
K:206:0x86/0x81

# Genocide
K:207:0x86/0x81

# Darkness
K:208:0x86/0x80

# Protection from Evil
K:209:0x86/0x81

# Satisfy Hunger
K:210:0x86/0x80

# Dispel Undead
K:211:0x86/0x81

# *Enchant Weapon*
K:212:0x86/0x82

# Curse Weapon
K:213:0x86/0x82

# *Enchant Armor*
K:214:0x86/0x82

# Curse Armor
K:215:0x86/0x82

# Summon Undead
K:216:0x86/0x80

# Blessing
K:217:0x86/0x80

# Holy Chant
K:218:0x86/0x80

# Holy Prayer
K:219:0x86/0x81

# Word of Recall
K:220:0x86/0x80

# *Destruction*
K:221:0x86/0x82

# Slime Mold Juice
K:222:0xBC/0x85

# Apple Juice
K:223:0xBC/0x85

# Water
K:224:0xBC/0x85

# Strength
K:225:0xBC/0x86

# Weakness
K:226:0xBC/0x85

# Restore Strength
K:227:0xBC/0x86

# Intelligence
K:228:0xBC/0x86

# Stupidity
K:229:0xBC/0x85

# Restore Intelligence
K:230:0xBC/0x86

# Wisdom
K:231:0xBC/0x86

# Naivety
K:232:0xBC/0x85

# Restore Wisdom
K:233:0xBC/0x86

# Charisma
K:234:0xBC/0x86

# Ugliness
K:235:0xBC/0x86

# Restore Charisma
K:236:0xBC/0x86

# Curing
K:237:0xBC/0x86

# Invulnerability
K:238:0xBC/0x86

# New Life
K:239:0xBC/0x86

# Cure Serious Wounds
K:240:0xBC/0x85

# Cure Critical Wounds
K:241:0xBC/0x85

# Healing
K:242:0xBC/0x85

# Constitution
K:243:0xBC/0x86

# Experience
K:244:0xBC/0x87

# Sleep
K:245:0xBC/0x85

# Blindness
K:246:0xBC/0x85

# Booze
K:247:0xBC/0x85

# Poison
K:248:0xBC/0x85

# Speed
K:249:0xBC/0x85

# Slowness
K:250:0xBC/0x85

# Dexterity
K:251:0xBC/0x86

# Restore Dexterity
K:252:0xBC/0x86

# Restore Constitution
K:253:0xBC/0x86

# Lose Memories
K:254:0xBC/0x85

# Salt Water
K:255:0xBC/0x85

# Enlightenment
K:256:0xBC/0x85

# Heroism
K:257:0xBC/0x85

# Berserk Strength
K:258:0xBC/0x85

# Boldness
K:259:0xBC/0x85

# Restore Life Levels
K:260:0xBC/0x87

# Resist Heat
K:261:0xBC/0x85

# Resist Cold
K:262:0xBC/0x85

# Detect Invisible
K:263:0xBC/0x85

# Slow Poison
K:264:0xBC/0x85

# Neutralise Poison
K:265:0xBC/0x85

# Restore Mana
K:266:0xBC/0x86

# Infra-vision
K:267:0xBC/0x85

# Resistance
K:268:0xBC/0x85

# Light
K:269:0xB7/0x8F

# Tame Monster
K:270:0xB7/0x8F

# Frost Bolts
K:271:0xB7/0x8F

# Fire Bolts
K:272:0xB7/0x90

# Stone to Mud
K:273:0xB7/0x8F

# Polymorph
K:274:0xB7/0x8F

# Heal Monster
K:275:0xB7/0x8F

# Haste Monster
K:276:0xB7/0x8F

# Slow Monster
K:277:0xB7/0x8F

# Confuse Monster
K:278:0xB7/0x8F

# Sleep Monster
K:279:0xB7/0x8F

# Drain Life
K:280:0xB7/0x91

# Trap
K:281:0xB7/0x8F

# Magic Missile
K:282:0xB7/0x8F

# Clone Monster
K:283:0xB7/0x90

# Scare Monster
K:284:0xB7/0x90

# Teleport Other
K:285:0xB7/0x8F

# Disarming
K:286:0xB7/0x8F

# Lightning Balls
K:287:0xB7/0x90

# Cold Balls
K:288:0xB7/0x90

# Fire Balls
K:289:0xB7/0x91

# Stinking Cloud
K:290:0xB7/0x8F

# Acid Balls
K:291:0xB7/0x91

# Wonder
K:292:0xB7/0x8F

# & Flight Arrow~
K:293:0xCD/0x86

# Acid Bolts
K:294:0xB7/0x90

# Dragon's Flame
K:295:0xB7/0x91

# Dragon's Frost
K:296:0xB7/0x91

# Dragon's Breath
K:297:0xB7/0x91

# Annihilation
K:298:0xB7/0x91

# Rockets
K:299:0xB7/0x91

# Trap Location
K:300:0xB9/0x99

# Treasure Location
K:301:0xB9/0x99

# Object Location
K:302:0xB9/0x99

# Teleportation
K:303:0xB9/0x99

# Earthquakes
K:304:0xB9/0x9A

# Summoning
K:305:0xB9/0x99

# Light
K:306:0xB9/0x99

# *Destruction*
K:307:0xB9/0x9B

# Starlight
K:308:0xB9/0x99

# Haste Monsters
K:309:0xB9/0x99

# Slow Monsters
K:310:0xB9/0x99

# Sleep Monsters
K:311:0xB9/0x99

# Cure Light Wounds
K:312:0xB9/0x99

# Detect Invisible
K:313:0xB9/0x99

# Speed
K:314:0xB9/0x9A

# Slowness
K:315:0xB9/0x99

# Door
K:316:0xB9/0x99

# Remove Curse
K:317:0xB9/0x9A

# Detect Evil
K:318:0xB9/0x99

# Curing
K:319:0xB9/0x9A

# Dispel Evil
K:320:0xB9/0x9B

# Probing
K:321:0xB9/0x9A

# Darkness
K:322:0xB9/0x99

# Genocide
K:323:0xB9/0x9B

# Power
K:324:0xB9/0x9C

# the Magi
K:325:0xB9/0x9C

# Perception
K:326:0xB9/0x99

# Holiness
K:327:0xB9/0x9C

# Enlightenment
K:328:0xB9/0x9A

# Healing
K:329:0xB9/0x9C

# [Call of the West]
K:330:0xA3/0x8A

# [Light of Valinor]
K:331:0xA3/0x8A

# [Divine Mastery]
K:332:0xA3/0x8A

# [Words of Power]
K:333:0xA3/0x8A

# [Apprentice Handbook]
K:334:0xA3/0x8C

# [Mystical Words]
K:335:0xA3/0x8C

# [Arcane Chants]
K:336:0xA3/0x8C

# [Locus of Force]
K:337:0xA3/0x8C

# & Small wooden chest~
K:338:0x80/0x96

# & Large wooden chest~
K:339:0x80/0x97

# & Small iron chest~
K:340:0x80/0x98

# & Large iron chest~
K:341:0x80/0x99

# & Small steel chest~
K:342:0x80/0x9A

# & Large steel chest~
K:343:0x80/0x9B

# & Ruined chest~
K:344:0x80/0x9C

# & Iron Spike~
K:345:0x8B/0x84

# & Wooden Torch~
K:346:0x8B/0x86

# & Brass Lantern~
K:347:0x8B/0x85

# & Flask~ of oil
K:348:0xBC/0x90

# & Empty Bottle~
K:349:0x8A/0x99

# Havoc
K:350:0xB8/0x94

# Door
K:351:0xB8/0x94

# Trap Location
K:352:0xB8/0x94

# Probing
K:353:0xB8/0x97

# Recall
K:354:0xB8/0x96

# Illumination
K:355:0xB8/0x95

# Light
K:356:0xB8/0x94

# Lightning Bolts
K:357:0xB8/0x94

# Frost Bolts
K:358:0xB8/0x95

# Fire Bolts
K:359:0xB8/0x95

# Polymorph
K:360:0xB8/0x95

# Slow Monster
K:361:0xB8/0x95

# Sleep Monster
K:362:0xB8/0x95

# Drain Life
K:363:0xB8/0x97

# Teleport Other
K:364:0xB8/0x96

# Disarming
K:365:0xB8/0x95

# Lightning Balls
K:366:0xB8/0x96

# Cold Balls
K:367:0xB8/0x96

# Fire Balls
K:368:0xB8/0x97

# Acid Balls
K:369:0xB8/0x97

# Acid Bolts
K:370:0xB8/0x95

# Enlightenment
K:371:0xB8/0x97

# Perception
K:372:0xB8/0x96

# Curing
K:373:0xB8/0x97

# Healing
K:374:0xB8/0x97

# Detection
K:375:0xB8/0x95

# Restoration
K:376:0xB8/0x97

# Speed
K:377:0xB8/0x97

# [Inner Void]
K:378:0xA3/0x8E

# [Lurkings of the Night]
K:379:0xA3/0x8E

# [Beings of Darkness]
K:380:0xA3/0x8E

# [Material Shadow]
K:381:0xA3/0x8E

# [Sign of Chaos]
K:383:0xA3/0x90

# [Chaos Mastery]
K:384:0xA3/0x90

# [Chaos Channels]
K:385:0xA3/0x91

# [Armageddon Tome]
K:386:0xA3/0x91

# [Nether Openings]
K:387:0xA3/0x92

# [Unholy Blessings]
K:388:0xA3/0x92

# & Firestone~
K:389:0x8B/0x88

# & Small Firestone~
K:390:0x8B/0x89

# & Broken Skull~
K:391:0x8B/0x8A

# & Broken Bone~
K:392:0x8B/0x8B

# & Canine Skeleton~
K:393:0x8B/0x87

# & Rodent Skeleton~
K:394:0x8B/0x87

# & Human Skeleton~
K:395:0x8B/0x87

# & Dwarf Skeleton~
K:396:0x8B/0x87

# & Elf Skeleton~
K:397:0x8B/0x87

# & Gnome Skeleton~
K:398:0x8B/0x87

# & Great Hammer~
K:399:0xCD/0x87

# Black Dragon Scale Mail~
K:400:0x88/0x9F

# Blue Dragon Scale Mail~
K:401:0x88/0x9D

# White Dragon Scale Mail~
K:402:0x88/0x9E

# Red Dragon Scale Mail~
K:403:0x89/0x81

# Green Dragon Scale Mail~
K:404:0x89/0x80

# Multi-Hued Dragon Scale Mail~
K:405:0x89/0x82

# Pseudo Dragon Scale Mail~
K:406:0xBB/0x9C

# Law Dragon Scale Mail~
K:407:0x88/0x9F

# Bronze Dragon Scale Mail~
K:408:0x88/0x96

# Gold Dragon Scale Mail~
K:409:0x88/0x9C

# Chaos Dragon Scale Mail~
K:410:0x89/0x80

# Balance Dragon Scale Mail~
K:411:0x88/0x99

# Power Dragon Scale Mail~
K:412:0xA2/0x9E

# & Dragon Helm~
K:413:0xA2/0x9D

# & Dragon Shield~
K:414:0xA2/0x9C

# Death
K:415:0xBC/0x88

# Ruination
K:416:0xBC/0x87

# Detonations
K:417:0xBC/0x87

# Augmentation
K:418:0xBC/0x87

# *Healing*
K:419:0xBC/0x87

# Life
K:420:0xBC/0x88

# Self Knowledge
K:421:0xBC/0x87

# *Enlightenment*
K:422:0xBC/0x88

# [Necromantic Incantations]
K:423:0xA3/0x92

# [Curses of Angmar]
K:424:0xA3/0x92

# Fear Resistance
K:425:0xB5/0x81

# Light and Darkness Resistance
K:426:0xB5/0x81

# Nether Resistance
K:427:0xB5/0x81

# Nexus Resistance
K:428:0xB5/0x81

# Sound Resistance
K:429:0xB5/0x81

# Confusion Resistance
K:430:0xB5/0x81

# Shard Resistance
K:431:0xB5/0x81

# Disenchantment Resistance
K:432:0xB5/0x81

# Chaos Resistance
K:433:0xB5/0x81

# Blindness Resistance
K:434:0xB5/0x81

# Lordly Protection
K:435:0xB5/0x81

# Extra Attacks
K:436:0xB5/0x81

# Cure Light Wounds
K:437:0xBC/0x85

# Clumsiness
K:438:0xBC/0x85

# Sickliness
K:439:0xBC/0x85

# Map of Bree
K:440:0xD8/0x81

# Map of Gondolin
K:441:0xD8/0x81

# Map of Lothlorien
K:442:0xD8/0x81

# Map of Minas Anor
K:443:0xD8/0x81

# & Silver Arrow~
K:465:0xCE/0x91

# & Silver Bolt~
K:466:0xCE/0x92

# Lightning Resistance
K:467:0x87/0x80

# Wisdom
K:468:0x87/0x80

# Regeneration
K:469:0x87/0x80

# Infravision
K:470:0x87/0x80

# Devotion
K:471:0x87/0x80

# Weaponmastery
K:472:0x87/0x80

# Trickery
K:473:0x87/0x80

# ESP
K:474:0x87/0x80

# Sustenance
K:475:0x87/0x80

# Palantir
K:476:0xD8/0x8F

# Elfstone 'Elessar'
K:477:0xB6/0x8F

# Jewel 'Evenstar'
K:478:0xB6/0x90

# Ring of Durin
K:479:0xB5/0x8E

# copper
K:480:0x80/0x8B
K:481:0x80/0x8B
K:482:0x80/0x8B

# silver
K:483:0x80/0x8C
K:484:0x80/0x8C
K:485:0x80/0x8C

# garnets
K:486:0x80/0x8F
K:487:0x80/0x8F

# gold
K:488:0x80/0x8D
K:489:0x80/0x8D
K:490:0x80/0x8D

# opals
K:491:0x80/0x90

# sapphires
K:492:0x80/0x91

# rubies
K:493:0x80/0x92

# diamonds
K:494:0x80/0x93

# emeralds
K:495:0x80/0x94

# mithril
K:496:0x80/0x8E

# adamantite
K:497:0xA3/0x95

# & Mighty Hammer~
K:498:0x87/0x9A

# & Massive Iron Crown~
K:499:0x87/0x9B

# & Phial~
K:500:0x87/0x9D

# & Star~
K:501:0x87/0x9E

# & Arkenstone~
K:502:0x87/0x9F

# & Amulet~
K:503:0xB6/0x82
K:504:0xB6/0x83

# & Necklace~
K:505:0xB6/0x84

# & Ring~
K:506:0xB5/0x83
K:507:0xB5/0x83
K:508:0xB5/0x84
K:509:0xB5/0x85
K:510:0xB5/0x86
K:511:0xB5/0x87

# [Rites of Initiation]
K:512:0xBC/0x91

# [Ways of War]
K:513:0xBC/0x91

# [Divine Retribution]
K:514:0xBC/0x92

# [Essence of Fury]
K:515:0xBC/0x92

# [Novice Crafts]
K:516:0xBC/0x95

# [Arcane Channels]
K:517:0xBC/0x95

# [Sigils of Wizardry]
K:518:0xBC/0x95

# [Mana Focus]
K:519:0xBC/0x95

# Reflection
K:520:0xB6/0x80

# Anti-Magic
K:521:0xB6/0x80

# Anti-Teleportation
K:522:0xB6/0x80

# Resistance
K:523:0xB6/0x80

# & Zweihander~
K:524:0xCD/0x88

# & Dwarven Lantern~
K:525:0xD8/0x86

# Splint Mail~
K:526:0xCD/0x8A

# & Everburning Torch~
K:527:0xD8/0x87

# & Trifurcate Spear~
K:528:0xCD/0x96

# & Three Piece Rod~
K:529:0xCD/0x8C

# & Feanorian Lamp~
K:530:0xD8/0x85

# & Fur Cloak~
K:531:0xCD/0x8E

# Potion: Water Curing
K:532:0xBC/0x84

# & Hatchet~
K:533:0xCD/0x90

# Rhino Hide Armour~
K:535:0xCD/0x91

# Leather Jacket~
K:536:0xCD/0x92

# & Sickle~
K:537:0xCD/0x93

# [Psychoportation]
K:538:0xA3/0x88

# [Clairsentience]
K:539:0xA3/0x88

# [Telekinesis]
K:540:0xA3/0x89

# [Empathy]
K:541:0xA3/0x89

# & Club~
K:542:0xCD/0x99

# & Broad Spear~
K:543:0xCD/0x9A

# & Khopesh~
K:544:0xCD/0x9B

# & Flamberge~
K:545:0xCD/0x9C

# & Claymore~
K:546:0xCD/0x9D

# & Espadon~
K:547:0xCD/0x9E

# & Great Scimitar~
K:548:0xCD/0x9F

# Trapping Kit: Arrow
K:549:0xD7/0x84

# Trapping Kit: Bolt
K:550:0xD7/0x83

# & Fauchard~
K:551:0xCE/0x82

# & Guisarme~
K:552:0xCE/0x83

# & Heavy Lance~
K:553:0xCE/0x84

# & Basillard~
K:554:0xCE/0x85

# Trapping Kit: Catapult
K:555:0xD7/0x82

# Ring Mail~
K:556:0xCE/0x87

# Cord Armour~
K:557:0xCE/0x88

# Paper Armour~
K:558:0xCE/0x89

# Padded Armour~
K:559:0xCE/0x8A

# Trap Kit: Fumes
K:560:0xD7/0x80

# Stone and Hide Armour~
K:561:0xCE/0x8C

# Trap Kit: Magic
K:562:0xD7/0x81

# Trap Kit: Device
K:563:0xD7/0x85

# Scroll: Nothing
K:564:0x86/0x80

# Poison
K:565:0xD9/0x82

# Wand: Nothing
K:566:0xB7/0x90

# Ring: Nothing
K:567:0xB5/0x80

# Staff: Nothing
K:568:0xB8/0x96

# Rod Tip: Nothing
K:569:0xB8/0x95

# Explosion
K:570:0xD9/0x82

# Teleport
K:571:0xD9/0x82

# Amulet: Nothing
K:572:0x87/0x80

# & Blood~ of Life
K:573:0x87/0x88

# Cold
K:574:0xD9/0x82

# Fire
K:575:0xD9/0x82

# Acid
K:576:0xD9/0x82

# Mage Staff
K:577:0xCE/0x97

# Lightning
K:578:0xB5/0x81

# Life
K:579:0xD9/0x82

# Confusion
K:580:0xD9/0x82

# Light
K:581:0xD9/0x82

# Ring of F'Lar
K:582:0xB5/0x8F

# Invisibility
K:583:0xB8/0x85

# Chaos
K:584:0xD9/0x82

# Corruption
K:585:0xB8/0x85

# Invisibility
K:586:0xB5/0x81

# Time
K:587:0xD9/0x82

# Deep Thoughts
K:588:0xD8/0x80

# More Deep Thoughts
K:589:0xD8/0x80

# Compendium of Deep Thoughts
K:590:0xD8/0x80

# Artifact Lore Vol. I
K:591:0xD8/0x80

# Artifact Lore Vol. II
K:592:0xD8/0x80

# Artifact Lore Vol. III
K:593:0xD8/0x80

# Monstrous Compendium 1
K:594:0xD8/0x80

# Monstrous Compendium 2
K:595:0xD8/0x80

# Monstrous Compendium 3
K:596:0xD8/0x80

# Monstrous Compendium 4
K:597:0xD8/0x80

# Monstrous Compendium 5
K:598:0xD8/0x80

# Monstrous Compendium 6
K:599:0xD8/0x80

# Monstrous Compendium 7
K:600:0xD8/0x80

# Monstrous Compendium 8
K:601:0xD8/0x80

# Monstrous Compendium 9
K:602:0xD8/0x80

# Monstrous Compendium 10
K:603:0xD8/0x80

# Monstrous Compendium 11
K:604:0xD8/0x80

# Abomination
K:605:0xBC/0x85

# Shape of Wolf
K:606:0xBC/0x85

# Shape of Ape
K:607:0xBC/0x85

# Shape of Goat
K:608:0xBC/0x85

# Shape of Insect
K:609:0xBC/0x85

# Shape of Sparrow
K:610:0xBC/0x85

# Shape of Ent
K:611:0xBC/0x85

# Shape of Vampire
K:612:0xBC/0x85

# Shape of Spider
K:613:0xBC/0x85

# Shape of Mana ball
K:614:0xBC/0x85

# Shape of Fire cloud
K:615:0xBC/0x85

# Shape of Cold cloud
K:616:0xBC/0x85

# Shape of Chaos cloud
K:617:0xBC/0x85

# [Wolf]
K:618:0xCE/0x93

# [Ape]
K:619:0xCE/0x93

# [Goat]
K:620:0xCE/0x93

# [Insect]
K:621:0xCE/0x93

# [Sparrow]
K:622:0xCE/0x93

# [Ent]
K:623:0xCE/0x93

# [Vampire]
K:624:0xCE/0x93

# [Spider]
K:625:0xCE/0x93

# [Mana ball]
K:626:0xCE/0x93

# [Fire cloud]
K:627:0xCE/0x93

# [Cold cloud]
K:628:0xCE/0x93

# [Chaos Cloud]
K:629:0xCE/0x93

# [Ghost]
K:630:0xCE/0x93

# [Kobold]
K:631:0xCE/0x93

# [Dragon]
K:632:0xCE/0x93

# [Demon]
K:633:0xCE/0x93

# [Hound]
K:634:0xCE/0x93

# [Quylthulg]
K:635:0xCE/0x93

# [Maia]
K:636:0xCE/0x93

# [Serpent]
K:637:0xCE/0x93

# [Giant]
K:638:0xCE/0x93

# [Vala]
K:639:0xCE/0x93

# Magic
K:640:0xD9/0x82

# corpse
K:641:0xB4/0x90

# skeleton
K:642:0xB4/0x8B

# head
K:643:0xB4/0x8E

# skull
K:644:0xB4/0x8F

# raw meat
K:645:0xB4/0x8C

# Dragonrider Coat
K:646:0xCE/0x98

# Stone of Lore
K:647:0xD8/0x90

# small wooden boomerang
K:648:0xCE/0x99

# large wooden boomerang
K:649:0xCE/0x9A

# small metal boomerang
K:650:0xCE/0x9B

# large metal boomerang
K:651:0xCE/0x9C

# The Space-Time Anchor
K:652:0xD8/0x91

# Summon never-moving pet
K:654:0x86/0x80

# [Life in symbiosis]
K:655:0xA3/0x84

# [Perfect Symbiosis]
K:656:0xA3/0x85

# Cure Light Insanity
K:657:0xBC/0x85

# Cure Serious Insanity
K:658:0xBC/0x85

# Cure Critical Insanity
K:659:0xBC/0x85

# Cure Insanity
K:660:0xBC/0x85

# & Phial~
K:661:0x87/0x9D

# Craftmanship
K:663:0x86/0x82

# The One Ring
K:664:0xD8/0x81

# [Apprentice Handbook]
K:665:0xA3/0x81

# [Minstrel's Music]
K:666:0xA3/0x81

# [Harps of Rivendell]
K:667:0x8A/0x90

# [Lays of Beleriand]
K:668:0x8A/0x90

# & Flute~
K:669:0xD8/0x88

# & Drum~
K:670:0xD8/0x89

# & Harp~
K:671:0xD8/0x8A

# & Banjo~
K:672:0xD8/0x8B

# & Lute~
K:673:0xD8/0x8C

# & Mandolin~
K:674:0xD8/0x8D

# Palantir of Orthanc
K:675:0xD8/0x8F

# Egg
K:676:0xD8/0x84

# Reset Recall
K:677:0x86/0x81

# Divination
K:678:0x86/0x81

# Rune: Self
K:679:0xDA/0x80

# Rune: Ray
K:680:0xDA/0x80

# Rune: Sphere
K:681:0xDA/0x80

# Rune: Knowledge
K:682:0xDA/0x80

# Rune: Life
K:683:0xDA/0x84

# Rune: Fire
K:684:0xDA/0x81

# Rune: Cold
K:685:0xDA/0x80

# Rune: Lightning
K:686:0xDA/0x85

# Rune: Acid
K:687:0xDA/0x88

# Rune: Element
K:688:0xDA/0x89

# Rune: Chaos
K:689:0xDA/0x83

# Rune: Mind
K:690:0xDA/0x84

# Rune: Holding
K:691:0xDA/0x84

# Rune: Arrow
K:692:0xDA/0x80

# Rune: Power Surge
K:693:0xDA/0x80

# Rune: Armageddon
K:694:0xDA/0x80

# Rune: Gravity
K:695:0xDA/0x82

# Essence: Extra Life
K:696:0xD9/0x82

# Rune: Undeath
K:697:0xDA/0x82

# Rune: Protection
K:698:0xDA/0x82

# Horn
K:699:0xD8/0x8E

# The Ring of Precognition
K:700:0xB5/0x8E

# Sprig of Athelas
K:701:0xCE/0x96

# [Magic for Beginners]
K:702:0x8A/0x80

# [Conjurings and Tricks]
K:703:0x8A/0x80

# [Incantations and Illusions]
K:704:0x8A/0x80

# [Sorcery and Evocations]
K:705:0x8A/0x80

# [Beginners Handbook]
K:706:0x8A/0x89

# [Words of Wisdom]
K:707:0x8A/0x89

# [Chants and Blessings]
K:708:0x8A/0x89

# [Exorcism and Dispelling]
K:709:0x8A/0x89

# [Resistance of Scarabtarices]
K:710:0x8A/0x88

# [Mordenkainen's Escapes]
K:711:0x8A/0x88

# [Kelek's Grimoire of Power]
K:712:0x8A/0x88

# [Tenser's Transformations]
K:713:0x8A/0x88

# [Raal's Tome of Destruction]
K:714:0x8A/0x88

# [Ethereal Openings]
K:715:0x8A/0x85

# [Godly Insights]
K:716:0x8A/0x85

# [Purifications and Healing]
K:717:0x8A/0x85

# [Holy Infusions]
K:718:0x8A/0x85

# [Wrath of God]
K:719:0x8A/0x85

# & Old Scroll~ of Deincarnation
K:720:0x85/0x80

# Dark Sword
K:721:0xCE/0x9D

# Numenorean for beginners (I)
K:722:0xD8/0x81

# Numenorean for beginners (II)
K:723:0xD8/0x81

# Advanced lessons of Numenorean
K:724:0xD8/0x81

# Advanced lessons of Sindarin
K:725:0xD8/0x81

# & Shard~ of Pottery
K:726:0x8B/0x88

# & Broken Stick~
K:727:0x8B/0x89

# Wall Creation
K:728:0xB5/0x80

# [Illusions for Beginners]
K:729:0xA3/0x86

# [Tricks and Visions]
K:730:0xA3/0x86

# [Phantasms and Illusions]
K:731:0xA3/0x86

# [Shadows and Prisms]
K:732:0xA3/0x86

# [Serten's Immunities]
K:733:0xA3/0x87

# [Knowledge of Kenault]
K:734:0xA3/0x87

# [Otiluke's Spheres]
K:735:0xA3/0x87

# [Boccob's Book of Shadows]
K:736:0xA3/0x87

# [Bigby's Handbook]
K:737:0xA3/0x87

# [Hunt of Orome]
K:738:0xA3/0x8B

# [Holy Sanctifications]
K:739:0xA3/0x8B

# [Secrets of the Feanturi]
K:740:0xA3/0x8B

# [War of Wrath]
K:741:0xA3/0x8B

# [Gifts of Iluvatar]
K:742:0xA3/0x8B

# & Potion~ of Learning
K:743:0x87/0x86

# [Eye of Sauron]
K:744:0xA3/0x93

# [Flame of Udun]
K:745:0xA3/0x93

# [Corruptions of Melkor]
K:746:0xA3/0x93

# [Crescent of Morgul]
K:747:0xA3/0x93

# [Morgoth's Ring]
K:748:0xA3/0x93

# Scroll: Spell
K:749:0x86/0x82

# Staff: Wishing
K:750:0xB9/0x9B

# Khuzdul - The hidden tongue of the Dwarves
K:751:0xD8/0x81

# Nandorin for dummies
K:752:0xD8/0x81

# Advanced lessons of Orcish
K:753:0xD8/0x81

# Ring: Flying
K:755:0xB5/0x80

# [Powerful Sigils]
K:756:0xA3/0x8D

# [Disruptive Forces]
K:758:0xA3/0x8D

# [Forces of the Mind]
K:759:0xA3/0x8D

# [Power of Ancient Sorcerors]
K:760:0xA3/0x8D

# [Tricks of the Wild]
K:761:0xBC/0x93

# [Mastering the Rituals]
K:762:0xBC/0x93

# [Rites of Power]
K:763:0xBC/0x94

# [Tribal Power]
K:764:0xBC/0x94

# [Aiding Shades]
K:765:0xA3/0x8F

# [Morgoth's Space-Time Warpings]
K:766:0xA3/0x8F

# [Murazor's Tome of Conjuring & Dispelling]
K:767:0xA3/0x8F

# [Channeling the Void]
K:768:0xA3/0x8F

# [Sauron's Forgotten Tome]
K:769:0xA3/0x8F

# Ring of Phasing
K:770:0xB5/0x8E

# [Earth]
K:771:0xD8/0x82

# [Fire]
K:772:0xD8/0x82

# [Air]
K:773:0xD8/0x83

# [Water]
K:774:0xD8/0x83

# [Mana]
K:775:0xD8/0x83

# Rod Tip: Home Summoning
K:776:0xB8/0x84

# Shadow Blade
K:777:0xCD/0x9C

# Bluesteel Blade
K:778:0xCE/0x9E

# Amulet: of the Serpents
K:779:0xB6/0x9F

# Darkness
K:780:0xD9/0x82

# Knowledge
K:781:0xD9/0x82

# Force
K:782:0xD9/0x82

# Lightning
K:783:0xD9/0x82

# Mana
K:784:0xD9/0x82

# Nazgul Ring
K:785:0xB5/0x85

# Climbing Set
K:786:0xD8/0x92

# Adventurer's guide to Middle-earth
K:787:0xD8/0x80

# [Dark Incantations]
K:788:0xCE/0x94

# [Immortal Rituals]
K:789:0xCE/0x94

# [Minions of Azathoth]
K:790:0xCE/0x95

# [Demonthoughts]
K:791:0xCE/0x95

# [Hellfire Tome]
K:792:0xCE/0x95

# Rod: Wooden
K:793:0xDB/0x80

# Rod: Copper
K:794:0xDB/0x81

# Rod: Iron
K:795:0xDB/0x82

# Rod: Aluminium
K:796:0xDB/0x83

# Rod: Silver
K:797:0xDB/0x84

# Rod: Golden
K:798:0xDB/0x85

# Rod: Mithril
K:799:0xDB/0x86

# Rod: Adamantite
K:800:0xDB/0x87

# Greater Ration of Health
K:801:0x8A/0x9E

# Scroll of Mass Ressurrection
K:802:0x86/0x82

# Cleaver
K:803:0xD8/0x93

# Light War Axe
K:804:0xD8/0x94

# Slaughter Axe
K:805:0xD8/0x95

# Runestone
K:806:0xDA/0x83

# Fortune Cookie
K:807:0x8A/0x93

# Portable Hole
K:808:0xD8/0x96

# Ring: Critical Hits
K:809:0xB5/0x82

# Wand of Digging of Thrain
K:810:0xB8/0x97

# Gnarled Staff of Holy Fire of Mithrandir
K:811:0xCE/0x9F

# Partial Totem
K:812:0xB4/0x82

# True Totem
K:813:0xB4/0x85

# Player
R:0:0x8C/0x81

# Filthy street urchin
R:1:0x9B/0x8A

# Scrawny cat
R:2:0x98/0x8B

# Sparrow
R:3:0xBD/0x87

# Chaffinch
R:4:0xBD/0x86

# Wild rabbit
R:5:0xBF/0x85

# Woodsman
R:6:0xBD/0x88

# Scruffy little dog
R:7:0x8E/0x9D

# Farmer Maggot
R:8:0x9B/0x8B

# Blubbering idiot
R:9:0x9B/0x8C

# Boil-covered wretch
R:10:0x9B/0x8D

# Village idiot
R:11:0x9B/0x8E

# Pitiful-looking beggar
R:12:0xBB/0x82

# Mangy-looking leper
R:13:0x9B/0x90

# Agent of the black market
R:14:0xA2/0x94

# Singing, happy drunk
R:15:0x9B/0x92

# Aimless-looking merchant
R:16:0x9B/0x93

# Mean-looking mercenary
R:17:0x9B/0x94

# Battle-scarred veteran
R:18:0x9B/0x95

# Martti Ihrasaari
R:19:0xA1/0x8D

# Grey mold
R:20:0x9A/0x88

# Large white snake
R:21:0x93/0x8A

# Grey mushroom patch
R:22:0x8E/0x85

# Newt
R:23:0xA0/0x86

# Giant white centipede
R:24:0x96/0x9E

# White icky thing
R:25:0x99/0x8C

# Clear icky thing
R:26:0x99/0x8D

# Giant white mouse
R:27:0x9D/0x8F

# Large brown snake
R:28:0x93/0x92

# Small kobold
R:29:0x9A/0x82

# Kobold
R:30:0x9A/0x83

# White worm mass
R:31:0x9E/0x88

# Floating eye
R:32:0x98/0x84

# Rock lizard
R:33:0x93/0x8B

# Grid bug
R:34:0xA2/0x9B

# Jackal
R:35:0x8E/0x9E

# Soldier ant
R:36:0x96/0x8F

# Fruit bat
R:37:0x96/0x98

# Insect swarm
R:38:0xBD/0x89

# The Greater hell-beast
R:39:0xA2/0x82

# Shrieker mushroom patch
R:40:0x8E/0x86

# Blubbering icky thing
R:41:0x99/0x8E

# Metallic green centipede
R:42:0x96/0x9F

# Novice warrior
R:43:0x9B/0x96

# Novice rogue
R:44:0x9B/0x97

# Novice priest
R:45:0x9B/0x98

# Novice mage
R:46:0x9B/0x99

# Yellow mushroom patch
R:47:0x8E/0x87

# White jelly
R:48:0x99/0x93

# Giant black ant
R:49:0x96/0x90

# Salamander
R:50:0x93/0x8D

# White harpy
R:51:0x91/0x8C

# Blue yeek
R:52:0x9E/0x92

# Grip, Farmer Maggot's dog
R:53:0x8E/0x9F

# Wolf, Farmer Maggot's dog
R:54:0xBD/0x8A

# Fang, Farmer Maggot's dog
R:55:0x8F/0x80

# Giant green frog
R:56:0x93/0x8C

# Freesia
R:57:0xBC/0x98

# Green worm mass
R:58:0x9E/0x89

# Large yellow snake
R:59:0x93/0x91

# Cave spider
R:60:0x94/0x82

# Crow
R:61:0xBD/0x8B

# Wild cat
R:62:0x98/0x8C

# Smeagol
R:63:0x9B/0x9A

# Green ooze
R:64:0x99/0x94

# Poltergeist
R:65:0x90/0x9D

# Yellow jelly
R:66:0x99/0x96

# Metallic blue centipede
R:67:0x97/0x80

# Raven
R:68:0xBD/0x8C

# Giant white louse
R:69:0x9A/0x86

# Giant yellow centipede
R:70:0x96/0x9D

# Black naga
R:71:0x9A/0x91

# Spotted mushroom patch
R:72:0x8E/0x88

# Silver jelly
R:73:0x99/0x95

# Scruffy-looking hobbit
R:74:0x98/0x9C

# Giant white ant
R:75:0x96/0x91

# Yellow mold
R:76:0x9A/0x89

# Metallic red centipede
R:77:0x97/0x81

# Yellow worm mass
R:78:0x9E/0x8A

# Clear worm mass
R:79:0x9E/0x8B

# Radiation eye
R:80:0x98/0x85

# Yellow light
R:81:0xBD/0x92

# Cave lizard
R:82:0x93/0x8F

# Novice ranger
R:83:0x9B/0x9B

# Blue jelly
R:84:0x99/0x97

# Creeping copper coins
R:85:0x8E/0x80

# Giant white rat
R:86:0x9D/0x90

# Snotling
R:87:0xBD/0x8D

# Swordfish
R:88:0xBE/0x81

# Blue worm mass
R:89:0x9E/0x8C

# Large grey snake
R:90:0x93/0x90

# Skeleton kobold
R:91:0x9D/0x93

# Ewok
R:92:0xBB/0x90

# Novice mage
R:93:0x9B/0x9D

# Green naga
R:94:0x9A/0x92

# Giant leech
R:95:0xBD/0x8E

# Barracuda
R:96:0xBE/0x82

# Novice paladin
R:97:0x9B/0x9C

# Zog
R:98:0xBD/0x8F

# Blue ooze
R:99:0x99/0x98

# Green glutton ghost
R:100:0x90/0x9E

# Green jelly
R:101:0x99/0x99

# Large kobold
R:102:0x9A/0x84

# Grey icky thing
R:103:0x99/0x8F

# Disenchanter eye
R:104:0x98/0x86

# Red worm mass
R:105:0x9E/0x8D

# Copperhead snake
R:106:0x93/0x91

# Death sword
R:107:0x89/0x85

# Purple mushroom patch
R:108:0x8E/0x89

# Novice priest
R:109:0x9B/0x9E

# Novice warrior
R:110:0x9B/0x9F

# Nibelung
R:111:0xBB/0x8E

# The disembodied hand that strangled people
R:112:0x9F/0x87

# Brown mold
R:113:0x9A/0x8A

# Giant brown bat
R:114:0x96/0x99

# Rat-thing
R:115:0xBD/0x90

# Novice rogue
R:116:0x9C/0x81

# Creeping silver coins
R:117:0x8E/0x81

# Snaga
R:118:0x9A/0x97

# Rattlesnake
R:119:0x93/0x92

# Giant slug
R:120:0xBD/0x93

# Giant pink frog
R:121:0x93/0x93

# Dark elf
R:122:0x98/0x9E

# Zombified kobold
R:123:0x9E/0x97

# Crypt creep
R:124:0x9F/0x93

# Rotting corpse
R:125:0xBB/0x8B

# Cave orc
R:126:0x9A/0x98

# Wood spider
R:127:0x94/0x83

# Manes
R:128:0x91/0x96

# Bloodshot eye
R:129:0x98/0x87

# Red naga
R:130:0x9A/0x93

# Red jelly
R:131:0x99/0x9A

# Green icky thing
R:132:0x99/0x90

# Lost soul
R:133:0x90/0x9F

# Night lizard
R:134:0x93/0x94

# Mughash, the Kobold Lord
R:135:0x9A/0x85

# Skeleton orc
R:136:0x9D/0x94

# Wormtongue, Agent of Saruman
R:137:0xBC/0x9A

# Robin Hood, the Outlaw
R:138:0xBB/0x88

# Nurgling
R:139:0xBD/0x94

# Lagduf, the Snaga
R:140:0x9A/0x99

# Brown yeek
R:141:0x9E/0x93

# Novice ranger
R:142:0x9B/0x9B

# Giant salamander
R:143:0x93/0x95

# Space monster
R:144:0x8A/0x9B

# Carnivorous flying monkey
R:145:0xBD/0x95

# Green mold
R:146:0x9A/0x8B

# Novice paladin
R:147:0x9B/0x9C

# Lemure
R:148:0x91/0x97

# Hill orc
R:149:0x9A/0x9A

# Bandit
R:150:0x9C/0x85

# Hunting hawk
R:151:0x96/0x99

# Phantom warrior
R:152:0xA0/0x83

# Gremlin
R:153:0xA1/0x86

# Yeti
R:154:0x95/0x99

# Bloodshot icky thing
R:155:0x99/0x91

# Giant grey rat
R:156:0x9D/0x91

# Black harpy
R:157:0x91/0x8D

# Skaven
R:158:0xBD/0x96

# The wounded bear
R:159:0xBD/0x98

# Cave bear
R:160:0xB0/0x82

# Rock mole
R:161:0xBD/0x99

# Mindcrafter
R:162:0xB0/0x85

# Baby blue dragon
R:163:0x97/0x86

# Baby white dragon
R:164:0x97/0x87

# Baby green dragon
R:165:0x97/0x88

# Baby black dragon
R:166:0x97/0x89

# Baby red dragon
R:167:0x97/0x8A

# Giant red ant
R:168:0x96/0x96

# Brodda, the Easterling
R:169:0x9C/0x86

# Bloodfang, the Wolf
R:170:0xBD/0x9A

# King cobra
R:171:0x93/0x96

# Eagle
R:172:0xBD/0x9B

# War bear
R:173:0x9F/0x9D

# Killer bee
R:174:0xA0/0x88

# Giant spider
R:175:0x94/0x87

# Giant white tick
R:176:0x9D/0x9C

# The Borshin
R:177:0xBD/0x9C

# Dark elven mage
R:178:0x98/0x9F

# Kamikaze yeek
R:179:0xBD/0x9D

# Orfax, Son of Boldor
R:180:0x9E/0x94

# Servant of Glaaki
R:181:0xBD/0x9E

# Dark elven warrior
R:182:0x99/0x80

# Sand-dweller
R:183:0xBF/0x80

# Clear mushroom patch
R:184:0x8E/0x8A

# Quiver slot
R:185:0x89/0x9A

# Grishnakh, the Hill Orc
R:186:0x9A/0x9C

# Giant tan bat
R:187:0x96/0x99

# Owlbear
R:188:0xBF/0x81

# Blue horror
R:189:0xBF/0x82

# Hairy mold
R:190:0x9A/0x8C

# Grizzly bear
R:191:0xBF/0x83

# Disenchanter mold
R:192:0x9A/0x8D

# Pseudo dragon
R:193:0xBB/0x9B

# Tengu
R:194:0x91/0x98

# Creeping gold coins
R:195:0x8E/0x82

# Wolf
R:196:0x8F/0x81

# Giant fruit fly
R:197:0x90/0x95

# Panther
R:198:0x98/0x8D

# Brigand
R:199:0x9C/0x87

# Hobbes the Tiger
R:200:0x98/0x8E

# Shadow Creature of Fiona
R:201:0xBB/0x8F

# Undead mass
R:202:0xA0/0x89

# Chaos shapechanger
R:203:0xA0/0x8E

# Baby multi-hued dragon
R:204:0x97/0x8C

# Vorpal bunny
R:205:0xBF/0x84

# Old Man Willow
R:206:0xBF/0x86

# Hippocampus
R:207:0xBE/0x85

# Zombified orc
R:208:0x9E/0x98

# Hippogriff
R:209:0x91/0x8E

# Black mamba
R:210:0x93/0x97

# White wolf
R:211:0x8F/0x82

# Grape jelly
R:212:0x99/0x9B

# Nether worm mass
R:213:0x9E/0x8E

# Abyss worm mass
R:214:0xA0/0x8C

# Golfimbul, the Hill Orc Chief
R:215:0x9A/0x9D

# Swordsman
R:216:0x9C/0x89

# Skaven shaman
R:217:0xBD/0x97

# Baby bronze dragon
R:218:0xB0/0x89

# Baby gold dragon
R:219:0xB0/0x8A

# Evil eye
R:220:0xB0/0x8B

# Mine-dog
R:221:0xBF/0x88

# Hellcat
R:222:0xBC/0x97

# Moon beast
R:223:0xBB/0x9E

# Master yeek
R:224:0x9E/0x95

# Priest
R:225:0x9C/0x88

# Dark elven priest
R:226:0x99/0x82

# Air spirit
R:227:0x90/0x83

# Skeleton human
R:228:0x9D/0x95

# Zombified human
R:229:0x9E/0x99

# Tiger
R:230:0x98/0x8E

# Moaning spirit
R:231:0x91/0x80

# Stegocentipede
R:232:0x97/0x82

# Spotted jelly
R:233:0x99/0x9C

# Drider
R:234:0x94/0x85

# Mongbat
R:235:0xC4/0x80

# Killer brown beetle
R:236:0x92/0x80

# Boldor, King of the Yeeks
R:237:0x9E/0x96

# Ogre
R:238:0x92/0x90

# Creeping mithril coins
R:239:0x8E/0x83

# Illusionist
R:240:0x9C/0x8A

# Druid
R:241:0x9C/0x8B

# Pink horror
R:242:0xBF/0x89

# Cloaker
R:243:0xBF/0x8A

# Black orc
R:244:0x9A/0x9E

# Ochre jelly
R:245:0x99/0x9D

# Software bug
R:246:0xA0/0x92

# Lurker
R:247:0x80/0x80

# Tangleweed
R:248:0xBE/0x9E

# Vlasta
R:249:0xBF/0x8C

# Giant white dragon fly
R:250:0x90/0x97

# Snaga sapper
R:251:0xBF/0x8D

# Blue icky thing
R:252:0x99/0x92

# Gibbering mouther
R:253:0xA0/0x8A

# Wolfhound of Flora
R:254:0xA0/0x91

# Hill giant
R:255:0x92/0x96

# Flesh golem
R:256:0x98/0x92

# Warg
R:257:0x8F/0x83

# Cheerful leprechaun
R:258:0xA0/0x93

# Giant flea
R:259:0x90/0x96

# Ufthak of Cirith Ungol
R:260:0x9A/0x9F

# Clay golem
R:261:0x98/0x93

# Black ogre
R:262:0x92/0x91

# Dweller on the threshold
R:263:0xC4/0x83

# Half-orc
R:264:0x9B/0x80

# Dark naga
R:265:0xBF/0x8E

# Poison ivy
R:266:0xBE/0x9C

# Magic mushroom patch
R:267:0x8E/0x8B

# Plaguebearer of Nurgle
R:268:0xBF/0x8F

# Guardian naga
R:269:0x9A/0x94

# Wererat
R:270:0x9D/0x92

# Light hound
R:271:0x95/0x9B

# Dark hound
R:272:0x95/0x9C

# Flying skull
R:273:0xA0/0x95

# Mi-Go
R:274:0x9F/0x9F

# Giant tarantula
R:275:0x94/0x86

# Giant clear centipede
R:276:0x97/0x83

# Mirkwood spider
R:277:0x94/0x84

# Frost giant
R:278:0x92/0x97

# Griffon
R:279:0x91/0x8F

# Homunculus
R:280:0x91/0x99

# Gnome mage
R:281:0x99/0x83

# Clear hound
R:282:0x95/0x9D

# Umber hulk
R:283:0x94/0x9E

# Rust monster
R:284:0xBF/0x90

# Ogrillon
R:285:0xB0/0x8C

# Gelatinous cube
R:286:0x99/0x9E

# Giant green dragon fly
R:287:0x90/0x98

# Fire giant
R:288:0x92/0x98

# Hummerhorn
R:289:0x90/0x99

# Lizard man
R:290:0xBF/0x91

# Ulfast, Son of Ulfang
R:291:0x9C/0x8C

# Crebain
R:292:0xC4/0x94

# Berserker
R:293:0xBF/0x92

# Quasit
R:294:0x91/0x9A

# Sphinx
R:295:0xBF/0x93

# Imp
R:296:0x91/0x9B

# Forest troll
R:297:0x94/0x8E

# Freezing sphere
R:298:0xBF/0x94

# Jumping fireball
R:299:0xBF/0x95

# Ball lightning
R:300:0xBF/0x96

# 2-headed hydra
R:301:0x93/0x98

# Swamp thing
R:302:0xBF/0x97

# Water spirit
R:303:0x90/0x84

# Giant red scorpion
R:304:0x94/0x8C

# Earth spirit
R:305:0x90/0x85

# Fire spirit
R:306:0x90/0x86

# Fire hound
R:307:0x95/0x9E

# Cold hound
R:308:0x95/0x9F

# Energy hound
R:309:0x96/0x80

# Lesser Mimic
R:310:0x8E/0x8F

# Door mimic
R:311:0xBF/0x98

# Blink dog
R:312:0x8F/0x84

# Uruk
R:313:0x9B/0x82

# Shagrat, the Orc Captain
R:314:0x9B/0x83

# Gorbag, the Orc Captain
R:315:0x9B/0x84

# Shambling mound
R:316:0x8E/0x8C

# Giant Venus Flytrap
R:317:0xBE/0x9D

# Chaos beastman
R:318:0xBF/0x99

# Daemonette of Slaanesh
R:319:0xBF/0x9A

# Giant bronze dragon fly
R:320:0x90/0x9C

# Stone giant
R:321:0x92/0x99

# Giant black dragon fly
R:322:0x90/0x9A

# Stone golem
R:323:0x98/0x94

# Red mold
R:324:0x9A/0x8E

# Giant gold dragon fly
R:325:0x90/0x9B

# Stunwall
R:326:0xBF/0x9B

# Ghast
R:327:0xBF/0x9C

# Neekerbreeker
R:328:0xBE/0x86

# Huorn
R:329:0xBF/0x9D

# Bolg, Son of Azog
R:330:0x9B/0x85

# Phase spider
R:331:0x94/0x89

# Lizard king
R:332:0xBF/0x9E

# Landmine
R:333:0xBF/0x9F

# Wyvern
R:334:0xA0/0x97

# Great eagle
R:335:0xC0/0x80

# Livingstone
R:336:0x80/0x82

# Earth hound
R:337:0x96/0x81

# Air hound
R:338:0x96/0x82

# Sabre-tooth tiger
R:339:0x98/0x8F

# Acid hound
R:340:0x96/0x83

# Chimaera
R:341:0x91/0x90

# Quylthulg
R:342:0x92/0x9F

# Sasquatch
R:343:0x95/0x9A

# Weir
R:344:0xA0/0x96

# Ranger
R:345:0x9C/0x83

# Paladin
R:346:0x8D/0x9C

# Werewolf
R:347:0x8F/0x85

# Dark elven lord
R:348:0x99/0x85

# Cloud giant
R:349:0x92/0x9A

# Ugluk, the Uruk
R:350:0x9B/0x86

# Blue dragon bat
R:351:0x96/0x9A

# Mimic
R:352:0x86/0x82

# Ultimate Mimic
R:353:0xC0/0x83

# Fire vortex
R:354:0x9D/0x9E

# Acid vortex
R:355:0x9D/0x9F

# Lugdush, the Uruk
R:356:0x9B/0x87

# Arch-vile
R:357:0xC0/0x84

# Cold vortex
R:358:0x9E/0x80

# Energy vortex
R:359:0x9E/0x81

# Globefish
R:360:0xBE/0x8D

# Giant firefly
R:361:0xB0/0x8D

# Mummified orc
R:362:0x92/0x8D

# Wolf chieftain
R:363:0xBE/0x8E

# Serpent man
R:364:0xC0/0x85

# Vampiric mist
R:365:0xC0/0x86

# Killer stag beetle
R:366:0x92/0x81

# Iron golem
R:367:0x98/0x95

# Auto-roller
R:368:0xA0/0x98

# Giant yellow scorpion
R:369:0x94/0x8A

# Jade monk
R:370:0xC0/0x87

# Black ooze
R:371:0x99/0x9F

# Hardened warrior
R:372:0x9C/0x8D

# Azog, King of the Uruk-Hai
R:373:0x9B/0x88

# Fleshhound of Khorne
R:374:0xC0/0x89

# Dark elven warlock
R:375:0xA0/0x81

# Master rogue
R:376:0x9C/0x8E

# Red dragon bat
R:377:0x96/0x9B

# Killer white beetle
R:378:0x96/0x91

# Ice skeleton
R:379:0xC0/0x8A

# Angamaite of Umbar
R:380:0x9C/0x90

# Forest wight
R:381:0x95/0x83

# Khim, Son of Mim
R:382:0x99/0x87

# Ibun, Son of Mim
R:383:0x99/0x86

# Meneldor the Swift
R:384:0xC0/0x8B

# Phantom beast
R:385:0xA0/0x84

# Giant silver ant
R:386:0xB0/0x87

# 4-headed hydra
R:387:0x93/0x9A

# Lesser hell-beast
R:388:0xC0/0x8C

# Tyrannosaur
R:389:0x9F/0x94

# Mummified human
R:390:0x92/0x8E

# Vampire bat
R:391:0x96/0x9C

# Sangahyando of Umbar
R:392:0x9C/0x8F

# It
R:393:0x80/0x80

# Banshee
R:394:0x91/0x81

# Carrion crawler
R:395:0x97/0x84

# Xiclotlan
R:396:0xC0/0x8D

# Silent watcher
R:397:0xA0/0x9A

# Pukelman
R:398:0x98/0x96

# Disenchanter beast
R:399:0xC0/0x8E

# Dark elven druid
R:400:0x99/0x88

# Stone troll
R:401:0x94/0x9A

# Black
R:402:0xC0/0x8F

# Hill troll
R:403:0xB0/0x8F

# Wereworm
R:404:0x9E/0x8F

# Killer red beetle
R:405:0x92/0x83

# Disenchanter bat
R:406:0xB0/0x9B

# Gnoph-Keh
R:407:0xC0/0x90

# Giant grey ant
R:408:0x96/0x95

# Khufu, the Mummified King
R:409:0xA0/0x9C

# Gwaihir the Windlord
R:410:0xC0/0x91

# Giant fire tick
R:411:0x9D/0x9D

# Displacer beast
R:412:0x98/0x90

# Ulwarth, Son of Ulfang
R:413:0x9C/0x91

# Werebear
R:414:0xB1/0x96

# Cave ogre
R:415:0x92/0x92

# White wraith
R:416:0x95/0x84

# Angel
R:417:0x8E/0x92

# Ghoul
R:418:0xBB/0x8C

# Mim, Betrayer of Turin
R:419:0x99/0x89

# Hellblade
R:420:0x89/0x87

# Killer fire beetle
R:421:0x92/0x84

# Beast of Nurgle
R:422:0xC0/0x92

# Creeping adamantite coins
R:423:0x8E/0x84

# Algroth
R:424:0x94/0x91

# Flamer of Tzeentch
R:425:0xC0/0x93

# Roper
R:426:0xC0/0x94

# Headless
R:427:0x9F/0x86

# Vibration hound
R:428:0x96/0x84

# Nexus hound
R:429:0x96/0x8A

# Half-ogre
R:430:0xB0/0x9E

# Lokkak, the Ogre Chieftain
R:431:0xA1/0x80

# Vampire
R:432:0x94/0x9F

# Gorgimaera
R:433:0x91/0x91

# Shantak
R:434:0xA0/0x9D

# Colbran
R:435:0x98/0x97

# Spirit naga
R:436:0x9A/0x95

# Corpser
R:437:0xC0/0x95

# Fiend of Slaanesh
R:438:0xC0/0x96

# Stairway to Hell
R:439:0x81/0x9E

# 5-headed hydra
R:440:0x93/0x9B

# Barney the Dinosaur
R:441:0x9F/0x96

# Black knight
R:442:0x9C/0x92

# Seahorse
R:443:0xBE/0x91

# Cyclops
R:444:0xC0/0x97

# Clairvoyant
R:445:0xC0/0x98

# Purple worm
R:446:0x9E/0x90

# Catoblepas
R:447:0x9D/0x8B

# Lesser wall monster
R:448:0x80/0x82

# Mage
R:449:0x9C/0x94

# Mind flayer
R:450:0x9C/0x95

# The Ultimate Dungeon Cleaner
R:451:0xA0/0x99

# Deep one
R:452:0xC0/0x99

# Basilisk
R:453:0xBB/0x9F

# Ice troll
R:454:0x94/0x92

# Dhole
R:455:0xA1/0x82

# Archangel
R:456:0x8E/0x93

# Greater Mimic
R:457:0x82/0x81

# Chaos tile
R:458:0xA2/0x86

# Young blue dragon
R:459:0x97/0x8D

# Young white dragon
R:460:0x97/0x8E

# Young green dragon
R:461:0x97/0x8F

# Young bronze dragon
R:462:0x97/0x90

# Aklash
R:463:0xC0/0x9A

# Mithril golem
R:464:0x98/0x98

# Skeleton troll
R:465:0x9D/0x96

# Skeletal tyrannosaur 
R:466:0xC0/0x9B

# Beorn, the Shape-Changer
R:467:0xA1/0x92

# Thorondor, Lord of Eagles
R:468:0xC0/0x9C

# Giant blue ant
R:469:0x96/0x94

# Grave wight
R:470:0x95/0x85

# Shadow drake
R:471:0x97/0x91

# Manticore
R:472:0x91/0x92

# Giant army ant
R:473:0x96/0x95

# Killer slicer beetle
R:474:0x92/0x85

# Gorgon
R:475:0xC0/0x9D

# Gug
R:476:0xC0/0x9E

# Ghost
R:477:0x91/0x82

# Death watch beetle
R:478:0x92/0x86

# Mountain ogre
R:479:0x92/0x95

# Nexus quylthulg
R:480:0x93/0x80

# Shelob, Spider of Darkness
R:481:0x94/0x8B

# Giant squid
R:482:0xBE/0x87

# Ghoulking
R:483:0xC0/0x9F

# Doombat
R:484:0xC1/0x80

# Ninja
R:485:0x9C/0x96

# Memory moss
R:486:0x9A/0x8F

# Storm giant
R:487:0x92/0x9B

# Spectator
R:488:0xA0/0x85

# Bokrug
R:489:0xC1/0x81

# Biclops
R:490:0xC1/0x82

# Half-troll
R:491:0x94/0x94

# Ivory monk
R:492:0xC0/0x88

# Bert the Stone Troll
R:493:0x94/0x95

# Bill the Stone Troll
R:494:0x94/0x96

# Tom the Stone Troll
R:495:0x94/0x97

# Cave troll
R:496:0x94/0x93

# Anti-paladin
R:497:0xA1/0x84

# Chaos master
R:498:0xBB/0x84

# Barrow wight
R:499:0x95/0x86

# Skeleton ettin
R:500:0x9D/0x97

# Chaos drake
R:501:0xBB/0x9A

# Law drake
R:502:0x97/0x93

# Balance drake
R:503:0x97/0x94

# Ethereal drake
R:504:0x97/0x95

# Groo, the Wanderer
R:505:0xA1/0x81

# Fasolt the Giant
R:506:0xBB/0x83

# Shade
R:507:0x91/0x83

# Spectre
R:508:0xA2/0x85

# Water troll
R:509:0x94/0x98

# Fire elemental
R:510:0x90/0x87

# Cherub
R:511:0x8E/0x94

# Water elemental
R:512:0x90/0x88

# Multi-hued hound
R:513:0xA2/0x83

# Invisible stalker
R:514:0x90/0x89

# Carrion crawler
R:515:0x97/0x85

# Master thief
R:516:0x9C/0x98

# The Watcher in the Water
R:517:0xBB/0x87

# Lich
R:518:0x92/0x88

# Gas spore
R:519:0xC1/0x83

# Master vampire
R:520:0x95/0x80

# Oriental vampire
R:521:0xA1/0x88

# Greater mummy
R:522:0xC1/0x84

# Bloodletter of Khorne
R:523:0xC1/0x85

# Giant grey scorpion
R:524:0xBB/0x9D

# Earth elemental
R:525:0x90/0x8A

# Air elemental
R:526:0x90/0x8B

# Shimmering mold
R:527:0xA2/0x93

# Gargoyle
R:528:0xC1/0x86

# Malicious leprechaun
R:529:0xA0/0x94

# Eog golem
R:530:0x98/0x99

# Little Boy
R:531:0xC0/0x81

# Dagashi
R:532:0x9C/0x9A

# Headless ghost
R:533:0xC1/0x87

# Dread
R:534:0x91/0x85

# Gauth
R:536:0xC5/0x8D

# Leng spider
R:535:0xC1/0x88

# Smoke elemental
R:537:0x90/0x8D

# Olog
R:538:0x94/0x99

# Halfling slinger
R:539:0xBB/0x91

# Gravity hound
R:540:0x96/0x86

# Acidic cytoplasm
R:541:0x9A/0x80

# Inertia hound
R:542:0x96/0x87

# Impact hound
R:543:0x96/0x88

# Shardstorm
R:544:0xB0/0x9F

# Ooze elemental
R:545:0x90/0x8C

# Young black dragon
R:546:0x97/0x96

# Mumak
R:547:0x9D/0x8C

# Giant fire ant
R:548:0x96/0x96

# Mature white dragon
R:549:0x97/0x97

# Xorn
R:550:0x95/0x97

# Rogrog the Black Troll
R:551:0x94/0x9A

# Mist giant
R:552:0xC1/0x8A

# Phantom
R:553:0x91/0x87

# Grey wraith
R:554:0x95/0x87

# Revenant
R:555:0xC1/0x8B

# Young multi-hued dragon
R:556:0x97/0x98

# Raal's Tome of Destruction
R:557:0xA3/0x91

# Colossus
R:558:0xA0/0x80

# Young gold dragon
R:559:0x97/0x99

# Mature blue dragon
R:560:0x97/0x9A

# Mature green dragon
R:561:0x97/0x9B

# Mature bronze dragon
R:562:0x97/0x9C

# Young red dragon
R:563:0x97/0x9D

# Nightblade
R:564:0xBB/0x92

# Trapper
R:565:0x8E/0x8E

# Bodak
R:566:0x91/0x9D

# Time bomb
R:567:0xC1/0x8C

# Mezzodaemon
R:568:0xC1/0x8D

# Elder thing
R:569:0x9F/0x9E

# Ice elemental
R:570:0x90/0x8E

# Necromancer
R:571:0x9C/0x9B

# The Greater hell magic mushroom were-quylthulg
R:572:0xB1/0x97

# Lorgan, Chief of the Easterlings
R:573:0x9C/0x9C

# Chaos spawn
R:574:0x9F/0x85

# Mummified troll
R:575:0x92/0x8F

# Storm of Unmagic
R:576:0xB1/0x98

# Crypt thing
R:577:0xC1/0x90

# Chaos butterfly
R:578:0xC1/0x92

# Time elemental
R:579:0xA2/0x84

# Flying polyp
R:580:0xC1/0x93

# The Queen Ant
R:581:0x96/0x97

# Will o' the wisp
R:582:0x90/0x8F

# Shan
R:583:0xC1/0x94

# Magma elemental
R:584:0x90/0x90

# Black pudding
R:585:0x9A/0x81

# Killer iridescent beetle
R:586:0xA3/0x94

# Nexus vortex
R:587:0xA1/0x9D

# Plasma vortex
R:588:0x9E/0x83

# Mature red dragon
R:589:0x97/0x9E

# Mature gold dragon
R:590:0x97/0x9F

# Crystal drake
R:591:0xBB/0x99

# Mature black dragon
R:592:0x98/0x81

# Mature multi-hued dragon
R:593:0x98/0x82

# Sky whale
R:594:0xC1/0x95

# Draebor, the Imp
R:595:0x91/0x9C

# Mother Hydra
R:596:0xC1/0x97

# Death knight
R:597:0x9C/0x9E

# Castamir the Usurper
R:598:0x9C/0x9F

# Time vortex
R:599:0x9E/0x82

# Shimmering vortex
R:600:0x9E/0x85

# Ancient blue dragon
R:601:0x8F/0x8B

# Ancient bronze dragon
R:602:0x8F/0x8C

# Beholder
R:603:0x98/0x88

# Emperor wight
R:604:0x95/0x88

# Seraph
R:605:0x8E/0x95

# Vargo, Tyrant of Fire
R:606:0x90/0x91

# Black wraith
R:607:0x95/0x89

# Nightgaunt
R:608:0xA0/0x9E

# Baron of hell
R:609:0x9F/0x8F

# Scylla
R:610:0xC1/0x98

# Monastic lich
R:611:0xC1/0x91

# Nether wraith
R:612:0x95/0x8A

# Hellhound
R:613:0x8F/0x87

# 7-headed hydra
R:614:0x93/0x9D

# Waldern, King of Water
R:615:0x90/0x92

# Kavlax the Many-Headed
R:616:0x98/0x83

# Ancient white dragon
R:617:0x8F/0x8D

# Ancient green dragon
R:618:0x8F/0x8E

# Chthonian
R:619:0xA1/0x83

# Eldrak
R:620:0x94/0x9B

# Ettin
R:621:0x94/0x9C

# Night mare
R:622:0x9D/0x8D

# Vampire lord
R:623:0x95/0x81

# Ancient black dragon
R:624:0x8F/0x8F

# Weird fume
R:625:0xC1/0x9A

# Spawn of Ubbo-Sathla
R:626:0xC1/0x9B

# Fat Man
R:627:0xC0/0x82

# Malekith the Accursed
R:628:0xBD/0x91

# Shadowfax, steed of Gandalf
R:629:0xC1/0x9C

# Spirit troll
R:630:0xC4/0x84

# War troll
R:631:0xA1/0x8C

# Disenchanter worm mass
R:632:0x9E/0x91

# Rotting quylthulg
R:633:0x93/0x81

# Lesser titan
R:634:0x92/0x9C

# 9-headed hydra
R:635:0x93/0x9E

# Enchantress
R:636:0xBB/0x81

# Ranger chieftain
R:637:0xB1/0x99

# Sorcerer
R:638:0x9D/0x82

# Xaren
R:639:0x95/0x98

# Giant roc
R:640:0x8E/0x9A

# Minotaur
R:641:0x91/0x93

# Medusa, the Gorgon
R:642:0x9A/0x96

# Death drake
R:643:0xBB/0x98

# Ancient red dragon
R:644:0x8F/0x91

# Ancient gold dragon
R:645:0x8F/0x92

# Great crystal drake
R:646:0xBB/0x97

# Wyrd sister
R:647:0xC1/0x9D

# Vrock
R:648:0x9E/0x9D

# Death quasit
R:649:0x91/0x9E

# Giganto, the Gargantuan
R:650:0xBE/0x95

# Strygalldwir
R:651:0x8E/0x9C

# Fallen angel
R:652:0xC1/0x9E

# Giant headless
R:653:0xC1/0x9F

# Judge Fire
R:654:0xC2/0x80

# Ubbo-Sathla, the Unbegotten Source
R:655:0xC2/0x81

# Judge Mortis
R:656:0xC2/0x82

# Dark elven sorcerer
R:657:0x99/0x8A

# Master lich
R:658:0x92/0x89

# Byakhee
R:659:0xA0/0x9F

# Eol, the Dark Elf
R:660:0xB2/0x8A

# Archon
R:661:0x8E/0x96

# Formless spawn of Tsathoggua
R:662:0x9F/0x9C

# Hunting horror
R:663:0x9F/0x98

# Undead beholder
R:664:0x98/0x89

# Shadow
R:665:0x91/0x86

# Iron lich
R:666:0xA1/0x8B

# Dread
R:667:0x91/0x85

# Greater basilisk
R:668:0xC2/0x83

# Charybdis
R:669:0xBE/0x96

# Jack of Shadows
R:670:0xC2/0x84

# Zephyr Lord
R:671:0xC2/0x85

# Juggernaut of Khorne
R:672:0xC2/0x86

# Mumak
R:673:0x9D/0x8E

# Judge Fear
R:674:0xC2/0x87

# Ancient multi-hued dragon
R:675:0x8F/0x94

# Ethereal dragon
R:676:0x8F/0x95

# Dark young of Shub-Niggurath
R:677:0xA1/0x8F

# Colour out of space
R:678:0xC2/0x88

# Quaker, Master of Earth
R:679:0x90/0x93

# Death leprechaun
R:680:0xBD/0x82

# Chaugnar Faugn, Horror from the Hills
R:681:0xC2/0x89

# Lloigor
R:682:0xC2/0x8A

# Utgard-Loke
R:683:0xC2/0x8B

# Quachil Uttaus, Treader of the Dust
R:684:0xC2/0x8C

# Shoggoth
R:685:0xA1/0x8E

# Judge Death
R:686:0xC2/0x8D

# Ariel, Queen of Air
R:687:0x90/0x94

# 11-headed hydra
R:688:0x93/0x9F

# Patriarch
R:689:0x9D/0x84

# Dreadmaster
R:690:0x91/0x89

# Drolem
R:691:0x98/0x9B

# Scatha the Worm
R:692:0x8F/0x93

# Warrior of the Dawn
R:693:0xA1/0x8A

# Lesser black reaver
R:694:0xC2/0x8E

# Zoth-Ommog
R:695:0xC2/0x8F

# Grand master thief
R:696:0x9C/0x84

# Smaug the Golden
R:697:0xBB/0x96

# The Stormbringer
R:698:0xA0/0x9B

# Knight Templar
R:699:0xB1/0x9A

# Leprechaun fanatic
R:700:0xC2/0x90

# Dracolich
R:701:0x8F/0x98

# Greater titan
R:702:0x92/0x9D

# Dracolisk
R:703:0x8F/0x9E

# Winged Horror
R:704:0xC4/0x85

# Spectral tyrannosaur
R:705:0x9F/0x95

# Yibb-Tstll, the Patient One
R:706:0xC2/0x91

# Ghatanothoa
R:707:0xC2/0x92

# Ent
R:708:0xC2/0x93

# Hru
R:709:0xC2/0x94

# Itangast the Fire Drake
R:710:0x8F/0x99

# Death mold
R:711:0x9A/0x90

# Fafner the Dragon
R:712:0xA1/0x90

# Charon, Boatman of the Styx
R:713:0xB1/0x9B

# Quickbeam, the Ent
R:714:0xB1/0x9C

# Glaurung, Father of the Dragons
R:715:0x8F/0x99

# Behemoth
R:716:0xC2/0x97

# Garm, Guardian of Hel
R:717:0xC2/0x98

# Greater wall monster
R:718:0x80/0x82

# Nycadaemon
R:719:0xC2/0x99

# Barbazu
R:720:0xB2/0x9D

# Goat of Mendes
R:721:0x9F/0x8D

# Nightwing
R:722:0x95/0x91

# Maulotaur
R:723:0xA0/0x8B

# Nether hound
R:724:0x96/0x89

# Time hound
R:725:0x96/0x85

# Plasma hound
R:726:0x96/0x8B

# Demonic quylthulg
R:727:0x93/0x82

# Great Storm Wyrm
R:728:0x8F/0x9B

# Ulik the Troll
R:729:0xC2/0x9A

# Baphomet the Minotaur Lord
R:730:0x91/0x95

# Hell knight
R:731:0xC2/0x9B

# Bull Gates
R:732:0xBC/0x9B

# Santa Claus
R:733:0x9F/0x89

# Eihort, the Thing in the Labyrinth
R:734:0xC2/0x9C

# The King in Yellow
R:735:0xC2/0x9D

# Great unclean one
R:736:0xC2/0x9E

# Lord of Chaos
R:737:0xBB/0x85

# Old Sorcerer
R:738:0xB1/0x9E

# Ethereal hound
R:739:0x96/0x8C

# Lesser kraken
R:740:0xBE/0x98

# Great Ice Wyrm
R:741:0x8F/0x9C

# Demilich
R:742:0xC2/0x9F

# The Phoenix
R:743:0x8E/0x9B

# Nightcrawler
R:744:0x95/0x94

# Lord of Change
R:745:0xC3/0x80

# Keeper of Secrets
R:746:0xC3/0x81

# Shudde M'ell
R:747:0xC3/0x82

# Hand druj
R:748:0x9D/0x98

# Eye druj
R:749:0x9D/0x99

# Skull druj
R:750:0x9D/0x9A

# Chaos vortex
R:751:0xBB/0x93

# Aether vortex
R:752:0x9E/0x87

# Nidhogg, the Hel-Drake
R:753:0xC3/0x83

# The Lernaean Hydra
R:754:0x94/0x80

# Thuringwethil, the Vampire Messenger
R:755:0x95/0x82

# Great Hell Wyrm
R:756:0x8F/0x9D

# Hastur the Unspeakable
R:757:0x9F/0x8C

# Bloodthirster
R:758:0xC3/0x84

# Draconic quylthulg
R:759:0x93/0x83

# Nyogtha, the Thing that Should not Be
R:760:0xA1/0x91

# Ahtu, Avatar of Nyarlathotep
R:761:0xC3/0x85

# Fundin Bluecloak
R:762:0x99/0x8B

# Bile Demon
R:763:0xB1/0x9F

# Uriel, Angel of Fire
R:764:0x8E/0x97

# Azriel, Angel of Death
R:765:0x8E/0x98

# Ancalagon the Black
R:766:0x8F/0x90

# Daoloth, the Render of the Veils
R:767:0xC3/0x86

# Nightwalker
R:768:0x95/0x95

# Gabriel, the Messenger
R:769:0x8E/0x99

# Artsi, the Champion of Chaos
R:770:0xC3/0x87

# Saruman of Many Colours
R:771:0x9D/0x88

# Harowen the Black Hand
R:772:0x9D/0x86

# Osyluth
R:773:0xB2/0x8E

# Dreadlord
R:774:0x91/0x8A

# Greater kraken
R:775:0xBE/0x99

# Archlich
R:776:0xC3/0x89

# The Cat Lord
R:777:0x98/0x91

# Jabberwock
R:778:0x91/0x9F

# Chaos hound
R:779:0xBB/0x94

# Vlad Dracula, Prince of Darkness
R:780:0xC3/0x8B

# Beholder hive-mother
R:781:0xC3/0x8C

# Leviathan
R:782:0xBE/0x9A

# Great Wyrm of Chaos
R:783:0xBB/0x95

# Great Wyrm of Law
R:784:0x90/0x80

# Great Wyrm of Balance
R:785:0x90/0x81

# Shambler
R:786:0x9F/0x92

# Gelugon
R:787:0xB2/0x8B

# Glaaki
R:788:0xC3/0x8E

# T'ron, the Rebel Dragonrider
R:789:0xB2/0x88

# Great Wyrm of Many Colours
R:790:0xA2/0x95

# Mardra, rider of the Gold Loranth
R:791:0xB2/0x85

# Tselakus, the Dreadlord
R:792:0x91/0x8B

# Sky Drake
R:793:0xA2/0x80

# Eilinel the Entrapped
R:794:0xB2/0x80

# Horned Reaper
R:795:0xB2/0x81

# The Norsa
R:796:0xBB/0x80

# Rhan-Tegoth
R:797:0xC3/0x8F

# Black reaver
R:798:0x92/0x8A

# Master mindcrafter
R:799:0xB0/0x86

# Greater demonic quylthulg
R:800:0x93/0x87

# Greater draconic quylthulg
R:801:0x93/0x85

# Greater rotting quylthulg
R:802:0x93/0x86

# Null, the Living Void
R:803:0xC3/0x90

# Feagwath, the Undead Sorcerer
R:804:0x92/0x8C

# Omarax the Eye Tyrant
R:805:0x98/0x8A

# Tsathoggua, the Sleeper of N'kai
R:806:0xC3/0x91

# Greater Balrog
R:807:0xB2/0x9E

# Ungoliant, the Unlight
R:808:0x94/0x8D

# Atlach-Nacha, the Spider God
R:809:0x94/0x8D

# Y'golonac
R:810:0xC3/0x92

# Aether hound
R:811:0x96/0x8E

# Pit Fiend
R:812:0xB2/0x9F

# The Serpent of Chaos
R:813:0x9F/0x8E

# Yig, Father of Serpents
R:814:0xC3/0x94

# Unmaker
R:815:0xA1/0x9E

# Cyberdemon
R:816:0x9F/0x91

# Hela, Queen of the Dead
R:817:0xC3/0x95

# The Mouth of Sauron
R:818:0x9D/0x89

# The Necromancer of Dol Guldur
R:819:0xC5/0x8B

# Lessa, rider of the Gold Ramoth
R:820:0xB2/0x86

# Master quylthulg
R:821:0x93/0x84

# Qlzqqlzuup, the Lord of Flesh
R:822:0x93/0x88

# Cthugha, the Living Flame
R:823:0xC3/0x96

# F'lar, rider of the Bronze Mnementh
R:824:0xB2/0x87

# Maeglin, the Traitor of Gondolin
R:825:0xA1/0x9C

# Cyaegha
R:826:0xBD/0x81

# Pazuzu, Lord of Air
R:827:0x8E/0x9C

# Ithaqua the Windwalker
R:828:0xA0/0x82

# Hellhound
R:829:0x8F/0x87

# Cantoras, the Skeletal Lord
R:830:0x9D/0x9B

# Mephistopheles, Lord of Hell
R:831:0x9F/0x90

# Godzilla
R:832:0x9F/0x97

# Abhoth, Source of Uncleanness
R:833:0xC3/0x97

# Ymir, the Ice Giant
R:834:0xBD/0x84

# Loki, the Trickster
R:835:0xC3/0x98

# Star-spawn of Cthulhu
R:836:0x9F/0x8A

# Surtur, the Fire Giant
R:837:0xBD/0x85

# The Tarrasque
R:838:0x94/0x81

# Lungorthin, the Balrog of White Fire
R:839:0x9F/0x82

# Draugluin, Sire of All Werewolves
R:840:0x8F/0x88

# Shuma-Gorath
R:841:0xBD/0x80

# Tulzscha, the Green Flame
R:842:0xC3/0x99

# Oremorj, the Cyberdemon Lord
R:843:0xC3/0x9A

# Vecna, the Emperor Lich
R:844:0x92/0x8B

# Yog-Sothoth, the All-in-One
R:845:0x9F/0x8B

# Fenris Wolf
R:846:0xC3/0x9B

# Great Wyrm of Power
R:847:0xA2/0x81

# Shub-Niggurath, Black Goat of the Woods
R:848:0x9F/0x99

# Nodens, Lord of the Great Abyss
R:849:0xC3/0x9C

# Carcharoth, the Jaws of Thirst
R:850:0x8F/0x89

# Nyarlathotep, the Crawling Chaos
R:851:0x9F/0x9B

# Azathoth, the Daemon Sultan
R:852:0xC4/0x8C

# Huan, Wolfhound of the Valar
R:853:0xB2/0x83

# Jormungand the Midgard Serpent
R:854:0xBE/0x9B

# The Destroyer
R:855:0xBD/0x83

# Gothmog, the High Captain of Balrogs
R:856:0x9F/0x81

# Great Cthulhu
R:857:0x9F/0x84

# Sorka, rider of the Gold Faranth
R:858:0xB2/0x84

# The Unicorn of Order
R:859:0xC3/0x9D

# Sauron, the Sorcerer
R:860:0x9D/0x8A

# DarkGod, the Mighty Coder of Hell
R:861:0xA1/0x93

# Morgoth, Lord of Darkness
R:862:0x92/0x9E

# Human Warrior
R:863:0xB2/0x82

# Elven archer
R:864:0x9C/0x81

# Dwarven warrior
R:865:0xB2/0x89

# Elite uruk
R:866:0x9B/0x81

# The Philosophy Teacher
R:867:0xC4/0x82

# The Variant Maintainer
R:868:0xA1/0x99

# Random Number Generator
R:869:0xBD/0x9F

# Rocket mine
R:870:0xB2/0x8C

# Bouncing mine
R:871:0xB2/0x8D

# The Balrog of Moria
R:872:0xB2/0x8F

# The Icky Queen
R:873:0xB2/0x90

# Rot jelly
R:874:0xB1/0x91

# Death
R:875:0xB2/0x91

# Famine
R:876:0xB2/0x92

# Pestilence
R:877:0xB2/0x93

# War
R:878:0xB2/0x94

# Pike
R:879:0xB2/0x95

# Electric eel
R:880:0xBE/0x8C

# Giant crayfish
R:881:0xB2/0x96

# Mermaid
R:882:0xB1/0x9D

# Box jellyfish
R:883:0xBE/0x83

# Giant piranha
R:884:0xBE/0x84

# Piranha
R:885:0xBE/0x80

# Bullywug
R:886:0xB2/0x97

# Bullywug warrior
R:887:0xB2/0x98

# Bullywug shaman
R:888:0xB2/0x99

# Whale
R:889:0xBE/0x8B

# Sand mite
R:890:0xB0/0x9D

# Octopus
R:891:0xB2/0x9A

# Giant octopus
R:892:0xBE/0x93

# Eye of the deep
R:893:0xB2/0x9B

# Murk dweller
R:894:0xB2/0x9C

# Drowned soul
R:895:0xC5/0x8F

# Tiger shark
R:896:0xC5/0x8E

# Hammerhead shark
R:897:0xBE/0x88

# Great white shark
R:898:0xBE/0x8F

# Aquatic golem
R:899:0xC5/0x95

# Aquatic kobold
R:900:0xC5/0x96

# White shark
R:901:0xBE/0x89

# Scrag
R:902:0xC5/0x97

# Jaws
R:903:0xBE/0x92

# Aquatic elf
R:904:0xC5/0x98

# Aquatic elven warrior
R:905:0xC5/0x99

# Aquatic elven shaman
R:906:0xC5/0x9A

# Stargazer
R:907:0xC5/0x9E

# Elder stargazer
R:908:0xC5/0x9F

# Flounder
R:909:0xC6/0x81

# Giant turtle
R:910:0xC6/0x82

# Baby dragon turtle
R:911:0xC6/0x83

# Young dragon turtle
R:912:0xC6/0x84

# Mature dragon turtle
R:913:0xC6/0x85

# Ancient dragon turtle
R:914:0xC6/0x86

# Fastitocalon
R:915:0xBE/0x97

# Undead stargazer
R:916:0xC6/0x80

# Killer whale
R:917:0xBE/0x8E

# Merrow
R:918:0xC5/0x9D

# Water naga
R:919:0xC6/0x87

# Devilfish
R:920:0xC6/0x88

# Undead devilfish
R:921:0xC6/0x89

# Moby Dick, the White Whale
R:922:0xC5/0x9C

# Aquatic hound
R:923:0xC4/0x9E

# Water demon
R:924:0xC6/0x8B

# Ixitxachitl
R:925:0xBE/0x86

# Ixitxachitl priest
R:926:0xBE/0x8A

# Vampiric ixitxachitl
R:927:0xBE/0x90

# Mathilde, the Science Student
R:928:0x9D/0x80

# Child spirit
R:929:0xC5/0x90

# Young spirit
R:930:0xC5/0x91

# Mature spirit
R:931:0xC5/0x92

# Experienced spirit
R:932:0xC5/0x93

# Wise spirit
R:933:0xC5/0x94

# Fangorn the Treebeard, Lord of the Ents
R:934:0xC2/0x95

# Gandalf the Grey
R:935:0xC3/0x88

# Nar, the Dwarf
R:936:0x99/0x84

# Novice mindcrafter
R:937:0xB0/0x84

# Great Swamp Wyrm
R:938:0x8F/0x9A

# Great Bile Wyrm
R:939:0x8F/0x9F

# Blue Firelizard
R:940:0xB0/0x99

# Green Firelizard
R:941:0xB0/0x98

# Brown Firelizard
R:942:0xB0/0x97

# Bronze Firelizard
R:943:0xB0/0x96

# Gold Firelizard
R:944:0xB0/0x95

# High-elven ranger
R:945:0xC6/0x93

# Uvatha the Horseman
R:946:0x95/0x8B

# Adunaphel the Quiet
R:947:0x95/0x8C

# Akhorahil the Blind
R:948:0x95/0x8D

# Ren the Unclean
R:949:0x95/0x82

# Ji Indur Dawndeath
R:950:0x95/0x8F

# Dwar, Dog Lord of Waw
R:951:0x95/0x8F

# Hoarmurath of Dir
R:952:0x95/0x92

# Khamul, the Black Easterling
R:953:0x95/0x93

# The Witch-King of Angmar
R:954:0x95/0x96

# Green Dragonrider
R:955:0xB0/0x91

# Blue Dragonrider
R:956:0xB0/0x94

# Brown Dragonrider
R:957:0xB0/0x92

# Bronze Dragonrider
R:958:0xB0/0x93

# Gold Dragonrider
R:959:0xB0/0x90

# Thread
R:960:0xB0/0x9A

# Gorlim, Betrayer of Barahir
R:961:0x9D/0x83

# The Blubbering idiot, agent of black market, Simon the weak
R:962:0x9B/0x8F

# Aranea
R:963:0xB0/0x80

# Elder aranea
R:964:0xB0/0x81

# Giant brown tick
R:965:0xC5/0x9B

# Dolphiner
R:966:0xC6/0x98

# Novice possessor (soul)
R:967:0xC6/0x8E

# Bat of Gorgoroth
R:968:0xC6/0x94

# The Princess
R:969:0xA2/0x9F

# Merton Proudfoot, the lost hobbit
R:970:0xC6/0x9E

# The Wight-King of the Barrow-downs
R:971:0xC6/0x91

# Adventurer
R:972:0xA9/0x86

# Experienced possessor (soul)
R:973:0xC6/0x8F

# Old possessor (soul)
R:974:0xC6/0x90

# Death orb
R:975:0xC6/0x99

# Bronze dragon worm
R:976:0xB1/0x80

# Gold dragon worm
R:977:0xB1/0x81

# Moldoux, the Defenceless Mold
R:978:0xB1/0x8A

# The Physics Teacher
R:979:0xC6/0x9A

# Ar-Pharazon the Golden
R:980:0xA1/0x9B

# Doppelganger
R:981:0x8C/0x81

# Marylene, Heartbreakeress of the Netherworld
R:982:0xA3/0x9E

# The Greater Lag Monster
R:983:0xC6/0x96

# Hrungnir, the Stone Giant
R:984:0xB1/0x8B

# Bullroarer the Hobbit
R:985:0x98/0x9D

# 3-headed hydra
R:986:0x93/0x99

# Uldor the Accursed
R:987:0x9C/0x93

# Mystic
R:988:0x9C/0x97

# Elder vampire
R:989:0xA1/0x9F

# Ulfang the Black
R:990:0x9C/0x99

# Demonologist
R:991:0x9C/0x9D

# Hezrou
R:992:0x9E/0x9C

# Glabrezu
R:993:0x9E/0x9D

# Nalfeshnee
R:994:0x9E/0x9E

# Marilith
R:995:0x9E/0x9F

# Lesser Balrog
R:996:0x9F/0x80

# Master mystic
R:997:0x9D/0x85

# Grand master mystic
R:998:0x9D/0x87

# Erinyes
R:999:0x9E/0x9A

# Novice mindcrafter
R:1000:0xB0/0x84

# Polyphemus, the Blind Cyclops
R:1001:0xC6/0x92

# Great Wyrm of Perplexity
R:1002:0xB1/0x8C

# Hound of Tindalos
R:1003:0xB0/0x8E

# Great Wyrm of Thunder
R:1004:0xB1/0x8D

# Silver mouse
R:1005:0xB0/0x83

# The Rat King
R:1006:0xB1/0x8E

# Vort the Kobold Queen
R:1007:0xB0/0x88

# Giant black louse
R:1008:0x9A/0x87

# Fire Phantom
R:1009:0xB1/0x8F

# The Insane Player
R:1010:0xBC/0x99

# Glaryssa, Succubus Queen
R:1011:0xA3/0x9F

# Vermicious Knid
R:1012:0xB1/0x90

# Bone golem
R:1013:0xB1/0x92

# Snake of Yig
R:1014:0xC6/0x8A

# Bronze golem
R:1015:0xB1/0x93

# Dimensional shambler
R:1016:0xB0/0x9C

# Cultist
R:1017:0xC6/0x8C

# Cult leader
R:1018:0xC6/0x8D

# Servitor of the outer gods
R:1019:0xC6/0x95

# Avatar of Nyarlathotep
R:1020:0xC3/0x85

# Thiazi, the Storm Giant
R:1021:0xB1/0x94

# Hypnos, Lord of Sleep
R:1022:0xC3/0x8D

# Blue dragon worm
R:1023:0xB1/0x82

# White dragon worm
R:1024:0xB1/0x83

# Green dragon worm
R:1025:0xB1/0x84

# Black dragon worm
R:1026:0xB1/0x85

# Red dragon worm
R:1027:0xB1/0x86

# Multi-hued dragon worm
R:1028:0xB1/0x87

# The Minotaur of the Labyrinth
R:1029:0x91/0x95

# The Sandworm Queen
R:1030:0xB1/0x88

# Sandworm
R:1031:0xB1/0x89

# Tik'srvzllat
R:1032:0xC6/0x9B

# The Glass Golem
R:1033:0xB1/0x95

# The White Balrog
R:1034:0x9F/0x82

# Golgarach, the Living Rock
R:1035:0x80/0x95

# Atlas, the Titan
R:1036:0xC6/0x9C

# Kronos, Lord of the Titans
R:1037:0xC6/0x9D

# Water hound
R:1038:0x96/0x83

# Improv, the mighty MoLD
R:1039:0xB1/0x8A

# Emperor Mimic
R:1040:0xA3/0x8D

# Melinda Proudfoot
R:1041:0xC6/0x9F

# Thrain, the King Under the Mountain
R:1042:0xC6/0x97

## Fire golem
R:1043:0xBC/0x9C

# Spells (*)
S:0x30:0x85/0x93
S:0x31:0x85/0x92
S:0x32:0x85/0x92
S:0x33:0x85/0x8D
S:0x34:0x85/0x8C
S:0x35:0x85/0x8F
S:0x36:0x85/0x90
S:0x37:0x85/0x95
S:0x38:0x85/0x93
S:0x39:0x85/0x92
S:0x3A:0x85/0x91
S:0x3B:0x85/0x8E
S:0x3C:0x85/0x8D
S:0x3D:0x85/0x8F
S:0x3E:0x85/0x90
S:0x3F:0x85/0x95

# Spells (|)
S:0x40:0x84/0x9C
S:0x41:0x84/0x98
S:0x42:0x84/0x98
S:0x43:0x85/0x88
S:0x44:0x84/0x80
S:0x45:0x84/0x8C
S:0x46:0x84/0x90
S:0x47:0x85/0x84
S:0x48:0x84/0x9C
S:0x49:0x84/0x98
S:0x4A:0x84/0x94
S:0x4B:0x84/0x88
S:0x4C:0x85/0x88
S:0x4D:0x84/0x8C
S:0x4E:0x84/0x90
S:0x4F:0x85/0x84

# Spells (-)
S:0x50:0x84/0x9D
S:0x51:0x84/0x99
S:0x52:0x84/0x99
S:0x53:0x85/0x89
S:0x54:0x84/0x81
S:0x55:0x84/0x8D
S:0x56:0x84/0x91
S:0x57:0x85/0x85
S:0x58:0x84/0x9D
S:0x59:0x84/0x99
S:0x5A:0x84/0x95
S:0x5B:0x84/0x89
S:0x5C:0x85/0x89
S:0x5D:0x84/0x8D
S:0x5E:0x84/0x91
S:0x5F:0x85/0x85

# Spells (:)
S:0x60:0x84/0x9E
S:0x61:0x84/0x9A
S:0x62:0x84/0x9A
S:0x63:0x85/0x8A
S:0x64:0x84/0x82
S:0x65:0x84/0x8E
S:0x66:0x84/0x92
S:0x67:0x85/0x86
S:0x68:0x84/0x9E
S:0x69:0x84/0x9A
S:0x6A:0x84/0x96
S:0x6B:0x84/0x8A
S:0x6C:0x85/0x8A
S:0x6D:0x84/0x8E
S:0x6E:0x84/0x92
S:0x6F:0x85/0x86

# Spells (\)
S:0x70:0x84/0x9F
S:0x71:0x84/0x9B
S:0x72:0x84/0x9B
S:0x73:0x85/0x8B
S:0x74:0x84/0x83
S:0x75:0x84/0x8F
S:0x76:0x84/0x93
S:0x77:0x85/0x87
S:0x78:0x84/0x9F
S:0x79:0x84/0x9B
S:0x7A:0x84/0x97
S:0x7B:0x84/0x8B
S:0x7C:0x85/0x8B
S:0x7D:0x84/0x8F
S:0x7E:0x84/0x93
S:0x7F:0x85/0x87

# Amulets (")
S:0x80:0xB6/0x87
S:0x81:0xB6/0x88
S:0x82:0xB6/0x85
S:0x83:0xB6/0x86
S:0x84:0xB6/0x81
S:0x85:0xB6/0x82
S:0x86:0xB6/0x83
S:0x87:0xB6/0x84
S:0x88:0xB6/0x87
S:0x89:0xB6/0x88
S:0x8A:0xB6/0x8E
S:0x8B:0xB6/0x86
S:0x8C:0xB6/0x81
S:0x8D:0xB6/0x82
S:0x8E:0xB6/0x8B
S:0x8F:0xB6/0x8C

# Rings (=)
S:0x90:0xB5/0x8B
S:0x91:0xB5/0x8C
S:0x92:0xB5/0x89
S:0x93:0xB5/0x8A
S:0x94:0xB5/0x81
S:0x95:0xB5/0x82
S:0x96:0xB5/0x83
S:0x97:0xB5/0x88
S:0x98:0xB5/0x8B
S:0x99:0xB5/0x8C
S:0x9A:0xB5/0x80
S:0x9B:0xB5/0x8A
S:0x9C:0xB5/0x81
S:0x9D:0xB5/0x82
S:0x9E:0xB5/0x83
S:0x9F:0xB5/0x88

# Staffs (_)
S:0xA0:0xB9/0x84
S:0xA1:0xB9/0x85
S:0xA2:0xB9/0x85
S:0xA3:0xB9/0x81
S:0xA4:0xB9/0x81
S:0xA5:0xB9/0x82
S:0xA6:0xB9/0x80
S:0xA7:0xB9/0x87
S:0xA8:0xB9/0x84
S:0xA9:0xB9/0x85
S:0xAA:0xB9/0x83
S:0xAB:0xB9/0x87
S:0xAC:0xB9/0x81
S:0xAD:0xB9/0x82
S:0xAE:0xB9/0x80
S:0xAF:0xB9/0x87

# Wands (-)
S:0xB0:0xB7/0x84
S:0xB1:0xB7/0x85
S:0xB2:0xB7/0x85
S:0xB3:0xB7/0x86
S:0xB4:0xB7/0x81
S:0xB5:0xB7/0x82
S:0xB6:0xB7/0x80
S:0xB7:0xB7/0x87
S:0xB8:0xB7/0x84
S:0xB9:0xB7/0x85
S:0xBA:0xB7/0x83
S:0xBB:0xB7/0x86
S:0xBC:0xB7/0x81
S:0xBD:0xB7/0x82
S:0xBE:0xB7/0x80
S:0xBF:0xB7/0x87

# Rods (-)
S:0xC0:0xB8/0x84
S:0xC1:0xB8/0x85
S:0xC2:0xB8/0x85
S:0xC3:0xB8/0x86
S:0xC4:0xB8/0x81
S:0xC5:0xB8/0x82
S:0xC6:0xB8/0x80
S:0xC7:0xB8/0x87
S:0xC8:0xB8/0x84
S:0xC9:0xB8/0x85
S:0xCA:0xB8/0x83
S:0xCB:0xB8/0x86
S:0xCC:0xB8/0x81
S:0xCD:0xB8/0x82
S:0xCE:0xB8/0x80
S:0xCF:0xB8/0x87

# Scrolls (?)
S:0xD0:0x86/0x82
S:0xD1:0x86/0x82
S:0xD2:0x86/0x82
S:0xD3:0x86/0x82
S:0xD4:0x86/0x82
S:0xD5:0x86/0x82
S:0xD6:0x86/0x82
S:0xD7:0x86/0x82
S:0xD8:0x86/0x82
S:0xD9:0x86/0x82
S:0xDA:0x86/0x82
S:0xDB:0x86/0x82
S:0xDC:0x86/0x82
S:0xDD:0x86/0x82
S:0xDE:0x86/0x82
S:0xDF:0x86/0x82

# Potions (!)
S:0xE0:0xBC/0x84
S:0xE1:0xBC/0x83
S:0xE2:0xBC/0x8A
S:0xE3:0xBC/0x8B
S:0xE4:0xBC/0x87
S:0xE5:0xBC/0x86
S:0xE6:0xBC/0x85
S:0xE7:0xBC/0x89
S:0xE8:0xBC/0x84
S:0xE9:0xBC/0x83
S:0xEA:0xBC/0x8E
S:0xEB:0xBC/0x88
S:0xEC:0xBC/0x8B
S:0xED:0xBC/0x8C
S:0xEE:0xBC/0x8D
S:0xEF:0xBC/0x89

# Food (,)
S:0xF0:0xBA/0x84
S:0xF1:0xBA/0x85
S:0xF2:0xBA/0x85
S:0xF3:0xBA/0x86
S:0xF4:0xBA/0x81
S:0xF5:0xBA/0x82
S:0xF6:0xBA/0x80
S:0xF7:0xBA/0x87
S:0xF8:0xBA/0x84
S:0xF9:0xBA/0x85
S:0xFA:0xBA/0x83
S:0xFB:0xBA/0x86
S:0xFC:0xBA/0x81
S:0xFD:0xBA/0x82
S:0xFE:0xBA/0x80
S:0xFF:0xBA/0x87

# Unknown Amulet
U:40:0xB6/0x81

# Unknown Ring
U:45:0xB5/0x81

# Unknown Staff
U:55:0xB9/0x81

# Unknown Wand
U:65:0xB7/0x81

# Unknown Rod
U:66:0xB8/0x81

# Unknown Scroll
U:70:0x86/0x82

# Unknown Potion
U:75:0xBC/0x85

# Unknown Food
U:80:0x8B/0x81
# non-defines encountered :
# Load the special player pictures
%:xtra-xxx.prf
# Load the Trap image definitions
%:trap-xxx.prf
tome-235-src/lib/pref/font-dos.prf0000644000076400017500000000035611012107762014635 0ustar  dgdg# File: font-dos.prf

#
# This file is used by Angband (when it was compiled using "main-dos.c")
# to specify simple attr/char remappings using a standard font, allowing
# the use of special pseudo-graphic pictures for walls and such.
#

tome-235-src/lib/pref/graf-mac.prf0000644000076400017500000000041311012107762014553 0ustar  dgdg# File: graf-mac.prf

#
# This file defines special attr/char mappings for use in "graphics" mode
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#

# Standard file
?:[EQU $GRAF old]
%:graf-xxx.prf

# New tiles
?:[EQU $GRAF new]
%:graf-new.prf
tome-235-src/lib/pref/font-x11.prf0000644000076400017500000000066611012107762014465 0ustar  dgdg# File: font-x11.prf


# Color palette - Text

V:0:0x01:0x00:0x00:0x00
V:1:0x01:0xFF:0xFF:0xFF
V:2:0x01:0xC7:0xC7:0xC7
V:3:0x01:0xFF:0x92:0x00
V:4:0x01:0xC0:0x00:0x00
V:5:0x01:0x00:0xC0:0x00
V:6:0x01:0x00:0x00:0xFE
V:7:0x01:0xC8:0x64:0x00
V:8:0x01:0x8A:0x8A:0x8A
V:9:0x01:0xE0:0xE0:0xE0
V:10:0x01:0xA5:0x00:0xFF
V:11:0x01:0xFF:0xFD:0x00
V:12:0x01:0xFF:0x40:0x40
V:13:0x01:0x00:0xFF:0x00
V:14:0x01:0x00:0xC8:0xFF
V:15:0x01:0xFF:0xCC:0x80

tome-235-src/lib/pref/font-xxx.prf0000644000076400017500000001401511012107762014674 0ustar  dgdg# File: font-xxx.prf

#
# This file defines special attr/char mappings for use in "text" mode
#
# See "lib/help/command.txt" and "src/files.c" for more information.
#


##### Special attr/char values #####


## # Unused (@)
## S:0x00:0x00/0x40
## S:0x01:0x01/0x40
## S:0x02:0x02/0x40
## S:0x03:0x03/0x40
## S:0x04:0x04/0x40
## S:0x05:0x05/0x40
## S:0x06:0x06/0x40
## S:0x07:0x07/0x40
## S:0x08:0x08/0x40
## S:0x09:0x09/0x40
## S:0x0A:0x0A/0x40
## S:0x0B:0x0B/0x40
## S:0x0C:0x0C/0x40
## S:0x0D:0x0D/0x40
## S:0x0E:0x0E/0x40
## S:0x0F:0x0F/0x40

## # Unused (@)
## S:0x10:0x00/0x40
## S:0x11:0x01/0x40
## S:0x12:0x02/0x40
## S:0x13:0x03/0x40
## S:0x14:0x04/0x40
## S:0x15:0x05/0x40
## S:0x16:0x06/0x40
## S:0x17:0x07/0x40
## S:0x18:0x08/0x40
## S:0x19:0x09/0x40
## S:0x1A:0x0A/0x40
## S:0x1B:0x0B/0x40
## S:0x1C:0x0C/0x40
## S:0x1D:0x0D/0x40
## S:0x1E:0x0E/0x40
## S:0x1F:0x0F/0x40

## # Unused (@)
## S:0x20:0x00/0x40
## S:0x21:0x01/0x40
## S:0x22:0x02/0x40
## S:0x23:0x03/0x40
## S:0x24:0x04/0x40
## S:0x25:0x05/0x40
## S:0x26:0x06/0x40
## S:0x27:0x07/0x40
## S:0x28:0x08/0x40
## S:0x29:0x09/0x40
## S:0x2A:0x0A/0x40
## S:0x2B:0x0B/0x40
## S:0x2C:0x0C/0x40
## S:0x2D:0x0D/0x40
## S:0x2E:0x0E/0x40
## S:0x2F:0x0F/0x40

# Spells (*)
S:0x30:0x00/0x2A
S:0x31:0x01/0x2A
S:0x32:0x02/0x2A
S:0x33:0x03/0x2A
S:0x34:0x04/0x2A
S:0x35:0x05/0x2A
S:0x36:0x06/0x2A
S:0x37:0x07/0x2A
S:0x38:0x08/0x2A
S:0x39:0x09/0x2A
S:0x3A:0x0A/0x2A
S:0x3B:0x0B/0x2A
S:0x3C:0x0C/0x2A
S:0x3D:0x0D/0x2A
S:0x3E:0x0E/0x2A
S:0x3F:0x0F/0x2A

# Spells (|)
S:0x40:0x00/0x7C
S:0x41:0x01/0x7C
S:0x42:0x02/0x7C
S:0x43:0x03/0x7C
S:0x44:0x04/0x7C
S:0x45:0x05/0x7C
S:0x46:0x06/0x7C
S:0x47:0x07/0x7C
S:0x48:0x08/0x7C
S:0x49:0x09/0x7C
S:0x4A:0x0A/0x7C
S:0x4B:0x0B/0x7C
S:0x4C:0x0C/0x7C
S:0x4D:0x0D/0x7C
S:0x4E:0x0E/0x7C
S:0x4F:0x0F/0x7C

# Spells (-)
S:0x50:0x00/0x2D
S:0x51:0x01/0x2D
S:0x52:0x02/0x2D
S:0x53:0x03/0x2D
S:0x54:0x04/0x2D
S:0x55:0x05/0x2D
S:0x56:0x06/0x2D
S:0x57:0x07/0x2D
S:0x58:0x08/0x2D
S:0x59:0x09/0x2D
S:0x5A:0x0A/0x2D
S:0x5B:0x0B/0x2D
S:0x5C:0x0C/0x2D
S:0x5D:0x0D/0x2D
S:0x5E:0x0E/0x2D
S:0x5F:0x0F/0x2D

# Spells (/)
S:0x60:0x00/0x2F
S:0x61:0x01/0x2F
S:0x62:0x02/0x2F
S:0x63:0x03/0x2F
S:0x64:0x04/0x2F
S:0x65:0x05/0x2F
S:0x66:0x06/0x2F
S:0x67:0x07/0x2F
S:0x68:0x08/0x2F
S:0x69:0x09/0x2F
S:0x6A:0x0A/0x2F
S:0x6B:0x0B/0x2F
S:0x6C:0x0C/0x2F
S:0x6D:0x0D/0x2F
S:0x6E:0x0E/0x2F
S:0x6F:0x0F/0x2F

# Spells (\)
S:0x70:0x00/0x5C
S:0x71:0x01/0x5C
S:0x72:0x02/0x5C
S:0x73:0x03/0x5C
S:0x74:0x04/0x5C
S:0x75:0x05/0x5C
S:0x76:0x06/0x5C
S:0x77:0x07/0x5C
S:0x78:0x08/0x5C
S:0x79:0x09/0x5C
S:0x7A:0x0A/0x5C
S:0x7B:0x0B/0x5C
S:0x7C:0x0C/0x5C
S:0x7D:0x0D/0x5C
S:0x7E:0x0E/0x5C
S:0x7F:0x0F/0x5C

# Amulets (")
S:0x80:0x00/0x22
S:0x81:0x01/0x22
S:0x82:0x02/0x22
S:0x83:0x03/0x22
S:0x84:0x04/0x22
S:0x85:0x05/0x22
S:0x86:0x06/0x22
S:0x87:0x07/0x22
S:0x88:0x08/0x22
S:0x89:0x09/0x22
S:0x8A:0x0A/0x22
S:0x8B:0x0B/0x22
S:0x8C:0x0C/0x22
S:0x8D:0x0D/0x22
S:0x8E:0x0E/0x22
S:0x8F:0x0F/0x22

# Rings (=)
S:0x90:0x00/0x3D
S:0x91:0x01/0x3D
S:0x92:0x02/0x3D
S:0x93:0x03/0x3D
S:0x94:0x04/0x3D
S:0x95:0x05/0x3D
S:0x96:0x06/0x3D
S:0x97:0x07/0x3D
S:0x98:0x08/0x3D
S:0x99:0x09/0x3D
S:0x9A:0x0A/0x3D
S:0x9B:0x0B/0x3D
S:0x9C:0x0C/0x3D
S:0x9D:0x0D/0x3D
S:0x9E:0x0E/0x3D
S:0x9F:0x0F/0x3D

# Staffs (_)
S:0xA0:0x00/0x5F
S:0xA1:0x01/0x5F
S:0xA2:0x02/0x5F
S:0xA3:0x03/0x5F
S:0xA4:0x04/0x5F
S:0xA5:0x05/0x5F
S:0xA6:0x06/0x5F
S:0xA7:0x07/0x5F
S:0xA8:0x08/0x5F
S:0xA9:0x09/0x5F
S:0xAA:0x0A/0x5F
S:0xAB:0x0B/0x5F
S:0xAC:0x0C/0x5F
S:0xAD:0x0D/0x5F
S:0xAE:0x0E/0x5F
S:0xAF:0x0F/0x5F

# Wands (-)
S:0xB0:0x00/0x2D
S:0xB1:0x01/0x2D
S:0xB2:0x02/0x2D
S:0xB3:0x03/0x2D
S:0xB4:0x04/0x2D
S:0xB5:0x05/0x2D
S:0xB6:0x06/0x2D
S:0xB7:0x07/0x2D
S:0xB8:0x08/0x2D
S:0xB9:0x09/0x2D
S:0xBA:0x0A/0x2D
S:0xBB:0x0B/0x2D
S:0xBC:0x0C/0x2D
S:0xBD:0x0D/0x2D
S:0xBE:0x0E/0x2D
S:0xBF:0x0F/0x2D

# Rods (-)
S:0xC0:0x00/0x2D
S:0xC1:0x01/0x2D
S:0xC2:0x02/0x2D
S:0xC3:0x03/0x2D
S:0xC4:0x04/0x2D
S:0xC5:0x05/0x2D
S:0xC6:0x06/0x2D
S:0xC7:0x07/0x2D
S:0xC8:0x08/0x2D
S:0xC9:0x09/0x2D
S:0xCA:0x0A/0x2D
S:0xCB:0x0B/0x2D
S:0xCC:0x0C/0x2D
S:0xCD:0x0D/0x2D
S:0xCE:0x0E/0x2D
S:0xCF:0x0F/0x2D

# Scrolls (?)
S:0xD0:0x00/0x3F
S:0xD1:0x01/0x3F
S:0xD2:0x02/0x3F
S:0xD3:0x03/0x3F
S:0xD4:0x04/0x3F
S:0xD5:0x05/0x3F
S:0xD6:0x06/0x3F
S:0xD7:0x07/0x3F
S:0xD8:0x08/0x3F
S:0xD9:0x09/0x3F
S:0xDA:0x0A/0x3F
S:0xDB:0x0B/0x3F
S:0xDC:0x0C/0x3F
S:0xDD:0x0D/0x3F
S:0xDE:0x0E/0x3F
S:0xDF:0x0F/0x3F

# Potions (!)
S:0xE0:0x00/0x21
S:0xE1:0x01/0x21
S:0xE2:0x02/0x21
S:0xE3:0x03/0x21
S:0xE4:0x04/0x21
S:0xE5:0x05/0x21
S:0xE6:0x06/0x21
S:0xE7:0x07/0x21
S:0xE8:0x08/0x21
S:0xE9:0x09/0x21
S:0xEA:0x0A/0x21
S:0xEB:0x0B/0x21
S:0xEC:0x0C/0x21
S:0xED:0x0D/0x21
S:0xEE:0x0E/0x21
S:0xEF:0x0F/0x21

# Food (,)
S:0xF0:0x00/0x2C
S:0xF1:0x01/0x2C
S:0xF2:0x02/0x2C
S:0xF3:0x03/0x2C
S:0xF4:0x04/0x2C
S:0xF5:0x05/0x2C
S:0xF6:0x06/0x2C
S:0xF7:0x07/0x2C
S:0xF8:0x08/0x2C
S:0xF9:0x09/0x2C
S:0xFA:0x0A/0x2C
S:0xFB:0x0B/0x2C
S:0xFC:0x0C/0x2C
S:0xFD:0x0D/0x2C
S:0xFE:0x0E/0x2C
S:0xFF:0x0F/0x2C



##### Default inventory object colors #####


# SKELETON
E:1:0x01

# BOTTLE
E:2:0x01

# FIRESTONE
E:3:0x01

# SPIKE
E:5:0x02

# CHEST
E:7:0x02

# JUNK
E:11:0x01

# BOOMERANG
E:15:0x07

# SHOT
E:16:0x0F

# ARROW
E:17:0x0F

# BOLT
E:18:0x0F

# BOW
E:19:0x07

# DIGGING
E:20:0x02

# HAFTED
E:21:0x01

# POLEARM
E:22:0x01

# SWORD
E:23:0x01

# AXE
E:24:0x01

# BOOTS
E:30:0x0F

# GLOVES
E:31:0x0F

# HELM
E:32:0x0F

# CROWN
E:33:0x0F

# SHIELD
E:34:0x0F

# CLOAK
E:35:0x0F

# SOFT_ARMOR
E:36:0x02

# HARD_ARMOR
E:37:0x02

# DRAG_ARMOR
E:38:0x02

# LITE
E:39:0x0B

# AMULET
E:40:0x03

# RING
E:45:0x04

# STAFF
E:55:0x0F

# WAND
E:65:0x05

# ROD
E:66:0x0A

# ROD TIP
E:67:0x0A

# SCROLL
E:70:0x01

# POTION
E:71:0x0E

# POTION2
E:72:0x0E

# FLASK
E:77:0x0B

# FOOD
E:80:0x0F

# BOOK
E:111:0x0E

# SYMBIOTIC_BOOK
E:112:0x05

# MUSIC_BOOK
E:113:0x02

# DRUID_BOOK
E:114:0x0D

# DAEMON BOOK
E:115:0x03

# POWER BATERIES
E:4:0x0D

# MAGE STAFFS
E:6:0x0E

# PARCHEMENT
E:8:0x03

# CORPSE
E:9:0x0F

# HYPNOS
E:99:0x0F

# RANDOM ARTIFACT
E:102:0x0D

# MUSICAL INSTRUMENT
E:14:0x0A

# EGG
E:10:0x03

# BASE RUNE
E:104:0x0A

# SECONDARY RUNE
E:105:0x03

# GOLD
E:100:0x0B

# TOOL
E:12:0x0A

# TRAPPING KIT
E:46:0x08

# TOTEM
E:54:0x08
tome-235-src/lib/save/0000755000076400017500000000000011012107763012372 5ustar  dgdgtome-235-src/lib/save/delete.me0000644000076400017500000000000111012107762014145 0ustar  dgdgatome-235-src/lib/scpt/0000755000076400017500000000000011012107763012405 5ustar  dgdgtome-235-src/lib/scpt/s_mana.lua0000644000076400017500000000642211012107762014351 0ustar  dgdg-- The mana school

function get_manathrust_dam()
	return 3 + get_level(MANATHRUST, 50), 1 + get_level(MANATHRUST, 20)
end

MANATHRUST = add_spell
{
	["name"] = 	"Manathrust",
	["school"] = 	SCHOOL_MANA,
	["level"] = 	1,
	["mana"] = 	1,
	["mana_max"] =  25,
	["fail"] = 	10,
	["stick"] =
	{
			["charge"] =    { 7, 10 },
			[TV_WAND] =
			{
				["rarity"] = 		5,
				["base_level"] =	{ 1, 20 },
				["max_level"] =		{ 15, 33 },
			},
	},
	["spell"] = 	function()
			local ret, dir	

			ret, dir = get_aim_dir()
			if ret == FALSE then return end
			return fire_bolt(GF_MANA, dir, damroll(get_manathrust_dam()))
	end,
	["info"] = 	function()
			local x, y

			x, y = get_manathrust_dam()
			return "dam "..x.."d"..y
	end,
	["desc"] =	{
			"Conjures up mana into a powerful bolt",
			"The damage is irresistible and will increase with level"
		}
}

DELCURSES = add_spell
{
	["name"] = 	"Remove Curses",
	["school"] = 	SCHOOL_MANA,
	["level"] = 	10,
	["mana"] = 	20,
	["mana_max"] = 	40,
	["fail"] = 	30,
	["stick"] =
	{
			["charge"] =    { 3, 8 },
			[TV_STAFF] =
			{
				["rarity"] = 		70,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 15, 50 },
			},
	},
	["inertia"] = 	{ 1, 10 },
	["spell"] = 	function()
			local done

			if get_level(DELCURSES, 50) >= 20 then done = remove_all_curse()
			else done = remove_curse() end
			if done == TRUE then msg_print("The curse is broken!") end
			return done
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Remove curses of worn objects",
			"At level 20 switches to *remove curses*"
		}
}

RESISTS = add_spell
{
	["name"] = 	"Elemental Shield",
	["school"] = 	SCHOOL_MANA,
	["level"] = 	20,
	["mana"] = 	17,
	["mana_max"] = 	20,
	["fail"] = 	40,
	["inertia"] = 	{ 2, 25 },
	["spell"] = 	function()
			local obvious
		       	if player.oppose_fire == 0 then obvious = set_oppose_fire(randint(10) + 15 + get_level(RESISTS, 50)) end
		       	if player.oppose_cold == 0 then obvious = is_obvious(set_oppose_cold(randint(10) + 15 + get_level(RESISTS, 50)), obvious) end
		       	if player.oppose_elec == 0 then obvious = is_obvious(set_oppose_elec(randint(10) + 15 + get_level(RESISTS, 50)), obvious) end
		       	if player.oppose_acid == 0 then obvious = is_obvious(set_oppose_acid(randint(10) + 15 + get_level(RESISTS, 50)), obvious) end
			return obvious
	end,
	["info"] = 	function()
			return "dur "..(15 + get_level(RESISTS, 50)).."+d10"
	end,
	["desc"] =	{
			"Provide resistances to the four basic elements",
		}
}

MANASHIELD = add_spell
{
	["name"] = 	"Disruption Shield",
	["school"] = 	SCHOOL_MANA,
	["level"] = 	45,
	["mana"] = 	50,
	["mana_max"] = 	50,
	["fail"] = 	90,
	["inertia"] = 	{ 9, 10},
	["spell"] = 	function()
			if get_level(MANASHIELD, 50) >= 5 then
			       	if (player.invuln == 0) then
					return set_invuln(randint(5) + 3 + get_level(MANASHIELD, 10))
				end
			else
			       	if (player.disrupt_shield == 0) then return set_disrupt_shield(randint(5) + 3 + get_level(MANASHIELD, 10)) end
			end
	end,
	["info"] = 	function()
			return "dur "..(3 + get_level(MANASHIELD, 10)).."+d5"
	end,
	["desc"] =	{
			"Uses mana instead of hp to take damage",
			"At level 5 switches to Globe of Invulnerability.",
			"The spell breaks as soon as a melee, shooting, throwing or magical",
			"skill action is attempted, and lasts only a short time."
		}
}
tome-235-src/lib/scpt/s_geom.lua0000644000076400017500000004413411012107762014366 0ustar  dgdg-- Geomancy school

function geomancy_random_wall(y, x)
	local c_ptr = cave(y, x)

	-- Do not destroy permanent things
	if cave_is(c_ptr, FF1_PERMANENT) ~= FALSE then return end

	local feat = nil
	local table =
	{
		[1] = { SKILL_FIRE, FEAT_SANDWALL, 1},

		[2] = { SKILL_WATER, FEAT_TREES, 1},
		[3] = { SKILL_WATER, FEAT_ICE_WALL, 12},

		[4] = { SKILL_EARTH, FEAT_WALL_EXTRA, 1},
	}

	while feat == nil do
		local t = table[randint(getn(table))]

		-- Do we meet the requirements ?
		-- And then select the features based on skill proportions
		if get_skill(t[1]) >= t[3] and magik(get_skill_scale(t[1], 100)) == TRUE then
			feat = t[2]
		end
	end

	cave_set_feat(y, x, feat)
end


GF_ELEMENTAL_WALL = add_spell_type
{
	["color"]       = { TERM_GREEN, 0 },
	["angry"]       = function() return TRUE, FALSE end,
	["grid"]     	= function(who, dam, rad, y, x)
			if player.py ~= y or player.px ~= x then
				geomancy_random_wall(y, x)
			end
	end,
}

function geomancy_random_floor(y, x, kill_wall)
	local c_ptr = cave(y, x)

	-- Do not destroy permanent things
	if cave_is(c_ptr, FF1_PERMANENT) ~= FALSE then return end
	if not kill_wall then
		if cave_is(c_ptr, FF1_FLOOR) ~= TRUE then return end
	end

	local feat = nil
	local table =
	{
		[1] = { SKILL_FIRE, FEAT_SAND, 1},
		[2] = { SKILL_FIRE, FEAT_SHAL_LAVA, 8},
		[3] = { SKILL_FIRE, FEAT_DEEP_LAVA, 18},

		[4] = { SKILL_WATER, FEAT_SHAL_WATER, 1},
		[5] = { SKILL_WATER, FEAT_DEEP_WATER, 8},
		[6] = { SKILL_WATER, FEAT_ICE, 18},

		[7] = { SKILL_EARTH, FEAT_GRASS, 1},
		[8] = { SKILL_EARTH, FEAT_FLOWER, 8},
		[9] = { SKILL_EARTH, FEAT_DARK_PIT, 18},
	}

	while feat == nil do
		local t = table[randint(getn(table))]

		-- Do we meet the requirements ?
		-- And then select the features based on skill proportions
		if get_skill(t[1]) >= t[3] and magik(get_skill_scale(t[1], 100)) == TRUE then
			feat = t[2]
		end
	end

	cave_set_feat(y, x, feat)
end


GF_ELEMENTAL_GROWTH = add_spell_type
{
	["color"]       = { TERM_GREEN, 0 },
	["angry"]       = function() return TRUE, FALSE end,
	["grid"]     	= function(who, dam, rad, y, x)
			geomancy_random_floor(y, x)
	end,
}

CALL_THE_ELEMENTS = add_spell
{
	["name"] = 	"Call the Elements",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	1,
	["mana"] = 	2,
	["mana_max"] = 	20,
	["fail"] = 	10,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	["random"] =    0,
	["spell"] = 	function()
			local ret, dir = 0, 0

			if get_level(CALL_THE_ELEMENTS) >= 17 then
				ret, dir = get_aim_dir()
				if ret == FALSE then return end
			end

			fire_ball(GF_ELEMENTAL_GROWTH, dir, 1, 1 + get_level(CALL_THE_ELEMENTS, 5, 0))
			return TRUE
	end,
	["info"] = 	function()
			return "rad "..(1 + get_level(CALL_THE_ELEMENTS, 5, 0))
	end,
	["desc"] =	{
			"Randomly creates various elements around you",
			"Each type of element chance is controlled by your level",
			"in the corresponding skill",
			"At level 17 it can be targeted",
	}
}

-- Seperate function because an other spell needs it
function channel_the_elements(y, x, level, silent)
	local t =
	{
		-- Earth stuff
		[FEAT_GRASS] = function()
			hp_player(player.mhp * (5 + get_skill_scale(SKILL_EARTH, 20)) / 100)
		end,
		[FEAT_FLOWER] = function()
			hp_player(player.mhp * (5 + get_skill_scale(SKILL_EARTH, 30)) / 100)
		end,
		[FEAT_DARK_PIT] = function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			local type = GF_DARK
			if get_skill(SKILL_EARTH) >= 18 then type = GF_NETHER end
			fire_bolt(type, dir, damroll(10, get_skill(SKILL_EARTH)))
		end,

		-- Water stuff
		[FEAT_SHAL_WATER] = function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			local type = GF_WATER
			if get_skill(SKILL_WATER) >= 18 then type = GF_WAVE end

			if get_skill(SKILL_WATER) >= 8 then
				fire_beam(type, dir, damroll(3, get_skill(SKILL_WATER)))
			else
				fire_bolt(type, dir, damroll(3, get_skill(SKILL_WATER)))
			end
		end,
		[FEAT_DEEP_WATER] = function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			local type = GF_WATER
			if get_skill(SKILL_WATER) >= 18 then type = GF_WAVE end

			if get_skill(SKILL_WATER) >= 8 then
				fire_beam(type, dir, damroll(5, get_skill(SKILL_WATER)))
			else
				fire_bolt(type, dir, damroll(5, get_skill(SKILL_WATER)))
			end
		end,
		[FEAT_ICE] = function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			if get_skill(SKILL_WATER) >= 12 then
				fire_ball(GF_ICE, dir, get_skill_scale(SKILL_WATER, 340), 3)
			else
				fire_bolt(GF_ICE, dir, damroll(3, get_skill(SKILL_WATER)))
			end
		end,

		-- Fire stuff
		[FEAT_SAND] = function()
			local type
			if (get_level(FIERYAURA, 50) >= 8) then
				type = SHIELD_GREAT_FIRE
			else
				type = SHIELD_FIRE
			end
			local dur = randint(20) + %level + get_skill(SKILL_AIR)
			set_shield(dur, 0, type, 5 + get_skill_scale(SKILL_FIRE, 20), 5 + get_skill_scale(SKILL_FIRE, 14))
			set_blind(dur)
		end,
		[FEAT_SHAL_LAVA] = function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			if get_skill(SKILL_FIRE) >= 15 then
				fire_bolt(GF_HELL_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15))
			else
				fire_bolt(GF_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15))
			end
		end,
		[FEAT_DEEP_LAVA] = function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			if get_skill(SKILL_FIRE) >= 15 then
				fire_ball(GF_HELL_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15), 3)
			else
				fire_ball(GF_FIRE, dir, damroll(get_skill_scale(SKILL_FIRE, 30), 15), 3)
			end
		end,
	}

	if t[cave(y, x).feat] then
		t[cave(y, x).feat]()

		if magik(100 - level) == TRUE then
			if cave(y, x).feat == FEAT_FLOWER then
				cave_set_feat(y, x, FEAT_GRASS)
			else
				cave_set_feat(y, x, FEAT_FLOOR)
			end
			msg_print("The area is drained.")
		end
	elseif not silent then
		msg_print("You cannot channel this area.")
	end
end

CHANNEL_ELEMENTS = add_spell
{
	["name"] = 	"Channel Elements",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	3,
	["mana"] = 	3,
	["mana_max"] = 	30,
	["fail"] = 	20,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	["random"] =    0,
	["spell"] = 	function()
			channel_the_elements(player.py, player.px, get_level(CHANNEL_ELEMENTS), nil)
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Draws on the caster's immediate environs to form an attack or other effect.",
			"Grass/Flower heals.",
			"Water creates water bolt attacks.",
			"Ice creates ice bolt attacks.",
			"Sand creates a wall of thick, blinding, burning sand around you.",
			"Lava creates fire bolt attacks.",
			"Deep lava creates fire ball attacks.",
			"Chasm creates darkness bolt attacks.",
			"At Earth level 18, darkness becomes nether.",
			"At Water level 8, water attacks become beams with a striking effect.",
			"At Water level 12, ice attacks become balls of ice shards.",
			"At Water level 18, water attacks push monsters back.",
			"At Fire level 15, fire become hellfire.",
	}
}

ELEMENTAL_WAVE = add_spell
{
	["name"] = 	"Elemental Wave",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	15,
	["mana"] = 	15,
	["mana_max"] = 	50,
	["fail"] = 	20,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	["random"] =    0,
	["spell"] = 	function()
			local ret, dir = get_rep_dir()
			if ret == FALSE then return end

			local y, x = explode_dir(dir)
			y = y + player.py
			x = x + player.px

			local t =
			{
				-- Earth stuff
				[FEAT_GRASS] 		= { GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 200) },
				[FEAT_FLOWER] 		= { GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 300) },
				-- cannot turn chasm into a wave

				-- Water stuff
				[FEAT_SHAL_WATER] 	= { GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 200) },
				[FEAT_DEEP_WATER] 	= { GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 300) },
				[FEAT_ICE] 		= { GF_ICE, GF_ICE, 10 + get_skill_scale(SKILL_WATER, 200) },

				-- Fire stuff
				[FEAT_SAND] 		= { GF_LITE, GF_LITE, 10 + get_skill_scale(SKILL_FIRE, 400) },
				[FEAT_SHAL_LAVA] 	= { GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 200) },
				[FEAT_DEEP_LAVA] 	= { GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 300) },
			}


			local effect = t[cave(y, x).feat]
			if not effect then
				msg_print("You cannot channel this area.")
			else
				local typ = effect[1]
				if get_level(ELEMENTAL_WAVE) >= 20 then typ = effect[2] end

				cave_set_feat(y, x, FEAT_FLOOR)

				fire_wave(typ, 0, effect[3], 0, 6 + get_level(ELEMENTAL_WAVE, 20), EFF_WAVE + EFF_LAST + getglobal("EFF_DIR"..dir))
			end

			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Draws on an adjacent special square to project a slow-moving",
			"wave of that element in that direction",
			"Abyss squares cannot be channeled into a wave.",
	}
}

VAPORIZE = add_spell
{
	["name"] = 	"Vaporize",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	4,
	["mana"] = 	3,
	["mana_max"] = 	30,
	["fail"] = 	15,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	-- Must have at least 4 Air
	["random"] =    0,
	["depend"] =    function()
			if get_skill(SKILL_AIR) >= 4 then return TRUE end
	end,
	["spell"] = 	function()
			local t =
			{
				-- Earth stuff
				[FEAT_GRASS] 		= { GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 100) },
				[FEAT_FLOWER] 		= { GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 150) },
				[FEAT_DARK_PIT] 	= { GF_DARK, GF_DARK, 5 + get_skill_scale(SKILL_EARTH, 200) },

				-- Water stuff
				[FEAT_SHAL_WATER] 	= { GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 100) },
				[FEAT_DEEP_WATER] 	= { GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 150) },
				[FEAT_ICE] 		= { GF_ICE, GF_ICE, 5 + get_skill_scale(SKILL_WATER, 100) },

				-- Fire stuff
				[FEAT_SAND] 		= { GF_LITE, GF_LITE, 5 + get_skill_scale(SKILL_FIRE, 200) },
				[FEAT_SHAL_LAVA] 	= { GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 100) },
				[FEAT_DEEP_LAVA] 	= { GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 150) },
			}

			local effect = t[cave(player.py, player.px).feat]
			if not effect then
				msg_print("You cannot channel this area.")
			else
				local typ = effect[1]
				if get_level(VAPORIZE) >= 20 then typ = effect[2] end

				cave_set_feat(player.py, player.px, FEAT_FLOOR)

				fire_cloud(typ, 0, effect[3], 1 + get_level(VAPORIZE, 4), 10 + get_level(VAPORIZE, 20))
			end

			return TRUE
	end,
	["info"] = 	function()
			return "rad "..(1 + get_level(VAPORIZE, 4)).." dur "..(10 + get_level(VAPORIZE, 20))
	end,
	["desc"] =	{
			"Draws upon your immediate environs to form a cloud of damaging vapors",
	}
}

geomancy_can_tunnel =
{
	[FEAT_WALL_EXTRA] = TRUE,
	[FEAT_WALL_OUTER] = TRUE,
	[FEAT_WALL_INNER] = TRUE,
	[FEAT_WALL_SOLID] = TRUE,

	[FEAT_MAGMA] = TRUE,
	[FEAT_QUARTZ] = TRUE,
	[FEAT_MAGMA_H] = TRUE,
	[FEAT_QUARTZ_H] = TRUE,
	[FEAT_MAGMA_K] = TRUE,
	[FEAT_QUARTZ_K] = TRUE,

	[FEAT_TREES] = TRUE,
	[FEAT_DEAD_TREE] = TRUE,

	[FEAT_SANDWALL] = TRUE,
	[FEAT_SANDWALL_H] = TRUE,
	[FEAT_SANDWALL_K] = TRUE,

	[FEAT_ICE_WALL] = TRUE,
}

-- Dig & sprew
function geomancy_dig(oy, ox, dir, length)
	local dy, dx = explode_dir(dir)
	local y = dy + oy
	local x = dx + ox

	for i = 1, length do
		local c_ptr = cave(y, x)
		local ox = x - dx
		local oy = y - dy

		-- stop at the end of tunnelable things
		if not geomancy_can_tunnel[c_ptr.feat] then break end

		if geomancy_can_tunnel[cave(y - 1, x - 1).feat] then geomancy_random_wall(y - 1, x - 1) end
		if geomancy_can_tunnel[cave(y - 1, x).feat] then geomancy_random_wall(y - 1, x) end
		if geomancy_can_tunnel[cave(y - 1, x + 1).feat] then geomancy_random_wall(y - 1, x + 1) end

		if geomancy_can_tunnel[cave(y, x - 1).feat] then geomancy_random_wall(y, x - 1) end
		if geomancy_can_tunnel[cave(y, x + 1).feat] then geomancy_random_wall(y, x + 1) end

		if geomancy_can_tunnel[cave(y + 1, x - 1).feat] then geomancy_random_wall(y + 1, x - 1) end
		if geomancy_can_tunnel[cave(y + 1, x).feat] then geomancy_random_wall(y + 1, x) end
		if geomancy_can_tunnel[cave(y + 1, x + 1).feat] then geomancy_random_wall(y + 1, x + 1) end

		y = y + dy
		x = x + dx
	end

	y = y - dy
	x = x - dx
	while (y ~= oy) or (x ~= ox) do
		geomancy_random_floor(y, x, TRUE)

		-- Should we branch ?
		if magik(20) == TRUE then
			local rot = 1
			if magik(50) == TRUE then rot = -1 end
			geomancy_dig(y, x, rotate_dir(dir, rot), length / 3)
		end

		y = y - dy
		x = x - dx
	end
end

GEOLYSIS = add_spell
{
	["name"] = 	"Geolysis",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	7,
	["mana"] = 	15,
	["mana_max"] = 	40,
	["fail"] = 	15,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	["random"] =    0,
	-- Must have at least 7 Earth
	["depend"] =    function()
			if get_skill(SKILL_EARTH) >= 7 then return TRUE end
	end,
	["spell"] = 	function()
			local ret, dir = get_rep_dir()
			if ret == FALSE then return end

			msg_print("Elements recombine before you, laying down an open path.")
			geomancy_dig(player.py, player.px, dir, 5 + get_level(GEOLYSIS, 12))

			return TRUE
	end,
	["info"] = 	function()
			return "length "..(5 + get_level(GEOLYSIS, 12))
	end,
	["desc"] =	{
			"Burrows deeply and slightly at random into a wall,",
			"leaving behind tailings of various different sorts of walls in the passage.",
	}
}

player.dripping_tread = 0
add_loadsave("player.dripping_tread", 0)
add_hooks
{
	[HOOK_MOVED] = function(oy, ox)
		if player.dripping_tread > 0 then
			geomancy_random_floor(oy, ox)
			player.dripping_tread = player.dripping_tread - 1
			if player.dripping_tread == 0 then
				msg_print("You stop dripping raw elemental energies.")
			end
		end
	end
}
DRIPPING_TREAD = add_spell
{
	["name"] = 	"Dripping Tread",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	10,
	["mana"] = 	15,
	["mana_max"] = 	25,
	["fail"] = 	15,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	["random"] =    0,
	-- Must have at least 10 Water
	["depend"] =    function()
			if get_skill(SKILL_WATER) >= 10 then return TRUE end
	end,
	["spell"] =     function()
			if player.dripping_tread == 0 then
				player.dripping_tread = randint(15) + 10 + get_level(DRIPPING_TREAD)
				msg_print("You start dripping raw elemental energies.")
			else
				player.dripping_tread = 0
				msg_print("You stop dripping raw elemental energies.")
			end
			return TRUE
	end,
	["info"] = 	function()
			return "dur "..(10 + get_level(DRIPPING_TREAD)).."+d15 movs"
	end,
	["desc"] =	{
			"Causes you to leave random elemental forms behind as you walk",
	}
}

GROW_BARRIER = add_spell
{
	["name"] = 	"Grow Barrier",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	12,
	["mana"] = 	30,
	["mana_max"] = 	40,
	["fail"] = 	15,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	["random"] =    0,
	-- Must have at least 12 Earth
	["depend"] =    function()
			if get_skill(SKILL_EARTH) >= 12 then return TRUE end
	end,
	["spell"] = 	function()
			local ret, dir = 0, 0

			if get_level(GROW_BARRIER) >= 20 then
				ret, dir = get_aim_dir()
				if ret == FALSE then return end
			end

			fire_ball(GF_ELEMENTAL_WALL, dir, 1, 1)
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Creates impassable terrain (walls, trees, etc.) around you.",
			"At level 20 it can be projected around another area.",
	}
}

ELEMENTAL_MINION = add_spell
{
	["name"] = 	"Elemental Minion",
	["school"] = 	{SCHOOL_GEOMANCY},
	["level"] = 	20,
	["mana"] = 	40,
	["mana_max"] = 	80,
	["fail"] = 	25,
	-- Unnafected by blindness
	["random"] =    0,
	-- Must have at least 12 Earth
	["spell"] = 	function()
			local ret, dir = 0, 0

			ret, dir = get_rep_dir()
			if ret == FALSE then return end

			local t =
			{
				[FEAT_WALL_EXTRA] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_WALL_OUTER] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_WALL_INNER] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_WALL_SOLID] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_MAGMA] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_QUARTZ] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_MAGMA_H] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_QUARTZ_H] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_MAGMA_K] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },
				[FEAT_QUARTZ_K] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } },

				[FEAT_DARK_PIT] = { SKILL_AIR, { "Air elemental", "Ancient blue dragon", "Great Storm Wyrm", "Sky Drake" } },

				[FEAT_SANDWALL] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } },
				[FEAT_SANDWALL_H] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } },
				[FEAT_SANDWALL_K] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } },
				[FEAT_SHAL_LAVA] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } },
				[FEAT_DEEP_LAVA] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } },

				[FEAT_ICE_WALL] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } },
				[FEAT_SHAL_WATER] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } },
				[FEAT_DEEP_WATER] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } },
			}

			local y, x = explode_dir(dir)
			y = y + player.py
			x = x + player.px

			local effect = t[cave(y, x).feat]
			if not effect then
				msg_print("You cannot summon from this area.")
			else
				local skill = effect[1]
				local types = effect[2]

				local max = get_skill_scale(skill, getn(types))
				if max == 0 then max = 1 end

				local r_idx = test_monster_name(types[rand_range(1, max)])

				-- Summon it
				local my, mx = find_position(y, x)
				local m_idx = place_monster_one(my, mx, r_idx, 0, FALSE, MSTATUS_FRIEND)

				-- level it
				if m_idx ~= 0 then
					monster_set_level(m_idx, 10 + get_level(ELEMENTAL_MINION, 120))
				end

				cave_set_feat(y, x, FEAT_FLOOR)
			end

			return TRUE
	end,
	["info"] = 	function()
			return "min level "..(10 + get_level(ELEMENTAL_MINION, 120))
	end,
	["desc"] =	{
			"Summons a minion from a nearby element.",
			"Walls can summon Earth elmentals, Xorns and Xarens",
			"Dark Pits can summon Air elementals, Ancient blue dragons, Great Storm Wyrms",
			"and Sky Drakes",
			"Sandwalls and lava can summon Fire elementals and Ancient red dragons",
			"Icewall, and water can summon Water elementals, Water trolls and Water demons",
	}
}
tome-235-src/lib/scpt/s_water.lua0000644000076400017500000000707411012107762014563 0ustar  dgdg-- handle the water school

TIDALWAVE = add_spell
{
	["name"] = 	"Tidal Wave",
	["school"] = 	{SCHOOL_WATER},
	["level"] = 	16,
	["mana"] = 	16,
	["mana_max"] = 	40,
	["fail"] = 	65,
	["stick"] =
	{
			["charge"] =    { 6, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		54,
				["base_level"] =	{ 1, 10 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["inertia"] = 	{ 4, 100 },
	["spell"] = 	function()
			fire_wave(GF_WAVE, 0, 40 + get_level(TIDALWAVE, 200), 0, 6 + get_level(TIDALWAVE, 10), EFF_WAVE)
			return TRUE
	end,
	["info"] = 	function()
			return "dam "..(40 + get_level(TIDALWAVE,  200)).." rad "..(6 + get_level(TIDALWAVE,  10))
	end,
	["desc"] =	{
			"Summons a monstrous tidal wave that will expand and crush the",
			"monsters under its mighty waves."
	}
}

ICESTORM = add_spell
{
	["name"] = 	"Ice Storm",
	["school"] = 	{SCHOOL_WATER},
	["level"] = 	22,
	["mana"] = 	30,
	["mana_max"] = 	60,
	["fail"] = 	80,
	["stick"] =
	{
			["charge"] =    { 3, 7 },
			[TV_WAND] =
			{
				["rarity"] = 		65,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 25, 45 },
			},
	},
	["inertia"] = 	{ 3, 40 },
	["spell"] = 	function()
			local type
	
			if get_level(ICESTORM, 50) >= 10 then type = GF_ICE
			else type = GF_COLD end
			fire_wave(type, 0, 80 + get_level(ICESTORM, 200), 1 + get_level(ICESTORM, 3, 0), 20 + get_level(ICESTORM, 70), EFF_STORM)
			return TRUE
	end,
	["info"] = 	function()
			return "dam "..(80 + get_level(ICESTORM, 200)).." rad "..(1 + get_level(ICESTORM, 3, 0)).." dur "..(20 + get_level(ICESTORM, 70))
	end,
	["desc"] =	{
			"Engulfs you in a storm of roaring cold that strikes your foes.",
			"At level 10 it turns into shards of ice."
	}
}

ENTPOTION = add_spell
{
	["name"] = 	"Ent's Potion",
	["school"] = 	{SCHOOL_WATER},
	["level"] = 	6,
	["mana"] = 	7,
	["mana_max"] = 	15,
	["fail"] = 	35,
	["inertia"] = 	{ 1, 30 },
	["spell"] = 	function()
			set_food(PY_FOOD_MAX - 1)
			msg_print("The Ent's Potion fills your stomach.")
			if get_level(ENTPOTION, 50) >= 5 then
				set_afraid(0)
			end
			if get_level(ENTPOTION, 50) >= 12 then
				set_hero(player.hero + randint(25) + 25 + get_level(ENTPOTION, 40))
			end
			return TRUE
	end,
	["info"] = 	function()
			if get_level(ENTPOTION, 50) >= 12 then
				return "dur "..(25 + get_level(ENTPOTION, 40)).."+d25"
			else
				return ""
			end
	end,
	["desc"] =	{
			"Fills up your stomach.",
			"At level 5 it boldens your heart.",
			"At level 12 it make you heroic."
	}
}

VAPOR = add_spell
{
	["name"] = 	"Vapor",
	["school"] = 	{SCHOOL_WATER},
	["level"] = 	2,
	["mana"] = 	2,
	["mana_max"] = 	12,
	["fail"] = 	20,
	["inertia"] = 	{ 1, 30 },
	["spell"] = 	function()
			fire_cloud(GF_WATER, 0, 3 + get_level(VAPOR, 20), 3 + get_level(VAPOR, 9, 0), 5)
			return TRUE
	end,
	["info"] = 	function()
       			return "dam "..(3 + get_level(VAPOR, 20)).." rad "..(3 + get_level(VAPOR, 9, 0)).." dur 5"
	end,
	["desc"] =	{
			"Fills the air with toxic moisture to eradicate annoying critters."
	}
}

function get_geyser_damage()
	return get_level(GEYSER, 10), 3 + get_level(GEYSER, 35)
end

GEYSER = add_spell
{
	["name"] = "Geyser",
	["school"] = SCHOOL_WATER,
	["level"] = 1,
	["mana"] = 1,
	["mana_max"] = 35,
	["fail"] = 5,
	["spell"] = function()
		local ret, dir
		ret, dir = get_aim_dir()
		if ret == FALSE then return end
		return fire_bolt_or_beam(2 * get_level(GEYSER, 85), GF_WATER, dir, damroll(get_geyser_damage()))
	end,
	["info"] = function()
		local n, d
		n, d = get_geyser_damage()
		return "dam "..n.."d"..d
	end,
	["desc"] =
	{
		"Shoots a geyser of water from your fingertips.",
		"Sometimes it can blast through its first target."
	},
}
tome-235-src/lib/scpt/s_fire.lua0000644000076400017500000001352111012107762014360 0ustar  dgdg-- handle the fire school

GLOBELIGHT = add_spell
{
	["name"] =      "Globe of Light",
	["school"] =    {SCHOOL_FIRE},
	["level"] =     1,
	["mana"] =      2,
	["mana_max"] =  15,
	["fail"] =      10,
	["stick"] =
	{
			["charge"] =    { 10, 5 },
			[TV_STAFF] =
			{
				["rarity"] =	    7,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 10, 45 },
			},
	},
	["inertia"] = 	{ 1, 40 },
	["spell"] =     function()
		local obvious
		if get_level(GLOBELIGHT, 50) >= 3 then
			obvious = lite_area(10, 4)
		else
			lite_room(player.py, player.px)
			obvious = TRUE
		end
		if get_level(GLOBELIGHT, 50) >= 15 then
			obvious = is_obvious(fire_ball(GF_LITE, 0, 10 + get_level(GLOBELIGHT, 100), 5 + get_level(GLOBELIGHT, 6)), obvious)
			player.update = bor(player.update, PU_VIEW)
		end
		return obvious
	end,
	["info"] =      function()
		if get_level(GLOBELIGHT, 50) >= 15 then
			return "dam "..(10 + get_level(GLOBELIGHT, 100)).." rad "..(5 + get_level(GLOBELIGHT, 6))
		else
			return ""
		end
	end,
	["desc"] =      {
			"Creates a globe of pure light",
			"At level 3 it starts damaging monsters",
			"At level 15 it starts creating a more powerful kind of light",
	}
}

FIREFLASH = add_spell
{
	["name"] =      "Fireflash",
	["school"] =    {SCHOOL_FIRE},
	["level"] =     10,
	["mana"] =      5,
	["mana_max"] =  70,
	["fail"] =      35,
	["stick"] =
	{
			["charge"] =    { 5, 5 },
			[TV_WAND] =
			{
				["rarity"] =	    35,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 15, 35 },
			},
	},
	["spell"] =     function()
		local ret, dir, type
		if (get_level(FIREFLASH, 50) >= 20) then
			type = GF_HOLY_FIRE
		else
			type = GF_FIRE
		end
		ret, dir = get_aim_dir()
		if ret == FALSE then return end
		return fire_ball(type, dir, 20 + get_level(FIREFLASH, 500), 2 + get_level(FIREFLASH, 5))
	end,
	["info"] =      function()
		return "dam "..(20 + get_level(FIREFLASH, 500)).." rad "..(2 + get_level(FIREFLASH, 5))
	end,
	["desc"] =      {
			"Conjures a ball of fire to burn your foes to ashes",
			"At level 20 it turns into a ball of holy fire"
	}
}

FIERYAURA = add_spell
{
	["name"] =      "Fiery Shield",
	["school"] =    {SCHOOL_FIRE},
	["level"] =     20,
	["mana"] =      20,
	["mana_max"] =  60,
	["fail"] =      50,
	["stick"] =
	{
			["charge"] =    { 3, 5 },
			[TV_STAFF] =
			{
				["rarity"] =	    50,
				["base_level"] =	{ 1, 10 },
				["max_level"] =		{ 5, 40 },
			},
	},
	["inertia"] = 	{ 2, 15 },
	["spell"] =     function()
		local type
		if (get_level(FIERYAURA, 50) >= 8) then
			type = SHIELD_GREAT_FIRE
		else
			type = SHIELD_FIRE
		end
		return set_shield(randint(20) + 10 + get_level(FIERYAURA, 70), 10, type, 5 + get_level(FIERYAURA, 10), 5 + get_level(FIERYAURA, 7))
	end,
	["info"] =      function()
		return "dam "..(5 + get_level(FIERYAURA, 15)).."d"..(5 + get_level(FIERYAURA, 7)).." dur "..(10 + get_level(FIERYAURA, 70)).."+d20"
	end,
	["desc"] =      {
			"Creates a shield of fierce flames around you",
			"At level 8 it turns into a greater kind of flame that can not be resisted"
	}
}

FIREWALL = add_spell
{
	["name"] =      "Firewall",
	["school"] =    {SCHOOL_FIRE},
	["level"] =     15,
	["mana"] =      25,
	["mana_max"] =  100,
	["fail"] =      40,
	["stick"] =
	{
			["charge"] =    { 4, 5 },
			[TV_WAND] =
			{
				["rarity"] =	    55,
				["base_level"] =	{ 1, 10 },
				["max_level"] =		{ 5, 40 },
			},
	},
	["spell"] =     function()
		local ret, dir, type
		if (get_level(FIREWALL, 50) >= 6) then
			type = GF_HELL_FIRE
		else
			type = GF_FIRE
		end
		ret, dir = get_aim_dir()
		if ret == FALSE then return end
		fire_wall(type, dir, 40 + get_level(FIREWALL, 150), 10 + get_level(FIREWALL, 14))
		return TRUE
	end,
	["info"] =      function()
		return "dam "..(40 + get_level(FIREWALL, 150)).." dur "..(10 + get_level(FIREWALL, 14))
	end,
	["desc"] =      {
			"Creates a fiery wall to incinerate monsters stupid enough to attack you",
			"At level 6 it turns into a wall of hell fire"
	}
}

FIREGOLEM = add_spell
{
	["name"] =      "Fire Golem",
	["school"] =    {SCHOOL_FIRE, SCHOOL_MIND},
	["level"] =     7,
	["mana"] =      16,
	["mana_max"] =  70,
	["fail"] =      40,
	["spell"] =     function()
			local m_idx, y, x, ret, item

			-- Can we reconnect ?
			if do_control_reconnect() == TRUE then
				msg_print("Control re-established.")
				return
			end

			ret, item = get_item("Which light source do you want to use to create the golem?",
					     "You have no light source for the golem",
					     bor(USE_INVEN, USE_EQUIP),
					     function (obj)
						if (obj.tval == TV_LITE) and ((obj.sval == SV_LITE_TORCH) or (obj.sval == SV_LITE_LANTERN)) then
							return TRUE
							end
							return FALSE
					     end
			)
			if ret == FALSE then return TRUE end
			inven_item_increase(item, -1)
			inven_item_describe(item)
			inven_item_optimize(item)

			-- Summon it
			m_allow_special[1043 + 1] = TRUE
			y, x = find_position(player.py, player.px)
			m_idx = place_monster_one(y, x, 1043, 0, FALSE, MSTATUS_FRIEND)
			m_allow_special[1043 + 1] = FALSE

			-- level it
			if m_idx ~= 0 then
				monster_set_level(m_idx, 7 + get_level(FIREGOLEM, 70))
				player.control = m_idx
				monster(m_idx).mflag = bor(monster(m_idx).mflag, MFLAG_CONTROL)
			end
			return TRUE
	end,
	["info"] =      function()
			return "golem level "..(7 + get_level(FIREGOLEM, 70))
	end,
	["desc"] =      {
			"Creates a fiery golem and controls it",
			"During the control the available keylist is:",
			"Movement keys: movement of the golem(depending on its speed",
			"               it can move more than one square)",
			", : pickup all items on the floor",
			"d : drop all carried items",
			"i : list all carried items",
			"m : end the possession/use golem powers",
			"Most of the other keys are disabled, you cannot interact with your",
			"real body while controlling the golem",
			"But to cast the spell you will need a lantern or a wooden torch to",
			"Create the golem from"
	}
}
tome-235-src/lib/scpt/intro.lua0000644000076400017500000000557411012107762014255 0ustar  dgdgfunction drop_text_left(c, str, y, o)
	local i = strlen(str)
	local x = 39 - (strlen(str) / 2) + o
	while (i > 0)
	do
		local a = 0
		local time = 0

		if (strbyte(str, i) ~= strbyte(" ", 1)) then
			while (a < x + i - 1)
			do
				Term_putch(a - 1, y, c, 32)
				Term_putch(a, y, c, strbyte(str, i))
				time = time + 1
				if time >= 4 then
					Term_xtra(TERM_XTRA_DELAY, 1)
					time = 0
				end
				Term_redraw_section(a - 1, y, a, y)
				a = a + 1

				inkey_scan = TRUE
				if (inkey() ~= 0) then
					return TRUE
				end
			end
		end

		i = i - 1
	end
	return FALSE
end

function drop_text_right(c, str, y, o)
	local x = 39 - (strlen(str) / 2) + o
	local i = 1
	while (i <= strlen(str))
	do
		local a = 79
		local time = 0

		if (strbyte(str, i) ~= strbyte(" ", 1)) then
			while (a >= x + i - 1)
			do
				Term_putch(a + 1, y, c, 32)
				Term_putch(a, y, c, strbyte(str, i))
				time = time + 1
				if time >= 4 then
					Term_xtra(TERM_XTRA_DELAY, 1)
					time = 0
				end
				Term_redraw_section(a, y, a + 1, y)
				a = a - 1

				inkey_scan = TRUE
				if (inkey() ~= 0) then
					return TRUE
				end
			end
		end

		i = i + 1
	end
	return FALSE
end

function tome_intro()
	screen_save()
	Term_clear()

	if (TRUE == drop_text_left(TERM_L_BLUE, "Art thou an adventurer,", 10, 0)) then screen_load() return end
	if (TRUE == drop_text_right(TERM_L_BLUE, "One who passes through the waterfalls we call danger", 11, -1)) then screen_load() return end
	if (TRUE == drop_text_left(TERM_L_BLUE, "to find the true nature of the legends beyond them?", 12, 0)) then screen_load() return end
	if (TRUE == drop_text_right(TERM_L_BLUE, "If this is so, then seeketh me.", 13, -1)) then screen_load() return end

	if (TRUE == drop_text_left(TERM_WHITE, "[Press any key to continue]", 23, -1)) then screen_load() return end

	Term_putch(0, 0, TERM_DARK, 32)
	inkey_scan = FALSE
	inkey()

	Term_clear()

	if (TRUE == drop_text_left(TERM_L_BLUE, "DarkGod", 8, 0)) then screen_load() return end
	if (TRUE == drop_text_right(TERM_WHITE, "in collaboration with", 9, -1)) then screen_load() return end
	if (TRUE == drop_text_left(TERM_L_GREEN, "Eru Iluvatar,", 10, 0)) then screen_load() return end
	if (TRUE == drop_text_right(TERM_L_GREEN, "Manwe", 11, -1)) then screen_load() return end
	if (TRUE == drop_text_left(TERM_WHITE, "and", 12, 0)) then screen_load() return end
	if (TRUE == drop_text_right(TERM_L_GREEN, "All the T.o.M.E. contributors(see credits.txt)", 13, -1)) then screen_load() return end

	if (TRUE == drop_text_left(TERM_WHITE, "present", 15, 1)) then screen_load() return end
	if (TRUE == drop_text_right(TERM_YELLOW, "T.o.M.E.", 16, 0)) then screen_load() return end

	if (TRUE == drop_text_left(TERM_WHITE, "[Press any key to continue]", 23, -1)) then screen_load() return end
	Term_putch(0, 0, TERM_DARK, 32)

	inkey_scan = FALSE

	inkey()

	screen_load()
	return
end

add_hook_script(HOOK_INIT, "tome_intro", "lua_intro_init")
tome-235-src/lib/scpt/corrupt.lua0000644000076400017500000002737011012107762014616 0ustar  dgdg-- Definition of the corruptions

-- The Balrog corruptions
CORRUPT_BALROG_AURA = add_corruption
{
	["color"]       = TERM_ORANGE,
	["name"]	= "Balrog Aura",
	["get_text"]    = "A corrupted wall of flames surrounds you.",
	["lose_text"]   = "The wall of corrupted flames abandons you.",
	["desc"]	=
	{
			  "  Surrounds you with a fiery aura",
			  "  But it can burn scrolls when you read them"
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.xtra_f3 = bor(player.xtra_f3, TR3_SH_FIRE)
			player.xtra_f3 = bor(player.xtra_f3, TR3_LITE1)
		end,
		[HOOK_READ] = function(obj)
			if magik(5) == TRUE then
				msg_print("Your demon aura burns the scroll before you read it!")
				return TRUE, TRUE, FALSE
			else
				return FALSE
			end
		end,
	},
}

CORRUPT_BALROG_WINGS = add_corruption
{
	["color"]       = TERM_ORANGE,
	["name"]	= "Balrog Wings",
	["get_text"]    = "Wings of shadow grow in your back.",
	["lose_text"]   = "The wings in your back fall apart.",
	["desc"]	=
	{
			  "  Creates ugly, but working, wings allowing you to fly",
			  "  But it reduces charisma by 4 and dexterity by 2"
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.xtra_f4 = bor(player.xtra_f4, TR4_FLY)
			player.modify_stat(A_CHR, -4)
			player.modify_stat(A_DEX, -2)
		end,
	},
}

CORRUPT_BALROG_STRENGTH = add_corruption
{
	["color"]       = TERM_ORANGE,
	["name"]	= "Balrog Strength",
	["get_text"]    = "Your muscles get unnatural strength.",
	["lose_text"]   = "Your muscles get weaker again.",
	["desc"]	=
	{
			  "  Provides 3 strength and 1 constitution",
			  "  But it reduces charisma by 1 and dexterity by 3"
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.modify_stat(A_STR, 3)
			player.modify_stat(A_CON, 1)
			player.modify_stat(A_DEX, -3)
			player.modify_stat(A_CHR, -1)
		end,
	},
}

CORRUPT_BALROG_FORM = add_corruption
{
	["color"]       = TERM_YELLOW,
	["name"]	= "Balrog Form",
	["get_text"]    = "You feel the might of a Balrog inside you.",
	["lose_text"]   = "The presence of the Balrog seems to abandon you.",
	["desc"]	=
	{
			  "  Allows you to turn into a Balrog at will",
			  "  You need Balrog Wings, Balrog Aura and Balrog Strength to activate it"
	},
	["depends"]     =
	{
			[CORRUPT_BALROG_AURA] = TRUE,
			[CORRUPT_BALROG_WINGS] = TRUE,
			[CORRUPT_BALROG_STRENGTH] = TRUE
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.xtra_f2 = bor(player.xtra_f2, TR2_IM_ACID)
			player.xtra_f2 = bor(player.xtra_f2, TR2_IM_FIRE)
			player.xtra_f2 = bor(player.xtra_f2, TR2_IM_ELEC)
			player.xtra_f2 = bor(player.xtra_f2, TR2_RES_DARK)
			player.xtra_f2 = bor(player.xtra_f2, TR2_RES_CHAOS)
		end,
		[HOOK_CALC_POWERS] = function()
			player.add_power(PWR_BALROG)
		end,
	},
}


-- The Demon corruptions
CORRUPT_DEMON_SPIRIT = add_corruption
{
	["color"]       = TERM_RED,
	["name"]	= "Demon Spirit",
	["get_text"]    = "Your spirit opens to corrupted thoughts.",
	["lose_text"]   = "Your spirit closes again to the corrupted thoughts.",
	["desc"]	=
	{
			  "  Increases your intelligence by 1",
			  "  But reduce your charisma by 2",
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.modify_stat(A_INT, 1)
			player.modify_stat(A_CHR, -2)
		end,
	},
}

CORRUPT_DEMON_HIDE = add_corruption
{
	["color"]       = TERM_RED,
	["name"]	= "Demon Hide",
	["get_text"]    = "Your skin grows into a thick hide.",
	["lose_text"]   = "Your skin returns to a natural state.",
	["desc"]	=
	{
			  "  Increases your armour class by your level",
			  "  Provides immunity to fire at level 40",
			  "  But reduces speed by your level / 7",
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.to_a = player.to_a + player.lev
			player.dis_to_a = player.dis_to_a + player.lev
			player.pspeed = player.pspeed - (player.lev / 7)
			if player.lev >= 40 then player.xtra_f2 = bor(player.xtra_f2, TR2_IM_FIRE) end
		end,
	},
}

CORRUPT_DEMON_BREATH = add_corruption
{
	["color"]       = TERM_RED,
	["name"]	= "Demon Breath",
	["get_text"]    = "Your breath becomes mephitic.",
	["lose_text"]   = "Your breath is once again normal.",
	["desc"]	=
	{
			  "  Provides fire breath",
			  "  But gives a small chance to spoil potions when you quaff them",
	},
	["hooks"]       =
	{
		[HOOK_CALC_POWERS] = function()
			player.add_power(PWR_BR_FIRE)
		end,
		[HOOK_QUAFF] = function(obj)
			if magik(9) == TRUE then
				msg_print("Your demon breath spoils the potion!")
				return TRUE, FALSE
			else
				return FALSE
			end
		end,
	},
}

CORRUPT_DEMON_REALM = add_corruption
{
	["color"]       = TERM_L_RED,
	["name"]	= "Demon Realm",
	["get_text"]    = "You feel more attuned to the demon realm.",
	["lose_text"]   = "You lose your attunement to the demon realm.",
	["desc"]	=
	{
			  "  Provides access to the demon school skill and the use of demonic equipment",
			  "  You need Demon Spirit, Demon Hide and Demon Breath to activate it"
	},
	["depends"]     =
	{
			[CORRUPT_DEMON_SPIRIT] = TRUE,
			[CORRUPT_DEMON_HIDE] = TRUE,
			[CORRUPT_DEMON_BREATH] = TRUE
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			-- 1500 may seem a lot, but people are rather unlikely to get the corruption very soon
			-- due to the dependencies
			if s_info[SKILL_DAEMON + 1].mod == 0 then s_info[SKILL_DAEMON + 1].mod = 1500 end
			s_info[SKILL_DAEMON + 1].hidden = FALSE;
		end,
	},
}


-- Teleportation corruptions

-- Random teleportation will ask for confirmation 70% of the time
-- But 30% of the time it will teleport, without asking
CORRUPT_RANDOM_TELEPORT = add_corruption
{
	["color"]       = TERM_GREEN,
	["name"]	= "Random teleportation",
	["get_text"]    = "Space seems to fizzle around you.",
	["lose_text"]   = "Space solidify again around you.",
	["desc"]	=
	{
			  "  Randomly teleports you around",
	},
	-- No oppose field, it will be automatically set when we declare the anti-telep corruption to oppose us
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.xtra_f3 = bor(player.xtra_f3, TR3_TELEPORT)
		end,
		[HOOK_PROCESS_WORLD] = function()
			if rand_int(300) == 1 then
				if magik(70) == TRUE then
					if get_check("Teleport?") == TRUE then
						teleport_player(50)
					end
				else
					disturb(0, 0)
					msg_print("Your corruption takes over you, you teleport!")
					teleport_player(50)
				end
			end
		end,
	},
}

-- Anti-teleportation corruption, can be stopped with this power
CORRUPT_ANTI_TELEPORT = add_corruption
{
	["color"]       = TERM_GREEN,
	["name"]	= "Anti-teleportation",
	["get_text"]    = "Space continuum freezes around you.",
	["lose_text"]   = "Space continuum can once more be altered around you.",
	["desc"]	=
	{
			  "  Prevents all teleportations, be it of you or monsters",
	},
	["oppose"]     	=
	{
			[CORRUPT_RANDOM_TELEPORT] = TRUE
	},
	["hooks"]       =
	{
		[HOOK_BIRTH_OBJECTS] = function()
			player.corrupt_anti_teleport_stopped = FALSE
		end,
		[HOOK_CALC_POWERS] = function()
			player.add_power(POWER_COR_SPACE_TIME)
		end,
		[HOOK_CALC_BONUS] = function()
			if player.corrupt_anti_teleport_stopped == FALSE then
				player.resist_continuum = TRUE
			end
		end,
		[HOOK_PROCESS_WORLD] = function()
			if player.corrupt_anti_teleport_stopped == TRUE then
				local amt = player.msp + player.csp
				amt = amt / 100
				if (amt < 1) then amt = 1 end
				increase_mana(-amt)
				if player.csp == 0 then
					player.corrupt_anti_teleport_stopped = FALSE
					msg_print("You stop controlling your corruption.")
					player.update = bor(player.update, PU_BONUS)
				end
			end
		end,
	},
}


-- Troll blood
CORRUPT_TROLL_BLOOD = add_corruption
{
	["color"]       = TERM_GREEN,
	["name"]	= "Troll Blood",
	["get_text"]    = "Your blood thickens, you sense corruption in it.",
	["lose_text"]   = "Your blood returns to a normal state.",
	["desc"]	=
	{
			  "  Troll blood flows in your veins, granting increased regeneration",
			  "  It also enables you to feel the presence of other troll beings",
			  "  But it will make your presence more noticeable and aggravating",
	},
	["can_gain"] =	function()
			-- Ok trolls should not get this one. never.
			if get_race_name() == "Troll" then
				return nil
			else
				return not nil
			end
	end,
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
			player.xtra_f3 = bor(player.xtra_f3, TR3_REGEN, TR3_AGGRAVATE)
			player.xtra_esp = bor(player.xtra_esp, ESP_TROLL)
		end,
	},
}

-- The vampire corruption set
CORRUPT_VAMPIRE_TEETH = add_corruption
{
	["group"]       = "Vampire",
	["removable"]   = FALSE,
	["color"]       = TERM_L_DARK,
	["name"]	= "Vampiric Teeth",
	["get_text"]    = "You grow vampiric teeth!",
	["lose_text"]   = "BUG! this should not happen",
	["desc"]	=
	{
			  "  Your teeth allow you to drain blood to feed yourself",
			  "  However your stomach now only accepts blood.",
	},
	["allow"]       = function()
		if test_race_flags(1, PR1_NO_SUBRACE_CHANGE) == FALSE then return not nil else return nil end
	end,
	["gain"]	= function()
		switch_subrace(SUBRACE_SAVE, TRUE);

		subrace_add_power(subrace(SUBRACE_SAVE), PWR_VAMPIRISM)
		subrace(SUBRACE_SAVE).flags1 = bor(subrace(SUBRACE_SAVE).flags1, PR1_VAMPIRE, PR1_UNDEAD, PR1_NO_SUBRACE_CHANGE)
	end,
	["hooks"]       =
	{
	},
}
CORRUPT_VAMPIRE_STRENGTH = add_corruption
{
	["group"]       = "Vampire",
	["removable"]   = FALSE,
	["color"]       = TERM_L_DARK,
	["name"]	= "Vampiric Strength",
	["get_text"]    = "Your body seems more dead than alive.",
	["lose_text"]   = "BUG! this should not happen",
	["desc"]	=
	{
			  "  Your body seems somewhat dead",
			  "  In this near undead state it has improved strength, constitution and intelligence",
			  "  But reduced dexterity, wisdom and charisma.",
	},
	["depends"]     =
	{
			[CORRUPT_VAMPIRE_TEETH] = TRUE,
	},
	["gain"]	= function()
		-- Apply the bonuses/penalities
		subrace(SUBRACE_SAVE).r_mhp = subrace(SUBRACE_SAVE).r_mhp + 1
		subrace(SUBRACE_SAVE).r_exp = subrace(SUBRACE_SAVE).r_exp + 100

		subrace(SUBRACE_SAVE).r_adj[A_STR + 1] = subrace(SUBRACE_SAVE).r_adj[A_STR + 1] + 3
		subrace(SUBRACE_SAVE).r_adj[A_INT + 1] = subrace(SUBRACE_SAVE).r_adj[A_INT + 1] + 2
		subrace(SUBRACE_SAVE).r_adj[A_WIS + 1] = subrace(SUBRACE_SAVE).r_adj[A_WIS + 1] - 3
		subrace(SUBRACE_SAVE).r_adj[A_DEX + 1] = subrace(SUBRACE_SAVE).r_adj[A_DEX + 1] - 2
		subrace(SUBRACE_SAVE).r_adj[A_CON + 1] = subrace(SUBRACE_SAVE).r_adj[A_CON + 1] + 1
		subrace(SUBRACE_SAVE).r_adj[A_CHR + 1] = subrace(SUBRACE_SAVE).r_adj[A_CHR + 1] - 4

		-- be reborn!
		do_rebirth()
		cmsg_print(TERM_L_DARK, "You feel death slipping inside.")
	end,
	["hooks"]       =
	{
	},
}
CORRUPT_VAMPIRE_VAMPIRE = add_corruption
{
	["group"]       = "Vampire",
	["removable"]   = FALSE,
	["color"]       = TERM_L_DARK,
	["name"]	= "Vampire",
	["get_text"]    = "You die to be reborn in a Vampire form.",
	["lose_text"]   = "BUG! this should not happen",
	["desc"]	=
	{
			  "  You are a Vampire. As such you resist cold, poison, darkness and nether.",
			  "  Your life is sustained, but you cannot stand the light of the sun."
	},
	["depends"]     =
	{
			[CORRUPT_VAMPIRE_STRENGTH] = TRUE,
	},
	["gain"]	= function()
		-- Be a Vampire and be proud of it
		local title = get_subrace_title(SUBRACE_SAVE)
		if title == " " or title == "Vampire" then
			title = "Vampire"
			subrace(SUBRACE_SAVE).place = FALSE
		else
			title = "Vampire "..title
		end
		set_subrace_title(SUBRACE_SAVE, title)

		-- Bonus/and .. not bonus :)
		subrace(SUBRACE_SAVE).flags1 = bor(subrace(SUBRACE_SAVE).flags1, PR1_HURT_LITE)
		subrace(SUBRACE_SAVE).oflags2[2] = bor(subrace(SUBRACE_SAVE).oflags2[2], TR2_RES_POIS, TR2_RES_NETHER, TR2_RES_COLD, TR2_RES_DARK, TR2_HOLD_LIFE)
		subrace(SUBRACE_SAVE).oflags3[2] = bor(subrace(SUBRACE_SAVE).oflags3[2], TR3_LITE1)
	end,
	["hooks"]       =
	{
	},
}


--[[
CORRUPT_ = add_corruption
{
	["color"]       = TERM_GREEN,
	["name"]	= "",
	["get_text"]    = "",
	["lose_text"]   = "",
	["desc"]	=
	{
			  "  ",
	},
	["hooks"]       =
	{
		[HOOK_CALC_BONUS] = function()
		end,
	},
}
]]
tome-235-src/lib/scpt/s_mind.lua0000644000076400017500000000655411012107762014372 0ustar  dgdg-- handle the mind school

CHARM = add_spell
{
	["name"] = 	"Charm",
	["school"] = 	{SCHOOL_MIND},
	["level"] = 	1,
	["mana"] = 	1,
	["mana_max"] = 	20,
	["fail"] = 	10,
	["stick"] =
	{
			["charge"] =    { 7, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		35,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 20, 40 },
			},
	},
	["spell"] = 	function()
			if get_level(CHARM, 50) >= 35 then
				return project_los(GF_CHARM, 10 + get_level(CHARM, 150))
			elseif get_level(CHARM, 50) >= 15 then
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return fire_ball(GF_CHARM, dir, 10 + get_level(CHARM, 150), 3)
			else
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return fire_bolt(GF_CHARM, dir, 10 + get_level(CHARM, 150))
			end
	end,
	["info"] = 	function()
			return "power "..(10 + get_level(CHARM, 150))
	end,
	["desc"] =	{
			"Tries to manipulate the mind of a monster to make it friendly",
			"At level 15 it turns into a ball",
			"At level 35 it affects all monsters in sight"
	}
}

CONFUSE = add_spell
{
	["name"] = 	"Confuse",
	["school"] = 	{SCHOOL_MIND},
	["level"] = 	5,
	["mana"] = 	5,
	["mana_max"] = 	30,
	["fail"] = 	20,
	["stick"] =
	{
			["charge"] =    { 3, 4 },
			[TV_WAND] =
			{
				["rarity"] = 		45,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 20, 40 },
			},
	},
	["spell"] = 	function()
			if get_level(CONFUSE, 50) >= 35 then
				return project_los(GF_OLD_CONF, 10 + get_level(CONFUSE, 150))
			elseif get_level(CONFUSE, 50) >= 15 then
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return fire_ball(GF_OLD_CONF, dir, 10 + get_level(CONFUSE, 150), 3)
			else
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return fire_bolt(GF_OLD_CONF, dir, 10 + get_level(CONFUSE, 150))
			end
	end,
	["info"] = 	function()
			return "power "..(10 + get_level(CONFUSE, 150))
	end,
	["desc"] =	{
			"Tries to manipulate the mind of a monster to confuse it",
			"At level 15 it turns into a ball",
			"At level 35 it affects all monsters in sight"
	}
}

ARMOROFFEAR = add_spell
{
	["name"] = 	"Armor of Fear",
	["school"] = 	SCHOOL_MIND,
	["level"] = 	10,
	["mana"] = 	10,
	["mana_max"] = 	50,
	["fail"] = 	35,
	["inertia"] = 	{ 2, 20 },
	["spell"] = 	function()
			return set_shield(randint(10) + 10 + get_level(ARMOROFFEAR, 100), 10, SHIELD_FEAR, 1 + get_level(ARMOROFFEAR, 7), 5 + get_level(ARMOROFFEAR, 20))
	end,
	["info"] = 	function()
			return "dur "..(10 + get_level(ARMOROFFEAR, 100)).." power "..(1 + get_level(ARMOROFFEAR, 7)).."d"..(5 + get_level(ARMOROFFEAR, 20))
	end,
	["desc"] =	{
			"Creates a shield of pure fear around you. Any monster attempting to hit you",
			"must save or flee",
		}
}

STUN = add_spell
{
	["name"] = 	"Stun",
	["school"] = 	{SCHOOL_MIND},
	["level"] = 	15,
	["mana"] = 	10,
	["mana_max"] = 	90,
	["fail"] = 	45,
	["spell"] = 	function()
			if get_level(STUN, 50) >= 20 then
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return fire_ball(GF_STUN, dir, 10 + get_level(STUN, 150), 3)
			else
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return fire_bolt(GF_STUN, dir, 10 + get_level(STUN, 150))
			end
	end,
	["info"] = 	function()
			return "power "..(10 + get_level(STUN, 150))
	end,
	["desc"] =	{
			"Tries to manipulate the mind of a monster to stun it",
			"At level 20 it turns into a ball",
	}
}
tome-235-src/lib/scpt/powers.lua0000644000076400017500000000376511012107762014441 0ustar  dgdg-- Various 'U' powers

-- Invisibility power, for the mouse mimic shape
POWER_INVISIBILITY = add_power
{
	["name"] =      "invisibility",
	["desc"] =      "You are able melt into the shadows to become invisible.",
	["desc_get"] =  "You suddenly become able to melt into the shadows.",
	["desc_lose"] = "You lose your shadow-melting ability.",
	["level"] =     30,
	["cost"] =      10,
	["stat"] =      A_DEX,
	["fail"] =      20,
	["power"] =     function()
			set_invis(20 + randint(30), 30)
	end,
}

-- Web power, for the spider mimic shape
POWER_WEB = add_power
{
	["name"] =      "web",
	["desc"] =      "You are able throw a thick and very resistant spider web.",
	["desc_get"] =  "You suddenly become able to weave webs.",
	["desc_lose"] = "You lose your web-weaving capability.",
	["level"] =     25,
	["cost"] =      30,
	["stat"] =      A_DEX,
	["fail"] =      20,
	["power"] =     function()
			-- Warning, beware of f_info changes .. I hate to do that ..
			grow_things(16, 1 + (player.lev / 10))
	end,
}

-- Activating/stopping space-continuum
-- When stopped it will induce constant mana loss
player.corrupt_anti_teleport_stopped = FALSE
add_loadsave("player.corrupt_anti_teleport_stopped", FALSE)
POWER_COR_SPACE_TIME = add_power
{
	["name"] =      "control space/time continuum",
	["desc"] =      "You are able to control the space/time continuum.",
	["desc_get"] =  "You become able to control the space/time continuum.",
	["desc_lose"] = "You are no more able to control the space/time continuum.",
	["level"] =     1,
	["cost"] =      10,
	["stat"] =      A_WIS,
	["fail"] =      10,
	["power"] =     function()
		if player.corrupt_anti_teleport_stopped == TRUE then
			player.corrupt_anti_teleport_stopped = FALSE
			msg_print("You stop controlling your corruption.")
			player.update = bor(player.update, PU_BONUS)
		else
			player.corrupt_anti_teleport_stopped = TRUE
			msg_print("You start controlling your corruption, teleportation works once more.")
			player.update = bor(player.update, PU_BONUS)
		end
	end,
}
tome-235-src/lib/scpt/mimic.lua0000644000076400017500000002561311012107762014214 0ustar  dgdg-- Define the various possible mimic shapes

-- Nature shapes
add_mimic_shape
{
	["name"] =      "Mouse",
	["obj_name"] =  "Mouse Fur",
	["desc"] = 	"Mice are small, fast and very stealthy",
	["realm"] =     "nature",
	["level"] =     1,
	["rarity"] =    10,
	["duration"] =  {20, 40},
	["calc"] =      function ()
			-- Mice run!
			player.pspeed = player.pspeed + 5 + (player.mimic_level / 7)

			-- They can crtawl under your armor to hit you ;)
			player.to_h = player.to_h + 10 + (player.mimic_level / 5)
			player.dis_to_h = player.dis_to_h + 10 + (player.mimic_level / 5)

			-- But they are not very powerfull
			player.to_d = player.to_d / 5
			player.dis_to_d = player.dis_to_d / 5

			-- But they are stealthy
			player.skill_stl = player.skill_stl + 10 + (player.mimic_level / 5)

			-- Stat mods
			player.modify_stat(A_STR, -5)
			player.modify_stat(A_DEX, 3)
			player.modify_stat(A_CON, 1)

	end,
	["power"] =     function()
			if player.mimic_level >= 30 then
				player.add_power(POWER_INVISIBILITY)
			end
	end,
}

add_mimic_shape
{
	["name"] =      "Eagle",
	["obj_name"] =  "Feathers Cloak",
	["desc"] = 	"Eagles are master of the air, good hunters with excellent vision.",
	["realm"] =     "nature",
	["level"] =     10,
	["rarity"] =    30,
	["duration"] =  {10, 50},
	["calc"] =      function ()
			player.ffall = TRUE
			player.pspeed = player.pspeed + 2 + (player.mimic_level / 6)

			player.modify_stat(A_STR, -3)
			player.modify_stat(A_DEX, 2 + (player.mimic_level / 15))
			player.modify_stat(A_CON, 4 + (player.mimic_level / 20))
			player.modify_stat(A_INT, -1)
			player.modify_stat(A_WIS, 1)
			player.modify_stat(A_CHR, -1)

			if player.mimic_level >= 20 then player.fly = TRUE end
			if player.mimic_level >= 20 then player.see_inv = TRUE end
			if player.mimic_level >= 25 then player.free_act = TRUE end
			if player.mimic_level >= 30 then player.resist_elec = TRUE end
			if player.mimic_level >= 40 then player.sh_elec = TRUE end

	end,
}

add_mimic_shape
{
	["name"] =      "Wolf",
	["obj_name"] =  "Wolf Pelt",
	["desc"] = 	"Wolves are masters of movement, strong and have excellent eyesight.",
	["realm"] =     "nature",
	["level"] =     20,
	["rarity"] =    40,
	["duration"] =  {10, 50},
	["calc"] =      function ()
			player.modify_stat(A_STR, 2 + (player.mimic_level / 20))
			player.modify_stat(A_DEX, 3 + (player.mimic_level / 20))
			player.modify_stat(A_INT, -3)
			player.modify_stat(A_CHR, -2)

			player.pspeed = player.pspeed + 10 + (player.mimic_level / 5)

			player.free_act = TRUE
			player.resist_fear = TRUE

			if player.mimic_level >= 10 then player.resist_cold = TRUE end
			if player.mimic_level >= 15 then player.see_inv = TRUE end
			if player.mimic_level >= 30 then player.resist_dark = TRUE end
			if player.mimic_level >= 35 then player.resist_conf = TRUE end

	end,
}

add_mimic_shape
{
	["name"] =      "Spider",
	["obj_name"] =  "Spider Web",
	["desc"] = 	"Spiders are clever and become good climbers.",
	["realm"] =     "nature",
	["level"] =     25,
	["rarity"] =    50,
	["duration"] =  {10, 50},
	["calc"] =      function ()
			player.modify_stat(A_STR, -4)
			player.modify_stat(A_DEX, 1 + (player.mimic_level / 8))
			player.modify_stat(A_INT, 1 + (player.mimic_level / 5))
			player.modify_stat(A_WIS, 1 + (player.mimic_level / 5))
			player.modify_stat(A_CON, -5)
			player.modify_stat(A_CHR, -10)

			player.pspeed = player.pspeed + 5

			player.resist_pois = TRUE
			player.resist_fear = TRUE
			player.resist_dark = TRUE

			if player.mimic_level >= 40 then player.climb = TRUE end

	end,
	["power"] =     function()
			if player.mimic_level >= 25 then
				player.add_power(POWER_WEB)
			end
	end,
}

add_mimic_shape
{
	["name"] =      "Elder Ent",
	["obj_name"] =  "Entish Bark",
	["desc"] = 	"Ents are powerful tree-like beings dating from the dawn of time.",
	["realm"] =     "nature",
	["level"] =     40,
	["rarity"] =    60,
	["duration"] =  {10, 30},
	["limit"] =     TRUE,
	["calc"] =      function ()
			player.pspeed = player.pspeed - 5 - (player.mimic_level / 10)

			player.to_a = player.to_a + 10 + player.mimic_level
			player.dis_to_a = player.dis_to_a + 10 + player.mimic_level

			player.resist_pois = TRUE
			player.resist_cold = TRUE
			player.free_act = TRUE
			player.regenerate = TRUE
			player.see_inv = TRUE
			player.sensible_fire = TRUE

			player.modify_stat(A_STR, player.mimic_level / 5)
			player.modify_stat(A_INT, - (player.mimic_level / 7))
			player.modify_stat(A_WIS, - (player.mimic_level / 7))
			player.modify_stat(A_DEX, -4)
			player.modify_stat(A_CON, player.mimic_level / 5)
			player.modify_stat(A_CHR, -7)

	end,
	["power"] =     function ()
			player.add_power(PWR_GROW_TREE)
	end,
}

add_mimic_shape
{
	["name"] =      "Vapour",
	["obj_name"] =  "Cloak of Mist",
	["desc"] = 	"A sentient cloud, darting around",
	["realm"] =     "nature",
	["level"] =     15,
	["rarity"] =    10,
	["duration"] =  {10, 40},
	["calc"] =      function ()

			player.pspeed = player.pspeed + 5

			--Try to hit a cloud!
			player.to_a = player.to_a + 40 + player.mimic_level
			player.dis_to_a = player.dis_to_a + 40 + player.mimic_level

			--Try to hit WITH a cloud!
			player.to_h = player.to_h - 40
			player.dis_to_h = player.dis_to_h -40

			-- But they are stealthy
			player.skill_stl = player.skill_stl + 10 + (player.mimic_level / 5)
			player.resist_pois = TRUE
			player.immune_cold = TRUE
			player.resist_shard = TRUE
			player.free_act = TRUE
			player.regenerate = TRUE
			player.see_inv = TRUE
			player.sensible_fire = TRUE
			player.levitate = TRUE

			-- Stat mods
			player.modify_stat(A_STR, -4)
			player.modify_stat(A_DEX, 5)
			player.modify_stat(A_CON, -4)
			player.modify_stat(A_CHR, -10)
	end,
}

add_mimic_shape
{
	["name"] =      "Serpent",
	["obj_name"] =  "Snakeskin Cloak",
	["desc"] = 	"Serpents are fast, lethal predators.",
	["realm"] =     "nature",
	["level"] =     30,
	["rarity"] =    25,
	["duration"] =  {15, 20},
	["calc"] =      function ()
			player.pspeed = player.pspeed + 10 + (player.mimic_level / 6)
			player.to_a = player.to_a + 3 + (player.mimic_level / 8)
			player.dis_to_a = player.dis_to_a + 3 + (player.mimic_level / 8)

			player.modify_stat(A_STR, player.mimic_level / 8)
			player.modify_stat(A_INT, -6)
			player.modify_stat(A_WIS, -6)
			player.modify_stat(A_DEX, -4)
			player.modify_stat(A_CON, player.mimic_level / 7)
			player.modify_stat(A_CHR, -6)

			player.resist_pois = TRUE
			if player.mimic_level >= 25 then player.free_act = TRUE end
	end,
}

add_mimic_shape
{
	["name"] =      "Mumak",
	["obj_name"] =  "Mumak Hide",
	["desc"] = 	"A giant, elaphantine form.",
	["realm"] =     "nature",
	["level"] =     40,
	["rarity"] =    40,
	["duration"] =  {15, 20},
	["calc"] =      function ()
			player.pspeed = player.pspeed - 5 - (player.mimic_level / 10)
			player.to_a = player.to_a + 10 + (player.mimic_level / 6)
			player.dis_to_a = player.dis_to_a + 10 + (player.mimic_level / 6)
			player.to_d = player.to_d + 5 + ((player.mimic_level * 2) / 3)
			player.dis_to_d = player.dis_to_d + 5 + ((player.mimic_level * 2) / 3)

			player.modify_stat(A_STR, player.mimic_level / 4)
			player.modify_stat(A_INT, -8)
			player.modify_stat(A_WIS, -4)
			player.modify_stat(A_DEX, -5)
			player.modify_stat(A_CON, player.mimic_level / 3)
			player.modify_stat(A_CHR, -10)

			if player.mimic_level >= 10 then player.resist_fear = TRUE end
			if player.mimic_level >= 25 then player.resist_conf = TRUE end
			if player.mimic_level >= 30 then player.free_act = TRUE end
			if player.mimic_level >= 35 then player.resist_nexus = TRUE end
	end,
}

--------- Extra shapes -----------

-- For Beornings
add_mimic_shape
{
	["name"] =      "Bear",
	["desc"] = 	"A fierce, terrible bear.",
	["realm"] =     nil,
	["level"] =     1,
	["rarity"] =    101,
	["duration"] =  {50, 200},
	["limit"] =     TRUE,
	["calc"] =      function ()
			player.pspeed = player.pspeed - 5 + (player.mimic_level / 5)

			player.to_a = player.to_a + 5 + ((player.mimic_level * 2) / 3)
			player.dis_to_a = player.dis_to_a + 5 + ((player.mimic_level * 2) / 3)

			player.modify_stat(A_STR, player.mimic_level / 11)
			player.modify_stat(A_INT, player.mimic_level / 11)
			player.modify_stat(A_WIS, player.mimic_level / 11)
			player.modify_stat(A_DEX, -1)
			player.modify_stat(A_CON, player.mimic_level / 11)
			player.modify_stat(A_CHR, -10)

			if player.mimic_level >= 10 then player.free_act = TRUE end
			if player.mimic_level >= 20 then player.regenerate = TRUE end
			if player.mimic_level >= 30 then player.resist_conf = TRUE end
			if player.mimic_level >= 35 then player.resist_nexus = TRUE end

			-- activate the skill
			skill(SKILL_BEAR).hidden = FALSE
	end,
}

-- For balrog corruptions
add_mimic_shape
{
	["name"] =      "Balrog",
	["desc"] = 	"A corrupted maia.",
	["realm"] =     nil,
	["level"] =     1,
	["rarity"] =    101,
	["duration"] =  {30, 70},
	["limit"] =     TRUE,
	["calc"] =      function ()
			player.modify_stat(A_STR, 5 + player.mimic_level / 5)
			player.modify_stat(A_INT, player.mimic_level / 10)
			player.modify_stat(A_WIS, - ( 5 + player.mimic_level / 10))
			player.modify_stat(A_DEX, player.mimic_level / 10)
			player.modify_stat(A_CON, 5 + player.mimic_level / 5)
			player.modify_stat(A_CHR, - ( 5 + player.mimic_level / 10))

			player.immune_fire = TRUE
			player.immune_elec = TRUE
			player.immune_acid = TRUE
			player.resist_pois = TRUE
			player.resist_dark = TRUE
			player.resist_chaos = TRUE
			player.hold_life = TRUE
			player.ffall =  TRUE
			player.regenerate = TRUE
			player.sh_fire = TRUE
			return 1
	end,
}

-- For avatar spell
add_mimic_shape
{
	["name"] =      "Maia",
	["desc"] = 	"A near god-like being.",
	["realm"] =     nil,
	["level"] =     1,
	["rarity"] =    101,
	["duration"] =  {30, 70},
	["limit"] =     TRUE,
	["calc"] =      function ()
			player.modify_stat(A_STR, 5 + player.mimic_level / 5)
			player.modify_stat(A_INT, 5 + player.mimic_level / 5)
			player.modify_stat(A_WIS, 5 + player.mimic_level / 5)
			player.modify_stat(A_DEX, 5 + player.mimic_level / 5)
			player.modify_stat(A_CON, 5 + player.mimic_level / 5)
			player.modify_stat(A_CHR, 5 + player.mimic_level / 5)

			player.immune_fire = TRUE
			player.immune_elec = TRUE
			player.immune_acid = TRUE
			player.immune_cold = TRUE
			player.resist_pois = TRUE
			player.resist_lite = TRUE
			player.resist_dark = TRUE
			player.resist_chaos = TRUE
			player.hold_life = TRUE
			player.ffall = TRUE
			player.regenerate = TRUE
			return 2
	end,
}

-- For Geomancy
add_mimic_shape
{
	["name"] =      "Fire Elem.",
	["desc"] = 	"A towering column of flames",
	["realm"] =     nil,
	["level"] =     1,
	["rarity"] =    101,
	["duration"] =  {10, 10},
	["limit"] =     TRUE,
	["calc"] =      function ()
			player.modify_stat(A_STR, 5 + (player.mimic_level / 5))
			player.modify_stat(A_DEX, 5 + (player.mimic_level / 5))
			player.modify_stat(A_WIS, -5 - (player.mimic_level / 5))

			player.immune_fire = TRUE
			-- was immune to poison in the 3.0.0 version
			player.resist_pois = TRUE
			player.sh_fire = TRUE
			player.lite = TRUE
			return 0
	end,
}
tome-235-src/lib/scpt/s_tulkas.lua0000644000076400017500000000352111012107762014735 0ustar  dgdg-- Handle Tulkas magic school

TULKAS_AIM = add_spell
{
	["name"] =      "Divine Aim",
	["school"] =    {SCHOOL_TULKAS},
	["level"] =     1,
	["mana"] =      30,
	["mana_max"] =  500,
	["fail"] = 	20,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			local dur = get_level(TULKAS_AIM, 50) + randint(10)
			local obvious

			obvious = set_strike(dur)
			if get_level(TULKAS_AIM) >= 20 then
				obvious = is_obvious(set_tim_deadly(dur), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
			return "dur "..(get_level(TULKAS_AIM, 50)).."+d10"
	end,
	["desc"] =	{
			"It makes you more accurate in combat",
			"At level 20 all your blows are critical hits",
	}
}

TULKAS_WAVE = add_spell
{
	["name"] =      "Wave of Power",
	["school"] =    {SCHOOL_TULKAS},
	["level"] =     20,
	["mana"] =      200,
	["mana_max"] =  200,
	["fail"] = 	75,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			return fire_bolt(GF_ATTACK, dir, get_level(TULKAS_WAVE, player.num_blow))
	end,
	["info"] = 	function()
			return "blows "..(get_level(TULKAS_WAVE, player.num_blow))
	end,
	["desc"] =	{
			"It allows you to project a number of melee blows across a distance",
	}
}

TULKAS_SPIN = add_spell
{
	["name"] =      "Whirlwind",
	["school"] =    {SCHOOL_TULKAS},
	["level"] =     10,
	["mana"] =      100,
	["mana_max"] =  100,
	["fail"] = 	45,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			return fire_ball(GF_ATTACK, 0, 1, 1)
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"It allows you to spin around and hit all monsters nearby",
	}
}
tome-235-src/lib/scpt/s_music.lua0000644000076400017500000002351211012107762014554 0ustar  dgdg-- handle the music school
-- *ALL* lasting spell must return the mana cost in the lasting function

MUSIC_STOP = add_spell
{
	["name"] =      "Stop singing(I)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     1,
	["mana"] =      0,
	["mana_max"] =  0,
	["fail"] =      -400,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      1,
	["blind"] =     FALSE,
	["spell"] =     function()
			player.start_lasting_spell(0)
			return TRUE
	end,
	["info"] =      function()
			return ""
	end,
	["desc"] =      {
			"Stops the current song, if any."
	}
}

--- Drums
MUSIC_HOLD = add_spell
{
	["name"] =      "Holding Pattern(I)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     1,
	["mana"] =      1,
	["mana_max"] =  10,
	["fail"] =      20,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      1,
	["blind"] =     FALSE,
	["lasting"] =   function()
			project_los(GF_OLD_SLOW, 10 + get_level(MUSIC_HOLD, 100))
			return get_mana(MUSIC_HOLD)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_HOLD)
			return TRUE
	end,
	["info"] =      function()
			return "power "..(10 + get_level(MUSIC_HOLD, 100))
	end,
	["desc"] =      {
			"Slows down all monsters listening the song.",
			"Consumes the amount of mana each turn.",
	}
}

MUSIC_CONF = add_spell
{
	["name"] =      "Illusion Pattern(II)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     5,
	["mana"] =      2,
	["mana_max"] =  15,
	["fail"] =      30,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      2,
	["blind"] =     FALSE,
	["lasting"] =   function()
			project_los(GF_OLD_CONF, 10 + get_level(MUSIC_CONF, 100))
			return get_mana(MUSIC_CONF)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_CONF)
			return TRUE
	end,
	["info"] =      function()
			return "power "..(10 + get_level(MUSIC_CONF, 100))
	end,
	["desc"] =      {
			"Tries to confuse all monsters listening the song.",
			"Consumes the amount of mana each turn.",
	}
}

MUSIC_STUN = add_spell
{
	["name"] =      "Stun Pattern(IV)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     10,
	["mana"] =      3,
	["mana_max"] =  25,
	["fail"] =      45,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      4,
	["blind"] =     FALSE,
	["lasting"] =   function()
			project_los(GF_STUN, 10 + get_level(MUSIC_STUN, 90))
			return get_mana(MUSIC_STUN)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_STUN)
			return TRUE
	end,
	["info"] =      function()
			return "power "..(10 + get_level(MUSIC_STUN, 90))
	end,
	["desc"] =      {
			"Stuns all monsters listening the song.",
			"Consumes the amount of mana each turn.",
	}
}

--- Harps
MUSIC_LITE = add_spell
{
	["name"] =      "Song of the Sun(I)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     1,
	["mana"] =      1,
	["mana_max"] =  1,
	["fail"] =      20,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["blind"] =     FALSE,
	["pval"] =      1,
	["lasting"] =   function()
			set_lite(5)
			return 1
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_LITE)
			return TRUE
	end,
	["info"] =      function()
			return ""
	end,
	["desc"] =      {
			"Provides light as long as you sing.",
			"Consumes the amount of mana each turn.",
	}
}

MUSIC_HEAL = add_spell
{
	["name"] =      "Flow of Life(II)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     7,
	["mana"] =      5,
	["mana_max"] =  30,
	["fail"] =      35,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      2,
	["lasting"] =   function()
			hp_player(7 + get_level(MUSIC_HEAL, 100))
			return get_mana(MUSIC_HEAL)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_HEAL)
			return TRUE
	end,
	["info"] =      function()
			return "heal "..(7 + get_level(MUSIC_HEAL, 100)).."/turn"
	end,
	["desc"] =      {
			"Heals you as long as you sing.",
			"Consumes the amount of mana each turn.",
	}
}

MUSIC_HERO = add_spell
{
	["name"] =      "Heroic Ballad(II)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     10,
	["mana"] =      4,
	["mana_max"] =  14,
	["fail"] =      45,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      2,
	["lasting"] =   function()
			set_hero(5)
			if get_level(MUSIC_HERO) >= 10 then
				set_shero(5)
			end
			if get_level(MUSIC_HERO) >= 20 then
				set_strike(5)
			end
			if get_level(MUSIC_HERO) >= 25 then
				set_oppose_cc(5)
			end
			return get_mana(MUSIC_HERO)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_HERO)
			return TRUE
	end,
	["info"] =      function()
			return ""
	end,
	["desc"] =      {
			"Increases melee accuracy",
			"At level 10 it increases it even more and reduces armour a bit",
			"At level 20 it increases it again",
			"At level 25 it grants protection against chaos and confusion",
			"Consumes the amount of mana each turn.",
	}
}

MUSIC_TIME = add_spell
{
	["name"] =      "Hobbit Melodies(III)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     20,
	["mana"] =      10,
	["mana_max"] =  30,
	["fail"] =      70,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      3,
	["lasting"] =   function()
			set_shield(5, 10 + get_level(MUSIC_TIME, 50), 0, 0, 0)
			if get_level(MUSIC_TIME) >= 15 then
				set_fast(5, 7 + get_level(MUSIC_TIME, 10))
			end
			return get_mana(MUSIC_TIME)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_TIME)
			return TRUE
	end,
	["info"] =      function()
			if get_level(MUSIC_TIME) >= 15 then
				return "AC "..(10 + get_level(MUSIC_TIME, 50)).." speed "..(7 + get_level(MUSIC_TIME, 10))
			else
				return "AC "..(10 + get_level(MUSIC_TIME, 50))
			end
	end,
	["desc"] =      {
			"Greatly increases your reflexes allowing you to block more melee blows.",
			"At level 15 it also makes you faster.",
			"Consumes the amount of mana each turn.",
	}
}

MUSIC_MIND = add_spell
{
	["name"] =      "Clairaudience(IV)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     25,
	["mana"] =      15,
	["mana_max"] =  30,
	["fail"] =      75,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      4,
	["lasting"] =   function()
			set_tim_esp(5)
			if get_level(MUSIC_MIND) >= 10 then
				fire_ball(GF_IDENTIFY, 0, 1, 1 + get_level(MUSIC_MIND, 3, 0))
			end
			return get_mana(MUSIC_MIND)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_MIND)
			return TRUE
	end,
	["info"] =      function()
			if get_level(MUSIC_MIND) >= 10 then
				return "rad "..(1 + get_level(MUSIC_MIND, 3, 0))
			else
				return ""
			end
	end,
	["desc"] =      {
			"Allows you to sense monster minds as long as you sing.",
			"At level 10 it identifies all objects in a radius on the floor,",
			"as well as probing monsters in that radius.",
			"Consumes the amount of mana each turn.",
	}
}

--- Horns

MUSIC_BLOW = add_spell
{
	["name"] =      "Blow(I)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     4,
	["mana"] =      3,
	["mana_max"] =  30,
	["fail"] =      20,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      1,
	["spell"] =     function()
			fire_ball(GF_SOUND,
				  0,
				  damroll(2 + get_level(MUSIC_BLOW, 10, 0), 4 + get_level(MUSIC_BLOW, 40, 0)),
				  1 + get_level(MUSIC_BLOW, 12, 0)
				 )
			return TRUE
	end,
	["info"] =      function()
			return "dam "..(2 + get_level(MUSIC_BLOW, 10, 0)).."d"..(4 + get_level(MUSIC_BLOW, 40, 0)).." rad "..(1 + get_level(MUSIC_BLOW, 12, 0))
	end,
	["desc"] =      {
			"Produces a powerful, blowing, sound all around you.",
	}
}

MUSIC_WIND = add_spell
{
	["name"] =      "Gush of Wind(II)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     14,
	["mana"] =      15,
	["mana_max"] =  45,
	["fail"] =      30,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      2,
	["spell"] =     function()
			fire_ball(GF_AWAY_ALL,
				  0,
				  10 + get_level(MUSIC_BLOW, 40, 0),
				  1 + get_level(MUSIC_BLOW, 12, 0)
				 )
			return TRUE
	end,
	["info"] =      function()
			return "dist "..(10 + get_level(MUSIC_BLOW, 40, 0)).." rad "..(1 + get_level(MUSIC_BLOW, 12, 0))
	end,
	["desc"] =      {
			"Produces a outgoing gush of wind that sends monsters away.",
	}
}

MUSIC_YLMIR = add_spell
{
	["name"] =      "Horns of Ylmir(III)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     20,
	["mana"] =      25,
	["mana_max"] =  30,
	["fail"] =      20,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      3,
	["spell"] =     function()
			earthquake(player.py, player.px, 2 + get_level(SHAKE, 10))
			return TRUE
	end,
	["info"] =      function()
			return "rad "..(2 + get_level(SHAKE, 10))
	end,
	["desc"] =      {
			"Produces an earth shaking sound.",
	}
}

MUSIC_AMBARKANTA = add_spell
{
	["name"] =      "Ambarkanta(IV)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     25,
	["mana"] =      70,
	["mana_max"] =  70,
	["fail"] =      60,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      4,
	["spell"] =     function()
			alter_reality()
			return TRUE
	end,
	["info"] =      function()
			return ""
	end,
	["desc"] =      {
			"Produces a reality shaking sound that transports you to a nearly",
			"identical reality.",
	}
}


--[[
MUSIC_ = add_spell
{
	["name"] =      "(I)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     1,
	["mana"] =      0,
	["mana_max"] =  0,
	["fail"] =      20,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      1,
	["lasting"] =   function()
			return get_mana(MUSIC_)
	end,
	["spell"] =     function()
			player.start_lasting_spell(MUSIC_)
			return TRUE
	end,
	["info"] =      function()
			return ""
	end,
	["desc"] =      {
			"",
			"Consumes the amount of mana each turn.",
	}
}

or

MUSIC_ = add_spell
{
	["name"] =      "(I)",
	["school"] =    {SCHOOL_MUSIC},
	["level"] =     1,
	["mana"] =      0,
	["mana_max"] =  0,
	["fail"] =      20,
	["stat"] =      A_CHR,
	["random"] =    SKILL_MUSIC,
	["pval"] =      1,
	["spell"] =     function()

			return TRUE
	end,
	["info"] =      function()
			return ""
	end,
	["desc"] =      {
			"",
	}
}
]]
tome-235-src/lib/scpt/library.lua0000644000076400017500000003367211012107762014566 0ustar  dgdg-- 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,
}
tome-235-src/lib/scpt/s_convey.lua0000644000076400017500000001174511012107762014744 0ustar  dgdg-- handle the conveyance school

BLINK = add_spell
{
	["name"] = 	"Phase Door",
	["school"] = 	{SCHOOL_CONVEYANCE},
	["level"] = 	1,
	["mana"] = 	1,
	["mana_max"] =  3,
	["fail"] = 	10,
	["inertia"] = 	{ 1, 5 },
	["spell"] = 	function()
			if get_level(BLINK, 50) >= 30 then
				local oy, ox = player.py, player.px

				teleport_player(10 + get_level(BLINK, 8))
				create_between_gate(0, oy, ox)
				return TRUE
			else
				teleport_player(10 + get_level(BLINK, 8))
				return TRUE
			end
	end,
	["info"] = 	function()
	       		return "distance "..(10 + get_level(BLINK, 8))
	end,
	["desc"] =	{
			"Teleports you on a small scale range",
			"At level 30 it creates void jumpgates",
	}
}

DISARM = add_spell
{
	["name"] = 	"Disarm",
	["school"] = 	{SCHOOL_CONVEYANCE},
	["level"] = 	3,
	["mana"] = 	2,
	["mana_max"] = 	4,
	["fail"] = 	15,
	["stick"] =
	{
			["charge"] =    { 10, 15 },
			[TV_STAFF] =
			{
				["rarity"] = 		4,
				["base_level"] =	{ 1, 10 },
				["max_level"] =		{ 10, 50 },
			},
	},
	["spell"] = 	function()
			local obvious
			obvious = destroy_doors_touch()
			if get_level(DISARM, 50) >= 10 then obvious = is_obvious(destroy_traps_touch(), obvious) end
			return obvious
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Destroys doors and traps",
			"At level 10 it destroys doors and traps, then reveals and unlocks any secret",
			"doors"
	}
}

TELEPORT = add_spell
{
	["name"] = 	"Teleportation",
	["school"] = 	{SCHOOL_CONVEYANCE},
	["level"] = 	10,
	["mana"] = 	8,
	["mana_max"] = 	14,
	["fail"] = 	30,
	["stick"] =
	{
			["charge"] =    { 7, 7 },
			[TV_STAFF] =
			{
				["rarity"] = 		50,
				["base_level"] =	{ 1, 20 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["inertia"] = 	{ 1, 10 },
	["spell"] = 	function()
			player.energy = player.energy - (25 - get_level(TELEPORT, 50))
			teleport_player(100 + get_level(TELEPORT, 100))
			return TRUE
	end,
	["info"] = 	function()
			return "distance "..(100 + get_level(TELEPORT, 100))
	end,
	["desc"] =	{
			"Teleports you around the level. The casting time decreases with level",
	}
}

TELEAWAY = add_spell
{
	["name"] = 	"Teleport Away",
	["school"] = 	{SCHOOL_CONVEYANCE},
	["level"] = 	23,
	["mana"] = 	15,
	["mana_max"] = 	40,
	["fail"] = 	60,
	["stick"] =
	{
			["charge"] =    { 3, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		75,
				["base_level"] =	{ 1, 20 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["spell"] = 	function()
	       		local ret, dir

			if get_level(TELEAWAY, 50) >= 20 then
				return project_los(GF_AWAY_ALL, 100)
			elseif get_level(TELEAWAY, 50) >= 10 then
				ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return fire_ball(GF_AWAY_ALL, dir, 100, 3 + get_level(TELEAWAY, 4))
			else
				ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return teleport_monster(dir)
			end
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Teleports a line of monsters away",
			"At level 10 it turns into a ball",
			"At level 20 it teleports all monsters in sight"
	}
}

RECALL = add_spell
{
	["name"] = 	"Recall",
	["school"] = 	{SCHOOL_CONVEYANCE},
	["level"] = 	30,
	["mana"] = 	25,
	["mana_max"] = 	25,
	["fail"] =      60,
	["spell"] = 	function()
			local ret, x, y, c_ptr
			ret, x, y = tgt_pt()
			if ret == FALSE then return end
			c_ptr = cave(y, x)
			if (y == player.py) and (x == player.px) then
				local d = 21 - get_level(RECALL, 15)
				if d < 0 then
					d = 0
				end
				local f = 15 - get_level(RECALL, 10)
				if f < 1 then
					f = 1
				end
				recall_player(d, f)
				return TRUE
			elseif c_ptr.m_idx > 0 then
				swap_position(y, x)
				return TRUE
			elseif c_ptr.o_idx > 0 then
				set_target(y, x)
				if get_level(RECALL, 50) >= 15 then
					fetch(5, 10 + get_level(RECALL, 150), FALSE)
				else
					fetch(5, 10 + get_level(RECALL, 150), TRUE)
				end
				return TRUE
			end
	end,
	["info"] = 	function()
			local d = 21 - get_level(RECALL, 15)
			if d < 0 then
				d = 0
			end
			local f = 15 - get_level(RECALL, 10)
			if f < 1 then
				f = 1
			end
			return "dur "..f.."+d"..d.." weight "..(1 + get_level(RECALL, 15)).."lb"
	end,
	["desc"] =	{
			"Cast on yourself it will recall you to the surface/dungeon.",
			"Cast at a monster you will swap positions with the monster.",
			"Cast at an object it will fetch the object to you."
	}
}

PROBABILITY_TRAVEL = add_spell
{
	["name"] = 	"Probability Travel",
	["school"] = 	{SCHOOL_CONVEYANCE},
	["level"] = 	35,
	["mana"] = 	30,
	["mana_max"] = 	50,
	["fail"] = 	90,
	["stick"] =
	{
			["charge"] =    { 1, 2 },
			[TV_STAFF] =
			{
				["rarity"] = 		97,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 8, 25 },
			},
	},
	["inertia"] = 	{ 6, 40 },
	["spell"] = 	function()
			return set_prob_travel(randint(20) + get_level(PROBABILITY_TRAVEL, 60))
	end,
	["info"] = 	function()
			return "dur "..get_level(PROBABILITY_TRAVEL, 60).."+d20"
	end,
	["desc"] =	{
			"Renders you immaterial, when you hit a wall you travel through it and",
			"instantly appear on the other side of it. You can also float up and down",
			"at will"
	}
}
tome-235-src/lib/scpt/s_divin.lua0000644000076400017500000001241511012107762014545 0ustar  dgdg-- Handles thhe divination school


STARIDENTIFY = add_spell
{
	["name"] = 	"Greater Identify",
	["school"] = 	{SCHOOL_DIVINATION},
	["level"] = 	35,
	["mana"] = 	30,
	["mana_max"] = 	30,
	["fail"] = 	80,
	["spell"] = 	function()
			if get_check("Cast on yourself?") == TRUE then
				self_knowledge()
			else
				identify_fully()
			end
			return TRUE
	end,
	["info"] = 	function()
		       	return ""
	end,
	["desc"] =	{
			"Asks for an object and fully identify it, providing the full list of powers",
			"Cast at yourself it will reveal your powers"
	}
}

IDENTIFY = add_spell
{
	["name"] = 	"Identify",
	["school"] = 	{SCHOOL_DIVINATION},
	["level"] = 	8,
	["mana"] = 	10,
	["mana_max"] = 	50,
	["fail"] = 	40,
	["stick"] =
	{
			["charge"] =    { 7, 10 },
			[TV_STAFF] =
			{
				["rarity"] = 		45,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 15, 40 },
			},
	},
	["spell"] = 	function()
			if get_level(IDENTIFY, 50) >= 27 then
				local obvious
				obvious = identify_pack()
				obvious = is_obvious(fire_ball(GF_IDENTIFY, 0, 1, get_level(IDENTIFY, 3)), obvious)
				if obvious == TRUE then
					player.notice = bor(player.notice, PN_COMBINE, PN_REORDER)
				end
				return obvious
			elseif get_level(IDENTIFY, 50) >= 17 then
				local obvious
				obvious = identify_pack()
				obvious = is_obvious(fire_ball(GF_IDENTIFY, 0, 1, 0), obvious)
				if obvious == TRUE then
					player.notice = bor(player.notice, PN_COMBINE, PN_REORDER)
				end
				return obvious
			else
				if ident_spell() == TRUE then return TRUE else return end
			end
	end,
	["info"] = 	function()
			if get_level(IDENTIFY, 50) >= 27 then
				return "rad "..(get_level(IDENTIFY, 3))
			else
				return ""
			end
	end,
	["desc"] =	{
			"Asks for an object and identifies it",
			"At level 17 it identifies all objects in the inventory",
			"At level 27 it identifies all objects in the inventory and in a",
			"radius on the floor, as well as probing monsters in that radius"
	}
}

VISION = add_spell
{
	["name"] = 	"Vision",
	["school"] = 	{SCHOOL_DIVINATION},
	["level"] = 	15,
	["mana"] = 	7,
	["mana_max"] = 	55,
	["fail"] = 	45,
	["stick"] =
	{
			["charge"] =    { 4, 6 },
			[TV_STAFF] =
			{
				["rarity"] = 		60,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 10, 30 },
			},
	},
	["inertia"] = 	{ 2, 200 },
	["spell"] = 	function()
			if get_level(VISION, 50) >= 25 then
				wiz_lite_extra()
			else
				map_area()
			end
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Detects the layout of the surrounding area",
			"At level 25 it maps and lights the whole level",
	}
}

SENSEHIDDEN = add_spell
{
	["name"] = 	"Sense Hidden",
	["school"] = 	{SCHOOL_DIVINATION},
	["level"] = 	5,
	["mana"] = 	2,
	["mana_max"] = 	10,
	["fail"] = 	25,
	["stick"] =
	{
			["charge"] =    { 1, 15 },
			[TV_STAFF] =
			{
				["rarity"] = 		20,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 10, 50 },
			},
	},
	["inertia"] = 	{ 1, 10 },
	["spell"] = 	function()
			local obvious = nil
			obvious = detect_traps(15 + get_level(SENSEHIDDEN, 40, 0))
			if get_level(SENSEHIDDEN, 50) >= 15 then
				obvious = is_obvious(set_tim_invis(10 + randint(20) + get_level(SENSEHIDDEN, 40)), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
			if get_level(SENSEHIDDEN, 50) >= 15 then
				return "rad "..(15 + get_level(SENSEHIDDEN, 40)).." dur "..(10 + get_level(SENSEHIDDEN, 40)).."+d20"
			else
				return "rad "..(15 + get_level(SENSEHIDDEN, 40))
			end
	end,
	["desc"] =	{
			"Detects the traps in a certain radius around you",
			"At level 15 it allows you to sense invisible for a while"
	}
}

REVEALWAYS = add_spell
{
	["name"] = 	"Reveal Ways",
	["school"] = 	{SCHOOL_DIVINATION},
	["level"] = 	9,
	["mana"] = 	3,
	["mana_max"] = 	15,
	["fail"] = 	20,
	["stick"] =
	{
			["charge"] =    { 6, 6 },
			[TV_STAFF] =
			{
				["rarity"] = 		35,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 25, 50 },
			},
	},
	["inertia"] = 	{ 1, 10 },
	["spell"] = 	function()
			local obvious
			obvious = detect_doors(10 + get_level(REVEALWAYS, 40, 0))
			obvious = is_obvious(detect_stairs(10 + get_level(REVEALWAYS, 40, 0)), obvious)
			return obvious
	end,
	["info"] = 	function()
			return "rad "..(10 + get_level(REVEALWAYS, 40))
	end,
	["desc"] =	{
			"Detects the doors/stairs/ways in a certain radius around you",
	}
}

SENSEMONSTERS = add_spell
{
	["name"] = 	"Sense Monsters",
	["school"] = 	{SCHOOL_DIVINATION},
	["level"] = 	1,
	["mana"] =      1,
	["mana_max"] =  20,
	["fail"] = 	10,
	["stick"] =
	{
			["charge"] =    { 5, 10 },
			[TV_STAFF] =
			{
				["rarity"] = 		37,
				["base_level"] =	{ 1, 10 },
				["max_level"] =		{ 15, 40 },
			},
	},
	["inertia"] = 	{ 1, 10 },
	["spell"] = 	function()
			local obvious
			obvious = detect_monsters_normal(10 + get_level(SENSEMONSTERS, 40, 0))
			if get_level(SENSEMONSTERS, 50) >= 30 then
				obvious = is_obvious(set_tim_esp(10 + randint(10) + get_level(SENSEMONSTERS, 20)), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
			if get_level(SENSEMONSTERS, 50) >= 30 then
				return "rad "..(10 + get_level(SENSEMONSTERS, 40)).." dur "..(10 + get_level(SENSEMONSTERS, 20)).."+d10"
			else
				return "rad "..(10 + get_level(SENSEMONSTERS, 40))
			end
	end,
	["desc"] =	{
			"Detects all monsters near you",
			"At level 30 it allows you to sense monster minds for a while"
	}
}
tome-235-src/lib/scpt/test.lua0000644000076400017500000001764511012107762014103 0ustar  dgdg--
-- This file takes care of providing the Shiny-Test class
-- with .. erm .. powerful spells
--

------------------------------ MAGICTYPE -- M KEY ---------------------------------

zog_magic = add_magic
{
	["fail"] =      function(chance)
			msg_print("So bad, we had "..chance.." chances to succeed.")
			msg_print("Hooo bad luck the spell backfires !.")
			take_hit("stupidity", 5)
	end,
	["stat"] =      A_CON,
	-- Must return a number between 0 and 50 representing a level
	["get_level"] = function()
			return get_skill_scale(SKILL_MAGIC, 25) + get_skill_scale(SKILL_SPIRITUALITY, 25)
	end,
	["spell_list"] =
	{
		{
			["name"] = "Zog1",
			["desc"] = "dessssc zog1",
			["mana"] = 1,
			["level"] = 1,
			["fail"] = 10,
			["spell"] = function()
				local ret, dir
				-- Get a direction
				ret, dir = get_aim_dir();
				if (ret == FALSE) then return end
				fire_ball(GF_MANA, dir, 2000, 10)
			end,
			["info"] = function()
				return " dam 2000"
			end,
		},
		{
			["name"] = "Zog2",
			["desc"] = "dessssc zog2",
			["mana"] = 3,
			["level"] = 3,
			["fail"] = 30,
			["spell"] = function()
				local ret, item, obj, o_name
	
				-- Ask for an item
				ret, item = get_item("What to uber-ize?",
						     "You have nothing you can uber-ize",
						     bor(USE_INVEN, USE_EQUIP),
						     function (obj)
							if (obj.tval == TV_HAFTED) or (obj.tval == TV_SWORD) or (obj.tval == TV_POLEARM) or (obj.tval == TV_AXE) then
								return TRUE
							end
							return FALSE
						     end
				)
	
				if ret == TRUE then
					-- get the item
					obj = get_object(item)
					-- modify it
					obj.dd = 255
					obj.ds = 255
					obj.to_d = 1000
					obj.to_h = 1000

					-- get the name
					o_name = object_desc(obj, FALSE, 0);
					msg_print("Your "..o_name.." is hit by a pure wave of uber-ification!")
				end
			end,
			["info"] = function()
				return " cooool"
			end,
		},
		{
			["name"] = "Zog3",
			["desc"] = "dessssc zog3",
			["mana"] = 4,
			["level"] = 5,
			["fail"] = 50,
			["spell"] = function()
				local list = {[1] = "Novice Warrior", [2] = "Novice Mage"}
				local x, y, num, max
	
				num = rand_range(1, 2)
				max = damroll(1, 2)
				while (max > 0) do
					y, x = find_position(player.py, player.px)
					place_monster_one(y, x, test_monster_name(list[num]), 0, FALSE, MSTATUS_FRIEND)
					max = max - 1
				end
			end,
			["info"] = function()
				return " summons 1d2 monsters"
			end,
		},
	},
}

-- Register a new magic type
MKEY_SHINY_TEST = 1000
add_mkey
{
	["mkey"] =      MKEY_SHINY_TEST,
	["fct"] =       function()
		execute_magic(zog_magic)

		-- use up some energy
		energy_use = energy_use + 100;
	end
}


------------------------------ EXTRA POWERS ---------------------------------


-- Register a new power (the 'U' menu)
POWER_TEST = add_power
{
	["name"] =      "Test power",
	["desc"] =      "You are a shinny test",
	["desc_get"] =  "You become a shinny test",
	["desc_lose"] = "You are no more a shinny test",
	["level"] =     1,
	["cost"] =      5,
	["stat"] =      A_CON,
	["fail"] =      6,
	["power"] =     function()
		msg_print("Zogzog !")
	end,
}


---- tests

function test_write()
	local conn = zsock:new_connection()
	zsock:setup(conn, "192.168.0.200", 2262, ZSOCK_TYPE_TCP, FALSE)
	zsock:open(conn)

	local res, len = zsock:write(conn, "footest", FALSE)
	msg_print("res "..res.." :: len "..len)

	zsock:close(conn)
	zsock:unsetup(conn)
	zsock:free_connection(conn);
end

function test_read()
	local conn = zsock:new_connection()
	zsock:setup(conn, "192.168.0.200", 2262, ZSOCK_TYPE_TCP, FALSE)
	zsock:open(conn)


	zsock:wait(conn, 50)
	local res, str, len = zsock:read(conn, 9, TRUE)
	msg_print("res "..res.." :: len "..len.." '"..str.."'")

	zsock:close(conn)
	zsock:unsetup(conn)
	zsock:free_connection(conn);
end


-- A level generator being tested

CORRIDOR = 1
ROOM = 2

possible_walls = {}

function level_generator_dungeon2_room(feat, y, x, h, w)
	if feat == CORRIDOR then
		-- Add the possible walls
		for i = x, x + w - 1 do
			tinsert(possible_walls, {y, i})
			tinsert(possible_walls, {y + h - 1, i})
		end
		for i = x, x + w - 1 do
			tinsert(possible_walls, {x, i})
			tinsert(possible_walls, {x, i + h - 1})
		end

		for i = x + 1, x + w - 2 do
			for j = y + 1, y + h - 2 do
				place_floor(j, i)
			end
		end
	else
		-- Add the possible walls
		for i = x, x + w - 1 do
			tinsert(possible_walls, {y, i})
			tinsert(possible_walls, {y + h - 1, i})
		end
		for i = x, x + w - 1 do
			tinsert(possible_walls, {x, i})
			tinsert(possible_walls, {x, i + h - 1})
		end

		for i = x, x + w - 1 do
			for j = y, y + h - 1 do
				cave(j, i).feat = 56
			end
		end
		for i = x + 1, x + w - 2 do
			for j = y + 1, y + h - 2 do
				place_floor(j, i)
			end
		end
	end
end

function select_feature(dir)
	if magik(30) == TRUE then
		return ROOM, rand_range(5, 12), rand_range(7, 17)

	-- Corridor selection
	elseif dir == "up" or dir == "down" then
		return CORRIDOR, rand_range(5, 17), 3
	else
		return CORRIDOR, 3, rand_range(3, 15)
	end
end

function put_feature(feat, y, x, h, w)
	level_generator_dungeon2_room(feat, y, x, h, w)
end

function can_feature(y, x, h, w)
	for i = x, x + w - 1 do
		for j = y, y + h - 1 do
			if j <= 0 or i <= 0 or i >= cur_wid - 1 or j >= cur_hgt - 1 then return nil end

			if cave_is(cave(j, i), FF1_WALL) == FALSE then return nil end
		end
	end
	return not nil
end

function is_near_wall(y, x)
	if y <= 0 or x <= 0 or x >= cur_wid - 1 or y >= cur_hgt - 1 then return nil end

	if cave_is(cave(y, x), FF1_WALL) == FALSE then return nil end
	if cave_is(cave(y - 1, x), FF1_FLOOR) == TRUE then return "down" end
	if cave_is(cave(y + 1, x), FF1_FLOOR) == TRUE then return "up" end
	if cave_is(cave(y, x - 1), FF1_FLOOR) == TRUE then return "right" end
	if cave_is(cave(y, x + 1), FF1_FLOOR) == TRUE then return "left" end
	return nil
end

function find_spot()
--[[	local y, x = 1, 1

	while not is_near_wall(y, x) do
		y, x = rand_range(1, cur_hgt - 2), rand_range(1, cur_wid - 2)
	end]]
	local i = rand_range(1, getn(possible_walls))
	local y, x = possible_walls[i][1], possible_walls[i][2]

	while not is_near_wall(y, x) do
		i = rand_range(1, getn(possible_walls))
		y, x = possible_walls[i][1], possible_walls[i][2]
	end

	tremove(possible_walls, i)
	return is_near_wall(y, x), y, x
end

function adjust_dir(dir, y, x, h, w)
	if dir == "up" then
		y = y - (h - 1)
		x = x - (w / 2)
	elseif dir == "down" then
		x = x - (w / 2)
	elseif dir == "left" then
		y = y - (h / 2)
		x = x - (w - 1)
	elseif dir == "up" then
		y = y - (h / 2)
	end
	return y, x
end

level_generator
{
	["name"] = "dungeon2",
	["stairs"] = FALSE,
	["monsters"] = FALSE,
	["objects"] = FALSE,
	["miscs"] = FALSE,
	["gen"] = function()
		for i = 1, cur_wid - 1 do
			for j = 1, cur_hgt - 1 do
				place_filler(j, i)
			end
		end


		-- the first room
		level_generator_dungeon2_room(ROOM, cur_hgt / 2, cur_wid / 2, rand_range(3, 10), rand_range(5, 15))


		-- Place 10 features
		for nb = 1, 0 do
			-- Find a spot near an empty space
			local dir, y, x = find_spot()

			local feat, h, w = select_feature(dir)

			local sy, sx = adjust_dir(dir, y, x, h, w)

			if can_feature(sy, sx, h, w) then
				put_feature(feat, sy, sx, h, w)
				cave(y, x).feat = 32
			end
		end

		player.py = cur_hgt / 2
		player.px = cur_wid / 2
		return TRUE
	end,
}


-- exmaple of display_list
function input_list_example()
	local list = { "a", "b", "c", "d", "e", "f", "h", "g" }
	local sel = 1
	local begin = 1
	local res = nil

	screen_save()

	while not nil do
		display_list(1, 0, 5, 9, "select", list, begin, sel, TERM_L_BLUE)

		local key = inkey()

		if key == ESCAPE then break
		elseif key == strbyte("8") then
			sel = sel - 1
			if sel < 1 then sel = 1 end
			if sel < begin then
				begin = begin - 1
			end
		elseif key == strbyte("2") then
			sel = sel + 1
			if sel > getn(list) then sel = getn(list) end
			if sel >= begin + 4 then
				begin = begin + 1
			end
		elseif key == strbyte("\r") then
		       res = list[sel]
		       break
		end
	end

	screen_load()

	if res then msg_print("Selected: " .. res) end
end
tome-235-src/lib/scpt/s_melkor.lua0000644000076400017500000001024111012107762014720 0ustar  dgdg-- handle the melkor school

-- Not included in the spell code directly because I need to call it from somewhere else too
function do_melkor_curse(who)
	local m_ptr = monster(who)

	if get_level(MELKOR_CURSE) >= 35 then
		local r_ptr = race_info_idx(m_ptr.r_idx, m_ptr.ego)

		m_ptr.maxhp = m_ptr.maxhp - r_ptr.hside;
		if m_ptr.maxhp < 1 then m_ptr.maxhp = 1 end
		if m_ptr.hp > m_ptr.maxhp then m_ptr.hp = m_ptr.maxhp end
		player.redraw = bor(player.redraw, PR_HEALTH)
	end
	if get_level(MELKOR_CURSE) >= 25 then
		m_ptr.speed = m_ptr.speed - get_level(MELKOR_CURSE, 7)
		m_ptr.mspeed = m_ptr.mspeed - get_level(MELKOR_CURSE, 7)

		if m_ptr.speed < 70 then m_ptr.speed = 70 end
		if m_ptr.mspeed < 70 then m_ptr.mspeed = 70 end
	end
	if get_level(MELKOR_CURSE) >= 15 then
		m_ptr.ac = m_ptr.ac - get_level(MELKOR_CURSE, 50)

		if m_ptr.ac < -70 then m_ptr.ac = -70 end
	end

	local i, pow
	i = 1
	pow = get_level(MELKOR_CURSE, 2)
	while (i <= 4) do
		if m_ptr.blow[i].d_dice > 0 then
			if m_ptr.blow[i].d_dice < pow then
				pow = m_ptr.blow[i].d_dice
			end
			if m_ptr.blow[i].d_side < pow then
				pow = m_ptr.blow[i].d_side
			end
			m_ptr.blow[i].d_dice = m_ptr.blow[i].d_dice - pow
		end
		i = i + 1
	end

	local m_name = monster_desc(m_ptr, 0).." looks weaker."
	msg_print(strupper(strsub(m_name, 0, 1))..strsub(m_name, 2))

	-- wake it
	m_ptr.csleep = 0;
end

MELKOR_CURSE = add_spell
{
	["name"] =      "Curse",
	["school"] =    {SCHOOL_MELKOR},
	["level"] =     1,
	["mana"] =      50,
	["mana_max"] =  300,
	["fail"] = 	20,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end

				if target_who == -1 then
					msg_print("You must target a monster.")
				else
					do_melkor_curse(target_who)
				end
				return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"It curses a monster, reducing its melee power",
			"At level 5 it can be auto-casted (with no piety cost) while fighting",
			"At level 15 it also reduces armor",
			"At level 25 it also reduces speed",
			"At level 35 it also reduces max life (but it is never fatal)",
	}
}

MELKOR_CORPSE_EXPLOSION = add_spell
{
	["name"] =      "Corpse Explosion",
	["school"] =    {SCHOOL_MELKOR},
	["level"] =     10,
	["mana"] =      100,
	["mana_max"] =  500,
	["fail"] = 	45,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			return fire_ball(GF_CORPSE_EXPL, 0, 20 + get_level(MELKOR_CORPSE_EXPLOSION, 70), 2 + get_level(MELKOR_CORPSE_EXPLOSION, 5))
	end,
	["info"] = 	function()
			return "dam "..(20 + get_level(MELKOR_CORPSE_EXPLOSION, 70)).."%"
	end,
	["desc"] =	{
			"It makes corpses in an area around you explode for a percent of their",
			"hit points as damage",
	}
}

MELKOR_MIND_STEAL = add_spell
{
	["name"] =      "Mind Steal",
	["school"] =    {SCHOOL_MELKOR},
	["level"] =     20,
	["mana"] =      1000,
	["mana_max"] =  3000,
	["fail"] = 	90,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
				local ret, dir = get_aim_dir()
				if ret == FALSE then return end

				if target_who == -1 then
					msg_print("You must target a monster.")
				else
					local chance, m_ptr, r_ptr

					m_ptr = monster(target_who)
					r_ptr = race_info_idx(m_ptr.r_idx, m_ptr.ego)
					chance = get_level(MELKOR_MIND_STEAL)
					if (randint(m_ptr.level) < chance) and (band(r_ptr.flags1, RF1_UNIQUE) == 0) then
						player.control = target_who
						m_ptr.mflag = bor(m_ptr.mflag, MFLAG_CONTROL)

						local m_name = monster_desc(m_ptr, 0).." falls under your control."
						msg_print(strupper(strsub(m_name, 0, 1))..strsub(m_name, 2))
					else
						local m_name = monster_desc(m_ptr, 0).." resists."
						msg_print(strupper(strsub(m_name, 0, 1))..strsub(m_name, 2))
					end
					return TRUE
				end
	end,
	["info"] = 	function()
			return "chance 1d(mlvl)<"..(get_level(MELKOR_MIND_STEAL))
	end,
	["desc"] =	{
			"It allows your spirit to temporarily leave your own body, which will",
			"be vulnerable, to control one of your enemies body."
	}
}
tome-235-src/lib/scpt/s_udun.lua0000644000076400017500000000745011012107762014412 0ustar  dgdg-- handle the udun school

DRAIN = add_spell
{
	["name"] = 	"Drain",
	["school"] = 	{SCHOOL_UDUN, SCHOOL_MANA},
	["level"] = 	1,
	["mana"] = 	0,
	["mana_max"] = 	0,
	["fail"] = 	20,
	["spell"] = 	function()
			local ret, item, obj, o_name, add

			-- Ask for an item
			ret, item = get_item("What item to drain?", "You have nothing you can drain", USE_INVEN,
				function (obj)
					if (obj.tval == TV_WAND) or (obj.tval == TV_ROD_MAIN) or (obj.tval == TV_STAFF) then
						return TRUE
					end
					return FALSE
				end
			)

			if ret == TRUE then
				-- get the item
				obj = get_object(item)

				add = 0
				if (obj.tval == TV_STAFF) or (obj.tval == TV_WAND) then
					local kind = get_kind(obj)

					add = kind.level * obj.pval * obj.number

					-- Destroy it!
					inven_item_increase(item, -99)
					inven_item_describe(item)
					inven_item_optimize(item)
				end
				if obj.tval == TV_ROD_MAIN then
					add = obj.timeout
					obj.timeout = 0;

					--Combine / Reorder the pack (later)
					player.notice = bor(player.notice, PN_COMBINE, PN_REORDER)
					player.window = bor(player.window, PW_INVEN, PW_EQUIP, PW_PLAYER)
				end
				increase_mana(add)
			end
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Drains the mana contained in wands, staves and rods to increase yours",
	}
}

GENOCIDE = add_spell
{
	["name"] = 	"Genocide",
	["school"] = 	{SCHOOL_UDUN, SCHOOL_NATURE},
	["level"] = 	25,
	["mana"] = 	50,
	["mana_max"] = 	50,
	["fail"] = 	90,
	["stick"] =
	{
			["charge"] =    { 2, 2 },
			[TV_STAFF] =
			{
				["rarity"] = 		85,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 5, 15 },
			},
	},
	["spell"] = 	function()
			local type

			type = 0
			if get_level(GENOCIDE) >= 10 then type = 1 end
			if type == 0 then
				genocide(TRUE)
				return TRUE
			else
				if get_check("Genocide all monsters near you? ") == TRUE then
					mass_genocide(TRUE)
				else
					genocide(TRUE)
				end
				return TRUE
			end
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Genocides all monsters of a race on the level",
			"At level 10 it can genocide all monsters near you"
	}
}

WRAITHFORM = add_spell
{
	["name"] = 	"Wraithform",
	["school"] = 	{SCHOOL_UDUN, SCHOOL_CONVEYANCE},
	["level"] = 	30,
	["mana"] = 	20,
	["mana_max"] = 	40,
	["fail"] = 	95,
	["inertia"] = 	{ 4, 30 },
	["spell"] = 	function()
		       	return set_shadow(randint(30) + 20 + get_level(WRAITHFORM, 40))
	end,
	["info"] = 	function()
			return "dur "..(20 + get_level(WRAITHFORM, 40)).."+d30"
	end,
	["desc"] =	{
			"Turns you into an immaterial being",
	}
}

FLAMEOFUDUN = add_spell
{
	["name"] = 	"Flame of Udun",
	["school"] = 	{SCHOOL_UDUN, SCHOOL_FIRE},
	["level"] = 	35,
	["mana"] = 	70,
	["mana_max"] = 	100,
	["fail"] = 	95,
	["inertia"] = 	{ 7, 15 },
	["spell"] = 	function()
			return set_mimic(randint(15) + 5 + get_level(FLAMEOFUDUN, 30), resolve_mimic_name("Balrog"), get_level(FLAMEOFUDUN))
	end,
	["info"] = 	function()
			return "dur "..(5 + get_level(FLAMEOFUDUN, 30)).."+d15"
	end,
	["desc"] =	{
			"Turns you into a powerful Balrog",
	}
}


-- Return the number of Udun/Melkor spells in a given book
function udun_in_book(sval, pval)
	local i, y, index, sch, s

	i = 0

	-- Hack if the book is 255 it is a random book
	if sval == 255 then
		school_book[sval] = {pval}
	end
	-- Parse all spells
	for index, s in school_book[sval] do
		for index, sch in __spell_school[s] do
			if sch == SCHOOL_UDUN then i = i + 1 end
			if sch == SCHOOL_MELKOR then i = i + 1 end
		end
	end
	return i
end

-- Return the total level of spells
function levels_in_book(sval, pval)
	local i, y, index, sch, s

	i = 0

	-- Hack if the book is 255 it is a random book
	if sval == 255 then
		school_book[sval] = {pval}
	end

	-- Parse all spells
	for index, s in school_book[sval] do
		i = i + __tmp_spells[s].level
	end
	return i
end
tome-235-src/lib/scpt/mkeys.lua0000644000076400017500000000471311012107762014244 0ustar  dgdg-- Mkeys for skills & abilities

GF_INSTA_DEATH = add_spell_type
{
	["color"]       = { TERM_DARK, 0 },
	["angry"]       = function() return TRUE, TRUE end,
	["monster"]     = function(who, dam, rad, y, x, monst)
			local race = race_info_idx(monst.r_idx, monst.ego)
			if magik(5) == FALSE or band(race.flags1, RF1_UNIQUE) ~= FALSE or band(race.flags3, RF3_UNDEAD) ~= FALSE or band(race.flags3, RF3_NONLIVING) ~= FALSE then
				return TRUE, FALSE
			else
				-- Reduce the exp gained this way
				monst.level = monst.level / 3
				return TRUE, FALSE, 32535, 0, 0, 0, 0, 0, 0, 0, " faints.", " is sucked out of life."
			end
	end,
}

-- Death touch ability
add_mkey
{
	["mkey"] 	= 100,
	["fct"] 	= function()
			if player.csp > 40 then
				increase_mana(-40)
				set_project(randint(30) + 10, GF_INSTA_DEATH, 1, 0, bor(PROJECT_STOP, PROJECT_KILL))
				energy_use = 100
			else
				msg_print("You need at least 40 mana.")
			end
	end,
}


-- Geomancy skill
add_mkey
{
	["mkey"] 	= 101,
	["fct"] 	= function()
			local s

			-- No magic
			if (player.antimagic > 0) then
				msg_print("Your anti-magic field disrupts any magic attempts.")
				return
			end

			local obj = get_object(INVEN_WIELD)
			if (obj.k_idx <= 0) or (obj.tval ~= TV_MSTAFF) then
				msg_print('You must wield a magestaff to use Geomancy.')
				return
			end

			s = get_school_spell("cast", "is_ok_spell", 62);

			-- Actualy cast the choice
			if (s ~= -1) then
				cast_school_spell(s, spell(s))
			end
	end,
}

-- Far reaching attack of polearms
add_mkey
{
	["mkey"]	= 102,
	["fct"]	 = function()
			local weapon = get_object(INVEN_WIELD);
			if weapon.tval == TV_POLEARM and (weapon.sval == SV_HALBERD or weapon.sval == SV_PIKE or weapon.sval == SV_HEAVY_LANCE or weapon.sval == SV_LANCE) then
			else
				msg_print("You will need a long polearm for this!")
				return
			end

			ret, dir = get_rep_dir()
			if ret == FALSE then return end

			local dy, dx = explode_dir(dir)
			dy = dy * 2
			dx = dx * 2
		    	targety = player.py + dy
		    	targetx = player.px + dx

			local max_blows = get_skill_scale(SKILL_POLEARM, player.num_blow / 2)
			if max_blows == 0 then max_blows = 1 end

			if get_skill(SKILL_POLEARM) >= 40 then
				energy_use = energy_use + 200
				return project(0, 0, targety, targetx, max_blows, GF_ATTACK, bor(PROJECT_BEAM, PROJECT_KILL))
			else
				energy_use = energy_use + 200
				return project(0, 0, targety, targetx, max_blows, GF_ATTACK, bor(PROJECT_BEAM, PROJECT_STOP, PROJECT_KILL))
			end
	end,
}
tome-235-src/lib/scpt/fireprof.lua0000644000076400017500000003417711012107762014737 0ustar  dgdg-- The Old Mages/Fireproofing quest: Bring back an essence 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 = 12

-- 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 essence 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 essence 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 essence 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 essence
					fireproof_quest.essence = randint(18)

					-- create essence
					essence = create_object(TV_BATERIE, fireproof_quest.essence)

					-- mark essence
					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 essence
				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 essence 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 essence 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 essence 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 (essence was retrieved)
			elseif (quest(FIREPROOF_QUEST).status == QUEST_STATUS_COMPLETED) then

				-- ask for essence
				ret, item = get_item("Which essence?",
						     "You have no essences to return",
						     bor(USE_INVEN),
						     function (obj)

							-- check it's the 'marked' essence
							if (obj.tval == TV_BATERIE) and (obj.sval == fireproof_quest.essence) and (obj.pval2 == fireproof_quest.essence) then
								return TRUE
							end
							return FALSE
						     end
				)

				-- didn't get the essence?
				if (ret == FALSE) then 
					return TRUE

				-- got the essence!
				else

					-- take essence
					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 essence 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

tome-235-src/lib/scpt/s_stick.lua0000644000076400017500000002327211012107762014554 0ustar  dgdg-- Spells that are stick or artifacts/... only

DEVICE_HEAL_MONSTER = add_spell
{
	["name"] = 	"Heal Monster",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	3,
	["mana"] = 	5,
	["mana_max"] = 	20,
	["fail"] = 	15,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 10, 10 },
			[TV_WAND] =
			{
				["rarity"] = 		17,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["spell"] = 	function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			return fire_ball(GF_OLD_HEAL, dir, 20 + get_level(DEVICE_HEAL_MONSTER, 380), 0)
	end,
	["info"] = 	function()
			return "heal "..(20 + get_level(DEVICE_HEAL_MONSTER, 380))
	end,
	["desc"] =	{
			"Heals a monster",
	}
}

DEVICE_SPEED_MONSTER = add_spell
{
	["name"] = 	"Haste Monster",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	10,
	["mana"] = 	10,
	["mana_max"] = 	10,
	["fail"] = 	30,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 10, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		7,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["spell"] = 	function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			return fire_ball(GF_OLD_SPEED, dir, 1, 0)
	end,
	["info"] = 	function()
			return "speed +10"
	end,
	["desc"] =	{
			"Haste a monster",
	}
}

DEVICE_WISH = add_spell
{
	["name"] = 	"Wish",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	50,
	["mana"] = 	400,
	["mana_max"] = 	400,
	["fail"] = 	99,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 1, 2 },
			[TV_STAFF] =
			{
				["rarity"] = 		98,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 1, 1 },
			},
	},
	["spell"] = 	function()
			make_wish()
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"This grants you a wish, beware of what you ask for!",
	}
}

DEVICE_SUMMON = add_spell
{
	["name"] = 	"Summon",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	5,
	["mana"] = 	5,
	["mana_max"] = 	25,
	["fail"] = 	20,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 1, 20 },
			[TV_STAFF] =
			{
				["rarity"] = 		13,
				["base_level"] =	{ 1, 40 },
				["max_level"] =		{ 25, 50 },
			},
	},
	["spell"] = 	function()
			local i, obvious
			obvious = nil
			for i = 1, 4 + get_level(DEVICE_SUMMON, 30) do
				obvious = is_obvious(summon_specific(player.py, player.px, dun_level, 0), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Summons hostile monsters near you",
	}
}

DEVICE_MANA = add_spell
{
	["name"] = 	"Mana",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	30,
	["mana"] = 	1,
	["mana_max"] = 	1,
	["fail"] = 	80,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 2, 3 },
			[TV_STAFF] =
			{
				["rarity"] = 		78,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 20, 35 },
			},
	},
	["spell"] = 	function()
			increase_mana((player.msp * (20 + get_level(DEVICE_MANA, 50))) / 100)
			return TRUE
	end,
	["info"] = 	function()
			return "restore "..(20 + get_level(DEVICE_MANA, 50)).."%"
	end,
	["desc"] =	{
			"Restores a part(or all) of your mana",
	}
}

DEVICE_NOTHING = add_spell
{
	["name"] = 	"Nothing",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	1,
	["mana"] = 	0,
	["mana_max"] = 	0,
	["fail"] = 	0,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 0, 0 },
			[TV_WAND] =
			{
				["rarity"] = 		3,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 1, 1 },
			},
			[TV_STAFF] =
			{
				["rarity"] = 		3,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 1, 1},
			},
	},
	["spell"] = 	function()
			return FALSE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"It does nothing.",
	}
}

DEVICE_LEBOHAUM = add_spell
{
	["name"] = 	"Artifact Lebauhaum",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	1,
	["mana"] = 	0,
	["mana_max"] = 	0,
	["fail"] = 	0,
	["random"] =    -1,
	["activate"] =  3,
	["spell"] = 	function()
			msg_print("You hear a little song in your head in some unknown tongue:")
			msg_print("'Avec le casque Lebohaum y a jamais d'anicroches, je parcours les dongeons,")
			msg_print("j'en prend plein la caboche. Avec le casque Lebohaum, tout ces monstres a la")
			msg_print("con, je leur met bien profond: c'est moi le maitre du dongeon!'")
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"sing a cheerful song",
	}
}

DEVICE_MAGGOT = add_spell
{
	["name"] = 	"Artifact Maggot",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	1,
	["mana"] = 	7,
	["mana_max"] = 	7,
	["fail"] = 	20,
	["random"] =    -1,
	["activate"] =  { 10, 50 },
	["spell"] = 	function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end
			return fire_ball(GF_TURN_ALL, dir, 40, 2)
	end,
	["info"] = 	function()
			return "power 40 rad 2"
	end,
	["desc"] =	{
			"terrify",
	}
}

DEVICE_HOLY_FIRE = add_spell
{
	["name"] = 	"Holy Fire of Mithrandir",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	30,
	["mana"] = 	50,
	["mana_max"] = 	150,
	["fail"] = 	75,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 2, 5 },
			[TV_STAFF] =
			{
				-- Rarity higher than 100 to be sure to not have it generated randomly
				["rarity"] = 		999,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 35, 35 },
			},
	},
	["spell"] = 	function()
			return project_los(GF_HOLY_FIRE, 50 + get_level(DEVICE_HOLY_FIRE, 300))
	end,
	["info"] = 	function()
			return "dam "..(50 + get_level(DEVICE_HOLY_FIRE, 250))
	end,
	["desc"] =	{
			"The Holy Fire created by this staff will deeply(double damage) burn",
			"all that is evil.",
	}
}

-- Ok the Eternal Flame, to craete one of the 4 ultimate arts
-- needed to enter the last level of the Void
DEVICE_ETERNAL_FLAME = add_spell
{
	["name"] = 	"Artifact Eternal Flame",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	1,
	["mana"] = 	0,
	["mana_max"] = 	0,
	["fail"] = 	0,
	["random"] =    -1,
	["activate"] =  { 0, 0 },
	["spell"] = 	function(flame_item)
			local ret, item, obj

			ret, item = get_item("Which object do you want to imbue?",
					     "You have no objects to imbue.",
					     bor(USE_INVEN),
					     function (obj)
						if obj.name1 > 0 or obj.name2 > 0 then return FALSE end
					     	if (obj.tval == TV_SWORD) and (obj.sval == SV_LONG_SWORD) then
							return TRUE
					     	elseif (obj.tval == TV_MSTAFF) and (obj.sval == SV_MSTAFF) then
							return TRUE
					     	elseif (obj.tval == TV_BOW) and (obj.sval == SV_HEAVY_XBOW) then
							return TRUE
					     	elseif (obj.tval == TV_DRAG_ARMOR) and (obj.sval == SV_DRAGON_POWER) then
							return TRUE
					     	end
						return FALSE
					     end
			)
			if ret == FALSE then return FALSE end

			obj = get_object(item)

			if (obj.tval == TV_SWORD) and (obj.sval == SV_LONG_SWORD) then
				obj.name1 = 147
			elseif (obj.tval == TV_MSTAFF) and (obj.sval == SV_MSTAFF) then
				obj.name1 = 127
			elseif (obj.tval == TV_BOW) and (obj.sval == SV_HEAVY_XBOW) then
				obj.name1 = 152
			elseif (obj.tval == TV_DRAG_ARMOR) and (obj.sval == SV_DRAGON_POWER) then
				obj.name1 = 17
			end
			apply_magic(obj, -1, TRUE, TRUE, TRUE)

			obj.found = OBJ_FOUND_SELFMADE

			inven_item_increase(flame_item, -1)
			inven_item_describe(flame_item)
			inven_item_optimize(flame_item)

			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"imbuing an object with the eternal fire",
	}
}

-- And one more silly activation :)
DEVICE_DURANDIL = add_spell
{
	["name"] = 	"Artifact Durandil",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	1,
	["mana"] = 	0,
	["mana_max"] = 	0,
	["fail"] = 	0,
	["random"] =    -1,
	["activate"] =  3,
	["spell"] = 	function()
			msg_print("You hear a little song in your head in some unknown tongue:")
			msg_print("'Les epees Durandils sont forgees dans les mines par des nains.")
			msg_print("Avec ca c'est facile de tuer un troll avec une seule main. Pas besoin")
			msg_print("de super entrainement nis de niveau 28. Quand tu sors l'instrument")
			msg_print("c'est l'ennemi qui prend la fuite! Avec ton epee Durandil quand tu")
			msg_print("parcours les chemins, tu massacre sans peine les brigands et les gobelins,")
			msg_print("les rats geants, les ogres mutants, les zombies et les liches, tu les")
			msg_print("decoupe en tranches comme si c'etait des parts de quiches.")
			msg_print("Les epees Durandil! Les epees Durandil!")
			msg_print("Quand tu la sort dans un dongeon au moins t'as pas l'air debile.")
			msg_print("C'est l'arme des bourins qui savent etre subtils.")
			msg_print("Ne partez pas a l'aventure sans votre epee Durandil!'")
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"sing a cheerful song",
	}
}

DEVICE_THUNDERLORDS = add_spell
{
	["name"] = 	"Artifact Thunderlords",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	1,
	["mana"] = 	1,
	["mana_max"] = 	1,
	["fail"] = 	20,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 3, 3 },
			[TV_STAFF] =
			{
				-- Rarity higher than 100 to be sure to not have it generated randomly
				["rarity"] = 		999,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 1, 1 },
			},
	},
	["spell"] = 	function()
			if dun_level > 0 then
				msg_print("As you blow the horn a thunderlord pops out of nowhere and grabs you.")
				recall_player(0, 1)
			else
				msg_print("You cannot use it there.")
			end
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"A thunderlord will appear to transport you quickly to the surface.",
	}
}

--[[ Template
DEVICE_ = add_spell
{
	["name"] = 	"",
	["school"] = 	{SCHOOL_DEVICE},
	["level"] = 	1,
	["mana"] = 	2,
	["mana_max"] = 	15,
	["fail"] = 	10,
	["random"] =    -1,
	["stick"] =
	{
			["charge"] =    { 10, 5 },
			[TV_STAFF] =
			{
				["rarity"] = 		7,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 25, 50 },
			},
	},
	["spell"] = 	function()
			return FALSE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"",
	}
}
]]
tome-235-src/lib/scpt/god.lua0000644000076400017500000006102211012107762013661 0ustar  dgdg-- The god quest: find randomly placed relic in a randomly placed dungeon!

-- set some global variables (stored in the save file via the ["data"] key)
god_quest = {}

-- increase this number to make god quests more common, to a max value of 100
god_quest.CHANCE_OF_GOD_QUEST = 21

-- increase this number to make more quests
god_quest.MAX_NUM_GOD_QUESTS = 5

-- d_idx of the god_quest (Lost Temple) dungeon
god_quest.DUNGEON_GOD = 30

add_quest
{
	["global"] =    "GOD_QUEST",
	["name"] =      "God quest",
	["desc"] =      function()

			if quest(GOD_QUEST).status == QUEST_STATUS_TAKEN then

				-- get the direction that the dungeon lies from lothlorien/angband
				local home, home_axis, home_distance, home2, home2_axis, home2_distance = get_god_quest_axes()

				print_hook("#####yGod quest "..god_quest.quests_given.."!\n")
				print_hook("Thou art to find the lost temple of thy God and\n");
				print_hook("to retrieve the lost part of the relic for thy God! \n")
				if home_axis ~= "close" then
					print_hook("The temple lies "..home_distance.." to the "..home_axis.." of "..home..", \n")
				else
					print_hook("The temple lies very close to "..home..", \n")
				end
				if home2_axis ~= "close" then
					print_hook( "and "..home2_distance.." to the "..home2_axis.." of "..home2..".\n")
				else
					print_hook("and very close to "..home2..".\n")
				end					
				print_hook("\n")
			end
	end,
	["level"] =     -1,
	["data"] =      {
		["god_quest.relic_num"] = 1,
		["god_quest.quests_given"] = 0,
		["god_quest.relics_found"] = 0,
		["god_quest.dun_mindepth"] = 1,
		["god_quest.dun_maxdepth"] = 4,
		["god_quest.dun_minplev"] = 0,
		["god_quest.relic_gen_tries"] = 0,
		["god_quest.relic_generated"] = FALSE,
		["god_quest.dung_x"] = 1,
		["god_quest.dung_y"] = 1,
		["god_quest.player_x"] = 0,
		["god_quest.player_y"] = 0,
	},
	["hooks"] =     {
		-- Start the game without the quest, given it by chance
		[HOOK_BIRTH_OBJECTS] = function()
			quest(GOD_QUEST).status = QUEST_STATUS_UNTAKEN

			-- initialise save-file stored variables when new character is created
			god_quest.relic_num = 1
			god_quest.quests_given = 0
			god_quest.relics_found = 0
			god_quest.dun_mindepth = 1
			god_quest.dun_maxdepth = 4
			god_quest.dun_minplev = 0
			god_quest.relic_gen_tries = 0
			god_quest.relic_generated = FALSE
		end,
		[HOOK_PLAYER_LEVEL] = function(gained)
			local home_axis, home

			if gained > 0 then
				-- roll for chance of quest
				local give_god_quest = magik(god_quest.CHANCE_OF_GOD_QUEST)

				-- check player is worshipping a god, not already on a god quest.
				if (player.astral ~= FALSE) or (player.pgod <= 0) 
				or (quest(GOD_QUEST).status == QUEST_STATUS_TAKEN) or (quest(GOD_QUEST).status == QUEST_STATUS_FAILED)
				or (god_quest.quests_given >= god_quest.MAX_NUM_GOD_QUESTS) or (give_god_quest == FALSE)
				or ((current_dungeon_idx == god_quest.DUNGEON_GOD) and (dun_level > 0)) or (player.lev <= god_quest.dun_minplev) then
					-- Don't let a player get quests with trickery
					if player.lev > god_quest.dun_minplev then
						god_quest.dun_minplev = player.lev
					end
					return
				else
					-- each god has different characteristics, so the quests are differnet depending on your god
					if player.pgod == GOD_ERU then
						god_quest.relic_num = 7
					elseif player.pgod == GOD_MANWE then
						god_quest.relic_num = 8
					elseif player.pgod == GOD_TULKAS then
						god_quest.relic_num = 9
					elseif player.pgod == GOD_MELKOR then
						god_quest.relic_num = 10
					elseif player.pgod == GOD_YAVANNA then
						god_quest.relic_num =11
					end

					-- This var will need resetting
					god_quest.relic_generated = FALSE
					quest(GOD_QUEST).status = QUEST_STATUS_TAKEN
					god_quest.quests_given = god_quest.quests_given + 1

					-- actually place the dungeon in a random place
					place_rand_dung()

					-- store the variables of the coords where the player was given the quest
					god_quest.player_y, god_quest.player_x = player.get_wild_coord()

					-- establish direction of player and 'home' from dungeon
					local home, home_axis, home_distance, home2, home2_axis, home2_distance = get_god_quest_axes()

					-- God issues instructions
					cmsg_print(TERM_L_BLUE, "The voice of "..deity(player.pgod).name.." booms in your head:")

					cmsg_print(TERM_YELLOW, "'I have a task for thee.")
					cmsg_print(TERM_YELLOW, "Centuries ago an ancient relic of mine was broken apart.")
					cmsg_print(TERM_YELLOW, "The pieces of it have been lost in fallen temples.")
					cmsg_print(TERM_YELLOW, "Thou art to find my lost temple and retrieve a piece of the relic.")
					cmsg_print(TERM_YELLOW, "When thy task is done, thou art to lift it in the air and call upon my name.")
					cmsg_print(TERM_YELLOW, "I shall then come to reclaim what is mine!")
					if home_axis ~= "close" then
						cmsg_print(TERM_YELLOW, "The temple lies "..home_distance.." to the "..home_axis.." of "..home..", ")
					else
						cmsg_print(TERM_YELLOW, "The temple lies very close to "..home..",")
					end

					if home2_axis ~= "close" then
						cmsg_print(TERM_YELLOW, "and "..home2_distance.." to the "..home2_axis.." of "..home2..", I can feel it.'")
					else
						cmsg_print(TERM_YELLOW, "and very close to "..home2..", I can feel it.'")
					end

					-- Prepare depth of dungeon. If this was generated in set_god_dungeon_attributes(),
					-- then we'd have trouble if someone levelled up in the dungeon!
					god_quest.dun_mindepth = player.lev*2/3
					god_quest.dun_maxdepth = god_quest.dun_mindepth + 4
				end
			end
		end,
		[HOOK_LEVEL_END_GEN] = function()
			local chance

			-- Check for dungeon
			if (current_dungeon_idx ~= god_quest.DUNGEON_GOD) or (quest(GOD_QUEST).status == QUEST_STATUS_UNTAKEN) then
				return
			-- if the relic has been created at this point, then it was created on the *PREVIOUS* call of HOOK_LEVEL_END_GEN, and 
			-- therefore the player has caused another level generation in the temple and hence failed the quest.
			elseif (god_quest.relic_generated == TRUE) and quest(GOD_QUEST).status ~= QUEST_STATUS_FAILED then 
				
					-- fail the quest, don't give another one, don't give this message again
					quest(GOD_QUEST).status = QUEST_STATUS_FAILED
					-- God issues instructions
					cmsg_print(TERM_L_BLUE, "The voice of "..deity(player.pgod).name.." booms in your head:")

					cmsg_print(TERM_YELLOW, "'Thou art a fool!")
					cmsg_print(TERM_YELLOW, "I told thee to look carefully for the relic. It appears thou hast missed the")
					cmsg_print(TERM_YELLOW, "opportunity to claim it in my name, as I sense that those monsters who ")
					cmsg_print(TERM_YELLOW, "have overrun my temple have destroyed it themselves.")
					cmsg_print(TERM_YELLOW, "I shall not ask thee to do such a thing again, as thou hast failed me in this")
					cmsg_print(TERM_YELLOW, "simple task!'")					
			else
				-- Force relic generation on 5th attempt if others have been unsuccessful.
				if (god_quest.relic_gen_tries == 4) and (god_quest.relic_generated == FALSE) then
					generate_relic()
				else
					-- 1/5 chance of generation
					chance = randint(5)
					if (chance == 5) then
						generate_relic()
					else
						god_quest.relic_gen_tries = god_quest.relic_gen_tries + 1
					end
				end
			end
		end,
		[HOOK_ENTER_DUNGEON] = function(d_idx)
			-- call the function to set the dungeon variables (dependant on pgod) the first time we enter the dungeon
			if d_idx ~= god_quest.DUNGEON_GOD then
				return
			else
				set_god_dungeon_attributes()
			end
		end,
		[HOOK_GEN_LEVEL_BEGIN] = function()
			-- call the function to set the dungeon variables (dependant on pgod) when we WoR back into the dungeon
			if current_dungeon_idx ~= god_quest.DUNGEON_GOD then
				return
			else
				set_god_dungeon_attributes()
			end
		end,
		[HOOK_STAIR] = function()
			-- call the function to set the dungeon variables (dependant on pgod) every time we go down a level
			if current_dungeon_idx ~= god_quest.DUNGEON_GOD then
				return
			else
				set_god_dungeon_attributes()
			end
		end,
		[HOOK_GET] = function(o_ptr, item)
				-- Is it the relic, and check to make sure the relic hasn't already been identified
			if (quest(GOD_QUEST).status == QUEST_STATUS_TAKEN) and (o_ptr.tval == TV_JUNK) and (o_ptr.sval == god_quest.relic_num)
			and (o_ptr.pval ~= TRUE)  and (god_quest.relics_found < god_quest.quests_given) then

				-- more God talky-talky
				cmsg_print(TERM_L_BLUE, deity(player.pgod).name.." speaks to you:")

				-- Is it the last piece of the relic?
				if (god_quest.quests_given == god_quest.MAX_NUM_GOD_QUESTS) then
					cmsg_print(TERM_YELLOW, "'At last! Thou hast found all of the relic pieces.")

					-- reward player by increasing prayer skill
					cmsg_print(TERM_YELLOW, "Thou hast done exceptionally well! I shall increase thy prayer skill even more!'")
					skill(SKILL_PRAY).value = skill(SKILL_PRAY).value + (10 * (skill(SKILL_PRAY).mod))

					-- Take the relic piece
					floor_item_increase(item, -1)
					floor_item_optimize(item)
				else
					cmsg_print(TERM_YELLOW, "'Well done! Thou hast found part of the relic.")
					cmsg_print(TERM_YELLOW, "I shall surely ask thee to find more of it later!")
					cmsg_print(TERM_YELLOW, "I will take it from thee for now'")

					-- Take the relic piece
					floor_item_increase(item, -1)
					floor_item_optimize(item)

					-- reward player by increasing prayer skill
					cmsg_print(TERM_YELLOW, "'As a reward, I shall teach thee how to pray better'")
					skill(SKILL_PRAY).value = skill(SKILL_PRAY).value + (5 * (skill(SKILL_PRAY).mod))
				end

				-- relic piece has been identified
				o_ptr.pval = TRUE
				god_quest.relics_found = god_quest.relics_found + 1

				-- Make sure quests can be given again if neccesary
				quest(GOD_QUEST).status = QUEST_STATUS_UNTAKEN
				return TRUE
			end
		end,
		[HOOK_CHAR_DUMP] = function()

			if (god_quest.quests_given > 0) then

				local relics = god_quest.relics_found
				local append_text = ""
				if (god_quest.relics_found == god_quest.MAX_NUM_GOD_QUESTS) then
					relics = "all"
					append_text = " and pleased your god"
				else
					if (god_quest.relics_found == 0) then
						relics = "none"
					end
					if (quest(GOD_QUEST).status == QUEST_STATUS_FAILED) then
						append_text = " and failed in your quest"
					end
				end

				print_hook("\n You found "..(relics).." of the relic pieces"..(append_text)..".")

			end
		end,
	},
}

-- this function places the lost temple at a randomly determined place.
function place_rand_dung()
	local tries, grid

	-- erase old dungeon
		if (god_quest.quests_given > 0) then 
		place_dungeon(god_quest.dung_y, god_quest.dung_x)
		
		-- erase old recall level
		max_dlv[god_quest.DUNGEON_GOD + 1] = 0
	end

	-- initialise tries variable
	tries = 1000

	while tries > 0 do

		tries = tries - 1
		-- get grid coordinates, within a range which prevents dungeon being generated at the very edge of the wilderness (would crash the game).
		god_quest.dung_x = rand_range(1, max_wild_x-2)
		god_quest.dung_y = rand_range(1, max_wild_y-2)

		-- Is there a town/dungeon/potentially impassable feature there, ?
		if (wild_map(god_quest.dung_y, god_quest.dung_x).entrance ~= 0)
		or (wild_feat(wild_map(god_quest.dung_y, god_quest.dung_x)).entrance ~= 0)
		or (wild_feat(wild_map(god_quest.dung_y, god_quest.dung_x)).terrain_idx == TERRAIN_EDGE)
		or (wild_feat(wild_map(god_quest.dung_y, god_quest.dung_x)).terrain_idx == TERRAIN_DEEP_WATER)
		or (wild_feat(wild_map(god_quest.dung_y, god_quest.dung_x)).terrain_idx == TERRAIN_TREES)
		or (wild_feat(wild_map(god_quest.dung_y, god_quest.dung_x)).terrain_idx == TERRAIN_SHALLOW_LAVA)
		or (wild_feat(wild_map(god_quest.dung_y, god_quest.dung_x)).terrain_idx == TERRAIN_DEEP_LAVA)
		or (wild_feat(wild_map(god_quest.dung_y, god_quest.dung_x)).terrain_idx == TERRAIN_MOUNTAIN) then
			-- try again
		else
			--neither player, nor wall, then stop this 'while'
			break
		end
	end

	-- Uhuh BAD ! lets use the default location up bree
	if tries == 0 then
		god_quest.dung_x = 32
		god_quest.dung_y = 19
	end

	-- create god dungeon in that place
	place_dungeon(god_quest.dung_y, god_quest.dung_x, god_quest.DUNGEON_GOD)

end

-- this function generates the relic at a randomly determined place in the temple.
function generate_relic()
	local tries, grid, x, y, relic

	-- initialise tries variable
	tries = 1000

	while (tries > 0) do

		tries = tries - 1
		-- get grid coordinates from current height/width, minus one to prevent relic being generated in outside wall. (would crash the game)
		y = randint(cur_hgt-1)
		x = randint(cur_wid-1)
		grid = cave(y, x)

		-- are the coordinates on a floor, not on a permanent feature (eg stairs), and not on a trap ?
		if (cave_is(grid, FF1_FLOOR) == TRUE) and (cave_is(grid, FF1_PERMANENT) == FALSE) and (grid.t_idx == 0) then break end

	end 
	
	-- create relic
	relic = create_object(TV_JUNK, god_quest.relic_num)

	-- inscribe it to prevent automatizer 'accidents'
	relic.note = quark_add("quest")

	-- If no safe co-ords were found, put it in the players backpack
	if tries == 0 then

		-- explain it
		msg_print(TERM_L_BLUE, "You luckily stumble across the relic on the stairs!")

		if (inven_carry_okay(relic)) then
			inven_carry(relic, FALSE)
		else
		-- no place found, drop it on the stairs
			drop_near(relic, -1, player.py, player.px)
		end

	else
		-- drop it
		drop_near(relic, -1, y, x)
	end

	-- Only generate once!
	god_quest.relic_generated = TRUE

	-- Reset some variables
	god_quest.relic_gen_tries = 0

end




function set_god_dungeon_attributes()

	-- dungeon properties altered according to which god player is worshipping,
	if player.pgod == GOD_ERU then

		-- The Eru temple is based on Meneltarma.
		-- W: Not too many monsters (they'll be tough though, with big levels)
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_level = 14
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_chance = 200

		-- L: Dirt and grass. More dirt at bottom, more grass at top. rocky ground would be nice
		dungeon(god_quest.DUNGEON_GOD).floor1 = 88
		dungeon(god_quest.DUNGEON_GOD).floor2 = 89
		dungeon(god_quest.DUNGEON_GOD).floor_percent1[1] = 70
		dungeon(god_quest.DUNGEON_GOD).floor_percent2[1] = 30
		dungeon(god_quest.DUNGEON_GOD).floor_percent1[2] = 10
		dungeon(god_quest.DUNGEON_GOD).floor_percent2[2] = 90

		-- A: Outer wall mountain chain. other walls granite
		dungeon(god_quest.DUNGEON_GOD).fill_type1 = 97
		dungeon(god_quest.DUNGEON_GOD).fill_percent1[1] = 100
		dungeon(god_quest.DUNGEON_GOD).outer_wall = 57
		dungeon(god_quest.DUNGEON_GOD).inner_wall = 97
		dungeon(god_quest.DUNGEON_GOD).fill_method = 2

		-- O: "At Meneltarma no weapon or tool had ever been borne" (but invaders would have left a small number)
		dungeon(god_quest.DUNGEON_GOD).objs.treasure = 45
		dungeon(god_quest.DUNGEON_GOD).objs.combat = 5
		dungeon(god_quest.DUNGEON_GOD).objs.magic = 45
		dungeon(god_quest.DUNGEON_GOD).objs.tools = 5

		-- F: A large pillar, with stairs created at edges. (You can't climb a rock through the middle, can you?)
		dungeon(god_quest.DUNGEON_GOD).flags1 = bor(DF1_BIG, DF1_NO_DOORS, DF1_CIRCULAR_ROOMS, DF1_EMPTY, DF1_TOWER, DF1_FLAT, DF1_ADJUST_LEVEL_2)
		dungeon(god_quest.DUNGEON_GOD).flags2 = bor(DF2_ADJUST_LEVEL_1_2, DF2_NO_SHAFT, DF2_ADJUST_LEVEL_PLAYER)

		-- R:
		dungeon(god_quest.DUNGEON_GOD).rules[1].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[1].percent = 50

		-- M: We want evil or flying characters
		dungeon(god_quest.DUNGEON_GOD).rules[1].mflags3 = RF3_EVIL

		dungeon(god_quest.DUNGEON_GOD).rules[2].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[2].percent = 50

		-- M: We want evil or flying characters
		dungeon(god_quest.DUNGEON_GOD).rules[2].mflags7 = RF7_CAN_FLY


	elseif player.pgod == GOD_MANWE then

		-- Manwe's lost temple is high in the clouds
		-- W: Has average number of monsters.
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_level = 18
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_chance = 160


		-- L: floor will be 'cloud-like vapour' and pools of 'condensing water'
		dungeon(god_quest.DUNGEON_GOD).floor1 = 208
		dungeon(god_quest.DUNGEON_GOD).floor2 = 209
		dungeon(god_quest.DUNGEON_GOD).floor_percent1[1] = 85
		dungeon(god_quest.DUNGEON_GOD).floor_percent2[1] = 15

		-- A: Outer wall is 'hail stone wall', inner wall 'dense fog'. FIlled at max smoothing, like islands.
		dungeon(god_quest.DUNGEON_GOD).fill_type1 = 211
		dungeon(god_quest.DUNGEON_GOD).fill_percent1[1] = 100
		dungeon(god_quest.DUNGEON_GOD).outer_wall = 210
		dungeon(god_quest.DUNGEON_GOD).inner_wall = 211
		dungeon(god_quest.DUNGEON_GOD).fill_method = 4

		-- O: Can't imagine Manwe having much treasure. Little need for tools in a cloud temple. lots of magical stuff though...
		dungeon(god_quest.DUNGEON_GOD).objs.treasure = 15
		dungeon(god_quest.DUNGEON_GOD).objs.combat = 25
		dungeon(god_quest.DUNGEON_GOD).objs.magic = 55
		dungeon(god_quest.DUNGEON_GOD).objs.tools = 5

		-- F: It's open, goes up like a tower, give it a few interesting rooms, make the monsters hard(ish).
		dungeon(god_quest.DUNGEON_GOD).flags1 = bor(DF1_NO_DOORS, DF1_TOWER, DF1_CAVERN,  DF1_ADJUST_LEVEL_2)
		dungeon(god_quest.DUNGEON_GOD).flags2 = bor(DF2_NO_SHAFT, DF2_ADJUST_LEVEL_PLAYER)

		-- R:
		dungeon(god_quest.DUNGEON_GOD).rules[1].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[1].percent = 20
		dungeon(god_quest.DUNGEON_GOD).rules[2].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[2].percent = 20
		dungeon(god_quest.DUNGEON_GOD).rules[3].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[3].percent = 20
		dungeon(god_quest.DUNGEON_GOD).rules[4].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[4].percent = 20
		dungeon(god_quest.DUNGEON_GOD).rules[5].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[5].percent = 20

		-- M: We want air(poison-type) or flying characters. Orcs too. They would have ransacked his elf-loving temple :)
		dungeon(god_quest.DUNGEON_GOD).rules[1].mflags2 = RF2_INVISIBLE
		dungeon(god_quest.DUNGEON_GOD).rules[2].mflags3 = bor(RF3_ORC, RF3_IM_POIS)
		dungeon(god_quest.DUNGEON_GOD).rules[3].mflags4 = bor(RF4_BR_POIS, RF4_BR_GRAV)
		dungeon(god_quest.DUNGEON_GOD).rules[4].mflags5 = RF5_BA_POIS
		dungeon(god_quest.DUNGEON_GOD).rules[5].mflags7 = RF7_CAN_FLY


	elseif player.pgod == GOD_TULKAS then

		-- Tulkas dungeon is quite normal, possibly a bit boring to be honest. Maybe I should add something radical to it.
		-- 'The house of Tulkas in the midmost of  Valmar was a house of mirth and revelry. It sprang into the air with many storeys,
		-- and had a tower of bronze and pillars of copper in a wide arcade'
		-- W: but with lots of monsters
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_level = 20
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_chance = 120

		-- L: floor is normal
		dungeon(god_quest.DUNGEON_GOD).floor1 = 1
		dungeon(god_quest.DUNGEON_GOD).floor_percent1[1] = 100

		-- A: Granite walls
		dungeon(god_quest.DUNGEON_GOD).fill_type1 = 56
		dungeon(god_quest.DUNGEON_GOD).fill_percent1[1] = 100
		dungeon(god_quest.DUNGEON_GOD).outer_wall = 58
		dungeon(god_quest.DUNGEON_GOD).inner_wall = 57
		dungeon(god_quest.DUNGEON_GOD).fill_method = 0

		-- O: Loads of combat drops
		dungeon(god_quest.DUNGEON_GOD).objs.treasure = 10
		dungeon(god_quest.DUNGEON_GOD).objs.combat = 70
		dungeon(god_quest.DUNGEON_GOD).objs.magic = 5
		dungeon(god_quest.DUNGEON_GOD).objs.tools = 15

		-- F: fairly standard
		dungeon(god_quest.DUNGEON_GOD).flags1 = bor(DF1_NO_DESTROY, DF1_ADJUST_LEVEL_2)
		dungeon(god_quest.DUNGEON_GOD).flags2 = DF2_ADJUST_LEVEL_PLAYER

		-- R:
		dungeon(god_quest.DUNGEON_GOD).rules[1].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[1].percent = 100

		-- M: plenty demons please
		dungeon(god_quest.DUNGEON_GOD).rules[1].mflags3 = bor(RF3_DEMON, RF3_EVIL)


	elseif player.pgod == GOD_MELKOR then

		-- Melkors dungeon will be dark, fiery and stuff
		-- Many many monsters! (but prob ADJUST_LEVEL_1_2)
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_level = 24
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_chance = 80


		-- L: floor is dirt/mud/nether
		dungeon(god_quest.DUNGEON_GOD).floor1 = 88
		dungeon(god_quest.DUNGEON_GOD).floor2 = 94
		dungeon(god_quest.DUNGEON_GOD).floor3 = 102
		dungeon(god_quest.DUNGEON_GOD).floor_percent1[1] = 45
		dungeon(god_quest.DUNGEON_GOD).floor_percent2[1] = 45
		dungeon(god_quest.DUNGEON_GOD).floor_percent3[1] = 10
		dungeon(god_quest.DUNGEON_GOD).floor_percent1[2] = 35
		dungeon(god_quest.DUNGEON_GOD).floor_percent2[2] = 35
		dungeon(god_quest.DUNGEON_GOD).floor_percent3[2] = 30

		-- A: Granite walls to fill but glass walls for room perimeters (you can see the nasty monsters coming)
		dungeon(god_quest.DUNGEON_GOD).fill_type1 = 188
		dungeon(god_quest.DUNGEON_GOD).fill_percent1[1] = 100
		dungeon(god_quest.DUNGEON_GOD).outer_wall = 188
		dungeon(god_quest.DUNGEON_GOD).inner_wall = 57
		dungeon(god_quest.DUNGEON_GOD).fill_method = 1

		-- O: Even drops
		dungeon(god_quest.DUNGEON_GOD).objs.treasure = 25
		dungeon(god_quest.DUNGEON_GOD).objs.combat = 25
		dungeon(god_quest.DUNGEON_GOD).objs.magic = 25
		dungeon(god_quest.DUNGEON_GOD).objs.tools = 25

		-- F: Small, lava rivers, nasty monsters hehehehehe
		dungeon(god_quest.DUNGEON_GOD).flags1 = bor(DF1_SMALL, DF1_LAVA_RIVERS, DF1_ADJUST_LEVEL_1)
		dungeon(god_quest.DUNGEON_GOD).flags2 = bor(DF2_ADJUST_LEVEL_1_2, DF2_ADJUST_LEVEL_PLAYER)

		-- R: No restrictions on monsters here
		dungeon(god_quest.DUNGEON_GOD).rules[1].mode = 0
		dungeon(god_quest.DUNGEON_GOD).rules[1].percent = 80

		-- R: Apart from making sure we have some GOOD ones
		dungeon(god_quest.DUNGEON_GOD).rules[2].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[2].percent = 20

		-- M:
		dungeon(god_quest.DUNGEON_GOD).rules[2].mflags3 = RF3_GOOD

	elseif player.pgod == GOD_YAVANNA then

		-- Yavannas dungeon will be very natural, tress and stuff.
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_level = 22
		dungeon(god_quest.DUNGEON_GOD).min_m_alloc_chance = 100

		-- L: floor is grass/flowers, plus dirt so not always regenerating quick!
		dungeon(god_quest.DUNGEON_GOD).floor1 = 89
		dungeon(god_quest.DUNGEON_GOD).floor2 = 199
		dungeon(god_quest.DUNGEON_GOD).floor3 = 88
		dungeon(god_quest.DUNGEON_GOD).floor_percent1[1] = 40
		dungeon(god_quest.DUNGEON_GOD).floor_percent2[1] = 15
		dungeon(god_quest.DUNGEON_GOD).floor_percent3[1] = 45

		-- A: Tree walls to fill, small trees for inner walls
		dungeon(god_quest.DUNGEON_GOD).fill_type1 = 96
		dungeon(god_quest.DUNGEON_GOD).fill_percent1[1] = 100
		dungeon(god_quest.DUNGEON_GOD).outer_wall = 202
		dungeon(god_quest.DUNGEON_GOD).inner_wall = 96
		dungeon(god_quest.DUNGEON_GOD).fill_method = 1

		-- O: nt much combat.. tools where ransackers have tried to chop trees down.
		dungeon(god_quest.DUNGEON_GOD).objs.treasure = 20
		dungeon(god_quest.DUNGEON_GOD).objs.combat = 10
		dungeon(god_quest.DUNGEON_GOD).objs.magic = 30
		dungeon(god_quest.DUNGEON_GOD).objs.tools = 40

		-- F: Natural looking
		dungeon(god_quest.DUNGEON_GOD).flags1 = bor(DF1_NO_DOORS, DF1_WATER_RIVERS, DF1_NO_DESTROY, DF1_ADJUST_LEVEL_1, DF1_NO_RECALL)
		dungeon(god_quest.DUNGEON_GOD).flags2 = bor(DF2_ADJUST_LEVEL_1_2, DF2_NO_SHAFT, DF2_NO_GENO, DF2_ADJUST_LEVEL_PLAYER)

		-- R: Demons, Undead, non-living
		dungeon(god_quest.DUNGEON_GOD).rules[1].mode = 3
		dungeon(god_quest.DUNGEON_GOD).rules[1].percent = 100

		-- M:
		dungeon(god_quest.DUNGEON_GOD).rules[1].mflags3 = bor(RF3_DEMON, RF3_UNDEAD, RF3_NONLIVING)

	end

	-- W: All dungeons are 5 levels deep, and created at 2/3 of the player clvl when the quest is given
	dungeon(god_quest.DUNGEON_GOD).mindepth = god_quest.dun_mindepth
	dungeon(god_quest.DUNGEON_GOD).maxdepth = god_quest.dun_maxdepth
	dungeon(god_quest.DUNGEON_GOD).minplev = god_quest.dun_minplev

end

-- Calling this function returns the direction the dungeon is in from the players position at the time
-- the quest was given, and also the direction from angband (if the player is worshipping Melkor) or lothlorien.
function get_god_quest_axes()
	local home, home_y_coord, home_x_coord, home_axis, home2, home2_y_coord, home2_x_coord, home2_axis, mydistance

	-- different values for different gods...
	if player.pgod ~= GOD_MELKOR then

		-- one of the valar, "home" is lothlorien, home2 is Minas Arnor
		home = "Bree"
		home_y_coord = 21
		home_x_coord = 34
		home2 = "Minas Anor"
		home2_y_coord = 56
		home2_x_coord = 60
	else
		-- Melkor, "home" is angband, home2 is Barad-dur
		home = "the Pits of Angband"
		home_y_coord = 7
		home_x_coord = 34
		home2 = "the Land of Mordor"
		home2_y_coord = 58
		home2_x_coord = 65	
	end

	home_axis = compass(home_y_coord, home_x_coord, god_quest.dung_y, god_quest.dung_x)
	home2_axis = compass(home2_y_coord, home2_x_coord, god_quest.dung_y, god_quest.dung_x)

	home_distance = approximate_distance(home_y_coord, home_x_coord, god_quest.dung_y, god_quest.dung_x)
	home2_distance = approximate_distance(home2_y_coord, home2_x_coord, god_quest.dung_y, god_quest.dung_x)

	return home, home_axis, home_distance, home2, home2_axis, home2_distance
end
tome-235-src/lib/scpt/joke.lua0000644000076400017500000000135411012107762014042 0ustar  dgdg-- Place a monster in a good spot
function gen_joke_place_monster(r_idx)
	local try = 1000
	local x
	local y
	while try > 0 do
		x = randint(cur_hgt - 4) + 2
		y = randint(cur_wid - 4) + 2
		if not (0 == place_monster_one(y, x, r_idx, 0, FALSE, MSTATUS_ENEMY)) then
			return
		end
		try = try - 1
	end
end

-- Check if a special joke monster can be generated here
function gen_joke_monsters()
	if joke_monsters == FALSE then
		return
	end

	-- Neil
	if (current_dungeon_idx == 20) and (dun_level == 72) then
		neil = test_monster_name("Neil, the Sorceror")
		m_allow_special[neil + 1] = TRUE
		gen_joke_place_monster(neil)
		m_allow_special[neil + 1] = FALSE
	end
end

add_hook_script(HOOK_LEVEL_END_GEN, "gen_joke_monsters", "gen_joke_monsters")
tome-235-src/lib/scpt/s_eru.lua0000644000076400017500000000611411012107762014226 0ustar  dgdg-- Handle Eru Iluvatar magic school

ERU_SEE = add_spell
{
	["name"] = 	"See the Music",
	["school"] = 	{SCHOOL_ERU},
	["level"] = 	1,
	["mana"] = 	1,
	["mana_max"] = 	50,
	["fail"] = 	20,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			local obvious
			obvious = set_tim_invis(randint(20) + 10 + get_level(ERU_SEE, 100))
			if get_level(ERU_SEE) >= 30 then
				wiz_lite_extra()
				obvious = TRUE
			elseif get_level(ERU_SEE) >= 10 then
				map_area()
				obvious = TRUE
			end
			if get_level(ERU_SEE) >= 20 then
				obvious = is_obvious(set_blind(0), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
			return "dur "..(10 + get_level(ERU_SEE, 100)).."+d20"
	end,
	["desc"] =	{
			"Allows you to 'see' the Great Music from which the world",
			"originates, allowing you to see unseen things",
			"At level 10 it allows you to see your surroundings",
			"At level 20 it allows you to cure blindness",
			"At level 30 it allows you to fully see all the level"
	}
}

ERU_LISTEN = add_spell
{
	["name"] = 	"Listen to the Music",
	["school"] = 	{SCHOOL_ERU},
	["level"] = 	7,
	["mana"] = 	15,
	["mana_max"] = 	200,
	["fail"] = 	25,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			if get_level(ERU_LISTEN) >= 30 then
				ident_all()
				identify_pack()
				return TRUE
			elseif get_level(ERU_LISTEN) >= 14 then
				identify_pack()
				return TRUE
			else
				return ident_spell()
			end
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Allows you to listen to the Great Music from which the world",
			"originates, allowing you to understand the meaning of things",
			"At level 14 it allows you to identify all your pack",
			"At level 30 it allows you to identify all items on the level",
	}
}

ERU_UNDERSTAND = add_spell
{
	["name"] = 	"Know the Music",
	["school"] = 	{SCHOOL_ERU},
	["level"] = 	30,
	["mana"] = 	200,
	["mana_max"] = 	600,
	["fail"] = 	50,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			if get_level(ERU_UNDERSTAND) >= 10 then
				identify_pack_fully()
				return TRUE
			else
				return identify_fully()
			end
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Allows you to understand the Great Music from which the world",
			"originates, allowing you to know the full abilities of things",
			"At level 10 it allows you to *identify* all your pack",
	}
}

ERU_PROT = add_spell
{
	["name"] = 	"Lay of Protection",
	["school"] = 	{SCHOOL_ERU},
	["level"] = 	35,
	["mana"] = 	400,
	["mana_max"] = 	400,
	["fail"] = 	80,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			return fire_ball(GF_MAKE_GLYPH, 0, 1, 1 + get_level(ERU_PROT, 2, 0))
	end,
	["info"] = 	function()
			return "rad "..(1 + get_level(ERU_PROT, 2, 0))
	end,
	["desc"] =	{
			"Creates a circle of safety around you",
	}
}
tome-235-src/lib/scpt/s_manwe.lua0000644000076400017500000000744711012107762014554 0ustar  dgdg-- Handle Manwe Sulimo magic school

MANWE_SHIELD = add_spell
{
	["name"] =      "Wind Shield",
	["school"] =    {SCHOOL_MANWE},
	["level"] =     10,
	["mana"] =      100,
	["mana_max"] =  500,
	["fail"] = 	30,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			local dur = get_level(MANWE_SHIELD, 50) + 10 + randint(20)
			local obvious

			obvious = set_protevil(dur)
			if get_level(MANWE_SHIELD) >= 10 then
				local type

				type = 0
				if get_level(MANWE_SHIELD) >= 20 then
					type = SHIELD_COUNTER
				end
				obvious = is_obvious(set_shield(dur, get_level(MANWE_SHIELD, 30), type, 1 + get_level(MANWE_SHIELD, 2), 1 + get_level(MANWE_SHIELD, 6)), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
			local desc = "dur "..(get_level(MANWE_SHIELD, 50) + 10).."+d20"

			if get_level(MANWE_SHIELD) >= 10 then
				desc = desc.." AC "..(get_level(MANWE_SHIELD, 30))
			end
			if get_level(MANWE_SHIELD) >= 20 then
				desc = desc.." dam "..(1 + get_level(MANWE_SHIELD, 2)).."d"..(1 + get_level(MANWE_SHIELD, 6))
			end
			return desc
	end,
	["desc"] =	{
			"It surrounds you with a shield of wind that deflects blows from evil monsters",
			"At level 10 it increases your armour rating",
			"At level 20 it retaliates against monsters that melee you",
	}
}

MANWE_AVATAR = add_spell
{
	["name"] =      "Avatar",
	["school"] =    {SCHOOL_MANWE},
	["level"] =     35,
	["mana"] =      1000,
	["mana_max"] =  1000,
	["fail"] = 	80,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			return set_mimic(get_level(MANWE_AVATAR, 20) + randint(10), resolve_mimic_name("Maia"), player.lev)
	end,
	["info"] =      function()
			return "dur "..(get_level(MANWE_AVATAR, 20)).."+d10"
	end,
	["desc"] =	{
			"It turns you into a full grown Maia",
	}
}

MANWE_BLESS = add_spell
{
	["name"] =      "Manwe's Blessing",
	["school"] =    {SCHOOL_MANWE},
	["level"] =     1,
	["mana"] =      10,
	["mana_max"] =  100,
	["fail"] = 	20,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			local dur = get_level(MANWE_BLESS, 70) + 30 + randint(40)
			local obvious

			obvious = set_blessed(dur)
			obvious = is_obvious(set_afraid(0), obvious)
			obvious = is_obvious(set_lite(0), obvious)
			if get_level(MANWE_BLESS) >= 10 then
				obvious = is_obvious(set_hero(dur), obvious)
			end
			if get_level(MANWE_BLESS) >= 20 then
				obvious = is_obvious(set_shero(dur), obvious)
			end
			if get_level(MANWE_BLESS) >= 30 then
				obvious = is_obvious(set_holy(dur), obvious)
			end
			return obvious
	end,
	["info"] =      function()
			return "dur "..(get_level(MANWE_BLESS, 70) + 30).."+d40"
	end,
	["desc"] =	{
			"Manwe's Blessing removes your fears, blesses you and surrounds you with",
			"holy light",
			"At level 10 it also grants heroism",
			"At level 20 it also grants super heroism",
			"At level 30 it also grants holy luck and life protection",
	}
}

MANWE_CALL = add_spell
{
	["name"] =      "Manwe's Call",
	["school"] =    {SCHOOL_MANWE},
	["level"] =     20,
	["mana"] =      200,
	["mana_max"] =  500,
	["fail"] = 	40,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] = 	SKILL_SPIRITUALITY,
	["spell"] = 	function()
			local y, x, m_idx

			y, x = find_position(player.py, player.px)
			m_idx = place_monster_one(y, x, test_monster_name("Great eagle"), 0, FALSE, MSTATUS_FRIEND)

			if m_idx ~= 0 then
				monster_set_level(m_idx, 20 + get_level(MANWE_CALL, 70, 0))
				return TRUE
			end
	end,
	["info"] =      function()
			return "level "..(get_level(MANWE_CALL, 70) + 20)
	end,
	["desc"] =	{
			"Manwe's Call summons a Great Eagle to help you battle the forces",
			"of Morgoth"
	}
}
tome-235-src/lib/scpt/s_earth.lua0000644000076400017500000000772011012107762014542 0ustar  dgdg-- The earth school

STONESKIN = add_spell
{
	["name"] = 	"Stone Skin",
	["school"] = 	SCHOOL_EARTH,
	["level"] = 	1,
	["mana"] = 	1,
	["mana_max"] = 	50,
	["fail"] = 	10,
	["inertia"] = 	{ 2, 50 },
	["spell"] = 	function()
			local type
			if get_level(STONESKIN, 50) >= 25 then
				type = SHIELD_COUNTER
			else
				type = 0
			end
			return set_shield(randint(10) + 10 + get_level(STONESKIN, 100), 10 + get_level(STONESKIN, 50), type, 2 + get_level(STONESKIN, 5), 3 + get_level(STONESKIN, 5))
	end,
	["info"] = 	function()
			if get_level(STONESKIN, 50) >= 25 then
				return "dam "..(2 + get_level(STONESKIN, 5)).."d"..(3 + get_level(STONESKIN, 5)).." dur "..(10 + get_level(STONESKIN, 100)).."+d10 AC "..(10 + get_level(STONESKIN, 50))
			else
				return "dur "..(10 + get_level(STONESKIN, 100)).."+d10 AC "..(10 + get_level(STONESKIN, 50))
			end
	end,
	["desc"] =	{
			"Creates a shield of earth around you to protect you",
			"At level 25 it starts dealing damage to attackers"
		}
}

DIG = add_spell
{
	["name"] = 	"Dig",
	["school"] = 	SCHOOL_EARTH,
	["level"] = 	12,
	["mana"] = 	14,
	["mana_max"] = 	14,
	["fail"] = 	20,
	["stick"] =
	{
			["charge"] =    { 15, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		25,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 1, 1 },
			},
	},
	["spell"] = 	function()
			local ret, dir
			ret, dir = get_aim_dir()
			if ret == FALSE then return end
			return wall_to_mud(dir)
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Digs a hole in a wall much faster than any shovels",
		}
}

STONEPRISON = add_spell
{
	["name"] = 	"Stone Prison",
	["school"] = 	SCHOOL_EARTH,
	["level"] = 	25,
	["mana"] = 	30,
	["mana_max"] = 	50,
	["fail"] = 	65,
	["stick"] =
	{
			["charge"] =    { 5, 3 },
			[TV_WAND] =
			{
				["rarity"] = 		57,
				["base_level"] =	{ 1, 3 },
				["max_level"] =		{ 5, 20 },
			},
	},
	["spell"] = 	function()
			local ret, x, y
			if get_level(STONEPRISON, 50) >= 10 then
				ret, x, y = tgt_pt()
			else
				y = player.py
				x = player.px
			end
			wall_stone(y, x)
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Creates a prison of walls around you",
			"At level 10 it allows you to target a monster"
		}
}

STRIKE = add_spell
{
	["name"] = 	"Strike",
	["school"] = 	{SCHOOL_EARTH},
	["level"] = 	30,
	["mana"] = 	30,
	["mana_max"] = 	50,
	["fail"] = 	60,
	["stick"] =
	{
			["charge"] =    { 2, 6 },
			[TV_WAND] =
			{
				["rarity"] = 		635,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 10, 50 },
			},
	},
	["spell"] = 	function()
			local ret, dir, rad
			ret, dir = get_aim_dir()
			if ret == FALSE then return end
			if get_level(STRIKE, 50) >= 12 then
				return fire_ball(GF_FORCE, dir, 50 + get_level(STRIKE, 50), 1)
			else
				return fire_ball(GF_FORCE, dir, 50 + get_level(STRIKE, 50), 0)
			end
	end,
	["info"] = 	function()
			if get_level(STRIKE, 50) >= 12 then
	       			return "dam "..(50 + get_level(STRIKE, 50)).." rad 1"
			else
				return "dam "..(50 + get_level(STRIKE, 50))
			end
	end,
	["desc"] =	{
			"Creates a micro-ball of force that will push monsters backwards",
			"If the monster is caught near a wall, it'll be crushed against it",
			"At level 12 it turns into a ball of radius 1"
	}
}

SHAKE = add_spell
{
	["name"] = 	"Shake",
	["school"] = 	{SCHOOL_EARTH},
	["level"] = 	27,
	["mana"] = 	25,
	["mana_max"] = 	30,
	["fail"] = 	60,
	["stick"] =
	{
			["charge"] =    { 5, 10 },
			[TV_STAFF] =
			{
				["rarity"] = 		75,
				["base_level"] =	{ 1, 3 },
				["max_level"] =		{ 9, 20 },
			},
	},
	["inertia"] = 	{ 2, 50 },
	["spell"] = 	function()
			local ret, x, y
			if get_level(SHAKE, 50) >= 10 then
			       	ret, x, y = tgt_pt()
				if ret == FALSE then return end
			else
				x = player.px
				y = player.py
			end
			earthquake(y, x, 4 + get_level(SHAKE, 10));
			return TRUE
	end,
	["info"] = 	function()
			return "rad "..(4 + get_level(SHAKE, 10))
	end,
	["desc"] =	{
			"Creates a localised earthquake",
			"At level 10 it can be targeted at any location"
	}
}
tome-235-src/lib/scpt/s_demon.lua0000644000076400017500000002122611012107762014536 0ustar  dgdg-- handle the demonology school

-- Demonblade
DEMON_BLADE = add_spell
{
	["name"] =      "Demon Blade",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     1,
	["mana"] =      4,
	["mana_max"] =  44,
	["fail"] =      10,
	["random"] =    0,
	["stick"] =
	{
			["charge"] =    { 3, 7 },
			[TV_WAND] =
			{
				["rarity"] =	    75,
				["base_level"] =	{ 1, 17 },
				["max_level"] =		{ 20, 40 },
			},
	},
	["spell"] =     function()
			local type, rad

			type = GF_FIRE
			if get_level(DEMON_BLADE) >= 30 then type = GF_HELL_FIRE end

			rad = 0
			if get_level(DEMON_BLADE) >= 45 then rad = 1 end

			return set_project(randint(20) + get_level(DEMON_BLADE, 80),
				    type,
				    4 + get_level(DEMON_BLADE, 40),
				    rad,
				    bor(PROJECT_STOP, PROJECT_KILL))
	end,
	["info"] =      function()
			return "dur "..(get_level(DEMON_BLADE, 80)).."+d20 dam "..(4 + get_level(DEMON_BLADE, 40)).."/blow"
	end,
	["desc"] =      {
			"Imbues your blade with fire to deal more damage",
			"At level 30 it deals hellfire damage",
			"At level 45 it spreads over a 1 radius zone around your target",
	}
}

DEMON_MADNESS = add_spell
{
	["name"] =      "Demon Madness",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     10,
	["mana"] =      5,
	["mana_max"] =  20,
	["fail"] =      25,
	["random"] =    0,
	["spell"] =     function()
			local ret, dir, type, y1, x1, y2, x2

			ret, dir = get_aim_dir()
			if ret == FALSE then return end

			type = GF_CHAOS
			if magik(33) == TRUE then type = GF_CONFUSION end
			if magik(33) == TRUE then type = GF_CHARM end

			-- Calc the coordinates of arrival
			y1, x1 = get_target(dir)
			y2 = player.py - (y1 - player.py)
			x2 = player.px - (x1 - player.px)

			local obvious = nil
			obvious = project(0, 1 + get_level(DEMON_MADNESS, 4, 0),
				y1, x1,
				20 + get_level(DEMON_MADNESS, 200),
				type, bor(PROJECT_STOP, PROJECT_GRID, PROJECT_ITEM, PROJECT_KILL))
			obvious = is_obvious(project(0, 1 + get_level(DEMON_MADNESS, 4, 0),
				y2, x2,
				20 + get_level(DEMON_MADNESS, 200),
				type, bor(PROJECT_STOP, PROJECT_GRID, PROJECT_ITEM, PROJECT_KILL)), obvious)
			return obvious
	end,
	["info"] =      function()
			return "dam "..(20 + get_level(DEMON_MADNESS, 200)).." rad "..(1 + get_level(DEMON_MADNESS, 4, 0))
	end,
	["desc"] =      {
			"Fire 2 balls in opposite directions of randomly chaos, confusion or charm",
	}
}

DEMON_FIELD = add_spell
{
	["name"] =      "Demon Field",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     20,
	["mana"] =      20,
	["mana_max"] =  60,
	["fail"] =      60,
	["random"] =    0,
	["spell"] =     function()
			local ret, dir

			ret, dir = get_aim_dir()
			if ret == FALSE then return end
			return fire_cloud(GF_NEXUS, dir, 20 + get_level(DEMON_FIELD, 70), 7, 30 + get_level(DEMON_FIELD, 100))
	end,
	["info"] =      function()
			return "dam "..(20 + get_level(DEMON_FIELD, 70)).." dur "..(30 + get_level(DEMON_FIELD, 100))
	end,
	["desc"] =      {
			"Fires a cloud of deadly nexus over a radius of 7",
	}
}

-- Demonshield

DOOM_SHIELD = add_spell
{
	["name"] =      "Doom Shield",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     1,
	["mana"] =      2,
	["mana_max"] =  30,
	["fail"] =      10,
	["random"] =    0,
	["spell"] =     function()
			return set_shield(randint(10) + 20 + get_level(DOOM_SHIELD, 100), -300 + get_level(DOOM_SHIELD, 100), SHIELD_COUNTER, 1 + get_level(DOOM_SHIELD, 14), 10 + get_level(DOOM_SHIELD, 15))
	end,
	["info"] =      function()
			return "dur "..(20 + get_level(DOOM_SHIELD, 100)).."+d10 dam "..(1 + get_level(DOOM_SHIELD, 14)).."d"..(10 + get_level(DOOM_SHIELD, 15))
	end,
	["desc"] =      {
			"Raises a mirror of pain around you, doing very high damage to your foes",
			"that dare hit you, but greatly reduces your armour class",
	}
}

UNHOLY_WORD = add_spell
{
	["name"] =      "Unholy Word",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     25,
	["mana"] =      15,
	["mana_max"] =  45,
	["fail"] =      55,
	["random"] =    0,
	["spell"] =     function()
			local ret, x, y, c_ptr
			ret, x, y = tgt_pt()
			if ret == FALSE then return end
			c_ptr = cave(y, x)

			-- ok that is a monster
			if c_ptr.m_idx > 0 then
				local m_ptr = monster(c_ptr.m_idx)
				if m_ptr.status ~= MSTATUS_PET then
					msg_print("You can only target a pet.")
					return
				end

				-- Oups he is angry now
				if magik(30 - get_level(UNHOLY_WORD, 25, 0)) == TRUE then
					local m_name = monster_desc(m_ptr, 0).." turns against you."
					msg_print(strupper(strsub(m_name, 0, 1))..strsub(m_name, 2))
				else
					local m_name = monster_desc(m_ptr, 0)
					msg_print("You consume "..m_name..".")

					local heal = (m_ptr.hp * 100) / m_ptr.maxhp
					heal = ((30 + get_level(UNHOLY_WORD, 50, 0)) * heal) / 100

					hp_player(heal)

					delete_monster_idx(c_ptr.m_idx)
				end
				return TRUE
			end
	end,
	["info"] =      function()
			return "heal mhp% of "..(30 + get_level(UNHOLY_WORD, 50, 0)).."%"
	end,
	["desc"] =      {
			"Kills a pet to heal you",
			"There is a chance that the pet won't die but will turn against you",
			"it will decrease with higher level",
	}
}

DEMON_CLOAK = add_spell
{
	["name"] =      "Demon Cloak",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     20,
	["mana"] =      10,
	["mana_max"] =  40,
	["fail"] =      70,
	["random"] =    0,
	["spell"] =     function()
			return set_tim_reflect(randint(5) + 5 + get_level(DEMON_CLOAK, 15, 0))
	end,
	["info"] =      function()
			return "dur "..(5 + get_level(DEMON_CLOAK, 15, 0)).."+d5"
	end,
	["desc"] =      {
			"Raises a mirror that can reflect bolts and arrows for a time",
	}
}


-- Demonhorn
DEMON_SUMMON = add_spell
{
	["name"] =      "Summon Demon",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     5,
	["mana"] =      10,
	["mana_max"] =  50,
	["fail"] =      30,
	["random"] =    0,
	["spell"] =     function()
			local type = SUMMON_DEMON
			local level = dun_level
			local minlevel = 4
			if level < minlevel then level=minlevel end
			summon_specific_level = 5 + get_level(DEMON_SUMMON, 100)
			if get_level(DEMON_SUMMON) >= 35 then type = SUMMON_HI_DEMON end
			if summon_monster(player.py, player.px, level, TRUE, type) == TRUE then
				return TRUE
			else
				msg_print("Something blocks your summoning!")
				return FALSE
			end
	end,
	["info"] =      function()
			return "level "..(5 + get_level(DEMON_SUMMON, 100))
	end,
	["desc"] =      {
			"Summons a leveled demon to your side",
			"At level 35 it summons a high demon",
	}
}

DISCHARGE_MINION = add_spell
{
	["name"] =      "Discharge Minion",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     10,
	["mana"] =      20,
	["mana_max"] =  50,
	["fail"] =      30,
	["random"] =    0,
	["spell"] =     function()
			local ret, x, y, c_ptr
			ret, x, y = tgt_pt()
			if ret == FALSE then return end
			c_ptr = cave(y, x)

			-- ok that is a monster
			if c_ptr.m_idx > 0 then
				local m_ptr = monster(c_ptr.m_idx)
				if m_ptr.status ~= MSTATUS_PET then
					msg_print("You can only target a pet.")
					return
				end

				local dam = m_ptr.hp
				delete_monster_idx(c_ptr.m_idx)
				dam = (dam * (20 + get_level(DISCHARGE_MINION, 60, 0))) / 100
				if dam > 100 + get_level(DISCHARGE_MINION, 500, 0) then
					dam = 100 + get_level(DISCHARGE_MINION, 500, 0)
				end

				-- We use project instead of fire_ball because we must tell it exactly where to land
				return project(0, 2,
					y, x,
					dam,
					GF_GRAVITY, bor(PROJECT_STOP, PROJECT_GRID, PROJECT_ITEM, PROJECT_KILL))
			end
	end,
	["info"] =      function()
			return "dam "..(20 + get_level(DISCHARGE_MINION, 60, 0)).."% max "..(100 + get_level(DISCHARGE_MINION, 500, 0))
	end,
	["desc"] =      {
			"The targeted pet will explode in a burst of gravity",
	}
}

CONTROL_DEMON = add_spell
{
	["name"] =      "Control Demon",
	["school"] =    {SCHOOL_DEMON},
	["level"] =     25,
	["mana"] =      30,
	["mana_max"] =  70,
	["fail"] =      55,
	["random"] =    0,
	["spell"] =     function()
			local ret, dir = get_aim_dir()
			return fire_ball(GF_CONTROL_DEMON, dir, 50 + get_level(CONTROL_DEMON, 250), 0)
	end,
	["info"] =      function()
			return "power "..(50 + get_level(CONTROL_DEMON, 250))
	end,
	["desc"] =      {
			"Attempts to control a demon",
	}
}

-- ok we need to have different wield slots
add_hooks
{
	[HOOK_WIELD_SLOT] =     function (obj, ideal)
			if (obj.tval == TV_DAEMON_BOOK) then
				local slot
				if (obj.sval == SV_DEMONBLADE) then
					if(ideal == TRUE) then
						slot = INVEN_WIELD
					else
						slot = get_slot(INVEN_WIELD)
					end
				elseif (obj.sval == SV_DEMONSHIELD) then
					if(ideal == TRUE) then
						slot = INVEN_ARM
					else
						slot = get_slot(INVEN_ARM)
					end
				elseif (obj.sval == SV_DEMONHORN) then
					if(ideal == TRUE) then
						slot = INVEN_HEAD
					else
						slot = get_slot(INVEN_HEAD)
					end
				end
				return TRUE, slot
			end
	end,
}
tome-235-src/lib/scpt/s_meta.lua0000644000076400017500000001743211012107762014366 0ustar  dgdg-- handle the meta school

RECHARGE = add_spell
{
	["name"] = 	"Recharge",
	["school"] = 	{SCHOOL_META},
	["level"] = 	5,
	["mana"] = 	10,
	["mana_max"] = 	100,
	["fail"] = 	20,
	["spell"] = 	function()
			return recharge(60 + get_level(RECHARGE, 140))
	end,
	["info"] = 	function()
			return "power "..(60 + get_level(RECHARGE, 140))
	end,
	["desc"] =	{
			"Taps on the ambient mana to recharge an object's power (charges or mana)",
	}
}

function get_spellbinder_max()
	local i

	i = get_level(SPELLBINDER, 4)
	if i > 4 then i = 4 end
	return i
end
--'
SPELLBINDER = add_spell
{
	["name"] = 	"Spellbinder",
	["school"] = 	{SCHOOL_META},
	["level"] = 	20,
	["mana"] = 	100,
	["mana_max"] = 	300,
	["fail"] = 	85,
	["spell"] = 	function()
			local i, ret, c

			if player.spellbinder_num ~= 0 then
				local t =
				{
					[SPELLBINDER_HP75] = "75% HP",
					[SPELLBINDER_HP50] = "50% HP",
					[SPELLBINDER_HP25] = "25% HP",
				}
				msg_print("The spellbinder is already active.")
				msg_print("It will trigger at "..t[player.spellbinder_trigger]..".")
				msg_print("With the spells: ")
				for i = 1, player.spellbinder_num do
					msg_print(spell(player.spellbinder[i]).name)
				end
				return TRUE
			end

			ret, c = get_com("Trigger at [a]75% hp [b]50% hp [c]25% hp?", strbyte("a"))
			if ret == FALSE then return TRUE end
			
			if c == strbyte("a") then
				player.spellbinder_trigger = SPELLBINDER_HP75
			elseif c == strbyte("b") then
				player.spellbinder_trigger = SPELLBINDER_HP50
			elseif c == strbyte("c") then
				player.spellbinder_trigger = SPELLBINDER_HP25
			else
				return
			end
			player.spellbinder_num = get_spellbinder_max()
			i = player.spellbinder_num
			while i > 0 do
				local s

				s = get_school_spell("bind", "is_ok_spell", 0)
				if s == -1 then
					player.spellbinder_trigger = 0
					player.spellbinder_num = 0
					return TRUE
				else
					if spell(s).skill_level > 7 + get_level(SPELLBINDER, 35) then
						msg_print("You are only allowed spells with a base level of "..(7 + get_level(SPELLBINDER, 35))..".");
						return TRUE
					end
				end
				player.spellbinder[i] = s
				i = i - 1
			end
			player.energy = player.energy - 3100;
			msg_print("Spellbinder ready.")
			return TRUE
	end,
	["info"] = 	function()
			return "number "..(get_spellbinder_max()).." max level "..(7 + get_level(SPELLBINDER, 35))
	end,
	["desc"] =	{
			"Stores spells in a trigger.",
			"When the condition is met all spells fire off at the same time",
			"This spell takes a long time to cast so you are advised to prepare it",
			"in a safe area.",
			"Also it will use the mana for the Spellbinder and the mana for the",
			"selected spells"
	}
}

DISPERSEMAGIC = add_spell
{
	["name"] = 	"Disperse Magic",
	["school"] = 	{SCHOOL_META},
	["level"] = 	15,
	["mana"] = 	30,
	["mana_max"] = 	60,
	["fail"] = 	40,
	-- Unnafected by blindness
	["blind"] =     FALSE,
	-- Unnafected by confusion
	["confusion"] = FALSE,
	["stick"] =
	{
			["charge"] =    { 5, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		25,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 5, 40 },
			},
	},
	["inertia"] = 	{ 1, 5 },
	["spell"] = 	function()
			local obvious
			obvious = set_blind(0)
			obvious = is_obvious(set_lite(0), obvious)
			if get_level(DISPERSEMAGIC, 50) >= 5 then
				obvious = is_obvious(set_confused(0), obvious)
				obvious = is_obvious(set_image(0), obvious)
			end
			if get_level(DISPERSEMAGIC, 50) >= 10 then
				obvious = is_obvious(set_slow(0), obvious)
				obvious = is_obvious(set_fast(0, 0), obvious)
				obvious = is_obvious(set_light_speed(0), obvious)
			end
			if get_level(DISPERSEMAGIC, 50) >= 15 then
				obvious = is_obvious(set_stun(0), obvious)
				obvious = is_obvious(set_meditation(0), obvious)
				obvious = is_obvious(set_cut(0), obvious)
			end
			if get_level(DISPERSEMAGIC, 50) >= 20 then
				obvious = is_obvious(set_hero(0), obvious)
				obvious = is_obvious(set_shero(0), obvious)
				obvious = is_obvious(set_blessed(0), obvious)
				obvious = is_obvious(set_shield(0, 0, 0, 0, 0), obvious)
				obvious = is_obvious(set_afraid(0), obvious)
				obvious = is_obvious(set_parasite(0, 0), obvious)
				obvious = is_obvious(set_mimic(0, 0, 0), obvious)
			end
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Dispels a lot of magic that can affect you, be it good or bad",
			"Level 1: blindness and light",
			"Level 5: confusion and hallucination",
			"Level 10: speed (both bad or good) and light speed",
			"Level 15: stunning, meditation, cuts",
			"Level 20: hero, super hero, bless, shields, afraid, parasites, mimicry",
	}
}

TRACKER = add_spell
{
	["name"] = 	"Tracker",
	["school"] = 	{SCHOOL_META, SCHOOL_CONVEYANCE},
	["level"] = 	30,
	["mana"] = 	50,
	["mana_max"] = 	50,
	["fail"] = 	95,
	["spell"] = 	function()
			if last_teleportation_y == -1 then
				msg_print("There has not been any teleporatation here.")
				return TRUE
			end
			teleport_player_to(last_teleportation_y, last_teleportation_x)
			return TRUE
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Tracks down the last teleportation that happened on the level and teleports",
			"you to it",
	}
}

-- Saves the values of the timer
save_timer("TIMER_INERTIA_CONTROL")
add_loadsave("player.inertia_controlled_spell", -1)
player.inertia_controlled_spell = -1

-- Automatically cast the inertia controlled spells
TIMER_INERTIA_CONTROL = new_timer
{
	["enabled"] = FALSE,
	["delay"] = 10,
	["callback"] = function()
		-- Don't cast a controlled spell in wilderness mode
		if player.antimagic then
			msg_print("Your anti-magic field disrupts any magic attempts.")
		elseif player.anti_magic then
			msg_print("Your anti-magic shell disrupts any magic attempts.")
		elseif (player.inertia_controlled_spell ~= -1) and (player.wild_mode == FALSE) then
			__spell_spell[player.inertia_controlled_spell]()
		end
	end,
}

stop_inertia_controlled_spell = function()
	player.inertia_controlled_spell = -1
	TIMER_INERTIA_CONTROL.enabled = FALSE
	player.update = bor(player.update, PU_MANA)
	return TRUE
end

add_hooks
{
	-- Reduce the mana by four times the cost of the spell
	[HOOK_CALC_MANA] = function(msp)
		if player.inertia_controlled_spell ~= -1 then
			msp = msp - (get_mana(player.inertia_controlled_spell) * 4)
			if msp < 0 then msp = 0 end
			return TRUE, msp
		end
	end,

	-- Stop a previous spell at birth
	[HOOK_BIRTH_OBJECTS] = function()
		stop_inertia_controlled_spell()
	end,
}

INERTIA_CONTROL = add_spell
{
	["name"] = 	"Inertia Control",
	["school"] = 	{SCHOOL_META},
	["level"] = 	37,
	["mana"] = 	300,
	["mana_max"] = 	700,
	["fail"] = 	95,
	["spell"] = 	function()
			if player.inertia_controlled_spell ~= -1 then
				msg_print("You cancel your inertia flow control.")
				return stop_inertia_controlled_spell()
			end

			local s = get_school_spell("control", "is_ok_spell", 0)
			if s == -1 then
				return stop_inertia_controlled_spell()
			end

			local inertia = __tmp_spells[s].inertia

			if inertia == nil then
				msg_print("This spell inertia flow can not be controlled.")
				return stop_inertia_controlled_spell()
			end
			if inertia[1] > get_level(INERTIA_CONTROL, 10) then
				msg_print("This spell inertia flow("..inertia[1]..") is too strong to be controlled by your current spell.")
				return stop_inertia_controlled_spell()
			end

			player.inertia_controlled_spell = s
			TIMER_INERTIA_CONTROL.enabled = TRUE
			TIMER_INERTIA_CONTROL.delay = inertia[2]
			TIMER_INERTIA_CONTROL.countdown = TIMER_INERTIA_CONTROL.delay
			player.update = bor(player.update, PU_MANA)
			msg_print("Inertia flow controlling spell "..spell(s).name..".")
			return TRUE
	end,
	["info"] = 	function()
			return "level "..get_level(INERTIA_CONTROL, 10)
	end,
	["desc"] = 	{
			"Changes the energy flow of a spell to be continuously recasted",
			"at a given interval. The inertia controlled spell reduces your",
			"maximum mana by four times its cost.",
	}
}
tome-235-src/lib/scpt/spells.lua0000644000076400017500000002244411012107762014417 0ustar  dgdg--
-- This file takes care of the schools of magic
--

-- Create the schools
SCHOOL_MANA = add_school
{
	["name"] = "Mana", 
	["skill"] = SKILL_MANA,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Eru Iluvatar provides the Mana school at half the prayer skill
		[GOD_ERU] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 2,
		},
	},
	["hooks"] =
	{
		[HOOK_CALC_MANA] = function(msp)
			if get_skill(SKILL_MANA) >= 35 then
				msp = msp + (msp * ((get_skill(SKILL_MANA) - 34)) / 100)
				return TRUE, msp
			end
		end
	},
}
SCHOOL_FIRE = add_school
{
	["name"] = "Fire", 
	["skill"] = SKILL_FIRE,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
}
SCHOOL_AIR = add_school
{
	["name"] = "Air", 
	["skill"] = SKILL_AIR,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["hooks"] =
	{
		[HOOK_CALC_BONUS] = function()
			if get_skill(SKILL_AIR) >= 50 then
				player.magical_breath = TRUE
			end
		end,
	},
	["gods"] =
	{
		-- Manwe Sulimo provides the Air school at 2/3 the prayer skill
		[GOD_MANWE] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 2,
			["div"] = 3,
		},
	},
}
SCHOOL_WATER = add_school
{
	["name"] = "Water", 
	["skill"] = SKILL_WATER,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["hooks"] =
	{
		[HOOK_CALC_BONUS] = function()
			if get_skill(SKILL_WATER) >= 30 then
				player.water_breath = TRUE
			end
		end,
	},
	["gods"] =
	{
		-- Yavanna Kementari provides the Water school at 1/2 the prayer skill
		[GOD_YAVANNA] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 2,
		},
	},
}
SCHOOL_EARTH = add_school
{
	["name"] = "Earth", 
	["skill"] = SKILL_EARTH,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Tulkas provides the Earth school at 4/5 the prayer skill
		[GOD_TULKAS] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 4,
			["div"] = 5,
		},
		-- Yavanna Kementari provides the Earth school at 1/2 the prayer skill
		[GOD_YAVANNA] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 2,
		},
	},
}
SCHOOL_CONVEYANCE = add_school
{
	["name"] = "Conveyance", 
	["skill"] = SKILL_CONVEYANCE,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Manwe Sulimo provides the Conveyance school at 1/2 the prayer skill
		[GOD_MANWE] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 2,
		},
	},
}
SCHOOL_GEOMANCY = add_school
{
	["name"] = "Geomancy",
	["skill"] = SKILL_GEOMANCY,
	["spell_power"] = TRUE,
	-- Require to wield a Mage Staff, as the spells requries the caster to stomp the floor with it
	["depend"] = function()
		-- Require at least one point in each school
		if get_skill(SKILL_FIRE) == 0 then return end
		if get_skill(SKILL_AIR) == 0 then return end
		if get_skill(SKILL_EARTH) == 0 then return end
		if get_skill(SKILL_WATER) == 0 then return end

		local obj = get_object(INVEN_WIELD)
		if (obj.k_idx > 0) and (obj.tval == TV_MSTAFF) then return TRUE end
	end,
}
SCHOOL_DIVINATION = add_school
{
	["name"] = "Divination", 
	["skill"] = SKILL_DIVINATION,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Eru Iluvatar provides the Divination school at 2/3 the prayer skill
		[GOD_ERU] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 2,
			["div"] = 3,
		},
	},
}
SCHOOL_TEMPORAL = add_school
{
	["name"] = "Temporal", 
	["skill"] = SKILL_TEMPORAL,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Yavanna Kementari provides the Temoral school at 1/6 the prayer skill
		[GOD_YAVANNA] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 6,
		},
	},
}
SCHOOL_NATURE = add_school
{
	["name"] = "Nature", 
	["skill"] = SKILL_NATURE,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Yavanna Kementari provides the Nature school at 1/2 the prayer skill
		[GOD_YAVANNA] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 2,
		},
	},
}
SCHOOL_META = add_school
{
	["name"] = "Meta", 
	["skill"] = SKILL_META,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Manwe Sulimo provides the Meta school at 1/3 the prayer skill
		[GOD_MANWE] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 3,
		},
	},
}
SCHOOL_MIND = add_school
{
	["name"] = "Mind",
	["skill"] = SKILL_MIND,
	["spell_power"] = TRUE,
	["sorcery"] = TRUE,
	["gods"] =
	{
		-- Eru Iluvatar provides the Mind school at 1/3 the prayer skill
		[GOD_ERU] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 3,
		},
		-- Melkor Bauglir provides the Mind school at 1/3 the prayer skill
		[GOD_MELKOR] =
		{
			["skill"] = SKILL_PRAY,
			["mul"] = 1,
			["div"] = 3,
		},
	},
}
SCHOOL_UDUN = add_school
{
	["name"] = 		"Udun",
	["skill"] = 		SKILL_UDUN,
	["bonus_level"] = 	function()
					return ((player.lev * 2) / 3)
				end,
}
SCHOOL_DEMON = add_school
{
	["name"] = "Demon",
	["skill"] = SKILL_DAEMON,
	["no_random"] = TRUE,
}

-- The God specific schools, all tied to the prayer skill
SCHOOL_ERU = add_school
{
	["name"] = "Eru Iluvatar",
	["skill"] = SKILL_PRAY,
	["spell_power"] = TRUE,
	["god"] = GOD_ERU,
}
SCHOOL_MANWE = add_school
{
	["name"] = "Manwe Sulimo",
	["skill"] = SKILL_PRAY,
	["spell_power"] = TRUE,
	["god"] = GOD_MANWE,
}
SCHOOL_TULKAS = add_school
{
	["name"] = "Tulkas",
	["skill"] = SKILL_PRAY,
	["spell_power"] = TRUE,
	["god"] = GOD_TULKAS,
}
SCHOOL_MELKOR = add_school
{
	["name"] = "Melkor Bauglir",
	["skill"] = SKILL_PRAY,
	["spell_power"] = TRUE,
	["god"] = GOD_MELKOR,
}
SCHOOL_YAVANNA = add_school
{
	["name"] = "Yavanna Kementari",
	["skill"] = SKILL_PRAY,
	["spell_power"] = TRUE,
	["god"] = GOD_YAVANNA,
}

-- Not a real school, rather a palcehodler for stick only spells
SCHOOL_DEVICE = add_school
{
	["name"] = "Device",
	["skill"] = SKILL_DEVICE,
}

-- Music "spells"
SCHOOL_MUSIC = add_school
{
	["name"] = "Music",
	["skill"] = SKILL_MUSIC,
}

-- Put some spells
tome_dofile("s_fire.lua")
tome_dofile("s_mana.lua")
tome_dofile("s_water.lua")
tome_dofile("s_air.lua")
tome_dofile("s_earth.lua")
tome_dofile("s_convey.lua")
tome_dofile("s_nature.lua")
tome_dofile("s_divin.lua")
tome_dofile("s_tempo.lua")
tome_dofile("s_meta.lua")
tome_dofile("s_mind.lua")
tome_dofile("s_udun.lua")
tome_dofile("s_geom.lua")

-- God's specific spells
tome_dofile("s_eru.lua")
tome_dofile("s_manwe.lua")
tome_dofile("s_tulkas.lua")
tome_dofile("s_melkor.lua")
tome_dofile("s_yavann.lua")

-- Specific schools
tome_dofile("s_demon.lua")

-- Device spells
tome_dofile("s_stick.lua")

-- Musics
tome_dofile("s_music.lua")

-- List of spellbooks

-- Create the crystal of mana
school_book[0] = {
	MANATHRUST, DELCURSES, RESISTS, MANASHIELD,
}

-- The book of the eternal flame
school_book[1] = {
	GLOBELIGHT, FIREGOLEM, FIREFLASH, FIREWALL, FIERYAURA,
}

-- The book of the blowing winds
school_book[2] = {
	NOXIOUSCLOUD, POISONBLOOD, INVISIBILITY, STERILIZE, AIRWINGS, THUNDERSTORM,
}

-- The book of the impenetrable earth
school_book[3] = {
	STONESKIN, DIG, STONEPRISON, SHAKE, STRIKE,
}

-- The book of the unstopable wave
school_book[4] = {
	GEYSER, VAPOR, ENTPOTION, TIDALWAVE, ICESTORM
}

-- Create the book of translocation
school_book[5] = {
	BLINK, DISARM, TELEPORT, TELEAWAY, RECALL, PROBABILITY_TRAVEL,
}

-- Create the book of the tree
school_book[6] = {
	GROWTREE, HEALING, RECOVERY, REGENERATION, SUMMONANNIMAL,
}

-- Create the book of Knowledge
school_book[7] = {
	SENSEMONSTERS, SENSEHIDDEN, REVEALWAYS, IDENTIFY, VISION, STARIDENTIFY,
}

-- Create the book of the Time
school_book[8] = {
	MAGELOCK, SLOWMONSTER, ESSENCESPEED, BANISHMENT,
}

-- Create the book of meta spells
school_book[9] = {
	RECHARGE, DISPERSEMAGIC, SPELLBINDER, TRACKER, INERTIA_CONTROL,
}

-- Create the book of the mind
school_book[10] = {
	CHARM, CONFUSE, ARMOROFFEAR, STUN,
}

-- Create the book of hellflame
school_book[11] = {
	DRAIN, GENOCIDE, WRAITHFORM, FLAMEOFUDUN,
}

-- Create the book of eru
school_book[20] = {
	ERU_SEE, ERU_LISTEN, ERU_UNDERSTAND, ERU_PROT,
}

-- Create the book of manwe
school_book[21] = {
	MANWE_BLESS, MANWE_SHIELD, MANWE_CALL, MANWE_AVATAR,
}

-- Create the book of tulkas
school_book[22] = {
	TULKAS_AIM, TULKAS_SPIN, TULKAS_WAVE,
}

-- Create the book of melkor
school_book[23] = {
	MELKOR_CURSE, MELKOR_CORPSE_EXPLOSION, MELKOR_MIND_STEAL,
}

-- Create the book of yavanna
school_book[24] = {
	YAVANNA_CHARM_ANIMAL, YAVANNA_GROW_GRASS, YAVANNA_TREE_ROOTS, YAVANNA_WATER_BITE, YAVANNA_UPROOT,
}

-- Create the book of beginner's cantrip
school_book[50] = {
	MANATHRUST, GLOBELIGHT, ENTPOTION, BLINK, SENSEMONSTERS, SENSEHIDDEN,
}

-- Create the book of teleporatation
school_book[51] = {
	BLINK, TELEPORT, TELEAWAY
}

-- Create the book of summoning
school_book[52] = {
	FIREGOLEM, SUMMONANNIMAL
}


-- Create the Armageddon Demonblade
school_book[55] = {
	DEMON_BLADE, DEMON_MADNESS, DEMON_FIELD,
}

-- Create the Shield Demonblade
school_book[56] = {
	DOOM_SHIELD, DEMON_CLOAK, UNHOLY_WORD,
}

-- Create the Control Demonblade
school_book[57] = {
	DEMON_SUMMON, DISCHARGE_MINION, CONTROL_DEMON,
}

-- Create the Drums
school_book[58] = {
	MUSIC_STOP, MUSIC_HOLD, MUSIC_CONF, MUSIC_STUN, 
}

-- Create the Harps
school_book[59] = {
	MUSIC_STOP, MUSIC_LITE, MUSIC_HERO, MUSIC_HEAL, MUSIC_TIME, MUSIC_MIND,
}

-- Create the Horns
school_book[60] = {
	MUSIC_STOP, MUSIC_BLOW, MUSIC_WIND, MUSIC_YLMIR, MUSIC_AMBARKANTA,
}

-- Book of the Player, filled in by the Library Quest
school_book[61] = { }

-- Geomancy spells, not a real book
school_book[62] = {
	CALL_THE_ELEMENTS, CHANNEL_ELEMENTS, ELEMENTAL_WAVE, VAPORIZE, GEOLYSIS, DRIPPING_TREAD, GROW_BARRIER, ELEMENTAL_MINION
}
tome-235-src/lib/scpt/s_nature.lua0000644000076400017500000000707611012107762014741 0ustar  dgdg-- handle the nature school

GROWTREE = add_spell
{
	["name"] = 	"Grow Trees",
	["school"] = 	{SCHOOL_NATURE, SCHOOL_TEMPORAL},
	["level"] = 	6,
	["mana"] = 	6,
	["mana_max"] = 	30,
	["fail"] = 	35,
	["inertia"] = 	{ 5, 50 },
	["spell"] = 	function()
			grow_trees(2 + get_level(GROWTREE, 7))
			return TRUE
	end,
	["info"] = 	function()
			return "rad "..(2 + get_level(GROWTREE, 7))
	end,
	["desc"] =	{
			"Makes trees grow extremely quickly around you",
	}
}

HEALING = add_spell
{
	["name"] = 	"Healing",
	["school"] = 	{SCHOOL_NATURE},
	["level"] = 	10,
	["mana"] = 	15,
	["mana_max"] = 	50,
	["fail"] = 	45,
	["stick"] =
	{
			["charge"] =    { 2, 3 },
			[TV_STAFF] =
			{
				["rarity"] = 		90,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 20, 40 },
			},
	},
	["spell"] = 	function()
			return hp_player(player.mhp * (15 + get_level(HEALING, 35)) / 100)
	end,
	["info"] = 	function()
			return "heal "..(15 + get_level(HEALING, 35)).."% = "..(player.mhp * (15 + get_level(HEALING, 35)) / 100).."hp"
	end,
	["desc"] =	{
			"Heals a percent of hitpoints",
	}
}

RECOVERY = add_spell
{
	["name"] = 	"Recovery",
	["school"] = 	{SCHOOL_NATURE},
	["level"] = 	15,
	["mana"] = 	10,
	["mana_max"] = 	25,
	["fail"] = 	60,
	["stick"] =
	{
			["charge"] =    { 5, 10 },
			[TV_STAFF] =
			{
				["rarity"] = 		50,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 10, 30 },
			},
	},
	["inertia"] = 	{ 2, 100 },
	["spell"] = 	function()
			local obvious
			obvious = set_poisoned(player.poisoned / 2)
			if get_level(RECOVERY, 50) >= 5 then
				obvious = is_obvious(set_poisoned(0), obvious)
				obvious = is_obvious(set_cut(0), obvious)
			end
			if get_level(RECOVERY, 50) >= 10 then
				obvious = is_obvious(do_res_stat(A_STR, TRUE), obvious)
				obvious = is_obvious(do_res_stat(A_CON, TRUE), obvious)
				obvious = is_obvious(do_res_stat(A_DEX, TRUE), obvious)
				obvious = is_obvious(do_res_stat(A_WIS, TRUE), obvious)
				obvious = is_obvious(do_res_stat(A_INT, TRUE), obvious)
				obvious = is_obvious(do_res_stat(A_CHR, TRUE), obvious)
			end
			if get_level(RECOVERY, 50) >= 15 then
				obvious = is_obvious(restore_level(), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
			return ""
	end,
	["desc"] =	{
			"Reduces the length of time that you are poisoned",
			"At level 5 it cures poison and cuts",
			"At level 10 it restores drained stats",
			"At level 15 it restores lost experience"
	}
}

REGENERATION = add_spell
{
	["name"] = 	"Regeneration",
	["school"] = 	{SCHOOL_NATURE},
	["level"] = 	20,
	["mana"] = 	30,
	["mana_max"] = 	55,
	["fail"] = 	70,
	["inertia"] = 	{ 4, 40 },
	["spell"] = 	function()
			if player.tim_regen == 0 then return set_tim_regen(randint(10) + 5 + get_level(REGENERATION, 50), 300 + get_level(REGENERATION, 700)) end
	end,
	["info"] = 	function()
			return "dur "..(5 + get_level(REGENERATION, 50)).."+d10 power "..(300 + get_level(REGENERATION, 700))
	end,
	["desc"] =	{
			"Increases your body's regeneration rate",
	}
}


SUMMONANNIMAL = add_spell
{
	["name"] =      "Summon Animal",
	["school"] = 	{SCHOOL_NATURE},
	["level"] = 	25,
	["mana"] = 	25,
	["mana_max"] = 	50,
	["fail"] = 	90,
	["stick"] =
	{
			["charge"] =    { 1, 3 },
			[TV_WAND] =
			{
				["rarity"] = 		85,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 15, 45 },
			},
	},
	["spell"] = 	function()
			summon_specific_level = 25 + get_level(SUMMONANNIMAL, 50)
			return summon_monster(player.py, player.px, dun_level, TRUE, SUMMON_ANIMAL)
	end,
	["info"] = 	function()
			return "level "..(25 + get_level(SUMMONANNIMAL, 50))
	end,
	["desc"] =	{
			"Summons a leveled animal to your aid",
	}
}
tome-235-src/lib/scpt/stores.lua0000644000076400017500000000642611012107762014436 0ustar  dgdg-- Whats shops can buy what
store_buy_list
{
	["General Store"] =
	{
		TV_CORPSE,
		TV_FOOD,
		TV_LITE,
		TV_FLASK,
		TV_SPIKE,
		TV_SHOT,
		TV_ARROW,
		TV_BOLT,
		TV_DIGGING,
		TV_CLOAK,
		TV_BOTTLE,
	},
	["Armoury"] =
	{
		TV_BOOTS,
		TV_GLOVES,
		TV_CROWN,
		TV_HELM,
		TV_SHIELD,
		TV_CLOAK,
		TV_SOFT_ARMOR,
		TV_HARD_ARMOR,
		TV_DRAG_ARMOR,
	},
	["Weaponsmith"] =
	{
		TV_SHOT,
		TV_BOLT,
		TV_ARROW,
		TV_BOOMERANG,
		TV_BOW,
		TV_DIGGING,
		TV_HAFTED,
		TV_POLEARM,
		TV_SWORD,
		TV_AXE,
		TV_MSTAFF,
	},
	-- We use a function because we want to restrict to blessed weapons and god spells
	["Temple"] = function (obj)
		if obj.tval == TV_DRUID_BOOK then return TRUE
		elseif obj.tval == TV_BOOK and obj.sval == 255 and (can_spell_random(obj.pval) == SKILL_SPIRITUALITY) then return TRUE
		elseif obj.tval == TV_SCROLL then return TRUE
		elseif obj.tval == TV_POTION2 then return TRUE
		elseif obj.tval == TV_POTION then return TRUE
		elseif obj.tval == TV_HAFTED then return TRUE
		elseif obj.tval == TV_POLEARM and is_blessed(obj) == TRUE then return TRUE
		elseif obj.tval == TV_SWORD and is_blessed(obj) == TRUE then return TRUE
		elseif obj.tval == TV_AXE and is_blessed(obj) == TRUE then return TRUE
		elseif obj.tval == TV_BOOMERANG and is_blessed(obj) == TRUE then return TRUE
		end
	end,
	["Alchemy shop"] =
	{
		TV_SCROLL,
		TV_POTION2,
		TV_POTION,
		TV_BATERIE,
		TV_BOTTLE,
	},
	-- We use a function because we dont want god spells
	["Magic shop"] = function (obj)
		local buy =
		{
			[TV_SYMBIOTIC_BOOK] = TRUE,
			[TV_AMULET] = TRUE,
			[TV_RING] = TRUE,
			[TV_STAFF] = TRUE,
			[TV_WAND] = TRUE,
			[TV_ROD] = TRUE,
			[TV_ROD_MAIN] = TRUE,
			[TV_SCROLL] = TRUE,
			[TV_POTION2] = TRUE,
			[TV_POTION] = TRUE,
			[TV_MSTAFF] = TRUE,
			[TV_RANDART] = TRUE,
		}

		if obj.tval == TV_BOOK and obj.sval == 255 and (can_spell_random(obj.pval) == SKILL_MAGIC) then return TRUE
		elseif obj.tval == TV_BOOK and obj.sval ~= 255 then return TRUE
		elseif buy[obj.tval] == TRUE then return TRUE
		end
	end,
	-- Black markets wants ALL!
	["Black Market"] = function (obj)
		return TRUE
	end,
	["Book Store"] =
	{
		TV_BOOK,
		TV_SYMBIOTIC_BOOK,
		TV_MUSIC_BOOK,
		TV_DAEMON_BOOK,
		TV_DRUID_BOOK,
	},
	["Pet Shop"] =
	{
		TV_EGG,
	},
}

-- Test only
function out_sticks()
	local i
	for i = 0, __tmp_spells_num - 1 do
		if __tmp_spells[i].stick then
			if __tmp_spells[i].stick[TV_WAND] then
				print("Wand: " .. __tmp_spells[i].name)
			end
		end
	end
	for i = 0, __tmp_spells_num - 1 do
		if __tmp_spells[i].stick then
			if __tmp_spells[i].stick[TV_STAFF] then
				print("Staff: " .. __tmp_spells[i].name)
			end
		end
	end
end

-- Take care to have Magic shop/Temple have specific spells only
add_hooks
{
	[HOOK_STORE_STOCK] = function (index, name, level)
			if name == "Magic shop" then
				-- Books
				if magik(20) == TRUE then
					object_prep(obj_forge, lookup_kind(TV_BOOK, 255))
					local spell = get_random_spell(SKILL_MAGIC, 20)
					if spell > -1 then
						obj_forge.pval = spell
						return TRUE, obj_forge
					end
				end
			elseif name == "Temple" then
				if magik(20) == TRUE then
					object_prep(obj_forge, lookup_kind(TV_BOOK, 255))
					local spell = get_random_spell(SKILL_SPIRITUALITY, 20)
					if spell > -1 then
						obj_forge.pval = spell
						return TRUE, obj_forge
					end
				end
			end
	end,
}
tome-235-src/lib/scpt/gods.lua0000644000076400017500000000113111012107762014037 0ustar  dgdgadd_hooks
{
	[HOOK_FOLLOW_GOD] = function(god, action)
		if action == "ask" then
			if not (god == GOD_MELKOR) then
				local i = INVEN_WIELD
				while i < INVEN_TOTAL do
					-- 13 is ART_POWER
					if player.inventory(i).name1 == 13 then
						msg_print("The One Ring has corrupted you, and you are rejected.")
						return TRUE
					end
					i = i + 1
				end
			end
		end
		return FALSE
	end,
	[HOOK_RECALC_SKILLS] = function()
		if not (player.pgod == GOD_NONE) and (get_skill(SKILL_ANTIMAGIC) > 0) then
			msg_print("You no longer believe.")
			abandon_god(GOD_ALL)
		end
		return FALSE
	end,
}
tome-235-src/lib/scpt/bounty.lua0000644000076400017500000000512111012107762014426 0ustar  dgdg-- The bounty quest! bring back corpses to increase your monster lore skill

add_quest
{
	["global"] =    "BOUNTY_QUEST",
	["name"] =      "Bounty quest",
	["desc"] =      function()
		if quest(BOUNTY_QUEST).status == QUEST_STATUS_TAKEN then
			print_hook("#####yBounty quest!\n")
			print_hook("You must bring back "..monster_race_desc(bounty_quest_monster, 0).." corpse to the beastmaster.\n")
			print_hook("\n")
		end
	end,
	["level"] =     -1,
	["data"] =      {
			["bounty_quest_monster"] = 0,
	},
	["hooks"] =     {
		-- Start the game without the quest, need to request it
		[HOOK_BIRTH_OBJECTS] = function()
			quest(BOUNTY_QUEST).status = QUEST_STATUS_UNTAKEN
		end,
	},
}

add_building_action
{
	-- Index is used in ba_info.txt to set the actions
	["index"] =     54,
	["action"] =    function()
		if quest(BOUNTY_QUEST).status == QUEST_STATUS_UNTAKEN then
			quest(BOUNTY_QUEST).status = QUEST_STATUS_TAKEN
			bounty_quest_monster = get_new_bounty_monster(3 + ((player.lev * 3) / 2))

			msg_print("You must bring me back "..monster_race_desc(bounty_quest_monster, 0).." corpse.")
		else
			msg_print("You still must bring me back "..monster_race_desc(bounty_quest_monster, 0).." corpse.")
		end
	end
}

add_building_action
{
	-- Index is used in ba_info.txt to set the actions
	["index"] =     55,
	["action"] =    function()
		if quest(BOUNTY_QUEST).status == QUEST_STATUS_TAKEN then
			local ret, item
	
			-- Ask for an item
			ret, item = get_item("What corpse to return?",
					     "You have no corpse to return.",
					     bor(USE_INVEN),
					     function (obj)
					     	if (obj.tval == TV_CORPSE) and (obj.pval2 == bounty_quest_monster) then
							return TRUE
						end
						return FALSE
					     end
			)

			-- Ok we got the corpse!
			if ret == TRUE then
				-- Take the corpse from the inventory
				inven_item_increase(item, -1)
				inven_item_optimize(item)

				msg_print("Ah well done adventurer!")
				msg_print("As a reward I will teach you a bit of monster lore.")

				if skill(SKILL_LORE).mod == 0 then
					skill(SKILL_LORE).mod = 900
					skill(SKILL_LORE).dev = TRUE
				end
				skill(SKILL_LORE).value = skill(SKILL_LORE).value + skill(SKILL_LORE).mod
				if skill(SKILL_PRESERVATION).mod == 0 then
					skill(SKILL_PRESERVATION).value = 800
					skill(SKILL_PRESERVATION).mod = 800
					skill(SKILL_PRESERVATION).dev = TRUE
					msg_print("I see you don't know the corpse preservation skill, I shall teach you it too.")
				end

				quest(BOUNTY_QUEST).status = QUEST_STATUS_UNTAKEN
				bounty_quest_monster = 0
			end
		else
			msg_print("You do not have any bounty quest yet.")
		end
	end
}
tome-235-src/lib/scpt/s_yavann.lua0000644000076400017500000001037211012107762014730 0ustar  dgdg-- Handle Yavanna kementari magic school

YAVANNA_CHARM_ANIMAL = add_spell
{
	["name"] =      "Charm Animal",
	["school"] =    {SCHOOL_YAVANNA},
	["level"] =     1,
	["mana"] =      10,
	["mana_max"] =  100,
	["fail"] =      30,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] =    SKILL_SPIRITUALITY,
	["spell"] =     function()
			local ret, dir = get_aim_dir()
			if ret == FALSE then return end

			return fire_ball(GF_CONTROL_ANIMAL, dir, 10 + get_level(YAVANNA_CHARM_ANIMAL, 170), get_level(YAVANNA_CHARM_ANIMAL, 2))
	end,
	["info"] =      function()
			return "power "..(10 + get_level(YAVANNA_CHARM_ANIMAL, 170)).." rad "..(get_level(YAVANNA_CHARM_ANIMAL, 2))
	end,
	["desc"] =      {
			"It tries to tame an animal",
	}
}

YAVANNA_GROW_GRASS = add_spell
{
	["name"] =      "Grow Grass",
	["school"] =    {SCHOOL_YAVANNA},
	["level"] =     10,
	["mana"] =      70,
	["mana_max"] =  150,
	["fail"] =      65,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] =    SKILL_SPIRITUALITY,
	["spell"] =     function()
			grow_grass(get_level(YAVANNA_GROW_GRASS, 4))
			return TRUE
	end,
	["info"] =      function()
			return "rad "..(get_level(YAVANNA_GROW_GRASS, 4))
	end,
	["desc"] =      {
			"Create a floor of grass around you. While on grass and praying",
			"a worshipper of Yavanna will know a greater regeneration rate"
	}
}

YAVANNA_TREE_ROOTS = add_spell
{
	["name"] =      "Tree Roots",
	["school"] =    {SCHOOL_YAVANNA},
	["level"] =     15,
	["mana"] =      50,
	["mana_max"] =  1000,
	["fail"] =      70,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] =    SKILL_SPIRITUALITY,
	["spell"] =     function()
			return set_roots(10 + get_level(YAVANNA_TREE_ROOTS, 30), 10 + get_level(YAVANNA_TREE_ROOTS, 60), 10 + get_level(YAVANNA_TREE_ROOTS, 20))
	end,
	["info"] =      function()
			return "dur "..(10 + get_level(YAVANNA_TREE_ROOTS, 30)).." AC "..(10 + get_level(YAVANNA_TREE_ROOTS, 60)).." dam "..(10 + get_level(YAVANNA_TREE_ROOTS, 20))
	end,
	["desc"] =      {
			"Creates roots deep in the floor from your feet, making you more stable and able",
			"to make stronger attacks, but prevents any movement (even teleportation).",
			"It also makes you recover from stunning almost immediately."
	}
}

YAVANNA_WATER_BITE = add_spell
{
	["name"] =      "Water Bite",
	["school"] =    {SCHOOL_YAVANNA},
	["level"] =     20,
	["mana"] =      150,
	["mana_max"] =  300,
	["fail"] =      90,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] =    SKILL_SPIRITUALITY,
	["spell"] =     function()
			local rad

			rad = 0
			if get_level(YAVANNA_WATER_BITE) >= 25 then rad = 1 end

			return set_project(randint(30) + 30 + get_level(YAVANNA_WATER_BITE, 150),
				    GF_WATER,
				    10 + get_level(YAVANNA_WATER_BITE),
				    rad,
				    bor(PROJECT_STOP, PROJECT_KILL))
	end,
	["info"] =      function()
			return "dur "..(30 + get_level(YAVANNA_WATER_BITE, 150)).."+d30 dam "..(10 + get_level(YAVANNA_WATER_BITE)).."/blow"
	end,
	["desc"] =      {
			"Imbues your melee weapon with a natural stream of water",
			"At level 25, it spreads over a 1 radius zone around your target"
	}
}

YAVANNA_UPROOT = add_spell
{
	["name"] =      "Uproot",
	["school"] =    {SCHOOL_YAVANNA},
	["level"] =     35,
	["mana"] =      250,
	["mana_max"] =  350,
	["fail"] =      95,
	-- Uses piety to cast
	["piety"] =     TRUE,
	["stat"] =      A_WIS,
	["random"] =    SKILL_SPIRITUALITY,
	["spell"] =     function()
			local m_idx, x, y, c_ptr, ret, dir

			ret, dir = get_rep_dir()
			if ret == FALSE then return end
			y, x = explode_dir(dir)
			y, x = y + player.py, x + player.px
			c_ptr = cave(y, x)

			if c_ptr.feat == FEAT_TREES then
				cave_set_feat(y, x, FEAT_GRASS);

				-- Summon it
				y, x = find_position(y, x)
				m_idx = place_monster_one(y, x, test_monster_name("Ent"), 0, FALSE, MSTATUS_FRIEND)

				-- level it
				if m_idx ~= 0 then
					monster_set_level(m_idx, 30 + get_level(YAVANNA_UPROOT, 70))
				end

				msg_print("The tree awakes!");
			else
				msg_print("There is no tree there.")
			end
			return TRUE
	end,
	["info"] =      function()
			return "lev "..(30 + get_level(YAVANNA_UPROOT, 70))
	end,
	["desc"] =      {
			"Awakes a tree to help you battle the forces of Morgoth",
	}
}
tome-235-src/lib/scpt/drunk.lua0000644000076400017500000000102411012107762014227 0ustar  dgdg-- silly function that allows a drunk to take a bottle of wine/ale from the player

function drunk_takes_wine(m_idx, item)

	m_ptr = monster(m_idx)
	o_ptr = get_object(item)

	if (m_ptr.r_idx == test_monster_name("Singing, happy drunk")) 
			and (o_ptr.tval == TV_FOOD) and ((o_ptr.sval == 38) or (o_ptr.sval == 39)) then

		cmsg_print(TERM_YELLOW, "'Hic!'")

		inven_item_increase(item, -1)
		inven_item_optimize(item)
		return TRUE
	else
		return FALSE
	end
end

add_hook_script(HOOK_GIVE, "drunk_takes_wine", "drunk_takes_wine")
tome-235-src/lib/scpt/init.lua0000644000076400017500000000162111012107762014052 0ustar  dgdg--
-- This file is loaded at the initialisation of ToME
--

-- Load the class specific stuff
tome_dofile("player.lua")

-- Load the ingame contextual help
tome_dofile("help.lua")

-- let the store specific stuff happen!
tome_dofile("stores.lua")

-- Add various 'U' powers
tome_dofile("powers.lua")

-- Add the mimic shapes
tome_dofile("mimic.lua")

-- Add the corruptions
tome_dofile("corrupt.lua")

-- Add the mkey activations
tome_dofile("mkeys.lua")

-- Add the schools of magic
tome_dofile("spells.lua")

-- Add god stuff
tome_dofile("gods.lua")

-- Add some quests
tome_dofile("bounty.lua")
tome_dofile("god.lua")
tome_dofile("fireprof.lua")
tome_dofile("library.lua")

-- Add joke stuff
tome_dofile("drunk.lua")
tome_dofile("joke.lua")

-- Some tests, if the file is not present, this is fine
tome_dofile_anywhere(ANGBAND_DIR_SCPT, "dg_test.lua", FALSE)

-- A nice custom intro :)
tome_dofile("intro.lua")
tome-235-src/lib/scpt/s_tempo.lua0000644000076400017500000000750211012107762014561 0ustar  dgdg-- Handles thhe temporal school


MAGELOCK = add_spell
{
	["name"] = 	"Magelock",
	["school"] = 	{SCHOOL_TEMPORAL},
	["level"] = 	1,
	["mana"] = 	1,
	["mana_max"] = 	35,
	["fail"] = 	10,
	["stick"] =
	{
			["charge"] =    { 7, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		30,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 15, 45 },
			},
	},
	["spell"] = 	function()
			if get_level(MAGELOCK, 50) >= 30 then
				local ret, x, y, c_ptr

				if get_level(MAGELOCK, 50) >= 40 then
					ret, x, y = tgt_pt()
					if ret == FALSE then return end
					if cave_is(cave(y, x), FF1_FLOOR) == FALSE or cave_is(cave(y, x), FF1_PERMANENT) == TRUE or los(player.py, player.px, y, x) == FALSE then
						msg_print("You cannot place it there.")
						return TRUE
					end
				else
					y = player.py
					x = player.px
				end
				cave_set_feat(y, x, 3)
				return TRUE
			else
				ret, dir = get_aim_dir()
				if ret == FALSE then return end
				return wizard_lock(dir)
			end
	end,
	["info"] = 	function()
		       	return ""
	end,
	["desc"] =	{
			"Magically locks a door",
			"At level 30 it creates a glyph of warding",
			"At level 40 the glyph can be placed anywhere in the field of vision"
	}
}

SLOWMONSTER = add_spell
{
	["name"] = 	"Slow Monster",
	["school"] = 	{SCHOOL_TEMPORAL},
	["level"] = 	10,
	["mana"] = 	10,
	["mana_max"] = 	15,
	["fail"] = 	35,
	["stick"] =
	{
			["charge"] =    { 5, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		23,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["spell"] = 	function()
	       		local ret, dir

			ret, dir = get_aim_dir()
			if ret == FALSE then return end
			if get_level(SLOWMONSTER, 50) >= 20 then
				return fire_ball(GF_OLD_SLOW, dir, 40 + get_level(SLOWMONSTER, 160), 1)
			else
				return fire_bolt(GF_OLD_SLOW, dir, 40 + get_level(SLOWMONSTER, 160))
			end
	end,
	["info"] = 	function()
			if get_level(SLOWMONSTER, 50) >= 20 then
			       	return "power "..(40 + get_level(SLOWMONSTER, 160)).." rad 1"
			else
			       	return "power "..(40 + get_level(SLOWMONSTER, 160))
			end
	end,
	["desc"] =	{
			"Magically slows down the passing of time around a monster",
			"At level 20 it affects a zone"
	}
}

ESSENCESPEED = add_spell
{
	["name"] = 	"Essence of Speed",
	["school"] = 	{SCHOOL_TEMPORAL},
	["level"] = 	15,
	["mana"] = 	20,
	["mana_max"] = 	40,
	["fail"] = 	50,
	["stick"] =
	{
			["charge"] =    { 3, 3 },
			[TV_WAND] =
			{
				["rarity"] = 		80,
				["base_level"] =	{ 1, 1 },
				["max_level"] =		{ 10, 39 },
			},
	},
	["inertia"] = 	{ 5, 20 },
	["spell"] = 	function()
			if player.fast == 0 then return set_fast(10 + randint(10) + get_level(ESSENCESPEED, 50), 5 + get_level(ESSENCESPEED, 20)) end
	end,
	["info"] = 	function()
		       	return "dur "..(10 + get_level(ESSENCESPEED, 50)).."+d10 speed "..(5 + get_level(ESSENCESPEED, 20))
	end,
	["desc"] =	{
			"Magically decreases the passing of time around you, making you move faster with",
			"respect to the rest of the universe."
	}
}

BANISHMENT = add_spell
{
	["name"] = 	"Banishment",
	["school"] = 	{SCHOOL_TEMPORAL, SCHOOL_CONVEYANCE},
	["level"] = 	30,
	["mana"] = 	30,
	["mana_max"] = 	40,
	["fail"] = 	95,
	["stick"] =
	{
			["charge"] =    { 1, 3 },
			[TV_WAND] =
			{
				["rarity"] = 		98,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 10, 36 },
			},
	},
	["inertia"] = 	{ 5, 50 },
	["spell"] = 	function()
			local obvious
			obvious = project_los(GF_AWAY_ALL, 40 + get_level(BANISHMENT, 160))
			if get_level(BANISHMENT, 50) >= 15 then
				obvious = is_obvious(project_los(GF_STASIS, 20 + get_level(BANISHMENT, 120)), obvious)
			end
			return obvious
	end,
	["info"] = 	function()
		     	return "power "..(40 + get_level(BANISHMENT, 160))
	end,
	["desc"] =	{
			"Disrupts the space/time continuum in your area and teleports all monsters away.",
			"At level 15 it may also lock them in a time bubble for a while."
	}
}
tome-235-src/lib/scpt/.cvsignore0000644000076400017500000000001211012107762014375 0ustar  dgdgdebug.lua
tome-235-src/lib/scpt/s_air.lua0000644000076400017500000001147711012107762014216 0ustar  dgdg-- handle the air school

NOXIOUSCLOUD = add_spell
{
	["name"] = 	"Noxious Cloud",
	["school"] = 	{SCHOOL_AIR},
	["level"] = 	3,
	["mana"] = 	3,
	["mana_max"] = 	30,
	["fail"] = 	20,
	["stick"] =
	{
			["charge"] =    { 5, 7 },
			[TV_WAND] =
			{
				["rarity"] = 		15,
				["base_level"] =	{ 1, 15 },
				["max_level"] =		{ 25, 50 },
			},
	},
	["spell"] = 	function()
			local ret, dir, type

			ret, dir = get_aim_dir()
			if ret == FALSE then return end
			if get_level(NOXIOUSCLOUD, 50) >= 30 then type = GF_UNBREATH
			else type = GF_POIS end
			fire_cloud(type, dir, 7 + get_level(NOXIOUSCLOUD, 150), 3, 5 + get_level(NOXIOUSCLOUD, 40))
			return TRUE
	end,
	["info"] = 	function()
			return "dam "..(7 + get_level(NOXIOUSCLOUD, 150)).." rad 3 dur "..(5 + get_level(NOXIOUSCLOUD, 40))
	end,
	["desc"] =	{
			"Creates a cloud of poison",
			"The cloud will persist for some turns, damaging all monsters passing by",
			"At spell level 30 it turns into a thick gas attacking all living beings"
	}
}

AIRWINGS = add_spell
{
	["name"] = 	"Wings of Winds",
	["school"] = 	{SCHOOL_AIR, SCHOOL_CONVEYANCE},
	["level"] = 	22,
	["mana"] = 	30,
	["mana_max"] = 	40,
	["fail"] = 	60,
	["stick"] =
	{
			["charge"] =    { 7, 5 },
			[TV_STAFF] =
			{
				["rarity"] = 		27,
				["base_level"] =	{ 1, 10 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["inertia"] = 	{ 1, 10 },
	["spell"] = 	function()
			if get_level(AIRWINGS, 50) >= 16 then
				if player.tim_fly == 0 then return set_tim_fly(randint(10) + 5 + get_level(AIRWINGS, 25)) end
			else
				if player.tim_ffall == 0 then return set_tim_ffall(randint(10) + 5 + get_level(AIRWINGS, 25)) end
			end
			return FALSE
	end,
	["info"] = 	function()
			return "dur "..(5 + get_level(AIRWINGS, 25)).."+d10"
	end,
	["desc"] =	{
			"Grants the power of levitation",
			"At level 16 it grants the power of controlled flight"
	}
}

INVISIBILITY = add_spell
{
	["name"] = 	"Invisibility",
	["school"] = 	{SCHOOL_AIR},
	["level"] = 	16,
	["mana"] = 	10,
	["mana_max"] = 	20,
	["fail"] = 	50,
	["inertia"] = 	{ 1, 30 },
	["spell"] = 	function()
			if player.tim_invisible == 0 then return set_invis(randint(20) + 15 + get_level(INVISIBILITY, 50), 20 + get_level(INVISIBILITY, 50)) end
	end,
	["info"] = 	function()
			return "dur "..(15 + get_level(INVISIBILITY, 50)).."+d20 power "..(20 + get_level(INVISIBILITY, 50))
	end,
	["desc"] =	{
			"Grants invisibility"
	}
}

POISONBLOOD = add_spell
{
	["name"] = 	"Poison Blood",
	["school"] = 	{SCHOOL_AIR},
	["level"] = 	12,
	["mana"] = 	10,
	["mana_max"] = 	20,
	["fail"] = 	30,
	["stick"] =
	{
			["charge"] =    { 10, 15 },
			[TV_WAND] =
			{
				["rarity"] = 		45,
				["base_level"] =	{ 1, 25 },
				["max_level"] =		{ 35, 50 },
			},
	},
	["inertia"] = 	{ 1, 35 },
	["spell"] = 	function()
			local obvious = nil
		       	if player.oppose_pois == 0 then obvious = set_oppose_pois(randint(30) + 25 + get_level(POISONBLOOD, 25)) end
		       	if (player.tim_poison == 0) and (get_level(POISONBLOOD, 50) >= 15) then obvious = is_obvious(set_poison(randint(30) + 25 + get_level(POISONBLOOD, 25)), obvious) end
			return obvious
       	end,
	["info"] = 	function()
			return "dur "..(25 + get_level(POISONBLOOD, 25)).."+d30"
	end,
	["desc"] =	{
			"Grants resist poison",
			"At level 15 it provides poison branding to wielded weapon"
	}
}

THUNDERSTORM = add_spell
{
	["name"] = 	"Thunderstorm",
	["school"] = 	{SCHOOL_AIR, SCHOOL_NATURE},
	["level"] = 	25,
	["mana"] = 	40,
	["mana_max"] = 	60,
	["fail"] = 	60,
	["stick"] =
	{
			["charge"] =    { 5, 5 },
			[TV_WAND] =
			{
				["rarity"] = 		85,
				["base_level"] =	{ 1, 5 },
				["max_level"] =		{ 25, 50 },
			},
	},
	["inertia"] = 	{ 2, 15 },
	["spell"] = 	function()
			if player.tim_thunder == 0 then return set_tim_thunder(randint(10) + 10 + get_level(THUNDERSTORM, 25), 5 + get_level(THUNDERSTORM, 10), 10 + get_level(THUNDERSTORM, 25)) end
			return FALSE
	end,
	["info"] = 	function()
			return "dam "..(5 + get_level(THUNDERSTORM, 10)).."d"..(10 + get_level(THUNDERSTORM, 25)).." dur "..(10 + get_level(THUNDERSTORM, 25)).."+d10"
	end,
	["desc"] =	{
			"Charges up the air around you with electricity",
			"Each turn it will throw a thunder bolt at a random monster in sight",
			"The thunder does 3 types of damage, one third of lightning",
			"one third of sound and one third of light"
	}
}

STERILIZE = add_spell
{
	["name"] = 	"Sterilize",
	["school"] = 	{SCHOOL_AIR},
	["level"] = 	20,
	["mana"] = 	10,
	["mana_max"] = 	100,
	["fail"] = 	50,
	["stick"] =
	{
			["charge"] =    { 7, 5 },
			[TV_STAFF] =
			{
				["rarity"] = 		20,
				["base_level"] =	{ 1, 10 },
				["max_level"] =		{ 20, 50 },
			},
	},
	["spell"] = 	function()
			set_no_breeders((30) + 20 + get_level(STERILIZE, 70))
			return TRUE
	end,
	["info"] = 	function()
			return "dur "..(20 + get_level(STERILIZE, 70)).."+d30"
	end,
	["desc"] =	{
			"Prevents explosive breeding for a while."
	}
}
tome-235-src/lib/scpt/help.lua0000644000076400017500000003405211012107762014043 0ustar  dgdg-- Ingame contextual help

-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-----------------------Here comes the definition of help-----------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------

ingame_help
{
	["hook"] =      HOOK_MOVE,
	["event"] =     function(y, x) if cave(y, x).feat == FEAT_BETWEEN then return TRUE end end,
	["desc"] =
	{
		"Void Jumpgates can be entered by pressing the > key. They will transport",
		"you to another jumpgate, but beware of the cold damage that might kill you.",
	}
}

ingame_help
{
	["hook"] =      HOOK_MOVE,
	["event"] =     function(y, x) if cave(y, x).feat == FEAT_FOUNTAIN then return TRUE end end,
	["desc"] =
	{
		"Fountains are always magical. You can quaff from them by pressing H.",
		"Beware that unlike potions they cannot be identified.",
	}
}

ingame_help
{
	["hook"] =      HOOK_MOVE,
	["event"] =     function(y, x) if cave(y, x).o_idx ~= 0 then return TRUE end end,
	["desc"] =
	{
		"So you found your first item! Nice, eh? Now when you stumble across",
		"objects, you can pick them up by pressing g, and if you are wondering",
		"what they do, press I (then *, then the letter for the item) to get",
		"some basic information. You may also want to identify them with scrolls,",
		"staves, rods or spells.",
	}
}

ingame_help
{
	["hook"] =      HOOK_MOVE,
	["event"] =     function(y, x) if (cave(y, x).feat >= FEAT_ALTAR_HEAD) and (cave(y, x).feat <= FEAT_ALTAR_TAIL) then return TRUE end end,
	["desc"] =
	{
		"Altars are the way to reach the Valar, powers of the world,",
		"usualy called Gods. You can press O to become a follower.",
		"Beware that once you follow a god, you are not allowed to change.",
		"For an exact description of what gods do and want, read the documentation."
	}
}

-- Beware this one, if Bree is moved from 21, 34 (y, x) on the wilderness map it will break
ingame_help
{
	["hook"] =      HOOK_END_TURN,
	["event"] =     function(y, x)
		if ((player.wilderness_x ~= 34) or (player.wilderness_y ~= 21) and (player.astral == FALSE)) then return TRUE end
	end,
	["desc"] =
	{
		"Ahh wilderness travel... The overview mode will allow you to travel",
		"fast, but that comes to the cost of GREATLY increased food consumption.",
		"So you should bring lots of food and really watch your hunger status.",
		"To enter the overview mode, press < while in the wilderness.",
	}
}

ingame_help
{
	["hook"] =      HOOK_PLAYER_LEVEL,
	["event"] =     function(y, x) if player.lev > 1 then return TRUE end end,
	["desc"] =
	{
		"Ok, so you now gained a level, and you have skill points to spend.",
		"To do so simply press G to learn skills. Reading the documentation",
		"about skills and abilities is also strongly recommended.",
	}
}

ingame_help
{
	["hook"] =      HOOK_MOVE,
	["event"] =     function(y, x) if cave(y, x).feat == FEAT_MORE then return TRUE end end,
	["desc"] =
	{
		"Ah, this is a stair, or a way into something. Press > to enter it.",
		"But be ready to fight what lies within, for it might not be too friendly.",
	}
}

ingame_help
{
	["callback"] =  "monster_chat",
	["desc"] =
	{
		"Somebody is speaking to you it seems. You can talk back with the Y key.",
		"This can lead to quests. You can also give items to 'monsters' with the y key.",
	}
}

ingame_help
{
	["hook"] =      HOOK_END_TURN,
	["event"] =     function(y, x) return TRUE end,
	["desc"] =
	{
		"Welcome to ToME! I am the spirit of knowledge and my task is to help you",
		"to get used to how to play. I have prepared a #vparchment#y for you to #vread#y.",
		"Press r, then space then select it. You can also check the documentation",
		"by pressing ? at (nearly) any time.",
		"The first place you can explore is Barrow-downs. Go to the west of town",
		"and you should see a #v>#y there.",
		"If you miss any of this you can press ctrl+p to see your message log.",
		"Now I must reveal your task here. You are on a quest to investigate",
		"the dreadful tower of Dol Guldur in the Mirkwood forest to see what evil",
		"lurks there, but beware, you are not yet ready.",
		"If you do not want me to bother you any more with tips, press = then go",
		"into the ToME options and deactivate the ingame_help option.",
		"You can see your quest log by pressing ctrl+q. Now go to your destiny!",
	}
}

ingame_help
{
	["no_test"] =   TRUE,
	["callback"] =  "select_context",
	["fct"] =       function(typ, name)
			-- list of files for classes, { filename, anchor }
			local t =
			{
				["race"] =
				{
					["Beorning"] = { "r_beorn.txt", 0 },
					["DeathMold"] = { "r_deathm.txt", 0 },
					["Dark-Elf"] = { "r_drkelf.txt", 0 },
					["Dunadan"] = { "r_dunad.txt", 0 },
					["Dwarf"] = { "r_dwarf.txt", 0 },
					["Elf"] = { "r_elf.txt", 0 },
					["Ent"] = { "r_ent.txt", 0 },
					["Gnome"] = { "r_gnome.txt", 0 },
					["Half-Elf"] = { "r_hafelf.txt", 0 },
					["Half-Ogre"] = { "r_hafogr.txt", 0 },
					["High-Elf"] = { "r_hielf.txt", 0 },
					["Hobbit"] = { "r_hobbit.txt", 0 },
					["Human"] = { "r_human.txt", 0 },
					["Kobold"] = { "r_kobold.txt", 0 },
					["Maia"] = { "r_maia.txt", 0 },
					["Orc"] = { "r_orc.txt", 0 },
					["Petty-Dwarf"] = { "r_pettyd.txt", 0 },
					["RohanKnight"] = { "r_rohank.txt", 0 },
					["Thunderlord"] = { "r_thlord.txt", 0 },
					["Troll"] = { "r_troll.txt", 0 },
					["Wood-Elf"] = { "r_wodelf.txt", 0 },
					["Yeek"] = { "r_yeek.txt", 0 },
				},
				["subrace"] =
				{
					["Barbarian"] = { "rm_barb.txt", 0 },
					["Classical"] = { "rm_class.txt", 0 },
					["Corrupted"] = { "rm_corru.txt", 0 },
					["Hermit"] = { "rm_herm.txt", 0 },
					["LostSoul"] = { "rm_lsoul.txt", 0 },
					["Skeleton"] = { "rm_skel.txt", 0 },
					["Spectre"] = { "rm_spec.txt", 0 },
					["Vampire"] = { "rm_vamp.txt", 0 },
					["Zombie"] = { "rm_zomb.txt", 0 },
				},
				["class"] =
				{
					["Alchemist"] = { "c_alchem.txt", 0 },
					["Archer"] = { "c_archer.txt", 0 },
					["Assassin"] = { "c_assass.txt", 0 },
					["Axemaster"] = { "c_axemas.txt", 0 },
					["Bard"] = { "c_bard.txt", 0 },
					["Dark-Priest"] = { "c_pr_drk.txt", 0 },
					["Demonologist"] = { "c_demono.txt", 0 },
					["Druid"] = { "c_druid.txt", 0 },
					["Geomancer"] = { "c_geoman.txt", 0 },
					["Haftedmaster"] = { "c_hafted.txt", 0 },
					["Loremaster"] = { "c_lorema.txt", 0 },
					["Mage"] = { "c_mage.txt", 0 },
					["Mimic"] = { "c_mimic.txt", 0 },
					["Mindcrafter"] = { "c_mindcr.txt", 0 },
					["Monk"] = { "c_monk.txt", 0 },
					["Necromancer"] = { "c_necro.txt", 0 },
					["Paladin"] = { "c_palad.txt", 0 },
					["Polearmmaster"] = { "c_polear.txt", 0 },
					["Possessor"] = { "c_posses.txt", 0 },
					["Priest"] = { "c_priest.txt", 0 },
					["Priest(Eru)"] = { "c_pr_eru.txt", 0 },
					["Priest(Manwe)"] = { "c_pr_man.txt", 0 },
					["Ranger"] = { "c_ranger.txt", 0 },
					["Rogue"] = { "c_rogue.txt", 0 },
					["Runecrafter"] = { "c_runecr.txt", 0 },
					["Sorceror"] = { "c_sorcer.txt", 0 },
					["Summoner"] = { "c_summon.txt", 0 },
					["Swordmaster"] = { "c_swordm.txt", 0 },
					["Symbiant"] = { "c_symbia.txt", 0 },
					["Thaumaturgist"] = { "c_thaum.txt", 0 },
					["Unbeliever"] = { "c_unbel.txt", 0 },
					["Warper"] = { "c_warper.txt", 0 },
					["Warrior"] = { "c_warrio.txt", 0 },
				},
				["god"] =
				{
					["Eru Iluvatar"] = { "g_eru.txt", 0 },
					["Manwe Sulimo"] = { "g_manwe.txt", 0 },
					["Tulkas"] = { "g_tulkas.txt", 0 },
					["Melkor Bauglir"] = { "g_melkor.txt", 0 },
					["Yavanna Kementari"] = { "g_yavann.txt", 0 },  
				},
				["skill"] =
				{
					["Air"] = { "skills.txt", 27 },
					["Alchemy"] = { "skills.txt", 49 },
					["Antimagic"] = { "skills.txt", 50 },
					["Archery"] = { "skills.txt", 08 },
					["Axe-mastery"] = { "skills.txt", 05 },
					["Backstab"] = { "skills.txt", 18 },
					["Barehand-combat"] = { "skills.txt", 13 },
					["Boomerang-mastery"] = { "skills.txt", 12 },
					["Boulder-throwing"] = { "skills.txt", 58 },
					["Bow-mastery"] = { "skills.txt", 10 },
					["Combat"] = { "skills.txt", 01 },
					["Conveyance"] = { "skills.txt", 30 },
					["Corpse-preservation"] = { "skills.txt", 44 },
					["Critical-hits"] = { "skills.txt", 04 },
					["Crossbow-mastery"] = { "skills.txt", 11 },
					["Demonology"] = { "skills.txt", 52 },
					["Disarming"] = { "skills.txt", 16 },
					["Divination"] = { "skills.txt", 31 },
					["Dodging"] = { "skills.txt", 20 },
					["Druidistic"] = { "skills.txt", 40 },
					["Earth"] = { "skills.txt", 28 },
					["Fire"] = { "skills.txt", 25 },
					["Geomancy"] = { "skills.txt", 60 },
					["Hafted-mastery"] = { "skills.txt", 06 },
					["Magic"] = { "skills.txt", 21 },
					["Magic-Device"] = { "skills.txt", 54 },
					["Mana"] = { "skills.txt", 24 },
					["Meta"] = { "skills.txt", 29 },
					["Mimicry"] = { "skills.txt", 47 },
					["Mind"] = { "skills.txt", 33 },
					["Mindcraft"] = { "skills.txt", 41 },
					["Monster-lore"] = { "skills.txt", 42 },
					["Music"] = { "skills.txt", 59 },
					["Nature"] = { "skills.txt", 34 },
					["Necromancy"] = { "skills.txt", 35 },
					["Polearm-mastery"] = { "skills.txt", 07 },
					["Possession"] = { "skills.txt", 45 },
					["Prayer"] = { "skills.txt", 39 },
					["Runecraft"] = { "skills.txt", 36 },
					["Sling-mastery"] = { "skills.txt", 09 },
					["Sneakiness"] = { "skills.txt", 14 },
					["Spell-power"] = { "skills.txt", 22 },
					["Spirituality"] = { "skills.txt", 38 },
					["Sorcery"] = { "skills.txt", 23 },
					["Stealing"] = { "skills.txt", 19 },
					["Stealth"] = { "skills.txt", 15 },
					["Stunning-blows"] = { "skills.txt", 53 },
					["Summoning"] = { "skills.txt", 43 },
					["Sword-mastery"] = { "skills.txt", 03 },
					["Symbiosis"] = { "skills.txt", 46 },
					["Temporal"] = { "skills.txt", 32 },
					["Thaumaturgy"] = { "skills.txt", 37 },
					["Udun"] = { "skills.txt", 48 },
					["Weaponmastery"] = { "skills.txt", 02 },
					["Water"] = { "skills.txt", 26 },
				},
				["ability"] = 
				{
				    ["Spread blows"] = { "ability.txt", 02 },
				    ["Tree walking"] = { "ability.txt", 03 },
				    ["Perfect casting"] = { "ability.txt", 04 },
				    ["Extra Max Blow(1)"] = { "ability.txt", 05 },
				    ["Extra Max Blow(2)"] = { "ability.txt", 06 },
				    ["Ammo creation"] = { "ability.txt", 07 },
				    ["Touch of death"] = { "ability.txt", 08 },
				    ["Artifact Creation"] = { "ability.txt", 09 },
				    ["Far reaching attack"] = { "ability.txt", 10 },
				    ["Trapping"] = { "ability.txt", 11 },
				    ["Undead Form"] = { "ability.txt", 12 },
				},
			}

			if t[typ][name] then ingame_help_doc(t[typ][name][1], t[typ][name][2])
			else ingame_help_doc("help.hlp", 0)
			end
	end,
}

ingame_help
{
	["hook"] =      HOOK_IDENTIFY,
	["event"] =     function(i, mode)
				if mode == "full" then
					local obj = get_object(i)
					local f1, f2, f3, f4, f5, esp = object_flags(obj)
					if band(f5, TR5_SPELL_CONTAIN) ~= 0 then return TRUE end
				end
			end,
	["desc"] =
	{
		"Ah, an item that can contain a spell. To use it you must have some levels of",
		"Magic skill and then you get the option to copy a spell when pressing m.",
		"Then just select which spell to copy and to which object. Note that doing so",
		"is permanent; the spell cannot be removed or changed later.",
	}
}

ingame_help
{
	["hook"] =      HOOK_GET,
	["event"] =     function(obj, idx) if obj.tval == TV_BATERIE then return TRUE end end,
	["desc"] =
	{
		"Ah, an essence! Those magical containers stores energies. They are used",
		"with the Alchemy skill to create or modify the powers of items.",
	}
}

ingame_help
{
	["hook"] =      HOOK_GET,
	["event"] =     function(obj, idx) if obj.tval == TV_RUNE1 or obj.tval == TV_RUNE2 then return TRUE end end,
	["desc"] =
	{
		"Ah, a rune! Runes are used with the Runecraft skill to allow you to",
		"create spells on your own.",
	}
}

ingame_help
{
	["hook"] =      HOOK_GET,
	["event"] =     function(obj, idx) if obj.tval == TV_ROD_MAIN then return TRUE end end,
	["desc"] =
	{
		"This is a rod. You will need to attach a rod tip to it before you",
		"can use it. This main part of the rod may give the rod bonuses",
		"like quicker charging time, or a larger capacity for charges.",
	}
}

ingame_help
{
	["hook"] =      HOOK_GET,
	["event"] =     function(obj, idx) if obj.tval == TV_ROD then return TRUE end end,
	["desc"] =
	{
		"You've found a rod-tip! You will need to attach it to a rod base",
		"before you can use it. Once it has been attatched (use the 'z' key)",
		"you cannot unattach it! The rod tip will determine the effect of",
		"the rod. To use your rod, 'z'ap it once it has been assembled.",
	}
}

ingame_help
{
	["hook"] =      HOOK_GET,
	["event"] =     function(obj, idx) if obj.tval == TV_TRAPKIT then return TRUE end end,
	["desc"] =
	{
		"Ooooh, a trapping kit. If you have ability in the trapping skill,",
		"you can lay this trap (via the 'm' key) to harm unsuspecting foes.",
		"You'll generally need either some ammo or magic device depending",
		"on the exact type of trap kit.",
	}
}

ingame_help
{
	["hook"] =      HOOK_RECALC_SKILLS,
	["event"] =     function() if game.started and (get_melee_skills() > 1) then return TRUE end end,
	["desc"] =
	{
		"Ah, you now possess more than one melee type. To switch between them press m",
		"and select the switch melee type option.",
	}
}

ingame_help
{
	["hook"] =      HOOK_GET,
	["event"] =     function(obj, idx) if obj.tval == TV_WAND or obj.tval == TV_STAFF then return TRUE end end,
	["desc"] =
	{
		"You've found a magical device, either a staff or a wand. Each staff",
		"contains a spell, often from one of the primary magic schools. There",
		"is a lot of information you can find about this object if you identify",
		"it and 'I'nspect it. Check the help file on Magic for more about these.",
	}
}

ingame_help
{
	["hook"] =      HOOK_PLAYER_LEVEL,
	["event"] =     function(y, x) if player.lev >= 20 then return TRUE end end,
	["desc"] =
	{
		"I see you are now at least level 20. Nice! If you want to gloat about your",
		"character you could press 'C' then 'f' to make a character dump and post it to",
		"http://angband.oook.cz/ where it will end up in the ladder.",
	}
}
tome-235-src/lib/scpt/player.lua0000644000076400017500000000502711012107762014407 0ustar  dgdg------------------------------------------------------------------------------
----------------------- Hook to create birth objects -------------------------
------------------------------------------------------------------------------
function __birth_hook_objects()
	-- Provide a book of blink to rangers
	if get_class_name() == "Ranger" then
		local obj = create_object(TV_BOOK, 255);
		obj.pval = find_spell("Phase Door")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end

	-- Provide a book of Geyser to Geomancers
	if get_class_name() == "Geomancer" then
		local obj = create_object(TV_BOOK, 255);
		obj.pval = find_spell("Geyser")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end

	-- Provide a book of prayer to priests
	if get_class_name() == "Priest(Eru)" then
		local obj = create_object(TV_BOOK, 255);
		obj.pval = find_spell("See the Music")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end
	if get_class_name() == "Priest(Manwe)" then
		local obj = create_object(TV_BOOK, 255);
		obj.pval = find_spell("Manwe's Blessing")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end
	if get_class_name() == "Druid" then
		local obj = create_object(TV_BOOK, 255);
		obj.pval = find_spell("Charm Animal")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end
	if get_class_name() == "Dark-Priest" then
		local obj = create_object(TV_BOOK, 255);
		obj.pval = find_spell("Curse")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end
	if get_class_name() == "Paladin" then
		local obj = create_object(TV_BOOK, 255);
		obj.pval = find_spell("Divine Aim")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end
	if get_class_name() == "Mimic" then
		local obj = create_object(TV_CLOAK, 100);
		obj.pval2 = resolve_mimic_name("Mouse")
		obj.ident = bor(obj.ident, IDENT_MENTAL, IDENT_KNOWN)
		inven_carry(obj, FALSE)
		end_object(obj)
	end

	-- Start the undeads, as undeads with the corruptions
	if get_subrace_name() == "Vampire" then
		player.corruption(CORRUPT_VAMPIRE_TEETH, TRUE)
		player.corruption(CORRUPT_VAMPIRE_STRENGTH, TRUE)
		player.corruption(CORRUPT_VAMPIRE_VAMPIRE, TRUE)
	end
end

-- Register in the hook list
add_hook_script(HOOK_BIRTH_OBJECTS, "__birth_hook_objects", "__birth_hook_objects")
tome-235-src/lib/user/0000755000076400017500000000000011012107763012412 5ustar  dgdgtome-235-src/lib/user/automat.atm0000644000076400017500000000000011012107762014554 0ustar  dgdgtome-235-src/lib/user/delete.me0000644000076400017500000000000111012107762014165 0ustar  dgdgatome-235-src/lib/xtra/0000755000076400017500000000000011012107763012412 5ustar  dgdgtome-235-src/lib/xtra/font/0000755000076400017500000000000011012107763013360 5ustar  dgdgtome-235-src/lib/xtra/font/8X13B.FON0000644000076400017500000001200011012107762014461 0ustar  dgdgMZ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE…ƒ/@H|……†	
	€P,€0€FONTDIR8X13B+FONTRES 100,75,75 : 8x13 Bold (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢º
	Public domain font.  Share and enjoy.KK
ä
0 	8X13BAŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿ
	Public domain font.  Share and enjoy.KK
ä
0 	zz‡”¡®»ÈÕâïü	#0=JWdq~‹˜¥²¿ÌÙæó
'4AN[hu‚œ©¶ÃÐÝê÷+8ER_ly†“ ­ºÇÔáîû"/<IVcp}Š—¤±¾ËØåòÿ&3@MZgtŽ›¨µÂÏÜéö*7DQ^kx…’Ÿ¬¹ÆÓàíú8|þ|8ÛfÛfÛfÛÌÌüÌÌ~~ððÀàÀÞxÀÀÀx|f~lfÀÀÀÀð||`x``8|ÆÆ|800üü00üüÌìüÜÌÌ0000>ÌÌÌxx0~~øøøøÿÿÿÿÿÿÿÿÿÿÿÿøøÿÿÿÿ0`À`0üü`00`~~þþllìÌþþ8þþ`À<~bðð```ò¾î000000000llllllþþlþþll0|ü°ø|4üø0BæL0 d΄0xÌÌx2vÜüv0`00```00`00`Æl8þþ8lÆ00üü008880`üü8880`À€€8|ÆÆÆÆÆÆ|88x~~|þ†|àÀþþüþ<<þü000>000000000x||xfþØUªUªUªUªUªUªU8X13BŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿtome-235-src/lib/xtra/font/6X10.FON0000644000076400017500000001100011012107762014351 0ustar  dgdgMZ{ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE„ƒ*@H|„„…	
	€P,€0€FONTDIR6X10&FONTRES 100,75,75 : 6x10 (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢º‰Public domain terminal emulator font.  Share and enjoy.
KK“
0 „6X10AŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿ‰Public domain terminal emulator font.  Share and enjoy.
KK“
0 „zz„Ž˜¢¬¶ÀÊÔÞèòü$.8BLV`jt~ˆ’œ¦°ºÄÎØâìö
(2<FPZdnx‚Œ– ª´¾ÈÒÜæðú",6@JT^hr|†š¤®¸ÂÌÖàêôþ&0:DNXblv€Š”ž¨²¼ÆÐÚäîø *4>HR\fpz88|88T(T(T(THHxHH<p@`@\8@@88$8$$@@@x< 8  8((8||HhhXH   <HH0 <pp||||||p|| @ |@  @||((((|| @$ x 8l (((((|(|((8P88$T((TH PP TH4      D(|(D| |8 @@(DDD(0P|8D @||D8(H||@XdD8 @XdD8|  8DD8DD88DL40888  ||@  @8D8DLTX@8(DD|DDx$$8$$x8D@@@D8x$$$$$x|@@x@@||@@x@@@8D@@LD8DDD|DDD88D8DHP`PHD@@@@@@|DDlTDDDDDdTLDD8DDDDD8xDDx@@@8DDDDT8xDDxPHD8D@8D8|DDDDDD8DDD(((DDDTTlDDD((DDDD(| @|8     8@@ 88(D|08JVbnz†’žª¶ÂÎÚæòþ
".:FR^jv‚Žš¦²¾ÊÖâîú*6BNZfr~Š–¢®ºÆÒÞêö&2>JVbnz†’žª¶ÂÎÚæòþ
".:FR^jøøpxˆxøø€€ðˆˆˆðøøpˆ€€xøøxˆˆˆxøøpˆð€pøø0H@à@@@øøpˆˆˆxpøø€€ðˆˆˆˆøø     øøˆpøø€€ˆàˆøø       øøÐ¨¨¨¨øø°Èˆˆˆøøpˆˆˆpøøðˆˆˆð€€øøpˆˆˆxøø°È€€€øøx€pðøø  ø   øøˆˆˆˆpøøˆˆˆP øøˆˆ¨¨PøøˆP PˆøøˆˆˆP @øøøp@ø  PˆP  øø€@ øøà    àøø Pˆ       PPPPøPPøP p¨ p(¨p øÈ @˜˜@  @¨h``À   €@   @€ ¨p p¨   ø  ``Àø`` @€pˆ˜¨Èˆp `    ppˆ @øpˆ0ˆp0Pøø€ðˆp0@€ðˆˆpø   pˆˆpˆˆppˆˆx`````````À @ øø@  @pˆ   pˆ¸¨¸€ppˆˆøˆˆˆðˆˆðˆˆðpˆ€€€ˆpðHHHHHðø€€ð€€øø€€ð€€€pˆ€€˜ˆpˆˆˆøˆˆˆp     pˆpˆ À ˆ€€€€€€øˆØ¨ˆˆˆˆˆˆÈ¨˜ˆˆpˆˆˆˆˆpðˆˆð€€€pˆˆˆ¨hðˆˆð ˆpˆ€pˆpø      ˆˆˆˆˆˆpˆˆˆˆPP ˆˆˆˆ¨ØˆˆˆP PˆˆˆˆP    øø@€ø8       8€@ à       à Pˆø00pxˆx€€ðˆˆˆðpˆ€€xxˆˆˆxpˆð€p0H@à@@@pˆˆˆxp€€ðˆˆˆˆ     ˆp€€ˆàˆ       Ш¨¨¨°Èˆˆˆpˆˆˆpðˆˆˆð€€pˆˆˆx°È€€€x€pð  ø   ˆˆˆˆpˆˆˆP ˆˆ¨¨PˆP PˆˆˆˆP @€øp@ø           €@@@ @@@€h°T¨T¨T¨T¨T¨T¨6X12AŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿtome-235-src/lib/xtra/font/6X13.FON0000644000076400017500000001200011012107762014355 0ustar  dgdgMZ{ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE„ƒ*@H|„„…	
	€P,€0€FONTDIR6X13&FONTRES 100,75,75 : 6x13 (MicroX font)ŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿÿ	Public domain font.  Share and enjoy.KK
o
 	6x13BONES      "YXòŽDATA       "YXõŽEXTRA      "YXøŽFILES      &YX@	Public domain font.  Share and enjoy.KK
o
 	zz‡”¡®»ÈÕâïü	#0=JWdq~‹˜¥²¿ÌÙæó
'4AN[hu‚œ©¶ÃÐÝê÷+8ER_ly†“ ­ºÇÔáîû"/<IVcp}Š—¤±¾ËØåòÿ&3@MZgtŽ›¨µÂÏÜéö*7DQ^kx…’Ÿ¬¹ÆÓàíúððððððððð pøp ¨P¨P¨P¨  à  p   à€À€ð@`@@p€€ppHpPH€€€àp@`@@``  ø  øˆÈ¨˜ˆ@@@xˆˆP ø          àà     <            <       ü     üüüüü       <            à            üü                   @ ø€@  @€øøPPPø ø€0H@ð ð¨à         PPPPPøPøPP p  p((p H¨P @P¨@  @ ˜h0 @  @@@  @    @ ¨øpø¨   ø  0 @ø p  @@€€ PˆˆˆˆˆP  `      øpˆˆ @€øø pˆp0PPøø€€°Èˆppˆ€€ðˆˆˆpø  @@@pˆˆˆpˆˆˆppˆˆˆxˆp p  p  p 0 @ @€@ øø€@  @€pˆˆ   pˆˆ˜¨¨°€x PˆˆˆøˆˆˆðHHHpHHHðpˆ€€€€€ˆpðHHHHHHHðø€€€ð€€€øø€€€ð€€€€pˆ€€€˜ˆˆpˆˆˆˆøˆˆˆˆp       p8`ˆˆ À ˆˆ€€€€€€€€øˆˆØ¨¨ˆˆˆˆˆÈȨ¨˜˜ˆˆpˆˆˆˆˆˆˆpðˆˆˆð€€€€pˆˆˆˆˆˆ¨pðˆˆˆð ˆˆpˆ€€pˆpø        ˆˆˆˆˆˆˆˆpˆˆˆˆPPP  ˆˆˆˆ¨¨¨ØˆˆˆPP PPˆˆˆˆPP     ø @@€øp@@@@@@@p€€@@ pp Pˆø0pxˆˆx€€€ðˆˆˆˆðpˆ€€ˆpxˆˆˆˆxpˆø€ˆp0H@@ð@@@@pˆˆˆxˆp€€€°Èˆˆˆˆ `    p0`€€€ À ˆ`       pШ¨¨¨ˆ°Èˆˆˆˆpˆˆˆˆpðˆˆˆð€€€xˆˆˆx°È€€€€pˆ`ˆp@@ð@@@H0ˆˆˆˆ˜hˆˆˆPP ˆˆ¨¨¨PˆP  Pˆˆˆˆ˜hˆpø @€ø   À            À      ÀH¨¨T¨T¨T¨T¨T¨T¨6x13tome-235-src/lib/xtra/font/6X9.FON0000644000076400017500000001100011012107762014301 0ustar  dgdgMZy ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NEƒƒ)@H|ƒƒ„	
	€P,€0€FONTDIR6X9%FONTRES 100,75,75 : 6x9 (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢ºCopyright 1989 Massachusetts Institute of Technology	KK‹	0 6X9AŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿCopyright 1989 Massachusetts Institute of Technology	KK‹	0 zzƒŒ•ž§°¹ÂËÔÝæïø
%.7@IR[dmvˆ‘𣬵¾ÇÐÙâëôý!*3<ENW`ir{„–Ÿ¨±ºÃÌÕÞçðù&/8AJS\enw€‰’›¤­¶¿ÈÑÚãìõþ"+4=FOXajs|…Ž— ©²»ÄÍÖßèñú0xüx0(T(T(T(TPpPp@`@0@0@@@`0H0||HhXHPP  pp||||||ðüü0@0Lp`dp|(((l|| @$ x (tD(((((|(|((8TP8T8@¨H HT0HH0LH40        D(|(D|0 |00 @@0HXhH0 `   p0H0@xx8x(H|x@Phx0@PhH0xH0 0H0HH00HX(00000000 0@0||``0H0  8HTX@8(D|DDxDxDDx0H@@H0pHHHHpx@p@@xx@p@@@0H@XH0HHxHHHp    p8H8HP`PHH@@@@@xDlTTDDHhXHHH0HHHH0pHHp@@0HHhX0pHHpHH0H H0|HHHHH0HHHx00DDTTlDD(((DDD(x @xp@@@@p@@ pp(Dü0  8HH<@@@pHHp8@@88HH80X`88 p   0HX(0@@@PhHH080p @@HPpHH08hTTDpHHH0HH0pHHp@@8HH8Ph@@x`x  p ((HHH8HH00DTT(H00HHHhH0x`x  `        @  0  @(PT¨T¨T¨T¨T6X9Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿtome-235-src/lib/xtra/font/8X13.FON0000644000076400017500000001200011012107762014357 0ustar  dgdgMZ{ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE„ƒ*@H|„„…	
	€P,€0€FONTDIR8X13&FONTRES 100,75,75 : 8x13 (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢º	Public domain font.  Share and enjoy.KK
V
0 	8X13AŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿ	Public domain font.  Share and enjoy.KK
V
0 	zz‡”¡®»ÈÕâïü	#0=JWdq~‹˜¥²¿ÌÙæó
'4AN[hu‚œ©¶ÃÐÝê÷+8ER_ly†“ ­ºÇÔáîû"/<IVcp}Š—¤±¾ËØåòÿ&3@MZgtŽ›¨µÂÏÜéö*7DQ^kx…’Ÿ¬¹ÆÓàíú8|þ|8’D’D’D’ˆˆøˆˆ>ð€à€žx€€x<"<""€€€ø> <  8DD8þþˆÈ¨˜ˆ   >ˆˆP >ððÿÿÿÿÿÿðÿÿ € þ€  €þþ$$$Dþþ@€" ø x¦@$$$$$~$~$$BF:@@@\bBBb\@ € € € € € @ @€    /€0@ @ @ @ @ @ @€€€€€€€ € € €     À#,0(&!€ @{€D@D@D@D@D@D@@@/0€ € € € € € €€ @ @ @ @ @ @€/€0@ @ @ @ @0@/€   @ À @ @ @ @ À@@@@'€@@€ @ ?€@@ @€€ € € € € € €!€€ € €

@@@@@@D@D@D@J@1€ @€		€ @ € € € € € €€€€ €?À€?ÀÀÀ<<8@D@C€tome-235-src/lib/xtra/font/VeraMono.ttf0000644000076400017500000014011011012107762015621 0ustar  dgdgOS/2´_õ*ª,VPCLT!?ͪ„6cmap¤Ãè ¨Xcvt é—0fpgmÆp((TŒgaspÀglyf­‚ñÅ(àtÈhdmxÇ32`ª¼HheadÙ…¥'À6hhea?ôª$hmtx
ε`¡4loca­™§ÌmaxpŠñ©è nameä£Á`úpostnî]¥4–prep:ÇÀ!8::h::mR0¶u	Œ
	y	t	¤	0
	

t	0
	0
	
~	6
H	`	Ž	0¼	
&
–Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans MonoBitstreamVeraSansMono-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc.
All Rights Reserved.
Bitstream Vera is a trademark of Bitstream, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:

The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.

The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera".

This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names.

The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.

THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.comCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved.Bitstream Vera Sans MonoBitstreamVeraSansMono-RomanRelease 1.10Copyright (c) 2003 by Bitstream, Inc.

All Rights Reserved.

Bitstream Vera is a trademark of Bitstream, Inc.



Permission is hereby granted, free of charge, to any person obtaining a copy of the fonts accompanying this license ("Fonts") and associated documentation files (the "Font Software"), to reproduce and distribute the Font Software, including without limitation the rights to use, copy, merge, publish, distribute, and/or sell copies of the Font Software, and to permit persons to whom the Font Software is furnished to do so, subject to the following conditions:



The above copyright and trademark notices and this permission notice shall be included in all copies of one or more of the Font Software typefaces.



The Font Software may be modified, altered, or added to, and in particular the designs of glyphs or characters in the Fonts may be modified and additional glyphs or characters may be added to the Fonts, only if the fonts are renamed to names not containing either the words "Bitstream" or the word "Vera".



This License becomes null and void to the extent applicable to Fonts or Font Software that has been modified and is distributed under the "Bitstream Vera" names.



The Font Software may be sold as part of a larger software package but no copy of one or more of the Font Software typefaces may be sold by itself.



THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.



Except as contained in this notice, the names of Gnome, the Gnome Foundation, and Bitstream Inc., shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Font Software without prior written authorization from the Gnome Foundation or Bitstream Inc., respectively. For further information, contact: fonts at gnome dot org.http://www.bitstream.com¸Ë¸Ëª‘¸f¸‡¸ÃË˸¸Ë‰ºË¦ü˃ò
Ç7ƒ¾X!Ëœçu¼ÓÉÛuç9ºËÓ!߸‰¾‰Ã¾{¾Xm¤®{¸o{¸RÍÑ͇‡“¤oÍ˸ƒ‘Ý´‹ô˜éZ´ºÅ!þÕöª=f‹ÅššƒÕs
þáÕ+¤´œbœÕ˜‡ÕÕð¤¸#Ӹ˦¼1NÓ
{T\qÛ…#wé`jÏÕ#fy```{{w`ªébø{!Åœ{´RNNÑfœœfœfœÍúƒ‘þHF?{L˜¢'oo5jo{ªª-–{öª3=œf‹öÍoD7fî…´}sÕ¹€²”]A–€þþþþšþ
²ëGA%
}%2
–	þþ%þ%þ@Yþþþý}üþûþú2ù»ø}÷öŒ÷þ÷ÀöõYöŒö€õô&õYõ@ô&óò/óúò/ñþðþï2îí–ìëGìþì¸ÿÑ@ÿëGêédê–édèþçæçþæåþäkãþâ»áàáúàß–ÞþÝþÜÛÜþÛÚ–ÙØÙþØØ×}Ö:ÕÕ:ÔþÓÒ
ÓþÒ
ÑþÐþÏŠÏÎÍþÌ–Ë‹%ËþÊþÉ}ÈþÇþÆþÅš
ÄþÃþÂþÁþÀÀ¿¾½»¾þ½¼]½»½€¼»%¼]¼@»%ºþ¹–¸A·þ¶A¶úµš
´þ³d²d±°¯þ®þ@ý­þ¬þ«ªþ©¨©2¨§¦§(¦¥¤-¥}¤-£þ¢þ¡þ Ÿ dŸžŸž
œþ›š
›þš
™˜.™þ˜.—A—––•»–þ•”]•»•€”%”]”@“þ’þ‘%‘»%‹%AŽŽŒ‹%Œd‹Š‹%Љþˆþ‡þ†…†þ…„þƒþ‚B‚Sþ€x~}þ~}}|þ{zþwþvþutuu¸@ÚttÀss@rþqþpþonSo–nm(nSm(lþk2jþi2húg»fþeþdþcbcþbbaþ`þ_þ^Z^]d\È[Z[ZYþXWþVþUU2TþSþRþQ}PþONþM-MþL»K(JIJ7ICIHEHþGCGdFEF»EDCD7CBCC¸@@	BABB¸@	A@AA¸À@	@?@@¸€@	?	??¸@@d>þ=-=ú<þ;(:þ9B9d818K7þ6-6þ5K404K303þ2B2þ1-10/-/.	.»-,--¸€@	,,,¸@@–+*%+þ*	*%):)þ(þ'þ&%B%E$#þ""þ! -!} -KBþþþþþþBF-B-Bþ-B¸@	¸À@	
¸€@	
	

¸@´	¸@7þ
	
þ	þ-þ:ú-:-¸d…++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++¶, °%Id°@QX ÈY!-,°%Id°@QX ÈY!-,  °P°
y ¸ÿÿPXY°°%°%#á °P°
y ¸ÿÿPXY°°%á-,KPX ¸EDY!-,°%E`D-,KSX°%°%EDY!!-,ED-hþ–h¤¼¶ƒ/ÄÔì1ÔìÔì0!%!!hüsüåþ–øòr)ÏÕ	@‡†ˆ
Ô<ì2991/äüì03#3#Ë¡ËËÕýqþ›eý¸þRªÕ@‰ˆÔìÜì1ô<ì20###®Ñ®ÕýÕ+ýÕ+;J@0Œ	Œ


	 ÔÌ91/<Ô<<ü<<Ô<<Ä2ì220333!3!###!5!!5!#3¬hõi iôþçTúþßh iöiŸhþþ)Tþö/hõTö¾þaŸþašþ²™þbžþbž™NšŸýÇþ²¾þÓZ
/d@9($)%/%‹$Ž(‹Ž!$,( 0Ô<ì2ü<ìüäî1/Æ2ÄîöîîÆöî999906654&'#&&'5&&546753&&'´n|pÞhumÔdfÉbdËcÈÊÓ¿dO¢TU¡PÎØé¼DþNtd]gÑp^VdûÀ-.)´>Bʶ–»ëë­+/þQššÎ	!°˜*9V@/7("	’"’7“(’.‘“’+

%
4
+:ÄÔìüìîþî99991/îîöîþîî9999032654&#"4632#"&'%32654&#"4632#"&¸iNMklLNi‡¸†@s..2º‡ˆ¶þH#)üiOMllMMk‡¸‡@u--1º†‡¸?NjkMMljO‡¹0./t?…º·`¢`åOikMMkjN‡¹0--uA†¹¸9ÿãÅð*7³@b


-,.+2345617B7	1
+"1—"!%—–™
(!7+!(!(!
.8ÜìÄüÄÆîî99999991/ÆäöîÖÎî9990KSXí9í9íí9Y"6654''3#'#"5467&&54632&&#"3267667# '&¤JKªÕNSºjØþ抋20Ç­AƒF;}Eap:6\[È›*\,#‹ýÑ1–h F'¡óXåmFD
̉êdHŠG–®·'%[M;ÏI£\—Ç
ª¾Õ·ˆÔì1ôÄ0#¾®ÕýÕ+ªþòu
@œ›

Ôì2ì991üì0#&547u…ƒƒ… —””—äþ;æåþ:æîÃàßÄì\þò'
@œ›Ôüì2991üì03#654\ —””— …ƒƒìþ<ßáþ<ìèÆã䯦J+ðN@,
	
–
		
Ô<ì2Ü<ì2991ôÔ<ì2Äì2990%#'%%73%+þšf9þ°sþ°9fþš9PsPßÂÃbËþ‡yËbÃÂcËyþ‡ËXqy“'@¡	 ¡
Ô<ìü<ì1Ô<ìü<ì0!!#!5!¼½þC¨þD¼“þDªþD¼ª¼“þáò/@£¢ÔìÔÌ1üì03#öüÅšc/Ïþdßmƒ¶ ÔÄ1Ôì0!!d	ý÷ƒ¤éå1¶¢Ôì1/ì03#éüü1þÏfÿB7Õ@ˆÔìÔì1ôÄ03#y¾üî¿Õùm…ÿãLð#
@¥	——–™$!"!$üììÔìî1äôìîÔî0@Ö//////////	/
/??????????	?
?OOOO
O____
_ŸŸŸŸŸŸŸŸŸŸ	Ÿ
Ÿ¯¯¯¯¯¯¯¯¯¯	¯
¯¿¿¿¿¿¿¿¿¿¿	¿
¿F//////////	/
/__________	_
_¿¿¿¿¿¿¿¿¿¿	¿
¿$]]4632#"&"32'2#"ãM68PO98K…‹‹Ž‹‹Žïõõïïôôî7PP78NLœþÐþÉþÊþÐ0670 þxþþ‚þxˆ~ˆöFÕ
&@——ˆ—	##ÔìÄüì1/ì2ôìÔì0%!5%3!!:þ®PÊ6üȪuL¸JúÕª˜#ðQ@)%%B§
—–—

"$üÄüìÀÀ91/ì2ôìôÌ0KSXí9í2Y"%!!5676654&#"56632u®üu»5dF“€[ÈpgÇaÛYd8ÕªªªÅ.>z—O}ŽBCÌ12é½`ÀtAæ‰ÿã7ð(G@)—
‹	¦
—‹ ¦—#–™©)&"	)üÄÄüìÔì91ìäôìôìîöîî90#"&'532654&##532654&#"56632“œþëõgÖgfÆb¦²²˜šš‹œ‘†Y¾hy½IÚ‰'Ç•Îë&$É54–‚™¦zms{((º  Ûµ{¤foÕ
B@


B—ˆ	
$üüÔ<ì291/äÔ<ì290KSXÉÉY"!33##!5ßþ)×!êÇÇÉý‡üëÍü3¤þœd¿ÿã-Õ=@"—‹Ž—
—ˆ
™ª
"üÄüÄìî1ääôìîöîþÄ90!!6632#"&'532654&#"ÏôýÄ+W,èþã÷wÅN\ºa§µ»§QšFÕªþ‘þîêìþð  Í21°¢ ²%%…ÿãLð$=@#—
—
«‹Ž—–™%"&
"%üììüäì1äôìôìåîî90&&#"6632# !2"32654&ß?ŽMÀÆ0ªnØíôÝþüò#J”þÝ””†ˆˆ´º%'þßþçdkþ÷óòþöu‘zýlº¤¤º±­®°‹7Õ5@%%B—ˆ"üìÄ991/ôì0KSXííY"!#!‹¬ýêÓý5ÕVú+ƒÿãNð#/C@%—'—-—–™'©0$*$	"!0üÄìüÄìîî991ìäôìîî990"32654&%&&54632#"$54632654&#"h‡“•…ˆ“•þÊ‘òÐÑò‘–ŸþþääþÿŸM€yz€{y€Å—ŠŠ™—Œ‰˜T!´²ÑѲ´!!ÈŸÊäãÉ Ébx~~xz€ÿãFð$;@"—«
‹Ž—"—–"™%"	&%üäìüìì1äôìîöîõî902654&#"532#"543 !"&T““†ˆ‡á?ŽMÀÅ/ªnØíóÞòþÝþëI”–º¤¤º±­®°ý‰º%'!dk
ôñ	þŠþoþ‡þséå'@
¢¬¢Ô<ì21/ìôì03#3#éüüüü'þÑþ9þÏ“þáò'	%@¢£¢¬

ÔüÔüÔÌ1äüìî03#3#öüÅšc
üü/ÏþÇþÑXyw!@®­('üì291ôì90	5yü®Rûß!ÁþÀþ÷¢¦¢X`y¢@  Ô<Ä21ÔìÔì0!!!!X!ûß!ûß¬BªXyw!@®­('ü<ì91ôì9055X!ûßRÁ¶þ^¦þ^·=ôð"{@B
	%%B‹—–†! 	 		) #ÔìÄÔÔìî99991/îöþôîÍ9990KSXí9í9Y"#546776654&#"566323#¬¾=TZ>/ƒmN²b^¿hºÝC^XE&ÅËË‘šb‰RY;X1YnED¼98À¡Lƒ\VBT=/þòþþÁšs4p@1(+$	4¯	¯'$¯+¯1+5'
(+
.!+-.5ÜìüÄþ<Äî991ÄÔüÄþÄÕÄîî999990@
€€€€€€]4&#"326#5#"&5463254&#"!267# !2€kkkk€Œ%ƒR¡ÓÓ¡P†$°‘öþÝJ6l90?{:þ›þ]x<Ñú!››‚››þèo?Dò¼¼òF=?œ¾þþ¹þ·þz‡ÒŒ†Îþöà%¬Õ
˜@A%%%%	%
%
%

%
B—°ˆ			/
Üì91/<äüì90KSXííííííííY"²]@
	†‰]]!3#!#hÕªþ±õÉÑnýõlÑ#ý®ú+…þ{¦qÕ =@#—
	—ˆ—
±21	0!üì2üìÔì9991/ììôìî9032654&#32654&#%!2!!qï°–ž¨ïë’ƒ”þJºåøƒƒ“§þöþùþFÉýÝ{’‰fþ>p}qd¦Æµ‰žÏ ËÏ‹ÿã1ð.@³²—
³²—	–™210üì2ì1äôìôìîöî0%# !2&&#"32671M¢[þáþÃ?[¢MJªVÅÄÄÅX©I5))–pn™))Ï=@þÐþÍþÎþÐ@=‰RÕ(@—	ˆ—	210üìüì99991/ìôì0%26&!# !!´ÿÊÉÿ`dVDþ¼þªþѦûHKûûw/þ”þ€þ‚þ•ÕÅNÕ)@——ˆ—±
	13üì2üÄÄ1/ììôìî0!!!!!!ÅvýTŽýr¿üwÕªþFªýãªéXÕ	$@——ˆ±14
üì2üÄ1/ìôìî0!!!!#éoý\eý›ËÕªþHªý7fÿãPð<@!——
³²—	–™625üìüÄüÄ1äôìôìþÔî990%# !2&&#"3267#5!PQËvþäþÄ@^¬PQª_ÅÅ¿ÆCe)Ùš{KM—on™56ÏMIþÏþÎþÉþÕ!‘¦‰HÕ&@—±ˆ
1	0üì2üì21/<ä2üì03!3#!#‰Ë)ËËý×ËÕýœdú+Çý9ÉÕ%@
—ˆ—77	Ôì2üì21/ì2ôì20!!!!5!!É=þÇ9üÃ9þÇÕªûªªmÿã¼Õ,@²——
ˆ™	5üÔüÄ1äôìîöÎ990753265!5!#"&m[ÂhqþƒGÓ÷`¾=ìQQ•ËDªüþæê,‰ÉÕ—@!%	%B´
	0üì2À91/<ì290KSXííY"²]@L&&6FUWX	dzy{	',+&:IGG[WXXWkzx]]33	##‰Ëwíý»VôþšËÕýh˜ýžüì¤ý¸×sÕ@—ˆ14üìì1/äì03!!×ËÑüdÕúÕªVyÕ…@,
	B
´	
/
0
üìüì91/<ì2Ä90KSXÉÉÉÉY"²
]@$
		&)&)	6968	
]]!	!###V»þö™þõºÕýøú+'üíúÙ‹FÕ	m@B´10
üìüì991/<ì2990KSXÉÉY"²]@&)&8Wdjuz
&)FIWgh]]!3!#‹øÃÿþÃÕû3Íú+Íû3uÿã\ð#@	——–™2625üìüì1äôìî0#"32#"32‰‡š™‡‡™š‡Ó÷ýýö÷üý÷éIþæþ·þ¸þæIþzþ€~ˆ‡€þ€ÅuÕ+@——	ˆ
2
8	3üì2üì91/ôìÔì032654&#%!2###ꌜþL´úþÿûêÊ/ýÏ”……“¦ãÛÝâý¨uþò\ð=@ ——	–™2625üìüì99991Ääôìî9990"#"32#"32ú÷÷üý÷‰‹È—‡š™‡‡™š‡€†‡€þ€þyþÚþ™H¾d÷Iþæþ·þ¸þæÑÕj@8	
%%B—	—
ˆ	

21
0üì2üÄì99991/<ôìÔì9990KSXíí9Y"#&&###!232654&#øNnRËÙ²M{cÁË ö¡ýÐÝ‘Ž—Áo¦þhy¡]ý‰ÕÞÒ”»Yý‰‹ÿãJð'„@=
%	
%B
³§—³§—%–™(
&919"0(üìÄüìä99991äôìôìîöî90KSXí9í9Y"²]@
]].#"#"&'532654&/.54$32ô\¹^¦m•jÒÀþøüiÔksÍh™ªu‘lм
ßV¾¢Í;<…qch#1ÒµÕà--×ID‰{pv /¾ Èñ'/¢Õ@—ˆ::Ôìüì1/ôì20!!#!/sþ-Ëþ+ÕªúÕ+“ÿã=Õ,@	—™ˆ10üìüì1ä2ôì99903326766553#"&'&&“Ë yVWx!Ê9FBªjiªCE:=˜üm];<<;\l^˜ühåÁ?;::;>Å9˜ÕL@)%%%%B´/0üì91/ì290KSXííííY"%3#3h_ÑþKõþKѪ+ú+ÕÑÕá@D	
	
	


%%%%B
´
	/Ì91/<ü<Ä90KSXííííÉÉÉÉY"²	]@^
//+
??8
ZZ&*%*(+	%&5:5:;:	46TTZXWV[[RW	X]ghyvy	v#]]333##ŪӬÅß¿ËÊ¿ÕûD"üܾú+wü‰¾ÕÆ@K	%

%
%	%%%%%B´	;/;
0üäüä91/<ì290KSXííííííííY"²7]@8
'()&Xxyw!%+%5UYXes]]3	3	#	#VÙHNÙþAßÙþ’þuÚôÕýÍ3ýBüéƒý}%¬ÕY@.%%%%B´<<	Ôìüì9991/ì290KSXííííY"33#%×lkÙþ!ËÕým“üÉýbžœ‘Õ	E@%%B—ˆ—/0
üÄüÄ991/ìôì0KSXííY"²]²]!!!5!²Éüô"ü÷ýÕšûoªš‘Ïþòw@¶·¶µ=ÔüÄ21üìôì0!#3!ϨððþXùüfÿB7Õ@ˆÔìÔì1ôÄ0#%¾üíÕùm“Zþò@¶·¶µ=ÔÄ2ì1üìôì0!53#5þXððøÞH¨‰Õ@
ˆÔÌ91ôÌ290##ÁȲþ‘þ’²ÈÕýÓ‹þu-þþmµ¸/Ì1Ôì0!5üþmPPîöf1@	º¹<Ôì1ôì0K°	TK°T[X½ÿÀ@878Y	#Ýšþ»fþˆx…ÿã#{)n@*
 ¶Œ!‹ ¿Œ$¾™

D >*ôìÄüì22991/Ääôüôìîî99990@00 0!0"    
 ¢    ]#"326757#5#"&546;5.#"5>32¾=¡£zl˜®¹¹;³€«Ìûó÷†“^À[f»X‹Å=& 3qpepÓº)Lý¦d_Á¢»Â†y64¸''RR2“ÁÿãX0@	Œ	Œ™¾›GFôì22üì1/ìäôìî9904&#"3266632#"&'#3–ˆ…†ŠŠ†…ˆýã,›fÊèéËd™.¸¸/ÖÚÛÕÔÜÚxRXþÉþïþëþÅWSÃÿã%{/@‹
À‹ÀŒŒ	¾™FôÄ2ì1äôìþôîõî0%# !2&&#"3267%JRþüþÛ%QšNI“]­º»¬`˜A9++88*,ÁA:àÐÏá;>{ÿã0@ŒŒ™¾›GHôìüì221/ìäôìî9903#5#"3232654&#"Z¸¸.™dËéêÊešþˆ……‹‹……ˆÑCùìSW;7WþÖÚÜÔÕÛÚ{ÿãX{E@&
‹	¶Œ
ÁŒ¾
™	IHôìüìÄ991äôìäîîôî990!3267# 32&&#"Xüã¿®XÀmiÃ[þûþÚ ðÖ÷¸‘ˆ…¬^Z·È89·++9@þÞÅ¢©°œÃ'4@¶Œ›Â
	
Ô<Äü<Ä2991/ä2üìî2990#"!!#!5!5463'ÑcMþ¸þÕ+©³™Qgcü/ÑN¸®{þH{)H@''	‹	ŒŒŒ$¾Ã(Â*'G!H*ôÄìüì221ääÄôìîîÕî999904&#"326#"&'5326=#"3253Z‡‡Žˆ‡¸îçL¦Sb C•ˆ,˜mÄêêÄl–/¸9Ï××ÏÏÙÚþÝüþü¶.,¢°}^\::VZ‘Ã,@	Œ¾›
J
	Fôì2üì1/<ìôì990#4&#"#36632¹jq‹¸¸1¨s«©¶ýJ¶—Ž·«ý‡ý¤`cá²D	
.@¶Ä
›Â¶LLK
Ô<äìü<ì1/ì2äüìî0!!!5!!3#×münmþḸ`ü/BCéºþV
8@
Œ¶Ä›ÂÃ	Ô<ì2ÄÄ991ääüìîî990!5!##53263#XþÃõ³¥þêZZ¸¸åûŒÃÓœ}¥éì²Å@:		B›
	DEôìì291/<ìä90KSXííííííY"²]@R546Ffuv	('(;;797JIYYkiiiyxyy]]33	##ì¾ãàþGþáþb‰¾ü{ÑþZýFBþ? 

&@	
¶ŶL	ÔìüÌ991/ìüì99033#"&5!5![Y×饵þÙß–|~œÔÂùmo{"Ì@'	Œ ¾ÂMNMNME#ôü<üìüì91/<<äô<ì299990@G000000	0
0?????????€€€€€€€	€
€#]K°TK°T[K°T[X½#@##ÿÀ878YK°TX½#ÿÀ##@878Y>32#4&#"#4&#"#3>32¤"iJ‡o¨5FP;¨9JI9§§!c?LeîHEÑþßýwís{åýðp{åý``ôìüì1äôìî0"32654&'2#"hŒŒé÷öêéöößÚÖÕÛÛÕÖÚœþÒþâþáþÓ-.¾þVT{3@ŒŒ¾™ÃÂGFôì22üì1äääôìî990%#36632#"&4&#"326w¹¹.™dËçèÊf™ð‡…†ŠŠ†…‡ýÉ
SWþÆþêþïþÉWõÖÚÛÕÔÜÚ‰þRw3@	Œ	Œ¾™ÃÂG>ôìüì221äääôìî99032654&#"#"3253#L‡……‰‰……‡-™eÉéèÊd™.¹¹+ÖÚÛÕÕÛÚýŠSY7:WSùöjƒ{O@—¾	Â
ÔÄì21/äôìÔÌ990@%   0030@@C@PPPP].#"#3>32ƒ;zI¬¶¹¹.¿ƒDv6y.*ØÌýÓ`Ûw"$Õÿã{'u@@
	
B
‹À‹ÀŒŒ%¾™(
OI"E(ôÄìüìä99991äôìþõîõî990KSXí9í9Y"&&#"#"&'532654/&&54632ÍO S}{\·J‰ìÒS¶jg¼Tz†õEŸ’ÚÊZ¦9´..QSKJ#œ}¦»##¾55cY€1“¡¯!ƒž1@¶Â¶
	Ô<Äü<Ä2991/ìô<Äì2990!!33#"&5!5!f¢þ^^uÏáϪþÕ+žþÂý |b“¦Ë`>Ãÿã^,@	Œ™
Â
	JFôìüì21/ä2ôì990332653#5#"&økp‚й¹1©q¬¨¨¶ýJ—Ž·«yû¢¨adádm`e@)BÂIEôì91/ä290KSXííííY"²']@%]]3	3#d¿EF¿þrí`üT¬û Ñ`@E
	


	B
Â
	/Ì91/<ô<Ä90KSXííííÉÉÉÉY"²
]@Œ		
&&)&))#,96993<EI	FJVX	WYfifij	evzx|	r-


++>><
H
Y
jih
{yz|

]]333##¶Ã ¢Ã¶þú°³²°`üwBý¾‰û fýšL…`©@H
	


	B
Â
IEôÄüÄ91/<ä290KSXííííííííY"²
]@	fivy

:4
ZV
]]	#	#	3	^þo¸Õþ¸þ¹Õ¸þoÌ)'`ýèý¸Áþ?Hþk•hþV` @E


	


B
	ŒÃÂ
IEôìÄ91ä2ôì9990KSXííííí9íY"²8]@v
&&8IIY
]]+532673	3Z.Gc".Š\”mQ\GþOÃLGÃhu¿þø:NNš^ÄNü”lËb	X@B¶Â¶IE
ôÄì2991/ìôì0KSXííY"²8]@68EJWXejuz
]!!!5!ã-ý}ƒü»ƒý•b¨üÜ–ª%Ýþ²ô$f@5%	 !¶	¶Æ	Ƕµ%	
$
 =
%Ô<Äü<Ä299999991üìäôìî99999990#"&554&##5326554633#"3ô@ù©kŒ>>j©ù@FŒU[noZUŒ¾”Ýï—tr–ðÝ“WŽøŽŽœøVþ¾·µÔì1üÌ0#¾¬øÝþ²ô$j@7% ¶¶#ÆÇ¶µ%#=%Ô<Ä2ü<Ä99999991üìäôìî9999999032655467&&554&##53233#"##ÝDVZon[VD>ù¨k@@k¨ù>¾XøœŽŽøX“Ýð–rt—ïÝ”Xìy&@  'üÄ1Ôü<Ôì2990#"'&'&&#"56632326yKOZqMg3OIN’S5dJt]F‰®;73
!;?®<6
7=ÿÿ%¬N'$u%¬m!Á@W%
%%% %!%!
%!!%!B	—
È	
É  !
PPK/K!"Üäüäî2î299999991/<ææÖîî9990KSXííííííííY"²€]@…
ŠŠ…€
€€]]4&#"326!.54632#!#Y?@WX??Y˜Õªþ”:A rr¡@;¬ÑnýõlÑZ?YWA?XXüýP!yIr¡¡rIv$ú‰…þ{ÿÿ‹þu1ð'&ÝdÿÿÅNk'(uÿÿ‹F^'1ÿîuÿÿuÿã\N'2uÿÿ“ÿã=N'8uÿÿ…ÿã#f'Dÿÿ…ÿã#f'DCÿÿ…ÿã#f'D×ÿÿ…ÿã#'DŽÿÿ…ÿã#7'DØÿÿ…ÿã#'DÜÿÿÃþu%{'FÝhÿÿ{ÿãXf'Hÿÿ{ÿãXf'HCÿÿ{ÿãXf'H×ÿÿ{ÿãX'HŽÿÿ²Df'Öÿÿ²Df'ÖCÿÿ²Df'Ö×ÿÿ²D'ÖŽÿÿÃ7'QØÿÿ‰ÿãHf'Rÿÿ‰ÿãHf'RCÿÿ‰ÿãHf'R×ÿÿ‰ÿãH'RŽÿÿ‰ÿãH7'RØÿÿÃÿãf'XÿÿÃÿãf'XCÿÿÃÿãf'X×ÿÿÃÿã'XŽ¢ÿ;/Õ'@Ë
ˆÊRQ	RÔ<ìü<ì1äôÔ<ì203!!#!5!±nþ’±þ’nÕþ\™û£]™+u¦ð @Ì	ÍÌ–STSÔìüì1ôìüì02#"&546"32654&hAu,-/º†‡´¸…OomOPqpð1.-rB„·´‡†ºoPPlnNOpÕþÇ%˜!N@*‹	‹Ë˾™
"E"ôìÔ<Ô<<ì221Ää2ô<Äìþôîõî990&&'667#&5473%C‚??ƒBI‚9gáþüÞg9‚þÞ„  5¬(,üš-(¬"þâ9ûú=þá"ü+`츸ë‹Xð>@ 
¶‹§—–—
	Ô<ÄÄü<ÄÔÄ1/ì2ôìôìÔ<î2990&&#"!!!!53#5354632D>C†sþü3ìÇÇÛßA‰¶¸,,³ÀÙþ/ªªÑîþúÇÿ=ð2>j@<#$93$*ÎÏÎÏ0–?#=÷><¶¤''PGZswšeZŒ54m@ލ¤''TLf{x™f[1,pE‚ŸýÕ-Z/L‡…-Z/Lˆ?Ñ‘!·	ÐVÔì1Ôä04632#"&?¬}|­®}|«ú|«¬{|­«jÿ;Õ
#@ˆWW1ÜüüÔì91Ä2ôÄÌ0!###&&54$FÀ¿×ìÕùfùáNݸ¾è¼ÿã}/V@1-'!
 *‹Œ*Œ›™.	
 !'	$'$-DF0ôìüÌÆîÔîî99991/äþîþÕî9904632#"&'532654&''&&5467&&#"#¼ÒØÌÒ›¨7C:—oàÄE‡BL…;l€AxC\[¢œyqyr»qÕÎÝØ|d1M*%]¤tš²¤aQG_J'8…O€«#krƒ‹û“}ÑN4L…@I
]	
	]

	B
	
××
ÖAÔ)Õ5Ô)ÓÑM	\\
[G#X;#Y//æþåþõÄîî299991ôìüäþí2îÖî9990KSXíí9Y"2#'&&####32654&2#"&'&&546766"32676654&'&&X“XP:&rk1=-7‚èffZJJDÚZZ\[[[Ú~}Ú[[[\ZZÚ~jµKKMMKLµijµLLKLKKµLbeG]C;º®P*þضTè6?>5VZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZgJKK¸jh·KLLLLLµij¸KKJ}ÑN1ID@'
Ú
ÚÜ&Ô>ÚÚÙÔ>Ó2ÑJ\
^,8 8YD/æþÅþå2î1ôìüôìÔìþýîÖî0&&#"3267#"&54632'"32676654&'&&'2#"&'&&546766`:o:u‡Œ‚8g24r=´Ïг=rÄjµKKMMKLµijµLLKLKKµkÚZZ\[[[Ú~}Ú[[[\ZZÚ/l•€„ŽhȬ­Ê¡JKK¸jh·KLLLLLµij¸KKJgZZ[Ü~}Ú[[[[[[Ú}~Ü[ZZ“fÕh@6	
	

				B	×
ˆ
	
``_`_/üþìÕîÖî91ô<<ì2Ô<<Ä90KSXÉÉÉÉY"###5!3###¶¢r¢´‰}¬rœ7¦qÕ^þä^ÿý¾âþÓ-þBÛîºf1@	º¹<Ôì1ôì0K°TK°	T[X½ÿÀ@878Y3#ôÆþ»šfþˆ?F‘\@ÞÝaaÔüÔì1ô<ì20K°
TK°
T[K°T[X½@ÿÀ878YK°
TK°T[X½ÿÀ@878Y3#%3#?ËˈÊÊÊÊÊX%yÝ<@ 

 
 
	Ô<Ä291Ô<Ä2ü<Äþ<Ä990!3!!!'7#5!7!X‡ö}¤Ëþ²¸ýyø}¤ÉJ¸ýþ¢;fÕªì¬þÅhÓ¬ìœÕg@7
%%%%B———ˆ—°±
	

c
/Ô<î2ÖÄÄ91/<îîîôî2îî0KSXííííY"!!!!!!#!‰þ®3þÍeýáþ e¸šxÊ5ÕªþFªýãªþÕªüüÿº°	+k@:+)&
	 *&——&–™, #*
	#)+262#5,üìüìÀ999999991/äôìîÀÀ9999990324&'&&#"#"&''7&5327sƒTš‡

ýÝøsVƒ»)+÷ýy´=g² %÷üs­9‹d/NZInˆ-ýËÏQUþÜþ†PeæQþþ£þzþ€QQËFüIž‡€RPÉJ)ú¨ð/7@$	á'!â	á-ß0$dd*0ÔìÔì99991ü<ì2ü<ì299032654&#"&&#"32676632#"&'#"&54632¶9[=G[TFBiË8\=G[SDCj~/“[w¬£~S€NA„U}¦„^ˆsˆd†lk€ut†c…jmvÿuÛ §Ôdƒ|kÖ¥­ÎsXy“.@	ã ã
 
Ô<ì2ü<ì21/ìÔ<ìü<ì07!!!!#!5!X!ûßd½þC¨þD¼ªª“þ·ªþ´LªIVw?
(@åä (	'ü<ì2291/ìôì905!5wûß!üß!ûß¶¶L¨K¸çþ
ªªXy?
(@åä 	('ü<<ì291/ìôì90%%5!!X#üÝ!ûß!ûß¶êç¸þµ¨þ´Vª%¬Õ@D%	%		%%Bç
çˆ<e
	e<Ô<ìì2ü<ì2ì99991/ä2Ô<ì2Ô<ì290KSXííííY"333!!!#!5!5'!53%×lkÙþ¶üþÅV‘þoËþqZþËóÕým“ýÏo—#oýôo#—oÃþTž` L@*	Œ‹™Ã
Â!	 	JF!ôìüìÄ9991ä2äô<ìüÄ9903326533267#"&'#"&'øxo¹ !	&D">K.…Y\,þTýHŽ—ª¦ü ;8

”OOPNLPýÕ¾ÿç-):@'!	'!¸
@
*$$*ÔÌÜÌ9991äÌÜÌÎÎ9906654&#"#"&54632#"&54324&#"32JIH7$$0e´ÖþßÕ˜ËÝ¢e‚WOmVPmmW£Kƒt,>bþÊþùþ±þFØ£Æ[àt}þþÏt{þL=î7´	¿	@
Ô<Ä91äôìî990!!55!!LñüR%ýÛšý#
þÕ‰\—P_ŒüݘþL9î¹@€€ÔìÔì1Ä2Ôì0!#!˜¡›ý•þL¢ø^øâPÿÙžL?@!
êêèì
hggfôìÔìäÄ91/äôì22î99990!#3267#"&5!##P117,#J%q\þT´L”ý@H?…
ƒ°¬üH¸þL%1¹ ²
½@	&
‚&Ôìüì1üìÜäÞä026732#"&'&&#"#"&54632‰j¾ÊPd@7*9	k½ÄOeD=!0	þú°l9¼TA6?&#Hý•Ánþ!þbSA8?TÕÁð
%)d@6	(ó&í&ñí ïîíð#–*&	('
	jkji*üìÄüì22ÀÀ9991ôäüôìÄîíÖîî99990"326557#5#"&5463354&#"56632!!¬|WHiƒ1ƒR–»¬¶wu3}CD‡?¸¬ýkœýdPDN@Ms=þ@pABˆtŒZ\#!¬ý{ôÕÝð3@óñíðí–		jkjiüìüì991ôìôìüì0"32654&'2#"&546!!hfssfeusgªËÊ«ªÊË«¤ý\{œ‹‹šˆ‹œu༻ßß»¼àü`{J‡´>@#ø÷ùqqroprol ôìäôìäää991/<î2öî0353&5323!5654#"Jõ{n ðò!o{øþ1x†´šš³†x¬† ¼7oþ’þȼþß…¬¬LIÞæ	þ÷æÞþ·L¬)ÿã°{
C@I=706%C‹Œ"7‹6¿.¶Á3Œ@:¾("™D%=/.M/uMCM6+sDôÄìüìÄüÄì29991ä2ô<ì2ô<ì2ôîþ<ôî999990@	05060708]5#"32654&#"!3267#"&'#"&546;54&#"5>32>321©xYS\JíMWWLëþepO27„Gn• '…aœ£È¿uc^8„>M„<[|%!„Y®‘ºHZqYa…4—…ˆ+#"¡33¬)+RNPP¬¤«³Xx€+'¨#!?@=BíþÎ/ÿ –¼	+s@>+,&

)& 
*&Œ&
Œ¾&™,+,* #
)#D>,ôìüìÀ999999991äôìîÀÀ9999999032654&'&&#"&&5327#"&''mþ1$eAH#cC‹•‹')öédž<“]¤*,öêg9 \ýÑ//ÛÕ4o¯0.ÖÊ0tG GÃq.78°MÃBÁzþáþÓ;<ºLÁÿåÝÕ!%‚@G
	%%B!‹"†$—™$ˆ&#	#	)"#&ÔüÄÔìÖî99991äôìþÍôî9990KSXí9í9Y"33267#"&546776654565#53%¾=TZ>/ƒmN²b^¿hºÝC^XC&ÄÊÊDšb‰RY;X1YnED¼98À¡Lƒ\V@T?þÏÕ	@†ˆ
Ô<ì2991/ôüÌ0533ËË¡×þþû)eþ›ýqXsy^@ 'üÔì1ÔÄì0!#!X!¨ü‡^þ?;ÿÙ  
/@

	ÔÄ991ÔÄÀÀ90'%3##d)#ÛÓ”/þöÝ}bý%¿ƒù¼9þV°#ˆ@N
B

¶ú¶ú¶!›$	
/Ì91Ä2Äüìôìîöîî299990KSXíí9í9íY"&&#"!!#"&'53267#5!6632°$R,fs-/þ¸d+Ǻ9f.1d0`yuü1Æ”1cð¤|‚þÉý…þöæ¤!–—¯J±ÉX1yÃ7K@&' 10+5  *  5' .810*8Ô<Ä2991Ô<ìÔì2Ü<üÔ<ì99990#"'&'&&#"56632326#"'&'&&#"566323326yKOZqMg3OIN’S5dK
t]F‰JKOZqSc1NJO’R`‚t]DŠï;73
";@®<7 6<þа;83
$77
7=ÿúÙO@*iiiiBùûÔÌ91/äì90KSXííííY"#3	!ÑýþáúqÃûéw#
/@	ü¬	
vvÔü<Ôì2991ô<ì299055LþÓ-þ+›þÓ-þ+#¿þôþô¿¢R¢¿þôþô¿¢RÁ\#
/@
ü¬vv
Ô<üÔ<ì991ô<ì29905%5‡Õþ+-þÓþ:Õþ+-þÓ#þ^Rþ^¿¿þ^Rþ^¿P1#@¢
	ÔüÔìÔì1/<<ì2203#3#3#Püü3üüþfüü1þÏ1þÏ1þÏÿÿ%¬k'$uÿÿ%¬^'$uÿÿuÿã\^'2uHÁÕ;@—
—ˆ—±	
-ÜìüÄÄÔì299991/ìì2ôì2î0%! !!!!!"33Áý£þÙõô(RþšHþ¸þþ±‹‹±=ªªMœ¡KªþFªýãæþ¤þ¦åÿãº{
8i@92/	& 8 ‹¶Œ#ÁŒ5/¾)#™92&	MuMCM,s9ôìüìÄüì29991ä2ô<ì2äî2îôî9999904654&#"265&#"!3267#"&'#"326632PVWMþ¦fRPhgPP¬þcpPƒ/;}Jb“04€T½ªª½Y€/%‚W¯‘&	‘‡‰ž+ýê¨ï#®§þóþó§‡T£53¬+)CBDA88>A>AíþÎìÑy¶¶ý/Æ1üì0!!Ñû/yìÑyµ¶/Ä1Ôì0!!Ñû/yÓÇþ%@£	µ	
ÔÌÔìÔüÔÌ1ü<ì20#53#53œüÄšbþ5þÇ™bÇÏ~þ‚ÏÏ~þ‚ÓÇü'@	£µ	
ÔìÔìÔÌÔÎ1ü<ì203#%3#üÅ™bþ5üÄšbÎþÎÎþÏÇ-@£µÔüÔÌ1üì0#53ËüÄšbÇÏ~þ‚ÏÇ-@£µÔìÔÌ1üì03#1üÅ™bÎþX–yo'@þþ 
	wÔ<Äü<Ä1ÔÄüÔìî03#3#!!îõõõõþj!ûß‹õÙö¢ªuþ#\u"@ÔÌ91ÔÌ990	hþþôþþ
üÏüÇ9%ûÛûÓ-ÿÿhþV'\Žÿÿ%¬N'<ufÿB7Õ@ˆÔìÔì1ôÄ03#y¾üî¿ÕùmÍÃLB/@ (-
	*-'!	ÿ¸@'ÿ)
-0)$ 
!'$*xyx( $0ÔÄ2ìüÄ2ì9999999991ÔÄ2ìüÄ2ì99999999904&#"3267'#"&''7&&5467'76632d|[Z}}Z[|¦Z¦¨^¦.[20`0¤\¦¨^¦.[3.^ƒZ{{Z\}~t¦]¦1]02[-¦^§£Z¦3].2]-¦_¨Z/#@ü¬vÔì291ôì905/þÓ-þ+#¿þôþô¿¢R¤y#@ü¬vÔ<ì91ôì905¤Õþ+-þÓ#þ^Rþ^¿#7N@*	¶
ŒÄ››
Â	
	JEEô<äì2ü<Äî2991/<æìþîîî299903#'#"!#!##535463¸¸w´cM“¸þ%¸ÉÉ©³éë™Qgeû¢Ñü/ÑN¸®#7B@#
¶Œ›Â		JE
Eô<äìü<Äî991/<æþîî29990#!"!!##5354637¸þÕcM%þÛ¸ÉÉ©³ùì{Qgeü/ÑN¸®¢ÿ;/Õ<@ËË
ÊˆR
Q	RÔ<<ì2ü<<ì21äôÄ2Ô<î2î20%!#!5!!5!3!!!/þ’±þ’nþ’n±nþ’nßþ\¤š™¤þ\™ýáé/å`¹µÔì1Ôì03#éüü`þÏ“þáò/²£¸¶ÔìÔÌ1üì03#öüÅšc/ÏþÓþáü/*´	£¸@
	
ÔìÔìÔÌÔÎ1ü<ì203#%3#üÅ™bþ5üÄšb/ÏþÏÏþј'3?Kt@%1=
ÈÈ1¸µ%È+‘C¸@&7ÈIF:4(:PFz4P@
PzP"P.zP@(/ÄìÄôìîöîîöî99991/<î2î2öîþîî299990'32654&#"4632#"&32654&#"4632#"&32654&#"4632#"&H%'üH_EDbcCE_y¥xx¦§wy¤LaEEacCEay¦yx¦¦xy¦aEF`bDEay¦yx§§xy¦7aŸ`ýJGacECcaEy¥¦xy¨¦ÓEaaECcaEx§§xy¨§ý"GaaGCcaEx¦¦xy¨§ÿÿ%¬m'$uÿÿÅNm'(uÿÿ%¬k'$uÿÿÅNN'(uÿÿÅNk'(uÿÿÉk',uÿÿÉm',uÿÿÉN',uÿÿÉk',uÿÿuÿã\k'2uÿÿuÿã\m'2uÿÿuÿã\k'2uÿÿ“ÿã=k'8uÿÿ“ÿã=m'8uÿÿ“ÿã=k'8u²D`	"@¶Â¶LLK
Ôäìüì1/ì2ôì0!!!5!!×münmþá`ü/B)î¨f7@º¹Ôì91ôì290K°	TK°T[X½ÿÀ@878Y3#'#“ö‹µ´‹fþˆõõ²7»@!ÌÌPPÔìÔì99991Ô<üÔ<ì99990K°	TK°T[X½ÿÀ@878YK°TX½@ÿÀ878Y@?	
	

]'.#"#>3232673#"&d9!&$|f['@%9!
'$}f['@Z7JQ†”!7JQ†”=b“ö¶¶ÔÌ1Ôì0!!=Výªö”/)¢H
8¹@¹PPÔìÜì1ô<Ôì0K°	TX½ÿÀ@878Y332673#"&/w`WU`wž‘žHLJJLDÏ6@	ÞÝaÔì1ôì0K°
TK°
T[K°T[X½@ÿÀ878Y3#ÍÍÌVá{W²È	¸@ÈP{PÔìôì1Ôìôì0K°	TK°T[X½ÿÀ@878YK°	TX½@ÿÀ878Y#"&546324&#"326{ŸtsŸŸstŸ{X@@WW@@Xôs  ssŸŸs?XW@AWX‹þu)'³	

º@		|ÔìÔÌÄ1/öþÅ90!#"&'532654&'¼85xv-W,"K/:=,,>i0Y[ƒ0.W=XîfZ@º¹ÔÜÔÌ991ô<ì20K°	TK°T[X½ÿÀ@878YK°	TX½@ÿÀ878Y3#3#ªà‰³ø‡fþˆxþˆ¤þu"³
¸@	
|ÔìÄÔÌ1/ÔüÄ90!33267#"&546w-+76 >&Dzs5=X..…

W]0i)î¨f7@º¹Ôì91ô<ì90K°	TK°T[X½ÿÀ@878Y373ö‹´µ‹öîxõõþˆÿösÕ
7@
—ˆ1	4ü<ìì2.9991/äì903%!!'7×Ë;NþwÑüd‘PáÕý˜Ûoþîýãª;jnžL
>@!
	¶Å¶
	Ô<Ìü<Ì2999991/ìüì999033#"&5'!5!%[Y×饵þÕP{þÙß;Pþu–|~œÔÂ$Ño/ý¾Ûnþíÿÿ‹ÿãJm'6uÿÿÕÿãf'Vàÿÿœ‘m'=uÿÿËf']àþ¢¾˜!¼·Ô<ì21ÔìÔì0##¾¬¬¬˜ý
öüý
öNÕ;@!¶
—ˆ
—

21	00ü<ì2ìüìÄ91/Æ2îöîî20 !!#5326&!#!!´VDþ»þ«þÑ}}/ÿÊÉÿ`þøÕþ”þ€þ‚þ•Å•{úÑûHKûþ+•ýá‰ÿãH)‹@O
BŒ$Œ™›*'!	!'D!	>*ôìüì9999991ìÌôìî99990KSXííí9íY"#"32&&''7'3%&&#"32654&ÍŶûåäûûà"#!H&þéí¶Û!!®#R-’™”ˆ‰”:/Ôþ„ÈþôþØ(	(-Y,\bPÈ‘^bþ

ÒÇÄÔÔÄnËÿÿ%¬k'<uÿÿhþVf'\ÉÕ4µ——¸@	ˆ28
	3üì22üì99991/ôüìÔì032654&#33 !##“êžžþLÊþøøþüþÊ!ý󄃃ƒ´þòÒÚÛÑþ‘¾þVT3@ŒŒ™¾ÃÅGFôì22üì1ìääôìî990%#36632#"&4&#"326w¹¹.™dËçèÊf™ð‡…†ŠŠ†…‡ýÉÉý²SWþÆþêþïþÉWõÖÚÛÕÔÜÚX-y×¶ ÔÄ1Ôì0!!X!ûßת–®;T.@
	
		Ô<Ì91Ô<Ì2907–^þ¢t^_tþ¢\tþ£þ¤%\^uþ¢^uþ¢þ¤w^þ¢Xœ“ß
9A				
	@
–aW}aÔììüì1ôìäÔìî2035733!jÍßåŠÌý×
c)t'ý+nBœ}ða@WWBA			
	@–ÔÄÔÄì9991ôìäÔìî990KSXí9íY"!!576654&#"56632ãšýÅçeQdR1q?Ay;ެJwrnâaz3=L$$}…k9wuFœð(\A	
		
		 
	@#–)
&	)ÔÄÄÔìÔì991ôìäôìîÆöîî90#"&'532654&##532654&#"56632Û^c¾±:r;Eq-evnmBJ]b`W,p;Eu2‘¨X`lP|†yQDJLl?<8?yvcG]ÿÿþòZ{'ðþþœ'	
¸üVÿÿþòZ{'ðþþœ'	ñÉüVÿÿþòZŒ'òÿœ'	
¸üVÿÿfÿãPm'*uÿÿ{þHH'JÚÿÿÉP',uÿÿ‹þuJð'6ÝÿÿÕþu{'VÝÿÿ‹ÿã1k'&ZuÿÿÃÿã%f'FZÿÿ‹ÿã1m'&ZuÿÿÃÿã%f'FàZ{ÿãÑ$H@	
"ç	¸@"ŒŒ™¾›
GH%ôìü<Äü<Ä1/ìäôìîý<î2990!5!533##5#"3232654&#"ZþÏ1¸¿¿¸.™dËéêÊešþˆ……‹‹……ˆÑ5y••yúúSW;7WþÖÚÜÔÕÛÚdßmƒ¶ ÔÄ1Ôì0!!d	ý÷ƒ¤é/å`¹µÔì1Ôì03#éüü`þÏ%ÿã%ð3p@<
ç1&ç³ ²—(#³²
—–#™43('1)-&-
2'-4ÔÄÄ2ìÄ2Ä99999999991äôìôìÆ2îöîî2Õ<î2032&&#"!!!!3267#"#73&'&54767#7Ó0ßT“JBŸN’®á1þFi1þÓ®“OCH”Uâþí,®1u¦1´!(*Ï=DÐÌl-.&nËÑC>Ï*( n-/l?‘ÙQ@
ÞaaÔüÔì1Ô<ì20K°TX½@ÿÀ878YK°TK°
T[X½ÿÀ@878Y3#%3#?ËˈÊÊÙËËËÛîZökµÔÄ1ÔÄ0K°TX½ÿÀ@878YK°TX½@ÿÀ878Y@&

//////]]3# ºåšöþø²éÑ@ÌÌ	ÔÄÔÄ99991Ô<üÔ<ì990K°TK°T[X½@ÿÀ878Y@t		


!

]]'.#"#4632326=3#"&d9#(}gU$=19#(}fT"<9!2-ev
3)dwyîööiµÔÄ1ÔÄ0K°TX½ÿÀ@878YK°TX½@ÿÀ878YK°TX½@ÿÀ878Y@
//]#1Åšãöþø7îšø]@	ÔÄ91Ô<Ä90K°TX½ÿÀ@878YK°TX½@ÿÀ878Y@//,	]3#'#
½ÓŒ¦¥Œøþö²²7îšøi@	ÔÄ91ÔÄ290K°TX½@ÿÀ878YK°TX½ÿÀ@878Y@
//*//]373
ÓŒ¥¦ŒÓî
²²þöøZj@
ÔÄ991ÔÜÔÌ0'3$øllœß

5³¸	²º
@	W	ÔÔ<Äì291ôôÔ<ì29033##5!5!w¢ttŠþ}ƒþîßýæoººy“þc/¢ø
²¸@	PPÔìÔì1ÔüÄ20332673#"&/wdRSawŸžø6978w{zÏÛ·ÞaÔì1Ôì03#ÍÍÛÍ	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßà>: ~ÿ1BSax~’ÇÝ©À & 0 : ¬!""""+"H"e%Êûÿÿ  0AR^x}’ÆØ©À  0 9 ¬!""""+"H"`%ÊûÿÿÿãÿõÿØÿ ÿ^ÿCÿhÿüöüÛà–à…àVßjÞqÞ_Úï¿8ôüúúü (B¬£„…½–熎‹©¤ŠÙƒ“ñò—ˆÃÝðžªóôõ¢­ÉÇ®bcdËeÈÊÏÌÍÎèfÒÐѯgï‘ÕÓÔhêì‰jikmln oqprsutvwéxzy{}|¸¡~€ëíºýþÿøÖùúãä×àÚÛÜßØÞ²³¶·Ä´µÅ‚‡«˜¨š™î¼¥’”•ÑhÑÑÑÑRÑѾÑ!Ñ9ÑѪÑ\ѦÑXÑ“ÑdÑéÑfÑ…ÑöјщÑfÑÑ…Ñ‹уÑÑéÑ“ÑXÑXÑXÑôÑÑ%ѦÑ‹щÑÅÑéÑfщÑÉÑmщÑ×ÑVÑ‹ÑuÑÅÑuÑÑ‹Ñ/Ñ“Ñ9ÑÑÑ%ÑœÑÏÑfÑZÑHÑÑÑ…ÑÁÑÃÑ{Ñ{ÑÃÑ{ÑÃѲѺÑìÑ ÑmÑÃщѾщÑjÑÕуÑÃÑdÑÑLÑhÑËÑÝÑÑÝÑXÑ%Ñ%Ñ‹ÑÅÑ‹ÑuѓххххххÑÃÑ{Ñ{Ñ{Ñ{ѲѲѲѲÑÃщщщщщÑÃÑÃÑÃÑÃÑ¢Ñ+ÑÕÑ‹ÑÇÑ?ÑjѼÑÑÑÑÛÑ?ÑXÑÑÑ)ÑXÑVÑXÑ%ÑÃѾÑјÑPÑÑÑôÑJÑ)Ñ/ÑÁÑÑXÑ;ÑÑXÑÿúÑwÑÁÑPÑÑ%Ñ%ÑuÑHÑÑÑÑÓÑÓÑÏÑÏÑXÑuÑhÑ%ÑfÑÍÑZѤÑ#Ñ#Ñ¢ÑéÑ“ÑÓÑÑ%ÑÅÑ%ÑÅÑÅÑÉÑÉÑÉÑÉÑuÑuÑuѓѓѓѲÑ)ÑÑ=Ñ/ÑÑVÑ‹ÑXѤÑ)ÑÿöÑLÑ‹ÑÕÑœÑËÑÑщÑ%ÑhÑÉѾÑXÑ–ÑXÑBÑFÑÑÑÑfÑ{ÑÉÑ‹ÑÕÑ‹ÑÃÑ‹ÑÃÑ{ÑdÑéÑ%Ñ?ÑÛÑÑyÑ7Ñ7ÑÑÑ/Ñÿ+
	

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóõôöøùúûüýþÿ	

	sfthyphenperiodcenteredEuroc6459c6460c6461c6468c6470c6472c6477c6478c6475c6476%%%%KmËJÍz‘½é6b•ªÄ‡²
i§õP~çAbŒ²Ó÷jô	\	°	õ
.
[
‚
Ó
þ)^ÅáAÎ

[
Á?`§ámï2l©Êì)žæ*rÆdœÐ‰µO†ÂT›JÇláV™þ|¼Écp}Š—¤±¾ËØåòÿ&3@MZgtŽ›¨µÂÏÜéP²ûŒ¬ÙJþ ‹ å!!M!!ê"l"Î##3#a#Ë$#$€$·$Ú% %u%æ&-&€'('©(#(J(f(—))Ž)Ë**A*m*m*z*‡*”*à+k+€+”+Á+ï,,),V,€,,š,´-?-`-ƒ-Ò..W.o..½/e/r//Œ/™/¦/³/À/Í/Ú/ç/ô0000(0O0|111S1{1Í22C2t2¢2Û3"3/3<3I3V3{3É4S4`4m4­4ö55E5x5Ñ696J6[6l6y6†6“6 6­6º6Ç6Ô6á7>7T7l7ô8/8r99K9‹9Ò9í:$:N:d
MF@WmþÑÿöÿøÙ
ÑGÌþBGÌSf	€¯ JBits@ ûþšmãB¹Ñ`#cÕVeraSansMonoÿÿÿÿ6ÿÿþ628R00@	

																																																																																																																																																																																																																																																																													



















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































ÿÿ䥉ë_<õºÀÂlÿöþÙmtome-235-src/lib/xtra/font/XM10X17B.FNT0000644000076400017500000000632611012107762015026 0ustar  dgdgYž
 ~xm10x17b.fntX_misc_bold€€€€€?À?À€€?À?À€€?€m€l€?ÀÀÀlÀ€?€9€;€3€1>ccb"cc@c€?€@€€€€€€€€€€3€3??0 ?€?€ÀÀÀ€00;€1€1€1€1€1€1€;€<,??€?À0À`À`ÀÀ€8ÀÀ€À`À`ÀÀ€€À`À`ÀÀ€€€€
€€€1€?À?À€€€ÀÀ``o€ÀpÀ@@`ÀÀ?€€?ÀpÀ``o€À`À`@pÀ?À€?À?ÀÀÀ€€9À0À0À€€0À0À9À€€9À0À8ÀÀÀÀÀ1À?€€00€?À?À?À?À€ÀÀ€€ À ÀÀ€€?ÀpÀf@o@i@oÀfÀ``À?À€€9À0À0À0À?À?À0À0À0À0À?€?À0À0À0À?€?€0À0À0À?À?€€?ÀpÀ``````pÀ?À€??€1À0À0À0À0À0À0À1À?€??À?À000??000?À?À?À?À000??00000€?ÀpÀ```aÀaÀ`ÀpÀ?À€`À`À`À`À`ÀÀÀ`À`À`À`À`À????ÀÀcc>`ÀaÀc€gn||ngc€aÀ`À0000000000?À?À`À`ÀqÀ{ÀÀnÀdÀ`À`À`À`À`À0À0À8À<À<À6À6À3À3À1À0À0À?€qÀ`À`À`À`À`À`ÀqÀ?€?€?À0À0À0À?À?€00000?€qÀ`À`À`À`ÀfÀgÀsÀ?€ÀÀ?€?À0À0À0À?À?€>73€1À0À€?À0À00?€ÀÀÀ0À?À€€€0À0À0À0À0À0À0À0À0À0À?À€`À`À`À`À1€1€
0À0À0À0À0À0À6À6À6À9À9À0À0À0À9À€€€€9À0À0À0À0À0À0À€?À?ÀÀÀ€80?À?À€€€€008€€ÀÀ€€€€€€€€€€€€€9À0ÀÀÀ€ÀÀÀ?À0À?ÀÀ0000?€?À0À0À0À8À?À7€€?À0À000À?À€ÀÀÀÀÀ?À0À0À0À1À?ÀÀ€?À0À?À?€0?À€€ÀÀ??À?À1À0À0À?ÀÀÀÀ?À?€00007€?À8À0À0À0À0À0À€€€€€€€€€€€1€1€?€0000À1À3€7<<73À0À€€9À?À?À6À6À6À6À6À7€?À8À0À0À0À0À0À€?À0À0À0À0À?À€7€?À8À0À0À0À?À?€000À?À1À0À0À0À?ÀÀÀÀÀ7€?À8@00000€?À0?€ÀÀ?À€€€ÀÀ€0À0À0À0À0À1À?ÀÀ0À0À0À€€0À0À0À6À6À?À9À0À0À0À€€0À0À0À0À0À0À0À0À?ÀÀÀ?À?€?À?ÀÀ€?À?ÀÀ@@À<##<8ÀlÀc€€tome-235-src/lib/xtra/font/7X13B.FON0000644000076400017500000001200011012107762014460 0ustar  dgdgMZ‚ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE…ƒ0@H|……†	
	€P,€0€FONTDIR7X13B,FONTRES 100,75,75 : 7x13b Bold (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢º
	Public domain font.  Share and enjoy.KK
°
0 	7X13BAŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿ
	Public domain font.  Share and enjoy.KK
°
0 	zz‡”¡®»ÈÕâïü	#0=JWdq~‹˜¥²¿ÌÙæó
'4AN[hu‚œ©¶ÃÐÝê÷+8ER_ly†“ ­ºÇÔáîû"/<IVcp}Š—¤±¾ËØåòÿ&3@MZgtŽ›¨µÂÏÜéö*7DQ^kx…’Ÿ¬¹ÆÓàíú0xüx0ÌÌ0ÌÌ0ÌÌØØøØØ<ðÀàÀÀ<0800pÀÀÀp84844ÀÀÀÀð<0800xÌÌx00üü00üüÌìüÜÌ0000<ÌÌHx0<000000ðððð00000>>00000000000>>000000þþ00000þþþþþþþþþþ000000>>00000000000ðð00000000000þþþþ000000000000000000`À`üüÀ``ÀüüülllìÌüü0üüÀ€8l``ð``l¸0000000000lll((||(||((0x´°x4´x0ä¬è0`\ÔœpØØØpÔÜØt880`00```00`0000`H0üü0H00üü00880`üü0x00``ÀÀ0HÌÌÌÌÌH00p°00000üxÌÌ8`ÀÀüxÌ8Ìx@À @ €@ @0€/?€@@€pà @ @ @ @ @ @ À@`pà @ @€€€		àà@@@@D@$€$€*€*€qÀ €

 € €qÀ8à@@@€€D8?À @ €@ @?À€@$€Ctome-235-src/lib/xtra/font/xm8x13b.fnt0000644000076400017500000000415211012107762015304 0ustar  dgdgYÓ
 ~
xm8x13b.fntX_misc_bold$$$~$$$~$$$*((

* PR$%<@@ 0IFF900k"   @@8 pppc``>c>~cccccccc>cccc666ccckkwwccfff<`````>?ccccc?>cc``>>?ccccc?>```~ccccccx~<```cflxlfc8<vkkkkccnsccccc>ccccc>~ccccc~``?ccccc?np`````>``<|~cccccg;ccc66cckkkk6ff<~0`~001IF Copyright 1989 Dale Schumacher, dal@syntel.mn.org
                399 Beacon Ave.
                St. Paul, MN  55104-3527
 Permission to use, copy, modify, and distribute this software and
 its documentation for any purpose and without fee is hereby
 granted, provided that the above copyright notice appear in all
 copies and that both that copyright notice and this permission
 notice appear in supporting documentation, and that the name of
 Dale Schumacher not be used in advertising or publicity pertaining to
 distribution of the software without specific, written prior
 permission.  Dale Schumacher makes no representations about the
 suitability of this software for any purpose.  It is provided "as
 is" without express or implied warranty.
FONT -Schumacher-Clean-Bold-R-Normal--13-130-75-75-C-80-ISO8859-1
COPYRIGHT "Copyright 1989 Dale Schumacher."
tome-235-src/lib/xtra/font/XM6X12B.FNT0000644000076400017500000000401311012107762014735 0ustar  dgdgYt ~xm6x12b.fntX_misc_bold0000000(((((|(|((@À0À8€À0À9€/€ÀÀ€yà0À0À0À0À0À0À0ÀÀàxà0@0@€€€

ñà`À`ÀdÀdÀ?€?€yà0À€€0À0Àyàyà0À0À0À€€Ll8?À0À1€À0À?À0€À€`,ÀG€tome-235-src/lib/xtra/font/10X20.FON0000644000076400017500000002100011012107762014426 0ustar  dgdgMZ} ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE…ƒ+@H|……†	
	€P,€0€FONTDIR10X20'FONTRES 100,75,75 : 10x20 (MicroX font)ÿÿÿÿÿÿo2'ƒ2)£2+Ã2-ã2/31#33C35c3ÿ39£3;Ã3=ã3?4A#4CC4ÿo4GóÿÿÿÿÿÏ4ÿÿÿO5Q#5SC5Uc5Wóÿÿÿÿ[Ã5ÿÿÿ_6ÿÿÿcC6ÿÿÿgƒ6i£6kÃ6mã6oóÿq#7sC7ÿo7wƒ7y£7{Ã7}ã78#8ƒC8…c8‡ƒ8‰£8ÿÏ8ÿï89‘#9“C9•óÿÿÿÿ™£9›Ã9ã9Ÿ:¡#:£C:¥c:§ƒ:©£:«Ã:­ã:¯;±#;³C;µc;·ƒ;¹£;»Ã;½ã;¿óÿÁ#<ÃC<Åc<ÿÿÿÉ£<ËÃ<Íóÿÿ=Ñ#=ÓC=Õc=׃=Ù£=ÛÃ=ÿÿÿÿ>ÿ/>ÿO>åóÿÿ>éóÿÿÿÿíóÿÿ?ñ#?óC?õc?÷ƒ?ù£?ûÃ?ýã?ÿ@”Copyright 1989 Network Computing Devices, Inc.KKu
0

 Ž10X20EW„EY¤E[ÄE]äE_Fa$FcDFedFg„Fi¤FkÄFmäFoGq$GsDGudGw„Gy¤G{ÄG}äGH$HƒDH…dH‡„H‰¤H‹ÄHôÿI‘$I“ôÿ•dI—„I™¤I›ÄIäIŸôÿ¡ôÿ£DJ¥dJ§„J©ôÿÿÿÿÿÿÿ¯K±$K³DKµdK·„K¹¤Kÿÿÿ½ôÿÿLÁ$LÃDLÅdLÇ„LɤLËÄLÍäLÏMÑ$MÓDMÕdMׄMÙôÿÛôÿÝäMßNá$NãDNådNç„Né¤NëÄNíäNïOñ$OóDOõdO÷„Où¤OûÄOýôÿÿP%PÿOPÿoPÿPÿ¯PÿÏPÿÿÿQ%QõÿeQ…Q¥QÅQåQR!%R#ER%eR'…R)¥R+ÅR-åR/S1%S3ES5õÿ7õÿÿÿÿ;ÅS=åS?TAõÿCETEeTG…TI¥TKÅTMåTÿÿÿÿÿÿÿÿÿÿ¨Copyright 1989 Network Computing Devices, Inc.KKu
0

 ¢z
z
¢
Ê
ò

B
j
’
º
â


2
Z
‚
ª
Ò
ú
"
J
r
š
Â
ê

:
b
Š
²
Ú

*
R
z
¢
Ê
ò

B
j
’
º
â

	
2	
Z	
‚	
ª	
Ò	
ú	
"

J

r

š

Â

ê


:
b
Š
²
Ú

*
R
z
¢
Ê
ò

B
j
’
º
â


2
Z
‚
ª
Ò
ú
"
J
r
š
Â
ê

:
b
Š
²
Ú

*
R
z
¢
Ê
ò

B
j
’
º
â


2
Z
‚
ª
Ò
ú
"
J
r
š
Â
ê

:
b
Š
²
Ú

*
Rz??€€UªUªUªUªUªUª@€@€@€@€@€@€fff~fff€|``x```€€333€€fv~~nf€fff<<€üüÀÀÿÀÿÀÿÀÿÀÿÀÿÀÀüÿÀÿÀ8à8ÿ€€€ppÀÀ?[3€€0€€€~|Vs€€À€333


?666€€€À€?mlll?


m?€€€€€9mm;663€€€€ÀÀ€666<8lfccv<À€€À003333€€€00``€€33aaaaa33€€€€€€€€€€€€`````nsaaaasn€€€€1````1€€3aaaa3€€€€€€€€€€€€€3a``1€€€~€€>cccc>`?aaa?€€€€€`````nsaaaaaa€€€€€€<€aa3€€€€€€€€€€€€`````cflx|ngc€<€[mmmmmm€€€€€€€nsaaaaaa€€€€€€3aaaa3€€€€nsaaaasn````€€€€3aaaa3€€€€€€€€€€€€o9000000€?a`?a?€€€€~€aaaaaa3€€€€€€€€aa33€€aaammm3€€€€€€€a33a€€aaaaaa3a3€€€€€€€€€€0`€€x€€xx€9mg€€UªUªUªUªUªUªUªUªUªUª@€@€@€@€@€@€@€@€@€@€@€@€@€@€@€@€@€@€@€@€10X20q$GsDGudGw„Gy¤G{ÄG}äGH$HƒDH…dH‡„H‰¤H‹ÄHôÿI‘$I“ôÿ•dI—„I™¤I›ÄIäIŸôÿ¡ôÿ£DJ¥dJ§„J©ôÿÿÿÿÿÿÿ¯K±$K³DKµdK·„K¹¤Kÿÿÿ½ôÿÿLÁ$LÃDLÅdLÇ„LɤLËÄLÍäLÏMÑ$MÓDMÕdMׄMÙôÿÛôÿÝäMßNá$NãDNådNç„Né¤NëÄNíäNïOñ$OóDOõdO÷„Où¤OûÄOýôÿÿP%PÿOPÿoPÿPÿ¯PÿÏPÿÿÿQ%QõÿeQ…Q¥QÅQåQR!%R#ER%eR'…R)¥R+ÅR-åR/S1%S3ES5õÿ7õÿÿÿÿ;ÅS=åS?TAõÿCETEeTG…TI¥TKÅTMåTÿÿÿÿÿÿÿÿÿÿtome-235-src/lib/xtra/font/9X15B.FON0000644000076400017500000001600011012107762014470 0ustar  dgdgMZ‚ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE…ƒ0@H|……†	
	€P,€	0€FONTDIR9X15B,FONTRES 100,75,75 : 9x15b Bold (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢ºPublic domain font.  Share and enjoy.KK’	0		 ‰9X15BAŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿžPublic domain font.  Share and enjoy.KK’	0		 ˜z	z	˜	¶	Ô	ò		.	L	j	ˆ	¦	Ä	â			<	Z	x	–	´	Ò	ð		,	J	h	†	¤	Â	à	þ		:	X	v	”	²	Ð	î		*	H	f	„	¢	À	Þ	ü		8	V	t	’	°	Î	ì	
		(		F		d		‚		 		¾		Ü		ú		
	6
	T
	r
	
	®
	Ì
	ê
		&	D	b	€	ž	¼	Ú	ø		4	R	p	Ž	¬	Ê	è	
	$
	B
	`
	~
	œ
	º
	Ø
	ö
		2	P	n	Œ	ª	È	æ		"	@	^	|	š	¸	Ö	ô		0	N	l	Š	¨	Æ	ä		 	>	\z??€m3m3m3m€€€€ff~ff€|`x``€>b`b>€€€````|€33€€€€fv~nf€fff<€üüüü€€€€ÿÿ€€ÿÿ€€ÿÿ€€ÿÿ€€ÿÿ€€ÿÿ€€€€üüÿÿ€€ÿÿ€€8`8€€€€pp€€€ss€€0`€€€€€?|_p€€66666654<5€€€€1{{677c€€€w>k€0€00`€3aaaaaa3€€€€€€<??aa0`€€€€a?€€€€€€3c€``qa?€€€€€€0``qaaa?€€€€00€€€?aaa?aaaa?€€€€€€€?aaac?>€€€€€€€000€€00?aa€€€?aaoy{o``?€€€€€€3aaaaaa€€€€€€€111?1111€€€€€€€?a``````a?€€11111111€€€€€€€€000>0000€€000>00000€?a```gaaa?€€€€€aaaaaaaaa€€€€€€€€€€??c>€acflxxlfca€€`````````€aasmmaaa€€€€€€€€€€aaqymgcaaa€€€€€€€€€€?aaaaaaaa?€€€€€€€€aaa`````€€€?aaaaaamg?€€€€€€€€€aaalfcaa€€€€€?a``?a?€€€€€€aaaaaaaaa?€€€€€€€€€aaa333€€€aaaammmm3€€€€€€€€€aa33aa€€€€aa3€€0``€€€`00€>>3a€ÿ€<??ac?€€€€€€```qaaaq€€€€€?a```a?€€?caaac?€€€€€€€€€€?aa``?€€€~€€?ccc>`?aa?€€€```qaaaaa€€€€€€?ccc>```ag|p|ga€€?mmmmma€€€€€€qaaaaa€€€€€€?aaaaa?€€€€€qaaaq```€€€€€?caaac?€€€€€€€€€€o910000€€?a`?a?€€€€cccccc?€aa33€€aammm3€€€€€€a33a€€cccccg?c>0€€€€xx9mg€€UªUªUªUªUªUªUªU€€€€€€€€€€€€€€9X15BЎюҎӎԎՎ֎׎؎َڎێ܎ݎގߎàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿtome-235-src/lib/xtra/font/7X13.FON0000644000076400017500000001200011012107762014356 0ustar  dgdgMZ{ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE„ƒ*@H|„„…	
	€P,€0€FONTDIR7X13&FONTRES 100,75,75 : 7x13 (MicroX font)2ÿÿÿÿÿÿÿo2'ƒ2)£2+Ã2-ã2/31#33C35c3ÿ39£3;Ã3=ã3?4A#4CC4ÿo4GóÿÿÿÿÿÏ4ÿÿÿO5Q#5SC5Uc5Wóÿÿ¯5[Ã5]ã5_6a#6cC6eóÿgƒ6i£6kÃ6mã6oóÿq#7sC7ÿo7wƒ7y£7{Ã7}ã78#8ƒC8…c8‡ƒ8‰£8ÿÏ8ÿï89‘#9“C9•óÿÿÿÿ™£9›Ã9ã9Ÿ:¡#:£C:¥c:§ƒ:©£:«Ã:­ã:¯;±#;³C;µc;·ƒ;¹£;»Ã;½ã;¿óÿÁ#<ÃC<Åc<ÿÿÿÉ£<ËÃ<Íã<ÿ=Ñ#=ÓC=Õc=׃=Ù£=ÛÃ=ÿÿÿÿ>ÿ/>ÿO>åc>ÿ>é£>ÿÿÿíóÿÿ?ñ#?óC?õc?÷ƒ?ù£?ûÃ?ýã?ÿ@	Public domain font.  Share and enjoy.KK
g
0 	7X13EW„EY¤E[ÄE]äE_Fa$FcDFÿÿÿÿÿÿiôÿÿÏFmäFoGq$GsDGudGw„GÿÿÿÿÿÿÿïGH$HƒDHÿÿÿÿÿÿ‰¤HÿÿÿôÿIÿ/I“Ô€•dI—„I™¤I›ÄIäIŸôÿ¡ôÿ£DJ¥dJ§„J©ôÿÿÿÿÿÿÿ¯K±$K³DKµdK·„K¹¤Kÿÿÿ½äKÿLÁ$LÃDLÅdLÇ„LɤLËÄLÍäLÏMÑ$MÓDMÕdMׄMÙôÿÛôÿÝäMßNá$NãDNådNç„Né¤NëÄNíäNïOñ$OóDOõdO÷„Où¤OûÄOýôÿÿPÿ/PÿOPÿoPÿPÿ¯PÿÏPÿÿÿQ%QõÿeQ…Q¥QÅQåQR!%R#ER%eR'…R)¥R+ÅR-åR/S1%S3ES5õÿ7…Sÿÿÿ;ÅS=åS?TAõÿCETEeTG…TI¥TKÅTMåTÿÿÿÿÿÿÿÿÿÿ	Public domain font.  Share and enjoy.KK
g
0 	zz‡”¡®»ÈÕâïü	#0=JWdq~‹˜¥²¿ÌÙæó
'4AN[hu‚œ©¶ÃÐÝê÷+8ER_ly†“ ­ºÇÔáîû"/<IVcp}Š—¤±¾ËØåòÿ&3@MZgtŽ›¨µÂÏÜéö*7DQ^kx…’Ÿ¬¹ÆÓàíú pøp ´H´H´H´ðð€à€€< 8  p€€€p8$8($€€€€ð< 8  pˆˆp  ø  øˆÈ¨˜ˆ    <ˆˆPP |ððþþþþþþðþþ`€`ü€``€üüHHHˆü ü@€8D@à@@D¸(((((|(|((8 pppc``>c>~cccccccc>cccc666ccckkwwccfff<`````>?ccccc?>cc``>>?ccccc?>```~ccccccx~<```cflxlfc8<vkkkkccnsccccc>ccccc>~ccccc~```?ccccc?np`````>``<|~cccccg;ccc66cckkkk6ff<~0`~001IF Copyright 1989 Dale Schumacher, dal@syntel.mn.org
                399 Beacon Ave.
                St. Paul, MN  55104-3527
 Permission to use, copy, modify, and distribute this software and
 its documentation for any purpose and without fee is hereby
 granted, provided that the above copyright notice appear in all
 copies and that both that copyright notice and this permission
 notice appear in supporting documentation, and that the name of
 Dale Schumacher not be used in advertising or publicity pertaining to
 distribution of the software without specific, written prior
 permission.  Dale Schumacher makes no representations about the
 suitability of this software for any purpose.  It is provided "as
 is" without express or implied warranty.
FONT -Schumacher-Clean-Bold-R-Normal--16-160-75-75-C-80-ISO8859-1
COPYRIGHT "Copyright 1989 Dale Schumacher."
tome-235-src/lib/xtra/font/xm4x6.fnt0000644000076400017500000000272111012107762015060 0ustar  dgdgY: ~xm4x6.fntX_misc@@@@   à à àÀà`à  @€ à@à à @ @@@ @   @@@à@ @à@ @à@  @€€à   à@À@@@à à€àà à à  à  à€à àà€à àà    à à àà à à@@  @ @€@ àà€@ @€À @@à à€à@ à  À À À`€€€`À   Àà€À€àà€À€€`€  `  à  à@@@à    @  À  €€€€à àà   ààà @   @À À€€@  À`À À  `€@ Àà@@@@    à    @  àà   @    @@@à @€à`@@@`€€@  `   `@ à@ @  `€À  À`€€` `  ``à€` @à@@` ` À€À   @@@@    @€ ÀÀ @@@@@ààà À   @  @À À€€` `  À €€`À`À@à@@@   à   @ ààà @@   ` Àà`Àà`@À@`@@@@À@`@À à€ Copyright 1989 Dale Schumacher, dal@syntel.mn.org
                399 Beacon Ave.
                St. Paul, MN  55104-3527
 Permission to use, copy, modify, and distribute this software and
 its documentation for any purpose and without fee is hereby
 granted, provided that the above copyright notice appear in all
 copies and that both that copyright notice and this permission
 notice appear in supporting documentation, and that the name of
 Dale Schumacher not be used in advertising or publicity pertaining to
 distribution of the software without specific, written prior
 permission.  Dale Schumacher makes no representations about the
 suitability of this software for any purpose.  It is provided "as
 is" without express or implied warranty.
FONT -Schumacher-Clean-Medium-R-Normal--6-60-75-75-C-40-ISO8859-1
COPYRIGHT "Copyright 1989 Dale Schumacher."
tome-235-src/lib/xtra/font/XM5X8.FNT0000644000076400017500000000321711012107762014564 0ustar  dgdgYø ~xm5x8.fntX_misc      (((PPøPøPP x p(ð `h X0@@(PP(    @  @H0x0H  ø    @ø    @@0HXhHH0 `     0H @x0H0H0((xx@@pp0@@pHH0x  0HH0HH00HH80        @ @ øø@  @0H  0HXX@00HHxHHHpHHpHHp0H@@@H0pHHHHHpx@@p@@xx@@p@@@0H@XHH8HHHxHHHp     pHH0HHP`PHH@@@@@@xHxxHHHHHhhXXHH0HHHHH0pHHp@@@0HHHHH0pHHpPHH0H@0H0ø      HHHHHH0HHHH000HHHHxxHHH00HHHˆˆP    x @@x8     8@@  pp Pˆø  8HHX(@@pHHHp8@@@88HHH80Hx@0  p   8HH80@@pHHHH `   p0`@@HP`PH`     pШ¨¨ˆpHHHH0HHH0pHHHp@8HHH8X`@@@8@0p x   HHHH8HHH00ˆ¨¨¨PHH0HHHHH80x @x        @    @(P Copyright 1989 Dale Schumacher, dal@syntel.mn.org
                399 Beacon Ave.
                St. Paul, MN  55104-3527
 Permission to use, copy, modify, and distribute this software and
 its documentation for any purpose and without fee is hereby
 granted, provided that the above copyright notice appear in all
 copies and that both that copyright notice and this permission
 notice appear in supporting documentation, and that the name of
 Dale Schumacher not be used in advertising or publicity pertaining to
 distribution of the software without specific, written prior
 permission.  Dale Schumacher makes no representations about the
 suitability of this software for any purpose.  It is provided "as
 is" without express or implied warranty.
FONT -Schumacher-Clean-Medium-R-Normal--8-80-75-75-C-50-ISO8859-1
COPYRIGHT "Copyright 1989 Dale Schumacher."
tome-235-src/lib/xtra/font/12X24.FON0000644000076400017500000002300011012107762014436 0ustar  dgdgMZ} ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE…ƒ+@H|……†	
	€P,€0€FONTDIR12X24'FONTRES 100,75,75 : 12x24 (MicroX font)i$j$k$l$m$n$o$p$q$r$s$t$ÿÿÿÿÿÿÿÿy$z${$|$}$~$$€$$ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›$œ$$ž$Ÿ$ÿÿ¡$¢$£$¤$¥$¦$§$ÿÿ´$µ$¶$ÿÿÿÿÃ$Ä$Å$Æ$Ç$È$ÿÿÎ$Ï$Ð$Ñ$Ò$Ó$Ô$Õ$Ö$×$Ø$Ù$Ú$Û$Ü$Ý$Þ$ß$à$á$â$ã$ä$å$æ$ç$è$é$ÿÿÿÿÿÿÿÿõ$ö$÷$ÿÿ˜Copyright (c) 1987, 1988 Sony Corp.dd”0 ’12X24A&ÿÿÿÿD&ÿÿÿÿG&H&ÿÿÿÿÿÿL&M&N&ÿÿP&ÿÿÿÿÿÿT&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]&^&_&ÿÿa&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&ÿÿs&t&u&v&w&x&y&z&{&|&}&~&&€&&‚&ƒ&„&…&†&‡&ˆ&ÿÿÿÿŒ&&Ž&&ÿÿÿÿÿÿ•&–&—&˜&™&š&›&œ&&ž&Ÿ& &¡&¢&ÿÿÿÿÿÿÿÿÿÿÿÿ¯&°&±&²&³&´&µ&¶&ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊ&Ë&Ì&Í&Î&Ï&Ð&ÿÿÒ&Ó&Ô&ÿÿÖ&×&Ø&Ù&Ú&Û&Ü&Ý&Þ&ÿÿÿÿç&è&ÿÿÿÿë&ì&í&î&ï&ð&ñ&ò&ó&ô&õ&ö&÷&ø&ù&ú&û&ü&ý&þ&ÿ&°Copyright (c) 1987, 1988 Sony Corp.dd”0 »ªzzªÚ
:jšÊú*ZŠºêJzªÚ
:jšÊú*ZŠºêJzªÚ
	:	j	š	Ê	ú	*
Z
Š
º
ê
JzªÚ
:jšÊú*
Z
Š
º
ê
JzªÚ
:jšÊú*ZŠºêJzªÚ
:jšÊú*ZŠºêJzªÚ
:jšÊú*ZŠºêJzªÚ
:jšÊú*ZŠºêJz??ÿ??€€ÀÀàÀÀ€€ÆÆÆ000ÆÆÆ000ÆÆÆ000ÆÆÆ000ÀÀÀ000ÀÀÀ000ÀÀÀ000ÆÆÆÆþÆÆÆÆ?ÀþÀÀÀüÀÀÀÀÀ€c?ø€€ÀÀÀ€€Àà````À€		!!AAÿ€€€€€€€€€€€€€€à€€€€à@@@@@_q`@|àÀ€À``````ÀÀ€0``ÀÀÏðÀÀÀÀÀÀ``1€À``````ÀÀ€ÿÿÀ€€àà @€€1 ````09#@ÀÀÀÀ@`€€ÀÀÀÀ€ÀÀ````@À1``ÀÀÀÀÀ@a8€ÀÀ``````à```ÀÀ€0``0 `À€€À` ÿÿÿÿàààà@`00`@€À``À€0``p0À````àÀ€ `@À—³³³³³³·À@` €À@`        `À À	  ? @@@@à€€€€ÀÀÀÀ````ðþa``````a~a``````aþ€ÀÀÀÀÀ€€À````À€00```````````00 à`   Àüca`````````````acü€ÀÀ`````````ÀÀ€ÿ`````aaccaa`````ÿÀÀ@  @ÀÀÿ`````aaccaa`````ðÀÀ@ 1``ÀÀÀÀÀÀÃÀÀÀÀ``1@ÀÀ@àÀÀÀÀÀÀÀ@ñ````````````````ñàÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀà??aáÁÁcà€€€€€€€€€€€€€€€€ñ```abbdh||ffccaa`ñà@€€€€Ààð`````````````````ÿ @ÀÀà``ppqYY[NNNDD@@@@àp`ààà`````````````ðà`pppXXLLFFCCCAA@@àà@@@@@@@@@@@@@ÀÀÀÀ@`@ÀÀÀÀÀÀÀÀÀÀÀÀÀ@`À@`````````````@Àþa```````a~```````ð€À`````À€a@ÀÀÀÀÀÀÀÀÀÀÀÌÒbc€€ÀÀÀÀÀÀÀÀÀÀÀÀÀ€€ àÀþa``````a~baaaaaaað€€ÀÀÀÀ€€€€€€  ÀaÀÀÀÀàp>€Àáž@ÀÀ@€Àà````À€ÿÌŒŒŒÀÀ@@@ð````````````````0à@@@@@@@@@@@@@@@@€ð````0000
à@@@@€€€€àÀÀÀÀÀÆÆÆÆÆÏËkkqq11`            @@@À€€ð``00

!!@@áà@@€€€€ÀÀàð``000à@@€€€€@@00``ÿàÀÀ€€ @ÀÀÀ€€À€À@` 0€€À@`  `xx`;`À€À`ÿÿàà<€sAaÁÁÁÁc<€€€€€€€€  À`à````nq`````````qN€ÀÀ`````ÀÀ€1``ÀÀÀÀÀ``1€ÀÀ@€1``ÀÀÀÀÀ``1ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀà1``ÀÿÀÀÀ``0€Àà`à Àÿ?À``À1```10'@ÀÀ``à€ÀÀÀ€Àà``À`à````oq``````````ñ€ÀÀÀÀÀÀÀÀÀÀà<?ÃÆ|`à````a`abdhxlfca`ñà€€Àà<?möffffffffffïÀ```````````pfù``````````ñ€ÀÀÀÀÀÀÀÀÀÀà1`@ÀÀÀÀÀ@`1€À@`````@À€nñ```````qn````ð€À`````À€1`ÀÀÀÀÀ`1@ÀÀÀÀÀÀÀÀÀÀÀÀÀÀà1ó6800000000üÀà`aÀÀà|€ÀàŸ@ÀÀ@€Àà``Àÿ€  @€`á`````````3ÀÀÀÀÀÀÀÀÀÀÀÀàð``000à@@€€€àÀÀÆÆÆÎËËQq` `        `ÀÀ€ð`0!@áà@€€Ààð``00
ÈÈpà@@€€€`A00`ÿàÀ€€ @@À@€€€€€€€€€€€€€€€€€@@  0000000000000  @8|ǃ `À€UªUªUªUªUªUªUªUªUªUªUªUªP P P P P P P P P P P P P P P P P P P P P P P P 12X24oÓÄ/µ™ˆ	'‘)€*ÓgnB<*Ó)oÉ*½*Ǭ*Ó *Ç-®Š-ûvk_T*@/5*$/-®-ûkì*Û/Ð*¿/« -Ïi:tJ;¿0)8³ý³ì³â³Ø³tome-235-src/lib/xtra/font/xm8x13.fnt0000644000076400017500000000415411012107762015144 0ustar  dgdgYÓ
 ~
xm8x13.fntX_misc$$$~$$$~$$$*((

* PR$%<@@ 0IFF9k"   @@8 `@00@>A"IUUJ >""c~AAA~AAA~!@@@@@!|BAAAAAB|@@@|@@@@@@|@@@@!@@@GA!AAAAAAAA>>BB<BDHP`PHDB@@@@@@@@~AAccUUIIAAAaQIECAA"AAAAA"~AAA~@@@@"AAAAA")~AAA~HDBA>A@@>A>AAAAAAAA>AAA""AAIIUUccAAA""AAAA" @@@  "A?AAAAC=@@@~AAAAA~>@@@@@>?AAAAA?>AA@@><?AAAAA?>@@@~AAAAAA8><@@@BDHpHDB8>vIIIIAA^aAAAAA>AAAAA>~AAAAA~@@?AAAAA?^`@@@@@>@@<|~AAAAAC=c""AAIIII6A""AAAAAAA?> 1IF Copyright 1989 Dale Schumacher, dal@syntel.mn.org
                399 Beacon Ave.
                St. Paul, MN  55104-3527
 Permission to use, copy, modify, and distribute this software and
 its documentation for any purpose and without fee is hereby
 granted, provided that the above copyright notice appear in all
 copies and that both that copyright notice and this permission
 notice appear in supporting documentation, and that the name of
 Dale Schumacher not be used in advertising or publicity pertaining to
 distribution of the software without specific, written prior
 permission.  Dale Schumacher makes no representations about the
 suitability of this software for any purpose.  It is provided "as
 is" without express or implied warranty.
FONT -Schumacher-Clean-Medium-R-Normal--13-130-75-75-C-80-ISO8859-1
COPYRIGHT "Copyright 1989 Dale Schumacher."
tome-235-src/lib/xtra/font/xm8x16.fnt0000644000076400017500000000461111012107762015145 0ustar  dgdgYð ~xm8x16.fntX_misc$$$~$$$~$$$*((

* PR$%<@@ 0IFF9k"   @@8 `@00@>A"IUUJ >""c~AAA~AAA~!@@@@@!|BAAAAAB|@@@|@@@@@@|@@@@!@@@GA!AAAAAAAA>>BB<BDHP`PHDB@@@@@@@@~AAccUUIIAAAaQIECAA"AAAAA"~AAA~@@@@"AAAAA")~AAA~HDBA>A@@>A>AAAAAAAA>AAA""AAIIUUccAAA""AAAA" @@@  "A?AAAAC=@@@~AAAAA~>@@@@@>?AAAAA?>AA@@><?AAAAA?>@@@~AAAAAA8><@@@BDHpHDB8>vIIIIAA^aAAAAA>AAAAA>~AAAAA~@@@?AAAAA?^`@@@@@>@@<|~AAAAAC=c""AAIIII6A""AAAAAAA?> 1IF Copyright 1989 Dale Schumacher, dal@syntel.mn.org
                399 Beacon Ave.
                St. Paul, MN  55104-3527
 Permission to use, copy, modify, and distribute this software and
 its documentation for any purpose and without fee is hereby
 granted, provided that the above copyright notice appear in all
 copies and that both that copyright notice and this permission
 notice appear in supporting documentation, and that the name of
 Dale Schumacher not be used in advertising or publicity pertaining to
 distribution of the software without specific, written prior
 permission.  Dale Schumacher makes no representations about the
 suitability of this software for any purpose.  It is provided "as
 is" without express or implied warranty.
FONT -Schumacher-Clean-Medium-R-Normal--16-160-75-75-C-80-ISO8859-1
COPYRIGHT "Copyright 1989 Dale Schumacher."
tome-235-src/lib/xtra/font/9X15.FON0000644000076400017500000001600011012107762014366 0ustar  dgdgMZ{ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE„ƒ*@H|„„…	
	€P,€	0€FONTDIR9X15&FONTRES 100,75,75 : 9x15 (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢ºŽPublic domain terminal emulator font.  Share and enjoy.KKL	0		 ‰9X15AŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿPublic domain terminal emulator font.  Share and enjoy.KKL	0		 ˜z	z	˜	¶	Ô	ò		.	L	j	ˆ	¦	Ä	â			<	Z	x	–	´	Ò	ð		,	J	h	†	¤	Â	à	þ		:	X	v	”	²	Ð	î		*	H	f	„	¢	À	Þ	ü		8	V	t	’	°	Î	ì	
		(		F		d		‚		 		¾		Ü		ú		
	6
	T
	r
	
	®
	Ì
	ê
		&	D	b	€	ž	¼	Ú	ø		4	R	p	Ž	¬	Ê	è	
	$
	B
	`
	~
	œ
	º
	Ø
	ö
		2	P	n	Œ	ª	È	æ		"	@	^	|	š	¸	Ö	ô		0	N	l	Š	¨	Æ	ä		 	>	\z?€$$$$€€€€"">""€< 8 '€  €€€   >€??€€"2*&"€""€üü€€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€€üÿ€ÿ€ ?€€€  ?€€?			€?? €€€>)€€			??$$€€))	!€€€"""""!#€€
?
€?€?€ €      €€€€€€   ?€€€€? €€€€€€	!?€?  /0 €€€€€€  /0   €€€€?€€€       €€€€€€€   !€€€€€€€??€€  €€€  '()&  €€€€€€
   ?   €€€€€€€??€€€€€€€        €€??€€€€€€€€??€€?€    #   €€€€€    ?     €€€€€€€€€€!€ !"$8($"! €€         ?€  1**$$   €€€€€€€€€€  0($"!   €€€€€€€€€€        €€€€€€€€?   ?     €€€      $"€€€€€€€€€?   ?$"!  €€€€€    €€€€€?€         €€€€€€€€€   


€€€    $$$$*€€€€€€€€€  

  €€€€  
€€?  ?€€€ €
 €€ !€€€€€€   /0   0/€€€€€     €€!   !€€€€€€€€€€  ?  €€€>€€!!!   €€€   /0     €€€€€€!!!    #,0,# €€;$$$$$ €€€€€€/0     €€€€€€     €€€€€/0   0/   €€€€€!   !€€€€€€€€€€'€€   €€€?€!!!!!!€  

€€  $$$*€€€€€€ 

 €€!!!!!#!??€€€€88$#€€UªUªUªUªUªUªUªU€€€€€€€€€€€€€€9X15ŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿtome-235-src/lib/xtra/font/XM16X25.FNT0000644000076400017500000001130611012107762014723 0ustar  dgdgYŽ ~xm16x25.fntX_misc€ÀÀÀÀ€€€€€€€€€€ÀÀ€0xxxx0000000?þ?þ0```üüÀÀÀ1€1€1€€èø˜˜ˆ€€
€€Àà°˜˜˜˜˜ðà€€€€1€1€1Œ1˜30`À€ð˜3c0àÀÀ@@ÀÀ1ø1ø0`0`0``àà````€ÀÀÀÀ€€€€€pÀ€€Àp€ÀÀ``00000000``ÀÀ€€ÀÀ˜=¼?üØ€àpxx0€€€€€?ü?ü€€€€€€ÀÀÀÀÀ€€?ü?ü€ÀÀÀ€00``ÀÀ€€00Àà0000000000000000àÀ€€€
€€€€€€€€€€€€€€ÀðøÀà00`À€0?ø?ø?ð?ð00 0``ÀÀ€À`00088pà€ààà`````````0`?ø?ø`````øøÀà08080?àÀàÀ?À<`00080000800àÀøø0 `@@À€€€Àà000000`Àà008000088ðà€àp000000xø˜000`À?€€ÀÀÀ€€ÀÀÀ€€ÀÀÀ€€ÀÀÀÀÀ€€0`À€€À`0?ø?ø?ø?ø€À`0`À€àð80`À€€€€€€ÀÀ€Àà00ð0øðà€€ÀÀÀÀ````ð?ð 0 0 `àð>€?àp00àà0?ðàôü00``````````00øðà?ð?ðàü?üøø?üüü?üøø?€ôü00```````ü`ü``00øðü~x<000000?ø?ø00000000x<ü~ðà€€€€€€€€€€€€€€€€àðþü00000000000000p0p`pà?À€||8<0`À€€€ÀÀ``08<|>üüààpppX6X&X&LfLFLFFÆF†F†C†C†C†Aàðð>p08<,&&##!ˆ!ˆ È È h h 8 8pøÀð8800````````0088ðÀ?ðøðà?€Àð8800````````008¸ðÀàp8à?ð80àÀÀ``08~ÿÐð000000€àp8 008?ð?àþþa†a†A‚€€€€€€€€€€€€àðü~x<0000000000000000ðÀü>x000   `@@@À€€üx000000‚ÄÄÄDdlhh888x>80 `ÀÀ€ÀÀÀ``008|x>80 `@À€€€€€€€€Àà?ü?ü0 00`ÀÀ€0?ü?üàààà00€€ÀÀ``00àà``````````````````àà€À`00ÿþÿþ€À€	 p>øp	 €À€àð0000ðð80`0`0`p`ò?¾<8xðøøààð0p00``````p8<8ðÀxø˜Ø0x`8`8``````088zÞœàð0?ü?ü00008øàøü?øð?àð€üp000000000`À€àð88``p?ðà8xàð<<~~€€€€€€€€€€€€€€€Àðøpppðð00000000000000``À€8x8`À€€Ààp<<~€€€€€€€€€€€€€€€€€Àðøc0÷ø=Ì9Œ1Œ1Œ1Œ1Œ1Œ1Œ1Œ1Œ1Œ{ÞûÞ1à{ð<<~~Àð800000008ðÀ9à{ð8ðÀ<~¸0ð0p`0`0`0`0`0`0`00p8ðð°0008<0>øÜŒ€ÀÀðp0 0àð80?ðÀ?øð8ðÀp8ðx00000000080x8Þžø~x<0  `@@À€€€øp001„1Œ1ˆÈÈHXpp00x~<<0`À€€€ÀÀ`p0<<~>x~8<0 `@@À€€88øø0`À€€øøpÀ€€€€Àp€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀàpàÀ€€€€€1Œ`øptome-235-src/lib/xtra/font/6X13B.FON0000644000076400017500000001200011012107762014457 0ustar  dgdgMZ‚ ÿÿe@@èSThis program requires Microsoft Windows.
$                                        Z´	Í!¸LÍ!NE…ƒ0@H|……†	
	€P,€0€FONTDIR6X13B,FONTRES 100,75,75 : 6x13b Bold (MicroX font)LYX›•ANGBAND EXE McXôåNGBAND EXE :cXR¢º
	Public domain font.  Share and enjoy.KK
À
0 	6X13BAŽBŽCŽDŽEŽFŽGŽHŽIŽJŽKŽLŽMŽNŽOŽPŽQŽRŽSŽTŽUŽVŽWŽXŽYŽZŽ[Ž\Ž]Ž^Ž_Ž`ŽaŽbŽcŽdŽeŽfŽgŽhŽiŽjŽkŽlŽmŽnŽoŽpŽqŽrŽsŽtŽuŽvŽwŽxŽyŽzŽ{Ž|Ž}Ž~ŽŽ€ŽŽ‚ŽƒŽ„Ž…Ž†Ž‡ŽˆŽ‰ŽŠŽ‹ŽŒŽŽŽŽŽŽ‘Ž’Ž“Ž”Ž•Ž–Ž—Ž˜Ž™ŽšŽ›ŽœŽŽžŽŸŽ Ž¡Ž¢Ž£Ž¤Ž¥Ž¦Ž§Ž¨Ž©ŽªŽ«Ž¬Ž­Ž®Ž¯Ž°Ž±Ž²Ž³Ž´ŽµŽ¶Ž·Ž¸Ž¹ŽºŽ»Ž¼Ž½Ž¾Ž¿ŽÀŽÁŽÂŽÃŽÄŽÅŽÆŽÇŽÈŽÉŽÊŽËŽÌŽÍŽÎŽÏŽÐŽÑŽÒŽÓŽÔŽÕŽÖŽ×ŽØŽÙŽÚŽÛŽÜŽÝŽÞŽßŽàŽáŽâŽãŽäŽåŽæŽçŽèŽéŽêŽAÿÿÿÿÿÿïŽÿÿñŽÿÿÿÿôŽÿÿÿÿ÷ŽÿÿÿÿÿÿûŽÿÿýŽþŽÿŽÿ
	Public domain font.  Share and enjoy.KK
À
0 	zz‡”¡®»ÈÕâïü	#0=JWdq~‹˜¥²¿ÌÙæó
'4AN[hu‚œ©¶ÃÐÝê÷+8ER_ly†“ ­ºÇÔáîû"/<IVcp}Š—¤±¾ËØåòÿ&3@MZgtŽ›¨µÂÏÜéö*7DQ^kx…’Ÿ¬¹ÆÓàíú0xüx0üxüxüxüØØøØØ<ðÀàÀÀ<0800xÈÀÈxxlxhlÀÀÀÀð<0800pØØp00ü00üØøøØØ0000<ØØØp <000000ðððð00000<<00000000000<<000000üü00000üüüüüüüüüü000000<<00000000000ðð00000000000üüüü0000000000000000000`0üÀ`00`ÀüüxxxØü0üÀ8l`ø`ðxÀ000000000xxxxxüxüxx0xðx8<88888ðà?ø?ø080ppààÀÀÀ€€àð>Ðð|>888888?ü?ü8888888|>|>ðð€€€€€€€€€€€€€€€ððþþ888888888p8p8p8p8p88pàÀùøùøpàqÀs€wv|x|~w€sÀqàpðpxøþøþ>>?ü?ü|>|>>|>|>\7Ü7Ü7Ü3œ3œ3œ100000x>x>x|<<>>7773Œ3Œ3Ì1Ì1Ì0ì0ì0|x|x<Àðx<<8ppppppppp8<<xðÀ?À?ð88ðÀ>>€à<ðxxp8ààààààààãœw¸tø<ðàð~>ÿ€ÿàpðpppppppppppàÀ€s€qÀpàpàppp8ø<ø˜øx888<€Àðx`<`ppx<|xoðgÀüücŒcŒ€€€€€€€€€€€€€ÀÀ||88888888888888øðøøpp8888800p```ÀÀÀ€€øøpppp88Œ8Œ9Ì9Ì;Ì||88~>~>00``ÀÀ€ÀÀààpp08ø~ø~|<|<8800``@À€€€€€€€ÀÀ?ü?ü0088pààÀ€88püüðððð88€€ÀÀààpp088ððppppppppppppppppppppðð€Ààp88pÿÿÿÿ8€Ààp8À?à0pppp?ðxðppppppxð?ü<xx888;à?ð<888888888<8ð{àðø<<888888<<øðxx888¸ø8xp8p8p8p8p8p8p8p88xü¼àð8888?ü?ü88øðøüàà?€?€¼ü8xp8p8p8p8p8p8p88xø¸8p8pp?ðàxx888;à?ð>x<88888888888888888||||€€€?€?€€€€€€€€€€€?ø?ø888øø8888888888888pàÀxx8889ø9ø8à9À;€???€;À9à8ð8x|þ|þ?€?€€€€€€€€€€€€€€€€?ø?øîxÿü{ÞqŽqŽqŽqŽqŽqŽqŽqŽqŽûßûß{àð>¼üx8888888888888888xø¸88||yð{ø?<><8888888||ðø8€àðx<8<<øð?ø?øœøðxxxx888888888888888888l|88ü|ü|80`ÀÀ€€Ààp08ø~ø~ü>ü>8880p`àÀÀ€€€çþ|üü<xðàÀ€<?ü?üðÀ€€€€€€€€€€€€€€€Àð€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ÀàpàÀ€€€€€€€€†?üaøÀptome-235-src/lib/xtra/graf/0000755000076400017500000000000011012107763013331 5ustar  dgdgtome-235-src/lib/xtra/graf/mask.bmp0000644000076400017500000434206611012107762015002 0ustar  dgdgBM6Ä6(pÀÃÃ000   DDDuuueeeUUU‰‰‰™™™ºººÎÎÿ™™ÿªªª™™ÎeeÎÎÎÎee™00e,ÞÞÞ0eee™Î0e™îîîe™™™ÎÎ0™Î™ÿÿe™0eÎÿÿeÎÎ000™™0ÎÎ0ÎÿeÎÿe™ÿ0™ÿ00™ÎΙ™ee™Îe™e™ÎÿÎÿe00™00™e0Îe0™™e™ee00Îeeÿÿe0eÎÿÿÎ00ÿ™™e™ÿ0e0eeÿÿ000e0ÿeee0U0™eD ™0ue ‰ÿ0DªeÿÎ0™ÿ0™™eÎÿ™™0Îeeÿe0ÿ00ÿÎeΙ0Ιe0e0ÿ™eee0eΙÿÿ™ÿÿe0Î0ÿÎÿe0ÿeeÎe™Îeee™000ÿe0uÎÎeî™ÿ™™Î™ÎΙ™eÿÿÎUÿ0eÿîee™0ÿ™ÿ™™eÿÎÿ™0Î00ÿ™Îe™eÿÎeÎ0ΙÎ0e0Îe0ÿ0™ÿÎ0™ee0™ 0™Î™™eÿ™e™0e0e™™0ÿÿ™eÎÎeÿ0eÿÎÎÿ0Îÿ0™Îe™eÎeÎÿÿ00e000™ª‰Î™ÎÿÎÿΙ™0™0™‰D™™0™0™0e0Îe0ÎÎ0ºÞΙÿe0ÿ0ΙU0ÿÎueÿÎîÿΙ0ÎΙª™Î0ÞºÎÎ0ÿ™ÿÿeÎ0ÿÿ™0ÿÎ0eÿÞeΙÿe0ÎÎ0eÎe™™™ÎÎÎÎ0™ÿÿÿΙÿ0ÎeΙÎ0ÎΙÎÿ™tome-235-src/lib/xtra/graf/tome-128.png0000644000076400017500000013102511012107762015314 0ustar  dgdg‰PNG


IHDR€€L\öœ	pHYsÒÝ~ü
tEXtCommentT´~%h¡ IDATxœ¸tSgš7N(L2É$™ô¡¹w0ƃ
6Æ6¸÷^e«KV±zïÍ–{ïÆ6ÔÉôÝov÷ÛÝÿ”o§m¦eÀ–tû{ï•dfÿbÏyÎ{î‘u|tŸßó+Ï»çÿ´ô/†žÝ÷ìê»v‡¥»Nñ®†Rs‚já®ÕÒêÃj]X,ÞÕ+ÂZqXéy!7dR„õýa3ì`…}áÙîkw‚½;+Ý’‡Æ•áiÝî”6ì5ìza§>èÐPn9íÕÒvyP%êe´GAÉ	¯8å¤YTÒ &mäí¢ ML»Ô´	·òÀ˜Vâš>LP…w_ Ú²ˆ¶².”E‘·r@Y1YÝLU6ѵ·‹ê©í¥ £pª(¯’’ÑSšÝGs¡Çcôš%x"8ç/¸w×Ü¡QyØÂÙ5³ÂÃüðP?=Üòö…Æ…¡1^8òìb<fíºûÃʰN´k5…ž m8dÙ™ìAçå£Þ c˜²9ƒã#!·=ä2JzÔJYƒ¶à°vXC##!›•rƒ¶È»·µÌPûuª>f6R‚æ=ÏnËv—YagMhNö2wÇd»&Nx°'$a…˜}!±4¬×…¹]»Òî]-{Wß½kgÊÉz™ô0ƒrEªŸò0è‘®§'ìl‰w½ò°SyÚæZ"å¢FÚh UJkj)3SR-Å“S%‘Ün0È MLÒÙG88@ǧ
jr@DŠHIoH×”7йTS.]u1XuiϳeQhôVЛšiÙ‹Ãê²°¢)ÔZ0C]½a×Pˆß¿kS=Ó0þ¡íü‡³÷£½Ï&¸»‹Æðœ><«=òïšC÷\»÷&ž-=›žÚON…ÆFÂÃZ®RrP¤ŒÏÀÅýD'“ìe—²9•ðQ®e‹0>/.ïÒV è"•<\ÉÇ4,ÌÂÁý¨ˆ‰
˜XC^q(N ®'“W?ÙQ í4™3©¨«tÊuPU
ZŠˆö «&$ÀÒIz•”GN9…Ô”œåÂ[Lk´”O«y”‘MyX䋚‘Ö3I‡´³¨È'ÃjˆK+B“6rÔIÙí@c¡ôJ­%U”|€	qÞ ÎÕáýz‚­½"Š/$=” —·ãÖVÜÓAXz’	dRȳä&)Ê£„…TG6]ž¬-ÙÖä­ÙôdQp¡Ž6憭õ¡ÆÁºëtSCˆ+Ía‹6¢<Ï\²XÿãåþÏ¢ìÝ
J‚szüã
mN†gw·×B³¡™Ùg„ÖÚ(©¥@$À˜«e2ˆ6hç“à1Q1 b!Ê£B!.áâ2&콄ˆ…+¸^ˆ[ň2ò,„Û;ŠZ,ÿ:‘	rÒˆ± ù$‘rĉÉdâ%òJ1¨¿IT]Å:¯âÌë„¢
Ø»GšÄÁ)9=Ʀg¹ä4òƒÚJ! 5\ÒÆ"'X`Ž	VX`*Bp	·–€11¡¢f-`ÊNY€NGªXIÊ$¤ŒOJ98Ÿ‡ódHŸë3
Ñ'LÉêĪuµãC¸­—0±€šOˆº‰ÁvBQO¨Š"Ó(V%n¦k*öÝ5”%ƒž(¢çª(ã•`V°9;ØWìh)5twoH%ËúžÙþaãücÓó,Òý©Á]· <2¾í®xèµ©ÐÆBxqqw!R+»KK¡Ù¹ s4hr“|)Q6ãö¼^ŒÓuõ>Á`ã*f"R,Œ ABT,Â`´ ¢K
	¦—a&9ªäÀü.¨£©®Ç®”`—¯ƒ¤$"9ÄÉI‚œT2'‡JÉ¡.ä•—ø&Î+ÚrDJ%”]B	éi¹È!–¸À9tbJ%.fi±ÀËb0%ÆG˜WŽ*Ð15:ªÁG5ĤŽôjH«Dú.‘A EºÄlœÏ¹
„iÄØÀT’èãá6Ћk¨«ór	‡Ð2U7®îš.B[Gh"Úx
¨S(a6ÕuƒîhØ4\¥Ç*ȉjrèVp¼;ä욘¿=8(¦¹BšÍÐ-hWìjúŸÙ„»Á³%Û³ãî°,<®ßö†ÖÆC+s¡õåÐÒRxu5<¿^^-,…F¦ió0­µÐƒ “>¡Œ¨P&eàB&ÎgãÜ~DÀBÄX4	Å(W†éT¸RŽËE¸\‚ˤ¨Fƒ¨õ°J…ê¥°Ž‹ˆ;à[%Xq)šv	‹I"ÎàéÇAâ›dêÛtÊûÁË©Á+Ùô•L²*ˆk€²–´ôƒ)35i çµÔ¬€\æ‘ë\lÛn †…ø¼ˆX“à›
°®"æuø¼›Ô#SzdB‡jP¯‘·ŠÔ±pÄ_Bry@À"$\ÀÆ„L¤ÆxF\f-àKP„+"ÅÁôl\ß,\ÛizpC'0EèØô%ÀP”™”øz¨¾0T[¾'´eÓÌà]9/'Çä¨
ؤIE5À ¥‡Ì¤+bëJzÞš¶…Çìa—a×­
Ow§-áÛÁ™	zn1´²ž_//…V–›áÍÅÐâBhv"49÷Òv+eR€nŠ…”0€B€ËĘ\†)ĨRŠÈå¨YÛu˜Fƒ™µ¸Nƒ›t¨Ú€Zˆ]	Ûˆ±é/Á
¯ ùhz6ž•E¦—>$>¤®@|Îý(”KUçR-ù@ZX¥”¦•Z¶+jr]MmŠÉ-1¹&Â–äø„Œ$¦”èª}¤'±&|ËŒß6¡Ë‘² KvtÆŠMš±!áÑ6%©d!‡dq)¶€â
ÈBÌ&¤ˆÊ4˜ÒD˜ÌÀl63.WàJ¡V­œPˆƒtã:&aî!l}@_T¹¤º(Ø•Aw_Õ„š*öPkòþ±ä"×ÇÀ´‹˜t‘“àr‘C.0jǧ-Ô¼	¬ê©3µ`
O8BnsØcØÑïN™Â“¡©±Ðätxa1<;ŽØÀÚôîæTxk2¼6^ÍŒP‹ãÁÙara¬{ñE¶dªĭzT-ÇÌÔ ÇÜ:Ì ÂL­'¬*\¯ÂŒÌ©…ǥȴg ¦z„]Š_Ï&R3ˆ¬\Ÿ.ÅÐ…Pïo½NW½KW¾,?CU$S­²”‘6qÛîèð»
â¾} Äïêñu¶hE—mømzߎ~jÇ>·ãŸZÑVô¡y`ÅîØçßq¢c0âÄ]Â"%UB0È2È)™
è4„AƒÕ¸CG¸M¸×†,äˆ
×[pU(0¥ñq‰„àƒ\ÍÂÍÌás=%˧Dt[V¨(;|µ \xcý“-âÞ±1
î.S#`z”œ¡ÆFÀ„L9Á¼¬šˆ-¹¡«Fjʱ†&í»ãºð¸bwÖšM„'fóSáYoxɾ;Þðî®xÂCôŒ‹\‹CÄÖ8x0¯ØñÛ^bÆ&œ˜Å€YP‡Ñbã:0oŧ´`ÎDN›¯Œk‘)²$D–øðL+®¿…õæ7³ÉK±™;9þ)dùÛdÛÁ¦ïÒMß§Z>"[c¨æhª1pòµLI°u3ñÀŽ?°à÷-ÄCþÐ…oz"?Ûðbw†Ð-z߉>r`íØóÓ†}ê€Ûñ{ÃØ²›˜ÇÇ'Àø4îqáÃVrØÜÒen71ä"F\¸×†EÊDŒ›€×@8
„шëˆHЉ˜ ŸŠ\ô*BdžNÂÚœ”ò&-( {ò‚9¡¼+Áæš=Ä×ñdzøÊ(qw–Üš&W&É)/99DEx0k'#,¾m[úÈ(5=5g¢'Mt¤ûºð´öÙædxq|wb,dvîºa—~÷ÞXhQýlݾ;­
oN—§ð¹1bc
[EWÜè²[´³nÂcÆíF0êcf|B‡/Èu'µbËbÁB.Z‰E=±&GïòM6ËØV•þ±*õ/×’{1þÛó)sãÿãÊ™ÿ¼ùî¯_ýsÛ«PÛ›Û-ï€ö÷@ÛIЙ„›qW?:¦€§ŒèªÛò¼ØÃaüþ¶>FnŒãkÞH‹Ñu7¶áD6è=;éþ#ò؉|îçð9l~›Ý 7ñ…ylu¬Œ‚¥qbzŒœð£öˆN€'1e&Æ5؈–Ò›ž0™p¹T "!ÉR!%0f€Ô°iS=%¦í¤ô:ÉL§ZÎÓ•étsI¨¼xñ£ôñ4¶9ú¿<!7¼ÁU7½ä¡¦ä¬,™ˆ
`CO®ë©eµl®ÚCËæð‰gkÞðÆÂ®×³;=½û`}wcb÷áԳϧŸÝu†7á{óäü4±0…Í£‹,"¯NlÞ‚O:€wˆt:ÇEθÉy¹f÷¼Äú¸3Š­‚ÕabÃ	Gjì¡üÛ©žûý‡>ZÍýx%ö­Í3o·$¼bLyC–ó]aÞwtEGïU½ù‹Æ×ÿÞôÙv
g]BT•°‹Pqa—Yr¡«^ìÞ8þ`ßÅW‡ˆU/‚;>gÈ=²hGï:‘{6ôžy0Œ<ö¢'‰{›øÒ]lá!±ùÛÚ$®ã›Ä̘!Æ]`ÌHÌÚð¾¨EçUØŒ·GŒMLDLªAå‘SH­Š–J)£2¬b‡<ÚÔ@êë'“ìϤ»óéºLº¥88нüø6º5ŠmwGÀ¦“~ä¡ZC·mÁ%k0ÒîE3¹e%ïš©Ã`]Oo˜é;NjËþr>üùüîÝéÝû«»_>ˆ¨øÓÝÇsá;îð½¡g_͇…Ö¦©…9|b›Á–&°Eº4„GinLÏ’Óäô¹4NnŽQ÷ÆèÏgÁÝyâLlÌ“÷¦ÉÏÆÀ×âsë¯]Ãçë.¼œ›øRAÌKåɯdÆ¿t=ñØùäof­Î=|1ãp÷ÕWþOý;xk*ÆÈE7!U;l‘8}°WÌZ±yºì"ÖG‰W¤wÄœ•˜6›]ö ‹tÝŽÝÁîàfðûsØÖ4¶±ô€Õ‡Ä㯰‡÷ˆÜ'>ß$fF‰™lÈ„Ž«±%-º6ˆoèE	º¤E¼2|Ö‰95„ÃŒ)T¤ÅFöH)ž’–ª‚ö„"lY‚ë–ð²-¸l§ï¸èÇ.ú³q꾇\ÑRê¡;øùDèñlè'wžýìþîWë»?\{öóG»?Û|öåܳû#Ï>›	=Ý›óóÄÂ6;-Ïà+sÄÚ¾>VÀêµ´¼½L?X >_"¿œ'?]oƒ»›Äƒ-ðhƒþz“þ§5êg3ä—ÿ´õ©j“/;’–pðí¸}ç¿·?6îÅÌÄ—RƦîKÏWCƒÍþîˆß…ê°±é»&b3`RKΚˆi->cƧLØ‚Ûx>|Ø–÷yÝ[ÀnOáãÄg·©/_DxD|ý)ñõ}<‚ÁE|i›B¦5Ȳ]—£›ZtEƒÌ«ïàóÿ62ˆÛÄ„’ÔJН¢k¨6Q%ñûÂÜZZÙ¤UDW.Uj¼l¹b6„¬=¡»+ÁÏÖÁÆuŒÚrÐ÷­Á-k(ÒýESxÉ^±=û|j÷GÓÁ;NzÙLͨÛ6jÍüb*ôåâîOÖŸýlõÙÏŸýóæî×s»ŸO†?Ý	Ýž?^¤Ö©µ°±Jm­“wÖˆ»«Äƒeâþ¸lݦ·nS÷Ö©OWè¯Wé¯VÉÝ#>½GþàKbë>ùh‹úé=ú_îÐ?Ÿ¥¾žù£[h.‰=Ÿr(%áà{1ûÞÛw:fÿG±{ó_ÊM~1#íÅÔôãÏ¿øÓæï²(¢"í-€øå0·µ—‚E-1%"FDä¼	Š<“ZbÁŠ-»°ÍäκáÂV†‘)7¾4Ž/{‰»£àóâñ$ùÃMðåøÑtuŸ›À&ðù!tZ™zlQOÊàq9<<»$¸GŠ„žT,’×Our¨>h «94Ÿâ6SƒuÄ@
h-&»B¥—Â5a/ìRí	s˜A¹ˆ·Ñ[^zËF¯ÛèUkpÚš¶†ç]á-WøË¡Ð#{èÁ(}ÛCO™¨y+}Ûz8þéÚ³¯×‚?X ¿˜ý`’¼3¼;E-Ï’‹`y)Ò}êÎ:¸³N=Z'mŸo/7‰lŸnŸoRŸnQŸo…~ô02ìÔoÓ_ß§¾xDþààÎ]êÑõÙýƒ1úk/ù™qɾ¨-,Iy%)épbÌ‹ÇcÝŸ•t´/íõŽó¯Ö¤}'.eÙÅÃÿVú6]ò	^œ¶äCÜd 
U¶¡¦|„Ï
`ÃlÄÂA4<ÌÄÆ$ø¨Ÿ‘ ËrlCŠÝq zÄ­ÀFؤ›swÇð-;¾a'6Üøò¾>Ny±	6î@ÆMð¸0 ÃjØ«Fƒ¨[†j™˜%7™@ÞE6—äðÉ&h’ݒͦ êÃ]xc
YW,Ï_K	ëø»öÁ=»‚`K-é§§µäœ88«N<ÏšáqGxÊþì¡;ü©9ø¹-ôÐCÍ‚+.zÞ\
>ž
Þ›
ÝŸ£·fèsÉ›“øÂX‰ÈÎ1½"µº
Ö—É;«ô§›Ôç‘QÚ?¼Mþä6øÉøz•üñêG÷ÈOoÓ_Ý¥~ò)õÏŸSŸF$h	lŽ·†éûnr]EÎ+Á¬fg ÛY”\üJ]ÂkÙQ‡s¢^º–üJyêë•I¯u'¿u.ùÅÔäýUçÿ¿ËïÓ	dFº‚Ï®€ù503V—¨ˆàÜ]w×ÁgÔ7ÈŸ®?^À4:K<˜—‰X!-Ã`ÕI.ëÀ’œ˜ã‘Sàè¥tì¿7^÷f,L8V{¬øì‘¼¨ï\57æeYÚqfÌ…‰GR’ö×&ýïÔ÷é¸(|̸÷V#š&ÔÙ‹L÷ÀSx”°1jv@Æ‚$=ˆ¶s2ˆ©&|µ]é@çØ¨›I©RHz5l5£Fju Vj4".ñÞ12¦EG°[PƒS³1U&mÁeM¸²W°II)1—KP±‘é`™!`4Àv=¬U‘ϬŽÐôpuf¸§x·ýꪣg·ÂN0ÐCJû(5‹”³	Œ5’«&ü¶Ž¼§!ï¨È
-XÖÓ³Òm&½L“SÄd$e΂õtv™^ÀooK[ÄÂ>ºJ,ÞÓs`yÜZ¡"õx“úê^DRñϦ°¯ÐGcØ£iôöq?’|ÜÄýaì®ßpK*|AæÚÉ©v *!ª‰Æ¢o«Rï_?ݘøJYì±–ä—k_½qö•š³otœüÞÍè—Sã¦&¼Ø÷òÏO½OŸ¡OÆâç3±æZDÛ	
÷Àó=ðx/ìíƒý>R2ÒnDÓ‰ÚÚð±l¶
íB'{a]/¢$¢€Né°Ù‰¨=¨Æ‰ê¬¨Ù„XL°Ûh‘QÍÿ*¾±ðP1òQE>ØŠË;1ƒ5“ƒÝ¤„T
\«BFHm‚õfÈf„Ÿ_¨È³UÐ¥áʤ`Oa˜[¶õïÁ˜Ý¯åö!<&B>ÀÜ~ —«¬èÁ²,iÀ”’ÖP^+¡·cc`r’E‡Fñ±ÈÆ8…N-`3›èä&6}›ÛÂ'Wˆ‰ebf‘XYkÔÝ5òñâñøê6ú`¹ÉÚØ£),×ø½qâ‘
ÜÁ—UÄ,‡o&'(G	)½…÷V£M%o‹ýAùû´—+b^ª8ìVÚ±‚¨cù'ŽJßÉŽ=’ÿ⹄ƒ…1‡ļŒ;EÇ¡Òñ²"t°uv£“Ýè\2Ñ	»ºýºž€¬’wÂê6ÔØ„Ùš°¡ftº	f æX-€-ZÈa…¬vT7‚†Q59P½2›žT¿Ó
¿5<1ÀVlc#ÖÄÁ²W´âÊNLÞ*e„RŽ+
¸ÚˆjtIPéa“6ë!«
v"v)ªça=Å.	uòrÂæÆ=Ÿà±!ð.ñ0ÑÁ®€ÔÈ	½”tJ‡Œp«H—P€mS»1‹vzQ›žÁ<‘t<ƒÙ0÷:æX§M||HÐrD‚¨‡wÀý5ìÁvg»;…¬
aÃè†ÝÆïL[.âÎ(¾á&–õ`¼›­£]—HS.¬Ã{šÐö›o‹yÜðÚÀÅïôœ{éæù#Yý9œ楲˜cY	‡ÎÄíMˆ;PžpäŸbÞz~-š~œÊŽÆ«‹ñÎ[¨©›hÁfZÐéØÑ;ÊVXÙ
iÚU+¦hÁÔ˜±5·£&b„zÈiƒÄ1†&Pó(bv£vû_µòÇ}mó5å+5å¿èmùoiïù-P·#¶.ÄÅDý˜U€Z˜Ak5¸&R:L«FTrب‡Ôš€N0ªf%bWÀV>µ™C‚̰øLx¤u¤\HÈŽÂïƒz‘"àal.Áa‘6PK“œô½žñA+¦q!–aØêB‡í؈sypÛnž&¬Ó˜kž&†GïÄs^^¥æWÈ;øúqwßÂ#ÉoŃ­a›cèm/±êÁWFÀÊXðÓÊÓJ×ÒŽ\ÊZFÖ¡ÜfŒQîëNø²õ5õå#ÍI‡jÓפçrÒ‘¢Ä£õ‰/_H8˜·/9æ@yÜ‘ÿsþíPÎûÁÜ·éÜ(òF¨-Åeu¸»ŸjB‡ZP{3ªkBM°±9 kƒ¤Íˆ°e5aÂv\чšÄG…=&xăx†aÛêœÂ<3èðH$ùüAËöV—4$Ç*/gò.ž›¨ºÞ—›>ÓTôC:ÚŒpÑ!1씣njVá%nˆ¸®Õ
a“ÒË`½2 UÊ€]ÙŨ¡È*ƒƒ™Aí• ùÊlȰ 1öA¼ˆÇôó{ÐA2؇©ú15“P
	¹˜´›H«•0Ùq¹Ó:0k䇺1æµà¡ÂMã„}w¸	·s9p‹X‡HËpLƒ±9b|[ôb«n°dÇçø¢~ËäAW=ج›Æ&ÜĸžòriWí)&‡	EÁk"znÀ=g¾®þ¾5ïhOò‘š¤CM©/¤¼t%ípEÂÑâ˜#éÑÎÆîM‰ÚÿÏI/ sÏyé ëVYNÔÝÂÔ혫s¶c¦TÛŠ˜!kSÀЉZvÖ×B{q…7é0‡	ñXa¯
ñA./2<†Ž!“ftFó­›s‡q«-=¦"þlÞéKbN*³t¥ÙÿejGf˜‘,‰¡!9ìa.n`á–Ì(D|ØÎ†­I0ÉýV9ä”An)dda†.`(§4Ù!uêhaÖ æ³`n¿ŸÙà2àˆ_i{¶10s?¡+9ì!´|ØyÜ蘳¢#ÖÈ3nðà†!ÜêÆ]Â¥%ì&Ìd%´vÂ4ŠëGˆá	,"V“bÉKÌ»ñHÐ^ˆà@ŸSa™ÁfÆð©bÂ
F…äòÖSLÂÖI;ÈŽ«hSÒ¯Û^fi=°"ýPáù3ÏÈHÛ_u$ïôᄨ}Ég÷§ŸyñȦÁ¬h27d]é¹ °„(º‰µ5¡òÜØƒj:u7¬ï„
í°¶Û?Љð{0v/&ÀÕ‘±µbN7â°Ãê¶ 3^xÞÞ‡×õ9Q`¢ï[çí¾kMé1-éÑ+-%³
E_óê}^¼ÈAVàE<%EÆ…ðxq³G4	Ù{a¶üæŸMps¡ÏÂ5¸¶œRäÅ	{þ{Úö«Q£O.€ùÜHAl¦ŸÍ€ý±¶·AŽ6ÄÁFÌ"X&@僸Û\ÖH‰	2å æ\‘ÔŒÙp‡·¹q»w1§!2P¸Æˆ+Œ„ÆN8GСçhEf‹$ë7>a#fÄ’£¯£ IDAT¢=ÂdnžE&½Øô06ã gu`A	æ%Ä´ŸÐfU“CT¦ý[Éû⌗øYGÊ/Î?ðܹ}Y©/VŸ=Z}êhòé½±§ö¦Þ÷ÅÉO‚	tVÈÏ%órÉË9ÄÍR¬¡ö£ƒLÉDÅ}ˆŠëÚêqú°¦5ãz7nõbÖQÔêŒ6Øf€ÇôÙÁÀ¼^ÙÐbO`¶çÉTÛ¿kÿe°õŠ®?©Oœ<ÿ׿Ć7%ÈíÀšïE'û°Ñ.d¼	nAì°µ+ ïú k?ä`Cn¦o¨'àfG€‰DRœ]ÜóèþègVþŸdÂ?)ÄþÎ>_O¯Ù½#èôk›ý–:¿­6`ió©z …Ð?À…|Ôášó°1:kDglÏy:dA6ÌnÁœfÔnB:LgÂõöˆ"acCØÔ6ã|~]5ù«·I	¯æ/OÔè°õZ°	'6fÄFˆ%'¹j VÌÄÚ0)ë§o+ˆË§~šýçäÎ胥±/ÞH<œŸ|ðzâá¶Øc¥Ñ/¥|²/öÃÎß÷ƒøÁ+‰ÔÕD*?.ΤŠÒÉò+ ©’è¬ÅtÔ*Ã4T'‚Tü€V‚ZŒÏËfÁ½£„{·.`³zÑ!/âÔÀ#2hJ˜ùæ™þU´ÞÝé
¬væø>7ǧgù‡$Û¶þ‰>ßí^ß½^ÿVŸ­Zj…çZéFd¤n„ìͰ¹Ò¶C†.ÈÖyÚC=þÑÎÀXW`¬µ‘ÆrJWµG7Þ3oïþ±œñ˜ëëëõ0wx;íÛòæmý޹Òun¶úøÝÛìN¿´ÇIfì•£CRÄ-§èŒµà#a³À¬—£æÈë—ù—ÉalsY´`Ó‘ %fàŽÁÈâŽ+º1]?ªa?GÅ!&¦MÄŒ™\6„R°ƒ
%ÁÜÁs©x\ô£¸zÞ?TóÎþ⸃EI‡r’t\xµ<ùPþ™CÉíû`oêÇûW²Þ#;3ƒÝç骨Py]L×^$ë.i'&nÇtlJŽ©¯ò˜©xÜŠÎŽâ‹‹¸{…YAÝSèØìÖø­»À7ÌóOr}‹ý¾õ~ÿºÛXgþaÁŽ™©§v¦oŠû€Ýþ»]ÛíðJÛóÈ;Û€ŒÕÞFÈÖé›a}d·90Þ˜h†F«Ñ‰kØDÐçQÌó{îüp~kRðcÿòžA—_ÊØwîH;¶åíÛÊæçfËŽ¸eGVï“5´,HÚqyØ!BG¤ø¨uè­ÖÈ`“²
!—QAZìŽ
¿cÅ–uèä 2ÄGì}¨ª´òn iÂd͸ºhn95Ò	í–€ÁšYÌŠ	fÄ„ãÏ¢g¢bÞ«|ÑGòϾX–xôzò±Ë©‡‹“fx1åľ¤÷%žØ»xíMD˜$‘œ,º=•nH¤.5¹ "o»E¨zPW/¶"GÖ5ð’Y´ak^da›žÅ&—Qï<22Vø½ò@D¬-\Ÿ›·3Áò-òü›½þ{\èÚäC›º7Ïçî9ø&ÙþeF`«Š|g£^éBæ;áF›aw3bë„õª5±kìf ÎFÌZŒÛ®žlàŽ't©”­rÏäWÃŽÉÞ‡¦ªß˜:ÿ¢jÛ‘tøÝÛâ¶§‚¿¼uGÚ´#iÚ4îpš}ìÆmq펬Á'nðsZ|íf'Äë@mØÞÛE°šëS± ‹Äï†þQ<#‡VUÐ]-²®@æÔȶ÷ Ê\ÇÂf`b‚rBÛMôßÂ;‹AÏ-ªýÙ™lÉ¥/ÅÏƽL>îO99ÿúÍØýW£_¼xúŬè#©±K“ÞŒ?tåì‹1û’?Ù{1z¿¹äõmQTPC±Ré–²í"U–@VfQäõl0ÐŒ+Ñi¼2€Ý³FÜ^5ÃÓ6diŸ„‡FÃÖÀ¤ÁïáÃCâ€p	|£œ¦ï6Ó—á»Ç
lIüs‘ÛvöŽƒãs±}½ÐB?t»Úì€7˜•dºí@½Ðóµ£³0QUt!ò&L[	D—õUz0–2Ÿ£]§I}4½ÀÞc{`_ÚTÜëûéPÝCÃŽ¾}[ÚâW÷îHZ}ÂF¿¨! ªœ~qóŽ ~GÚ¼3X»#¬ßa·í´¶ú›š¡Öz˜S
ɪas¯OÕϯé÷YЈhgˆ½3ÌÙ™àAkrh]/â3*ddÑuGˆ[	E3abªVº"4•’¥™TuÙ˜¼™@_>M'¼Lù ˜ò!”ò®úÂw‹3ö§JN8ýâ‡qû¢ã÷]>{ /ú@Vì¾óg÷¦œ~¡0õÀ¿3bƒ¼3ToE³_Õí·B¢¶HßaY‹°É/TûN¤Dí;¼V£Õ ®j­‚¥u°¶2u4]Ì|œ};òÎm+Ë7.ÚbføþñþÀš„ÆEȰ„p‰	›˜ûHUÝMÕ_§¯æÒÙTÑ9:ÿL0ëýPÊ[tÖñ`ÒÛÁÿýÒGªË¯–¤î/JÛ1åà[ñûÞMÜwUËŽ¼{GÖµ-íÚ–toGà¶û{›‚¨«R4BÂb¿¢ÂŠÛäãtû;›|]
ÏQ´ôî˜:}î>Ÿ¥?0"LBóxV‚¯°e=áê#M}Ô@ÝRNççÓY)Á¢‹Áܨ`ÎñPÆû¡o‡.¾Ìúèï×Þ¼Zœ°¿,ñÅœ„¯&î{-qï‡É{Ï%HÚ—zæ…ø¨ç½w¤ì=ºï4ÉΧë£)F~°è4]O7d’UçAÛ¼7¼ϱ 5q`šøLB¿KÓÀã:È+…'”ИæB£BdTOˆàiQ`–ë_Ô4Ђ^ŒœÊÀªÊGä{ÀïJ¸ÐAà6;0Θ„°M‹Ĉ‘ƒ
–ÊbJs=hÊ	ª/…UI!QÒ?ºÞØí‰Þú>¸…Õ_Ô•ûåŠ=Wt—ótÙeú쉕ßUýb¢ïG–ß`«_Üï6íÈ›¶ÕÍ;ŠŽíAÆŽ¸ÿ©”ùTÉØQôø>qc@R©š Ye@Ý™»vø•¾þfMm £%ÐV±kÚŽ€©%`êð©»#ÈŽŽ˜VD\Þ [||AF(jHq+ÙTF^»H_O¦ož§/~Ì>N|=œúZ(óýpÁ'ß”½ÃÏ>\š°¿:öÀÅèoÅøN⾓öEÅï‹ß›tú…¸³/ÄyálÌ>YÑ;hOÙ›Fò‹¨¶ªû
͸A•§€²lPœˆóòÅ5h¤^Fž/G*QÀ4è7‰#âƒLÉáq1:*F¦Uè¤VaS*dZ	Ïj‘EôÞoŠ“¼€~  Â|&&h&äÕ´>väҖ°)?¬>Ç…ù©TõGDyV›¥ÆAW)y{ªÕ—ånérLkƒóŒs³»¼ì_$Рâ÷¤=ÛÊž§RÖ6Ÿ³Íæn8$žêÛ¶µÍ>]«_UPVAæ6Ø‘©ê€–áë©÷W×øšê¡¾F˜Y°¯Cªò€¾Ö§n
hÛ*–ÏÍ÷Ïñ ;lô¡^ìC-]ø`+ÑšOtÑÔ­è`ê¡3¯ÐÙ§CÑ	¡‚“¿½ñ–,ëHqÌþÆØõ‰‡£bä$ÎK>÷⩘½ÉQ{>y!þøg¢^`fùKG,ÙO2ÎI=Ýw“.Ë k‹Éü,âj*ÖëÊaG½o¨=àúb¿A0Ký6Q`TÏŠ‘11¯ÆgÉY%1m£&lƒOyÙtÜ;# ™°)=ºâ†7ÜÐ{à‘	~¬…?•@wp$ãY4ˆP‚õv¬0xƒ²äÓî‚'/dÈ
)®’¼t´-ëɃJ/q§eב´Ô@ú¥=yªåÆRÞX{ïX“â¶Œ9ÞÅÒVŒiú~)Øàùy>©`‡ËÝéìtðvXlŸ€±-ëô©Z}Ú†€®Ò×Á†ZÄÝ05úåÍþ¾†@[-ÔQ7ß„;®#Ü|X}# ¿P–û¤Í~a³ßÊDføè*Ù`C#¨¬hÄ"=4Ç“ePïRù'¨Ì©ÂÔà¥ØPÞéÿÌ~‹‘z¸<þãü¡ÆäCu©ÛS^ºw0!þŨ¨}‰¿ÿþÞØ÷÷ž9µ73éÀÝ’·ÈÎS+
g^ìZ2ï2•‘KžËŒ€¶ƒxi^@Q°³üNAÀÉ8Dï2.‰6d^LÌ
’Sb0.¥¦Œä˜D`X°ãczĪČrDÆFRÔ3ˆ,‘5üpùÌ=²¡ëÒ¨P£È5 §‡`Tƒ”¹‚¾táâ‚çÚ“öœ'UçvòãŸÖ]EãN£‰§Ñ„³O¯ìéeרç¹]Ãõ%æÂ¦ÑV梀çîPÖ®«™?WóŸðÅOx_›Ð×Ä´òü}}~~OÒîW6AúZÈPYëÎzdõðôC†ö·.ÀªF8•° QÀÚ|Øt–—•f%Ä«ƒõMØh7nmBjFÖ”GÝú„*{Ÿ¬ø¨}›¬;A”ž¥1 :Ÿ*É×ϯ'¾Ú‘t¨ëÜQaúÑδCý給¿t+á`jÒþ˜³û"{@Ü/Äá““{O'ì¿Sö:è|¦¢œPq‰ÊÌ!K¯PWÓÁµx¼%fž‡XÙÈ@*+íM°‹Œô#Þ^xœ	MññI	>9@xy`X†¸¤“Ex˜¸£
5u#ÂkCØm‘µ³	ð9˜‘K
poŒ€E3ÓPÝßHIûéþ”8ŠÈ©^ÜY¡ÊÿR›ÿ—⌿ÞÊø{^ÒNFôNÊ點òë²ì?Öíé˜î+´ÜªuÕ7Õ7Œ4景Vºê.h.
^èèKá•ýÇ ðOíœo›Ùþ:®?röôí°ú|í>iK@]°Wlõ~WëÓᦡHòé€ôXT‹*›U9¢-BL7aC,.€Ø%poÌ(Eúñºl¢&«¾F”\…g¨kï“ÕQtñëTÍ›DÃDc4QT%ÓeéЕ¨‡çÞ¨N9ØzD˜öîÔ£ÍY/5f®M9|!~_Ü©bO¼}boÔ‰½'Oï=»w¬èe¤÷¼ÿ!ÎÌ\úÚ9º$™Î%›â@Óq´+
iKÇ:3p~!®ªÄU…˜¥5× æZTWhkpSnlÆÍ
¨ñn)í͸©U—¢â¤¿
aÖ£ýõ¸¡‹ꤽ
´«‘Ò7ÐN6içSÝ7¨ÞÒ £8Üdž#q„öj@^ð§Ê¬ßå~“•õMqî·™))9÷ë›ißäÄ|]šüUiÊ–½O±«.ÓXÔ0ÚUh¬Ì7–Ür—®¥kó+‡jK
—åæº¯mÊVJþÖÀü¶™ékcù}‘ýk›×²#höIê|êڧκ'£>G›ÏÖ½£ë(ú`a<ØkË Kl.…Õ×aÔS·_F»/b]Y "•<E$ÄçÎй†.~/xåMúêôÍ·@Ý é$hH «NíÞzó›Â¥™¯Öd¾T›y¨ï±¾‹‡Û®¼T—q¤.õH~ì¡Ø³{Ï~òBôñ½1§öŸ9½7*z¯àâ1_õ[ û4àDSÜš™ìŽ6§Û>!Û?ÄÚcàÚh¼.ŠèNŒœ}ã_ø×PÞU\PŒóKPþULt
Qç#Ækˆõ*f½†Ú¯!–Dsf—"=•£ãßCÕôdSÐZ’‡äµtû%ª»ºEU
öÃ߇8Ém9û߉¿«¸ø»‹çÿœ˜ñ—äÌ¿]¹øí¥Äß•$ÎÔ'[ÍìËîyéž±Í]5—_7—–X+/é¯çè¯Ûn•ºêªGZ¹óÌsÆÙó-º¿0øÛ‘îwôøú»|¬–§œÆ§ýu;Ìjß@Õ¶ªö©»þ‰³iGÓ½#b8l˜Å…ØÈ`¢)F…¸fÂ}…ã"Þ›@´§Q¹'¨¸ÉÓc>f¾¾üV(÷Mºøúú[ é4h;M5œ +OÐgÿ\ôýþœ—‹ò4]9ÂÊ<ÒžùR×åcÕŽ•¥»šp8ö“½g¿ýÁÞøã{ÏFâЙ½u‰G~™ÿ6ÙpŠàÅEÍ=E±N‡zÞ¡{ß#»Žƒ¦÷ˆ¦ÓDó	²ó8Ùz4^ º¯!×Þ<Œ}
ïÏÅúsPN."½òóUÄ–‡9®"Cyˆ®– Œ›˜°‚p·€ák´·<¬Ë‹òÂ-Ñ¡ª(º;¿vÍ{ÏWòá·7Oü©ìÌJbŸ÷û+ÉLMúSâùÿNËüÓÕÜßWçü¸ùüTsL;º\˜¢Yíújl`EÀ›ï+3eª¯\±_4\ùˆU /¹¬Ê‹§5{[z5·~n“?uØüJù6¯{›Ýô´¿þiGÕNgÙ³r[PñTU½­jØ‘µùØ}“38~N/Äk€D•°¢"Š›(÷*&½Œ	S©†èÜwéäèão“ÉÇ©¼Ó¡Ü·ÃùokO‡n½Eõ|@ð>½Qtõ›¡›¯ÿ"ïÝÎŒ£Í—޲¯¾Ú•Œ•q¤-ýXé…£ýéß=}(úô¾'^ˆ?µ/9êŸè}ñgöåÅšË|ëN$¸q¸>	¨¢hÁñ ëí`߇ÁŽwé†×Ɇw©¶·©¶tC„gçˆúKXGÚ‡2.a½Ùxw6Þ›…JrQõUÔœÿK!êÌCõ×0á
LZ‡HnâÎ"jº2èÊ+·Ä׃© &m¾—Ç<¹|üÏ×Oý¾ ú¥ñ(Nú}^ÂïsþžüǤ´ÿʽüvëϺ

Üä[¼“é¼µ™5–ë{ºæÙöÇ–FWIƒ³¬Ê]“¦»­HŽSœ¿¬-ÈdÔ{Ó3K¬eŠ1Þoî®~¡æ!lù•¸í÷ŒŠoÛoýµ­èIWéçÖSqÙ¶ºj{°`@|n€Ç„EHÒ
ÔÀÒ[§Ü@ä…¨ú"¡LÂÅ©TÙ‡TúÔÅOèÔBéo…
Þ£ëΆjÞv¼MJß!U¯ödÓ{Té›ÿ7ûíò„—Š"Æû*óâ«=ñ/ÕÄm;ÿraÒ±´ØC'£÷}µïøé½é	‡ÎÇŒ:³ÿzüañ¥×·;aª=c)Ö'tω`ëûÁú×èÆãtã‡ÁæïÑ
„*^§ŠŽã7“вL´%o¿„weÙ#æ ê\ThŠÝUB
(‰\z°V“#Åôè £4¨) W€°0ИúäFÜ“²¸oòÎþ± æ¿òc~{9þ·yI¿½žô_×#­OýUNÆ×•76e=CÆÖBuÖyUêyEZâ@üÅÁs{Ô÷-ã­ò^ƒ£¤ÒVRe½U婹á©ikkœh«ð4¤k®ÄÉ3Ïk¯ršÌZ[ß„´âçüÊ_vÜø][Ñ·7vúnìˆJý¢ªeõަiGÙ	©¹~E§_Þè¨Ä°¢’ß‚
Eˆ#·œ'ä	DOYyD×Èâ¨ÐÕw‚5‡^2^
*^¦4/ã¬ãxÛ›xÑ»_^8Y}ôÚé£Mño´$¾Þšr´<ùظ£×R^ŽO8ôIÔOböŸŒÙWxìBüÁô³#+BáÅ—ïU|‚±SAˆì>]§‚
ï«Þ¢k>	•½®|3Xóz°âûTÉ;TÁĵ“ȵX¼,¨»š3ðŽXo:ÎO¢LL–IôçŒl¼?‡`çà‚,B_Žëós	éê \½‘°Ojk Áå'1k?ÿ‡¼3¿Ë‰ý¯ŒØÿ*NþMAÒ¯o¥ý¦úâ¯*ÎÿGÅ…/j/ÍöWêÍÍ#­•C%®ò«¦¢Daz¶âòÞšÌù©ËýÈÂaÖ»kÅæTŸþ‘U°.ë[”7EÑû‚¸hEÖ
Oeÿ"'ßPÒëiqhª'…%ûKÿÜ]ò´¿âVúoíÊ}ƆmksÀÊØÖµ>•ÖûäÍOø•O$[uÀ^p¶<Äx–_Bih[&Q—AT'P5'ƒÕo[^
±Ž¥ß!Eoâœ7ÑšS;—?œJz«,þÕòøï5¥¼-Èz§ùÒwê²^¾äü¹cgF'ŒI8œ—ôÝKqÇr¢Žfœ>’ž|äBÖËöÒãÛ€›C°’ÈÖSTÍiúÆûôÍSÁÒBeoS5o}‡ºñ2qå<óm<ã8v!ÏK&o¥`Íqxç´ÿÞ}«ˆÁ
cÑ+	h~"\™€ô§ÃÜDv•\€9°¸ú¹¹O;N}ÛŸú—Ö~_óÿòbu#å—W“þófê¿w\þ׺ŒO
YYRé5éP¯zIØ;×Õ1ß+ßT	fù…𢛆’=#?˜øz~ä«)ÏžÏFkƒê;å–AzG[?Þyk¨ù¦«µaŠ‘¦¹\l/ÍV¦^7ç—{ªú=­“NÆ¿ô=Eß2K¡J¿ºÄg,ßvÖn{YÛ¶æ¿[ߪºþ*iøF^û¶öcíŸÕßhªÿª-ýVUôT|õïœk;‚ëþþ,¤%™¬ù(XýÝúZ˜{ ĉæÃÚ?BÊ¢{ጠáûד_+L}½9ý]Þ¥÷ë³_¹záØ¹óGÓÒ_NK?v:épRÊ˧_ªHx­ ö»Y1/œÿ^\ú±ŠœïÿKe
Ü•éïH†â‘¢¬<Ï=VD£õ'ñÚw‰[¯׿‹]zËø’ôšô1šäEûëNÁÝÇýÌ÷ ö Òãþ+'¡K	O’ÎìäFm_?ëïNñó/ìð“ÿΉ~ÒwñoU'ÿVñÉ·MÇÿÞõÞßzÞûmíÙÿïF”¥ÿkYú?3¯}Õ{eES>?Óg›fò'ú+Ýí“•=³uŒùvõ]mÏTW±®¨k¸ezÓäøtX}ת¾kë™b5¸kš‡›:gúÛfµãõŒ9^©§‹½¬(w×\R_ÈÓœÏR$§©’ÛFš8#ÍIÖhï…í/üVÞ©jüÖÆ¿ŽtÿÕÝøKßÕ-ÿn`þFÖòÿ´­¿²¶þZßò;]Ë7ú¦ßVýŽWþnÑßX—·{/î´ŸDRÅëtÅQºñåPÇ¡`ßaÐó
ÚôQ 8ñQNlUê÷_ÉMþ~Uڻ̬j3^-ËzõÆ¥×O¤N<41õhTÚáKé/Wÿ^~Â+©otg¿—™ñjNÆwGožùsWÖ·-é«:ÿ´<óIVêÓü´o’·›RwOjÞAJßB®¼†d½‰d|§‡R£kqþú3OûOìô}ô´ó£'ÿ?‡î$G~ÞiâÛ¸’8CŽ1ƒFûê®®.o³¼ËòÞÛ.×å½ÏòÞWW{ßðn,9Ã’#­n%JZiW!Q+R¢‘DŠ»Ò‘«‹¸¸—ØˆŠŽQÈÎÿûþ~ÏSÙÖÛÿ¢™û5oõ—”•B¯üuåŸ+¿ôlü2û§4ðómäÏ
K¿Þýøolßú©çýYn"ÿ™Oð'-çó¢tÐ1fÇúôEè“¿øxç‹qøÒ½ïðéÌû*Óž
_fò»²ì“ü5Ïž-|â
‡ÄCµÄ 	ò¾Øzheš´ÍãWhÙÇ9÷e(÷A9ò(î:	ŠÆzp¢æ¥²‰T3•kF"×¾©ü,3ü¤+ë0å¬5Ev%Ùºd·ÆnWSχMÇeÅò¨büªí¸ˆ IDATaz2püQÓýÃAòó¢ù	ÙO´ÀO
¸ßÈoý«æÞ¿+»þ[ó­ÿeøúoœóÿn{÷7ö¹ÿaYý…™ý©šnã,ÒÉï¤÷”»jêM
ím*ñ÷™”7ñ”×Ö¿‹'ÍÄú&‰ð»ü`’~Oºñ
ê
/ñ¦–úö»˜ÿCÅ|ë{ÔÏ´_Øx?á&aþLüŒKù¹•ôî}K¿ònü«æ½“,üßܵe~»ŠùáW’_Q?KcXüqpóü‹ÿi‹ü_à"“þ–Žúk-æ¿p“Zý«Ìò_—ÿضù+æc?ð4ÉþÓ²!)NÉZhïñé·x´÷Ü÷W	ÿaÿµ„ßyŸô»Læ7VÈ_“³¿îb}ƒHü‰ð55éM+á†CJú•ô
/コtñ‡ÒŒ¿“0~"`ü½”ù÷êOÂÜŸlcÛüÇ0æ—ö¥_ËWÍAÿ3•ô3&ío•Œ¿±Qÿ&ŒýªHûÒFPZÿʹyé¡}	>3_Úñß¿Êã>Ïâž$'`”µÃ¬RŽÛ†ÀT]Úª«|}wÏ,H	a3‡FC€|löž„Í3³ëÀ’»ò‹ëT BâtèÆ}]ýãÒµæÙò“hâ¿ð¢¹k~\÷ž;êŸtR/[Ñõög³ØýŒvbwDˆH­Ñ‹mØ¢#â¡’ÝQ:Ï’â–^eæ–m3Oá"‘:ñyf6mG*É1ÕEŽ»,ÊN­½½à“G£‚ò’Î
øÿ,\ù{õêß¹?Ðÿ.ÊügÛê_ùñ¾L	¾ŸÐžëñ&u+$ÇZù«VöÊ
œ3ä×V)¿÷áwÖ)¯¯Q_çq¯¯R~WÎþ†õÆ:áÿdR^#¾.£¼ÃÆ¿©¾µ-\4po¬·®ô˜?upþÒ+þ‹ô/cÒ¿v3ÿ:üy‘ý×YÒ´ÿæÁü©“õ·|Ê_‚¬?sþLÆøžý8Ã>Ê2³Œ’äÝ©Ÿraj=î»Ú,Å|ØTí•DÓ¼<ç2\;$0TxŽºÄÚ‘Ùfvû®Õ4UIZLr~Ñd
¡÷<-™¨5¾¸+56´¢í²D]NìYÂ~æ½Vþ =úb ÝUÇ©]¡jf)¼¬Bô÷þðaç»ûxbÙ3°[|tw30O«2À¯õ¢Ö|5^”žü§—û?¸Ú¾ÈÖ?ì¦ÞðYAÝ3€–¢%¡–˜èEÔe<£/öŽ?ßIŸFª%Íþ6Xðà?V,zq½¸—žÍ³ á0+|‘=MHŸ5q=É-Çø¸¨–ÖÐÔ’µ%ÂïÀ›úó”ßÇ2Þ&oÛdóÆ7ùÜ7¹Ì×%Àåu
éu,ák¸×µœ91ýãM.ûF^±òYRñgqé³Ò–_õ_µÅßïK?¯	¿Êð¾ˆI¾ob>²²¿§à}©_„gaQ1Å+eÙ“¢¨—çU °™â—b("ˆGX…(w)¦}WgèN¦P‡Ï¢¾óØìû§ýÏw³ÏІ}¿@PÊæFZ]Hs’d‰n*r@°g2T¹ñ"莱ƒn¦ÚMt8¨Åg¢m2nð¸ï‹™×]Š¥-Ý_¶ –ÜãŠÞg‹Þ
êïqÀ"þ
ð6~ ]_'¿)ãß•0®Ëx7Ýò•“¸üqQó¸®~0´<ïžïYŸïY¦có¦øAE|Ì|¼ŽâG>i7*+Fñ$;”c–‹Ül™U¾Š$YV¹!‰''ð4™‘'wœHîø”M©¢¯æ¶@ýÄ<‹åžƒ—ad
±™]'•°ô:Y5‘¦žä}çaýL¼è&jÕD£œÈè%¼yª2ìèÐE†bÇ~-ý4-¯-¤î\¿ƒ‚(kÓ}–Î=m×_¶¡‡QV	Jß]I.~sûöõÐ6w·2y™ë¼h6>,»ìÁ‹íçpÑúthÚó$îç¶÷·Tm¾q¢É<ˆŽ?í>ýÓg¥—Íö§£æ'm÷©MÜá©Ú"|x,ÒÀ*?|UŽõ–™KÙ×ã\bY]ö./x—çÝ÷¨Ñ
Y€À0¢,NBÔ¸V
R³i׺Q¦ ¡”ƒV®*GiÑ1â#™Ýx£éÔ!ÝZD\·9ªÛ. Ó¤êvµåޏՑ×wìÍ¡¦:Pæú²|™WÌðriIª Ï§µ­ˆ<b˜t]šžïë‚ma¸+¶%Ö¶T_êRn…ùܪ<|7Ž­š‰M=³‹&fó®·ùa'ÿBp‘;¤
q³°!«|÷ü¡aµ¼_a5©™jNª2ä­Æ UèÌ—Qç\ÑÌ&é^üÝ›áëeÊz!ìSÊÑ?ô8Ì« }ÖBì=tas=ƒ"©šÆ{*>.'D#¹BÔ¥–±zëЗ}VÚ:ró+\^™CHb]»öîÇ-Û‘K·gk~Üßÿò¨ñq½õaY2ë¦:ó¡åð'Óï5¿3UŽŒ¢¡ŽYcQòXT9]#–#LÅ(µ-ÐÜÃ]ivß –HVb»†ºàĘ=v™úl}“®©2=}Mxߣ‚؂ȺÀ½"MP·jÊBÏ–Û힦ÅÌžûí#³odvôÆOYjW׿yt=-bJ2tvH^FâgÛ[§fqPŒAz™H¯P$}°#£W@nS!íÉÅmÐ}õuâzZNœ‡gÛè<ŽÝd£!œåØ¥?vðÚùé›Û‹ßôݹ]¼CÌÅ×x
.&½A†H즕%3jœküw#;¿‘½Gª’ÔS“°¯É=†,;æä¹oûÈd˜ŠL»Rñ€I¯b¤-§¸Á.Q¥Miä8à<°b›Ô2^ÞáŠê,ÍH%Ê3cêA†œç
ë2aC¤ªìÇNÃƪÜÓ‚÷Äç?õ‚}PêðZ‚ùà½ÕÈ*1G•¶–™Ã¹çðœù¦_LJO³¾ýmãÐ¬í©µS­|jŒ>Ì®2á«$hÉáGžØýHf•±Ðuéjlj	(“¬»瞇Vâo¦°¸Ìš¤ÁÖ´ì*—UãQË€cGc™ªT#™}ßê9óZŽ\áûYj]p'ºöNpþVle>…z}{áÝÐÚBIÌ¡Ø5·ÎÇ9¡³lÂ5û¾Þý®:ù0á9pnL¡={ö28õfž$8=Š´Ç¥69Ð&5³$ir„
=Gåp°1˜w
’žHÖ—¸ŽÝê]ÿÌçØ÷éGy×À¯‹¶O\ú]õÈJ¨é
º¼/µÎŒòž¨ø²Ä«˜#µ'ÞhpîäI·r$\¯™YjwBsñ§å$(jÜ{æÐ¾AZBÓSwx%DáI öAzòEß´§r[å}P3‘¨&‚Ú‡Eë¡Q:SËL\Ž$ë*…u©¦oJÜÏ{O‚£ï޾;)?L¹w,ú¾Ò4ÖÈÇÒü‹|áYáð«Yÿ³¶ÿ·^À°Z|Dͬ3Ô#©qOÍ2°™bj]"–_6<Ç!íÈD+Rñ9Q•.ïð1)¯È»ìÀ‰Í2Óη•#¹óÈ%ê+•+²@&–…ÄÚuß»oún½Dà*üÕQç/üê©^64çŸÕ®™wL´2YÔåÛBnƒYVéhÌËmß¹ˆdfµ;*èE‹À™‡XBß‹ßD”2iû*佊'JîH"˜)€>èóÉu¦z¬‹?ŒYµáûéDj˜©¹MRüÌæIÔ5Šwf0MîkúqÌz 3ïYEÌf™
އEß¹—ѤàKhÍDaÝÕ%.<š.WÚ`ǯ‚šÍÖ±¡iЫŒÇg—¶Nìù'ùâÓrè$G\äÌM)Ó”Sƒh¨JõžFµ£t¹ÂSeÉz2ó®E>R9·µC½m¤eæ6dM5½ŠÜå@ltº‡Kc7Rxz•;„¾ÇbK¬<íNñ¶÷ÎMßMz&éKݧ>D"•€ÈePÑ“H2vKx\—ÜŽ!áz/t_¤1*<ëÌ’~ÈÞÖ^dŽ¿š–_ÆòÒ[3ÏöAHÝÕøö=îCOöA¾p•+Þ/žþà²ö²›{V-ÜVÏÌD¸²Ên•k•äU(áR%8h]\g÷8¬¾P¼«g¤ï6ImÎJ	-™(–iׯoqµSYòQÀsb¤7ñäòº~
j»ÔÌ™ÃÚ:&ºØƒ¸ï"`9°D/ô:™Ýåà*dÅÌ*žZ —5x²„}¡¨+TÑ3‹ªM–׉¹‡!ÿ¥—T#¯'ç–#7	¤¤'tž:œçÞÀý¨e×ؤãXaOjÞw
†bùŽ
_Á3ª4˜˜>'W°/¶¥@GM.sóhtð61¾ˆòßÂFî‘“kÛwVw±iüÍÀú½(ú½àºH»YCfó1ÄfTˆ°šÅ/ƒŒ*¨p{NAƒ¹™ZÂå6®y.
Ü®áfdc!Ž%—yØCØ•9ŧ¹æËìÉÕ™ÒÓŒ¦¯WÁ’ÕP8v]©ûÙÆózê<:&®’­o÷cOË–óáÀÉnsˆà;öúN‚–zf¤–ɬ@/“õ{Úì‹‚tßè{œàŽU¢©~¥HRÌŒÜÎMãÌ^|Q	ßõ>o´?­8õÁ+a¦(=OíÖµ
¥[¶ðýdéÃzåƒZñE!ó,|Ä@(vWÀéëV?Jì¼6Ÿß ¨:dïTœ<5?®Œ¾Û×δÈì
Þ‰¡xëÌ•~–ÓYuÇ6ýL§)=‡fvR~QÈ=Iež¦ñ5"­ÅÞ(`pE¦€a‘\À\>P"·L&Å–ˆ‰% ‡BmÃ0OK¯³Dv‘È­ÐÙ
¢ßðÞ[ޝ-Äׄ©zb´î;øM&1»*kr}Ç~ç¡×½ï–4¨äíÄík»_]Éw¼¨"8— 	ÚFõÔ®Ý1+ÇJï±;qáƒë%zé5íèTCµ°¥¶5š‘Í}²í=pl8½»Öòóbà*!ßµ" *ªÌ@å7½Ç.i[°}è…™×°çåŒ
#xÈ>É$žfaßv?û'8C½'®}Ü^Å}‰ãØ;ølZû¤Uþ°Ðùv£óVúi&ù,ï9uO¿u¿ÓN>͸Ïü¹g¹Ò‹bée±þQÕ{f׌DäVÜSxOÂ['~a_Á눅AæÂ—>q5Ç‹Âùçv“f96bËhÛ©Ë~ê~o~’RìëÝ—çÑ–óй~»uü½ÝDŽ«¤S5¡Ê\Íaa¦äuÅÌ6Î
1·ÊâV˜´NØ`Š›øÅ-ÓuäÔ?¥.Cì2€Í Wc‹Ì:ݸos8u¨@‰”¼Š–žT
O›Ò®ŠU6’‹¼:ùšñØ«Úwƒ#«h`/<ï„ÎÛ§AÃÔ9÷K›~ϯÑu€Û“ðúZÜ'ÛÖ=SðÄéÚÓÅνðÕ[­ä2\Y\8‚$…çØ¿Œ›àdèÊMS«&T
´º¡.pÑîBÃÚ}½á@ï¿
˜÷Íò´ø"Ïjp”#SíÃvèArðÅ8"|÷#ÎS¿
n¹‡!ó‘Étdq[‹O³ax,νáË uO¯‚Ò6SÔ•$B¦}—ãØ§Þ1Âà90ç.‚Á=[ãeuç‹™iÏ š(ŒfË©'ÿAgô½]Ó…×pêdÄ’‰”ÑÒ[‡vç¾Ù¶«e4˜*S½oÇÕ˜ôÏrà€©Æ~èÒô5²®\ÞÕȆ:IW«ªÅ-®¸ÁµÅ[‡^éP!ˆ#)P@Ó
8z™*éI—YqG/ê©)•W¹¢‹k[û‘àEÚ8QR‹ë„ºÎTºc;³£ˆ<Ìüßi¾¬ì|>”ô8Þc
»fN+êò˜]¡ñØÃ›èMGöÀ…;p¤Ï?
%/½†‰J6k'Z:DÛbiWÌ«ó…-¥i×-îªùM¥¢¯—ö5š±®eÓ®I;U.ÝÑKOöQ<þ(¬+¸!£. UxÉÇYÃ=ú4–—ÍtÊ™‰ÞäÓªtÝ®šÜ ”#iûÃrê~¨ûa=~Ž_„\Smó%$kË·öý0zw‘G1ï©Ëº£ÚÇŸ4]û¶ðULدeˆì¦jfÓNë¹7•³úÜØ£xÀwÁ«°ëÔå?ó8öÜ®€ßWˆÆZùH½Ÿ¶ï:¼‡Ûî£mÝØª[`ùô%’–€W"*š ä5¥øÏý¼69pRùŽ·ØU¶eâ0ílÑë"q_#èÈ…•ï(Ú|9à·´š©žT"mfׯ¥>ÈÅ^¤ŸTÊŸTüÑiç£ÂÎwÚÛfõHŒÉ Õ]>½:“ÓÀ‚g>uÉw®#Sâb+~妉lK¨E£DUõ•ú±^3Ôžxh¶ÕÆ-åØd?°©§:÷¡kûÄã80šw¦yò¾ßud‘åûIïyÈvèVNµš=z_¯92(öµÚ=³~×Ìiò¡~GR~‘î}Z›}ÞK_ÇurW±Ôq0¸ï¬?­Ä.’‚ŠJÒÑjF&í®†qøú'ÎÀÌ=À^iÚ±Ókœ¥ŠZRk v×.›h¼W^ùL¼ujó9uc°+dwù®¢¯àÖ9‘Ë€ÿÜgÙä}µ²¯–õ”ðaÈ:õȬ„A¨Á`רü
YÓ+Ú ·ÅC×µ3•¤+àÕX„Î25ní›9eŽndV,¼Ž_âʆÓŽ‹Y3êbíÌÆH¨Múµø‹TîÃ|ý;ÍijÈôË®ÿÌ¢²E:¬àøžÛ’
tQS,(y=±p$WLÛgðˆÉ½û&°ÊÆ©è™1Àž‚ÕàÁŽ¦î«€Zn¨«Sîhm‡VבÍu¸åÜ·Y÷ʩȲ¯VŽAû¡Y:R(vŒöc8TDEÕûjÏ…›Óãq†|Õ®Öt`Ö”Ñó-ï±.rjî|”ƒç#ÿ0Ö|ùvÙËxê*i[$u9ð« ½Ìv¥ü¨ʶÆÊ؉ýð»;‘³¤zd·d¸,•PàXv}œ†ì+¶¯‚©g)ï™öPÕDÉë
À¡h…]9³ÌTÙâ–Yb°j\Øu56µF£À8ÔË»2n•!éD
–´ÎVt„ì‡Õã8Níô:¿•°RKx°¨»`æARÔ×)Æb	$B|r‘E.ª‘ŽZác«ÖHr
ú¤¨?ÒËvÄÆeòI@9æZ÷µôY5Tà²$VUL¯I˜M1¥Ä•Žô’©‘דkvô†‘RTe‚M*KZÍqe6P²["z•£è%£Â´¥š©Úy`4Ì4–™Ás´¥ª}[Ò	cÀ„ƒÅ~d×ïÓOr0­‚;Jç•Ërl	>ðKGbÅT&K´ÍÖ¾)r¶<54_&«/b‡8QíˆâC±¡À…OÙ“Ùw·Äm¥ÐŠt Äj\)ÜUm¡¨J1tÙÉsoô"6D¶™VⱪrIÞÈíìó²ëôZw½žãÈî—ÇÛ÷Ó’©-÷¼¾}=Ë<5:\òžV–ˆºZIOÍ.1m‘f †–Q‰2¡D¦U©ì*€O"¨´z Röäñû	÷1Üþü³"8Õ{ÚMh“\eDg×=ÇnÕX&í‹õ;zZ…E+ø,^çDS(íiˆMïaâZôqSÛ4›<çŽÐ¹+pî¶ìa-ä¶$@U êiD
µ.
ÕÔ†êÍ.ãŽIÖà1sdz±™!	[2ÛÌ	kš®¯÷îÁlºÖ…‚›[ï.…ï2«®@õŸ…rOs½ÏZæ#|$“
$ʾL7Uo_xWÛÕOj©')ã¡©ð¢Ðú¸1ùlè9r¤ïÇ×Þȹӵ/Þ>R柣=®sëø‹ÁÞ—ãØ¹+uágB¯¦’Ra’ÊÌ	µS+µ@a‘¼""plÐOøù'‰ÆÇMóÌ\{^Ûûr/õ¤0ùÞÁé=´Ÿø­έCkéi!q–°íºùM
©È§–¸0¹©G:ûŒ@*L™F©3)e*§ÎX‹Þe—H¬"É1³*Z2ýÈä8t5}–=³zG³šE°ltK…IK*¬ó9%ФÎ2Œ`ô¤2«t~ƒë?Ú†A±kƒ>j_[‡VØ=6¶ŠµÀAÉåUY¶„TbÓ*ÅÈ`Üs2BNGJ©qù•f׿:öqªlA…+®‹	
»"Ð,éólè0<
ä$í3óö±‹_£o¦–çüo-„nÏï®&6ìûÎÝ/fßß±a·îšî“­ôã¸çÌé8…——e90jgêíK¯qG¸ôkàì:4²ëXnmݶ+¶ìI}'öæGÕƒ/§¯ÿÒ+„Њ&GXçèÆ&Lž§¥u?7ž²¯0%¡c“¬CáõЇ•ܳRúqA?Ò×?¨yN=õO[;_@/+Ý;ÝÛý:áãô¸"ëè”c#­Z½¬–HßÙB¿ï`´„a#ºÀ-“Á÷Èi.†`AŒ­'Œ@²¾N71*GJ$lgY42‹"Á‘±$u-GK€¾Ê«tXT#åÖ¡ƒÙdÑêìàe<ó¢zÙ¦¯åW0Ð&6‹¢fQÜ2‹˜càòZE¶TˆËiJ˜u¿+…5Çrà‚‘–QãˆZ2RC-ð…M¥mæ3Ïl¦cæ~²ò(_}–vXÊ‘d-úÞrèæbðöûþ;¤Å>s$î'2O2ÏZþKoñChë|«øa‘ßc)§ ¨Ë±ìë‰U"»Ëvº©Õâ
.¦DC瑄유†µŒ%þCGê*ê›:‹gÑü™¿ü Ø5oïoCâ¶&sU	õS7¼”ÆWODþs[辟?ƒ#¸ö’®BÞS:ö­‰‡áð…?õ0žx˜´ïY[¶—)ç®Ïw¶ŸDS³'TíY®óÄö¤ÊÿMwîC³ˆAGæP‘9\j
Q`5ƒUÔ‘‰ZF™¡žh¸M»R
,jîg³@sMÛûVëH)iñ¤)»ÍtAã¡Cwàì~grm9±°˜XXŠ/n&Wñ‰5B
KÌ“Ñi|øCÐV0k\v“GªÂÀ”4øâ«§’¼º„Rä2lVE*îjUiϨK]GÆÀ<ñ(…)“á›y/…TN­ÎÓðµ{á»Ë±¥ÅÈ5»FN®àކ¨TˆN)1Y5µH£	dO)“™M®DRôä(q"—œãÀhL+qy=¾€d×I¸ô¼ëPï<Ô“!6³FËbyMXdÈ ¶¦*²Œ
Ûç¯Ø«]Ða³Ú¾q#¼ò–ñV±]aV¨¼* È
c¿'b¶Y„"•^¤—p"ˆ)…ø²OW•Ks,aä6hy<6µo ¶ïPÒ¼*ƒY}9¢¸gi…©é‚¢H,±HEŽ´¯sxj/+¥'…ÔäçÄ/é)xm±h¤"7ÙÌ6hØs0pô+8=>»
ЫxQ‹¥èKÕ-­ÎÇ”ø2ývà&\l±yLè.«€–7˜æ‘Ò0R$®¢´ö=@UΨʰ̇hºRiT5þ‹¨xwŒi%‰A¦QÂŽÒž¾v/ŠÆd±˜ì&¯‚ã•âAÑ¡Yw•¢.¾›4øî°ÔŠV!s[\p ¥–XôŠ€Q¶¶•ôº@2Q¢ŠHzƒÔàYF 2óDh•R\–h’*O›gS¦®H´-¹q¨“ö$ü¶˜ÑM¾ ³„¹Èúž¹w¼÷®ûîÝ
Ü[Š,2(uO¦îHà¹SE´ê&-„o®´ÊäùÂÉ»O\ʱZ5Õ¨¦*œxYôfÔ@…+ïÊ%]P?Ñ&ziWL«Ñ&¸”£l^=äB$¨ä
%µÆÊ m¹}¬õì:‚ûðIDÖW
ºrZ•ÎR–ãëëI¹H¦—éÚ‰žÕëwš‰˜§l¤ñôª@Ö±\CÂÈᕬM3…ªÍ>“xu†±PÞå±ÊjC.àØ
–d ÷œù™rd›™Ûs «-ÎÔÐÆrjn=³¸–YXIÏQ MA
48Ú¾BÑ”šzUC¤ëʧ~åž8!½Î#Wø¸"}5¾å_~Ý7÷šçî
ßÜmï½¥àÂjhžS¡ñ«lýX'é‹xU2E1Äç…BHÈϳéI5¾JM,#7P‘{„’_¦Êí&`2¯Š“T@tHl S¸µ4åN”¸’¢á‹aGè9uÛv­‘˸ÍVŶC»ÃÄ—°ˆÜ"½¹–&)zzíÈ»‹q¢W
5즀Õ*\LY°–ø]	&ƒ
x~‘¦,óŒ=ÅÖÔ:ÆOƒ€sf×MõÈ4n5‰ZŽ­ ’›¨†P$ã‹$J™áØw‹ªaOJ9e>K¿Æj"aƒ¥ê
BÇvϮν«J_ú<{zq‹É®ÐØ&£_:–V¡†.bî#?£.ä4Åô¦@¹cVÍŒø@ªQ9Â,§îŠ(uެ
ª»
ëÈ»;;v¬:ŸReaàwipUSü[&¡Š˜…ô£	ˆ ´+ÔÕæ‘Á:6ÚaBõS]ü*»* ¿Á€M•Z¤£˜µÀÆÊöú’uη¼\^ð/ÝÛ†Ï`^¢Ñ!€Yã÷ìøššÅR²Tr†AJä$’¤P¢›¤(
\ÆÅ´IXæ ¦¸ÂU˜º.héKåU@^bñ‹,l¶EÎjŠö~½Õvi$ܤ^åPl‰I¹%„’ô¸Ás¿u׺H§mG¾;Q2ϼƼDÎÇñ²¾šQgâsy_Nʱ8@V•[*çÐêÛ†OÓÑ‹„ejP”	ìzl	£Öè•$•%ˆºrAO"ïJ8&*¶
6DÌ2ûÚìÛ{Þý`Í*â´]±´ÆÕé‚*W¥ò*4°Å¡BxÖ¿QÒdq*°ŽÓ9u.©@[ÏHU¶rb$ëùMùTÃîpE=ؼ–óÖÌï¦sæ0N–]kñIÎySyDÒ—ˆ{2
D#¤ñ¨Ù؈ Wƒ«¨^]
¯""«Œ2]Ò—kg6õØBÈ“Á–—!­ÆËa4"‚DW0Ñ
dq7°0Ý@§ñ¬"À.±¥]‰j(Ów%–®L߆ʉI“Yú(æMïêûaä»Á¥÷·ƒˆ8ú[Û‹÷¢«0n‘òž#“n ñX,;¦ÐY$÷¼â9	°ZâëÁå›áµ·ü«ol/¿³½´G­'ÖVãëkIÜBŒÀ­‚ü2¨­Ëí}ØE¶ãW…ÆG]ÓÔ(nƒø4—""cTŠH*°ðEæfžTø¦=‡aÇ"hŠá8ZK¢©æµòÒÜ7+;JÄd‰’:OVå™jÛÔ oƒ’&WP§SŠ8¡"_¢ÁŽI"IâZE‡àV©Æfë¾S1Q“«LN_$Ÿ´S‹ñÕX»p¦9Ý3ßÖ?vžˆ^&t»V^[BoYMÆsJ…F-Rp‰MN‘†Œ¬Ò‹$n•Å,3ÝÇýŽ9ö(o8p“+< Æ[Žã¢ØÛÕ›ž÷–ƒÛ·üó·‹‘udC-¼AuÄ⮸ø$›<
Èš| @ÙHa¿Zk{õíí寻æÞðͽµýþ7<·ßÚ^¸D¼ã_Ad0¼_f›¯é)Ã'áÀqÄ±í»–’HDšð;Î÷®—n†×·çWk·¼ï.Dà³\¿BQ‹|NIhlk·ÇŽÐ?ó0—{Vu¹-£Èd@,|ŠˆK“À†‚YÚ\®#ŸíØ82ÛRNG¾–#QêìkÝZö™	ÆUa•Í)3p±´¤†®Z×UšÇz^•Å*QE³ˆcðÌ‘#oÆ7ëó¾
d‰¬S§°jGzj™Å|UôvåÔd˜šì³g¶åÛõú÷ÞýpñqÅ:sH»*NO%Øm©d¬e49âW+	ÿ¿dN™«
è':ÃŽÙwâ·{µûfK¶–"­¥(·‚s¡õù0bÞ{s%pwÞÞ€µèÆZI.Ñ`B‡“×áåžd\ûvËŽe#ƒF¤±ïÀ%ï]x7„xÍu÷uÏí×Ü7o†ßò/½X3°Îë*5–¢#5t‘Ó¨ijÏ<)jv,0­®g0oyo¿î¹õ»Îwßuó†ïî;Þ›·|wÞõݽÇ®¤å×[ϰ=²¤/"¡«PøaÜwóúT=­¸&ÖöL²¶RÞV«z&ãŽÃ¸k	^Ä8]¡&æöuHˆe£&ä7$’–TPiCØ”UŽd¨æuÅôG=Ñw,ê‰É¸k‡yœ^çãJ´[‘•oùçæãkoûnÍ…ˆåVhu³ÈXIQèU®qdÔvUšNó¿Ÿ^iÆ6ÍÈ&jku	&M\I I̽Øê-ÿ½ëÞ;è<ùvxUä+RíØen%N‰³PêQ"ý$‘y’
^…¯;½Šoºa%”÷%ÒžìÙ-®x¤ÒO-‚A·ëÛ:‰Õ?œ\K<ˆ)2°ÅãÕYì*CÛSeލÌâ•n‰Á(Ü2›
q$M¥À çØÚæ|‹ËEï6JFm£™)%ŒÇDZ›)4"±FÍc©éjrNXFó«hBf€6	©5Q'oʤu…¨/–J\QqsBvË,ÁÏa7øü7|Þ>
øOâÖC¿fÇ'ši
!2'•WŸXT™Ô–ˆÛSÃ	æ<ð(û:QOM+óÄ•¸§{Ê­£mýÌ’¾Ÿö”öCÏb¿Q ˺@ÊìÍ,n-¶BÏà
›$y6»ÌÓõµÆ±Qß7ˆ[JU߬Ú¥p#¬êYÝÓƒM9­È‘õ4¬šˆZb£rÄe˜/³T,Äa4Uñ‹Bø4•»ŸK\†ÃÿE ý8³}‚WØ’JaÊM²¸Åà7Iâ.PÆIFLÏió­‡^ÿyòùŸ|rÍ8³°›<^“+†¡»Á–™Š:Ÿ‘ÃrrJÞt46¡N]¤éqYâF
@tj–†a°7Ïc&¬<ƒ’§Ãá°E,†çIébbŽ”|Ÿ^X%¤î!sÈø=V çEK-®)¹E#'²œÕøæF»‘EodPô
à>rz×a@ÚÖ³ÛZ[†­ÒW³è98Lò„ʼnֳÇZÍá–éÈcÜq
›
zEHØ‚¶Ô_e;V˜€aü%¨dˆN¯³ÐE*»Î5¢WǪê"ÛPgìª
-
ÜsêžJPÊÚ
ACƬHùMµ²g’÷lpjkúFuß`šZÝû~Y_v”«)ô­ÈÒRK­I@ø»“-ÿiv+X¤ÜGNÛžCÚ×€=5·%ƒ÷Qc‚–mO¥™€@C­x-:ÿ˜Ù@F†ðîåyçZè4"iËT}•¨!×Dš¦XÝ`ssìÄ
[bf64öUÈ–xÔ*ŸXfóÛR\ž
ß8Qdå™Â¼@ÞTpKb–H(R«óáEtb’]Å&î®D¿…ˆÜ@DßEÅç%½€uXUp!1§ ØH`ckK‰õ{ñEr•_“¢'£iä"M?r2šr¸~þNrõ^zc1‹[Ì)mP8ÕZϽ®ŸçÈ­è%6:ƒ5ŽÌÆ©M;4Á™Ë„Ã*¶Æ,’1)$®DfÕÙâžNMOo#³£§³¬ö¡Í44(ÛJ6ħy„—˜çqj2~M*i‰¤×MÞƒ ï08MȆzLL*³æ3¨Mˆ†X„ºD24½å‰Þºk1íL3«¨«"BT –™‚¦À±«å×	¸ü»JAeÖ׫Œ*›A®Dn)ÇRQL=Î_3LÆ¡EÒËë
eCiê©”5@ׄ?½"„0²—R¤#²äùE<0(v®–PdI`ŒiJ$u	¿ÊWM´˜i9‰~?ŠXŠ.£+ÈèÜjäæbä[+Ñë+±o­DnÐ ,¹@ÐLLÚ‰W™EÎz9ÿã~!‰ @YäÖ™¼[Ò‘’KLAW,R–
·RË÷r›0´Å”(žj·Î½é‡‰ØY ¼ïÕuT’¶Ð8‚»Î*npY">º‚
ΣÂ÷ðé5V¤*¸'íØd™˜;<Ô3¯mâQwŒÒ–‚’çЊ°Öp6ÓtbžI,¬2C1R¨G*Û¾3z‘ñF{A_µÁ¬A”¹,vpçÁ$Ýzõá>¯ÉµxÊÚ4s°šRdžºžÃš¦zÝ@ĬÂv›]^O-#â‹«á;Ô"f%òîF⹈Î=Î]ÛžÃQçÈí{U5•¹#ï>)Ø:ÜØ®Å=Rm4ŒUØ–®ä(wÓdlYd;Š˜CºÝ-Y_ë5¬K¬\eaK4ÕHThÈ“\ÝL--Çï,Ån.DßYŽ^G§îQK°wàÀ¶HÞS;gNi]Ä(RV3(r™J(``I–tyLˆJ+ÑUc£ ¯`u…·Ó‹«.ô0Žu±géèÃXþq:x¼Uz˜‰½‡u¬÷¹Ì;z~…FŒ¯ ýóÈÀ<&¼@Í"8
*·É÷¤p-k'FóžÅu윜³mû$`ºå¹ÀA§éë)*b¡sd\ž£0¯IgU‰ðmÔ¹–©Ý~°-ì+qu¦`¨¤vÄô®|­LÅÔé’±’V$=±j¤ôžùáŠ>È€=)¡°É(c”}«‚Dgî ï-ÇÞßL­­Gî®…ßEDÞåÖ(º‰²ô¢|­zUõŒ½ñ½„gâ³´Mî¡5¸g+ŸGòaCC hñ95¬$kYò\†B¬É˜=ª$ævÕÔ:“ͦ°/ÒíXp%@ÖSEÒäã2ë´a3»º’¸LÝÅåW£×IE$ØáÈRí@«ëjl½÷Ø¥›jÉe€VåØöœÔ2œÚB	§¤¸2lõXÇíñ
³Í—Žõþóxð<®ì+­SÝÖžÙ56zvö±Á:5êG
v™DÉ,£Cw7C÷þùÐ<.±D‡pðú‹» ,hª±Æqè
"—‘ÜœSß§ØD9±ÈD¦ÉKqüFO+Ó¨%".»B,¬©F
b~“Y¦3k,Ó¾Ã}`
$Ê+s¨ÀÖYø‹Ð`²:ñPέ³àJ=Êk'zå@‚Í,ⳋk‰wï„_[ˆ½±}›\ÜÜH-Ã>+h°Ð©:„d@È—öìZù,¿=ÜÖ·LŽá–k²eêšU-…¥g•øòº˜‘§PŠvC8—Üd5åk¹®Ô̼ô¦FlaƒT®¦–P¬r¨Uwô<ˆ-®r2\¹ë™••ÔTn•™Ãç—qEº€d7Ó`éq!s‹Ÿ‡»VÍHÇmÉy-9©DGç0›Y$6·Ï ¿Æf×8š¡Ê¼k4Ï,Ö‡ûp[=€÷Z«h‹Ô]¹a¢—µa“±Bæ,&~g#øÞZà6"ðþZpX$¥×i†	QXe&¯Æ7NLÖ#›ãÐã=9gA×,/¨+g4x`G¨r±9>ÅåÖ±ùdê!@g–0P¦jfÆÐý˜úÈLhñ¸c
¤¢v@r›Ãî‰-®|¢QMÑGéìƒ4&½@έÌ_¿üÆjüúBôí•Ä
B!l²_©~…îž™Äu¢®ËùàO_^‹Ì¼Þ‘Ó=Ùâ@Q]J+°p)ÚJ³Á‘³ŒÍ$__I®!’H€°Ç¶5¢¾yn…4r=…@fÖé5DjŸ&K 'ðr,^‰K((5Y@ldé÷qy½þêWkØQöa¾ø°Ðÿ°Û|Þð¸­S—aèâÀÀWᬥQ9ÔfF¢eªžù­µ{×âÚ±8§V]×C”al’¶$`SÄoœ&Ȩ)U"‹DdËá›kÁ¯v|Ù½V	à>ÉàºBí)ã[r]í¹fd©—ZÁ‘J8z™Ì.YE(Èä<FRûYÌA.»*§ôª)‹fƨŸ3€ãjå¸J7cŒÉãθ„Þàá*tL‰Bæ 
DHîç+
eU6 X–±ª³!§Œä†Œ3	PG!)Á7-XPå:»Ÿw¥¾‚gš¹N\®“é¦ڨ¤h˜Îê# •ðx—<–;ÿ}?¤Üe£Jù„øk¢”=Â'rڊد2ÝÍÙ.xI ó†8‚–lˆÇ-I6ƒ&©è[dÐÅ¢qP1©0G6®7Dâ¿.BpGœ1!sT@­q±VO†ˆ)Òà9*®ÄáªªN×0êkmU­ÑCí…®p)5½}X匞éÄdº»Â_ Ó]ÉÐ&"‡gz{ˆDK0Jùp .ÒÏhØÃ(l‹®kî»í@. ‰,³L£”8è­-ŽìM›ãðÎ$¦;'d‘ˆÄux²™V&t$Qð"íV–„ïçp«rÙèœwîø|P„ÜóAí„]3i6Œ¼šNÕ0Šò
àžv€5•¢¦jQU¡žÔ3XÒ*ƒhC"•j
÷¯¤b‹^͈*PU*« ²®V¼
—W—BéhÎ [³Hl“ºtÞy£u\­©Éùƒ|~UÈCßÌ…—ø°2Wᳪ~]Ì«AmÄàÕœ‹Uc³ëlVGbSø¬~¡°"kz°¦ÓÕ
††ÁňQW¹!¹Ì¹•CµdámyDWÕ…!sˆ®d[g¢¥%üUWª§5ÑÏáz3¨ÎDWo²“SËe]œs¹§ŒÎ	“}Ò8²W¿y“*xÃBî ˆZ`“s4T‡Mã»’=]IXO‰NãÈY·‚Ž·"“í·âÍ-ÉöÖT/¼€¡Ѐ†Ì8®‘)µ:댭ü¸ZŠúÂÚ)§mÞ/¨j8o@Ê.‹Äý8¤W
Ô5cð^Ä:gQŒ(e
@ÞÉëHœYftì*òÆmYTw‡ëgˆÆ•¾¥`p)Xx’©¬æϦcwìö)µvD®¬+UuÐKÃfˆ¨žDô&z‘)>Kħ1´	—è%¥ÐØTO{üfwº«)ÕÒ‘íà3ÿ:;¦”Œܪеà,=Ég‡×Ü~ÿbX6ª#”¹ØšeÙ€\9êª&Û¨#ý(«Só‡Dšq‘MC£­¶Y#º€lÏv5§{:˜î"V8&×N›‚‹þòÃL}µ\[-¤ï¹Cwlþ;͈\;¢QÕ@÷¤'8H•

"‹ëMÃèeм&´ÍêƒÀévÚ'ì²!m6€î°ê*\E€*Ó%	eHY2}ή‹ùC0dÐŽÚ
§eÔã˜ðx§}ΧmÄaoØ¡'Ž»uÂe€+zóXdƒ*¢9Užpø"ÑÖ’éù<~«+ƒ†eq-)dO–Ø–FvgÑŒ~60,ÑÖT¶šAWkú¤†¥g"᣺vÞ„(á{²X‹Ê0i&ƒEeÐ(é%…'%1ŒŸÂ íäblx¾Uìá
QMc
ÿœSXl¥Õ|åivb£VyTŽ.ŽwCà¤Q KG@TŽÂ-ñUƒ*kÃ*R™gì¬!!¤ä5£Ìç$„Á=fãÓѨ멶–lww	ÕUB²ª<猭ÿAfd¥j§:ºÝçŸÓïØ*u]ážô†§"¾ñ`ùá`ân‚Wbb“B
ѯvTišÐ¸§l±ùX2ݘT0‡dôª¤·@ÔΘ°w€*f+Gú0[ÐP
êjpÜj™ñX&}ŽÙ }ܼu{Ücç˜Û5æñL¹Sv嘖]•P¸ôAö_Ë`n[èC4È®¶þº3¼€‡À§;K õñ)!¼@F©¼ŠHQU€,‰U9‘¶ çDcË#×FŸ*æU½}ˆöB¼€ë†¥HÃdÿ:9ŽIÁi9-f¤ÉØ(CQ²ØÞd3>‡@ºdUŽgÆØw?•Z—󃕕âð“Rÿƒ|i1ïŸÄ“¤>ªH§õqi5C“„ª’L5¤6NC5ÓàJuÃÀÊq^܆D{M“šöB[OOSîVk¡£%ߎ+ãã–à˜czsdøiv|³™7e–‚ú†ÌT3€e•sÀY½SÓu–!=NR÷˼ãÖĺØ'¬æƒ"/S禲A;¨Çå˜úIWG†Ø“§Ò‡ÅˆT-$«L…”˜rL­ž4³FÃm‡ïN$°õÞ:çB®™@`>âó{&|žI{ÚåžsZ¦mº	«°Øæìæca9gúÏ5úÝy,¶LîÈ"{s8J‘ÓšDC¦
Q *ÇŒ¡ùp`:ä%Ò$OeòBLqT^<ÐÞUc†0ÅÎÖ\;ºˆ*(4B‘HL£è9‚¨Ì%Ç	ÄÃâ’(v‰¬©JÍcJÙ0Ã5¢Z*ææR£Ëcck#kúãÁ¡ûýÅ…¼¹nâõóõZLžL,Òa	´8Ï礘ҜHX–ÑúxŒa±hD-Ts’’^3–l£ÊÒÒð½€ç¡£w ·)ßr+wëV²½7Ú‹óãÌ}Fç°ièQqàA"0©Œ[#nI’&Uê„ΞwÆê±ôT2ØðR½CI9p¿ì®Ûu»<-5äuÉÑhc±6¸X¡gøˆ4WÓvdiˆãV&­ªèy¦±fÒÕôêh˜4¸gÜÑÛ‘ÄRÚ»,%ý‹ÉðbÜ¿ñÌx¼3ß¼×{Ûã™óYfÖIyš]Jç—²úªÖ:n1OY1¥Ì •i˜…TæÉÇö¹ ¯pŽy‚£An„ËôÓé.2ÝE3-÷wï_ë;(â†Ðð¾ÞÞRk˜Ñ]€AþÛ#”1œ
U¤¨†ešš†•ã’ÓTZ†
†šÜ0,5*ƒ#~MF­ËÆŸLúªÞñåQ]Ni(¨­e]xÔ£€ŠPVÒJTv†ŽòÃ8!ÙO!Å©ºq3ºÄFôä,¯ÇCêñ,kÆps<Ù˜D8.lÍÞú$üÉuÏ6kÃOÇê°|[‘Z+ªè¸W_PsZ}J+òŠÄ^©&®÷õù´)8ÈWÄ„¥ÙŒ»l3fÕž'ìBb¸¬“j$‚Ul2!ëײAjEÑž¡Á³Ìö(Z1 eD8œ°À4`‘ϨÛ7êr:Ýה߽vÜ	Ùoû³׬Ë;ãðL{œÓ^ßLT]µ¨+IJÊtY'ÀVe@	à”xŒ2‡Rbñ‡üA•p4U]©éÇÏÃq3	­Å²œŠ…®‡¯­}¿Æ«³€Qq[¦™ƒÑ+tÜ Ù â¢GÑgÝ¡i¿¨(v4슒ØÓ°¹j&}Inë3r:’…jïs鲯Â\1?›	Ö}þAhSa)‚¦Š"~ÇË*âe=AÀ»à$;mFÐ#LYEÉ–¢
,\ŠÙîD`ÌD¬§‰iômv)'ªMÖ&¸~Su£hÃj±
Za¥d’G¥Ê˜JRÐÌLkÖ&÷«ôq½Ä'æ:Yî~{¼æ8hꔲè쑵wIo¡T=l'ëféóã#ºX€¥ÙIfG”
‹ÐYI9ÕÍd|¿ˆããI“RKI¯Œ	iP’d9PV‚B-+€Æ›2«0Vl‚$ Ì(¥y5#(dxØÝ²^œÑ¢Ø^+È¢Fè²¢‚S«†²½0§òգƜÂpZ\€~ÝL3f
‹Ûw®ÍO&´¡õÄ;ø%–²&£Qèu
né~à°ÍwÞš³x;žÇF¼þºÝÞo
øxn.ÉLÅÉx399‘ÔçŒ@Dæ°Yóz (Õ=¦yhÊVx3Éh~$Á†à¹™$åèeåØ@¤”¹·"È;¬Wë•öðì¾]ž+†¦ÃÌ³ÛЉ0ÀZÄ×áŠn’‹TôÐM$®“íJ‚×%$›hڄј±X3V±O±³­E+ßÃ…D3á:ÿ«[ÂÖ¿SÞÿ„òÞuÖg’V„¼Û˜3€ikÄïŒÐ2²®ãcy«0 Bë‰$+]”‚Iã Rx´–Э@#5„^=k¡Ò\ºƒÃr²%aÎJæFÄ‚„gcôhÐM¢[4+£GChp5Œï*’ ¹ßbì³9·êçzyD3®€ÁdD­D`A´=gYX›½6º5ª¯jp$?Íá%X‘Û>ß=§z^)™†±š	Ed>¬JšŒÂ]±™òÁ‹¾ vUd;¥Çuƒ(q°õ»q•,pÜLž‡-‹ô…>'Ë/Ä\£zGUÍðà``JÓ%r¤q6=EÖŒ¨p|OÞkéíT¶“uD¦™¦ûõôx’î¡u)Únò¾ê•Ý‚rÇs±DnŽØËQETl—éàrBˆ#èÒÀvpèf2EOPÅ”‡î¤·ŠZš„ÍŸ0>þ€øî‡äw>¢¼ÿûÓiÑD`Ú鑱7"á%¤X7£×H¢X¸`ÒÄóx#MQ}bº…„S£o‰{z•¸vÝ&E¬<²C@0ÑF2B‹¦¸˜DHiøa9ÊLíU£¯›š%-½JØ-É-Œ#ð¤~‰2ªäûyúœŽå¢Q,¤¢“¢ÇÕhœARcÙ&Zz4víáñCu¤ú)¢¨PâèÊ`èŽ_:%6ÞÕS«”øý°0'pWʘˆJÔI¥2©ÓJSÁÈò°`Z4ÃÃAèð/?X‚1%ÛIxY'͘Qg&b¾ºÓS³¥¦¢@L„Òv²˜²•ë£pâ„Ь“œDý˜C{‡´©SÔJ†ÓDc
iP$
‹;[7_´‹›;…ב@ÇJ¥ðú„–e㪢$ˆ§Û9T#a¡Ò-d’CÒb®8(&š(
êÚGï’ß{ŸôÞäwþF{÷ÆG_	¾BІ¢Q±Ü\CÙ.
+Éf¶*®Gih,‡˜`dè³f®‡Ë°Ñ»%]MüÎ&!ü–Õ,F´JÑ]*ËÃÇèðpE´ÒpV
ÝÇDåHg¦4KZ±F|“¨¡AâuX¦‰"pryN6ÃA"RiXĶÓ!1FÑ‹SôRõxªDZÒn÷_ËÎæ¸\«’ –¦Æà°ÊvÏ.ŸQªg4î9—qÈD]J'	J5Iµ£hÕ#¾Š­CwªzZd]*8ÅAã¸Yò°ÄWqBÙ—…„’Œ+âãñäD"0ì9=ò¦^Ys»ä:RÓsçïÅ´E)BßJ4 nñot‰ÚˆZ´"½`B…Ñ¡[$­­âæy{·ø&ÓB‚KZÙV²Ä'”z¥¯˜l ¡A,Ó΢Ht3‘bıí4 (¦ZÉòöïR>|‡üÞ{¤wÞ'½ó1õ£¿3>l7u*:±fœ*
q•:mäd‰h Ã8„’dÈXMy‡4$ïô ”¨›‚ÎfQÏ-	²KÅ(ÿ	J‹Á	t‹b§êòº‹O¶±PPUԌԠ` Œj"²Ìž“#ó‰5)ÐX4r}‘Ï2‰Z$NÇ)á$>Rä¦rת÷kÒˆL‘q•"€I%”ñþµ¡èãdqµ,*‹4EÛÍBrY@Zš.”Æ‹š(ø¢©aD¾UÒÚ.ï"ÇÉcRyH(õó…^ËFW§ÕÚ¬&=™b¹(°§W~«CÖÜ"ø‚é 1$CV!
ñZD+ÿz3÷Ë6ÁM43å4ö²=T2ìQû-iG—´½Cx£ÿLÒF$Ú„Ê^²ã58¼ß+ƒátœ«ŽI¹n:Á€$T;žãb~Êüü=êßÞ£}ðéÝwÉï~1óã¯×oˆn2½²ªH*z"JKÀ(D#­GŽ€H§!1œ\Š…Ù)GÜàµÝàwÝõ´Jàh‘`¦Ë |óA€![H<ß_@a×ÓǔT+ãáuÈ:‘jB	§B@g!ÛrF[ÎÌt2ÉV² (ö…nňg˜¡ÖQLyD^¹7tÍZ¶BÁ÷ ·3ºx=6ø`Ø;©mŒº'}‚O`«ãr–•¡Ž*ua°ªÏžwÐl4„
Ž7ຕÝH5LT2šD#ÀwPÅÃD¤[©,Ë^¶9K0&G€]Ýò[7¹Ÿ÷*:™Nª©d„˜\âÃäMœ¯š9_6s¾â¹Ùú”ÆR4ýÂ.%¢Ck¶ßä~Ñ%iÅká7„6xÏ [ì!U¨Y/
Ät½:ÂÑ“bő̚“Äs1n
oüöÑû”Þ¡¼÷>íƒ÷ÈïÿùɧÜÏoˆ›ºÁ^AHD¶ÑÉ.\‹Ã™¨=J4ÓÉ—Ç4žæøÄX3µIÔý%¯ý«ÿ Ä!5D¢•Is0ð&<”Mœ‡Ò"•	À7ìñ¸¡)äyh5ªKÖÕ«è!™ˆ$#–e'³íTK¢w€êàÊbêÌtÎSñÈBq€G1“d€éd'ÇÓ×îV8^ž"¦ä¹ù"À^t˜VË«¸XñŽù}Ãnš+r3ýÎÜt*?™1¥
<Ê1<Á€»Á»~“S›P}Ü@Å%õñµ	…*
Ò”™ñôàí>YPØ&lF½_²þÞÜBizh6"TCN‹ÒÂÛÅ-M¼ë½ò.‘Ër3üU¿$,e»øÍ‚ÎNYïMîëìÏ:¥-’°Çœ3	}"¾WÐ&éêzi6:T-®ŸƒÓ£!äa{l?é¡~Bÿè](õ”÷ÿ‹òÎ{”÷ß§~ðçË ûº¨Y•TÛúœê”©Å7K{¨N^‡Åñй^	Ë+GUl¿´S‰m÷^ô´Já(¹G‰UÅ5ºŒÁÞoDZ\?d#‘ìx[Ÿ™ïåôª‰ŠÕ i:LÙC0á%!¡!­Ñ¥µ\hbHczmÖYº=(( „TÄX=NHB²áÅú5Q…¤;àÄ<¯H•ЫAÈßÛúÁºŸh@±$ºçé·éSªÊ½þÀP@›Ö3œ¯'Üä5µŠÚ4	µ!­e9¨L‘a&ˆ"Í!Þ6f™±ßÅè‘¶Þ\¿Îø°…÷$oz•Ý`
z$T€›Üëâ[7¸_µ‹[Õ:ÇdH-²MÚuKÔõ·é&¯å+ÎL ý`@S-i躺½íÒІÒc n¢Ø)PR(N
ÙN 9‰ŸÒ?|úò¼Czï¿Hïþ?”÷? Ü*ëd{øŠ8ÈòðNþMi÷
Ig‡Ý®@“!ÂÊ	†2«ƒk‰㦨·K‰½)îi‘ÀiŽ"¦‘D¶‹ËrqzTp¦›Is’U9@•‰"R'ëH0 RYdQ“V‰ƒ<ÿp@•Ôr½R¦G*‹ïÕÌ‹Ø/Ô¤ D±0ZÍÎ6m×¢ãQŠƒJqÒ¤QÍΔ„È"§F¢ù©”§ß)@XZxn†ÈÇÎN¥ÅØhœl£µZ›x-]@7N‡×¤Ô±±˜!«aÚHÎ~»&¥ÈÇU¶‹Cä¹èÐÇ9.ú
Ö'­EAÙqYTÚ.½Õ%ko4Óíœk/[õýwÈPüí:¿	­ÇiSúP#qf«´çKQkˆà…$=N¤]ÕPrºÈ	öJgb혎Àð`Z¼"¥-ßí÷Ô|áF­ÃaôXAHˆÐöðÂ\qX,ô
™6ÍDåº8ª¸ŠhÆK"BYT’œL''s¶~Ã%¡8–²«ïv9Xó[ó&=„"^ÓÁ™x4qÍ[ópƒ\¤)‹Á´VÔÊcº¹“Yß ×V¶ÓíTŠ•ˆ×£$a·ê	†Ä1Ö€m·àõø^yN‡!è0š¬‚î¦D'¢,Sp:db"’KKš±•FtÜ/(Vý? 	8^Ndž".†D0-ò¦´íã¿p£¥E µp„º[›ÿÒŽ2A@Ô%ïj—Üj7õª`lÈ"„¤4'ƒæbŒx¦•ÐĽñ1ý“w){‡üÁA@ÿôCÆ'(=òí•Å!}ÞØ"í 9X'ƒhK–òRuù|=³Ðoô-ì?ŒMåÈ&ÉÍ’r’›FvÓƒÓ±ÆÚˆ»îaúYí²š›!MËåY"ž‡'ô@ºC`-[tY¡¤wÕ™šK…&Ü@÷¹AiíéøÈ£ÑH-$ts..dÇÒ£Iÿïšµbã9(FrqL.	IU¿%g‡ÈÔ¡u(ˆy8^¶:¡^ê3–´¦²cÁcM8¨Ñzd—¬U–ÖV‡âw"ñ»±ø|DÓ§V¥åɹˆ³nZ+ÅéûqZ„n®Û¨~š,'÷ŽùÔe-T*GÅÒ
Ü‚«:õÃEÎ,d°|³¼­RGŠÎ/D-½d·ªc€“m8ç°“"µo4µ››EÍò.0²=\mFõ9o"èÒŽhŸ~@ûôïŒÏ? }ü1ãóyÅJ…hpfeF‘1œì.5Œêf ÍØÚ“F}¹ñàâñÊ›õ¾õºçvêöù}iQÎŽñ´z¤ís‹ËrÝÞ>âà„x½ZÍË"¹èܸ”íçi³Z†…IaER®.¨¼ãÏ´3¼¨4L£Vý …ú¦£Ñ¹ÌÄæ$tx¦œ!=–´äM…©ìÓƒ‡×L}¸	Ñ£ƒQ ±h$¨3Z’“îpY
æÁ{CÒ¨\—³ÝÜþÅ’¡ *Þ‹%ç#Ò¬D?d&ùhíÊ´mè×p£´ÜZ"¾QM(ͳÆÜjÚ=g1Œ¨"O|¾u·g+8òjJ»èM‰ý¾ÔN©¸?˜XMKû¥T?kê…©Ûì5+7ÁˆÞ‡ïFoi;áVìç’›_Š[`ZX³ðàLðð„_SÒúGH
¼[Ù½N´Û¤­œW“ÑÉSʾÅþÌlía¡µh„ýí³¿3¾øý³¨ŸÜä69+ÎÁû•þ»e×°—h£’œ´â½²sÄ“XLœÿóäðŸûnÌ|¿>(:žD¥559L1Ù°¬kÎÛ8sÎ{aŒ
שÜô\^6QÜLGÍ&O
âwý††*üÈí}b«_V<–øN$ü8$g¿ÓZ0ÝÙœ¿æ«‡¸íÔÀázÚL“0¥6dÒˆ´ïNŸcÈ!Ï(Åqqu¥oú`H_Úft¶YPU÷ºñ´—“âÑÂdëmíÔëúøwÕâó„eK;ñYWÕÁaÓºLiNýþ«¾ø×ÃîçYÓIвë-^
:×<À¤4ðÈãž5iêrq?W?¯3Þ·š²(©€¬´¸ÛЃÔÃðæKE埰§“æ†9s7Å3ášÎ6ñ
†›Ìrz5Ýì ×QsÆïä#·S}÷ú (h‘u}%híTÀ:•=ÝJX—ª+=—šÚ™Üùf's7Ÿ]*h‡L¥åòÂó…ùW“£ßÖßô/ýy?óºd=Ö¿žÉ¹æ}ܼ@Z–[§#§“·_.Í_.D“x/	YzES³Ú&ÿº^F;",ì†üë&Ϟɹ¯Ï¼Œå^¥ÕAÝC­î®A׬¸­ÉŸô†,nSÝ‘yXè_¬ï4ÆF¯™ú¬€¨„c-d”‹Òâèn¦0 Ðe4Å…‚,#õŒ9#·½ž90³mu=‘Åv<‚y±þ±‹2$fô‹D5™v^3ñumày,ûÜ›}8ª#zæµGº-î«u~ëUR×]Æu!Õ©ÝrîÕì˜]‡í²F{Om¼§TÙöGFÝcuä8&½oøëf·­š	3-A“y¬ šÆYÇt‰Çñòj¹½(L3$)6'BÃÙ‘$kÇ(
Jn’{˜‰>Îg÷Ûkn˜§)èPFÊ€F…œÛ5ëÚú}+»“ô=ugö2…£Bú(Õ÷¬Øÿ<;õ§_Ämg¶èëŒõ2ì;ÉÄvÊmè~\?n»˜«×–~x¼òãÊÈñ¿(å¥0á'ÈF%–E•oS?siw¤®S«õÜ	žšugvå–βeÌñÍË&Í#…{ÛÜ9z{ý¾ÇáðZjà¢Ö÷làÓ'hQÂZ½0¶„“ £aÄz*®—Ùw¯ÚFuª:wè84þ&:Q…ÎlžK¯ñÄWùf̾×=uÙ·ì…ËHò®ÛcGŸÛ»XáRºGó—6Ñ¡Upè{Y‡6ÃUrG‚ú'õ}…ñ©Æ´¥mÛž_ÿØ	.•Ó
í¤LZ¡›¦UÖãàùpt#QÜÎï;Œc€¸È4OL£a–ôË5#ûÝÀèó»…ÝjòŽ71¨1¥9)5@õÎø€…eÙê<2¹õC‹f]¦Úê·TêeaèÈã80)¶¥g¡Ä›|üU±þv&¸—²?x„¡˜ÿæþäwó[ÿÞ›ú~Ò±ìމœÎ‚VaÐêäø©Üf†/öxfæ¬ÏcŽgðÈh<0¶•Æu }
YÛ˪ݽtmG,ëžÒ«ÁèYâZ|"Ù¢š®
ê–¼“æ¢ÓldIL›‰8ÆÒÓ¤n\èº/Ë»„êÛHæ7õ]júŸóáïŠþ}†£HúUÑî²üU¸Ç‘ì‘x;pñ.Ò|¦äïKY{zÃEÔx‘”Ÿúd'vÍ©S}l÷Íþópü"fß³øö‰#oî,8²ŽÝ¡£@ä4>ŒZ¶œ–':ÓcµjA`Y6š–­îõ@b/é_±'6ÜÖ{*×’Î÷ĎɽK>ˌŻè¬JOw7]ÏÒŽç€þÛ.ï¬K:(°,Ô«ZÁ¦P´F3ïÂ4{£Ü¨7åʉjYbØÒèvôj=^—†¿o„/Óý/k³ßß]øùAþj¸úÃÔÜowïþëÞôo“Ê
€6KaLÓ»r½œ9s‘ìpœ—zñÄv雥çú]ÝbrIDATÃUŒw`ô=OXÏ­Öcmâ™×w¨š{¦ØE	ÈŽý¼måÄÁ[Æ›å.—ºÞ­”¿\ìüiêÓßû?øcðÝßçÞûaí£á´b—¥ßãp7z˜0ò±Ž$®âØk$É]ºNÑnðLÛJíš"B ,S{
Å>H_gQÖ©¬-G$Ø@…¬D«2`CÇzªa¯€ä§"îªX¿«–ùæ-д¥³î9eívPºæQlyÛfÓ®5t4îÍ»ÖÈq<¼ŸŠí'йô^8·ëï;,®»ŸsŸ~¨·ýØÿÙ/ùO+ýí·Ñ÷´*V;Å[hÆòç̵fÔʧ¬m,k†]ÇQÖI²=¡åHç:6¸v´®m­{Ïä?ö˜öíÿ[ö\Þ_æyÊsê	?˜žy6Ô6›´Ãï]Ç‘¶hŒm†âDyíNÅô}p&a0i{LɉšÁ®Dq sÒ¯<îSeíÛ¬÷Ü{	½
;¯<ýo+¾+Oþë\úEläíðàëÜÊ?ï]Kð}+”ض¨rå
+uëlý¾Lw¢Ò«U‡r×…ÜÓhŽ´PaÇFù±Aµo1ØŒ{ñ–…¶n lèà«2ôŠe…ÄÛ`ÑÖÈ5
rƒJÚâ’78¤Mo›G_cð7¤Ìeý±ž³¢ç¯éd›zÁºœ»ÌÓm©ûfç®ÕPnBdžRo‡C§eÿI2{•¯¾ʽÈ%/c}ÏÊWCϪù“ù7³“Wýû—þ_öxßÝ¥¿Íôü–üò—Á¯~ûì—âgÏ«_-ÁdkÜvÖêuêògôõ[ÄõÔza“,8P(/-ªC•÷Êã>ФÏ=þ#½ó@ïƒ2~É>Ï¥ÎÁ¿h “{ñ½
žyÛ,ú޳NWè”û ýÂ{‚†¹I@m‘Q[Tô±ÉTŸ™YÛrðP{pži
ýÈ{i
¿êÏæscð…ßáK½HçŸåû®r“ßÖF¿.]|aŒî³+/lõ¯ƒ¹—NHGÏ‘¯ƒÀ±8d»R`O.Ùg:Å©Eyj†C£õÐaÜ·ë]œ-“hÇ‚Yr¶$ËÖè
zƒÔµAêÙ ¡7qÄM<}“J\gWeÌ5
㩉þÔÈ[Ó“ŸÊd[zá: _“iÖó–Ñ{ð¥¬1×Q¢ôrØwÈ_¥!Ü,¾È½ê+]•¦ÞÎd®åØqôé¡ö÷äo{¤G`¿¦?þ-ýÎC~?ñÙOý-ïaŒk½¢MuícöF{³•ºÖDZï l±掌u Ž4êwj£G–Ä…×wfó¹—ñб¯ø¬Q°öE¬@yn“Ÿ™ä'Zë…Åva½y¯üúS‹ú\ËÛe±·ÉØÕ6üf/r
ß"÷l‘ñ[þž˜½Mcn±¡ñTìZíGݶ׼°íû¼'¡èi,vŽú‹gÉÐQÜ·¨­²]•jˆ@
x¨¶ç~ç‰Ëzäǃ‡žÒ:°?þ±ÑùÏG7-uþ0pó‡Ò{¿ºÞýÝùù>BaYn:	7a„åOÈkŸ‘W?álµÑ6Ú;|õžÞ|ìלøì—±Ì›þäóDéYlðEnô›á…_f+ß}S«¿®×_Ö믇ë_÷׿˜ûn|äõHâ¬ä?/K#¤-»ì(ÛÀ!¤Ýa7YØM¶ðHÅ?ÐP÷´äƒüØ£:ñp¶äÊ}yâëXäe’­¹ïsù·™™LNüÜèûºúÇ;ÓßÞ~úÛÊÈËÁ™o†¯=ý?›ÅŸfÁç‘à÷ʱ”r$¡(iû
ÞÔûþWx(bŠ”çFÞ±R|¨1]¹Ôçzûs»åÒì{îÎ~—r]™
g
ù!ºÞËß#ö(„-,y…Ýã²wÅê#x !:9vzOÖý€÷0’V¬¿,>Ïæ/2KÌœ…;ªÀq@³oæl+D»€ûÄ
e_½/
ž»U;
õ¶Ê½*Ë?ðÍèØÛé‘ïãß/ý2wï§ÙÆ·ƒµo‡ïürûÁ/÷§¾›šønlêû‘Ûo''_Ö—¾¹3ò|:|QÓœä—%ê¶½{MÈ;Ð÷®ЛDô6•°Ëa‚”##íÐ);õŽPÁ‡ñÔ“|•÷>D_F=WÎø×‘J™ÉÒËþÆ×c}W•»Ü{òǃkƒ¿Üs½–]†çfÒ‘},¦ì(û|Ú—³ÏTs‚oœ‚S©âÂ";7Y_µ¶ðëXÿý…ﲑ×þÈ+GæËw©“ì‘=ÏŒâ}
ua¸ÔÉO•À™V~b°_zô‡jß©=÷,=‹¿èï»*Ž~Sí™Í]B²Ïm?ÒxŽôÚ‰ãØb:²ƒ‡VžÖqêtÚݧ6׉Y»-l(Fçðß_ÿ¾ñÕ?²ŸýOöÓWšÿÛÿÅŸ‘æ_Ænþ4ûÙO¥O/G1ƒorîKe«µz¿ÖD^m¥¬µúÎÙ«ðÈËâÒsoçn¿½;õã½ùŸï¼þaêÉï‹?LnüóÑýßïlü÷ÊÒÏóóo§oÿ8}û‡‰ÅŸfï|7õàûÅ{ß.Ö^Í.«öË>à(ÄÙ7òwø-Ä‘Ôù€O9¹gåeÈ÷ª$8õ(ÎÃÒã°é2k:ŽF®r…oJ±×QÛ¥Ýqa\øãÁèI þ}=õ<ºˆ^þåžè4¦xãœèI|Î1—¶KfïÑćtàˆå¥ÍÖ_i-¯<ö7±ô۾ķùì7¹;¿ßû©þø_÷nÿ1Qý!ÕÿC8òÂ,? èŽ…‘W.å™8ü]8ümÊñ“.¿ÉW^æ¯Jµ×åÁç¥òU¡ô";ð*—¹t{δvˆi¶þ›d“}-¼îO¼ÌU¿mÄž‡Ë¯KÑgÓ®´²Á:š¾ùuã‹?*|Ûøü·™~üðÏØ§ÿ|ñG¦í×ò­ßÆZæ_$&ߎF^ø‚W6ð”/Ø#‚‡l×¹:~éXx;þä÷»O~œ]ÿíñòŸ+‹¿>YøíÑÒïþ¾øðÏÿzºñÏåÇ¿ß[þýÎö?¯þ±øô·…',>üõöÖï+¿½»ñÓꓟ×Ç¿_ûqÉz‘r>‹¨ŽÕÔ=p"£²¸ç
ñ¥…wáÔö/"׌	ð"Å=öÉÎÝâS€±‡–ÓDDÞ.¦ðÏÿÊÐø­8øëÀ쿆~©×~{ðïG÷þ\ZúcéÁïw·þ½zÿÏ™íÿy\û19ýk%ôÂ~aÝøŸÇ³ÿ½÷ïÅ…ß]ÿ¿Ûwÿœ›ûidâûÁ™·µê«lßËLþyjà›ræEhàÛŒõ„~f–ï1e;ë‰Ö~bI¾HOÿúÒ¸tÐùòþg¯¿xï›ù~¼óÞŸ“þ«ú奞Ÿû0ß,·¿k<üåþÝ·3Ã_—K¯SÞ+cù›Xì…eâmùÎ#k¿-ìþ÷êÖ?nýãÉæŸ+ÛÿÞ[þÇÆã®/ýãéÎÿÞYþ×êò?ž¬ýùhï¿×7ÿ|pðïµÕ?—¶þõäéï÷W~{°ñóÓõŸž®ü²ºûß‹,Oý|;ñu"ú*¤¹Pˆâs€q"CÉõ/bôS»ô<È:qN‚¬ƒx7è~¶-jZn0„:±A†v €Œÿ@)H‚1'$F‘ D@PfÀ™§LLÎ|ƒc†ò_¦D€’þÿzê©êy9çÜ{w¹ä’â=gï©·ž©šî®êz=ûý†clš¿òÓàÛÆ$¿ËRô“Z|;ýÃoYø‘yÂ"ׯ¥„·üI)Å(?oz}¶OñO¾ôÓ%—Óî,yìÆ?Ѿ‚}’ßÅ0mÂ.9¢ü#þÜzÛˆöyc\ô“+!r¹LGÈGß~}÷ø_j²À]{)`„)×h—VÉ;79뻌úå·oŠBi=„±ïÇ‹Àežgt dû‡iš†¢§aÏ›@Ú‘W.àréûËml{€€…^M¬= ³¾o”°¡¡¿þGÆ€â
DB„ 4bEÐH¡K}Œ—®(b±)‚¿RøÏÒhÂEBà?
C¹êxŒ®[‡žµiÖm¹	ÉΕ/ˆð+¨÷WCàjðY ¦œå›®z@‘§)hñ6ìäñº‡ ø—
®æ€N?+Â|må0fŠàp–Èã Hÿ”9 	þ9mzÀÝ9 9„Zrºâ)Ÿ;0 Øì‡À¢C@ñ×!0`xÐ7_BËÐñÍã¸ö€†o¾„Äå=¿]’!€¡ðÀÐê< 3€Ì¯;£'H`Á_†Èpƒþ"S,oD¾ÿhï?5o‘·û€ ‡VДÛnVü—dŸ1IoŽI ]£<…xÿ2W§k
l¹É›÷€R!§<šÇ{À²ä”ƒ#ÜÊHq^Ö€½è2œ•û:Žc`Yæ/{×-ï̯׆òØ =@Ĭr"XX×âýƒ˜”B!@›‹ü{¨,s—ý°¾ñÄí·1¤Ç o®4ƒ~ÊSæ€6§¥`éZyÿ›0)¦MÀòK	Ò–K»m CëÐN»ÿÒ瀸7´]À$(³@+“ p¯eCà/›é±I“ç¼t‹ÏDK€=	¾ô9àÉ=@˜5ø 1òFfÁ3a*Ž ¼3ÌÚÖÕ(Ñß ÆÍ$ø”¥øC°3ɰ˜|ÒhÏibø‰!ý[ƒí–÷þ¬¼ÿ¾þçý•¿£ë¿Í…õ¾½Ó°×÷`]˜„ƵtlòO²"õ§ßþI῵ÿVžB€ðþûòzÞ¿vm•Þ"ížôþø»×~òRà·¿%Úv¥@–ƒ$ÎoKâ´-àG?ûÙÏH×÷ƒ`^r–o3%âyC(N3ÓÄÅIßïàñøº,ÇÚ@pÇW'åâÃC@ºG°î¬{Rࣀ×/?C£ƒ·ðßbŠ.[€­è¾|x7ý[ö mÂýå·Ü_Zî/?ûYá ºK_(X„7…×sW3:ÒB%˜Œ}Ó2
þ-g’àO"	þíßH‚>"	|Ö¢®è¿Á=@Ñ€>ôA’û@ì	>úÈH€IPw?	>ʾ¯æ]•ýœ‰þŸþDôI€{û[îmÛ>"	ÈÁœ¿¿c6ø·þy&À3ž	ðL€g<à™ÏøV`¹¡ŸÛî~ìxwu¼Ûí¾V‰»Ý—«ã—ÝîÇŽ§Û:¬´ÕAôuënàJÒžwàÑãùx<ï÷OÇãÓ~ÿx<>î÷ŸÇÏûýéŽÏ÷_©ôã¬PÏŒ=Âó‘eÎv<ßD´“5Nwó8ªêr:¢ç[ûñ²Ù^ÿCD/çóù²'Èy‹¨šSöI[|_¤¯‰·{À|üïcÇóÍ÷¿þwºùþ×ÿŽ7ßÿúßóÍ÷¿þ7Ý|ÿëãÍ÷oÿ½ž–ûƒýÎñîzüï6†ëñ¿Û¸\ïÛƒýÎñtÛh®ÇÿºñÌž	ð5ûÐW
%q¤/“Wlˆ{Ƨòùk…Õ¼e–8ˆLˆ3”ò[¨eÀdª¡y‡v^ÿú4ê"—”.øƒå0tí—B€þ¸³ßpu×v¿ÿ9`1ö
m¬^–sk|Qç@¸‡)<ŸGeWp‰	ÕúxSRþصm÷åôv¯±O|+>j|¾Íím>ÏÓæœLy½»~¦¹V„ˆ¼,ò“ÛÜuò3Áô#?ýϽ±.?Âò™Øª
üÑTñ\Ú·ßnô€þøßöæû_ÿûˆðõïã=9Ä6ãóó=9I7¾sÀ·ž¸Ç­yh†q$|’_Ã×å“dcoÈ̆ĴG‚§±Ðs²-'¸&µ©)aNiNB‚$C²L)
iK÷M~[ð-÷œÌFû‘p^§a3Ò)š÷²®y €@	€Y	€÷ÑÖý~zå­A¬gRÄþBoé0¤isß§…ù˜Þƒ[
à/óï5zºNy‹°¢²Ì­¾aâ [dÝ»Þ÷ig½’½}Ð@	`= Yè­¤´'@?i œgÂܶÁhûíø4ö=¡0ûò˜}	°i£à‰C GP Áw~ý€má# ^XØ?+ÿI·…®
EÚÁuoŸO¤@6óþ¤ž.OÀÿ2
GVß¡
ð_DPSÑ®@TëD,€œÿ¼$Å~iÀø^¯×¢ÀƒPñ‡X*—AÊk°Aúé•·¿TIé¼Ñè˜ØT¾ØŠH/oµ0ôbÝ¿‘­C=~՟ƽÃÓ•ˆžw²¾?ñìXù¢óÉãþµ'H_GœγÁ³ÁøÕS )üºãq…Ú+úêçxÒÀ”¸òÅúwÜ¿®úÑbz&ƒ³Álð¼‹ùùj?†©¾ŒY1e{ÿ}¨~Ž'
ìÛðÅ•O÷×R"&#ÀlÈF€³ ¾l†Àµ´|g-·|qûÿ^gÉ	|	Ê=@gž1Ñ[8Ü;¡	0Š÷žñF€dËï¤Ëô§èlž ½y†BA¦0–þ—±(þ²ÒPüe塸Ë$ ø/çBïwAÞÔ|ÝËÕ œüUQq
gáúg}“QûrÏh»¬/ýeCQÅ!ÐÔ_ôAeóçbñÇåk3TâÍ|Á£½ð7éøc™5éR“øË
iNñg,ï;7)`lp\Õµ_B¤=N*»Y¥m÷Ëã¯vî¸A€¥ëŽ"¡dªåÀWóvqqÿ–îð¹!ËÚ
ÚCt²ÈÏ¿’9ä(‡!x¤ç‚ç
X'ÑɌԌömÕ‰ïÖb}}ű|a3µ¦Î4û¬€oa­ em½£\œž«[Â8^:ÐR®Ð°0yÐMš‡>›ˆý±é`*N	1³èr­Ì|*ÂDîÔ*ÒV4¾¬¹éŠþ@=ÅDgÆEPòÒ/& c µ1ë°7ßvno>õ• b @ñ‚¦äƒ¨x:gÇ¢=Õ¢…	;t Õ;Èš´X¾ˆ‚e~鑾@¸cò ®–<Àä7˜rÿßÙH^ºÅP
+ÛO>‚ k×· ©¨!ÛrÉ‚s¨Ç˨@t¨vŽˆ¢+M‡ÇÉœôòJ]åÐÃ@ânNƒ yClV¢èéòX‹¡†Qwú¾@¢·™<‚C‹úч\Ò°€HË"ø.×X{À
…*±¥ýA£d-÷(Aÿ¸9:â¯SJÙÍ€G%©Q(DŸtU”V” €HÊf²öFŸ´µl)­-fG[ÄD[¤(Â[$€v€«9T†ëneQö<ð¡O441LŒãåë`9¬'GÂõþõø­`îâóíÖ*bÛÉle+ãlÛòîàžK~ì®~jõ%·Ölp‘–Qí²G=It©Km4P¶Ômbµ3·`µ—úÜeƒ&._„Ù¨]¾ùRÂk`“ËòãîpíÈÛ<œ·
voQ½ñe •*T2íÛLÏN¾Ý!ÿæf—½ß1rû°OK¾hkM{W´$®Ã7¢WÂâ´C^¸=úήRõüz »*ëêjžPµ7×/™,תmOû@³CBBÈxgÒ:ðïwNç/fÑíÑ——ÙÁ#ŽÉ:Nºª ‰Ë”}¶Zešë|{8ÿÎ|Ë;$€vý¶0™¬–-\Ïch»®N
ÉÒñB_î§Žjƒ	°ZŠšüN	ЪBç@€UÏÅ!ÐmfEËÝÍlúñÈîùü®ç¥s~øW(ƒÏ.…Õ…[ÙÂüÈöÜŒžxÑç¿Þ‡¤Ã/Þž›¦Šú	ÒÔ´Bn½ÛFa,E.Äy”Hc‰Êh×åbÄ6«{$Œ!Tº„ýz{p7®uÇöŽ„yz{Ý
O´i¸mc…ׄ±c1S^±öëufÚ+t¾Þ@æåš0†P_„ž²¨R¶ßÒ8
+¦Iéq¹9“/í	cpì­=[3DõÞ–¡›¥=ê]ÛªR©Åò\®à5aˆøårÑe0ó^]g¹Ó›#¼E˜®kÔà‰&uÔ(ÃÕõQÙj<Â[„‘þPVêÒNÓàçwZÊ»š†ßài)úÜóÞ Œ´1—KQüG¼0Á8^§Ï¨((mÿ^ èŽ×k!Ö7x‹0]ŠÀ¿!€à_ŠÀÎï4¯z®þÕAb%(#¼M˜l´=	0L Àþ:âG…F€þBÀWåê¼d^Û„{ë“õ;¿Ëì
=I‡§¶ÌEþµO…]«Jé}Ü2øþHÍY¹y*T¯»Ë‚â;\‰+1ÁñS êéziN|2
ø~5åæ®ƒ«è°&<©º\1O…2þÕÑ`(̘½?®žÊìbO‚@p‚^—¨S{*{êê@¸2ú~mll¶Æ¿S8ºíÝ䫯÷˺6Ø,‡w|õkØÞƒn‡\ärëÆÉ÷w|5_M×|õ‹¶—ŒÝ®ðáö’É%Éä’drIªrÉ£p¾xDÄa½¡SØùh-bÓÞ„oØ^2¶{€×„±ö’±çdrÉzÉ%еÞ'ÁiSžæˆ>ðÍ+èÉÃð^{~ܽÎ×ÁEëí#¼&ÛSJ½¶;¥i=ºæ”C\èuw—µÀ5‚¨`RŽ|óébU†#¼A˜®8Ó¸£ãñ:€ý÷oFä’$ó1ð/½\
3Ãäçƒçá•Ú&6`Ï_Dd¸†·	ãÇ;­Z쯃šM<]ÃÛ„áš@€	š“Ÿ¯’˜@ä)/Ô(;ùâv„ò 
ß	cQ¾ÃùOƒ¡´·ù7øþHáP´›?
vE$¿í‰ä7¡=îG¸—ü‹Ër‘÷‹¿Ž|ñõ¡Õ²zm¸V:îw=ÃSa_‚8L%LÛýÂ:ò¶Ý·ç'ø´d– ?X2zÅ
a<$‚`@†exóDgy¯›¨Ðu¾mƒ»É«=Iíä3ÓÈӈܾE?Ác<Þc$ 
*{5·C>WG¥(Mï…ÇŽ™ðê/&ßV§w [h¤¹ß“îõà‘º€ˆ9Þz*öò«ébdðó,Gh<Û~”`M¬ÄÊžÑm5™¢]OšÃãå~uµSÞH¨ÞЇόI2š½³J7½ª¼C²ðûhék4ÚTþJC‡òF½yš¨Ñ§saB$uôк`QÃZÑ~®¬§T7žŸ’·«»
UíY½-³É¶µ²†tæÆl;Zïtë
¦š4ÌÛDp®ÙVgõKÔw¬&"Ý=Žô…JæÅÙ
‹BúFYÅÈP˜7­a+%pöÁxOM1w¦·…ÔéøA¦‹L;µž¯œµº`°R
ôÌQ”^z'ù¬¦R—Üüäü0Ø<¬Éº]Ý:Ý`®Äev¨6Õ-}ÐåoT
ŒÅfgãojOR6êºÿ&8XqÙX}IööF²ÊúŽV°>ñlïx°L­£¥Êˆ–Fv±°uZ7á›O4#_2#_ÔR)
gÌÛù(ƒ÷¤´(D„‰íwÌÚ¼ŒÖ’uh]`°.ÀÙU
'F€`°N—ÂÀv¢:ïòH €Ë¥ÑëÕÎ:Ç„«DúâfJíx
%AӴ
+›1öÓø¶Ò±g1l…¾?ú˜g+ãâQènËt“àd•ªl.*ÅBVÝKÐγR?ßå*
VF6ÕóV)•Þ¯^aÒû{DË2„T…/},¯RGÍãJGÀx°Fï©|Ú¾íƒ,v%ϨÐ÷ó½DÞEþvI0kæ2†+F'L|Å) †kÐq´$ÂX—ó{*MÞK­(ÈgNWÅ(ÀIP™éÊzëGÉú‡ötÎf¨ôÉù¡/C}¹¹æß·l]ivèûƒÀ8ƒeZ©i7–ÑšTÕ´Q3°ã}ýÇ®¦S &¡¸ó€¶ª«þUàGò€-*úä}Oþ¡ý
«æ­èúQ±áó»Ïû¾Êu4=qÕ{L[$Ó¯PÝæ	Õ'àÖ÷[wÀ™Ó‰<¬R Ÿ}`»ìÖN`ë/Šú‘ZH3Bi€úYY´V_X`z;`/?¶8ÔÄíÑsÓ½Í@dj#—óÒN‹Ôh‰Ò Q’øU6'CÀÕ;N/‘¢…c°<8Ê‚Î&†ØBœ=™Rýx•—|1RY—zGYS!{üè4/Ùwž‰¿P@ñ
´t@ìXƒÖ¦=Þ¡9öÍéà¼ÓŽ]cBEƒ³9œìÝW~©#i´	Q'^
¶]”¯J=³"¾Øz;©ÏÄX	àçùõ­ÉLïÐ kj£ÍZXL„%U…#{RcÙÊsPk7ú0ßùÔUBžàôiʶ̬¦»y%<‡«•ïBÌñ¼x9ó%$à¿ö;oã&ÖY ;(`C îç$]ÖüËaÁÛïÇ0b´:À5Þ(ÈÝ)à•Øl!M%Q`|ÍÇz%ž/%BúIÚy3REæñrÑã›õ„žg’…j$Zó-Ä“ªX¹€–Üžµp6”á7Z:c»*Ü0k¼ÊFNxÁÙfÍ[_ÿ·“¼a”®Væ%kÄÇ\¯“€ý%ó/ôHNÚÔm8¥h‡"k]‚b?&IYÛ{¸©ŽˆVÒgSè«kÎ|h]™6ö(¾Ÿò¢­Z¥4Æjì/—J­øRn½×äÜjŸ¥»Î:ÍåÇÆøk*jaiu$Ž!ž´¤RªdÜ ià‚ôq@χú¢~Õº¤¿©ZÊ[˜Ýã!!E)Ø.f,á˪Î`òç-­„ÿä=¡†°–õÐ!vÖ“JŒÃpÞ¥D}D(–À/–
^‘[‘N®îwtÑÍèëñ‹ü^€:@`ñ̃y瞀¦xøRTÒÉ£Õä‚×ÎÝÜRŸíb³[°ØÊî®ỈÿdìÑaX
çGn{,N6%©º²›3Ï®âQü¸OjÛýi³?O@âÄËÅÒÚÁ)Pϲ÷©­cÎ’†‹†-êô1®m|;˜¸µ0´ÛÌË4±šªç’]ˆË`(®ÊâÇaK–¯À˜‚u73GE4n]‚‹Ê´$ÀÞUذx7§’<1AcB|Öa”mT©ì°•ƒFE‚?gK¼¥èÊÏ40èÉ·µlìløgZ®ö¼Ó™–šàï¸BØ¢¥X¢¸ýtZEÊH‘ÞI€ˆì1<‘V¥<Êè:B2í¯AUߟÁ-|¦Üm™àcªÛ.œò“-G–tÙ>s@£³ÏØ9¯Û1ðd34ãs'gO¤@¬é×ÝX¹9np]RkY5~K(Bˆ‘ÕñÝš˜ž70Û¸\'zZuiу؂wèÛœàõÆsÏVoi²±îKß6(/_€·	âtÐk«†-$[jÅÛÊï¿ÿi¯çþ|€úkVÝ	6<­[yM‘ƒQàl®sÝ×tøÃÄU´ó„-N;‹iû%ý6âuA’ÏÇýª
»µP6Éðft´(yh|ªa;ûþÞ¤3Ÿ”­Çèªpo·ÛÑ{Ó:¿µWS%2CÉS_‹‡2§²B­&nYhUâŠ"xÁ2äü>Á-6<°mÐL{a¼´ :/-U]F€±´û{}¿sVSå[ØÚ­B,GtÐÌ䛳-Z¡ÐÑL›5hçÄ€Ie}L&Z&Ϋ¦	ÍäWÊúC8B
utpgQkv#d×m;ÞáÜNWÊF*N:,N±Ý0î#Á
HG¥CO›¸:IéüJ³)`°
ý¬UÊa`ź?ä¨ëyH|jVh&µ’J€¯T£þÿ¤Zpf'[¸ZH!êj‹nÓš«ýߎc„JÂìšÀ¿#t×:.¥•
jî6悼
šêt}ØÈMèâvûl2rR»–I±¬¤ó´§–Ž­C5¨ô:¨žÚå´HKal̨=1.zj\Àê¿	ÍŽP¹¯!ÊêàÇåæjôm&I]·[°û¶ÿaÝBþ5¦„žßØ?Àºè]Ï	ªcàZ6L³Û’\î0W{Ÿ™®D3U™MàD4ß;}²8Fs?ØPõ×ôz~‚óÀU‰¶JäŒ'­¶ª+UÃÉV:ãV£ÜfugK>U”ÔÓÐŽy½ÚVÍ-A§²ÉD=É=X/
ÁÃä?º½B~o`ÞàóT´Wv”F
¶¡-i®ÒdÇhÜõüömÑSX2@¯Ïr½IöÝÅıɖ=†â4¬»LŸàÛýÄétãí«léÂáÃq*‡к=Ä$gZn”üs0Û$ç•nì|7xëõMm‡ç7ÁlDz.2ž¤T™¶ê>ÁCÅÕõ	“oài#DqP¨eÇi«#”íÁüž0W))ÞÙÝ@³êF–Æšž¦u]Ѻzc×mZ[S·f)šgOõª†ˆ9L!ÊŽ,MÊN‡ºw¿ßàI%5•ó»¡`«é‚|R(À<צ-
Ä(„‚óQªÂâ­a ¶0:¬vÎuÝLÑ«=â_ÿèвÌL€Ýè0ûõ[ü
{Ðõ	÷ŽŸ"YulçfªwY47²óIf¸nR«¦‹ógHc]ãÇÚܚ͈©ª2tŽÕx	>°Ì«E¥»v£Páõ“ÅZÜ¡#ûõ>É×IÐ^ûmèú„;ÇO\ƒ4ͰK£HZP>)««LŒ*e;⼦òQw§4ÿ¼Ö8œÏS-5L*YÊ{tI’Æ’–3¹…_ï/{™éFÓ¿~b¤‰OÝ”•ܦO¸wüTg„h–fí£úãúü^ßl_·Û°çã}ý1?¹ú³Q•mÞc³Þ#|ÿñü#çqIšD
gÈ`½ç¹BA8i¡»wÒYÊ×ûn7XæK†ËZq{—:¨?T/å;Ùß L´*!–Iº”Îìê…
³Æ;Ïã¡ÐƒFg°r#Óíý4â¼ÞÛ¥FÓø¶C]+Ë¿ÜÎX?eÕ~&DŽbšuV\ÔuÑØ½ªàùX.£©Å»Ò†êtmè÷MìWŒaÄéãŠ>Õéµ´“·+ëéo@(ÔTAå25÷_¸¨^7,ƒ–èéöÃ8„ÉÊõ|ãS£Ž¶\çHW¨Ëùˆ@ÄAÅCwÁÓÄãìɽu¨_uPgN	M")
ÒÝí%¦€N¦±
ˆ´—ãf.ª•¤6zµt²!]/_(¦1(7§ñbP¿B0%"Gy¥
¡%ý§Î·=€÷qè#MMSÊi
•SNÔpyŠuãÓœæåVq£.]
yY]ËúøwÁ)pQüE¦è6©= Àt €rPÏSàç!°ï†Û}”Xw–®µçA2µ
_Äh0„étÞÖYËúÈÛÒÁO9f»æ„é1w†Qg«¶ÛÊÎ.‘Nn'˜¸ÊœT1>éP=åx+ÿ0•ÁÏ?Â	½nÃÜÎaÍ‘éE*u£L´3B€•/ªãÀÕ`Œ¾PP¬.ëÐ&ùêhzŽØúF˜Æ.AÇ€|7&5\ݾàÛÙ ;íL!,¬~=ÿFÀ½Òv…®Õ6oSÖœ6üRoèV^_9»‰© ×ñU»¯°5«º|muÞ3ë|—G1´5ý9WûþPŽ„o»EÓÍéS5í2OÁMä‹qž
²ÎƧÃþªP¿ÍN¢8²ÕU-±qù»·ä?8-lMcȽyÈ;ç§Ýº+ΫhCM#=FsFO³‰jÔ¬Õæ|{½în*¯UŸúDüJÅSmä›e®ûÜ2“lM%WþåbÕ ,üÝÚqé¯÷žÖi¨¶Îê#RïËÙŽ/MN:[‘îkì«SÞ#ù|Yï«{x¨=×\è¦FçaºóV
&ú~‹)oªž@&il#k;f}òë™É«U_#ô¨ÅÌÆÑÏw¥çÞ¦ÑØ4¨;Ñ
=H=¡jZº]܃Gêøn=Äñ•:À•X3ªÝø
è²q•UÞÒau¦®Ñ”â6Ù©ªÌÈyí¦+;e×k!lõÂÈŒ"2wðü`ü.ø,|¾\„ÒÜz™jïêÑ<ÕL­9?𭦱GšzœƒNiL§úæf‹G¤~éBKÕ¿VªåF)]
`ûê®8Û¢_.¶hEðvZBæ‹NÝX¨—±º)V×"ë¡rÎ9\,5ºã¡JÏ=‡ioñPSQך!áIõ*XX2¿ñxb»|s¦Eêlf.Ö÷FcB”¢tÚÒ÷ïûuqÞøÓ†íT*˜¶«ÿA õÈŽNi6PQ‰´oÓ2ß?âô.n7S}Î’ÕÕˆ8æõÔIÁ{¸­RUÏõ¢Î=‡€nÔ‰a<2ßê7P,xÖ›R1hê~^Wß—án©·þí–¦¥ÅÏãó„‰UûÆøOåàBËuˆÓÎÕµn¦b$t-Ç9øñ“óÚ„ÎŒ‡[ç*
/û?ŸúwÛ[ÏgªZk>Ø9}»…®Û±Á ø™ìºc²Î/Þ˜9ìÉÿ•ÊòÀ®½"€y¼Esèæ“¾ÊÏô€ž~çß6ÜWàrü©QüWîx;ë“©§»¯ù0uøÖ@Ÿ+!óKPíþ°Ùoç™Gi¬¡ OEß¼ª,@#k RaþFÜ /ïÝqÄßœ÷ß¾„ËŽß.À™ÝÁÝÚÅ,ÙMÓàÍ‹Yf¼Øü^Ïc0'M‹H¡qO¡òùaPÏìã:ÐÒ–g¦@úN§1ÄÕaLi€#©·ØËÖü½'Sñw¶žàú%O—`<Ïô—Šúr^èï3gç¿Ø2¸z߀™Oõ
Å—Áuh®|ƒ:ºàŸÈ(ºÌUtæÅxŸº][×ÅlåʲgÄ6¡WÕ
§ÖC[:5¾w@ùè5î®^z%ìoMž¡ÁÉðë¼\Ôe‚‰DPUõqЀ‘Ú…×Æ);úòíÎ)¸º±{ÀÖbñ¯ªýÜÈøÍ&:ni,ÑÀê¹N®ãÎÄ·VºE“Egi`(è0äŸ}íé: øR¿6ÎÎ̤ øËÇgqÅ
p௨AÝ!Zp\²epî|Ì”Æ]r)ÌSÛl¹Gð´Z’"h}eÐê¹ÂàN¬ÃSfÀlaQ
Èç„p±	ŸvFSsš
·5ëÔš:4Ûv!Wº4ÖÙΛ°ºdñ:ƒ…vj²zC´¡ÊÌdˆ%Ê
s°×Í”•ࣂ††-ê¯SŠOŸùci;¨®Ç€Š¼ÿ7aÆš×Á`rEëzÏDáÛ#€óÛŦ)Ãòv-TUæ€ÉPçLçî.0qPM>öå÷Bâ‚Í	¢ns¼†ry|åi£ÌŸ·s­Î|îˆyÞÀ×dy¯ÐQ¶*c<×Ã	Þ4`B#LU݇˜9ÐÕø’Bp†·õ¹B¡ÙØk
W§štrœÏ}ÿ ² yz nG€´ÚrÂÑÍËÀ‰”loSxÞó([LùÄ„”/æ†Â}cº#P`2Ÿü©ê!ú;qkͶ/M«­çÌPjd|Å	`
ûB«µl½iRêxÉ^c€ß
–6§$ÓÆä©/2ïj»XýŽfŸŒúN>„f/úgaFÞùfoò‹1N³»“Õ#CCÓ«	l§»Ûèâæ•é3X”‡r•b1ÁÅìü…A¹lôæ±Üv0¼\æ¸RڢɄWôšdBC™ŠêÝz Ã”¢ª¢Õxå-¥†~"JCûÅ)Ü¡€¹ð´+™"¬e‘"]p¦®Œö\³Én°Z;EëÅÄÑ,ðW-0q±ÇÅçNøp¦W2|Ìàf6S9‡­ß”Î_žg>ÀHuV˜þÔ÷·T|[|´¤MdÞz©{®'Èh^íz%i@ÖJiî:ÁØc— –ࣀ¿5¢Ô²Ûµ´ÇÛäkÙrKÕ¶ºìÌR¢ÞßÈìkÏæ+3k“¾—±Ç*ÉO½ÎΧ$IϺxO€ØxJ¦±oÛ?ChéÏôáך‘éà¤%R:—ÎPÒJCç¢]`@Ž$:·Èyšò©Ï"-Ix5Åçú¼ƒM5IáöEÓÉ»ŒÄ¾k›&Òñº4ŽàÈ9 Çq¤$ðëü|Ã?ÒͯaBDOÜC-HáŽ’Éø‹Ò
É›´×î(ö=°ë0B„Ú"w‚÷·2‡]¨iƒ0ko!¥‡¦¸ü¥i#ð»Ø"}~bõ>75²6Äù(dÛ®óóY²ƒAÅÒxlï–xÖÄ)Fe€<ÁgÃoΪZŸ“…®š¡bÐôÍWm•+µ³/Í
r©6å:4·ç€Š 3<$ÙÌõ|"ÛMÆìâsö¸lW¥æñ5¨»)„¶½kg~piW¹@¬vRÀó&å’·pµH‘WzÞ]$,i:j	šÈYZgjÛ-Yì˜ØöëìxbÑúYúßjVEºÀ)Þ]–ߎÜùÓŸ|µÛ8õ]2¶¯ë玑ˑšÖ‚7i"GHNÜìïÉŠÍž{Kìø:|<ο Q¾H±u¼„‹ÌêfÖÅv4㣞߼׈åóy®|õrÁdqæ¶-V`ýߺ/à¬.ž¶ÿ2~‰è[vÜJá‡(œÈEÎ…qÿêÛaÛ°8òO²„%ö ÀÒBN’ý²êJ¸
‘Zá\Ã(pÔÅ!ê‚\¦$ÍWìۣƋyâ~õ‰¹„1÷æÚjÚk[ÕÙäVó/Ø"Æj`ÂÅé‘ù{áîÏXÌP'C]4Òª±†•=ø6ÍÒ4‡'ð×Qœ§fvšp4?ÚE¶õ†+_/*APykîpÙîcß0·–zÂa9í¼‘ëfz²&3a©~¸1
X2‰f¯7íÁ#)<0a<ŸGM,`¢k§×EúÑùT¨NRžê!%êvIÛŽ,÷¹_ûY	Å̮ĿPÀ;@	ªQ×WÓGnÃÖQz˜‘ÎÏS”d:ih°h¬BC(
)d‰…ÃÅZ¤gÕpáiåFyÿ£P’#(Ð1¡
Ú"ädüPÎOI];?â*lG†lD?ëá~Ãî´lĺ&ppvN¦aˆžL.4½'"h̬1„ÖÔòê]hø¯EÍ`øgÿòÃ2ügà4ПgÃ?Ó«d3	:?Ç„’?á¸Ípƒ¡î×5„¾iZíˆ?|)hÒ[ƒ©ux¢úÖ8‚k»£%úkV‡Èõ¼>ñ@N_+Æ#)pÁ Ÿ%²t­õ€ÍRá}@Ø¥‡ìt]{'|lxŠ)¬½Zßõ\–åÑŒ]·oøy´Œ#¹‡ßeõÛÃ0ÁRùðãZåP:EËz;Ü>U%^ÙØi×ÎIŠ1?ãåreÈxRÎíî)Dh5¶_á4h˜k«nkmK¥ŸúÛ•MxžKZ»—ÕÛ*²†ª­)dU)³¹Â‘Š—ˆŠ<ïdšr7@—=)ôüe·—eO®°°Á^óäGú@G•BP€s¸§‰ëƒJ£v­ë\ãZ·É
<<Õ•™YKsü[£à(M-Â’qÞÉÌ‘KY]›<Í®²Ÿ8ÐY%Ž‹€"r2}•Ù1Ì=ÎR€]Êwƒù“¨ë¦¦
Íˆ6‰n¯_éïÁ¡®\ͦ–¥_\Ö =­3¶§øêóªÅá(‘ƒ«6DÍ÷¨^ƒ)‘üš¿øy>–Õ]³åàá”j£\ÖeÑÚWtµ®êé6·au9B0ÒÀôº£ŸäA‹Ûõgùê=UenË77€…Ø[þCJð¤ÊEÖ@¨üCõKм—ØP@·/¥s¨Õ ËaáçîÄl¦êrà@úÇè³-cÿæ5{6+CV.¦¡Pü3“€©ÿëÝ
LŒ)ûÿzfQàVQ³Ù&™¶·?ØÛ_ìíOæÙø¶?Sot›çm‰FM
cÛ–Ýö‰è/‹»9¯\Æ” ¦B§Q(0.7ðÕŠ(qAÝœ‡Ì¶–¢Ç¶üxHl&-?‡QªjÌ=cü½˜'
{@³nûó¹>©>/ë
­lðXǨì¶OwÙÑëÂ×qUxZÁ5.¡TÓF›YoËöÖÔÝ›»ªxÇ2ÆÁÙ`Ûmùb)o@4î²±…lja¯#X/ïÖj|º¼’ÕöBM4ß®^¼f<²±•=cÝÀ×óVv·í¬Ð0½u'€tñ¾Èû‚¯À_3¾'|u¿tèr|±-l7bÅXŽeøÚZ’{ÝÆúø,Ëk¬tˆÉÚ¢ëT‘­>Y\µqö‡££Sj/ýJMù>­;ìÇýü‹ŠË"¨¼Ôa6Uµ¡óQÀüQø÷ÿ,ø£¼ðïx™>Ù›„×­™¢Qf±Jç
ø3rï`ŽÀ¤)ÒþE{…²
pE¢áXv¾WݵòÅLÇ
YÑË÷Y½ÁQñð|oç˜@EÃÃPCÏùãR´}D•0iHp—‰¬l´á‚}Æ~¤Ã.4Ð:½‚¦r*X.–dzätyçeü!ïˆxùÖüz(„W€ƒiÉ<>×Å¡Ÿ5û_ôJO‡0ð¼Áë
úq?ßÛ9iÉH*Æ?wp18,»êhåm-@­	)ÒÒs¨=Bjžx¼èÐ7ÖšP†ÄXmË6·@XÚ
í|ö@1éyò‚Z¯7èÇý|oç´JpG~ùz°"bp-åÙØºÿ͹®šE4>P–°qš®å}WX´è»A-+,°ÆL·¤¢ê¯7èÇý|oç´©¿ó†u
:"š.þú€ÁÁJË+üÈ}Y|EP,Ú(xH÷þU~jÁ&òhji|V>Ú c+Ô´³ÅL›«³f¡×|#äº_zXö6	’ðˆEµÇg‡Æ¾”«+O ìûµÍ–­Î
.¬ÚjÕq)›£ž¾ÓÜhÅÛ“Ë´ø`ЄöQ•ÊX%õ˜úT‡)Û`¸ž
¯—í1‰‡
} –³‡ÜG
ÆG¥€úæòÁ©Aj}›å–ºßR‚DKõ1Ͷ_Ù¡Šd_Ý™æ‡Îö÷›…¡Ú~x¡Ðq^\£ÓÕáÇöZ½ÉÎdhAï·Ë¥Å<{ûš3nìû“7-.Z4ebë|tšZĎʧÁVtjáöÂ7U°_.5*á’R õ€S‡ˆèÈžêþ¸ÂfA³¥´–ÉÚœs`Hi(Üï3ÛëZ?ßÒ±CD¢EÃ
 Í‹&È™½ý~LJÓ†ÿêÀÉR>ÊD•ïºåÈ·­àDañ]´%@)0Áf¦¯Ú`´á糦¥	~êIÞW“eØù«€3ššÝT‡æÍÌörå&­¼}СaºÆÛEzÀÛïG¥@Š•ÿÃ.N㣞¥ž‡§º¬ÛV¢0˜‰Ù“ð4;	à×èuÆ‘Z«™Úuµ ™üóó«€3ª
l\ƒ©5t©óöë—oíÚPqì¶ïÚ6¯Ž#«CÔÂêVÏa`”ýJ ‹‰‘ª¬µPüDÊB]\¹×t0
 «¬ ×·Ðíaå],Xr½:\œ!‹yª/‹a.IU)M¹ËýÔÀ½‹F7ã³mÛnœ7ß~¦–Ppo¼j·opuZÑJ……žÀúö•iž&æÜÐ
}QIµ\ÆZ&š€ƒZyÖÂÇ0QNŠž?‰’´tf8%o_)À.$¥ŠÎv½ÈKª Ègƒ37ë6%¼]ú¼µT2ïf¦LÅšnÀb`Y
uàžÇƒÈx#@¢•µÑ*¿Z‰øVéD?vï €R=`Ø@¥@Ë8ví詇(”QC•‘‡•»¤UUõÌu[Ã-âÆï^ùß´5Bò|ÄqŸ¸ú{ÛÓjù$º»ë¤Ñó|ú'Ds—Ÿ5/'X¶ð8yXœ1¡{ÓÂVIý-W0
,2tºÓã4õ"‡õg픸ýWÕò¬,k>Ö纽"P#à«_¡Mó>­ùˆSÙ8ºW˜| 'ÊÆõ|?×s÷{RFËhsRFû³­qÈëÕGá\܃30WÐ! ?ÃÔ#j§	¦îr>kÉŠCõG8“ÿ„[6Ò6Qih3ø{äoªÑ­hHMòu~¿ñé;)?L=³ÐÄ”&ûè”!ÿèep>[Áëì¹<²BöîpÃU˜Ë>šwÙgZØYúó#˜Û<ým»xq§³´õÙ™Òà¶ÞÕoÀR9·§@üCËr:]0W›À’bÁdV‹Ï™NÍ0® 8«Ãû ‡–xh´{¸‡‡8S€)³Õ’ÝÛл°_ý¶è+bÙš¥ÕLŠP¬#¯¿‡´X
ö5d=­<·ßfEÏ,u/‚4 `9ë¢%[5&eéH®–bÒ`×a1l®«Zûr4|	µô¡ú^#/íÙÊÄ„|Û|ÞWr’1÷³Ôm-=Z`Çh‡K¼¸Lºz‹Á·@Õ¶¯µKgi
›u¢Q“/2'5âãy1 †n
¢ßV(ibòÃ)gö?ÓÌupêV{¦gth<Ö* ±v‚¼öƒÞ俣¥úŠ)u¾­vkÉËÐB=”ü/柞«ÍV’É¢–¿8XÙB«3I|8.¶Ð&¬§QÙë9Gæ
‡öTŒCZtŠœ§œÜ>1”âÆÅÚóêqâ®z&šŸr‹÷¦íf˜v¯r&–w,L&ÁneK¯ÏO®lvÙœä‘&*ËḂ@7É#Ú¶»pUû@Õ_áVLS}ĸ¦6?ƒ> ìÊÏlÂ(ã`<è¶asg.rÊlÇ–rÔ¬×Ãe†(/÷,t‡æÜ–Å»Át>3ØX;ÂÉk‰8ôŸ»BË‹i´û”@®³)‹6¨ Ñ!DY„íbaÜõå_Ö<ƒ†ÿ‚†Úâ–ú‡hAÉÛÊ—“Õ
z›3Ïn}
Fåãóÿ¬1üÙ³!”´ÐpsfÔ2tÒø+§¹ÖŒ¶¢*Úì…Ïšùw@¹x¤M¤»âßV
œ9$­[.= (b5Gÿ-o˜èPч(ÍTÛ¥ š¡ZT×:¦å4e=&÷v=	äΨg}ýj8CÑ'Ëì€9˜ÿ}M¯gƒEQ.–4Áu’­ÇZYñSΞúÛÜÓ«»º­«f¯	Mþ„>WæÚéIÅRš%ÄÏEç·Å
çÀ¥xæÍšÕË©ž-©C¥@)6h×Ã/*_.³|ËšFwšØ;Ü>¯‰#¢Õwô9ž“Ó&p߃•=ø‰ü_£¼bhеrjpzö™GCˆ—…ïn°Å瀕™ˆÒJmí°qþÝDÁ£!%º?SüTC‡žÈÀ9xÙ¬cÖ¢Å:<î@Eyu,
:¢ÿ/[ÿÀÀˆ•:Ùæ=ŠHj6üIçt}l3çµÒã9„5q‘³ßq›'çåŽ×·/V­+ï}ªËF:ŸoëûþèC¬O2¯éz®#ÃìQËÖ>Ð mj³&{3¥,á%¦5ŒÔª%äªq½É¤L1²
(ZëE†×A ªlŒS ¶á²‚šÔfY«¨¥J¬lœ»DDF
øQJê7iT[“T¥ÞÄ`–›…³_±àluäÁ¨‹*‡ˆ×æÙxr®ì™xQ	àõ
Ùx¶þƒÁ= «}=/6ëòÝ@·Ä(z‹ìIÉtV
5
Zu¦L©ï_)PϨÁeŒ¸ßEuÒÚ‘’ùñÅÑŠTrœ­[N×”«:ÕÛw.‘ÿåœaÐj ÔìÕˆ-PŸðú†…Sp­MÕ>¬<§¬C`%Þ¹/GF`4™®ïõ¸*ðäjM®YA€E…à¹Õ7ØUÉÙã0T ›e–UÝ¥Nfm¤!BÝJvÚbD£¹ÛØBY'ÒI©[ŒÏ«h £$½ lèC®pÊ'^—€ŠkÄp‹³¾*1z›FŸ8a¾ öÞcÆgÑý[²@[9å“£+¦µVfË—f¿Â£n:›P×]¬&t.  |^
èþ‰.g°¾!@5Ð(Š@Ó#:ƾ®ÉGbï?•
RÂëŽ~uæéá°ë¶vêä¬kÃV\×ñWáqeØæ+3÷¸õûç¬HûÀà¸Ó2nuŽñÔ>kKZf›_ Ô•ü&ãÀÜ!¦zv£FX‹©åƒÖ¹â‚ÞàÉ
vö}çäîXhÞl;h@y‹ºÙqó)·M¦úÄZ¸\,ªZÅ•S­ç`ÍJL¾œ=é‡Ûû'Y™RÆ^òê?¸­G@åŽÌiH.b6;¸i¼KéÛ~Wœ®Óˆ°Éòþ•5·y]ÇÖ0Yà„.]Ï~YWb-·»v,­m"C:Öãylx×Ûq¥€*Ÿ…Œq¶x¯ë;󽙉RyåöX…röY¯ˆºfó7w6	]„«ØÌ"‘ â¤Nî“V¶=cˆ¹=ïMEü|nÀ€Ym¡ÜsÇ?óþRg+yVõåF_ÃUFÍÐ÷H=8€â¥ÆxËbHÙ„×Ù¬¹ûR">xþy/g_èÎ]Ã9,‚ã¶¿YÍßmc!ºZ·FËê8ÜË	µÚºàùŠƒ¦WR9ˆg]ô人1å8>³8êiçbîåà“ j¶ð¾ÀOÀÈx…?"&J9)·ê¨Ë)›×„xö\ûƧ×2ö‹Ö0”ˆŠ‹ªÌÎÌ*¥nhÎOÑ’ÍU¸fiSÀÎJ
|¬ÏÚâ*rcÄvšýÔ*´T§Á¤„zü¢¸ͳýþ
Tå 	…îÉú:0-rá=‘—¢ÞEÑbøŒæµŠz@T‹^†©-æUïQbBc”­„†Šîå¬)*ÀÀ80άFŒÓ Yj¤ˆ&Àt,ª§¡žB)`;œÌgÙ7¨½°Õ»\viWÿ«®‡´=ºî¦ÞN ðti
(ž¸›ž3cœf@=N¶ËiSzx\𯵴Գ®,L‰ñ5ŒÆÔþBƒøË_þò7ª„O‰¨èŸí¨h¬ÃùììÐç/§5ÀнÂÓáÏø´çõõ~q…Ãü´ãB§Öi%ÆP+yúòÓ!ëP°¡ä‰j,6Þ®@dv{ÃåÖ_±ÿÇj|¿`•WÎ;­º/Žnå8HVŸæLùÙ±é6™¦|uþ¶à—þÑÇ×ÄÊf3þ®ÿ}ÚpéÙÓ*ªZmìµT7༖ìV׊í6Îßn£çl÷ÛÜ1«£Í-LJs?mÓ3qÒ¢Kù¢.9Eåph‚¶ïÜ’4Öè@ûàBßV[ÁÌd^³°A!·i%@†9e.¹×Š@cÏ‘›gº”œaœÁg®ûšÊ]hçmeÚÖÄ,Ö«5ЕrJKþŽ^=øÜ¹Áßâñpk–ô>{°÷É-qKÕÚ)þš)À¨ºýr¹:m:&‘¬n粕3Âò8tAd“Å6D=W¯Yf:avµ¼LدäÕlHô1ok5.aµ¶jžm@A+§V	€•þ.–úxò,<Æk²:÷H×m[Y;Â?À¦:×.6]iàªÎÏ“5Ðh¿`xûйÀ㲫T€¯–8ð<ߢ9‘fH½Æ&c³È‡”0©µ0_´$úø,ÙW+ìxvì ÓwPúªˆÚLoI0 €]¶dŒa;8[*þ˜ä&‚ÿ¢swª´WqÑ$ø²:5¡>q ¾“D8OI;£¯°Åá—;	Ò9m™½Éå°§ë=ä¨ó¥ÊdìÔðe°Â&†x5£Ô”e'¦	OfHZ	0ËÍ»ú²ì˜à—ÍYæR‹É!9¸ªìšk[Q>'·×òüýƒÀáq|R¡×û¼iþ;pB/›Ërm&àÇ¢Ñ..`õw>—¶V½Ñ(4‰‹‡˜¹j¸ôµËÈØÞA=)Šæ¶Ðú¿ÙÖ³­mμ¾¸Z™ÇfÜ„>U·Gn£9ݸ撉ɒŒêöÛ£P`.×Úœžì¶g¾¨ó¥X¨nït ¾=£ÃÆþÂÌ\—düß቞Áéæ3²ü2’¦ª ’ß”(Bˆ9ãKx6Ä3¾JÚš
b§€Ö-
	 ò;	PH¬¢•…€æK	PH4—p™ª²ÃYžSÀ¢N×çÆb™e…Àà*‹Êk@ß»F…¨¯oÂy ù¿Ã“FÒBm¦fa(,7^@P hÍpØY²ö€Y=Kâ(ê(qþzÀL=¾ÜEÞßy)Ìâ[ÎÌÁ¢@Æ­>J€RH„[õÜåßùš–”—¹ýR†À[íó™þghÏ•`³oNu¤oG^rûeL‚o·dSVƒ°çoðFC hžaº†ù%qôÖ`Q]Ò¨z*”o<	
Þƒ%¾RëÿÛ'@
ùqXÛ¯x*¸wÖ7fƒ(Ш
ói.ï0?šøÎó´ìâõkˆÇ.OÏ&ë„	jáƒÇîs<ßÛõŠf¬×M;çå劆4ŒDäs‡§e…žßçŠ0sw1bÄc€‘u¦ÕÜ!0soÛ	vžgØ»ßåÃS+®J¼ÊŠ:ßAÓƒû šVâX<MÞ:Õè~5¤EÚ)NªÈ„ëy›{Ù^•°{ËP,fZÙÃkÂØƒGÆ)ö×™=ÃŽ/fÀ_4©e©ÛMÓ±ÖT™™&À®уQ½aü}3ç¬ûõ~ì²Øn£à<ú@ßÏ-<'ý¹®€¥IÖÜÃk°(Û (˜.óÆõ]§²¶Ë|„ÈÍÛ´´Çs\T¢Bæ‡-!­½frVþÅööùÔ„¥ådeÜ`óáúY¿õº#°<”ýóÞCKø+#Á‚à?Ü»þ¬‘§ßÕšÕQíè1  /·È-î#KË,ðýVq!²nUIP^ïî7)þ³&äÒÌñº&
qáÞFàµ|Oˆh<Ü¿þ6tÔBg‘°¶ç÷ãù @®ï£™¯´D4z û×ó&À©Ö½òýWh©ØhŸ
»¢jùŽÉtËàû#a\ÏSØ]_¯ëû®çv¯
Ùìkú£Û")<û~ß^—HS¤¼…&õÒ6ñxŠÓ?ëè¡'þ<7ÌãÎVž
a•Ù&6zÝëÝà¸ÿ^{÷öó
»ã	0=ÆnO7äGý¹‘×
ñ°ï˜ØÏWÛpÛ–ƒgEYý®ãæÍ±ñ
jÜ·ãpJfÏßÈו“V®eþ7ƒÙíòG„,“‚'tM‹Ûñ“=·ã‚/݃a$¨eàVyC/LôZbÞbZ-lîç‚ÐBM¦MJ¢EÓä:ß„ÀæRR>[a†™úŠ0aøÃ±0_%Í×		×3WY!Ûd{zÜBNRèthßêï-`‘jŠö„Šìa"h;ÄNï"4‹«¯|_ï3h;žñ
4­xži'tÍ5O¸s€·ƒFËkâ2e¸u=žè^»€J™XdÂÚ9z¿ÁF–=èö|ˆ‚±>®§ã?¬>TÏkå™êöDXå€záÔµÆÞ@f`ÞC<¸âß}!Àë„)Q|¿µü>»óVÇñì»ËváWX·'ÂÉ倊×-D+Šü(4ôêµ®÷â˾=®û­=Ï|}ë:¨Þ|³ÜjwØlO„“˾ÿôÛ<ZV›‘nŒX¦¼Þõ÷ Û+á±óvàó&ÂÉ-L¾ÿ&¼É§@ 
¸€òº×߃Ö^xì¼<|ÞD8¹©æº!óÏQ9`eƒÝ–/oô厰ª +5Ó‚þ«ÈP¡mûkpÂíMۨϻÀ¦(é^æˆØ=¨7^(ø
jj«‘k! KG¿ïiÖ^f4™´+2Ày½·Wï+ÒƒÆÙÙvõkìýnðºZÝ|Ð×GìÉ“Q#¥¤êíp÷>È@²Ðí
úKYê¶R`jXñ¶
¯k¨­yÛ°#ìZÂÖ¡ï÷¢2*Ž{í5Ê뚢ž(u$Œ‡ó‡º=NMÍbjûoØtnŸ
;B‘Ú¾ßlzÑ·ƒÛøîÀžÔã…û‹Ã3áy`|{&œ½D˜ìyZßFTAYí|î“ M·ï–'çzÿ×k"¦-»
ñ6ø²ä€'~¦¦×“ŠÉÍþ¾Kû¸ÞàÇ7ìuóšÑüÍä›Ó«àz—¯‰À@èõ5ËYõÙEèŸÄô!“UË}M9`õvE”ðÁ›r€°‡‡ä€õÁöðžàÇY/¨Ü¸^ëòxµ\¯SP¡Æ~i6ÊÓ‚UP½îxŸÌvpü,ßzoos_aƒK=Î8‰Aä€A¿×NÓF€«¼nx˜ï(Ñu÷®vë1©Éæ¾¼O°ó3‰ó<Ôî‚¿Žù‚´4!
4Öö¯	 ˆ×ðÞx¼£wÿzµh
-·[‡ƒùÔšôܲ¶g÷	õ90’@€®;¯í»q¸ïR¯›§ÁsÜùy7äsíSaG(ªvþÁ÷³Š¡fv´ó´>A·ŽiÂÕ?@·ûµŽã
	WÎ<ãÀí™P5ýªävš§ÄëDè&ù·‘øÜ·¸ÀÖҘƎ;{{¬?ÏÛs‚øq÷8^çòÁív'`z,OÁW«¸¹fþìþÈáŽ> ¼¾> ™ûÛ
–’g–6?Ád~€Éü×vüüº­ˆ;¬Aaõ¼«ûìü“ù	&‹XMe¯@¢”ש~‚鮟`27¸¼&ŒÉÉìøÉü×ëÌ?ÂýQn%Ó>‚@ncÙª0“T·µ¶kcÿÙû	&óLæ'èíyHp¢ä Ð.îù	j=o¥ç^†
ÀI,õtkKZé—ç3õvQ„s²çƒud‰?’ÄÊ©v³X{eC@ØUJ£¹Íô¹˜Àýµ}–›UÿÑvIõx™ø<Õ.PŸóÚUV÷§#¼AEl,À¿ô`O‰õ|è®ñ³¶ÓÜ„á‚v{} oÏeÔ‡i@é&˜p޾mWñGÈûy·3°Ø~rbÚ—dž4xžr€N"íSaLjŒn Ÿ|D®T}?Oa·.VW9@·ûõ8ÙŸûý­úݾÖÔÉëÓC,«>Yo¶r€?ϵ—ر€Á#°×+ÿöý¹0Ýc×;?>î?¶çë÷ãöcû] ØÈ·ë
|9ñ{èÇW»À>Ío	çãé÷¾Iñá/Þ$^1wãŠÅ”¯c¼#_áýM¨ñn/°j§¢V{(^@ð¿/ ˜¢”âÎíù‘x3¢‰ðxsæ2ù<”×Óì>²Î{(K:¼Wäaóxs\qy/pÉ—Òx&èå¼ 8l}>D,j¿ ©4^€×M^à\XÃñç/pF¼ð¸È%¹Åõçóe
x;‘”àx )ãx½n™dŠgƯkh¾¦ó5¼ÀÇ{@xÓpÿúÛp/ÀBg‘°¶ç÷“®–I€º=
bÖä‚ó.^@÷~Ý2a{:{޿¡©íSaG¸‰àþHçÝ»¾'ì™—Sƒ¶×yÊKôµÂÀÐYnkì(ÂGoÆœaÐóD8Oòo#ð¾7Ø ³¡×…Îv^÷:—kOSÁ=°}#^`sÞDL±ÛÓ¬ž#úE¤âÛ÷„€Ýy›óëuöŸ,¼Ü·+v¼¶¸Ï»=°$…ÃmÀD˜ësx»º	ÃzÝŒMÍÏÌÕ÷ð:E^Žð‚÷ί°ð?Q›ØnïáF˜™ýµ"ÈTlOB•ô*…ô•,»ö­ò§_7énåƒ(¸PŸï†`t9À{Þ;…|ñš¹0bÔ”`“‡!xg´ÄÈkÜ !h–mGå%€Ëµý°»_Ùßr€€]Üàí~ý@Ü \·G°›_;n)S‹\jÜ Ê|!_,n0|¥qƒó›Å
.[ø-Œ\vð9nðNÜà*<Ç
~åqƒß8?Á/àð7å'ø5÷p¾Ïdè«pí'¸¼‘Ÿ ··õhoú,íòÀú {xÏ?àÞù„Y•Ç«ól¡ö eã'¸Üô´ö2’Ej»X6¯÷ñö6÷µó¸=аèwƒ×•póA_±'CLÙh¿çEÄG„»÷É@,³*Ðù‘ö[¨Ým[)01á&åâuMÕ­-¯µdåÝíŽÛwýý
Û,÷ÛTgОu›~î°žÇýu{œjmo÷-ú	¶(«¶ñÔíŸ`ËúwýõA«Ÿ`Çó»ÕOP·Ïî‡àÛ×þºõ°í8µ“üû2ý}Ö~êöõõåI׻߀oýŽû¹=‘Oò|Îð¥å¸ló\ÞÏPÞ0Àå‹äè/mJ¨Ó¾ÂœÇ'ä¸Xþ€K‹çr]Ô둵íÆÚÓ㌺¿„Qöwã&ÀE–ƒØÆùeÍÐ_öù.£ÊýeY4hºd	»èýmG¶§IŸqƒc‹ÒI½ß÷@Ïp„·ƒÖü
‡[×ã‰îµÊȺº—ÿ×öÂp±Š|ÐíùBi@dÍ«§ã?1îÚmå™êöD8…ž)"ë…W°|GÆkˆ¯ù}!Àë„?€eärh¯ï3r¿â¹œ}7ÓÆÝyC;¬Û¡Æ
Žøs¼nùž»u{Ðç"ž|½ÁcAúùŰi¯ï³ÚlSÏ‹‡v‡ÍöD¨³ –K³ý7À|¯‡‹~‡7½þ¢Uø.—}{ Àýë.—ºYk"œ8Ù‚Ü“|¢×ƒú¸:Þìú‹>í•G¯#xô¼‰pRüQ2Ëö?ËÏy„¾y„ò—”G(¿a¡lùw6ðÁæÊžG(ïòåšG(oÛmí<Ýž÷y„ò½æÚ]wxöMË#”·ç‰°nOŰÍ#t¹8eF€ly„²åzòõžGÈËãºPü™G(w7¯ƒß€o2PÞŸ7l¶'Â]¡|/P¶¸û§@°“ly„²åzëïA@<ÐCç­àúx“×í‰p—G(ßË#”-¤õ)P	`y„²åzëïAÀó=tÞ
>o"œX!×voÉßêÏ3ž	ðL€g<à™ßj¸ɧ€ŸÞ8å˜Uï¸Þ_¾oôѸd9’upÂ’5Xa/úå/C«5á»QA`ÿÔF£ÿÛ ðýòýò@˜),yâÿËãsÒ,îÐ×á/õ_­ÅÖÚSV"â@Àe§ŽÐR·-B
Rh»”ƒm-b}Kþþ—­ìϲS(½À~|2Y“ÿ[ñÿþ÷7! XÝãèwõóâ4‡¹‰òóiø´‰òóË_¤ÅŒª³²PýðƒPóBøóŸ?ýŸ­+FØÝÞo]£ÝÙñ%ߎŽ À8¦|þ9ÜÄJûùçJ˜üÑG‹+ý‡ÊÂ9dC+±Š6k•Ôab%ÐÑ
zøPU¡
þBŠKƒÈÚðÝ—úù.†ÀÜp|ÚÈOú¥|à±ðÒpzÿý÷›÷sþ@Þn“?øys.ÝË—ÿ>ýãŸ?ýôSC>òiãñ)kÖ¬åíØÑ^ÉÂäÕ«WZGJ#ArD‹Ã4}®õmû9:å#¶±ï?TµfFÏšµF”dì´V–´à
6¢îȼyÿÿ+_¼ÿ àûÿWèIH'$.pbXM#x(úÑ(ðR	Ð
@€FnüñÏ=ý9þøi“µh¡`“udÁÿœQ.ו:(_5/_6Í˰!;À0±t-;@Êìc¯€­¾xÁ»(”¤pš…}?¾x‘6SÀ¬ |_f€-^¥P
¼8áýPàS@P@ñǸõ5ƒo²È¾bЊTÚo„8é$¨ÑI‚¿†L¢Rø{ýÁ^°×ìõ¼~޾=ø¾ ¸—æÀ¡¤ÄZ/<€|`½àN`š7/§ýñSÁÿÓÿùå)1{ŸQ€õ÷qû¯¬#°°uŒ’ùÊÊ`%;º;•Äiµ`†{a-<|øëD°*ÛùGü߆ t¯Jð8ŽoÖ óPc¯VÏ1„ßýÎ0T¯²÷Šÿøçÿ—C=½÷ÞÎ[¬³±õ“ŸØÙÒ¡.á7¿ùÍÇÿF	€±6³ó*Ä·Û¸^ÕjM¼êzÞìeˆTá`qD’=І/d‹Ë£è?o?	þû¿ç™$ˆ-[&öÖ'Å¿W
Ò'Ÿý¡:Pà'ªÝïýð›>þ8…ßœ8{Íröˆâl=¶‘óR æ;—œF œ»ç>YΓýÎ2BòûdíŠá¢yñ¤‚GæäV
´w	ð2½|©ÝT,´…²ÿýß¿“JDGöïð`ùü9´}ô÷Òãå6ï½Ç$¢šžUGÞh‡â^Ú§äõÿæc6wÍ6rQ/]ÛxúY‹î²$ªU×Ò§˜Çý_çIyƬ€;	 ¡B:HvJ«‘˨¨ÂÁKÌ!/õiôƒ§Í2+ùßÉ<¿U]õž.$.¦ð÷m÷ýôÏ‚¿ükþîïÊß		†.¹V{Ü(BÀ¥„ß|,#@hpò—bÝ4øÀõþ뎺>‘{ñËÍȇúùÿÎkཞ±×7–†?O‹Ë3q}øòCÖ;%€`/}Ñÿèmî±*4¿CP¦–Þ{oCìéŸÿápHðwZïÏkî¶ôØá¾qÇß |,C€¼+ädb¼	}"ÒägI†¥oƒÅ¹„Æhùwù¢ECùyNžø°JÆIÞÿË—Q$Tî’—¨ÿ©) Úÿ‡Oh§C@ÕÖX›ÿðQ
|¿áD:Á?ƒÂacX:¾Âö×%üWù¯ñÒ'zŠè,(“ Ål—`²B´mfúšuêM æ3lN™”ÄZÈøÿû_þ¢§FÒ–ÄMlèãT
€ø·Ýqáÿ!€L‚:}ÿ­u5õþB€ðÑ÷Ã?ÿsÃ%E¢x®_ÿú×å¿þK?	!&€ß(q)s7Ž,$Œ9ÛnœÕüÝQL	Û*'Îu5ô—ñßÿ}ü‹t#‹”˲•pNaŸÀa!kQÑS—AÿRæXþþûwüÃûo-ÓçÿºÚü‡þaㆯÅÉ[%À¯ý_Å=(‚Δ^©pòOö·z}ûâ?ýèG”o°nÇGpSªýë¿r5Œuûõ²<¤—wØüaqþ/Â?½€9ú.²þ5„ÊìðËOv«]„7”ŒI/êÏ/~Á=‚Ž­fä
¯^¾þé³Ï>û§þX¯ÿ¢ª¯Ûbdc½þ¯Umݾçãxõ?úÑˇ0¿˜ùêþñÿIPÈÿE¼Vø×¿†þø0üò‡[±WÉÏP¯ƒ‘/^þ¥üÂ*:ÿðàç?^¾’oøìãþ³þ$âåß8óÕ‹W/@€?üA—kiž	ÿ{…ùÇ?ÖåZþÑ8“º¿ÒÜíIåD?j`>Úï¬÷Á³Í/çð×_
søðW þÞ÷^„ï½D~úÓ¢7R(WaNLÕïâ_>ÇGp!¿ÐÞ?>á?øÁ<ËÏI&Ífh@€Ï>;}ïãÓ'Eå—ø
CãÕ«X©üAW€"ü= áÇšá=çq5ЦyñÉ'gíŸöá^ëœC>a`ñß¿øqþO¬ó!b‘~õ«þ#Aà‡	ßÓ"OºýüçD\aøù{?—hgDóÀ?%£ðW
„_|¦Ÿ	î?ûÿ@¼é=à³Oßûìãï~RdÊ ¤ñJžøÃô…'e÷ÿ{íÒÐ’ô ú	f%Mü|ýèß¹ÒÙ‘
"|~üâÇ?þÏÿüñ
ý‚ž	\à%^þ¯þ*Ã@^þ¯>üðCöï}ï»ß%Ýä?ÿùÈ»Ôéð½ÿø÷^TÏ›ù¼°°tè @ঀ

éòùnäðƒ¨¯ÿ†@(°õúlð÷lëõ)ü„ó9ð®K¡Qù»€-Bâƒ7(K@¨ø½PàÅ­±«“@RmÔ_ÿúC¼¡À/ƒ*¼ð]í9À?úèûøË´üÞ{ÿñ`¥ÃÃçŸsþâ…tI<Ð/ôŸà¯ÿ~ µ³ƒàåKÖá
Á_à
þ	ò/^q°õúúzÝ Pî €àïxùò;7&âjeÌg`\2^¼°À2ÓĽTÜÁw§€Kžèè?ÕO	øAxï§?%^¼èK'àû¯s@ >üL P0€
á»ÍÇuý®/ß~×õúúz„þ/Øç@ï„Û(6™u$H—ø«áþáŽè@äù‡WýÓŸ¾Ð?ÔÞý‹
|¡|à@€Àðly&À3ž	ðL€g<à™Ô(˜¿zcêm¯þâþ•‹)ê£é­[Ûnm»÷ýsþf€yŠ@³Ú˜v³ñDˆf0_¯èê]Ûnm»?ìÿ¦ÖZëÑ:@c [HÖ²u€d`·ÿ¨Hµ6ä׌*“|?¾ZÐ2¢Ð/øãüñžø|ƒåïÅþ³|ÃÛ”\Aà$?~0(½Ìo—ÜŸùîú@Ô±cÍ×ã¾ýÎ	ðÖçdCæò-Ö>ˆq·=îÛ;sÀ”'¾ïHô­˜Xur|õxkÈ;fÈË“ *?“¶]ÑÝ'hÕ_ìk-¥GàS?_ôúwCw»»_û/tý»ëé‘¿×yÿ_äú/5A“p¬ólu‘Wx<^%h³$5f™m»X¦§h¦ ‡¾?¿ÿ~ùZ µPáwß5Ú\4wØ»‚Ï=àYðn	@÷„¦´tIï”¶n7*úo߆÷Ú9^ÏH€ëû¼3p掌ÜÙ·©n߃÷Ú9îgŠëû¼»!À\þ|†[ì¼ã~'ÂñïÝÍ–ͯ¾M7ßûöñø=x¯ãþ5äþ>ïnt— |>vü±óŽû59鶊Ĺ¼C‘p'	.&é17
rµp¹æ’ßœçg.æ:ˆºFº=wüPØ›é×›ëJõïòûøõïŠgA@>ãEŸ+듚°	ÏŸƒFkÝ«W¤R € …«c͈„Ó8.“>Ž÷ñûÍõÞž¾ÿ°ÞǯÿöôNIïƒ!€ëßéø–BÏ]ž™78eÖÑéGÍë7$Ž…sžY#Žçi(p„–¹eE㉢PØF=+9Ù¡2¢N6Y†¥½•©ù›G€o7þÏ8}Ëñ&À3üÖàÛ-<ÏÏlð™Ï¢ð·coEz,Y­çð]¬8¡i=B´`·ìÇÛ¿…)PÐLï0/„Ó`5nl»4„)ÚñlU–îo‚§Ðyõ 7„
‘o5Ná[NSø–S€‹!wÕ{SøÍ_
ZÞž7†ÏËág<à™Ïø¦ 7«íl5Jl1(«n7–
/™'h6OÐvùÛРÕÈк¼ü;PàlÛ¬e øk‚Á_íÝ­ß|  ‚Aw‡,~Âó=‹j(5ºÁËâXZD¯zãeŠ+ü‚mõC^_¶„žÓvB}µó|mŽñëþ<Ãó(^¤ûê6¸ûD†E$cÅDøê
k:0Š ¦>RP"íÍÿßÞ÷¼Xr\éÞ
ÛÙm=ÂÊ4î–Œzú!%B E;a¼°ÓMƒë½ò“˜2¤ÉÈ ¶¹ Œ0½Ô€gãíìmüƒñ™­fá„ZÌBƒ™ñÆ„—ñw¼ó}çDdÞUýÃî§Qëæ­ºQ÷VÞ¼y¾8qNĉó£*5u\Å€É"¦2¼mëÒy…åÖ
Ð-›²/{b­¬ÝF=☓JVö‡OyÛ-ú#rÓâ­²æ?„…¤¨Á¬8¸óÎ΀‘0…CE¹_d?Yk¸²gPÈUc¥±,}åâàåš;™)(š0lKÞÿP%ÊÇöuÍròe+€´±Ôúµ%òqµÌÉ•ë
[ù"¼4÷9Ï‚ËD Œþ	
\¦Ú1¾©¬GíðàÛ&·OnH¿œ?Xÿø›Lúcl‹”Bcý6ö¨NZÞŠˆiWj²¡tÈWð)Âý¢ø]:¸%ÓÆ
º‚8 Øøµk“pÎÂ	"|ŒÃ¢ÌŠ«,¿—ðì5Ó¯ÇyÈQFí¥qðä#HŒ¸‹tÞkÛtÚ®[mû^ÛºÔ¶¬¬-ì}ûÿzmŸo‚•Ò\fM{¯™r{!8*›Zí9Ö,iÉ„ŒBþHPañ¨x˜! ]XC22ã0@¦a ­¨%P€=[¤¾Æû=@ù¾nš†­èu|Ž)ΣÒî-Š
-‹¬ö¿h
^FgräýR¼h1‡À2^Ak8†@»ÁH¿ @úÇÈÜÏ(ˆú²Î¢Âháé—i!éG$=èG;pÆP¡ålÌÄzfõûku”›ð6Ÿ¶k“:;xh@ò‘Âá¯ß8«5—rÞg;#'6ÈlóæóÿÑEœ13?§ÐÅFž[ßçüþ±ÿ«€¦yr¯ÇW¿º{ýÊíšô8'u†¯¯ÎÜÉÙÙ‰;ã:Ùë
«[Fw5ýW{BÐ×±ÞE²Ì7vº] è^ó“iÚ¸ÜW‡”š¨›~ùéÖ%Ù0sΔ(qÄ©›;,Wg''!œ€n†ÀÙYTnº›f+I:/ÖÕ>*Vº@E ŒÊë8¹=êWÈ“Ó2=5{°ºA]ªÞ
¯er`­á¸÷{ù£HôË/Œ†#2¹IŽêÊj 0¾,´(;…àÉÉÉ™.—tü6â¡@FV+4¾±ÇÃ&˜³ÍT<9‘UEÀM­“PêXЬSµÆ^»15ûØ¡€1ŠÂã:¸bÁHYdš®m°+GÔîóJÆF/ô…Zúx× ÐÈ4Ošé‰êw@’Ú‹nF0 )u„ÐêÞA3'Á(¢ù†ÆM¡|ãIt¹Fúeÿ¦ùºZ/—}Z…&­®Ñ12T†,à­Ç1j‹UúúKå2sRàÌKâÂR;/•Ù€1ˆÂê1A€vw6s± Æˆ©.ϾR¤NL¸ýóz^ùïSXyòŸd°þfûBovÕBºo[¿¥«l`ÁöŒmÒ^'DE–3ú”mÄ›u”Þ0ä§óªOrîæ–CÜ7¡ Ëw¨û¦Ù¹moαú]ºX¯_Ÿ½Öí²“~0nT¸:"4¥/{o—ða0‹{6¼‡¦™?Üu¹ÂRã!')›é_„Š&“亵r&@׆åî»ÆF·0|v=½èʘ.K‡þiªu†)r…ãû$é+ígÆò	4/…múð™æ¹‡Låûûn„VÑ>ÐzˆAï»—GgP1¯ìR.-ÒDöËój^Ýêð½]‡ ÐÉÅ'ˆ+ˆäÈ]…˜K·5´¶–nqøCtÓ#Ë‚$)í´‰’~² ÁÓÄÛIó¹¸e3S|¦<÷*¼£ýo= ô[/¹Sü¿3Ã,.Y¤.uòqNÏ…<ðº6-{™ðÓv+ØT+ë¡-€mu¢¥ÒÍÅëÎÜë'
ƒ#g'¯»“%ØNGgÝÈûnԦʞ&È5)ç™Á¨Ñ?¥Õc3ÿŸýß%úë\›“ýŸ~“Þ~¢ßåZ/®êüèæ‡§tÒä DZ—A½!Ðr'â“}!úõå0Àë›BÐú1MK… W+ì`Cì\.è²\•ûlXï¯YПFÔ%
ê_MF:¥WV&å©TÃiÀKil3ý¦Ån£ɱŽëD+Ü?ɯ%«o×èö¯Ÿâ×Ož¼Îáp‘à…­kŸRþP&“ÿ:¹Ú)ˆj#&ɱҩÃb·9™¥ð6ÀmŽÂYš|í˜n±î·åOƒ½%L„ú¨*–eüOÜÀô“Õû^ÿú×S?'<÷:~îC
ö¹í‚?Ê¥Tèºiïççj{ãÆ:öüĪ­[ ôG“IçîãvÓzùÇdj°µ½8÷õ|²ðÜ믿þœ<ÍäÍ™ï>Ø‚;z›Öóšt\,Jîq@ªÕ{÷	ÎY¼§•XíꥅP•Ñ¡AVY²ÇÕeu³˜¢®ñÚ[Üà3Ó‡H[£)fÃ༼íùödN:f–a'Ka‰7Äé¶CDV‚1çª7gBºmP&ŽQל´ ïëÐgm0qˆêÁãu
á¶Ý{Ûó…Ø(Ißu÷ÖÕü=€$YÑWZ2JVÂuWc¹~^zäBQÀj=­`&f6\CÈYkdÜ7;lšÉ\Ib=/¢;é"Y‡Ó)Á0g”À”Õ=j‚YU]tÏZ¦9ë¸@·Ý{,“e¡ìƒ¦¶r²T”ÅR\³ì Œ²aýÖÁªÄnmUõV§£·Ií|·ÀŽª|wQ&c쀅ƒƒ1ŒÅž–æ.¶yž ©ó}”]ÄbW©6˱&Tlô¶ÇijÃ×Ò‡
cÀ ‘›Ñ"tT‘¾\\IA}`[^’ÑTp
ÀÈuiCA].‚¶œ$—6t³kB‡xŸ%ú˜í À1Mî'cèÓSe	G@eôW¨À[­#f¼±ƒQ}´)rZ2±iÙ9À¼“™ó:sJÃà··¡$*¥«(°Æ¶þ×À	±d}À˜tšîŲ£Í©?uÛa™-Oð)‹ÒVs˜…pBš¦v¡1TÖJ=Þ¨uO8›®`;ñ½Ömj›6ÔË1oÔ¦x±×ÞX®ÐÓ`åŠþ¥[ÈHKgã6… W!Xê6¶€¤SÌ.F¹ÀNæñl晓ÎÜHõý€v’Ç•–½¯LaS÷ÓêToL†ÅÕÜ0’ÜN
»-!Ź‚‘~¶­Ÿe€Ö
"ý:ƒ",µ@Àœéß´neÉï„dÂÚ[ì:4õí<8ÆÔ§ªÔ¥ÿ'E`JPÕ7iqQYf¹S³¥`>³}ÁÚi¿7lB`µe¾ÞJšÎ`uK3)ôfŠbH©³]ÜÔÉ\n…Ú’ É„TŃL3tLbnS¹õÞÛ*7è;û[®­Î%Äja?¿`‹h^NëuŠèCØ´Ã#Æ%õ¸°ÓoÙËwÜAw€—ž…,
¢'±ZÑy‡97ÉM„­ëZªlo¹Ò{Ö®_eûùÁyXª{<9;Sï<ͺ~Â#Ú20¦­nRqç­ªdFáàuŽ¥Ëä…ɦvÛ÷Q«»]HÎqlg5Zö%Ý
!÷±fjDha-´¦I^²°†/„lî;/ó¸ÂNT䪂WW«`„K[Ôz4;Ç’C»±ÃÉ	))ÌHás´
Æ7ož
ûc„üÅ#-ÔÎÖó6Ü@MÓf#Œ@¯Ÿë),F›ö…"p¹5è.!‚#Q
-'ÿ¥S£9ÇH!³ûq\Ëî˜^]¤(¨6!ýVÉ~®5Vç}²ø¾üÉ
,J‹Ä Ó*›Ë«òÂÞQ…ŸyÁïG¯î/IvØÎ‰Êm%õ7¬¬Š.§FmÞ—`	‹ êËgWm½™ÏKªÇÕE>b*OqÀHÔ5ÛïpºÀŽƒsSÏ)ºÚñEµ¥®¼}fL7B¸UZêÖc™ô;È×:Âk­±mó¸M†bŸLׯ8ÿYéxëå{è)÷–
W§Ž=¶¯ÒuüomV+ίñÔSdWqe,Ìàƒå]]+ÈzŸö[ަ0ß¶‰ò^HisN†úirM5ØlqTÓ3ÖÒé+DrAbYôÕõr	RQ“ζÌÛõ:·ê—K¸ËEÙî ¦_u®žÞûDÿ¸Â¦d/O`¸’ôW
ïför ·ØPVåñm3àKáëäèAIoÞØ|aª
{ÇZçò-†{ªcÔ…W'-RõZîgmVŸuÀ¶„çÆòüÃ.TáçvL{v²¶°Ü Ã6ýNj#_p^F·ÂJϽYGsd	ý²,ú3
ðè-™ÿ(Eëb•æZ‚$šN«Õè%EÛéi±˜Û­mõ íš¹™8Aô‘¶›ußÊcAúº	WœX]hMß)Àmœ·˜V™¹žÖå¼&”/)€“˜—^_Ex¾Ä>V#k¿gýªá÷÷˸^`—º—SŠ™þÎÍAèÝbáD)ÎØfkJ q3ÈÖê¼ÌL*×bo	v©–þåÒý²NöÝÔ:àZ†H+@ô
|¯ ¨§ýÚu¨ŽfCìY=M½	WêÙÒU€ˆbD°=¡7±©Y²wzæLÞz" ëèS·tªUÖ\+MspU¡ÚÐã{KŽ=lé’u]¯×í¤‡ôMÚrX•nÆ™~IP”½®±Ï  [
šÌ…Ád¬’~u.-±B4ñaδL6wBOFÄ^˜×&×6‘AWÊr˜¹Éj2C¯Ò(-åel–‚¼ÅE-êkïf¡Ú›ýÞ\QÒž5èø¬‘ôôDj9f½O;\Q]¬6×].Ä
ú³/A±Ø”MÕ³~ÛM Öe|íÔåÒY2ˤE‡ÁTË!³V[¿ß^É®Ío€Šßvo,Õ±ËóxªJ†\dÔ»íyÇŠÀÊ´h¿±4a2Åz&0lÛë½÷ÛoÐ.>M³ð¡™Ï«qûÎ*¹†*è*.`5F;þzþžüz½åi¡‘ÂÐQýÒþ°yƒ2 ê\à'¤ÝõmyÎ_}Ð;²ð-Ø<¥Âʼ	Ë®,*íÎÏT%Šro°œ¨ôË|J!¨=õ]òË[a-é¨]@ÏH¿Úñaô+0xókzDØ~°ÅÕÁžõøP IDAT­~Q}ß¶c]:×Ê–ýZO½ÑYgO“j¨XîìHµÉ-4äÀ®}Ã)7çžK«Ù®9´×ëœNЀôÔ,vÿ¼:¿è†T‰kN
€
Z¤bÜK]p#vü
í!ÁÓkö=éÓ4§“G¸ñÉœe”e^­NC:!cmt ÒOWC0(rՕ£֦ô0q›]2kÐکȜЅ¾†÷ÄI)ÍÔõŸ€ÆËg"Õì¬ ¿st>,l7×&‘Xù¶ªA±×5„çëºj×É)†ñYÃPÙ„&Å+Öe¥UÖE¯ê(¨ÛV³mÛÁî/—‘‹
ðÚ—1@zP”EQâÚÐjÜvš[O¨Ò°ÿwu£‰ÿ%Þb€€ÈuÏ)¨¼‰ÏŸ)gÔ{2‘ M›ÝéKO7¨7"ÓN›´ª·I08'b†0ÂOe0Rn@³pä8PU@.ÈLŒC;ÈCNoeœT#S=¬TÀ±(Ë6²ÿ[gÚÍ«áÃg—™.+M3É­ˆPò—òé“0""d"@-(ßCo·ýUI1{B z ¯k¸Ûz´©:£ä}©Öâ5ð(•°[Ô ,à*s¨€ÇÊÐ,ïß3ý.fÃG€²uú"§$àSá„ä^%ßdMçÒu¹Æ}ƒµ:E1®A4låÑ“~6”³Û¿wù5äŸJˆ€Áö2–Ï}òBïû‚?µ°€èÂò¢•&€š/Žô‡U¯`} .¨3ªX€˜·Ñ·HZ@çØ1ï-°fÓ­Ú­Ld|Ôx–p³ßÛúÓ^sè@bÂÏß…íÀB,õI÷CêÚd˜lÜ*"Ã*‡Ùóî¾§¥†ýäåZ¢f'Û¤©ç.#EfkvKzxËK/‡—n–q>¯@Ìváz5hȺ7A—Ïõ¼[®ûc²…+–ßÓªr0µ½=¯©ï0aûιð:­•¨¦±„@¡Ì^(ã¤MDº˜Gz‹AÏ{šyÈj7;Þ„¨ÞB2®L„l›
†(_×>l³®u¨Ud5	{ÎШT4dÌÃPê¾E½XìЬÎκ9+µôh©mQmÿòbªàÌíÌÚPÆ®kb59wÐÅ€U§M±@uÅ]ΡKõä4l=jžYx4üѰ}Û×€%n¬½”+t›æb)bÞðEƒ è¶®±OÌ‘!'VêEÍ@ w§,çªiË@h¦©®§3Æȇ½ùYÜ~¡›æÕDê±][¨6À¦E”hH¬Rü`'
°†‘ùBŒp:¡ªzv
ÌØÖ–áú³6)*|•Ün¥^À¸ºYÃ	Œ¹è#¨Ÿ„Ú%„C…ñá_dz@ÉÌtÓwPo©˜Ó(«ül[MSr…”ÅpJã‹¡ò+}Og§Æì˜wÕ2¸
|¡S#J‘gšDvé0t¢x„WÖ-óˆÇz{Ì€äÆK=*R/¿­†MÈúË;¡~àUt?l»t@t%¨GÝšRYÕ§h´Žé(œƒ•‹-Ú¥³´úã5“%(­Ôºª_xXpçkª’³—Nn	æ=O(:‚¼«Óˆ‰¬­>$ÐÚ3I€˜5é‡GAŽ›£T7ø›äBÒñLÚ>ùI¤ð“í§c¬¨.Ët¸ÁŽy€"#:eÔ,\¸VƒêÍ¡¤KÔ¾Ný’¿šŸt]?%w7™áPO•:….y¼Ò‘e…áùœ'OqvìDØbVî8*Ä,+Ì>^¥xƒHÐu-U¦çCmoI
¸¼M.ô£|Ý:E¿Y,"úEèïlI¿ë¾RéX/Ö÷jÝž=dæxBÆnÙ“Küõ½fxòº=êâ¼z:±„4ƒG‹Дa´X€æBºdV«Â2|Å49å×Ü3£ù’¤åï"L`•€i;X\ýpú"LTj
¤J×Tj>Y­Rz1Ë@Õ ²&ލœ5pšß'Ùÿ£êÆ.eyóIÎëÛqkMžħª\vR*ÌkÉÂÿTß‹=9ùšÔ9B­G>λîçzë›Õ–R0sâ&ø‡”É€*²Ì=µéæV_ô'ºïFk\/³gþlÆQÏÁHLuå.$¢¿Û›KÇ×ÊêÚãÝ5¼UçýÛÖ¾§í$—eo¾)O_±‹}åÂàÀÕ…$}7è¦‰8•F=Ò­WîÇÊ€˜&N,O2fÎr;vH2Þ]•GÞ1’ã®üܽ‹Æ)èÖ×59ëêU9ùmçÞ~ûm÷ö{ν÷Þ{î½oâøà}ŸzJ`ë¬-þÝ«¸vÓÃ>?ÈÚLzÆ~4cÓ#zÍöA¦Æ‚b<4Q–¬áEê6ñ¬…AEžÎμüäø[Y¬
Ch4mž®&×]½©»wÁÂw	€žÚŠ×„z´W¯¾ý6Ú·ß~ï=´Á›€^â€æ‡×ܽûøÀZÇ‹–îé§Ë§ù]«ÕJ }S>BžqîòÂ+e5¨Ù{9P­ni·uÞJÿþÄ\øzè^5dˆ†9ƒš!ù‹10L¢M"x@;ý*3¨ÞfúÒõwx÷‡?¼kRT@€tþ¯®þêWÂo¿}|,ðÞ'ï}òÉ{o‚n @úÑèÏ]òÃSî.à9’ÿ?’«
ý¥ @úW?úÉ0ñ—åp)n1|k˜%B¬kŒh·Aà2¢„ØÏîÖžB=G€.ªdÕ(‹O¬Õ!p†£–WuBº{÷‡Iz`uõW/2ŽŒŸ8€\ÿÁUî>H%ÞTñÔGˆ¼>rå“DàIí0€°€üKˆ¯åq†%y„U©ú³Ì¶º"ÈlŸ1 M°@ÀN÷Äæx˾„þF~¦í%Ü&ÎR°Á¤ªÉhlIrÅ('>oiô  8Üü›ÁôdiÏÎ	Oë0*1)4.»ËGò€èH,»kÁ¦]_w‹­ïN3@ŠŒ;™WZnGȰþ6𰡆6k“zü0ÑŸÖèFÿ¯Œþc£ÿÒïfî`ÇkÃ1ñ&è—ÇÏ“3²»œ¹¨Ìä'0²¿Á€m5Ø%!0e!p2{š5ScO	!W))/ gÏ{•á·^_³öWÖ[û‰ÉþôWh¸:Ï€ý/?GoRR6ãuàìUƒÇñâ«·ŽŸÛïwì÷>”=/9¤×[ï“öÂKè‡Û·ogL6_ÿzÿ½ëÞý‡åë[î–¦K6‹~]Ÿ3ØF Óÿ=yàxYŠÀÏÙ~ô/ó\Ñ;w—¾¹ˆˆÍ®7æ×,ó²Ð[m´_þò—õˬkéÀ[Ï?ÿµM¾ûÝ#þzsËÅNú‡ôdÀ&G>¦Kvs»€ß/ßyòÉ'óßOoµo½•Î!]Í7¢Ã¼¿—ì×ýSúðk¯½öo8wSþ;"*ïˆl£{¢ª‚>²l©²öùr>íDñºQdòó·n´“'Ñ-Àñ‘ô?LÒoÝÒ/zñE#ý'¿Xpéï«\¢÷xY~hí¶+!þ÷r(Jÿ“O÷’߃•öekþ–Ò~§póFÀÊ䊗„úK—ðüOrýÒÜùãÿèÿxçNÛÞ‘#¶O|å+_ñ_yâ	YÕ_ñWÔ‹¦CC¶?D
?ÿ|õµç«kž<>>¾-ôž>rRó¢Ml~ò‹_ —Óõ®_‰ï}â.]Ý¡*?¼ª­¼O†KíJˆÿ‰<~O*®$ŽÝ+/}¼òÒË/kûsðÊKßQÀìèaû©¿”z_xíÿÑÉÿï€þ?þñŽÒxÁxù Ú9`º¡E´EiVâ[·²LJPüÚý	üSµö¢huœðp=€ˆ|.¿&—¤o.	|xõÃ?x‡þ9ŽÀ¿ÿŸòJŠ÷’±þF+Cà¥4„zÒI?wéèh†€Ã€@¿ïÐ@¿@úîwÛÝÞ”Bÿm’ïþ¤–£?aZ÷"Û»‚À)8èzQ\—1$ãã×¢@Jܬo‚~W¾IÿkîQèÿÃdG€K|ŸB½ïÜ7çË­QJý“ŠŽwcàhAûÆÀÆ@¼Òoñ3e´ø¿Ûò³A¿èÊ*÷¼æ%~þr>áT\Çrþz‚·°ö¾dév÷åøb”Ÿ/;°ÀÑ_¢Éߨ9é=ý¯Ðž¸ƒ'¡]¸R$¸Ç³y·ÄφyÁîìô'œû¿?j ɱóA¨Ôì˜[÷bÄOîs~8pàÀ€8pàÀ€8pàÀ€ŸOt[{mGog±ú}®tÈÔáq@=,Õ÷ZéÌ8ËX0@ª€æ3€¦}o|À€ø€~Én°@ßçÜ%Ÿq8€ü:ƒЖÝÌɯD¹"0¨C!…šÏ4*€ Ð×–g§§dèsa…\sE?û0À!èïk¦Î)‡©¥SÙÙ<2  B0?4EtÔ,;aPýg^f-ÐØc½¥	@3d´Ä̰TžÍgY
æØáÎã„&''·£Ý:,i\¡¸êTpz\ÙÑ3CY»Øð·EýùEE)üNHÆÒMÓÈL`HŠ­9LãPó‘bzÆ1=£¤7
¬°˜ýÈœ²AËOZne+Žé×k(f1¢Ùþ¿Óò;
D²¦BÎr÷J?ëM÷@¦I`¼œ¯2Ž!jäj£Eäð§DȶE—!$9ð©	J¿PæI?`îµ®AœR‚V
5¼ÖÚýú!À7´…%$õÆã‚ŒþÞèïŒþÖèfXËn€‘	””n0‚pÀ|À3̱FлŠ@v…BßpÒß¡ï€À_Â2‘ˆàþ>ð»Œ5iíÊ€AD…›´nV(Yà¥%léLrÀ “X9½a¢‚ˆ4m˜þi°œ§ç×z~CNœ€€¤Ñ‚ÐµÿKe]Q}liyWıȀJxA$aY5"®›ÉZ¡¿3€šl±‚/ÄDcòiÚ "c”uÊmq~Ðóåu£ç«(z;¿°ó;¿±ëý iõúuº~oç§û©Æa	€È€Æd@±Ð;ó€…m ªãCÙÊøHL¡H×ÕØ)”Ëï[™í£HŸVÁÎJŸ«—¯—ÔÕýQbié´vPN—sƒi±o´¬'!º}™ô§¥Ì©Ò„™-ba¹[·¾6•*RbèÀ\dœ¡3AbBÚŽÉîøºÂëÕ¢ÉLH,?ºŽ¡í»¬RH½EŒñùŸ‘ªÂ§ë¤ì#ÔeìGÉͬú.ãæìû4%OY~×"iH”ð&%q“	Kœ˜ýÏÄrŒÇ)`1ä*Láä9½^¹D>©ä]c(W¡YOöÒÔ%4‹‘|Dæ\ü|КŒ˜8!‹Ô%ru3µΓÉ)ÿÏtÃùL¿SÆr1Hè€3¼gP$ªÔ”3«k—Úý…Ͷ ½«"fàAË×…Š	‘£_2eˆR*ΈDFL¶Tbp/ê2"+a¬RÚQCjKÍ_ÌØ±%>Xß	ÈęЕîw‹e~ßÊê€WCÀ8ù•¤ž€zZ¿8]Pû«R*\§Xà˜˜€e>Vúé:…^0÷0úP<iUÜÇFGfo"ð|xÃ;h"#íRûä„*Ä}$Ž%аõ@ŠŸhÖ_˜ö˜Ø–#Uë¤ëXâǪœIžÿ» ŒûÀÞOà}.«¸€‚Ëœ³ç]o©GôÝò›ÓË…ÞºHô=¤Á¸Ôç(‘Dnµ
@÷2@Ò©nAzÇtF¾OkCØQƒ™€¬G„²}ÈÝïÇ.Θôø÷·/wëÖÑÝÏæ< ¸ŸýÌ…Õò>ÓD#Ľ¯ýƒÁÀÕ÷¾çªüfï-p¾(8·8¾û]<¿u.Û‰Üôýƒê
Á[.ÖÛ¿·õ“<ù
Mo³î£<AUº¯˜ÑÎ#"Ä|žO¨¶S!%uÒ-¶‰+Olà~ó…7œû÷þßùÆ¿~ÿ_£‘Lž~ô\¿ŽùzI÷µ§gºÙ~	ãFõjõóL¢Rliç‹Í63@v•Ž^άäŸ%–WÁêB}V(Ó®ÌzªtžV	ð±A_±ìÕôÕÏH%>n(ý{8þ.¢›ßz/¯Çër0\>ÑéÿÒF뿤÷ÿƒÿø2ÀÓ&I˜˜Ð´Öç™u€…ŒYw  Þ.X&`æ-02ë¶Ã\GÕÛ¼p@{T¯‚ý@æu‘ÆFâmoÜú÷`ô+Â5¸ý;èçgÎa€¬êî^P-ªÅ¤óf”B„ý@x°®Óÿ6¸q.ÇÜ®ÀÓÎöù€ý@íìã.34äU¬–»Ú—>OÞMo³4ó!ën.0ž°/Ø•F¿u £0)v‘ØÀ>¿Êê¿ÜZ4έßJÊþªËߺڞ_lM
Æ
5hxÿZÀÅ/ÙuþcÁ,¶mãˆG»{h);ÒyiE“ÚÏgÿ¯ñ“ü,NÓQÊ¿NuÏë­Ck¬Œ¾[ëc²GÚ˜I[qéûe™ÄEqå¶r-~5ÛÐtû-ëoær.{$ö`Wº
¦t, C™Oð¸@ˆ¯â6Fÿ9p ~ìîƒ~ ?ÀM&rfßÔ#_?•uZcÍèä¦
¥¿­N
“¢ 0“íü–O§§ ÿ”?»$îp¨?ÝË>s€7X¬·8À/8 å5ÊOs	+‹üðè§Üá˜[Z4ÌùÓêž@Øà;NO…Ò
ïP^4lŒë­19ÀÆÀy‡Ào<ÈÁd€ÓЬב>1­‡Õ@üéiÓ,`/ì«Óóe€7°6ú×[2Àߟ˜(+ zÀ! ÀàÊ6‚þ­É¶hhéÁk@Ú¥ÀÉûPú÷r€Oàc`ƒüù0Ë€€Qníƒq@"\)K¯e> 2Àn¡95-pzº¤¿¥ØÀéy2 ÙÓm¬m¬·´€ßÒçË‚e™÷ôËr»ðÝ=¸ð‰qTtãzûÿÊ€Óó‡€ÉÀq½5àïK˜Üði°ü÷{¤Ö¡±ÇÖa9GQCf`uýÎ;ï¬VòôÆoðIÞ}×ÓuœVìqÛ½³ÒGÿ·ú ”ÆeQ¸ÿOÇJ¨×Ç(sèÉcôºÉ#ä;®ÃK@HÖSmûlÆèÇèïý«zx¯Ïwùc>ñ‹€°ÉÉp@ý¥²vו“¯å+ô>¸ ¾®þ¬îQ›ÆjûìÍg3´»à_
?¾Ä3ìáòåËúéÿ|ñ_ˆ†2}˜gϜܓ¤ÿoÞÌ¡¬õÛ€‡p`.?vLò&ô?
2@}a’àPú{±¸~\O°!z^{¿0(
À€Ô‚€tÿ¥ï=B²°žJ~€ûF€Ìî‡ò¨âRýõ
€pÁù`µ¢DAÊQøÈH2 j•Šä¸Gx¸âÝS@sd¯ò$2¨Ø‘
ÀÄ„áHøÞ£ KÎ’àCkëª3XªÁØ:¸×¶4ú>*R]ß…ÞÞÚÉ`Éü•2§§@©qÒY©0t
%zãd¾ßüš–½ÿþæõ?¥ˆN±Û›pUú5¹x×ýÖªñ0G+Ë›(}W‚íôJó†Ò_ßÒÿ3ϱÔPéÿøý|ýO
•-2É-£Éþez{g–Y»ûmÚ“r&Álp©ÀÓfî¾e‘wÁ8¡²šìï¼yýO	oe})°79 QßšT ë‘0ª«ý§9tcßÖ^˜ßôŒ‡–…(­Fk’Yi™žLU+`à˜ÿŸV­ïóÀõ?UV©(z×®°•öÏN}áÙÿ8Ðÿ8RmÌTÚý¯–{+¿ó†Å“ÝÒ°<é¢ââ
ý;h(¡ùi Gkó€€|¿W0íéº?wP{µÞˆ@4â©üP4¢
€hD€ETÿ›Ð¢ª§È€ÄªÖ¢FoP¨'¡B=[«$™&
õZøhÔ–>*l…z¶0#¡êÑ2^¢îûO
€®C5yL4Œ1xê©çžzNx,c°ÿîwÓï´&éãy¬@: @|, xî9…@ËÊÿ&…à1@!`|‰PŒÞ>Ó!|‚<¾l€®ÓðÔS:šFq¢	úIDATÀï_2à 2àó-ÎÛKïç¸Àª¬`‹Ò2tÎâ÷‡Þ‚s~§ñ„2»ÕÏ‹÷ëåßÞGœ7ž/˜âuãi·Õ8Ϲˆc­ÈQç\vhÿί·[-îºBìÖÈDv0A”q,¢Û#ú„¡3ZD¶JmLáëwhñ„ˆ»dÜ¡Å[lö~`ñ¹¦¹Ë‚#ß,'"T7Þ Xm³Ý*Q‰8yFؾ|Šcâ^CìÇž¯å.pÒ3Ï<£f5gBj-ö”
:ˆô òù'	.}Y€|i_fð)€0T-
@z˜ ž(TÊõé.5òÑð„rs£›Ê±–GÙ I7ßÖk¶èh€÷€¶dp ÞÀ3×®]“Û‹ì5io~óf "q݈ÙAŸüg
B^ƒ $´Ò1ò1ûcÐm¾¦Áv7<›Ñu=Ì*	 ¦·x̱?Ÿ'€
Qkˆ¬äk…£Axo-"AÞ'7ÈëiŠºiŠ:åx`HÁp/`•Uo@ÞزØ}±ä€¡¶8`¤9èC…0DH;Ä¿¯P¤7”¦bª¦…êÄ¢b¼¯}iŒ—ÇíÜIY}úáLúc¶ðÉk&}ôGùÙ@oÔà*‚ëýÊ\ÌÞM(æVI)ÈvCC‘(”€B	@$]/Ÿ›
?1ŽU(“»ü=¸_Ø‘[@(,z&|ó›2
蔯¬Ëõµ>Ë¡!0ع(C	ÏÀnCLñûç°T0wù{p¿Bð2Àâ)”آ‡G=-€÷·ãÓÿSüþnû,…àíÛ·)G¹L…·"ð(Õà+Üø
e JÁ
!˜‡À÷7/”‡@
•M *·â}çp0ˆüµ6ä¶ýìð«JÐØk{üm{=h½¶¾Ð¶¯µ­ÊÇ€W_0ÂFm¿}¬í`¯}Ô¶0 jª¬Œz#ìÛÆƒq€7Âã€Ú8 ,Cà0‹åp0:¶ýÌðyŸ¼ þÔÔÈ]­Ù«ÿ^´šðI½˜Ôª·ôiµƒ`Ë)íg
€^xõU  Yâ@ÿ·¿
þþ+,èhR®îJ ðê«þ3¸}ûøø3ˆ€€|Á
ò€oËà*¬~Î%Lõ“ŠpyÇžÐ/àœ‡!p‚5xàÀg
€±Ôšo?»ñ·?CûÅâÒi~ªÌ|õ	¶÷Ígÿí¾óÚ¢ýøßÞÿ8x†ÀçîsŽÀ€Ã<àÀ€8pàÀ€8pàÀ€8pàÀ€8pàÀ€8pàÀ€8pàÀ€xlŽÿ›ÇXÖtIEND®B`‚tome-235-src/lib/xtra/graf/16x16.bmp0000644000076400017500000434171611012107762014635 0ustar  dgdgBMÎÃÎ(pÀæAAA+++\\\žžž‰‰‰sssºººÏÏÏüüüÿÿÿÏÏÿæææÏÏÿ‰‰ÿÿÿÿ‰‰ÏAA‰<ÿÿÿA‰‰‰ÏÿA‰Ïÿÿÿ‰ÏÏÏÿÿAÏÿÏÿÿ‰ÏA‰ÿÿÿ‰ÿÿAAAÏÏAÿÿAÿÿ‰ÿÿ‰ÏÿAÏÿAAÏÿÿÏω‰Ïÿ‰Ï‰Ïÿÿÿÿ‰AAÏAAωAÿ‰AÏωω‰AAÿ‰‰ÿÿ‰A‰ÿÿÿÿAAÿÏωÏÿA‰A‰‰ÿÿAAA‰Aÿ‰‰‰AsAω\+ÏAž‰+ºÿA\æ‰ÿÿAÏÿAÏωÿÿÏÏAÿ‰‰ÿ‰AÿAAÿÿ‰ÿÏAÿωA‰Aÿω‰‰A‰ÿÏÿÿÏÿÿ‰AÿAÿÿÿ‰Aÿ‰‰ÿ‰Ïÿ‰‰‰ÏAAAÿ‰Ažÿÿ‰ÿÏÿÏÏÿÏÿÿÏωÿÿÿsÿA‰ÿÿ‰‰ÏAÿÏÿÏωÿÿÿÏAÿAAÿÏÿ‰Ï‰ÿÿ‰ÿAÿÏÿA‰Aÿ‰AÿAÏÿÿAω‰AÏ+AÏÿÏωÿωÏA‰A‰ÏÏAÿÿωÿÿ‰ÿA‰ÿÿÿÿAÿÿAÏÿ‰Ï‰ÿ‰ÿÿÿAA‰AAAÏæºÿÏÿÿÿÿÿÏÏAÏAϺ\ÏÏAÏAÏA‰Aÿ‰AÿÿAüÿÿÏÿ‰AÿAÿÏsAÿÿž‰ÿÿÿÿÿÏAÿÿÏæÏÿAÿüÿÿAÿÏÿÿ‰ÿAÿÿÏAÿÿA‰ÿÿ‰ÿÏÿ‰AÿÿA‰ÿ‰ÏÏÏÿÿÿÿAÏÿÿÿÿÏÿAÿ‰ÿÏÿAÿÿÏÿÿϳ³Þ(œ$"$œœ#œ##$#(#œ
6(*6(6(*r6((6(*(  :ÎÎÎ


	³³¦ÞÞ(7$"6œ7$œœ$#œ$œ

		6666r66*66*r6((()	   :ÎÎÎÎÎÎ



	Þ³¦Ý³™¤¤™™™¼$#rr77œ7œœ$œœœ###
		Sr((6//6rr6r/(6(6¶¶¶¶¶:)
	   :ÎÎÎÎÎÎÎÎÎÎrrrrrrrrrrrqq

					zÝÞ³¦Þ™™™¤¤¤7¼7rr77$¼œœœœrœ"#"#

		66(666((6(66/(66mmm¶¶¶m¶¶:)
	   :ÎÎÎÎÎÎÎÎrrrrrr{rrrrrrqq
							¸zÞÝi¦Ý¤¤¤¤¤¤™™¤™7¼¼¼r¼¼œ¼$œœœ67	":	
	((66r()6(*r6rr6(m¶¶¶mm¶m¶¶:)
	   :ÎÎÎÎÎÎÎ,66rrrrr{{{rrrrrq8									z¸zz8ÛÞÝi¦ÞÞÞÞ™¤¤™¤¤™¤™¤¤6¼¼¼¼¼6¼7777œ6¼		:6:
		6r(6*(r6rrr6(666œ¶mm¶¶mmm¶¶:)
		  :ÎÎÎÎ<,:,66rrrrr{rrrrr2qqq									z¸¸88***[Ý*)©···©ÝÞÞ¦ÞÞÞ¦ÝÝ™™¤¤¤¤¤™¤¤(¼Ž¼Ž¼6r¼¼¼¼#¼7	:	
		6r6666rr*r(66/6rjœœ$mmm¶m¶¶m:)
		      :ÎÎÎÎ<<<,:6:,:6rrrrrrrrrrr							zz8*****[ݳ³###)$*/*·Ï···ÞÞiÞÞ¦¦¦¦³Ì¤¤¤¾¤¤™¤™¤(¼¼r޼6r¼¼7¼¼¼¼			6r6(r6(6rr(6/rr($$$œœ$$¶¶mm¶¶:)
	       :ÎÎÎÎ66<Ý<<ÝÝ,:6:,::::rrrr{kkrr					*)****ݳ³³##)*/))·ÏÏ··Ý™¤™¤¤¤¤¤¤™™™(r¼r(¼6r(¼¼¼Ž¼Ž		r6r6r(66666r/6r6j$$œœ$$¶mm¶m¶:)
		      :ÎÎÎÎ66<Ý<<Ý<,::6::,:::77rrr{{{rrr*))))*¦¦¦¦³#Ï")**··ÏÏ·¤™™¤™™™™¤(r¼r(¼6((¼¼Ž6r(		(*(6)6(rrrrr666rj$kk$$k¶m:)

	       :ÎÎÎÎ66:6<<<:::6:::,7766rr{{{rr****¦ÝÝÝÝ))*©···©¤™™¤™™¤™¤((6666r(Ž(6r		

(6rr/rrr6*/r/((6Dkkjk$$k:)
	        :ÎÎÎÎÎ66:6<<<<:66666:,66rr{{{rr¦¦Ý)¤¤¤¤¤¤¤¤¤¤™(66r((66	
66*r6(rr)rr/(6(rjjkkk$kj:))

    :ÎÎÎÎÎ66:66<<:::6:::,7Ër{{{r™¤¤¤™™™™6(6(((6	

66(666r*rrr)6rrrkkjkjkk))v/  6ÎÎÎÎÎÎÎ66:66<<,::6::,6ËCCrr{rr¤™™6((((((66(r6(rrr6r6(6jjjjkjj)v)v 6Ï6ÎÎÎÎÎÎÎ6:::6::/,<<<,:::,6rrr:((rr6**6(rr6((*(kj)vˆ6ÎÎÎÎÎÎÎÎ66:66:Á/,<<<,,,Ë((((((((6666((((j6ÎÎ66666:,<<ËXX	2ccc2c111]]]111		
	2b22-F-AAF³³³1^11b³³'D

zzy¬yzzyz¬¬¸¸¸¸1( **ŽŽŽ1¸¸¸¸>144()((((( 
 yy*ŽŽŽÂ¸>¸>¸d():)(
+((( 
 
**y*)):uÂ;1>>¸¸4			4			Ad4())())(
)/"+(69((
   ¸¸¸¸**y*6::::u;Â;;			¸¸¸¸		4				4		AAH%544():(((:)(
)"+((
   yyyy**y6y6ÜÜ::::	ui	i	;	Â		¸¸¸1AAHG%54()((((6))(('4
))
6"+



 ¸¸¸¸**6y6y6yyÜ:9:				uu	Â;ÂÂÂÂ		ȸ£>ÈH6(3G5004(6(6(((:)('4
))Ð



¸¸¸¸Cy666yCÜÜyÜ:::	ii	u	;ÂÈ>>8>ȸ1
	
	



	
		H3663HG1004666(6(()('4))

6#*67677ÜÜyÜ		u	iiuÂ;		Èȸ££8¸¸	

		H110040(666(((('4))Ð
6)###676ÜÜyC		u	iÂ	£$£>14	

(

	
	1004666((
Ð#)69#6ÜÜC		u	...1


	(
	
	10040((()##6#9#)	.
	
*Ã-4			100400(######*Ã-10##%%Ã00[[*PCCC[

44444***##"+++*###)))!!)))000666((PdBBC6966DAHAAAA[				££%%%

----44444)$*###+*+*""#"100000(((6(6(B699966HAFAAAA
							££%6












-------((((444444444	444+)&)#""**+**""#***)*))*110000(66666969966FHFAAA
666	

				

	£8%%%6(







((((((((((4444444444444466)&)+**++*))**))))**10000(6666BB999969HAAAAA

/66W7666	

	
			++££%%%6	


-(((((((((((4444444444444

44+			)&)+*))*)**)))*1000666699996):HFAHAA

	
W6W	%		++8£
%6






-((7((444444444444444444
444444++))""*"#")))***(11001£(666()9999:):HFHHAAA






%%++£8£


/6--!!77$$74444444444444444444
4444++))*#"""##7£110010£6(6(B9:999):HFHHAAAAH




)))	
 %%	

%/%/







--$$44444444444444

4444444""""##"*7£0011000100(((6):99::HHHAAAHHH



	

%%%%/%/%

--)($$444444444
44
44444žžEžžB""#"###"))))))*(011001001006(66((:)9)9::AAAAAAAH




666
--$$444444444444444EžE••EžžžBžBžž)**"##	##""***))**11010000((((666(((B):)))):AAHHHAA


96





-4
44444444444444EBEž¬£BB££B•B•ž()("#"#"#""##""***)))))*))*10£00((6(((((66):)::HHAžA




6666-
44
4444Ež•B£¬E•££E•EEB(6((("##"#""**))****(7(1£<£

()))AžA

(

C






4444

4žžžBBžEE•EE•EBž((6"###"#"""**)**)****(7(£<£AHmmHA)):)AA/6
(4
44

žEBE•žBžžEBžBž(""#"""")))70£,,)A


6(6/6žžžEEžBEEžžž("""")0)/66





žž
 £££33k#
((



5555554440000000		
						£***+++++""""""žžžžIIžžEEEž

8£££££ £  œk###kœ

žžË(ˆFFJJH






555555""00000	
			0£0	
£ž££¶££+*********"""""
f
HHžEžžžžžžžEžIžžž­EIžžIEžžž"



88££8 <È££   kœkkœ#)œ
œžžžžžž)6ˆÇˆËH+++J+HH




555"""000	1£9£


			
££££++$*****+**+#$$$""""""2"f2ff
ff44HHHžžžEžžžžžžžžEEžEIE­žž­E­žIž+++žžI666"





£8£££ <£ <£  (kkkkË))žžžkˆ)ˆ6C(ˆˆHF++JJJ+++





,5554"#"40000000


	£0£0



	
	



			£	¶£*#$$*+++++***"#$$$""""""ff222

22ff44žHžžHEžEžEžžEžžEEžEžžE­Ež­EEE­E*******"666""""






£8£££---		 <£ £kœkk(

œ
žžžžžkˆvË6C(ˆ6F++JJJF++




,55554""#""40005000

	0£0£0£0



				
	¶	£*#$#*+*******+"#$$$"""
""f*f222fff4444HžžHEEEEEEžEžžEEEEEEEEž
ž­E­­­­­­­žž+******""""""



y££888--					 <<<kœ#Ëœk
:))œ
	žžEžžEž))ˆ(((6(ˆ(+++N++NN++







,,,/555""#""000044550	



	£9£££1££9£



$	
		£		m++***+++*****+""""""""Pf
f44!!!!4žžžžžžžIžžžEEEEEžE­­E­­­EE­EžžžE****""""





£848848£----			£<  £(#kk#kË

:
œ)

	žžž¶££žEž6vkˆ6ˆ666ˆ(FJN++N++
dd



,/,,,55555"04455445550



	0£0£££8££0£0



$

	

£		£++***+**++***+"""
4444444žžIžžžžžžžž[[žžE­ž­­E­EEžmEI666""


ƒ££4-4-£8----			££<<£ <<£kœk##ËD#œ
::œ:)

			ž££(££žž(vk(66ˆ66ˆ6HHJHFJF+











,,,,,/5555555""44454555500
		
	
88££8££


$$$

	
£+***+**+*""""""""4444[IEžEžždž­"
ƒJƒ



£-4-48-----		- £<<£<È£<k#9###kœ#kœ

:œœ::::œ			žžž£(6(£žž((/666ˆ66ˆ6)6H+J(F(H







,//,,,5555555544554454500
	



8£4£



			

££*+$$$++*"""""
""""""""[žžžžžžž­

ƒJƒ


  £-4-£   ----- <<£< <<<<kœœœ#œ###9kv#œœ
œœ:
œœ	ž££(£¶žžE(//66(6ËË/:)(6HJJH+H




,,55555554454454500
		


	8((6£££1



			
	
£¶£++**+*"""""""""žžžž[žEžžž­
ƒ



 44-4    £ £ <<£   Ëkkœœ##kœœœvÊœœœœœœžžžž£££Ežž(v/666((v/v6(HJHHH



/,,55555555555455545500
	
			

1£8(¨(£0£
		
¶£¶+*"$$$$"""""""EžžžIdžE


   £8£     È <<<<£<£)ËËËkk##œkk((Ëœ
œ

)œœžžžžžžž(66(6(v/(6(),/,/




,5544545500
%		$	
£8(668£££++"""""""[Bžžžžžžžž




 
8£

   £ < £ˆ(Ë(##kËË(œ
)œ
œ)
))œ(/6//((),///
555554444400

$		$

0££8£80££ 
£¶£+++"""­ž­­E





 ££  £((6œ6((

(((k())/55555444000


			
£9£0£££££9£

¨£¶££+++"Ežž

  £6kk

((ˆ55555
		0£00££££00£0
+Ižž­+11
	+++--+-""+   +(((("





001+ÇYYÇYÇÇDZ








ˆˆˆvv£££9999&IIIIIIII===sD!¶´]5O©Oµµ°–WOX²³KL[™DO :%:[L³”””²””²A”¨§¨µ§[GHGHHGHGKGHGHGHGILILLILI[ILILILIMNMNNMNMFMNMNMNMs222222s22ssssssssssssss3aaaaaa3aa333333X|||XXXXXX|||XXXW(((([KLLkLDDDDD00²²0s«s_s!OZ´]5O¤µ°Ø–”™”[²DDW[[[dd²À”²ÀP”¨[KGGGHHGGHGHGKGHG[IIILLIILILI[ILIFMMMNNMMNMNMFMNMs2s22sssss2sssssssss3a3aa33333a33333|||X|||||XXXXX||

(IILDODDD0s>s]5¤µ°ØDD[LL[²ÀHGHGGHGHGGHGHGGGLILIILILIILILIIINMNMMNMNMMNMNMMM2ss2ssssss222222ssssssssa33a333333aaaaaa|||X|||||X||||||GGGJJ((CCff11f1^^^y4[[0




GJJ  GKJ(99(69(XDDOOff™12fD(q^^
4y[PPO¾”!fA!0


KKGJJGJ  KJ(99((XDO²
[1f221™f24DCDCq^&À22y12{{y4P™LSSO¾””!+?
K
GKKKKGJJGJÆ KKJJG((69jDCXO²²
OY
D[If2122241f4CDDDD;

fy›qHH
™%:21y4244444y{yyPP[y%:ILPO¾f%:?0?0“0K
KKKKHKKJJGÆÆJ JG699jCXOOO²À0
}}YOOOOD[LI¨f2™ss44(CDODDDOD;;›yyÀÀ›LHHB&ÀB$:2y4422444y´n´SPLyy$:²IO0¾¾”f$:?0?0


GGKHKKKKKKGJÆ GGGO('9'(DjOO²ÀYY

OLI™™f21sf411f™CODCCDYˆD(DIy;››
Af00f(((y
ÀÀLH:BL&&ÀB::%y2442442y´”PS[LZZy
::%”²D[LdI[OP0¾””::%?00D0

K


HHHGH
KKGGJJJGGGIIG6D9'9CjO²²²
6YËYI™¨?™ff2ffs441fCYDCDOCDODLy;›

A0fff4((yf›q›0HHB´Y&9²BN%:%{{424´fd²””PPS[fyf%:%””OD[P[LIL[POPO+A”%:%??0OD“0

K
HH
HKKJJ GGGIGGGDOOO9DXO
YYYË}}6[[¨™¨Kd1fsfff41fff4fCDCDOCDDO–;5^›y;^0K0KfX4Zj–y5­y^›0€€AB´O9k&²N´–%5::%%{{4222224–d´´­y´´²”S[LOOZZZZ–y5­yZOZ–%5::%%DP[dIL[PPO0¾”A!¾”–%5::%%000000“OD“0?W:WKH


KKJÆ JJGJGDDD(9'SS.
.OY6ËË}}Ë[™?¨jdddfff4ffffDCCDCDODD[:;-;››››^yfNf•˜KZ/j:5-4	y^;°Ô€0AOYkU²´:%-%%	%yy44224224:´d4ddd´y”PP[:O-O	:5-4	y:%-%%	%DODP”[L[[PPPS00sÀ¾f”:%-%%	%?0¨OD“0??
KH


HHKJÆGJÆJ(JÆGDD9(S


Y}}YË
}}}DDD¨™ddIIf4fIf’s™DCDCCOYL^;››;›y;



f---fNXZ0Z/

f5y 
y–^µÔ}·0O}kXB´5% 
y%2{y424yy442d´n´nnP5 
OZ5y 
y–5% 
y%DOPP”™”[SPO0ss¾”5% 
y%0“PD“0?0

UWWKHGHKKHGHKKJÆJGGJJGJ}JGD(''9}
O}
}OYOD™?¨KKIddIIIId’(’ssDC(CDˆ¨™0IIL^f4
^^^^^


f˜-•KXjXZf

(ff4
f ­–

^;°Ô}©OkYPH´::4:: :%{y4222442dd´4df ­´dZO4fZf4
f ­–::4:: :%DP²™?™SO0ssÀf¾::4:: :%0“0?0?
UW:,KGKKHKKHGKJGÆJGGÆJIG(DDOj%9XZ
}}¨¨dKI’’ddId’6ds(COD¨™™¨I^;–^›^;–;ZXZf
ff–y–
;µ°Ô·}YPNL%:::::44y{42224nnn´ndy´dOOZOf–y–%:::::DP””™”SPPO10s”%:::::“0?0WjW:KHKK
HGJÆGIGGJÆG(DODUDXXOOS%%XXZ&&Y
DU|K’g’’dd6Od
™YD¨;;–
^^^–;^W/Xf

ff–
y––
°µ}YPH´[L%$:%%%2414yy4422y{4dddn´dynnnZfZf–
y––%$:%%%D™™?”OPOPO011sÀ%$:%%%0“000?
K
KKK
KÆJJGJJJJDDSWSSS%Y
|t|dKLdg’’dO(
’dODD^;^;^0fXf0fff
f y––

}YHH[[L :%:2@4422y4y{{{4dnnnO6O
OOZOO y–– :%:²OPWX1550s¾”” :%:0??0
KKKK
KKHK
KGJJGIGJSO(

}}Y|tKIddd’d/(YCDD(^fkfffkf
fW²”
””B[[[LHW2444yy444{4nO
OWWO15510s¾0W00KKKKK
IL(/((f444f²²
B[LL2442240011110f))))}}DOf]f@@@@@,+!++!++!OfffffCCC99PPPCYCY}DCUXDDDDYPPPPPO™ÏY

PPPPKKIIKK]f@@@,++++++*!PPOPPO]ffxfCPCCPPCPSPPOPPPCCCYC}}PPPDDD”””¨UXOPDDD

DDOYDOP66POÙÏ´N
]f]DZ,@,*+QÆOSODPPO!Of]fx]CPPCCPPSSPPOPPPCD|DYC}Y}}OIG*GSSDD”¨¨§jUPDD}PDO}YD

DOD¨›ÙNK
IIKKffuffWD,)Z,)+H+Q*+*+ODDDO!OOXff]]0CPCPPStSPPDDPPPCˆ}C}+GI,,GSSSDDDODDD”§UPDODOYDDYDD

DY(O(DO¨€[›¤KKgO
Ou]f//D,)@))),HN+Q*+DOSDOOOOXfff]ff00CPCCPStPPPPOPD!PP}CˆC+IOG****YPSDDDYOODD²”¨jDPOYDY



DODDO6O(PO¨[¤¯;£N´ˆˆ“ˆ““LOGOf]]f]D//D)@),,,f!!H+*Æ*ODOODOC!Offff0K00CCPPSCPYOPDPˆˆ}C}IG***

,GSSYDYDODDOY”§XPDO}


YODD(ODPP(€I¤¯;£]˜´d9Yˆ“ˆˆ“}
IKOGGO]f]]fufO}ODWWD,)@@),,f++!HF+Q*Æ+++
OtO
DOOC!fffKdK0CPCCSPPOPYPDPD!O!}CG*G+PSYDYDYOODDO¨}DY


DODD(6DOPO¨[dYY}ÏÙ¤;¯;£˜˜T—jWf(ˆYOO

Ofu]]{]fffDO}OD,)@)),),Z++!K+*+*F+*9SjWODOOYXf]dCCCPOPPYPOP!|DOO}YG+*GPSYDOOD
DOYO


DDD6(6(X[™ˆ
Ù00
0ffffYWY©DO}O
Of]]]]]]ffDOOOD)@)Z*)Z+*++HF!K+F~+**+9DS±DOODC!O}XOff]ffffK49CCCCCPPSSOOPPDDPDDD|O!CC+*,G
SDOOP



PYDWYˆ
DDYO6X6(PPDD6(OO™™™Ï0P04fˆˆ©YDO!GGGGKOf]]]]uf)@)Z))Z
ÆQ+H+~HQÆ.ODUUDDD9DCO!Zff]xfff]xfKddK0CCSPCCCKSOSPPPPPD|DDD|DD|O!DCG*,*G
SPDYDODP}YW”




DDDY


OYDOD6OOPPDP(€¨€¨”™0PPS¨00ffW(4ˆˆYOODL,]uu])@),Z,)ZKK66H(UUWOD!XZ]ff]fff]KKC9SPSPCCCPSPPOPSSOD!|DD|OODG*,GGGGG*G
SSSDDOYWYOPDDOYPDOj9j
PDDY






fDO((POOOX
¨¨)(S§9104f4fO©YYYYˆ“©“YOGG
]{u]f,),*Z,,)ZZ,f0Y.UUUWO!XOffK0KPSSPSPCSWOPOOSSPD!O!DG*GG*

G,SPYSSPSDDYYYDPDDYOXXDPODDDDDYO



]D((6YO6L9(?OO©Yˆ“Y©O]uffu{u)),*+,@,@Z,,6Y6.O9f0O99SSOOPPWODDD|DGG!G!

SXWSYDYYDO9ODDOOO

]DDO(XXXD(?“?OOOOuf,)*+)@,6~909SSY

!!!!DOYDD9DDO
fOYXDZX?,)*Z,@),)0SO
!!DYOOOOfŠ 66(sfsssŠgDDDDDDDDDD+++

ˆ6€€€€6669.
KKIPPPPŠgfd"DODODDD!++!+++



ˆODYYDYOYOOYOD€€¨¨€€€LKHHHKHLH((6™999.
KGKK((’PSPPDŠgŠ-DODOO
H++!




6XODDODDOD€¨€€BHBBH((6(((66OOSODOOO
GK(((’PSDŠ-ff


!HH+




(DOD€¨KK€?KN!BI(((66((66OODDDOO!OX
O
IIKK((9(d"PSOP’gŠfODZ,,!+



"
ˆOZ,X(©(XXDD€KNN€?€€N



+!!IK((6(66DOSDO!Z,,ZZZOO999X(979ddd’fPgŠfDDDOD4+!+!HH+
!((¨((DD€KNNK€¨€KCCCCCC+!BLIKLK(((6(6000OOtOOZO//OODOO9LXGK(7’dd’I’
!PSsf|d½ffDD
ODOfK++!++""H+++
!((§(((€NNN€€CCCCCPPPCCCCCC-!BIILII((6660202
DD99OXZ,,X.OIKXGGO(99O(K U ’’P!!!GffDO
4++++!""!H+!O(((¨§©(0D€NK¨€€
C
PPP
PP
CC
---LL(((66™00›2OY±DOO.ZZ00,/,O!OXX((9((9(99’d’’’


!PODf’---fDf+O+!+H!+H
(((§§¨"€??€K€€¨€€?€PPSSSSPPSSSSPC!BIBL(((6I020q2DD±D/00Z
:UX(O9O779d’’d’SfPD|!dffg-D4f!!H+!++H+H6"!OXZ,X¨¨¨€€
€€CCCCCCCCCC-Ix-L6((66™|D0202DDO9DDZ.O!D!!GGGGK
(((Kdd’d ’SfPSsŠ-d!LPfD

}}f++!K*+*+HHHK6!
"6,/¨"0?€€



-(BxIL((66I™A024DODO(OZZDOD
%L,

((((d’    ’fsff
fŠ--’PDUDf
4+H!!+*+HHKK!!"6(("€€-ˆ--L(600OD99,ZO!OO9%%GG(K’d   ’’df0fŠ-OODf4!H++!K:::6}(€€??-x-L(

999ZZOO9O%(((’d’’’’d(
f-fDH++!!K
((€?OOOO(((rf!(

OOCCCYSSµYOttOˆ(OY!O!OOO
O[OO(SOSCYOSS=µDDDDDOOYˆttYO!OBD.."O!O[L[[9OYSSYOSPµµµ=µ=ODDDOKdIIOBKKBKBOD..YYYO!L[YYOY66XOO('9OYOCCCSPPµµµµ=
OOOOIdLKBBKBNBO!OXZXZOO!OYOOL[YSSSOY66XOXOOO
9'SPPPCYSµµµµOLH
((IKKLBB-BLLBOO!O!ZXZOZOOYYO!LKXYOSSYXOODX
XODOX

99(9(CP
PCCPOS=µµµµµOOAHH
DD((LLLL
ONL--NO!O!!OOOXZZXOO!!OO!O³L[XYOSOYYOY66O

D*DDXXODDXX
(@(P
CCPOµµµµLHOD(O/,BKKBL!O!O.ZOX.OOZOY"!YL[OXYYOYXYSY,*XXXOXXX




99'(CPPCSS=µµµµLABL
ODO(O((dLLLKKjBLNBKLB!O!O!Z.OZXO6YY(Y""6K”YXYXYYXOYSYY


ˆ}X
*OXOXX



((99CPPCOµµµµAHH
OD(((ˆO(Kdd}KKdK,OXXj
}B}OOO*O!/!OXZOZYYY6YY6"6[K[L[”²²”YOOY
O}ˆ7ˆX&
'CP
PPOµµ(((O7(d}
ODOBBBKOYZZ!Z.XZX!YLL[²™X
OˆO
99


.9CCP
PPPµµµµµ
ˆ((Oˆ(ˆ(OOOODBB}
*O.Z!!(([²?YO
.&9&9
&&.9PPPPY==µµ=ˆˆODOOOOZXOOYOW™YO9.W..9.PO}OP=µµ=xddOOO
OY!!6™YW&.POPµ(HKdH
OOYYOZ/WP(}KOO231"+P!*****<Û¬>>ºààåÙÙÙäÔPPCPCPPCPCCCCCCC^^^^;^;;;;;;;;		5	––––––––––;Â--f˜˜˜f˜˜B˜fffffff?0?0?????µ?1111^––^11111111ØØØØ=Ø^5^5155Ø=^00-55=555=55	55?;;××Üܰ““((((""Ù¤¯¯›qzz³³³³³³³³zqq›¯¯¤Ùš©©©Y©©©šÙÙÙ¤¤¤¯¯››qqz³‰•‚MMJJJ**XX22fff0020f02+P!********||S³³zzqq¸ºÂàá¤ÙãäPDDPDPPDPCPCPPCP^^^^;^^;;;^;;;		––––^–^–^0–;;-˜-˜f˜BBBBfffff˜˜00¨???????000?¨00551115^^11^51000ØØ5Ø^5-;5455^Ø00---55=--5-5-5-=5;×××ܰ°““((("""’¤¤¯›qzz‰‰‰••‰‰‰³zqq›¯¤ššYYXXXXXY©©©ššÙ¤¤¯¯›qzz³‰‚MMJJ*XXXXXYY0000ddd˜-ddf ff““2dfA001DSBÈ•B!!CPPPD|O|DDppfzfq£>¹ªºâ¯¤ÙãDDDDDDSDDDPDPPDP^^55^^11^;;;;;;;		––^–^–^–15;0;˜Bff˜BBBBf˜fff˜˜¨0¨?0????¨¨0?5515^^––^^^55000Ø=5^Ø×4f455]44	00?“=555µ=--=µ-=-¸¸;;××Üܰ““((("""’´!¤¯›qzz³‰••••••‰³zq›¯¤š©YXXXXXYY©ššÙ¤¯¯›qz³‰•‚MJJ*XXXXXXYY0f0?f?ff’--C!!+!W““2d+232pcb«†È+!!DSC!!!SS****SËËD|t|DYÇpB³³ffz£qqª«¯¯áSSDDSSSS|DSDSDDD5151^1^^^;^;;;^–^––^–^^^1;;;;	Bf˜ff˜BBf˜’’ff˜˜¨0¨A0A?0?????¨¨™0?A005^^––^550000=Ø5^4^4545450
---55---5£¸¸¸;;×××ܰ°““((("""’’’´¯¯›qz³‰••‚‚‚••‰‰zq¯¤š©YX*****XYY©ššÙ¤¯›qz³••‚MJJ**XXXXX0?2?5?0“-’dd
-´-0!!!G!!!+!C"“??“2^p”eÆ”SÆÈÈ«+!!G+((****::*vˆ|t|DˈvDBB³fffz0zq›««ªà||SS||SS|SSSSSSS5101^11^^^^^;	–^^–^^^^;;;;;-	B˜˜˜˜fBBBf˜˜fff˜?001A0¨?????¨¨¨¨0?0550005^–550000===5554425244505-555µ5--££¸;;4Üܰ“(((""""’’!!¨¯›qz³‰••‚MMM‚••‰z›¯¤š©X**JJJJJJJ*XXY©šÙ¤¯›qz‰‰•‚‚MJJ**0°f“0
x†-!G+(C¨(!C"““““?“05^Æe”e$ÐdÈ•´(GGG??**:::**}ËÇDtttS}}ABffffffzqq›ªÂOOO||O||S|||||||^05151^^^^^^^^^^^^^1;;0;0˜˜fff˜˜ff˜˜˜f˜˜f?00000¨?00??¨¨¨¨0?0100001550000552554-5-×555xŒ--5-5µµ5££¸¸;;××°““((("""’!!!›qzz³‰•‚MMMMM‚•‰q›¤Ù©YX*JJJJMMMMMJJ*XXY©šÙ¤¤¯qz³‰••‚‚MJJ******01f“- 	@

--	  !!!¨Z§(!!!!**"““““““?05§0§^ÆÆ$”$d†B(((GM((???***)*:"***vYS±tt±|}fdfff³qfq¸ºtOt|OOt|O||OO|OO5–11151^^1^^^^^^^^^^^^15^;;;;;˜˜f˜ffff˜˜˜˜f˜˜˜¨??00¨000??¨0¨¨?0100000000550055==-5554554ØØxŒ“--522??µ=--£¸¸¸;××ܰ““((("""""’’’’¨!!!›qz³‰‰•‚MMMMM‚•‰q¯¤š©X*JJJJMMM‚‚‚MMJ**XY©©š¤¤¯qzz³‰‰•‚‚MMJJJJJ00’"5?f	
 @$!IC!t!!t+’!**"““““““055="ÉßÙß$d+GM??********:""ʱOOtYYYOÇ}NBf³Ûzfz££t±ttOtttOOOOttOt–500155^^1^^^^^^^^^^150;^0;^;d!				Bf˜Bff˜ff˜˜fff˜˜???00????00¨¨¨¨¨?1100000000==5^5552^Ø=¥Œ=5555=552µ5-¸¸;;×Üܰ°(((("""""""""!qzz³‰•‚MMMMMM‚•‰q¯ÙšYX*JJMMM‚‚•••‚MMJ**XY©©šÙ¤¯qqzz³‰‰••‚‚‚‚M‚0?0’200
@
{@
´†- ![!!GG!+++*""*““Å“505555="˜5Ùß$(GGGG(??*::::::*::ÊYOOYˆËÇYËËSGNdf‰³ffz¬8YtOttt±tt|O±tt±t^550151110111^^^^^^^^^0^^^0^-				˜’f˜˜ffff˜ff˜˜˜˜??000A?0??¨¨¨¨D01500000000Ø^^^^424]-	^=Œ-==-55---55--?¸;××Üܰ“““("""""""""""qzz‰‰•‚MMMMMM‚•³›¯Ù©Y*JJMM‚‚••••••‚MJJ**XXY©šÙ¯¯›qqzz³‰‰‰•••••0df5?’--?
44o

¶†-f!!!¨S+J+++++""""?““““5§§55©555€µ=ÜÙ$G!!!MG(**:::::::**:SSvvttÊ}ÊÊ}ˆÇSGdQdddffff³ÝÞY±t±±tt±ttt±Y±±Y^5511555151111^^^^^^^15;^^^^0^^	f			f˜ff˜˜˜˜fdd˜˜˜˜˜¨?00?00¨??0“1^50005505Ø^ØØØØ4^5ר55Œ¥	
x
–ŒŒ	555=5-555-?;;Üܰ°“““(((""""((zz³‰••‚MMMMM‚•‰³›¤Ù©Y*JJM‚‚•••‰‰••‚MJJJ**XXY©š¤¤¯¯›qqzzzz³³³³zf05-µf(4oo4

-df0f¨!++!!!,,"?““?“©5§5§§555?5=5ŒØ!GGG*)::::::**S|O}ËË}}}}ˆÇS+MMNddddff‰³ÛÛÇYÇYY±±±±t±±±YYY^05111;51101^^;;^^^^^0^^^^				ffff˜˜˜f˜’dff˜˜˜??000¨?00????????°]10000055055Ø^5Ø45-=Ø^	ŒŒŒx	
–Œ	Œ-5-555==5554××Üܰ°““““(((((((((zz³‰••MMMMM‚‚•‰³›¤š©Y*JMM‚••‰‰‰‰••‚MJJJ***XXY©šÙ¤¤¯¯¯››qqqqqqq’fµ5?5“?4oo4@010!!!!!!!C*,""(???5©©5“5G5=ØÆŒ"XGG**:::**||vv:}:ÊÇSSSJJMMQBddp‰‰³³ÇËËËËÇY±±±Y±±ÇÇÇ^^05111^0;;;111;^^;^^^^0^^^0^^«	ffff˜˜f˜˜’fd˜f˜f¨???0¨?0?¨???????0¨?f00000500004455555-	
ŒŒ	xx	x		x5-5=55=5555×ד“““((((((((((((((““°z³‰‰••‚MMMM‚••‰³›¤Ù©Y*JM‚••‰‰‰‰‰‰•‚MJJJ***XXY©šÙÙÙ¤¤¤¯¯¯¯¯¯¯¯d’f050f?f?0?44-221C!!!!!L**“§/55/===ÆÎUZ*||}vvS||S**JMT‚Q••‰pfYˆËˆËËËËDZÇY±ËËË^«^^5^50;;;011^;;;1^^^^0^^00^	ffffff˜˜˜f˜˜˜BBB¨??00¨???0001?0¨¨¨?00050000000000;552=^5442µ5ŒxxŒxx		

Œ^^5-55==55°°“““((((((((((((((““°°°z³‰‰••‚MM‚‚‚•‰³z›¤Ù©YJMM••‰‰‰³³‰‰•‚MJJJ****XXY©©ššššššÙÙÙÙÙÙÙÙd´’050??f05310““5555==ÎUÆ"Z??)**))***SS	||SZX,**Mž‚dd••‰ÇËʈʈÊʈËÇËËˈË^^«^0›^;;0;10;;15^^0^^–^^^0›	-f-ff˜˜˜˜˜˜˜˜BBB¨??0?0???¨¨¨¨¨°f55000000000500-^^5555^54-	ŒŒ			
Œ¥¥==55?--“((((((((((((((((“““°°°°°fzz³‰‰•‚‚‚‚‚••‰³z›¯Ù©YJM‚••‰‰³³³‰‰•‚MJJ****XXXY©©©©©©©©©©©©©©©dd00?0??“(001110*§5ŒÆUU"Z??)**))**
DDDkXUZ***JJMdQTÚÖÇÊÊvÊÊÊvÊÊˈˆÊˆÊ›››«11›;0;;;;0Â;;^5^^0^^0^0^«1›		---ff˜˜˜˜˜˜fB˜BfD???0???¨?¨¨¨¨¨¨“205––5500000000^µ555^^µ^××5	

Œx	¥=
Œ555=55(((((((((((((((“““°°°°°µµµzz³³‰••‚‚‚‚••‰³z›¯Ù©XJM‚‰‰‰‰³³³‰‰•‚MJ****XXXYYYYYYYYYXXXXXXX012µ(0s005UÆÆU	}ÇXWZZX**JžžÓÃÓ}vvv}vvv}ÊÊËÊÊvÊ››››››1›1›;;;Â;Â;;–^––^–^^––›1››--˜fff˜˜f˜˜f˜˜˜B??0¨??¨?¨¨¨¨¨?25––55005500550001^µ555µµµ×5	Œx	¥Ø¥¥¥5==5((((((((((((((((°°°°°µµµ1111qzz³‰‰•‚‚‚‚••‰³z›¯Ù©XJ‚•‰‰³³³³³‰‰•‚MJ*XXXXXYYXXXX***JJ*****XXYY©XXÆŠd”44444(+***XXYY©*ddd-XXXXXXX‡‡‡‘¶‡””À44		
44	DD|7(X((+***XXXYY""d´´´ddd-///XXXXZZjjX(‡m½xÀÀÀ444444444
	4|OOS|OtO(7(XO(((+****XXt9("?d´’’dd---Xjjjj,WZZjjjjX‡½†¶d[!!”²²À444yyyyy44*,,,*OtDOOD||OO(767OOO((((+***XXXO""9	d´ddd’’d	XjjjZ,WZXXXjX
‡‡¶´IdILLIGdL””4
yyyyyy
4,)WW,,+OtOSOODO7((6XXOOD(OO(**XXXX|""d´’´´d´´d--
XZjXXXXX‡m†ddLALddd!!GI””4yyyyyyyy4*,W,**,OOD|±DOO(76((XXXOO!OOODD*XX**Xddddd’’??--XXXjjXXXXdddd½¶’ddd²¾!ddddLIL”4
yyyyyyyy44,,(ÇÇtOO(((7(jXOXOXXO!((OO**XXX""*,?d’´d´´d??CPCPP--/XXXXjjXXXXXdd’’´­¶’’dddÈÈI!!IIA4
yyyyyyyy44,,/,*,*|OS!Ëjˆt||((OOj~jjXO!DO!!O((O!!ODOOXX"ZZ

??GG+´??!XXSXUP--/!XXXXZXXXjXXXd´´d¶x½’dddL!²²dG4yyyyyyyy4W/,,,,,*|OSOÇjjÇ|((((OOO~jO!((DDOOXXXXX*,WZ

d?(!GG!d??SXXSC--UXXXXXjXdddgx´¶’ddd”È[”²fG4
yyyyyy
4!W,,/*DOËjÇO(7(D(OO(**XXXXX,,XG““GGPDC-XXXXXXXXXdd‘†MA­xddd””As	4
yyyy

	!,)!,*+|OS±YtDD(6((76(O((((GJ******""*(!’´d-	XXXXX(“XXXX(d
‡‡Ö‡‡m­dd”””””²”	44444	),),*ËËOD||((((((GJJJ****,,"	ddddd-//XjX(““(XX(XX­‡ÆJÔ>‚mЇž”””}O}”²”444,,,,,ˆˆt|S|7(((d+JJJJ*****XX’’’’--/XXjX?““(jjjXJz‡dd’t>ž‡MVž””²”””²44ZYYSD|OddGGJJJ*********Xjj??XjXXM¸MdÁžVV>VƲÀ”²À44D•NNMMMJJJJJJJJJJXjJJMMGžVÆž²ÀfY!!!!*D¨0°°PPOO(DDj(jjjUUDDD6(UWUDD(U::kYYYs4YY!!!*PPP¨!°?00?00?°(}(DYDPYDOOODOO(D//((~/W~YUYD6(U(ˆUWˆ(DYkUD(U:k(OU:OYˆYYttPDODfsfsfsfYYY[!!”++PPD¨¨¨!+P
0°?000001°O((}(7}ODOPPYYODDD
6((O6(/WUjW/Wj~jYjrr(WkˆˆWˆOYkU:Wr((kU(OSSˆYˆSSODfffsfsY}Y!!²!!PPD¨¨¨?¨
!¨00°01?1?°005OO005(((O((
DODODYO(DDO6(6YY~6(/Uk~~kjjDYD6
O6k(WˆD(W(kWWWU(OY:OOˆ|OtS

PP!sfffYYYY!!”!+!PPD¨¨??¨=¨¨01Ž?1?°0ް000505!O00505O}OODD}(DOODYOOOY
DD
YDD6(~~O~WDjk~kjDO(77(D((k((OOOWWU(OO:UkOOYÇYOSDCP45
P!fs4fYYYj}Y[[[I!”²””!PP¨¨?=¨S?=¨°01°?=°?1°005OO050505OO(O(ODDYY(OY6(YDO
YD6~DY~~~YY~((/6DOkjjjjjDj6O
7
DWUOUWrrOUY((SOYY}}ËtD||f

4–54


PD4f4ffYYj(YjYI[I”²+²”PD¨?=¨SS¨1?°?1°?ް0A™5O!O!A™55A™OD(DYDDDOYDO((OYO(6ODYOODDO~~Y~YY~~~U/66OjOjjDOj6O
(UˆD(OYrWrOOUDY(OOYY}YYSDÇO
ff®yy

5D4sffffY}jY(YYYI[[²
+PD¨“?OOS¨¨¨0°0??°=?°=Ž5A0A5!OO05(5A0ADDD
DOOOOOYDOP}D66YOYODO(OOYYYPOD66ODOY~(~(UU(DjOOjDjjYOOrDYY(U(YYYUDDOSYˆYOSSˆ
5{{
S|t!}kfffsfsf4fY}Y(Y(Yj[II[”+PPDD¨¨¨D??¨S?0°=?°?500™O!00!50™5(O(O(YOODOYDPYYP(YYOY(6ODDDYPPY(O6DDYY6~D(((ODOOjYYOOD
7DUY((rY(rYDSYPYˆtOˆ}®®	

S|SP
f4f44sf4Y}jY[I!++PPPP¨?“O¨°011Ž??°=00?5A005A00005(OO((7CDCYDOYDDOPDY((OD}666DY
OPY(6~YDO~OY(DD(YY((OOD
OO(DD(Y(YYY(Y(OOY}YPYYYtO}

{{


PPP
f4fs(jYY}YL!
+
PD¨?=S0°0ް0°°005,00j5550656((DO}(CODCY}YYDDYDDYOD6(ODYDDDO(~YDY~~6(DUODDrODD
O((D((Y(DO((OYO}¶PSSYYtYˆf
4®cDOD!Ds4f44fYYjYYY}[[™”
PP¨O?“¨°00000?°5k„6((}(CDCCOCODOPDYYjYOO}YDOYOOYD~OYOY~O(DYUYYOOOODDr7OODO
7(DDY(YDDY(DOOS}SOYOˆ·	
4{
P!PDOfssfffYYY}?”””*¨PPPPD¨“?¨001010°°6(CDDYUDDP}YWPPDYWYYDYO6OOYWY
OD~YDOOY(DDUkOOY(7D
rDYDOYDOSSS}YYYOˆ}·}f	{c


{§!OP4fsffYj[[™?™²À²¨PPDDD¨O¨0°0000(CDODYPDDOYPOO}DYOOOOY(6OˆDOYˆ
O(~~ODDODDO6(6UkYDOY7(OOO
DYOOODYDOSSOˆ}YYYˆˆt}·4

{·§kO
4fsfYPPP¨°°0°0DYDPDYOPYDDOWW(666OYYˆ,O
OY~(YOYUOODOO((YUYkYWYY7OrOrO
r
(DDOWˆWOODOO(SO}ˆYˆ}

{{
fY¨PPP¨°0DDOY6~(OO6OO(UYD((r7((DOODOO(Oˆ}}
{X



ˆ
f-7fKÆ
’½d,XX,X,K








DO

(jˆ

fu(f]]]]fWGKGGKÆW
’DD,K




D6DjUf-fuu-(}f]f  
XZGGJGKGÄ/WX’’,XOd
((



(6DD, ,~DDjU
	ff4xffr}7ffXZKGKJGG/ZZ


’H’’KX,DKK!

((((((



6(6ODDDO6DDDˆ9UWkff




fffff4ff667x  ²”OKGJGKJÆÄ/WX


’dHd’ddDOdKO!



((





(((~DDO(6(DDDOO(ˆˆjUUXˆfff
	ff]4x
fff(6r76]f ™²OKGKGJÆÄ/WZ


½’’’’dd$KdODKKdKO!



((

(((}



(6ODO(6
DDOYODDˆkYËkUUk(ˆff

fff-xff(6r77vf ?”LKGÆÄÄXW


dHd½’’’$-(œKdKdD!

((((







%O(DD O~(YkUOD(YˆkkWWkUfff-

]]fffxfr76r7(f] 
™L(~&ÄZZXZ



’H’dd--dXDdKddOODOU


(


((OY,D6
@O±ˆU±ODD(YÊjWWUkˆff




fffu]f4­f6.6ˆr7}ff ²d((}}Ïr&lZZ



’d’Kd’’’$-dDOOd-d!OD!ODO











		



(((%ODD((O
@
(OYkU±ODOˆ((ˆvUWWZÊff--f

4 fff	­­fffr}...(7fx]   ²””L³(“((Ïr&Ì2qX


’d’d$$d-XDX
(9d-dO!DOOO

(





 (((· 
(DDDOD

((YˆYOODOˆˆ(Y((vjWWj(ff-


ffff4fff}r77((777rff]] ??™™²KÎ?Î(&lÌ2q2q



’d’d’-{X
X(9{-!OO!ODO
6(



 
 
§OO%(((OYDY
((±OOYYˆ(Y((ÊjWU6(


ff4r77(((77ffff]xx]?™²²”IKd³?ÎÍ?(&lÌ2q2q
½’-d{dK
,d-{y’KO!!O!







  
%(
D(,OD
((ˆˆYY(ÇkUj


ffff]­f(rr77777ffff]f  ”[LIKd““ÎÍ?“Ì2q


d’’$$gyy-wdx…d’dO!6

6





(
(OD(O
(Yˆˆ(YÇkË



	f44ffu4ff66rr7ff [LK³??“Í“Ì22

’’dd’d’dg-dK--’dKODO






(DD(((Yˆˆˆkˆff-fff-r}}(f
	[???Î222q2’½KdddKKKddKOD


D(YˆkYfffr??q
!!¨!
|22242™!§D|X¨!!9!¾¾DOO
OODOO±±OO

9OO9””OOOC|D|t|||DD
2212414424CCCCDD²™™€DDDDD9OOXPOK””²”²tYXOjXSOOOSSOO!!P¾CDODSOOPOO±OOO±ˆOO
.

999OO99”¾OOCD|t|tt|22111Õ1ÕDCC”™€DOD999DD9999XODOKK””²ss!jX·XXj!SSDOO!!OO!!¾¾|DP|PPPD||D|PPPS|PCC
ˆOtˆ±±ˆ

..OOSODOOO


”¾CD|ÇtÇ|

2104242DPDD²™™€DDYDOSODO!O”OOOODO!OKXPO10K”²«1s!OX|ˆDDD!+!O!ODO
”ÀSDCCCCPtOPPPD|SPCP9±±tˆ±ˆ

..OODDDOO!O



”¾CDtt|


2014ÕPODO™€™DDOOODDDO!O”””²DODDD!OK0ZDO0KKK”²«ss1!X§XUÇ!OSDO!O!OO
”¾0¾PSPPDSDO|DC|SSPD&Dˆtˆˆ
.
(DOSDO!


DD|t
00Õ2DDO™€DOYDOSDO²”””²DODD!KK0ZO01”²«s151!XX!DO!!”¾¾0|SO±|DDP|SOPS!9OOtˆ

OOtOO
”YYCC|
B20122DDO”™€DOODOOs²”²DODOO0XO0KK9”²s11sP!S(!!OOt+”¾0¾ZCOt&D!&&D:W(
DD99DOYY
DCD±|

B221121112B²OX9DOtO””²DOtO00XZ,(01K²”551(O!OOIGGO!!OO&&¾”¾OD|POZSO&DOˆOOˆD(

9±DOO
¯¾Xj|DD|t|||
´9421244124Õ9´PDOD²XSjjs”²s9ODD9DXO(010”²²551!!(Çkj!SO+IDSO!&”PC|CDD|±|DDOC!Y&&OYˆ6(

(
DD±D



””¯”¾¾Yjj||DD|t|tt|

BBB211Õ4B´B9PDOODO²DDS±D”s²²9D±DOO0DZOD0K²
²«s15stj,UjX!SDOIDSDSO!!O¾DPSCCD|DOSOPCC|PDY
OO6.6±ˆ
Ž“Ž

DDO9DD



¯”²¯Yj||||t|


BB1D124B9PPXZD²²™X)ODSDO±DDD”²””OOD±OK0((XZODOs”
²ss1|X(©UYX§!!OGIOD!!
0(¾|t|tt|9OCSCPOSO
Y±j6(ˆˆˆ.
““
..
DODO(O


¾¯.
Yj
((CjtÇ((

Cj2B™DDDD²²j²™€DDjDDO9OODOOOOD”²s²”9O
O!K10(X
XOPDOX(ss²

s1sX§$ZXO!G+&¾OStOY

9±ˆ'
“?§9“.“OD99
99
.”
jX(((

9²S99²9€DS9ODO9O”s²9O

OKK10
(OO/UX(s”
«s1|UZ'+9+

OS
D&&
Yˆ99O9%“?/9/?“
999
9.
Y
(C}(
9(O99(²9D(O}D(O99²9K100900U/Us²9sst6X9
0

DOˆˆY““

¯



(CC(6·
²
(S((((S(((99KK10KKXUj«ss
SDDOˆY



™(((K1KjXsOD””DOSDOOOODDDDDDOOODDD”²”ODOOODOOOOOOOOOOOOODOOYODDO
D|DDDD!O!¨O¨!O!OOOOSSPOP!!O!OOD

D|DDOOODOOOOODDOOOOODDD””²””²O

OOOOˆˆOOdOIOOOOOOOOYˆO±±±


DDO!O¨¨§???¨O!!!OOO!SSDPD!P!DD!!O!



DDO!!YjOY!(OOO9&&!”””²”²

ˆOtˆ±±ˆ!!IIIIKd


ˆOtˆˆ±ˆ±

”OKdII¨§?§¨²§¨¨OKdII


!!DCPPDPD

!D!ddDDYZjYYDDODDDO!ODD9&&DDO””²”²


±Otˆ±ˆ!!IKId±Otˆ±ˆ±

&DDO”IIdLKK¨?¨¨²²?¨IIdLKK!!CDPPD


&DDD!OOdKdd!jYYZZ!OOOX!OO!!ODO!””²””²

ˆOtˆˆ!!IdLK

ˆOtYˆ
O!””¾KIK
dK§¨²¨KIKIKdK

+!|CP
DODO

D!!O!LKddOYOYYO!ODD,,OOOOO!OO!O²”²²””9OtˆdH"IIKI


OtˆO!O¾”¾L
KdO¨²²¨LIIKd

DDP
DDD
ODOO!OOLKdOjYZODDODOO

DO”²””
W:W±ˆDD±Zd@LLI


DD±ZZWDO””¾LO§LLL
+DO!W:W
!ODKKdKZYjÏDODDODO!O

9DOD&&&DOD&²”²

±O±DO±""@L
W:W|O±D

DOD””¾?W!D|!,O!
Kdd’ZjYO(DO!OOO!!


D9&&!OD””


±Oˆˆ±OO±d"dKKd
±Yˆˆ±O



|!DODO?¨KdD!SDO!!
)

Dd’YYjZO!OOO!O&O!O&²”

ˆ±ˆˆ±KIdd


|Y|±ˆˆ±
DDO¾¾OOO?²¨KIdd+DS!!

*:OtKdYZ(D(D((²”(¾

O±jˆ±LLLK


±|±jˆ±ˆ±
|D(D0(¾
OO?§²¨LLLK

!S
O


Ot!OOO!,/O&
O9O
9ˆ±OO&¾O
?¨O
%

&YYOD/9D&&””
9O9±D¾
OKKOO±ª
%
OOYjO//&
²”

DD0O
OLIKK
±}²ª
DK
s!!!d!!!!!d!AAAA2qqH’HHXZ!!!!!+!!!!!!!!AAAAAAHH9662qA22244LHN"’HNNHXXXX,,ZG+!!!!!!!!!!!!!!0000!§!¨!S!¨!AfAAAAACP”H""dddH66692qqq2224IHN"HHN’’NH"""""""X!!GKKW""XXXWYXXYXX""""Z,,,,d!!!!!!!!!!!!!Gdd!dd0f0?f?00?0tt±||X§!AAppAAAACCCP"#dHdddH6669 2qq24I’NHNKKHHNO""!!""!!XXG’XDDXW"HXAXssXssXWsXXYXY
"",,/5!!!!!!!!!!!!++!Gddd!ddG!0?2?5?0“5OOtYXËX±±OSApAAfAApACÈCCCDD"dHdHdg@66622qAq2…dHK’"HHNKIHHOOO""O!OXX"O!OX!!dG’DDDDDDDK!KBAAIAABsssXX
K!KK!KjYZ/5!!!+!!+G+!!!!!!!+!!!dddddd0?°f““?0SOtYXËX±XOAAAAApAfAAPP¨§0¨!"ddKH­9666 222Asq24dddfHK’"NHKLKKHOOO"O""
OOOOOO!
d

DODDDBHAIABs2XYYX
Zjj5!!!!!!!!!!!!+X++!Gdddddd!dd01°“f“?!ttXYÇY±tt|DAAfAAfAAÈPP¨DP??”!""dddKKK@9666 -222HKL’""NHLLIKHDDDO9XOOYvY
O


OOO
KBABWB2
sYXYYKXZ,//,0!!!+G!A!!!tG+!!dddddG00µŽ=“5?fOXjXY±YOOAAAAAAAAAfACDSPÈ”D™C!HHKK"#d66Y((22222 -2qfKL"’KLIKK"OOD"""
ˆO9XOYˆOODXWAHIIXXHXs2Y
KZ,YXZj@Y,5!!!!d!+G!!G!+!!dd´ddd!!0?0°“?2?00S!±jjjX±t±OSAAApAAAAAPPDSDC”¨ÈHdd"d96Y(2qqq 2qK’.I"O"""½
"!OYX9X!"œXXOYˆ!Od0d’U/DOYXKDDP
BAIXXsXY"KK""ZZ,ZZYj,!!!+!G+!!+!!!+X!!!´ddd!0d05?=“=µ?!SXjZjjY±OOSAAAfAAAfAAADS|P””H’6Y(((q2ff.OO"O"½

OOˆYO9XX
OOOYO’d0qKXXDOYX"K!O!OK
BKXX2sUXjK
OK"XZ@YZjYj!!!!!!!!!!++!¨dGddG!d0005??=?=µfDÇjjjX§t!¨!AAAAAAApAAC¨PDd­(qAA4fODD"""!OO
XYˆOX9XO
OYOYX

qO0’XYXOY
DKOK"
WXXBXXs2s
XUYUjY
KK

K,,j,//,j!!+!+!!!+!+!!ddddddddd!!?0fµ5?5“?DOXXjXOOtO§¨AAAAAAAACPCÈ!H"g6YY(qqA-…42.O"""½"
"X!ˆO""X
!OY


d0

WYOWO
KKK
ABWH
ssW2ˆUUjKK
KK
Y/,@/!+!+!!!d!!!!!!!!!!dd!ddddd?0050f?f?0?|tYX±|OOtO!AAAAAAAAC!dHd’96q4422ff..""D"½XX"""XXXXY’

d

YY
d
d

/ZYY@,!!!!+!!!!G!!!!!!ddGdd0050??f0OtttDS!AAAAfAAACPdd6244ffd.HHHO
X"X


"
BBssXX
"
"XX!!!!!!!!!!!!!d00?0OSS¨!¨AAAAA9--224ddHOO
XUX,@X!!!!!!!!!!0D!¨D2224’d’’dXXZZ”²+!ODDXXOOsfs”²dddddd"+++!!!XXjZXD((ss”²”DDdddddddddddddd"""ddddddddssss™""!++!++++*+XjjjZZ(f²™²Dd
dd-
ddddHA"ABd
ddddddd’ssss¸¸2sddOOY(((™™€™™""!+!+++!+!+jjjWZs²²€”
AHBAB
r¹sdsssAAIIdKdd’fUªs`s2s««¸q¸¸2IQddddOYYOOY(66(™€€š€™((!!
+++*!++**++*ZjZU(²²€”

AA"´#B

¹sf
AIddKddd’f5UUU$$ªs¹¸s¸222s«\ª«sqqq¸csIKd´´dQd´´dOYˆYˆ(ˆ((6rr™€™€Ôš€€™™((O(!!+++"""
+!+O+++O+O
!!ZZXZXj”™/:-


BBKHB’"Ar
sfss



IKdKdKdd1fU$$$ªsªqq¸q¸22c`¸ssªsªsss¸qq¸{sIAHd´QdQ´¶´ddOYYYˆ(ˆ(66rr6Y™€€€š¼Ôšš€?™™OO(!!!!"
$²""OOO+*+(ZZXjZU(fs²
BAAB’BHr
s¹fs4





AKdKdKKKfU$$$$«ª¸¸¸¸`22222css«ªs\qqss¸2sIBQ´´Q´´¶¶´dOˆYˆ(((66r76(Y™€š€š¼š€==™?(OO$dO+"²””"+D++DDD++OO+*D+*+((ZOZ((6ffss”™

O

AB’´B

ss4




AKdKdddKdKd5$$$$ª`2222cc2cs«¸ssqqqs¸2sHKLABQ´´´¶¶—´dYˆ((666r7666(€™€ššÔ€?=?=O((($$.dA
²””””@
+D++*OO!+++*DD+*OD+++*+
((&&(((96(fs²²€

O

H#

s¹4



AIdKKddKdKKKdd5U$$s`2c2cc{s¸\s¸qs¸q¸s¸IKd´´´´¶—¿dˆY66r767(€™€??=?($...+dO+A
²”””
@D++O!+OO+O!
X(6(²™&
&&O


B´
ssf


KKKKdKKKddddd’d1$s`cc{ª\¸qs¸q¸q¸2IBN´´¶¶dY(66((™™?(d"
"”@@+*+++++O!O
+++
!!(XjZW(s”O&f4IAIKIdddd’’d1Uªª\¸¸¸\qs¸2HQ´´—Y(7(?=$B"A"@
++*O!!OO+*WZ((6ff
SSAId’d«ª\dQB"
+++++!W(f
Bd""""#"#"@+*!d!(Ad""""""###
+!!(A"""!fuff2
{O			H++O
ffuuuuuuuf®c
y4wOODOOO			
		ffsffffsfffssffssffffsffDDffsffsH+Xfu­uu­ufc
{c
{ODOODO!	
			

	0sffsfssfffs±±±±DD
sfDOXDDDOXXXDD!sfL[[[f!+HXXOXj¾jXOX

fu­fu]®
wc
DOODO!

		
000!fs!sfsfssffsOOO±ˆˆ±OOO±ˆˆ±DD
ss
sXXXZXXXZZZLLfsL[[fs!+H+(7XXXOOXXXj
¾¾DOXjOXjf­­c
cwO!ODO

	
	0050



fsDDfsffsffsOOO±}ˆOOO±}ˆD
XXXXZXZWXLO[[O!HH+!O((XOXPPOZjX

¾DDO!jOXuufu]]®
®
OO!ODODO
		
	50

!s!fsODsODO&±Wˆ}±ˆ}
XZXXZZWXOODOO!HH+O!!O(XXsOXXOPXXYXXX¾”™¾DDDCOO!Xu­fu]fc®
c
c

{OODCD!D		
	OO5W!DfDODOˆ±±O±±f

Ofs&ZOWZZXZZLLOODDD!ff+D!! 7XssPOXXOjZjZS!jXjj”¾”™s”OkODDOXOfufuf®
w®
cwcDDDOCDD!XO



O


ffOD!sfsfsO!ffO±

±ˆˆ:O±

ˆ±sfOXXOZWW&XWZZ![L*X!fs+DO!!O X77(sXOPZOZOOOOSZ$j$”s¾µ™”DCOODOXX

]u­u]®
{4	c
{DOCDCDOO!D
	

	
OO
fsDDDOfssfffsDDPf&&
ˆ±&&
ˆ±OfODOZX&WW&ffsL+O!sHO!O!O  X7((r(hsXZOPXXjX$$¾µµODDODO!Xuuff
w5-®wO!ODCO!XO





fOsfsfffsf!O!Of&ˆ&O
fsD&&WZ&&&fsfsO+!HOOsH"O!! Z (hr¾X¾µµ™”DCXZXPO!POXfuufuuf
{5{cwO!ODDODCO!



	sff!fsODsOf
OO±±fOO±±&&O

ssXOXO!f!+D+!!XZ(h1
¾™ODXDXXPDPXX'']ufu­­u]u­®45	{w5{!!DODCCOO!
	




	Os!s¾OssfOO
±ˆs±ˆO
ssXXZZZ&XXZZO!sH+OO!XOxlhh¾”ODDDXPO!O!
]u­]u­u­ffuu®
2c{	4w{!!OO!DDOO!!	





OO
ff
ffOff
O±ˆff
±ˆ
ff
WZWZff
+ " xh
¾”¾ODXXP
uff­u]]uc
cc

w
w{cO!OOODCDO




f0f0ff0f0ZZf0!H" ”¾D:ZOOPDOfu]]]ufc®w{{cOXOX
	

	



f

!H XX
f]ff]f






+

ˆˆYYb2bbb

				ˆˆO¤,b2bb2FKˆY::jjddµµµb2q2bq	
		KKIFFK
	AAL}©SS¯¯:,222b222b2bLLFF,OOˆjˆYˆYW:>ªNHk°jjjd´=bq22	
	KLF!	
	ALš©SS¤Z,:b2bAqbbbKL[KKO,!!OOOˆjjOOˆYˆYUWª>NHkkjXOd52b222bbq
	IKdFLKœ
	
ALµ¤S¤¯%
:sqsb2sqb22bKL[FKKdœ!OœODˆjˆOYˆjYˆUU
2
NH°Xjjˆj´d=52bqb2	


KLLLddLK,!,y

A5µ¯
W/Zqq¸bf3b2bFI[FKKLd,!O,jOOˆˆˆ||YjYˆ,UW#ª>UdTAµµ(AAX!|jO´d=542b2bq2
FKdKd!,!,,yy%%

525¤¯
H/X/:qq£320sb22bLF[IIL’,O,O,,ˆODˆjjUj|S±ˆjjYˆ:,XW::
>2NKKN:AH
޵1((0?0XXXO±j2´dŽ122bbqbq2b%

dKFKKd,œ,œy
%%
%2¬5µ¤
FTW)::*,qb0sbq22bLKLLddI,œ,,œjYXjUˆYˆSDtËjYˆ(XUXW::y5ª>dIZÊN޵°1q6(}Y000?°ˆXjËj:2ddŽ71µbb2b2b%
		KddF’F,Oœœ,O””yf%%%
%2½
HÃ,):),qb2qqb2bbdLLd’KIœ,Oˆj±|OUUˆ(OjjˆU:XW:::W
5%2dI[ZIKNT]
ÏÏZ°1µ1q((–26(²00?jjjjˆ
dŽ7bqbbq
ddKFdL’FF,,,
O²²”²–y5­y%%%
%	¯;;;¬
ÃT:,:b2qbKKdLLd’dKIOœœ
!!jXjUOˆOXjˆX:W:::W5yµ%0dILZËGÓ]u:

ÏZzqp˜6^° ^6A²??jjjjŽ&qbbb2qb2
%KÄdLdKF

!™W²²²”L:5-4	y.ZX 
	%		¯:;T:W/:£qbKddKILI’dK
O!!jˆˆjjUUO±OXUj:::,,:

55yy%0HU}udH1Zzb˜——˜ € –0²0“°XŽq{bbb~%dKL’dO?™?™²”L5y 
y–%	

FF/U::2q£qbƒILKddK
OO!OjjˆYˆ±XUj(::UW:,,j%c#y#
OXO}}6?Z}rT]’ddÏk}}‰fzp——n^–76
A0qbbL’FO[Ldf4
f ­–%%	~
	
TÃ/Wbbb2bLdd’KO!O(ˆˆOYˆYjUj(WU:WW:W5(µc

y}:U}Êr]Tu’:H:k}‰p˜˜A00?0qL’dOO[KKd³f–y–}%%	
Tq{bbLLKd’K!ˆˆjjj:::W(
xycy}}tr7’
’’1‰000
LdO[KL³f–y––%	
FqbLKd(jY:5cy­­yY
222ªÒ


K[[L y––%
y­}:22WZjUWZW????}?????“kZWUUUWZZZ??????OOOf]ff]}r77r}rrgggd????Î?“?ÏÏZ:/ZZOODUW

OjBp222WZ}r}ZZ99Ž???Ž?bbbAAddOOOfff]f]r7r77rgdggg²²??“=Î?“Ä/WX/WYf(OOODDDk,,UZ
WWdd’UqqBÐÑ9}}77}9!C?Ž?Ž???Ž?Ž?Ž2b22bAdAAddODDDOf]}r.}7dg’g’’gd™²²™??ÎÍ?ÍÏ/Ä/WYY(ffO}DOOCDDDkU,#Z
UI’‡’dqqqBÐ9ˆ}}r}O!C-7?Ž?7=7Ž?2b2b

AdAddAdDODf]]]]f}r7.77r’gggd?²²??Í?“Ä*/ZXZO66Y(Yff]]ffOODDOCDCDDˆ#@,
OI’’F’’qq^bYˆ}99OCC-77ŽŽ?-=77=Ž2b2bb2
% 
dAdAdOODDOCDDOf]]f}rr7...rdg’’g™²²™?ÍÄÄ*XZXO

(67(Y(6YYf…ffOOOYYOCDDCDDCCD2Y#,
A’‡qs5f9ˆ}r9!!O%DCCd--Ž??d-=7=bbbub2	dddDODODOODffffffr...r(’g’’g’d7(’d™²²[²qllÌlÄÆÄ*XDDO
(667(]f]f	Yk}ˆODDDDDCDOD2YY#	’ddsAfYr7!%DOD-x--d-x--uuu2bub2%ddd’ddddOOOOOffff(77.7rrd7’g’(7’gg’²[[ql2ÌlÄÄÆÆÆJGD

]……f	YˆUkYDOCDCCDCDODD2Y#Ad’A0b9ˆ}!OOCCdxwxddx--buu2ub
Äd’’dD¶I77r77r(}(gdd’d²[[[LdL[qÌ]2]ÌJÆG	(Yˆ}ˆYDDCCCOCDCDOYDDDb2OOˆˆ€#
d¶ss0ˆˆr9!DOOOdxwxdd-x
-x2bbuuu	’dd’’D7.7r7}r7OL³³ddLLL²q2q2q2GÆKG((((DCDOYDCDOYDDODOD2b2222ˆˆˆjˆ}O¾™¾#	HHs0ˆ}79DOODCdnxx´d-x

x2{u2uu2~
d’Drrr(}7WO™qq2q2qGKGGK(ODDDOY7ODOOODD2sb2s22bjˆj/ˆjˆ¾™€¾™X""	H¶BssˆvrCCDDdxwnddnx­
x-dd}7rk²q22q2pKKGKGDDDDDjjDDODOOOD2sss2U2s2bbjˆˆYjˆYjjj™X"Hd3sYËËÇ(CDDDCCCDCdwx-nnxx-d’²q2pKGKGKjjOOOb2ss2b2bsjjjˆYˆjjˆX	dsq±Çʈ((C²ODODDDDDODd-x-nn--ddd}2qKKGKOOb22ZZjYˆjXXHddÇYˆˆ(9CÀ²CCDDDODDd-´d--KKObZˆXZCCDDDff™™™

+!++SDD&&&&&&&ff0™¨™DD!+++!OSDS

DDDffffÈÈ[A0””™™¨™CPDDDPC

D”¨¨È[[[DDP!!OS

P!DD |OOfufffuuf

’f4ff++++!++OOO”ÈAAȲ²?È?™PDDSDCC
ÈDPPPCȔȔ¨™¨È[[[L[DD|SP”Ȳ+!O



!9! XXjjjOjXOOXXO
4

fffffuffuuu

=
Bf44444++!!!§O§§””È[A²CP”=??DDDDC

ÈÈDCPDSPÈ”¨¨[[L[SSDD”””!O

&&!!!&XXDO9ˆXDjYj4
fuuuu­uf
=
d
BKHBA44AAff4f+++!!+!!OD(§DOY”È[A[ÈCDP™CC||P



”DP|DC²¨¨”[[LLPDC”ÈOO!&
&O&PPDD&& XXO}(DY}X
44fuuuuf%2%KBAHBAAAfffAffff+++!!+!!+Z+D(©DY§”È[”ÈDDC?||PÈÈ
”!DD¾¨”[[L[CPC”O!P!!&&&PC!DO   (}Y9YkX
4fffuu­uff%2%KAKAA!!+++!(((OYDD©(
”È[[””DDP?™¨ÈDDDPÈ”
È!ÈC²”[LL[CPPÈÀ:,!O!!DO!



O  YˆkUYkUY(44
uuuu­­­­­uff’
=
»2ABBAKBAA4ff++++++ZZ+!O§©Yˆˆ}Yˆ}©(

ÈA[AA””PC™¨ÈCPDPPDS”È


²””[L[PC+!O!OOP!O!&
ODD&&!O   Y}O}kU}k}Ok}O
h
f­fu­­u­u2%%=y»yŒyAAHHB’Bf44f++Z++(7§(O©©}YO}YO
ÈAAÈÈC””CDPPt|O””
²CCCC[,DOOPPD!
9&
D&DD/O((OOX9XYfhf
4
uffuuffu
’d’y­­y22
BBddBd’’dAB4f+++!+!++++++(O(O§((©Y

LpffPDPYO””È

²²²CPPDDC”¨ÈPPDP+DDC!&O!!9! XY(XXf
h4u
h4hffufU
mBAAKdddBA++!!!!++((((


CPCYIȔȲCDPCPSD¨¨¨È	DDCCÈÈ”!!OP!OO

&O!D!OXXXX

4	
h

hfffff%NAAAAAAAA(




DDIOƒIÈÈÈÈÈCCˆˆCPC””ÈO,,
ODÈDD²ª²”O+!OOSO!OO!!!&O(h4hhfffAAAAA((


YO}DrJIUYÈÈDÈȲ(WˆW(OZ
GIG
}O²D²›”OrO&&OO
fffAAA(
DDIÈ”ˆD2(ˆ	ª²²OOO«ÈO
&&ffAA(””ª²!
AA69¨IL[LLI++++++++++ffffff!!!!!PPPŠ O69,%,¨¨IL[[LI!+++**++!!+


!!OffffffffX!ª²|SPCŠg²O((96,,%¨¨§¨I[LI





+*!!!+

OOffffOOOXX!!!!O””ª²|SCCŠgfd"D²OO66996,,¨¨¨¨ILLG


+!!!!

!!Of4,O,$,XXO9X!!!!ªª²²PP||PCDŠgŠ-DOD	
²²D!OO66996%,™¨¨§¨¨GIOIG





+!+!!+	
!4		OO!OOf,,O,,,XjX!OXXX!!!!!Oª”ª²²””|P|PCPCDŠ-ff
²²²DOOO696(6(966cc%,,™¨¨¨¨¨¨ILIOIGIIL




++WW+!+*+WW4f!ODOOOOOOfffff,OD$$DjjXOXOX"!!dO!”ª”ª²ª””|S|PCPCCOP’gŠfOD
²²OOO9666(((9cc,%,™”Ȩ¨§¨”¨IILI!LLI



++WW!+O*+W

!!ff
!DDO!D!O!O

Off,,DDD,,DOj9XO!OXX"O44d”²5ª”ªª””|P±PCPPCPgŠfDD
sssfs
O!O—6669'6S96ccyc,,%,ÈȨ¨¨¨GIILOLIIG!


+++O

!!f
CDO!DDO.O!
OO!ff$,ODO$,ODOjXODOjX"ODO""4OOO²²5

²ª²””±PSPPPC|d½ffD

fsssfO!OO½—(6996O9cyyyc,”™§¨§ILO!LI!!

+!OO+
!!
DDCCO!ODDOOOD!O4,ODO$$OXXODDCOj9XLODO"ddd!!O!²ªÉªªª””||SPC!!!Gff


fssfO!O½—6((69((66y­c,,””””O¨¨I[[[OLI!WÄ!+++O+4
ff4

CCCC!O!!!!D!fAf,,OD$$!XXODDXXO!4d4!O!”²

ª²”
|PCODf’---f


0f²²sf4OOO½((66cc­y,¨¨¨OUOUO¨IL[LILI[I
+*!++!!+!O!+44
	4
!DCDDCOO!.!f4ff$,,OO,,XX!OOXXX""!O"4dx!!OO”²ª5
ª””(
PP|CCAD|!dffg-	
fffssfOOO6((69c”™¨­§¨OOO¨¨ILLL[LIILLIG+

!*,*+++!!+!**44ff4f

OCDDDOO!fff4,$,O,$$,!G!XjXOO!Xjj"#"!!"#"4dxOO²ª5
É”(
(±5CdŠ-d!LPf	
4ssf4!69%,,™¨”¨¨§¨§¨GILIIIGGIILIGG++!+


!

!,+*+!!L!!+**44ff44
OODOOC!!.!OO
ffff,$$,,D,$$,GXj9X!XX!Xj9X"#"!!!"#"d44W5²²((|P5ddAfŠ--’PDUDf			


ff
OOD96996',,”™¨¨µ”§GGIIILGLIGIGG+*!*

++*
+**+L!++*+*+44


!DD.!O
ff$$,O$$,6O6j9XODXj9X"#"!"#"4dd4dW:
ªrª(P
55dA)fŠ-OODf


f0DD'966'',,””¨§¨µ¨GGGIGGJGGGI**+

!+!+
+**U!U+*+4f4fDDDD



f44f4,,,$,,,XXXXXXXL!L""Ä4ÄdW}²²ª²²(r=ddf-fD


O,¨¨¨IGGIII**
+**+++

O


f"4ª²5=dfAA(AAXXLLf(.+AAAAAAAADXOXSO[[YYXYX[[L//IIIIIB²BHHHHHYDDDDD4f
4f44KFdKAHdd.(.(.((AAAAAA(!!
 GDXZYZZX!O6ˆ6ˆ[[LYXXYZ[[[L[KXUXUUW//W//GGGGGƒAƒNMHNMt6OYˆYˆYˆˆ
f


4HKFFF!KKKAAd¶d..((AAdA++A GM½G!G((ˆZXW!!ˆˆ6L[K[YXZYXZ[LLKKL[[LKXUWUWW/W/IFGJGJ²AªAHHNMžžHMOYOYDY}ˆY}
ff4f4

IFIHFFFL!dKdd++d´....Ad(ddAAO
 
GG!!MMG!!G*@/*XDZXWS!O!6ˆ67[L[XXOXXXZXLL[[LKX,XXUWUWWW/X/IGGKFJGJ²1²²HNMNMžÄžNMYYOtOY6DˆˆˆYˆkkYY
f44ff4
4f
IF+LIFFOAAIHd+’J´dA..(A+(dAAO
!!G!!MM!G(ˆ((@****@*YYDXSSOˆ7~6[LYXOOOYXZZXYX[LLK,,UXUWXXXUW/W/XZ/FJKFGKIIGJ²ªHNMHžžHHNMžžtYOOYYˆˆO6ˆ}YYYUWˆkkY
f4f
¶fW+WIIFL[IKFKA!IIHG´J¶’´+dd....AA+*dAA! 
G!GGMMGG!ˆ(9(/*CCCOˆ~ˆ6[L[[OYZZYX,,X,UWUUUUUXW/W/ZWW////KJKIKGKKKK”²ªNMNMMHHNHMMžÄžOYtYOtYYtY}OOkk}WUOkk

f+F+LLHK[L[KFKO"H!I!Kdd´d’¶+d(dd((.......(Add*!
GMMM½!('*CDX!S6ˆ6~[[[[XYYXXZLX,,,,WUXXWXXZZUW/ZZWWW/W//KGKKFKJJKGGKJJ²”²1NNNMMNMžžHNNžMOtOOYYtOOtOYO}ˆkk}YOkk}k:kf

4
IILKMIHIIIFHOÀKKI!H+d¶¶½dA(...((A!G!GGMM!½Gˆ(9(**DCOXC~6~~66[[[LXYOYZXX,,,WUXWUXXZUU//WW/W/W//KFFGGJIGKGJIJ”²1NNNHNMÄžHFFˆ6OOOˆˆYYˆˆYkkOˆWkYYˆYkk


ILHJFJJMKHIO"ÀA!Kddd´’¶’´dAA..A(AddAOO!O !GMGGMMGGGM½G((*@DOX
~ˆ~6[[[[OOXZXLXXXWWWXWWXWWUZWWXWW///KKJJKKJJGKKJJ”²ª²²HMHKMNžžMMFˆD6tYD6OˆD6YOkWUYkk}kkOY4ƒLIHFIFFJILIO"À+AH´+d´’´dH(d....AA+(A*AOO!
!M½!!MMGˆ'**/DO6ˆˆ~6LYXXLX,XUXWXWWXWUZWXXZW/KKJKKGJGGG²²HHNHMMMMNMMMˆYOOˆ6ˆ6OˆˆOYOkk}YYOUWY}ˆ


„
ILLKKKKHKO+d+d´¶´d....Addd*A(O

 GG!!GGMMG(9*DOOˆ6LOOYXL[[XXXUUW/XWWZZ//ZXXWKGGIGGGG”²ª²NNHMNNNMMYOOOOOYYD6YOYO}}}ˆ}Ykk}kk
¶

ƒ
LKFF
AAA´d+dH.A(AAAOOOO
 
!G!GG(*Sˆ66LL[OYXX[[L[XXXUXUWZXUW/W//W/KGGJGJGGGKG”²NžžžžžžMžžžYtYˆttˆ6OˆˆkUkkk}}ˆ}k:k



Mž/AAAAAAA.(+AAA!OOO 

!G(ˆ[LL[OY[[K[XUWWUWWWW/,///XW/KGJIJIJGJJ”²NMMÄĞĞMžÄž6OYtˆODˆDtˆD6kWkU:kkkkkk¶

zzpMMž*/AAAAA66OYLK,XXWUUWWW////KKJGJG1”NMMMžMž6YˆDY6tˆ6ˆ6YˆkkWUWUƒ
44ppdFpMJJ*/A6OYY,X/WK””²ªMY6ˆˆkkkk


z[L!LL!!




1311133pp44&.&..&&.&.&&.&”Y(2X[LALPDDPD!LLCCPL!LOD}Y









ttDtt!


UWZZ
1311334pppp4&...&..&&..””ÀYYOSY(OY22222X6[LA[ALdDDDD!CPD!O}YDO}YD"
"


"
tttt!t!f-%9%
44
hhUZW
133s1133sps&.&&&..&ÀÀÀ((ODDOOSSSOI2cac22222O(OX6A[LAdPDDPDOLPODP}YOY






tDtt!tt9%%%

hZssssss&&9&&~~
”²²Àv((SPPDSDDDSLIII222acaac2aa2O(6DX6[ALAddDODO!CPOO}YD



~~tDDttttf---tSf--jX99%h
Z
!sssssss&&&	~&&
”””vrr((vrYODCPDDPDOYLILILIKI22acahhcachha2((YˆˆX,,6LLAAdDOOOO!CCO}}D
"
"


"
~~~t!tDtSXX!999h(ZW!sssszss&


¾””%r7rrv(rrv((ODPCCPPCPDOSOLI[IKH+KI2acahhhhh{{hha2OOYYkkˆOXXX,/XDL[!LAPDOOL!PL!O}DYO







		

D~!!DDf--Stf-Xj!!!
9ZZZ!!13s11szzzss

²¾”&&&v7777rr77v((((YDCCCCPDDOYLLILIKKHHKIcah{{{{{{hac2(YYˆkD6XXXXODDL!!D!"!"LLOœU}D"



D!!tCCD!!j9X!
!1313zssszs
&.&&
ÈÈ””&&%%%rr7777rrrvv((ddODCCPSO(L[LIIIIK+F22cah{{{{hhc22((6OYYOYO(XXXXDX,ZDDYL[LAOPDDDDD
!!LPL!!YD}

"



CCCOttt!CCCD!!ttjj
!XZ(

sssssszzss

&&..&&

²²””&&&&%%%&vv777777rvdd(OPPCCCPDY6(I[LILIKH+FKKI22ahh{{{{hhha(Y6PDOD(OXP!+/[L[Ld[LLDODOLLL!PDCC6}O/O}D"



"
~CCDDDtt!CCt!SSSt9XO
4(W(W(Z(!!zzsss{zss

&

”È”²À&&&%%&vr7777rr(d(YOCPPOY~(ILLILIIKHF+FKKahhhhh{haahhc(6OPOY((PO+,XX[LAdLAAAdDDDPODDDO
O
CCC!C!!CPP(6YD}}Y

"

""~DtOtO~!!tDtCDttttSStt9fO!!WWW(Z(!!!s4ssssz{{p4p
&&
	
””²À(vr7777rrr(d((6~YDOY(66([LIIIK+FK+KKI22caahhacacc(O(D|DOZ,/XX[AdA	OPOPDDO6(O!!!P!!CO!~/}Y/OO
""
""
	

OtO~t!tDtDCD!t!!tt!fStSjX-

!
jX%%%h4
ZWWWZW(W/!444sss{{{444p&
&...&”””””²”(rrrrv(((6(6(((LIIKH+JKIKKI2c2aha22ca(CCDOZ,/X	d	OOO6O!!P!///}~D""
"
!tOOt!tDCD,tt!tt!,ftS

jjf

%%9!jjX9%%h
4…(WWWU/(!ss4z4zsss4p{4{p44
&.&
		”””}O}”²”(vv(6((II[I+HHKIIaa2ac2a(Z//XÄPrD6(
/O
}P/6~/OO


"
	O
~~tCD,!t,f-fj-

%9j%%h…((Z((U/sz111zssz4ppzpsp44&%

		&&&


””²”””²(((IIIIahchCXD(6(/!PO6/6}œ




O~tDDttjj!%X4h44(W(WUssss33sssssp44s444ss44&

/W:

²À”²À((caaa6P~}Y
""~~D4Ussss44s²À(!+CCDDD,,+!DDDOOSOCD~(W,DO,OKJ+!CDOSSOD



CDD&ŽZWW,OWI,O,K+KJ+!!DDCOO
SPSDPODD
	CCDDq&(~(7(¨99'',DOUW,,,LL,,O++U+!DCOOOO
CPSWYWPPSPPDSPOODDDD




DCDDq(~ŽŽލ''ZZDODOW,,+G%,,+K!+!DODOOO
CSCDPDDSSYPPPPPPSDPPDOODDD		


DCCCDCq55››šŽššŽ7¨99,,OU
,,r+r,,,K+K+J&!
COO
CSSCSSYYPPSPDSSOSYSPPPPPPPSSPPP[DOODDDD			
	DCCDCCC›4…11qš¼¼¼Ž7(¨
,,,W
,,
,%%,,%%,
W!++&&&"
DSO

XPYYPDSYPDSYOPSC(PDDS²[LDOODD

CDDDODCCq11121›qŽŽ€¼7&7¼™¨
999
,,,
,%,,,,,
+&&&
SSSYSYWDSDPSPPPPPSPPY(DDSY[LKDDODODDCDODOCCCD›qq11221q7޼¼7&¼(ŽŽ(”¨”
,W
,,

,,,



++&&&&
(SOPCSPPIPPSPPYPPSY((O}DDY²[LKdDDDOOODD		
CDDCCOCCCCq224…15›¼¼7š&~7ލ”¨
9
9





,,

r

GG+G++&&&

(%OWYPPPDSPƒPSSDPPPDYW((((PP²²[[LK³DODOOOD
	

DCCDDOCCCC›q2115	5qŽ6(r~&~Ž(D”¨DODDOYYOLGLG







%%
/~LLLLGGKK++J.&
O%SYPDIƒPPSSPDDPYWPPDD((((P²™²Ld³DOO		DCCCDCCDOC›554	…4›Ž7Žr(7&7(YDO”¨ˆDYDUOUk:W:LƒLL



,


%
+ILLLLKK+JJ&&

SOOOS%XSSSPPDDPDDDD(PW™²DDDOODCCDDCD›554	57(6&.~~”§”ODOUYUL


,



+LL+++J&.
SSSS%UOYWPDDDDD(P™™??DDDDCDDCDq55Ž(6.~((¨Y




ILLL+++JJJ
SO(
²DCCDDCOŽ66¨




I+JJJJ

D(66UUWU6U6UU6LL!!!!!!!!(((fffffkUUUWkUWWWUUkk(f4y44ff(696UWWWWWUU6f!L!L+!!!!!!!CStYtSfffffffffkUW///:/WUUUkkff4yy444fy44ff(6U(6U////U66(fOL!I!!C!+!!CStSCff
fff
fffDD(kW/::/WWUUkk4f4fff444ffff(6UrUW///WU6(54ff![!!!C!!+!!SSC
f
yffDOO(UW/://WUk((4f4ff44444fy4(ffffffO((UW666UUWW//WU((ff5!!L++D!D!CCy
yODDOUWW/::/WU(((((44f44fff4y4ffdf((ff˜˜ffffO996UU66rUWWUWWUrU6f4yf![!SD!+SPP

y…yYODDY(W/::/WUkk((y44ffff4yd´d((ff˜4ff4fffOU66U6U6966UUUUWUr(r6(f55f!![|!+X+!!CPPCCyyy…yDˆYDˆW:::/WU(U(444ffff4yy4d´´df(f˜fW6U6969((6U((WWU6(UU6ff54445fO!!!X!!+!CCCCyOˆODYˆWW://:/WUUUky44yff4fyD*ˆd´´dd(f˜4ffffO96UUUW(((6(r6(UWWUUrrUr544yfffO!++
OYOYˆOU//W/:/WkU/WWkff4fffff4O!DODKXK!!)YAAdf((f˜4fff4ff66UWWUUW(6U((WUU6UU(6(f44f445ffffO!L!+!!
ˆˆOˆˆYOkW/WW//WU////W(fy4fff44f!!Dj
jJFGK!*O!*!YZWWZdAAAAdffff(((f˜f˜ff((UU66UUUU6rU6U(UUr6ffff4yy445fO[[[!X+!CPSSPPCCy
y
OkUˆk6((U//W////WWWWW(fyf4y4

K
GJKZZ!ZZ)
gd´dd´dff((ff˜f4ff44f(U6U69966(Ur6Ur6666U6f44b55b4ffffO[[!!+++CPPCCC4
4yYDO}k}(((U//WWW/WWUkUWk(ffyy4yyyf

GKG*)W-g
-ddddddff˜4f4fffWUUWU6(((66U6UU6U(6Ur6f5y4ffy5ffO![!+CCC
y
…yOkOOˆUDkUW/WWWW((kWUkffy4f4y4f
@W-gdd´´d´(fff4ffUU6((rU(6Ur6(6(Uf555fff545fL!!!++yYUYOOU}DkkUWkUUWU((kUkffyy4f4yf
-gddddf(f6666U66ffffO++++
YkYˆk}ˆ(kkU(kUWk(kfyyyyfyyf
f˜(6((!+ˆUkˆk(U(U(kffyyff22q22
[[LL[dYY}}}}}YOZZ//
yy}}ZZ(O(OS((}(}((!–yyyy((222q2




[[[L[dKY}ˆˆYttY}}}OXZ//
=
»yy¼

((XZ[[


Okk}ZÀ;ÀÀªÀ

(}ˆ((}(!!IIII–yy–y­f.OOO((YY(C}2qbqq2b,

[[LL[[LKdd}ˆYtD}}Z/=
%


’(((X$WXZ[L[[[[[
Ukk}OˆkW”À;À”À;;À²

}ˆ(ˆˆ}(LIILIIA–y–f–­–A–9OOOO(ˆY((OOˆˆr(D(6}Yr(6}YY(}}2q2b22quO,


[LLKILKd’d}YODD}ˆˆZXX//:»%
¼}’%%%((kX$WXZWZFL[[LK[d

(k}}}ˆˆkUˆZW²À;ÀÀª;À”²²


}ˆ}(Yˆ}IIL™²²IdAA–(y­––f	xfx	fOD(ˆDOY((ˆ(rrOrk~((DD(6~~YOr~}~YY~}~%qq2b2q,O!


[LLIKLId’dXSˆYYODˆˆjXZ/X//::	y@?ÇŽ¯1?%%XZXW$XW(WZ[FF[LFF[dd
(kˆO}kUZWW²²²ªª;À”²

O}OOk}}OO(Y}LIf??²LIfAf–  f­yf–ffxffxf(D(O(D(YOO(ˆ6~~O~k~r(CCD}}}~O~ˆ}~Oˆ}}r(q%b2q,œ
%%
[KLLKILIK’’dSYˆYYYYjW/XZ/:?­y“G¯?%%%%Z:XXUZ$W((W[[[LLFK[d
O(k}ˆ}}kWWˆ²ªÀ²ÀÀÀª;À”~

}ˆDD$k$DYˆ}LI³WjZIfI²AffAAf–fy9fxx{{x	f	xf((r~OYDDY~(YO(6ˆ~Oˆkˆ~rDDDCrk/k}ˆ}}OO}U~(2bqqquq,,,!

[KLLLLLId’’dYODYˆˆYYYjUjW/ZW/XXW//WZ,
"y°10¯11??%ZXZXkZW((ZW[L[K[L[[Lddd


O(kZWWkˆ”²;Fª²Àª  ÀªÀ



UYDk}UYDOY}}Id²j™²Ld³[?Aff  –y–y(}f	xf	x{{fOOYYˆˆ}Yˆ}Y((6rYOˆYOkˆ~r(DDCDC66~}}Y}kU}ˆUkY~%%2b2qu2q
O,/O
%
[IKI[[Id’’’KYjOYDYYYYjUj/UWZ/:%W//,,,%j2=4}µ°1µ11›À¯199%WX$XUkZZWZ[[[LL[L[[[L
dd



Okk}ZWWˆˆ”²;ÆF²””ÀªªÀ²$

UYODD}YOYˆ}([IIL[²If²f–Af   y­–­–(ff	f	xf(/O~OkkUkO}YO6ˆˆˆ~ˆˆkˆUYY~r6CCDCDO(rˆYYYˆˆk}ˆk}Yr(%22qqz22,,/,O!
~%[IKL[ddd’dOWYYODDYjUjjDD,/XZ/:W/Z,ZZ
=5"¼Åddµ1›À¯¾¯d9%ZWkZWWWZ([k[[[[LF[[
dd
OOkWWWZZˆ””ª;KÀ²ª;À²À
$
XkˆYOO}YYˆ}}!D[[L²dI?fy:–­–fyDY(Offf{f(Or6rYYY~rrY(r/kˆkUUkˆ~OY~rCOCDO(ˆkWˆOY}ˆkk}}~r62qu›qzD,
œO!
LLL[Idd’’KL(YYYOjUjjDDW:XX%/:ZZ/:,XZ
»24Å’AÀÀ¯¾dý1XZXW$ZW$ZZ((F[[L[[LF[[[d

dSOZWWZZWˆ””ÀªÀ;À²²


$

XˆYYOYYˆ}}(k[[[[²²fy–f  yAy­–
.
fffx(r(6~rr~Orˆ~ˆˆˆˆ~r~~Y~(DOCDO6~ˆ~Ykˆ~~~rˆ}~%2q…b2uq2D,,OO
III[Idd’’dLKYOYjUUjYD(,UX'/W//:Zyyf#f
°HHdA¾d½½d1%%ZWXU$WW$W(KFL[[LF[[ddˆkˆZWWZkWˆO”²;ª;À²²À






(}ˆYYYˆYY}}X!O[[L²™²?y­f–yA–...ff(6(r(~r6~~~r6r~~r(O}DDDO(r~YWˆ~rr~6~}ˆrq››bbO!œ
O!

LK[Kd’’dLLOYOOUUUjY((U/Z/W/:,W4­y#f
HÄQ1d½T½dXWZUkWZ$W[LFF[
d(U/ˆZWZSOZZ(”²À;ªÀ;À²ÀÀ




(X}kk}ˆYˆ}OXX[[L²[™f­ y­


YDDYf(6((66~r66~r(OCDO§¨6Y}ˆ~ˆr6~}ˆ62q›qqqbOO!!!O
NKLIId’’dLKVLYYjUjjOY(/WZ/:W:,:=f
­@NÃHdd½ÃTdZ(ZWkkZZWW$ZWZ[LF[
kkZWZSOOWZ(”²²À;ªª²À««²


(XOOOkˆ}YX![[[²­ ––AA
.

(r(r6(r6(6(6r~66rˆ~bb2q›qbq›DO!O
NƒKId’’KOYjUjOYZ/W::/,:5»y%N9½½Td(XZZZWW$WZZ[[[žF[
(kWZWk}(²²”²À«²


(XXOOOOYXDO![[[™–yyy–y–A

D666(6(r6r~2{b2›qqqbqqOODOO
ANLd’’LKjUjO:/,d2d	y­%½Td(XW$([[LFF[

WZkkkk}((À²²²ÀÀ²
(X(OYXX((Dy–y–A


YDDY((6622›qbuqOODO!

KALj,dd2»
y
TdW$
WW}}À²²À²

ˆX(DA

f]X,,,,,,,ˆYYˆYˆ&!!

f]f]
XX
,//,YYˆYˆ
&
%6(”+!+!*
X+++0000AOO
xffs]	
	



X,/,/ˆYYk




O((((²””OZ!,Z+

+++++(
A0™0pp˜˜O
xf]s]]	





X/,/kYˆˆk




OD(6(²”µOOOXOOO!"+""Z"*/X+
4+f"


o
+XL++!

™05p˜Bl˜!OO


xs]f]
¶
X
,//(kYˆ
6Yk

OOOW(((WU²””™OOOOOO

+!XXZ+XZ+ZX,++4
"+h

"

f+o

XIKHG++!+++
(¨A0Bpp˜pp˜n˜!d1›1›
D
x
s]f]




XX@,/,@~k

6


!UW6(WW²™DODXOOXO
!!!!X'+X""++,Z/Z+*++44"h44
"
w 
 w
f


KF"G!+*$
A0™1500˜lnnll˜ln!!d"dddd
5151
O
f]f]]

—½


X@,,,@~
6~%%DD!W/W6WW(U/W²”µXDXXO
.
X+''++""Z"X""Z,*X+4
4h 4"hh"+ff
w +"
++G"GX*$+$*+



™A05A0˜l˜nl˜pl!!!d""dd555–DD
f]]
—



,@,,,,~'

66~~%%%DO!//WW/W66W/W²™²™OXXXXXOXX


!+X+X+++""/ZZ,"",+/Z/h"
"
 h y	f
f"wo  
o
HGK+GGXG+**
(
™00™s˜˜˜ppnp˜!+ddd"
54%OO4

ss

	——

,%,,@,//YˆYkkkYˆˆ%%%%DO!!!W//UWW/UW//Wµ”²µ™XXXX
.

XXZX++"Z+,+"/Z,44""hh"f"w wow 	x

KGGGG+KG$++!
™A0s0¨0ppppll˜!!d

44
f]]sffsff

——

—

X
,/,,///@ˆˆ~kY6
kk'Yk%
%%O!!O!O(//UUUUUUU//WW™²µO.!+""Z","/+Z+ 
u
+-
n"


IHG"GLKG"G!*$(
(
A15™™A5l˜˜nll˜d""dO

4

x
f
sf]f]]]]]f

——
—
X


,
@/,,,//,œ(6''k
k~'~6%

%%D!O!(/WU(UW(UW/WS²™”

'XX+""Z+ X/X	4+	+no



KG"IKHG""*++*


(
05¨A0A11pppdp˜˜!O


4x%
f]f]]]

.½+

XX

X,œœ/,,/,@œ6''~Y~'~%
%O!!OWU(WWWWW(}S™”²
.
X+

I"GIKHGG+$
(


(0™5115˜ll˜d"O




]

]
½

j,%œœ@//,œœœ(~'6ˆY(~6

&!OUW(WUU(WWU™²™””™
!+XZ++

KKH*$

A15˜˜dd

x


]



½.
%
,


%@//œœ~~(6ˆk((~6
%&&&W(WU””™$05
%




%,%@@//@6~(kk(~&W/%O(UW(UU(”²




%%@@66???=???$????™šŽš??((((6((?fO?42?0??!O?ss?0?=24=?42?0??2O?f20?0?5$ZW$?W$$O?42,0??22??42?0??!ODDD&&AfKK!+5™™™™?™™™OŽšššš?€22?OY(kY6~~kY(XXXXOPDPD?42?0??!ffofOODDD2y44?122??ss44?144=2y42?12	2?2f44?24?0445554?44??Z––5$5–	$2y44,122?2y44?122??244?!O&&????KKA?????+*445554?44™?00™000™šš?š??€4452€?€€?((Yk~~~k~6(jXjODOXDDO2y44?122??Dfff˜˜????0??2??	y20	yssy=44=?	y?4	ff20425(554544?455445?244?	–'5	5?’y2,	2?	y20	42y4??24?(????????????224?????0fK2442?54544?455?0™0?5š??4€?4š4yy455?522((6Y66~Y6(((OXXODX?	y20(CDff˜n…˜ff?242?12	2?2	4?y20?4y2	=2yf5?24555545??5244?24y4???02	5'5d2½,?y?d&	4?y2(2	y?0	4(??42??555™™™™€šš???42??5y52422?2y4K02K?22?5545??55?0™0ŽŽŽ244?€?4š(4y44?224((6YYY6YYY(OOOXDDOX2	4?}CCCff˜…˜f˜ffffff˜?	y?4	2?	4=ys=4y?	4=00?425(00544?4
&?5454?	495ddd?	½?4’d???4?4(2	4?y26442?5452™?==?™€š'9(442?5452?4K- ABf???00??0™0Žš€222??2š(2y4?24((OO(6O(ODOXOOOX?	4?4(DDfff˜n…o˜f˜ff˜xfx˜2	?2y2d´0&?=2s™y=s24f4d5254f202??4y22??02y4ZZ?2Z½’d244?2($$?	4?4$$(?2402y4222s?™?9''9(?2402y4????2?KAB?42??22?f??™0™Žš?24?š(45?2P|O(DDDDXDX??2(CC(fff˜f˜o…˜˜fffffw˜w?	4?2´0242ss2ff40?242405f4?0f42y2y40242?24(W22’?24696??269$6?42?2222ss22ss=9''?42?222?224?22fK242?24?+X2f4?0??2f™š™((OPXOY|DOOOXO(ODDDDO66ffff˜n…{n˜˜fff˜w?22d4420=4ssssy0=y	4s0?2sf4?04y20d2&&2’d44?42f44944y2?242(W45Z?Z422,?4’2220?6&6(6&654??2sss===y5?52??2y44AAKB24+++XX??424?42424?™00™?™š2™2?44(((242™(|±±/±O(±|X/k/XDOPX20?677ODDODO776ff˜4˜…{{…˜˜f˜fww˜24424242024y2s2s22=244y	s	s220222	s4ff44y0fd&’5d&d455yyf4(224??4250224?426~5–5–5W5–5Z~44224,024½2d?442026?20?(64224?422?'42s2244y54?224?422?4:KBK-AB+*??44455yy445?0?0™000™$42242š2444$(625™44?2(((6±(±(±jXjXjDXOOOXOX20(6(DDOD66(fn4…o…{{…n……˜fffw’˜wf04420?24224	0=4yy&2s24=44yy
s4	0?4y	fy4&4fd4’dd4&&4402542204245?244(5–	0Z5s–W(22½44	Z?4y2&d2	0?4222?6&242024&6(44245?242'$=42s522455y?245?242y?BA-LAf+?24244242?5??0™05?™f$šš4242šš242šš$y244Ž2“Ž(5y|±((±XXDXX4	0?42?6DD((f˜n{˜…nn…˜{nffxf˜wfxf0d24244024222?y&22=2y&
(&	2=:2(f444.4d’dd’d504424y222?44y   655Zs(6~~62&2’2,Z2&d?2??424?(&4?0?4y&24y222?20449$$=sss5554yyy222?2yKKBAkB??““?5?Ž“??55™™s$š$š2š’Ž4š$$4y“?™“2yy±(~OXPZ?24422?(?(D(fnn…n˜˜…{˜ffnnnff˜ff?d´s24	?4y4&s.
&('6:&%66fff4fd’ddy42224y44yy ((f(~(&d4,&Zd’X&&4?&2?
44424y4?24y4296'=2ss424y45y4?24BA?“?ŽŽ?y4?““Ž“?ff$$šŽ$24™“9§?(k~D
XXZ
4677D(f˜f˜ff…{f˜f˜f“´d?42?D?42&s&(9(	:'69'6(fdd242y42(5(6d’dd2//ddd2X?2..242?y5..(96?=4%994245?2?AA??““?????“??0fŽŽ6((?/9/?((6~k(/r//2}Of˜f˜ff˜˜fff˜f?“´?02DO24	s	((	69((d444y4–	((dd2,dd4	?D~D4.4.6(??4%9245?2KK?????????0	š(6((““((((~6/
/XX/
/4	DOffffffff0??02//26(((d2444y4(24224y4AA???ššŽ((6/f0?024	4!.&..&.&5X!!O!!O!ODO!f!!OPPPPPOSSSPSS&.&O++!+D!D“““““




55yOOX!!LLLAD!!PPPPPXZXf!(OPPOOSPS%9&OO++++*¨§¨¨§§¨!O?“??O
(
([554455OXXLBI0000022((6PPPPPPXZWZX((SOZWZW:WZZ??D-(((5555y{555DDLILIPPPPPPZXZZWW/!”DD5544{y4555
DDLLAL[LX:WPPZ!+¨§¨”!DPODO(Y55545{{4545

DDLLBLLI,,P!PPXDO,!”!DDDOO-D55454y{{45455DD$XALLI(00PPPXOD!!§§””!"!!PDO--DO554544{{44455
A[Z[00&&00WPPPZOW,!O++++!§§”!!!!!!PPD€D

–Y5y{{4y{{y4{{y5
$A$Z[02(PP!(((XZZ!DO++*+¨¨0!!!DPO]DD-{y4y{{{{{4y{5

AABII&DDDD((PP!!!!XX(O(ZZ+O!!++Af0DSDDO
(Y544yy{y4555


OOOO99AAB&III.DDDD(PPZ
sZ((O(OO(%..XX]+++fAf!1Ž“ŽD
-YY5544{{45455OOOO9&&9&&&/&.PPf
ffO&&Y

(.D&&.+!ffff““DdB–5454{{5455XXX&$&!!
fXXX.D.h!!f
sff““5§“Â^^554555jXDjXX$$!

YXD~DD.D~D
“?h5h“^5555UjUDOD!““5DD.&..&.&’’’B99D!!O	f9O&.&OOOO!+ff’’’’½’““““““ZZXZXZ
BBB99999&9!O!!O!P!!O
O!O!D
f999DDODDD%9&OOOOO++!O!!O!000ff’’??OOOOO??ZXXXZ

OOOˆPPCCDPBBOOSODDOOOOSODOOOOO!+OOXO!OO!!ODOPDOPOOOO!OO!	D!!ODOOSODPPDOOOOSODDOOOOSODOOCDCDODDOODD%DOOO&&DDCDD05O!O!OOO!OO!!OOSODOO’’DXPCCODOPBBB
BOPPOOODDDOO!OOODDOO+!O!!++OODOOOXOXjXOOO!O!DDP!O!OOODO+OO!ODDD!O	OODDPDO!OOODDDOO!OOODDOCDCODDDOODODOOOO!!DDCCCDOD0DODODODOO!OOO!OOODDOOd’’½d’!!OX
(PPCCOBBB-BBBBOOPPDOSDO!ODOSDO+!++OO!!OO!ODOO!!O!+
D!!!DOD	
DOSDO!ODOSDO!ODOSDCCDODOOOODDDODOOO!O!O!DODCDCD5DDDOD5OD9ODXZWDOSDO’’dd’d!OPPXXDDPDPBBB
-BBB!O!OOOtOOtO+OO!XXOD!OOODO!OOOO	DO!!DDODOOOtODOtCCDDODODODODOOO!O!DOCCODODOOOOOOOD!OOOt’dA’Ld!O!OPDO
ODODBBBB
BBBBO!O!OOOOO+.DO!OOOOXjXO!D!OD!OODO+
OD!O!DO!OO
ODOODCCOOODOOCCDCODODDDODDDDDDDA00O9OO!OOO!D!OD!DDOOddAL’’ODODOPODO
DBB-BB-
-BBB-BO!PO!DOO!OO+OO!O&&XD!ODDO!DDDPDODOD	DOOD!ODD!D!DDOZDODC,:DDDOOOO!ODD5DO5OOOO!+++D!ODD!0DPdLd#½½ODODPSOOOOOO!PDDPDBB-
B

-B
-B±DDDODOOD±DDDO!!+OOXjO!ODDOODDODDD.ODDDDDDODDODDODDOPDDOODOD±DDDOD±DDDDCCDCDDODDODDO!!!DDDDOCDOO9DOP+**O0fOPP±DDDd’’’"dd!ODO“O?OOPPYDD


OD!!ODO!O!B

B



B-
B
'!OOODDO9DDO9ODDO9DDOO!9+!XODPDD!!OO!OD)8)!DO)8)	
fODPDODODDO9DDDODO9DDODDDCCCDODDDDODDOODOOO!OO!!O&DCCDDODCDOODODODX*+0DOfDDOOd"’A’’A’’""d!O!“9O!DPPPOOOOX

}(OˆOOOB
B-

-BB



OO!OODODO(OO9OO(OO9O!(DOO!O.O+	DDDDDODODDOPsOOO(ODO(OODDODCDDOODODD%DDDDDDO.!O!DD!.CDDOOOODOkOXO0OOfd½½Add¨½Ad""!D/9/D“DDPYWPPDDZXOOOXX

}(=B-BB

-BB-BBOOdOOD99Z&&&OO/.O!!+DDDDODOODD
ffDDYDOD
CDODODOO&.!&!O.&CDDDDO
fff0d"d½dd"“!“PDDPDDDDXOODOXZZX

5

BBB

-BB-O--d99O9O99OD!DDODOODDOO9OjDCDDDOO&&O.&
DXOOO0fd"dd"““PDDDDDZODXZXZ=}BB--BdO+OODODOOCCOOO&DDddXZ==BBBOODOOODDXddBPPYY““ADOODDDDPPPÈDDOPPPODDD&&ODDDODYDYOYYOYŽŽŽ“Ž“?DDDDDOODAODODDDDDODODDYODYPPÈDDYODOPOODOYDDODDOYDOOOPODDDYDOOODDODOOOOY(DOHADDDODDDDYODDDOYOYDOODO¦¦8³¦³ÈDDYODODYDDODODDO(DDD+OODDDDDDOSODDODOO}DOAAHD(OODDDODD(DO(Ȧ¦8¦8³¦³ÈDDDO.(DOY69DOD(DOOODOYSOYO(?““DO(DOOH6r(k(DDDOODODOO(D(DOYODYO(O(³8³888³8³¦ÈDOODOOD(DO((D/D(DOD++(“DOY“ODOOXDDYDYSXOD(DDODPODDOOˆkA6U6UkDkkODYDDY((rD(&DO&(D((DDO(³8³8³¦³ÈÈDYDDDY(DODYO(DOYODOODD/9D((YO(L*POY“6DrDYOOOXD(?DOYODODYDDODOOˆk9O9AAHO9DU(r(k(DODOk(DODO((YD(((rD(DDOYD(DDO(DOD(DY(Dȳ888¦ÈDDODO(DDDODY(DODDDDDDD/DDO(((K[+D!O6rDDO“6“YDOXCCDD“?DOkPODDDDDO(DOYˆ9DOHA9DO(UrDkDDOD((((((ODDO((DODDDDDÈÈÈȦÈ/&DOO69/9CDODO((K[+++“DO“(OXDXCDˆDDO“(kYDOODO((DD
}DOYBDD9
U6D(kDk&&D((((((D&Y(DODOYDD(DDȳ8³88¦ÈD(&DZPDDODDD...P69(DYDO(DkD((((OODXCSSYXY?D(k(YO
kOO6DO(DDDOAA9
U6DD(OODD&(&kDO&&((&DD&DrDDYDrDOO(DO88¦³8¦³(DDOD(DO&Z&WPDOYDOOPDO&DODPPO6(DDO(O([K””™²²DO“Dr(f0DD0f(6YYYDCSDYYXY?D“Ž““?k(OSDDDD(66DDODDO(DOYDA
6DDDk(YDOYDk(DOYDk(DDODDYDYOADO8888¦³ÈOD
sOYDO(DOYDXWZXDYPOOOYDDDDOODD.DO(DO(”²W™DY(f(0D0DO(f(~Y~OSCOWˆDXY““D“?k(DDOY(DYDYODDOYDY((X(D/OYDOOODY¦³³È(9
f99(ZXDYOP

YPDDYO(.PPDDODOD(™“(kD
OYk((6~XOYˆOXDD“9DO(k“6(DODOODYO(kr/.kDDDUAUDO8ªª³³9(/(9(ÁXXrYPPkkOYP(DDDY6PDYO(/YO(0f((6XYˆYX?/9/Ok(DU}}O}DOZZDO(DOODk&OOD((O(OXDODDO6%6(WWD(6%PDDD}}DY(DO(Dr0((YˆYDD(OOYOYOYDYOYÈÈDYOYOYOY(6DD(6DDDDYYYO(PP““ffff!!OOOOO!O!ffPPPPOOOOOOOOOPPPPPOOO0fff!+DDDDD”””””ŽŽŽ“Ž“?44f

fff!4OO!+O+44PPOODDOPPO|SO%9f0005˜f++*OD
””””““Ž?O4ff
(}”ffff|OO4f4f44f4f),,),4f4SO%%ff4˜f++4ff4f””””?““4DOffff”ffffffOff
ff4f4f4),,,),499fffff4f4””””?““DDU(4fffffff"OOOf4f444f4f4ZXf,,,,)fyy4f4(499ff4ff4005˜ f+ff””4”””4”Àff4((
DU(4fffffff#"OOf4f4f4f4fff4,,,),4ff4f4(6(4ff4f4445f04˜ A˜fff!ff4s”f”À??f4((
DDfU(ff4”ffffffffff##OOf4f4ff4f44f,)Z,ff4%fff46f4494455000f""Aff++!4f4f”f”“?(““(DPPf4OO4ff4”¨fx4fxffff###fff4&((f444f4,fff(9''(C/5,5fA"f++++4??fsf”f””“““(DPDZD4f
Y
§f44ffff"##"f&(.fffdd4fff,,)ff4((ff4f4(f.'''f˜ff
+*
“?ff”f4À”””“f4“DDDDff
Zf}f”§(ffff44ff’f4f&&f4(.f4fDDd4f44f4),),y4ff6fdffffff('9f˜f˜f"fIf+
?““??sfs4
s””f4”²?“Ž“D44Z4(
f4(fffff4xf#ff4444f4d4f4)),
sy(6(f4’dOf94949(f44f˜˜4?fs4”²À”A²²²“f“4D4
4(f44f¨

(ffff4xffnxn˜f

f/4.),,,
f6d’fY44

f44(4f
f??f
ffÀ””WÀ²f“94
f
}

”((ffff4xf˜n˜f
Z/.444,,(Od44..4
f˜0f
²$²²ÀA?/9/
r
(}(ffffff˜f˜ff©©444f4
f4f4f44f44f44(f4fff4$””f44f4(fffff444
4f4W“



5OOOOOOO!O!OOOOOOPPPPPO

O!+Z:XWZXZWXWZjUWjjUŽŽŽ“Ž“?D

ˆ(554 J G JOOOO!+O+

DDOPPO
%9OO++*XXXYYZZYjU““Ž?D
//W//W
(ˆ


554455GJGGJ









OOO:%%
++XXXYjWjY?““W/WUWW:(
555554555IGGG





fWW:99.Z,/


s

jUjYWWjY?““OOUUZj/
554454555IG







W:/WW::W




P99

O+jZ/


YUYjjU@jjY
DODUZjZjˆ

555554554
G





W/



Z
Z








PP









O+
!+ZW



jYYUUjYWj

DkWOjZWW


555554
454455







W

W









:


OPO




9



+
!
+ZWWW



jY/“
YUjWZjUWW/


(
55555545

W:W,W:W

&&
ZW:Z
W::Z

ZW:W

W:W


W
j:W%W:WC/


+++WZZ:

sjYj

WY?“DYjWWZUUWU/:
UWXˆ

544y454555U/j

..

ZZ
GfZZ::


W
Z%...ZX
+*X
sXXZfjY
WYUY“

OD
D/WUjWjjUW


}
4y5
4555





.

DD





W:WfZ
ZWPDP

W








+Z
XYfX:sUjYUW
jZ?“Ž“
ODUjW//jU/




554–4
5555



IG











WZ
s:WZ:WO
jZWW:9.



X
XYYsZWZUY
Z§@W
““
“
DDUUW:ZU


(

5–y55555GG
GJ

/

.
fW:
Y



W
9
9.


...


ffUU/W“9
“DOWjW:W
5

555yy555J
DDJOZ/.




O
O(:


..


0fWW@?/9/?
DWW=r5555555UU











W:





ˆD~D



D~D
UZ““
W/=5555O
W(DOODUj5OOO?BOOOOOODOOOOOOPPPPPOSSSPSS!+DOO,?““??“?OOO(BFBO!!OOO!!OOO!!OODODODOOO!O!!OO!OOOD!OODDOOPPOOSPS%+9[[[!!OOK+*DODOO![OO,d?dIL*O’HOOHˆ(L[FFF˜B!!!!DDdKODKd!!+!+OO!!!+!+!!O!!!!DKdDCDD|ODOL!!LL!SOSS+*!+![L[[K[[LD!DdIdIBL!!!!+LILI’d’LIF*d’d’HL
ILIBFN˜B!!!!OKdD!dK+++!OO+!+!+O!!ODdKCCKK|D|OL+L!O!*!L!+*L[[[[[LLD!D[D!0HIIKLI+LK[[IL,d’dLIFd’A’A!dK[[ILBFN˜NNFBBB••!KdDKd!LL!+!+!!+!!!CLKCKdDDODOL!L!+!!++!L!+*LLL[[[LL[[!D[[!dLKKLd5DD/+LLLILKO,d’d’I[LIODH’H’LH(I[[BBN˜˜B-˜BFB†BmdL
!!DKIdKKLKdK!Kd!!+I!!!CCdLdDODOL+!L+!!!+!L!+LLL[[[LL[D[!LdHHddOD*LKG+LKdKL[ILO#Oddd’ILIFIODODDdHdALˆL[[BBBN˜n˜FFNNBB†•B’dLLKFL!!!IKdLKL!KdKdKd!KKK!LI+!!K!DCL/L||OL!!!!LL!L[LL[L[[[[LLIdA00O!+BGKKddffILL[GI[[IOODDHdA!(LBBNNNAABNFNN˜B•BmB†•’dOLLKKFLDL/LD/LLKLddKd&&KKIdK!LL!!KKKKKLODKD[PdfD!LLL,[[LL[I05O!OKB+++KIdKf[IKfL[[[IO“?d[IKFSPPIL(L!K[BNNNN˜Bn´NNn˜Bm•†•BOdKKddKKdDdKOdDKIdK!+I!I+KdLLLLK[L!KdLDOKdK!PPDDL!!L!KLLLK..[L[OOX!+*f[LKDf/IGLLI,“dKKF“Fdd?“SSPƒDDOOO[L!L!+HdL[LBBNn—A˜Bn-—NBBBm•OLKKLOKIddKIddKDdDODD!+!+KLILdKdK!LL!KLD!|KdOPPDPK!!KL+!+K%LLHLHLHNIKH[LI[[[[O!D+sLLs,IGGIOCLI“+“d“PSSPOODO!O*!!(!!+KLLBBNnN——˜B—˜NBB•GKLKGHKLHGDLLLKLLLKDDODDODD!+!dKLKLddKKd+LLDDOsDOKDL!!OPOOOd!LKL++!+HNHLN´NNHNIIIKHHLII[¾,,O[L“9FIPSSS!OO!D+HHBB˜˜NNANNBBNGHKGOHHGDOjD/DDKddLdddKD
fDOOYKd!K

++KHLLK´HLNIIIKKHH.[D
ffOO?/9/OD
DNBBn—BBGHOOGZ/DKLKdKKDXXXLK+KLIKKKHHDDD!sfO(FFGG*D*D}BB——G¿XZj//
YXD~DDDLLIIHHD!
,(kYFNNBBXDOODDLIKFB!““
BAXZX!!OO[O!”DDDDO!””!OPPPPPOOOO!+Dfsf?“““
OOOBBABZXZO[[!O”””DD!O”””O”POPOPPOOS|%..OO++*DDssf[[[L€?OOYY!!!BBBHA[[[[”²”¨¨”PPPOS.s¾sL[[PDO!BBBBAAHBL[[²²”¨§””CSCPSf¾LPPDD!|BBBHBBBBBB[L”²”¨””PPPO++s¾LPPPD(”BBBBBABBBB""L[”²¨PS*+
¾sKLLLLPS?“DD¨”BBBBBAAHBBBBB"XL”&¨”CS.+!fsKLLKKLSP““DPPD|¨BBBHBHAHBBBB#"&L[§fCPC+++sHLL[K|S?“DDkO

O!¨BBHHHAHHAB"L[((¨SC.sHKL[HLL|Ž“ŽDDDD  ˆ
(”AAAABBB#XZ[.²¨”CP.¾sKKLLHKL[LLLPS““SD  (ˆ”BHBAAH-BBO&.D”fPOO..9XffHK[LLLLMLP“9§?DˆB-BHB-B-B!&&&&&&Y
&OsfKHLLKK?/9/?D
BBAHBBBBDDDSXXX.
LKL““
¨¨}BBHBŽSYXD~DOOKL¨|BHHBBBDB.&..&.&U


















,/,,/XPPP
OOO&&.&"""!+U/WW/

P






5545OO











		











,
@@Z




&""+*




X

|







554

















@X





&&
05"




UX


(55555455






















/











""
X








554455555










Z










05L!"L"+

X





555544555





X





5


!/L
!W
P

|P5555544455555
,




	




	
	$Z,Z,

L!""

!W!W/PP
P|

544454y5555





&&








,,



CC
A02!"
+++
+
ZW/
“

||
||P
55y444455555


















	


$




,/












"L!+*






Z!
W
“




|U|P

(

55544y4555











&
&&









	


Zf$

/@










&&

""I+


Af

UZW/!!
Ž“Ž
“|
|



(
5554–4yy455



X


.
.

&



	
f
ZXZ











&...

""fA


U
U}/
“““

ˆ

5555–y5y55ZOZX/.


	f
fY

%%

&&
&.&
"fff
AUWWœ“9§?





5555yy5y45ZZ’#X


:.
f
XXX%





ffWU/W?/9/?



}55554y5XOO









YX
D~


UWW““

55545






WW5????????$????™šŽš???fH–PP––P–HGHGKGHGGKGHGGKHGGHGKG!!!!!!!!!!!!!2ppp24?42?0??!O?42?0??24??42?0??2O?420?0?5?42?D!$ZW$?W$$O?42,0??22??42?0??!ODDD&&1211!+5™™™™?™™™OŽšššš?€22?PPDDPD?42?0??!¨¨ff4fG!G!GGGKP±±Ç·––P±±ÇÇG		G!!!!S!!]1]1]

2y44?122??2y44?124?2y42?12	2?2444?24?0445554?44??2y44?120??Z––5$5–	$2y44,122?2y44?122??244?!O&&????0121?????+*445554?44™?00™000™šš?š??€4452€?€€?|DDDD2y44?122??¨¨fffffG??0??2?GKP±Ç·			P±Ç·HG			H!!!DXXX|PPPPPPPPPP!!]4]4]

?	y20	4?	y20	2?	y?4	25420425(554544?455445?244?	y2004?	–'5	5?	y2,	2?	y20	42y4??24?????????????2240?????00212442?54544?455?0™0?5š??4€?4š4yy455?522|PDDPDX?	y20(¨¨ffff4ff?42?12	2?HGPÇ–	–	––	PÇGGH		Œ	GXXX|PPPPPPPPPPPPPPp000p2	4?y20?2y2	?2y&25?24555545??5244?24y4???02	4?y202	5'52	,?y?&	4?y22	y?0	4(??42??555™™™™™™™???42??5y52422?2y41021?22?225545??55?0™0ŽŽŽ244?€?4š4y44?224|DODO2	4?}¨O¨¨¨ff4fffff’?	y?4	2HGKGHŒ	ŒŒGG|XXSSS,UUUPPPPPPPPPPPPP!!P0?	4?4s?42?	4?24y00?425(00&2&544?4
&?5452?	4?4?	495?	,?4???4?42	4?y26442?5452™?==?™™4442?5452?41- 02??2+00??0™0Žš€222??2š(2y4?24DXOX?	4?4(¨DD¨?fffff4xffff½½2	?2yHG	KHHU	Œ			UH!!GXS,UPPPPPPPDPP		4??2s™4?24424f45254f202242??4y22??02y4??2ZZ?2Z??244?2&&??	4?4&(?2402y4222s?™?4?2402y4????2?21?42??24f™0™Žš?24?š45?2P|PPDO??2OOD¨?fffff4f44ffff½½?	4?2HG	–	–	–	–HGHU·UŒ	U·UG!XSSS,UUUP!PPPP!PPPPP		&42422y40?242405f4?0240y42y40242?22'99W22?24??	??266?42?2222ss22ss2y?42?222?224?222-0242?22f4?02f™š™(OPX|||PPDˆˆO¨?fffff44xffff½?HHGHG––GH·±··±·GXS,UPPPPPPPP				&420?424y0?44420?22?04y202&&2y44?4244y2?24290?9W45Z?Z422,?42220?	4&54??2sss222y5?52??2y4A004124+++424?42424™00™?™š2™2?44242™|±±±/±±|POPDX
(20?§Dˆ
?¨ff4f44x4ffff½½2G–––GKGGHGGKHGKG–––GG±t±		±t±G!!!!!!!XS,UPPPPPPPP			


242420244224yy024442424202424f44y0d&25d&d455yy24??4250224?42240202425–5––W5–5Z644224,02442?44202242?20?4224?422?'42s2244y54?224?422?040j55-+*?44455yy44?5?0?0™000™$42242š2444$25™44?2(±±±PDOXOX(}20(§OO?f4f444xx444ff½’½4420?2H–P–GHGKGKHHGGHG–P–KH	K!!!!XS,UPP!!PPPP24	0?4y2&44y&&4y24s24	0?4y44y4&fd45dd4&&402542204245?24242020?4y45–	0Z5s–W(22444	Z?4y2&d2	0?42	?242024&44245?242''=242s522455y?245?242y?51-12+?24244242?5??0™05?™f$šš4242šš242šš$54244Ž2“Ž52|±((U±±XXDPXDXX2	0?42?§ODD¨?f44˜f4xff44f½½½2424202424G–P–HGGKGHGHKGGG–P–HGŒŒ–Œ–Œ–Œ–ŒH!!!XSS,UUPP!!!!!!!!PPPP						4

22?2&22?22&&422?:4244ffd504424y222?2044422?224455Zs(62&22,Z2&d?2??24224?0?4y&24y222?2044(''=?sss5554yyy222?2y121W212?““5?“?55™™s$š$š2š’Ž4š$$244y“?™“2y42±(UUU((PXPXZ22?(?¨¨˜n4n˜f4xfff4nnfs24	?4y4GH–P–GKHGHGGGHKGKGH–P–GGGGXSSS,UUUPPPP!!				4&&4&&.:&%y42224y45y4442f(&d4,&Zd’X&&2422?
44424y4?24y42('=22ss424y45y4?2421202?“?y4““?ff$$šŽ$(“224™“9§?“2(((U((UXZ
/Z4?

¨˜f˜ff4xf˜f˜f42244GGHKP±±ÇÇGHGGHGGGHGKGGHGP±±ÇÇG				GXSSSS,UUUUPPPP!!					
22(2:.(242y42"2"5(d’dd2//dd2X4??2242?y5((?244245?2?20012????0fŽŽ“?/9/?“(((PrXPXZ2}?˜fffffffff˜4GHGHHP±Ç·GHGHGHGGHGHHGHGKGP±Ç·HGŒŒŒŒŒŒXSS,UU!!!!!!		4	4	4	(444y44	–	(d2,d4	??D~D4%4%(??4245?2211010	š((““(((((X4	¨?ffff2/KGGGHPÇGHGHGKGHGKGGGHHGGHGPÇKGHGŒP–			–PŒ!!!!!!		
d2444y4(24444y4110ššŽ((f4	4HGHGGHGHGGHGHGGGHGHGGHGHGGHGHGGG–P–ŒŒ–Œ–Œ–P–!!!!!!!!4				!“XXBf]f33"ttÊÊttGMGGGG??+«!!O!O!DDO!!DDDD!!PPPPPOOOOFFF!+DDDDDOO““““Ž“?ZZX

DDBBBOf]fÉ]fttËtË233f222"""ttÊËttGGGMGVMGMVVŽ?

322++++""ËËttËt2222Ù€€))*00«««"°!OOO!O!DDO!OOOPPOOOOO%9OOMF++*ODDD
OOO““Ž?OX
DDBBBBO€€€ffÉff]É]ftÊvtttf332f233f2f##"ttËÊËËMGMGGMVVVMVV???“

322222**++++*++ttÊt2bb2€€€€€€€€+)*+*)+6660001000«;tttÊttt"#""°NNNO&D&&L!!!G!!GD!DODDDDOOD%%MFO++sO?“Ž“DODDBB-B
OO€€€€€ÙÉÉ]]]f]]fttvËtttf3332f333223"###ËtËËvttËMVVMMGGVGMGG

?“??“??“5
22233222



**+++++**+"""tÊtËËt2bb2222€Ù€€€Ù€€+)*+*++((66;000000«««ÊtvtËttË2Ì22222222""#"""ÚTNT&&+!LLLL.+


GDGODDPPOOO99/!MFFO
sfsfODOO““DOOODDBBBBBBB$
O€€€€ÉÉf]f]ftËvËttt323f333332#"#"ËÊtÊvvÊVGMVGGVVMMGMGG


?“Ž?““Ž?“?5
33222222




ŒŒŒŒ)*++++)*++#"tÊttËt2b222€€€)+*+*)+(((60100000««tÊttÊ2Ìb222222#"?
ÚNNNN+!+



!
!PP
PDO99DOM/F/++sDODOOD?“DDDPOOODDDDOBBBB-BBB@$€€€ffffffÊÊËtË223f3333f###"vvtvtËVMGGMVMGVVM

??“Ž?Ž“Ž??“È55




33233




)*+++++*)+*+#""tttËtttt2b2bb€€€Ù€€Ù€Ù€€€)*)*)+)*(6(6(010000««ËttttË2Ì222b2#""?°?

ÚTTNTNN!L

!O
D
!D
OPPD..

D
F/FM*OO+ODOODDODDD
XDODOOODODDDDOBBBBBBB$$+Ù€tvÊËtf32f2f233###tËËÊttGGMMMVGGMMVMG



?“?Ž?Ž“Ž??“È^


2233


***++++))+*+##"tttËËt22bbbÌ22€€€)+*+)*)))))6(6(010000;«ÊËtËËvtbÌ2b#""?°°
TÚTÓNNÚ!



4!D|GD
DOOPODDD
..DDDI""FFMF+O!ffODOODD““DPPODZXODDPXXOOODOD,DOBB
BB-B
BBB@$+++€Ù€fftvvtt2333f2f2233f##tttttt!GGGGMGGVGG


“?“Ž?Ž???NNNNÈ55


23232


ŒŒŒŒ)*++++++*)+*+"###"#ËttttËË2bÌbbbÌb22b€€€)**))*666601001««««ËÊËËÊtËbÌ#""?
ÚÚÚÓNNÓN&&LL:Z&&fOD
!PfOOPCDCCDO%..CDCCD,IF"FF+++ffsfDD““ŽŽ“?PPIXXZX
(DDDDBB
-B
BB
$+OããÙff]fvvttf33332ff2###"ËËËËtGGGMG




“?“????NTTNNÈ55

232
)*++++)+*+#"#""ËtËÊÊtËtb2b22bbÌ222€€€+)+*)*6(6660100«;;«ËËÊËÊtbÌ222###???????

TTTÚNTÚNN&&.L+&.

Gf!OOOPPDDCCDDD..CDDFFFI+*ffsfDDOD“OD“DPOƒDDXOD(}(ODDOODBBB
B-
BBB
$OãÙ€Ù]]]Évvt3323ff3232f2""##ËËÊtttt


?“?Ž????NNNNTN^52233
)*++++++*+*+"""###"tËtvËtËt2b2Ì2b2222€€€Ù€€Ù€Ù€€)+**(666660100«;;«ttËÊÊ2Ì222b#""##""??°°°???


ÚTNTNNTÚNN&&!+.&DD


G!O|GfDOOOPPDPDtOt%%%...DtOtMIMF"FIF+ffsOODO“DD“Ž
“DSOOXO

D(OO
OOODDBBB

-BB
OOã €Ù€ff]f]Éftvtf3333ff2333322#""###ËËËttttt





?“Ž?ŽŽ?NTNNNNN55

222


ŒŒŒŒ)*++*+++)++####tttËtËËt22222222€€€+))+)(6(60010«;;«ËËËËtËÌ2222b##"???°°¡°°???





NTNÚNTT&!WDD


G!Os!OGODYPOOOOtO%99%%OtOFFkF
s
:D!“OO“O““DXDDXO(O}(DOB-BB-B--!+OãÙ€ã€ã]ÉÉ]tÊt23fff23ff3f#"##"ËËËËËÊtt



“Ž?Ž?Ž?NTVNVNN555
232
+*++*)**+*++"#tËtttbbb2€€Ù)++*66(((100«;;«ËËtËÊ2Ìb22222b2"#??°°°??



NÓÓ
&&j&&O
/&&D.
fOYt
9

td
ffOOO“9§
DXOXZDD
}(

BBB

BBBBO!++JÙ€ÙÙ€É]ftËfffff3322####"Ët?“?“““VNVN”^^55

*+))*++)"#"ttËÌ€€€+)+)(((6(00««««tËttÊttÌ222222222"#???°°?





NÚN
Z&O:.D
O
OXXXO~

O
~d0f!?/9/XZX(O}OBB

O+€Ù€]ÉtËff3f"##Ët??“??TTN

))*+#"Ët222Ù€€€Ù€€€Ù€€*))*)+)***00«««ËËÌ22222222222#""????




N
ZZ:/
OYYXD~D
D~Ddd
““ZBBBBOO+JfË???N

+)*#Ëtt22€€€€€€+0«««««««t##"""?°°°°°°°°°°?DOODBO”002000fAAA000?0000(6(r¼¼((((¼(231"BK˜VXrX””((((}(042002404ffuAAAAHAHAAAff000000000000%
dd((6r(r7r6(676¼(6¼6¼6(¼(622fff00KBKgVV%’d(**XrœrX(((}}}(}}}((5	5
5	ff44u4ffufAAABHAHBBBHAAff0?0?00?0000?0?0’

76rr7r7677(“6¼66Ž666“((˜-ddf ff˜˜B˜VEEEd((((+))*""XrœkœrXd(((((}}kk}}kk}}(0025{	4{4f@4u­­u44ufAHBdBAdBBBBAA24ff4200?°?0??0????0@%


%4
’

L(77..r77(6¼7¼6666¼666¼76(--˜L˜˜˜B		’@%wEE
%Ed((“((())*)))""XrœkkkœrX(’((((}}}kUUk}kUk}}(404	44yy24254uu­u44­uf4uAAHBBddB´dBHA24f4ff000?µ?0???µ?000
@
Œ
Lf77.....776¼¼66¼6¼676¼6¼(d
-´-0LKBKB		VžEwƒƒE((((“(((f))))*+""rœkãkkkœrX6’’((((((’((’(}}kkUUUkUUUk}(02
4
yyy4y2y{0u44­­4uu­fuffAABd´B´´d´´BAff444f00?0?µ?µµµ??000%
@@

2LL§¨§r.......7(“66¼¼¼66¼¼66¼6(
x†-BBK[L[Bg				E%wƒŠƒ
Ed(((““(“((f	))**""œkãâãkkkœrX½((((’’½’(((½((}}kkWWWUWUkk}}20444y{yy4y2400f4uuu­­­­­ufABB´´’’’’´dHf44xx400???µµ°µ?000%@2[¨¨Z§§L6r.....66(“66¼77¼¼7¼6666¼ 	@

--	  ˜[K[g			’E%ƒŠŠEd(((““°““°“((ff4			)))*""kkkãkkkkkœrX(’’(((’½½½’’((’((’’(}}kWW/WUk}}}(0yyyy{{{yy442fuf4­­­u­uf@4fAHdd´’’’’B’AAf4ffx44f00?0?µ°°µ???000%@@%%
2
%4IOPSt¨Ifr......776¼7¼¼¼77¼7¼¼66“	
 @$BBB[KKKLg	
		’%ƒwŠƒ%E’0((°“°°°““(“(4ff44f4f4ff		+))*"“kkkkãââãkœr(’½’((((’’6((’½(((½’}}kUUWWWUkk}((4y4y{{{{{yyy450044­­uu4ABB´’’’’Bd’HAf4444f000?µ°°µ?°?°?0%@42{­’
[CCCCP¨I77.....7((66¼¼77¼¼6676¼(
@
{@
´†- ˜BKg[LL˜K				%wwƒŠ’d((““°°°°“°“(444)))+""“kkkkkãâkkœ((½’(((((’½(’((}kkUUUWWUUkk}(04y{y{{{{{44f2{u­u­­­uuAdB´´’’’’dxff4000?µ°µµ°µ??000%%
@@%4{


4¨DCC[6........7((Ž666¼¼7¼6¼666(
44o

¶†-f˜[[[KK	
		
	%E
ƒwŠƒ%’((““°“°““((fff+))*""“kkãkkâkkk(d’(’(’6(}}kkUUWUkk}}y{y{{y{y2y20f4@4u­uu­u­44fAHBd´d’’BAf4f440?00??µ???µ?000%%
@@@%»
44f¨C¨L(.....r((¼6¼67¼¼6666((4oo4

-df0B˜LLB	
	
	’%E
Šƒw@E’V((“(“““(((f		))*"“kkââãkk“d(((6((((}}kkkUUkk}}(4yyyyyyyy50ff44uu­uu4f4fAAddBdBdBf0°0?µ?0?0?0??0@@@%


¨¨rr77.r7(66¼6¼¼6666¼74oo4@010KLKB			V@ƒƒEE’d(((((“(“((


		)))“kkkkk“(’(((}}}kkkkkkk}}(04yy44y{44u4u­44ffAKBBBABBBBBHAH4f0000?0?000?0%%%
%­Œ2[IL6777.r6(r7(¼666¼66޼((¼¼44-221KK	V%%%EVd((((((0




	))“kkk“d((}}}}kkk}}}({40y2y225f4fu4u4f4fAAHAHABHAHAAf0000?0000000%@2
d(r7r777r(7(6¼7(“66Ž6“((5310KKBKVV%@VEEVd((((

++“k“(}}}}}}((02020000200ufœuf4AAAHAAAAAf2420000000d
2(7(67r6rr7r(6((¼(((¼((¼(??“(001110KKBBVV’V’d(0((“}2000f4ff4fAff000Œr(6(rr(((((6612µ(0s00˜KK˜’’ddd”[p[p[pÛppÛp
p£p‚‚ËË6[p[[p[

£p£z£z£pz£TT‚ËÊSSSSy(6(6(0(4

z££0p£p£“‚M‚T(vËËttt622(7(6((rr((76(60[p[§44
£z0z£p£?“MJ)Mtjt§(oËÊotËÊtttËS»2’y%677(((7r(6(67(7((76642s%%0pÛp§%%(4%%4%%z£s%%0p£p??%%“MM))##MË)˧%%(tvËËotËvvËtËOS
y22’²™I(6(7r77r(6r7r(((r((((

III


02s%%0[p[#§(6%%(4  %%44%%z4y%%1s£p??“=?%%“?M))ž´M##MMtËt§§(“%%(ËvSËËËËtËËtS

yy%%y5™OZj?™d(77(((7r7.7r7r((67((r77r(7(67(6767(66

GIGIIGI{
{
{{s442s,#Ç446(p³ 4q333¸0p??44=?“MMžžVMž)Mt§g“•(ÊvtSvvÊvttËtS
	
’y»»»’»?™™³™7.7(((r77(76(7.7(((7.76(((6(667(GIG


[p[›2204s,,©6#(4,³p "4›yy
y°==“4?´ž´ž‹JJf˜	g•vvtSvÊvvËtËtS
	%y?f™((7(((((7r(r7r((((((44GIIpÛp›¸¸¸¸¸,#6##³  ›¸¸¸¸¸?°ÅÅÅÅÅ´žžVžž^€††‰(?vvtSËvžvÊžÊtS	
»%™Lr7((r7667r6(7766I[p[)³    ##

??“=?%%“?ÊvËËžvÊvÊžS
2y»²Ir((((r6((r(6(([p[)³pp   g#

??44=?“F‚

Êvt
ÊËËvÊË	
y(7(((([p[pÛp,p³  #


°==“4?TFT‚tÊvËt
ËÊtt

		(pÛp[p[p g


°ÅÅÅŰ«3«‚


tËËË				[p[pp;v;

«;«+ËtttµµµµµµµµGGMG00000
++
tË+ËtjjfÌ??°×µAAAµµAAA??GVMGGGMttt+¸++««0fAAAA0?000f


++
ttËt++++AËAjXjttf]ÌÌ]°Ü??AAAAµµAAAAA++++GMGGGGGMËttttËËtÆ++««««««		«¸++¸¸««
(0000002HAAAAHAA00?00000Af



+++


ËtttËt+++++AttttËËËAAjXjX)ËtÊËffÌ]ÌfÜ?°°??AAAAµµAAAAA?+*+*++ÆMGMMGGGMGMttËÊËttTtt+*ÆËO+*««¸«?««¸	
¸««+««+¸«¸¸


((((2000000000fuffHAHAAAAHAHAAABABAf0?µ000000?0000?0
	ff

++,

tÊËtÊÊ,+++++++XAAËtttËÊËAAAtqqq¸««,,,vttvfÌf]Ì]]f?ܰ?????ܰ°?AAAAµµAAAAA?ÆÆ+*+Æ+GGMGMGGMGMËËvtttTtËt+++ÆÆË*Æ+«««¸«???¸¸¸
	
¸¸+¸«+¸¸¸«t
t}((((}(((}(0400000000042000020f4f44fAABAHHBAHABABdHAHAABBd´A-ff?05??00000?µ0µ000µ00000?µ00ffff
+++,

ÊËtÊvtË++++++,+XZXAAtËtËvËAAAt«qqqqq««),)vtttÊÊtfÌffÌÌÌf°ܰ????Ü??AAAAµAµAAAA?+Æ*+++ÆMGMGMGGMGGMÊËvËtTttt**ÆZY*Æ*ttt«??««¸0	
	
¸¸+¸«+¸«¸
Ê

Ë(k6(66(k6((((6k(0240000200004200040uf4­uH´dAAHAAB´BAAAAHd´´BAHAAHB´´dBf--0?=?00000?µµµµ??0000?5µ?00?µ5?0   ffff
,,+++,,

ÊËËtËÊvtË+,,+++jZXZAAAËÊvvËAAAvË«qqqXq«q),,),,vttttvÊ]Ìfff]Ì]°°°??°?°Ü??AAAAµAµAAAA?*++Æ+MGMGMGGMGMGMÊvtttTtË*+ÆÆË*+Æ+tËË??«11Ë		

¸+¸««+«
Ê

Ê
(6/6(((}k/Uk}((/6(((6/60{00024{y44200{00002{2004ff42­u4u44ff­f{AB´´HAHAB´¶¶¶´BAHAAAB´¶´BAHAHB´¶BHAff--f0?µyµ?000?µµ5=–y=5µµ?000µ–µ?00?µ–µ0  

	fff
,,+++,,
ËtvËtttËvËÊt,,++,+++,ZXZXAAAtËÊÊAAAAÊËqqSXS«),,,),vtttÊÊ,]Ì]fffÌ]fÜ?°??¡???AAAAµAµAAAA?jËMGMGVGGMGMGMËÊtËtVËt**Æ*Ë+ÆÆÆGtt???Ëj		
	+¸¸«+
Ê

Ê
(U6((66((6U((((6U6(00y0000220002y0002y200f2fff­ufufy2fH´¶BAHdB´dBAHAABABB´dBABHAd´BBA--f0µ–?00000??µµ?µµ000µyµ0000µyµ000
	fff
,,+++,,
ÊvÊtttÊvËË,,,,+,++,j,XjAAAAËvËAAAAÇ«qqvStqq),),ÊËttËÊU,ÌÌff]ÌÌ¡??°?°?Ü?AAAµAAµAA?VGMGMGGVGMGMËËËÊTtË++*ÆË**ÆÆGMË??tvM

	+¸+
Ê


Ê
(k((((((k((k(024000000042004002ff4fuAB´BAAAHAHAHAAHAB´HAAABdBAHAff-000?=µ?000000000000?=?000?=??0   
	fff
,+,


ËÊvÊttËvËttË,+,++++,XXXXZAAAAËAAAA«««XSt|Xq«««)),,)UËttUU,fÌff]Ì?°?°???AAµAAAµAA?MGMGVGGGMGMGMvvtTtË+*ÆY++ÆÆ+VMt?tV?			++++

Êb3bÊ
(}(((}}(0200000200200u224fdBHHHAAAHABABAHABAHAf0?5?000000?µ?0µ?00

fff,+

ttÊvËtËvtËËt+,,++++,ZXjjAAAAËAAA«««vjËXXq««««Ë,,),UËttU,ÌffÌf°°?????°°?AAA

5AAA?VGMGGGGGGGMGMGMvËtTË*+ÆYY+*ÆMMG?MV°		++++
Ê3b3Ê

((((0000000002ff4AHAHHAAAAAAAHAf00µ0?000?00?000
ff
++

ÊËÊËÊtÊÊËËt,,,XZXXAAAvËAA««««jj«XX«««ÊË),,,,tt,,ff]f??°°?°?µAAAA?GGMGGGGGGGGGGGMÊËËTt,,,,,+*XËO+GVG?MG??°		
++),)


),)0000ffAAAA0?00000000
f

+++

ËÊÊÊttËtËt+	XXZj+AtËA«««j«t«X««Ë)),,,f?°?µ


A?GMGGGGGGMGGGMtttTt,,,,,,++G?G°??°		++),)


),)0H00000

Ëtttt		+JZXJ++AttËËËtËÊËËtËt??


?GGGGGG
t
,??##+,)


),A0000			JJ+J+JGJ+AttË??


?

,,,?##

		J+J+G++ËËË????		4Of4f4


22O!ff4x4x444f

,23AOXXOOOO!

(f4xxyx4xyx4%
























































X//d--dOAdd%




XZDO!OOOO!O



((  4yyx4xx4x4f%%%













































#










XZ//,AOOOOAYOOAB%%

XD!O!O!O(O
 



}("""  f4x­444­yxf%%%%
Z
,

yb˜b˜y
  
XZ/,XA,,AOOBAAABd%%



DO!OO!O9(!
 

(k6 "@@"f4x44­4­x444%%%%
Z
,
	
ybb˜˜y
##
ZZ,,d  dOYOAAABd’ddd%

OOOOOO!!(99(

 

 


 
 
 
(6/6(  ""f44y444xxf%%%@%%
Z
1,1


	
2b23
##
ZZd((­OABd’’

X!OO
fO


9




(U6"@@" f44xy4­­4x4%@@%%
tZË

;;



	

22

##


  ZX-AA-d


Z,D!
4!

49(!OOO
 
















(k(( @@  fg4x44­444yx%%@@%%%%
ËËËË
10


  
 dd
DjXDOf
4


ff4y!O










(}("@@@"f4x4x­4yx4%%%%
vtË





y y

 


A-



DkXZOy

4ffy



(  " 44xyx4yx4f%%



00

ddZ4y
44

 f44xxxx4%%%






f


f444x44f4f%





ZZfff4ff---GGHHGGIIL!LI!Imm´      

 ´m m
	




	
	


	




	
	


	




	
	


(6(r				

	







–
bÛÛÌuyyyyyy]			




		
	dd(dd-dddd-dddd-ddHGGL!!II´   
  
 

  
mm	
	
	
	





	
	
	
	





	
	
	
	





((6r(r7r6(67		
	



yyyuÌÌyyyyyyyyyy
		


dd((-----ddd---‘-ddd-d---dddH!DD!DL     
 
  

´
	



	
	

	



	
	

	



	
	
xxx76rr7r7677

		

		

yyyuc–yyyuyyyyyy	
	
	dddHddd¨XXXXk((9(d----d--dd--‘gd--dd----d--dDDD  
  

   

 	
		



	
		
		



	
		
		



	
	x%(x(77..r77(
	

	





yyb¬yyyyyyÌÌyu	
		
AdAdAdKHdd
¨¨¨OXOXOX(kU9(d-d--d-dd-d-d-gd-dd-d-d-d-ddd-DDD!  
 


  

  
	

	




	

	




	

	



x%(%x4477.....776



	









cuÌuyyyyuuÌuyu		
				AAH%AAH%AAH%QKKH%Hd%%%
%¨¨OXX%XOXX%XOjj%X(kUk%U9(OO%OOO%OOO%OOO%Od---d--dd---d--dd--dd--dHDHLDD!DL´  
 
  
  ´	
	
	




	
	
	




	
	
	




}%r.......7
		





uyyyyyÛuy–yyÌ	




	AAHG%AAHG%AAHdQd%QKKHHNH%H%%

%
:
%¨¨¨¨OXX%XOXOZX%XOjjZZj%jkUOkWk%U(OO%OOO%OOO%OOO%Oddd---ddd---dd-d---!!!D!DD  
   

  	

	



	

	



	

	



4x%(k6%%46r.....66				


uyyuyyyyyyy
yuÛ



			
		
HKGH!H!GHd’’GQdQKHžHžQHH





://
¨¨§¨§¨¨¨§¨¨§¨·¨¨XˆOˆXXOZXjZUˆˆjjj(kWWWkUOOODOODOOd-d-d-d-dd‘d-d-dd-dd!D!D!DDD!D 

  
 

	






	






	





x%6/6(xr......77	
	


yyÌÌÌÛÌcyyy
uÛ				HH!!!HGH!!!HGHGKKH’ddKHƒƒžQH




::W/
¨§§¨¨§¨¨¨§©¨§·©§·¨XˆOˆXXXZXjZˆˆOZj((kOkWkODDDODDDODDDD-ddd-‘dd‘d‘-ddd-HHDDHGLLDDDDDLI´´

 

´m



	
		





	
		





	
		


x%(U6%477.....7

	








yyy

yyÌÌyyyyu
		HHHQ’’’QdKQQTTQd
:::
¨¨¨¨¨¨¨XZZZXZZZZZjjˆZUUkWUWUUOOO-d---dd-d-dd-dHHHDDKGKLLLDDD[I[´´´   
 ´m´	






	
	






	
	






	
4(k((%46........7(
			




yyyyyyyyuyuÌyyyu
		
	
	d((-dd------ddd-‘dd-‘-‘--ddd--dd---d--ddd-GHHHDDGKGHILLLDDI[ILm´´´

  m´m´	
	




	
		
	




	
		
	




	
	44(}(x(.....r(


	






	yyyyyyyyyyyyyyyÌ	
		

	ddd--d-dd--dddd--dGHKGHDDGHGGIL[ILDDILIIm´´m´ 

m´mm
		


	




		


	




		


	



 (%%rr77.r7	
	









uyyyyyy–uyy
yu	


			
		
				-dd-dd-dd-dd-dddddGGHGKD!HGGHGIILI[DLIILImm´m´

 ´mm´m
	





	





	




x%%%%446777.r6(r		


	





	

uybyyÌÌÌÌÛuyccuÌ				d--d-d--d‘-d‘d-gdd-d-d--GHGHHGD!HGHGHGILILLILILILIm´m´´m 
´m´m´m
	

	
	




	

	
	




	

	
	



4%4(r7r777r(7(			

			
uu¬yyuuuucbuyyy
	

d------gd---‘-‘gd-d--d-KGGGHHG!!GHGKGHG[IIILLIILI[ILI´mmm´´mm´m´m´m	



	


		



	


		



	


	4xx(7(67r6rr7r(6(	

	



		


uycyyyyyyyyyyy

	



	
	

		-dd-dgd-dHGHGGHGHGGHGHGGGLILIILILIILILIII´m´mm´m´mm´m´mmm		







		







		







r(6(rr((	
	
		


	Ìuuuy

yyyyy–¬£			
			00))),??0000?00000000),Wt????°?°??Y?000B?B000000000000000,U,W°	Œ?¥???¥¥°	?ttYODYOOOOOOOODOOO??0DB?00000¸0000>200tËv˰°	Œ¥?¥=Œ5¥?vËqqYO
YDOOOOOOOOOˆOˆOˆOˆWD
OOOOOˆ“?“O&DBB00000¸000¹–>220t,tv?ŒŒ=??Œ––¥	½"Êvq£qq8£jODD%%ODD%%ODD%%OOO%%OOO%%ˆOO%%ˆOO%%ˆOO%%ˆ//D%%%%%%%%
%DD%%OOO%%OOO%%ˆ“?OOOBB0s%%0s%%003%‘¸000¹ºyb20Ë,v˰?ŒŒ?ŒŒ–¥	#½½½vËq££qq££qjjDDOOO%%OODDOOO%%OODDDOO%%OOOOOOO%%OOOOYˆY%%ˆOOX}ˆY%%ˆOOOYXY%%ˆOOOYˆY%%ˆOD//D%%%%

%%%

%
:
%DDOOO%%OOOOOOO%%OOOOYXY%%ˆO“OOODOO??000s%%0s02s%%0s0›¸¸3‘%¸s000¹ºº>8–bs00tUvt°°ŒŒŒŒŒ?¥?	

#"#½"½ËÊq££q££j

DOOXZOODOXWOOODOOXZOOOXOXZOOYˆZWˆYOYˆWZXYOYZWWZYOYˆXZˆYOO}ODWWD














://
DOOXZOOOXOXZOOYZWWZYO?0O§-BDO&&DB0s420s0s442s000›¸b£¸3¸00002¹_h8£8–b00ËÊÊtt?°?ŒŒ–°¥¥?	

""##"½½½½tLjÊʈvvq88££q

OZWWZOOOXWOOOWXWXOOWZXZOYˆWZˆYY}XWZYYZXWZYYˆWZˆYDO}OD












::W/
OZWWZOOWZXZO?YZXWZY?00?L§ZBDO?00›s24ss›2204s0›¸bb¸3000¹_hh88	0Êtt,tttt¥?Œ–??°°

###½½½½tvvÊʈq88£OXOOOOOOOXOOOOOOOOOOOOOOYˆˆˆˆYYˆ}}ˆYYˆˆXˆYYˆˆˆˆYDOOOD





:::
OXOOOOOOOOOOYˆˆXˆY000L™ZBDO000›¸¸¸¸s›¸¸¸¸¸›¸¸¸¸300¹º>>>80),t,ËvU),)Utt°??ŒŒ––?¥°	#"#½½½½½vtq888£?00000000000,ËÊÊvW,ttttË¥°ŒŒŒŒ–Œ–¥¥?
##½½½"vt£8q£8q
00Ë)vtË)),Ët°°ŒŒŒŒŒŒ	ŒŒ?¥	###½"vtq8£q£q

,UËtt,,t?ŒŒŒŒ?Œ	ŒŒ–Œ??#"½Ët££££vËtttŒŒŒŒ?Œ??	ŒŒ=?"qqqqtttt?	Œ??°¥??°????ttt??°?OPDDODC!O!ODO
DO!OOD¨!
O!!OOO!OO!OPO¨!OOO!DO!OODDD!D!OD¨!PP!DDOD


D!O
PO¨!
!D!OO!
D|DOPD!O!OO

OYO!DOCO
O
!
Y


!OOD|D:666<<<DOOP¨


O




O
DO!DOSD::666<<D
CD¨·¨(X
O




O
OOO!DOSD:::66<<<
P(©
©j
O






O!DO|D::666<<<


CC(§©§









O
OOO|
::666<<<


P¨(
!



!
::6666<<<










:666<<<

000		[[²(©99©

000002q	
%%
L!!ˆˆˆ6LL[[[[[XX,/'²²™ž|©99°µ
0000D00	0022
%
""!L±ˆPZZPˆ6ˆLAAI[[[[O,XXZœX™?² 6N
|9¨§§§¨9°



0?O02	02c
%

L!!!±±ˆPZWP±ˆAIIdd´KFOO,œ,ZZ!Z,œO//²™–ff fy(žN
s
(©¨§¨²9µ








00?
0ODO02	2c2
%"±±ˆPZˆ±±LId´¶dFO,,Z,,,,Z$$œ™?²ufssy–6(N©9¨²9©






0ª
?0D0c2
!!P±ZZW±IAAAIOœ,/œœXO$œ²™?04c –yf
©'²'°











0?ª?00	"!"!PPZZLK++AO,œ,jXZ²[5]gyf™
99'@9O



0000D0	2
!!!!PPOZWˆLIK***IO!!!!ZZ,'œ[f[ff(™
AY©d9ddµD




000		22%%%LL!!POZZˆL[Id+—¶II!,,!CX/,'X'[[LLd³[f–ccf6›
AY©99'‡9°O



*+*
00002	c2		
L±OZZWW6ˆ[[[K+**´KI,CXZXZ@,OZœL[[Lfd[–y­­y–(€™NT|}}´BB9©°5DOD++*00022002c…c2


ˆOOtˆˆˆˆ6ˆL[[IFKKKFFKODD,œ,WXZ,,,@XZLdL³fL–yyyyy(ˆš€™sABNTNN

©´B²9µo°DO
O**0c…c00c…c2


±
6ˆP±OOˆ
IIFT
FKODODO,œXWXXWœ,
Z Z
Ldy–y­..š
šˆv±OsN
||Y©¨²²B"5°DD+*Dª		




OOOœ,WZ,WœW––­y..

||Y}9"oo°ooOO+DªÖÖÖÖÖÖÖÖÖÖÖÖÖÖÏÖÖÖÖÖÖÖÖÖÖÖÖÖÏÏÖÖÖÖÖÖÖÖÖÖÖÖÏÏÏÖÖÖÖÖÖÖÖÖÖÖÏÏÏÏÖÖÖÖÖÖÖÖÖÖÏÏÏÏÏÖÖÖÖÖÖÖÖÖÏÏÏÏÏÏÖÖÖÖÖÖÖÖÏÏÏÏÏÏÏÖÖÖÖÖÖÖÏÏÏÏÏÏÏÏÖÖÖÖÖÖÏÏÏÏÏÏÏÏÏÖÖÖÖÖÏÏÏÏÏÏÏÏÏÏÖÖÖÖÏÏÏÏÏÏÏÏÏÏÏÖÖÖÏÏÏÏÏÏÏÏÏÏÏÏÖÖÏÏÏÏÏÏÏÏÏÏÏÏÏÖÏÏÏÏÏÏÏÏÏÏÏÏÏÏ



Y5
5
DÖÖÖÖÖÖÖÖÖÖÖÖÖÖÏÖÖÖÖÖÖÖÖÖÖÖÖÖÏÏÖÖÖÖÖÖÖÖÖÖÖÖÏÏÏÖÖÖÖÖÖÖÖÖÖÖÏÏÏÏÖÖÖÖÖÖÖÖÖÖÏÏÏÏÏÖÖÖÖÖÖÖÖÖÏÏÏÏÏÏÖÖÖÖÖÖÖÖÏÏÏÏÏÏÏÖÖÖÖÖÖÖÏÏÏÏÏÏÏÏÖÖÖÖÖÖÏÏÏÏÏÏÏÏÏÖÖÖÖÖÏÏÏÏÏÏÏÏÏÏÖÖÖÖÏÏÏÏÏÏÏÏÏÏÏÖÖÖÏÏÏÏÏÏÏÏÏÏÏÏÖÖÏÏÏÏÏÏÏÏÏÏÏÏÏÖÏÏÏÏÏÏÏÏÏÏÏÏÏÏ
GI!!OOOOIGJGGIIIG0?0000	



o	
!!O!O!DDO!!DDDD!DDO!!O

OOO!O!OJGGGFGFFHKG44??00??DO4			





cpcc

	o!OOO!O!DDO!O!%9!+OO
CP”OO!!OO***244!G!OOOOGJGFGHHHKIG4???	4DDODDODD!DD!DOO					


	!!







co
c
­{wO&D&&L!!!L!!!%%++*G!!G%:CCCPOODDdKODKd!**¤“cW/KGM2424u!G!!!!IGFFHKHKIIG0?4	4DDDDDD,DDDO


	f!(Y
(




p{4c
f­f	{w&&+!LLLL.+


+!LLLL.+99O++/!GDG$:CÈCCCDD!OOKdD!dK**
¯©“¥cjZW/YOY6(KGKMG2;24u¦4X/!G!DY!IGHHKKKIIGD0?4y44OO!O,!DDDO(
f
	O
(((		coucoA	w+!+



+!+D99OO!
!::%PP¨§0¨OO!KdDKd**¨
¯¤?“3¥“YZW/œ/Y(Y((6(FKGMM;0224uuXZ!!!ODOFHKKIILGJDD0?y44OODSDDCD				DOO






c
c5
foAf!L

!O
!LD/++
D
!O%:%ÈPP¨DP??”O!O!DKIdK****

¤?¤?¥¥cYUjZ/YY6Y(r6KIFMEJK02;u44uXXZ/G!OOGKILLGGJ™?0?4ZZD!DOP	,
	,
j,:

2cc
AAo!



!DDD
*OO+4!D|GOOO–%5::%%CDSPÈ”D™C!OO!IKd****+++*¨

¯¤?3“c¥YXjZW/œY(Y(ˆ7rIFGMJVG00424u2X/Z!DYFLLGGHJ4400DZ,DDDCDDCDDPO

		f
		
		




	
p5cfAff
&&LL:Z&&&LL:ZCDCCD+O!,fOD
!Pf
:%-%%	%PPDSDC”¨ÈO!D/L****++**

€¤©“¥“¥YUWZœ/œœOYO(6r7FKFMVEE;2244XZ!!OD!G/LGLKGDD444?4DDDDDDDC!C!DO4
	

2
p-p{u-{02c

Afww˜
&&.L+&.

.L&.CDD+++Gf!O-"-"""""OD5% 
y%DS|P””dKOdD**++****

¯?¥“XjZUW/6Y(67ˆ(KFKGJEJ02u4Z/DDOZj/LKGDDDD444?		4!DO!PSPSOOD!	
													
	






5c5uc	f{{ccfffA˜wo
&&!+.&DD


+.&DtOt%%+*G!O|Gf--"---"

D::4:: :%C¨PD,KDd++***

©©ZWZW/(Y(6(FGMVJ04ZODDODLHK/440		!!!D||DO										
	((						-pcu
p-{	Ac{scfAA˜ff
A&!WDD


!OtO%99%%+G!Os!OG--""""""-""O%:::::CPCÈDOD***!D!HLKG040444™DD!!DDDOOO
						4					
					Y((Y		

		

	
f	®4w{cAf­f­­
&&j&&O
/&&D.:/&&t9

f""""--"-"DD
%$:%%%C/D/*/GK[GGH4			yy?!ODDD!ODDDDOO

			Y(	
		
c{c
c{cAf

ff

­­
Z&O:.D
O:/O
~
""""""--- :%:CP/*!GGJH!!!!	


{c
ZZ:/:D~D
""""-W//DOO

]ÌÌff]psss2ssssss2sssssSO



]uufÌÌu4fu]fÌss2222sss2ssssssSSSSSSS0µµÜÜܵµ0		


		
???!

f£pÌu]uÌ]4fÌ4uÌs2ssss2222222sssOOSSOSSS0ܵµÜ000µµ0		

		???
!!fsqpfÌÌuÌffu]Ì4Ì]2ssssss22sss2222OYO±SS0Ü0µ00		S




	?°???			!,,!+
f]	jWSYq£0DfuÌfuÌffffÌ]ÌÌs22ss22ssssssss2OY±SSSµµÜµ00		!O±s	?°°	!

!D!,!+,


f]	XjZDOYO[LL«sq¬qO!XfÌf]4Ìff4]Ì]]Ì222222ssssssssssSY±OSܵ0µ00		±sA?°?		O!

!P+,!+,

fu	{
jZUWDOO(YOL[LIFKIqs££O!!]fÌÌ]Ìf]4ÌÌ4]Ì2ss22sssssssssssSYOS0µÜµ00Aq°		!O!




D+,	!,,


fu	{
XjZUZDODOYˆ([LLIIFFq«sq£qODO!XfÌuf4]Ì44uf]uÌ]ssss2sssssssssssO±S0µÜ0µ00"s!O


!

DD+,	!,

f]f	{{



jZjZUSDOODY(([LILIIKsqq¬£DO!XXuff4]Ìf4]]Ìf]Ì2ss22ssssssssss2±O0µÜ0µµ€¨	XXss¤“(O6I22X!!ODD




D!+,	++,,,


]f	{{


XjZUWDOSOOˆYˆL[LIFKF«ss££qO!O!Xfuf4]ÌÌ]Ìuf]Û2222222sssssss22S±0µÜ0µ0µ!¨€	

	
	UXUOˆLLILsq£O!?§§cj/YO6rME4¦2,ZO!O


!!,!+,,


f{{



jZjUWUSODY(OYKLLFIFFªqq£q£DO!Xfu]]Ì]ÌÌfuffÛs222ss222sss222s±OOµµÜ00µ0	


		XOOUYOOYLIq!DD§¨¨©ZYY/ODD7GIIJ004XOOOO!
!+,
!!!+,,



{{



ZjZZUWSOYˆY[KLIFKFª£q£!O!X


u]]44uÌ4fÌfu]Ûss2sssss22222sss±±S0ÜÜ0000000		
	jWUWOYˆj[ILFsq£sO!O
"¤?¥“jW/Y6rFEME24¦uZ,
,,,	!+,+,







ZjUZLIKIF£q


Ìu]4]]u4Ìf]]Ìss22ss222sssssss±0µÜ0000µµ0	
jWOjLFsq!“c/Y7FJ2uX
+,





fuf]44Ìf4ÌÌ]uÌfs222222s22ssssss0Ü0000µ000!	









4]uÌ]u4u44Ì]u]³s2s22sssss2sssss0ÜÜÜܵµ0		







4444ffÌ]f2ss2ssssss222222DDDDDDDCCCDDDDD!DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDODtD!!O	D!!O	D!!O		D!!O	D!!O	D!O	D!!O	D!!O	D!!O	D!n!O	D!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	D!!O	9tZ,

O!O!D

O!O!D

O!O!D

-z´(C-zC°

O)))O!D

O!O!D

O!!!!O

O!O!D

O!O!D

O!O!D

O!‹n‹O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D

O!O!D
(¡¢05+D!,
	D!!OD	D!!OD	D!!OD	-°z†(C-z°	D))OD	D!!OD	D!!!!	D!!OD	DOD	D!!OD	D!‹‹‹‹‹OD	D!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD	D!!OD
jUYˆIL3DOŸ W}6MžfyODt,OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	C-°C†(-z°	O,,DDD!O	OO!ODDD!O	OO!!!!!	OO!ODDD!O	OO
DDD!O	OO!O2]2DDD!O	OO!ODDD!O	OO!DD!O	OO!%DDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	OO!ODDD!O	
UWY&FIO!

XX67ž‡X,ZODt+:
D!!!DOD	

D!!!DOD	

D!!!DOD	

	

D))!DOD	

D!!!DOD	

D!!!D!D	

D!!!DOD	

D!

!DOD	

D!z¬]zzOD	

D!!‹n‹DOD	

D!!OD	

D!%%DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	

D!!!DOD	
+++(X4XZ,,Xt+*,	DO!!O	!D	DO!¨!D	DO!!O	!D	°"(-#(-z	D,)!O	!D	DO!!O	!D	DO!O	!D	DO!!O	!D	DO
O	!D	DO!2¬22	!D	DO!‹‹É	!D	DO!!O	!D	DO!O	!D	DO!!O	!D	DOZ!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D	DO!!O	!D9Z4ZX,ZD!*Z
OD!Oa!DO!OO

OD¨O

O,),))/),)OO

°"(-°(-Pz

O,),!DO!OO

OD!O!DO!OO

ODDO!OO

OD!O!DO!OO

OD

DO!OO

OD!2¬zz2O!OO

OD!O!DO!OO

OD!!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!Z!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO

OD!O!DO!OO
+XXX…XXX,X,
X+t+,	DOODaODD!D!D	DD	D,OD)O,D),!D	°"(-°#-z	DOOD!ODD!D!D	DOOD!ODD!D!D	DOD!!!!!D	DOOD!ODD!D!D	DO
DD!D!D	DOODz\\O	

!0O	



	

!!!,O	

!O.O	

!.....O	
CDDDCDDDCCDCCDDDDOSDD

	

		O!OO!O!O!GLILIKGGGGGKLKHI[IIIII[D[LNFIFIKIIIIIKLFNLLKLLOKIKK																																																																																																																																																																																																																																																																																																0000000555	DO!!O	!D	OODCC	DODD	DO!!OP	O..U!	O.
.!	O
.!	O!	O!	O
<8\\!	D0\<0O	

	O!!OO!	OOYYYX!	O.b....2!CDCCDCDCC			
		
	

	!DO!DO!LIKIKKHGGGKLIKLG[[[LIII[[IFIKIKKHIIIKLIKLMKLGKKGIDLGKKGKKGKKG																																																																																																																																																																																																																																																																																																0000555
OD!O!DO!OO

D!ODCC

OD!OO

OD!OP!DPO

D...WUO

D.
.O

D..
O

D	!

DPD
<>
DO

DZ0WO



D!O!DO!O

D.OYYXX.O

D.2.2s2bO
DDDDDDO



		

	OHHI!SIILOHHKIKHHGHKHGKKIKHKI[LLIL[LI[[[L[FKHHIHKHIKKIKHKIK[KKKGJGI[IIKGGGKIKGKGJJ																																																																																																																																																																																																																																00000555	DOOD!ODD!D!D	OOO!O	DODD	DOODPODDPPP	O...U:W!	O..!	O...!	OOD!DD!D
	ODD
DDP!	OZW!		OOD!ODD!D!	OOPPPX!	O.ssU22b!DDDD


		
		ODHII!SPILLODHKKLHHGGGHKIKHHGHHLLLIIIL[[LLILLFHHIIIHKIKHHIHHLLKKJGKGJGLIIKGKGGGIIKGJGJGJG																																																																																																																																																												yyy	000000555DDDDDDODDODDD!ODCDDDDDDDPDODD
DD...UWU.D	
D.......D	
D...D	
DDODDODD
DDPPD	
DD	
	
DDOD!DODDD	
DXYYYX.D	
D..2..D	
DD	
		
				
OGI!SGLOGKIKGGGGGKLHHGGGHK[IIIII[LLIIIL[FKIIIIIKFHHIIIHKLKLGGJKKLKLGGKIKKGKGGJKI44444000000005555DDOD!DODOD	
O!OOPP	
DCDD	
DDOD!DO
D	
	..U.	.	.	DDDODOD(	DDP			DDDDODOD	......	.CCCCDCCCCCDDD

	
			HD!OIIGOGGIP!SLLGSGGHD!OKKGOGJGKHGGGKKIKGGGGGKI[LIII[[[IIIII[MFHIIIKKIKIIIIIKGKGGKGGKG444444444444000000000555555	DDDDDODODD	DOODOP	DCDD	DDDDDODDDDDODOODDDDODOODDDDODOODDDDDOOD
DDDODOODDDDODOODDDDODOODDDDODOODDDDODOODCDDCCDDCDCDD
		
		IIHGGGJILLIGGJLKKHGGGJKGHKHGKKHHKHGGGKGIL[LI[[LL[LIII[IMNFHIKKHHKHIIIKMKIK4444y4y44000000000005555555DDDDODOODDDODOPPPCDDDDDDDDODOODDDODODDDODODDDODODDDODODD


DODODDDODODDDODODDDODODDDODODDDCCDCCSD
	
		
		GIGGGGIGFFEGGGLGGGGLGKKJGGGKJGJGKGFJEGGGGHGKLHHGGKHGKHGIILI[LLII[LI[LIMMHGKLHHIIKHIKNM44yy440000000005555555555DDODOODDDODPPPDCDODDDODODDDDODDODDODDODDODDODDODDODDODDDDDD
		
					
	GIGDIFGJIJJGIJGGLGPLKGJLJJGLJGGJJDKJGJKJJGKJGGHGHHIKGGGGGKGHGILILL[IIIII[ILIMNGFHIKIIIIIKMNM444000000000555555DODPCCDODDOD



















DDDDD
		
			GFGEFGIGJIFHGGKGJKGLGJLKIGGFGEJGKGJKFJGKGGGHHKHGGGKKGHG[IIILL[LIII[[ILIFMMGFHKHIIIKFMNM000005555CDCDD						EFGHIGFFHJKGILGKKIEFGJKGFFHHGHGGHGKHGKGHGGGLILIILI[LI[ILIIINMNMGFGFHIKMNMMM1121121224221121121224220010101010102222222200101010101022222222


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	6002010101000121022224322222002010100000121022224522222



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	((((696(&0000200002010022422<322422000001000020100224225522422$

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					(96(96&10010;10021000010100288283232420000010010000001002252=525242$$
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							A!A!B6666$:$010;1;110110211;112122328333322200??0?101100??0?001225255555222@$																																																																																																																																																																																																																																																																																																AAAABB9((9((0101;1;1;;11210101;;;;2;11222838883322201000?0?0011101000?0??01122255===55222$@																																																																																																																																																																																																																																																																																																696(996(&010111;;;;1;;1120101;;>>>1201142223338<883334301010?0??010211201010?0??0101142225555=5==5343$$@$$																																																																																																																																																																																																																																6(6((9(6((&&$:$1211;;1>;1;101211212;>;>>;;121214423328<8<38<3341211010?0?0101211212210?2?012121442552=5==554334$$@$$																																																																																																																																																																(9(669(6&7$$::$$1011;1;1;101111010;1;;12;11242423338832<4510100?0?00011110100?0?0001124242555=552445$$696(6997::010101;1;101101;;>;002222323883324301000?0?01011000?0??02222525==55243@$@(((697$:$01201;101010;0;1002428388<822330120010001000100024255=5552233$(6700110110101101002232322823220011010010110100225252252522$000112101110011202242242322322000112100000112022422423223220010111010010012222332432200101010001001222235245220121000120233433201210001202334332			

	
		

					





		

	
		







						
						

	

		

			

	



		

	.		

	.

									
	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


	


			

	


		

							

	




	

		  	

	
  				
	
			
	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	



	


	



					
	

	



	
.
	

	.
									




					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

					

	

			


	



. "

		
.
,,#"			
											


							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
							
								
	


										
	


  %$			"
  %%


,,"",/				

							




																																																																																																																																																																																																																																																																																																
	
	
	

				

	
	


	' .
"	
 .	,,,*+//										

																																																																																																																																																																																																																																																																																																	





	
							
			
	  $$
	
	)#
 
!",,!#-	
			
				
																																																																																																																																																																																																																																					


		

							

	






$$$% 
	#)#

%% 

*+""								

	
				
																																																																																																																																																																				
	
	
			

	

	&$''&	# 	&%&
		(!						
	

			
	
			

		


	

	
	



			




	





$
"##	


%
			
				
	
							
						
	
		
			
				





			
 
 		

 
 
		!"!#"					
	

			
	
					

	

				
	
						

	


			
	

	
			
					

	
					
		

		
			

	

			


				

	

	


							
					
							



	
	


								






	
	


			


			
	
				
	


	

						





	
	


	

			





								
		
	
		tome-235-src/lib/xtra/graf/16x16.png0000644000076400017500000063214511012107762014636 0ustar  dgdg‰PNG


IHDRpCáÖp²PLTEAAA+++\\\žžž‰‰‰sssºººÏÏÏüüüÿÿÿÿÏÏæææÿÏÏÿ‰‰ÿÿÿω‰‰AA<ÿÿÿ‰‰AÿωωAÿÿÿÏωÿÿÏÿÏAÿÿÏω‰Aÿÿÿÿÿ‰AAÏÏAÿÿAÿÿAÿÿ‰ÿωÿÏAÏAAÿÿÏω‰ÿωωÿÿÏÿÿAA‰AAÏA‰ÏA‰ÿ‰Ïω‰ÏÿAAÿ‰‰‰ÿÿ‰AÿÿAAÿÏÿωÏAÿ‰A‰ÿÿ‰AA‰AA‰ÿ‰A‰sA‰Ï\+AÏž‰+ºAÿ\æÿ‰AÿÿÏÏAÏÿ‰ÿAÏω‰ÿA‰ÿAAÿ‰ÿÿAÏÿ‰ÏÿA‰A‰ÏÿA‰‰Ïÿ‰Ïÿÿ‰ÿÿÿAÿA‰ÿÿ‰ÿA‰ÿ‰‰ÿω‰AÏÿAAA‰ž‰ÿÿÿÏÿÏÏÿÏÏÿÿ‰Ïÿÿÿsÿÿ‰Aÿ‰‰ÿAÏÏÏÿÿ‰ÏÏÿÿAÿAÏÿAÿωÿÿ‰Aÿ‰ÿÏÿAÿA‰‰AÿAÿÿωÏAÏA‰+ÏAÏÏÿÏÿ‰AωA‰Ï‰ÏÿÿAÿ‰Ï‰ÿ‰AÿÿÿÿÿAÿÏAÿ‰ÿ‰Ïÿ‰ÿAÿÿ‰AAAÏAæºÏÿÿÿÿÏÿÿAÏÏAϺ\ÏÏAÏA‰AωÿAÿAAÿüÿÿÏÿÿA‰ÏÿAsÿÿAžÿ‰ÿÿÿÿÿAÏÏÿæAÿÏÿüAÿÿÿÏÿÿ‰ÿÿAAÏÿAÿÿÿ‰ÿÿ‰‰ÿÏÿA‰AÿωÿÏÏÿÿÿÏAÿÿÿÿÿAÿωÿÏÿAÿÿÿÿÏÏÿ¦Øš	pHYsšœtIMEÕ
71¡öÒ: IDATxÚì½ÿsÇ•'XU™YYUdèrwšÍ.©%JÅ&Ñh5`‹²LÓh©Áá„?ØÒöé¨[EyDiætw³»Úój57ÞÙ•oîö¾xwÇ»«¹³ãNóÜwŒ¸¸Ÿgþ˜{ïe}É,
@¤dÙ¨D£Ñ¯3+«ºQŸO¾÷ò½LË.§TX©ðR®ÂðBJ.éâ|HÇÃJ߃?øðDpJœöƒðôéÐß÷üwêgg=áûÐÁÜ)ït8œ>„ss!4*µ÷|·]Öj{n¹½×ÃÁ¥àøŠÛp=Ì–Ì‘_1¼XWz®À‡p]lEµHŠˆÚ«Vµgðù¡=|ššt=õ
>…ëáçññ‚¡üü¢øüð‰„BMˆ_÷ûtœô‘¾dIýÚ·³XU9Ùå¡	À¸#šàÙu
.ܶÒå€B€—¢ž¬¾
‚Ó^p*ðÚ!¾øŸÁzÆa®~ÊŸ;5žOss§Ëí=¯†L;õjÐÄhЇÄ?R€#úE¶$Ⱥ
ÿžÈ²EDZ„íö6ÒãPƒ3q8à¿&¡=péó¸t€yøä"ÿü~ˆ%ÄKšð|§„?Vúz9ÒF^\Ní³'làdOôW}ÿR=ÉŠªòÛ&¸ó9!@Ò`HÈìã3*‘¢k¡”tô)σqÞ©	5½¨›áÜLXŸ«‡Á)€}Êo6ÍöµZ-íÈuAp¡€9Õþôi€§׃'ϘÈfܱ:6³",-],!WJ·Á]7qLíUKÀ~z´‡H|gÃC5ûø©|â=Ïüüˆ|Ò
„âÇÂã·ÂÓÍ&¶µ–ˆ[ИÀ5·uö4	[Áé³M8È>
hÄ^
üK?¹¥‹ÀÅQé§Qs¢¼w:±+#F~GÈ(éDÜ©Á€áµÚÕð0ú<©	¡úÐ??)þˆ|ÔO ¥ãüCÞ…'$‡t"=AðÛIÎ'@ËIüaðW˜W̪W#EÈühÝGÀ¿È›Þ°™¡|x÷*¨Ê#%üPV0€(€F))É„&sY( ËÃí†2kÚ3´o<Z.)+jü÷•¿/ûüB}~ü˜jüôC@89
Ðóˆe¨ ÓÐ&ÚöÈ«‰}:påûC
Þ±|&ÐÆïßNgXáÙFŽƒ#I“ŽÒQXïÂ	\tB¢{Àsá‹?€8)!<¿)*ùäÈ`G?¥”ÂØJî*©ŒVÀ'bÈŒÔO5 ½ƒ/ff	/0”Òoxê´?7‡¯^< ƒÓ­Ço´ÏP{¿&Z­öù'Ûq}
оõØãͳ`œagïšè€ë±‚„.tKº~rç“ÊÂx·ñDÔéõ:5œ Ë,ét’ˆ¡åÀeC´ñ“ÅíÆÅÌ™‰ŸÇ	Dñù=úüDt¨ï‡sÈ>ŸåS ݬ(P6¡í|¦Yøý“ (ÀB
ÀV~ǘ8Ê%˜œ,@8k_Rg¬­)€L
o_P÷Cq‡Tò	’Ú	H·½ŠƒÁ‡`ŸNR¡Í,²Nýå´äÀœÂ° _Ì*Úõgðw.8øá	uÐæ@W8}¦Ý<ÓþfûñKSkŵÖív«†‡?ž>Ólžižm>~É÷æN¡Iì8pà¢ÀÌ¡9Œ5ô€­îÁè¯.šó(Žã^¯‡*ŒÊ€¿( s!‚ñ•Ù€µZ»Õ^\|¬Õ’ôq=Wÿ<åÏ/ö¾RàÇAB¦³÷ô}ÚÙœW¨¶ej¸äçãv®óÛ™EQ`„ KD8Dy‚	ržÉ8Ë0oÃì;àg%½A*ùÉm PÓW@jÐqÕø‘€©fœýðsê4zý„F5ýÌ̪ù4¾^÷ëÁ(õù9/Ax¦õxëñ§Îµ›ÔÞ-ø­'â¶÷æUÿÔÙfB{´¬‘Pÿçx=€#äÔÿ^^NþSLŒ’QÜAÀ÷z1"î(Þ‰ =÷ÜFë±'žh÷Û5Àš„«VG{jPH‘}~šEè+"4ä«©ÑÔZMþ‘Š!’®ÒÞñR•Òº£ö¨Š &`) gxÅ)J‰4(šp!j9Š	$MÃÀ·_‹j¯ ’)¸éý@ Ð>z¡å§J5²é	Ìzxu
£dAn@„þº
‘
Ây´päçæPê¡=˜û—o¶ŸÀö.EƒP‹A?€ú³­K5ÏžóæBT~Ñ&W †ö\¤Sã}hŒâhH弋œFG*1">!‹0gá¥lµž|¢ÑªµÛµ†§¡ÀIˆ†gŸßKC}
ðñAòCk£\áÊõŒÓoYàŠä*
(†ÁLÿS`?b68%``òÑ	C¿[óg`”òësá©zèÏy³õS^ ÚŸiaû3—àpšˆoa^
ŒxsÐþLÛŸ¹ä0°â0(\ò¢IpƒÎpt˜Q$ Ä¹{þÉÆs$kQÔ¨
4è6È"²£¾‘[kþ[µZ£¥b•ó€O”?¿ŠÊ\ž>ÎügS{™Àôï–Ó¼'%;ý§X™ ÉHX˜zDç³À?ÃÁkæ8Ó „Š'&߃çÀÒö'€ 
DÌnJ>9òÃÇT0Ž;¨ø+}=ÒÊà§Ñûˆ8{€C¹çŸÞÊèÒN«û€ç9Êýðt0¤í[g°ýãŸ!ü{h€*šAÚ¾uÛC½GáÇjˆÅ Œìg2M¥Ag …ëª!“{ðGŠˆó²@”F²°s๭†D£¡U£8€ôóP0v!ÜT Ï>9œþ£`h™Nâ+0ªïÓ6€,™)¤Xyüïl)}VjÀ;p™8ÿo£¢åq—i“j@8ŸÀÎtôY¥
ʾNÀ ÀÐ/wUòÉ‘Þ	¨bàEzÿÓèO±ø„7ËHjúÏO…0V†³§¦ÿ¼©ój`àôŸ€Ž†Áì\Ú~æÒ´Ÿ™=㉀,1¸åªöPí¡ïrÌ pDÀ€ç€êOq\ù•¥žzíÐꔿ„í
hOoMƒñƒ`žœ=GcŒÁÄO£(žýÒçit%ÁsèdÑüê²é•÷Ÿe`;¹’À³oÜü£ÿä:T]1åNÄ)NœÐ KÆ”ßÐAÃÇV±C.¼)Pccÿi@º!´i¢J>1òÃ;–òŒGÍd^ Ò€¿ÓB`ä;†<ëºä2C pCxÚó0½íÿ¹¹}Ú×\å‡d†—Û”qrs)ÜÇ¡Á=€”NÜ)Ežp,Íö*ÛFG†Š³!Ï&÷0vÓÉõ—}W¥©L`õùÉõGJ€â4TŸkÉ:ŽìÔ2Hãýݧ'åíbHçìœ(RR‘éÜlT£
Éý>q*Ï"”¿O®ÌÛ÷j/Ëð£ž\4bÀ8jø0Æ;Ji‘4ÇÁ¥ÚÄP®-%3]<TåëHçÐF¼aÐKÞ>•íÌ	æ¤õJÎòâÔäËsh±}±Þ–린@¿QÆ5lžVœçR@òšDüg@
ÏE
2s.3d˜Ú#îÏe,@}éyÒé—pD‡#Ÿï?àî“KFóo?ûíoçÛh¤í	ÿE{%«ö¨0,/¿°¼¼œ¶„ƒf߆Wž>J|„©„ëä9Ò*¨ÊoŸÔŠ–Û¿=èi=¶G¬ÄítÞ<—Õ4X!gÓfÙ/ÏGôT¦·TîmžA‹ÀG´ã3zdxñœÊ·¯!Ì"¨ëÇá¿9mÄ?¶.;åËqºHg›0Ù&-Çs´èŸG€±Çsžÿîói´ÑhÑ€È
 ©}¿~Šö$_)ÚÃèÿP´Çd«˜ÃßvÚdÐZG8çÊbLf0ò·ãïÉøœü^Œå°Yž
|ù 2YUüj–è¢bÜS•žRÝiõÊÝUW1¯L“¿ëõj=‹”mÇ29MŸuT’
 Ä&‚Yx•€h…ÖÛ\ý¹TéWhÅÙ—O×	¾•}ÞøÜ¹vœOã|ùr;ÎMu±^}ÔþŸWø_]ž¡*ÒóKƒç—–¸ƒ
ôÏ"¾3\VÚ>â¿_´Ïå¬ý2éƒ!´w¤pdÛ˜ÇNîÒ¡õQ@žsÛçb°Ú¼"€ª|°éíÌUxL]hv&§óày=®€‡=õ øS,¼!C{³G@+UsU“Ëiò&Ñ*UßR°²°²e¦ü$#²Ȇ~zvöéYšM«©ëÚçÚÊ`Pµ/£œÞê¥Â?_,!Ú¿«`€î½ÿßý.Rüý0¾ó,<žb€¼ÒÒöWúY{@þ¤¡=‡q°ø–hè;”öÀ¹+{‡!1`õ÷Úç@-9'DU~üɕӼ2Z^®´­–«Ñlt\ë§Ñq…
µ\wÒ쉢}»žª(°cRfäõ*žÙY8,èšLÙsz½
ÍŠ­’g
™VÖdº÷Ÿ[YH½z¤ù“L^="ÉgkÄD¨Û1ªüé¬A!«Ïã¬Dk›,®¦Ÿ‡‚<€î2¾û]|É—øæüh<;|¶ŸÂñ?HÛgrÖ~™ h£?à=>‡$@6¾Zç vÓ5‚Á ‘Pù½sXOG!€*?þËib9sÒUæÓ4´4â,4Ô§ÙóÔüjd_å2ÉÀA9Mo¥æßoØßwe#]·^E¢¨Ô75-mÙþÓ¶¬^¥ÃÚ9|³ö©lS,|!;¼Dì 
็þ…ŒÀ2™eo€	0Kž"€(NýôÂüÓ,Éxý1M˵qê=õ(ÁlzÅÏ?èè.† }8­‡¿RùÑ ö©€ÚSØàŸ|Øçþ`lwq¤'–F ­›F⥠ÿ] –…ªôØ,gN÷¡P*z‘’žªèÌMçÆR ¹ê$Zh«Ó½Êº… yô}Ù(bÛmå`yÿ¤ü§±ðdÿÛùt69s€§NÀΩð@(kl?S%Òæõ3™¥‹nÂè?[ËçõÒÈ¥îL/“œ™T¯À!g>2ù }ßqÐ,PtÀ¤D Žþˆ—Ú;÷+Z{’ûÄ]ò.Ó,µwÐpct*–¸þ	£Õ”Fùáº%eE•||éN@¦ío£5µs‚¡ÕïUÞ¬²²dØ”>òdXÕ>“‰µtÀ³°’&Ï, Îeóú™Ì2@ËYôÔHPŸ·¹¥r±U¨Û}åd·8K}ºLqz}ÚýÓL £Më¥&@Fæõ ú\€¶,å²è~Õg?ÍöQ:8±y¨ÑK½}ßö.µ_.Ú#ìQ	€?˜DyÎjC‰#1Eã,à‘B«üø,ÿÎ&÷8f:,3M;÷1d1†éž»û÷ïL½ž¸Dq)(6ÛgÙ=ŽÓ젯 mOn@‚3Þ^¦ÙCÿAºçI¾UHž”“1‚ÉðªÍ”TåÇŸ\ù÷&»1gƒóÐýG¥ö‘Ù^îéÉAŸÞ¿ò’€^ïc KžÖû§öî@[0€çIÁæå;±º ”“ªtàª%¨w¢‘ŽÚù
îÊe±,Äò²Ú¹÷ú´–ËÝcË´z®Ú,ˆvÓûºÉêSG«¶=²óe{H¶uy”ÕsZÔå PÑ*#´õîNè:´ó˜¤‘q×ÚP8ή­½è¬;ÎÚµk΋ð}_ßX[g›Œ­ml°uø¾¡þ:ßàêù‹üŵ×à±|µ¶¹¾¹Wà¯Ö_~éå—Ö®­]{q}^½ôÒq	®BÀ‰'ôAq€¼–îôy?Í|årÙ]Æe¯€–—q™_Ï“Ñh<Š"\YÓQòÖêª!—ëYx¸P(.îqÚNäk&ÛN4r(ápyP›9#–0¢Ì£î¿PÙjûsî…-ËîÙ‰K‰9¸È0§µA=é>m&$¬€ðugíúúµ×€6Ö€6ÙÚõÍõ5 ¨¿¾¶õ×®¯q¾ ñÅ
ÄþRÀ+úÍÍWû¯ \{	ðõ o\
¨ *Ç#À½hgùèŒT,}Yâ4@ƒæ¢q´ŒF€çñx4ŠpIL”Ç£­­-è+“W­ÑزŠzl?RíiY-E®Îÿ¥Èj•Ý/tü(Â
·";]«XÀ±ñ£1:bI¹r„(·¹d€ütsSÚõÛ£Åi[4\Mº¸²ï«e‚Cø][_9ë0ȯ_¿¾¶~†ôµ-¶	,°	ò&Èׯœë€á/`þEÝ×° æ77-¤uÒ^z™F’7*¨ÊÑÊp8,@öÕT´ÒÒÀyNJ€ÃHàKúƒ«éžs\zÆD–Còê^Âo^o´çŠ1ˆ?pMácÈ­0Ò^ªðyÜþQÐÎWYÄ£Õˆ¢”A×t|Ðßpj.¼åÖ€xHÈ÷2C‚Fwq‡4Ú‘ó€ï§»	á$æuÐð°¶æ0`”7a€¸3¨OÖûk×®C='ýóEÐ6È ýßÚ
à2^zIÕü*¨Êáà‡Ç{ïeà@Éç¨	/­ïäq»€Æ¿›2²è2.Êã)À"åUêydeõª½„Ñ”T‚(#äƒ#ÊåV(½#´gYü¡[e?•i´Øíâø.9!²þ·oß¾½kççƒK\ŸQšo„»ƒÁ Ÿ&1¨™?J`€Aƒˆ#tŽ"\·Ám7CAÛº´éh‚,Ñ€;…IàBd€t\N:I2˜fCs7I’öhTT=Â4>Y dÀ'+Ôk)寳þ¢"€Í͵µë]e°ªÔ¯WprÕ€ÌèKåüC
P[úêf£Ã—QàÊ2>)ã]€S~À"c°ºc‘‹òhlå äñhÚommqá\¾Õì‚•Žò%b“òR&ãÝô¢¼ÎçáùÈ4€ð1è0«\îÜx¦2íýI£8^]o*7Ñe±ççwïÞ~„²
è¶#œ
à‘íDÄÈ4%€< e„þªç¡Gš½«ÌÚuÌÆ•àxnw–‹2Ò9’Îxôâ:šê{
`k}ÓÞÌFhªß@M=>˜øèÜÌ€o€îÀøX¿õÝ	k××l2 „üš"”®ÓOFU~üI“ß{ï½T¦vuWöq.Pÿ)EX()€ãT` NIw„¨‹ JX%½e¬OO4Îä-h¿åIÝ€FüزnÝD‘d$€P^Êd €8Œâf&ËZË÷Z²Û¡¼5
¿óÝpdeõ6ÛéÛÀ©Œ›‚Ñ`2­Ï¯7;ßÐrÆÿÁÝÁP9yíˆã†BèŒÐH>sF¼&G@Wc¬Çï§îávÜh„4Òþ¨h +{ó87 ÑÀP…Âÿ8C ý²»7¶n¯of#4ÕóÑRWÀ'?¼ÜXWÀ'?¼|źFÀG ª'À+)þ©ÿõWÖ×SüSÿÄׯg&@•’×è«tÒÐ	¹‰èc IDATȹ¶T6g.yq`Žñ@.Žèݤ›Œ;ÂïŽpo¬q¢ø£$Ó”¬Ús¶…›V+
€ÙÖÍfWx$gÉM†ø¿”×w§A%Îd+üηÿð³RyÄìþ~§@2ÎË…ó!…æ¤ÇÃùµã›c2òþù¥¡	2@y•9¸% €>‚×ÄÐÖÇ€ô®â!Œþëᯇ»ƒÁ×ãùu?ÝuˆB]ÜÇhÈ÷CÚ?؇+Âú¦Á é0ÍIr¢;éºI§“ê›`Üo(?¼Ü\³,¾òàËõkª­¬WNÀdsmCy”p²½±–›	0€ÜÈ4€*=öD§“Pe¥âüY]J‰y€ÓNJPOîˆÁØŽû|ÂÍÛí*' Er73VU=´ß¢ö`ÐA·y)InÞ¼tiì’ä˜9¡ŒsùÒ%ð©™Ép¾P3º™lyßþîþ¡ge2šç€¦dîÔa\†ñXðâøN·Ó;›Ÿo\‡Rœ¯y‰#p”Ññ7B ã_ø]]EðXæÄ÷Fl4f7ðuD›â€ôB4\Ú
½ê]Nû‡ÑÞ瘃¥4ÊHÒ±‹Ü»‰]À>m'õÖaè_êˆ6éøÅ¦~€è/_# ?@´yíer8›I'	 Û'öFÞÿ:0DGnäNÀ
'{=ÙWÅ‘i>jž"ƒùè`ùã _VóžÓ훌Àª¸¥•0&Г<)`kUÕçí¹'|øÇIBf~D’/ÅŽŒ5Ùvl½Žo%€âL¶¶0ðnd¥2@Ÿõa %Œܸ0?¾“$;½¼ÿíÛã1iJæå„DYíÞ©QÔÂ8åggk
;´lXdÓ
Äœ¢‡<î¢{ÏóC’Žëà6ƒÈäÒ„_ƒë‡‡{2T¤Îh”d}¢Ü…o3[ï€ê“$QÀææVæÀp`úfS?†¿üÒµ—3?¼~)[ƒÙ <‡N0ðn'QûbwU~üI^ O¡@hügùèYî>íL!U$ ”*MQ©ŒS'j£­Ü	صº
ÔÝRõÔ~Ú{#râu“¸	V@3KÀÈ4é§ÉÌiFz=ïÃáÝLÆÆœ"“ÓÔ?;•‹µÇŠã¡ŒFy{Ï)“ÁÔ_8ýEŒ}¨ùhGoÂðŽ‘€6“ÒÉZ„á?w+ÅJ=èМ	íøí`øP†A.³“±=wlÛNZù ‹r‚r—<Ži}bƒàpÌȀȘ	9‘^~饗Sൗ_¦\ü*–°|³Pì~ŠX°¾£–`£¢Ê?ÉëÐüÎð4=Í›ÍòÑ	ù*îèT@¨¨ðwDN>´¯GŠ”Óê£À	ªžÚou’€È	2ÎÀø¹›Ép|Kâù²zj­ÉæñN¶Ç+ŽW×;ý|$“ïc<¡Ú-6œÆG®ËX
 ’ÜÆmƒA»g
ä’€S›¢H
pÐõ¯¢P
®C™ÊI6ü;j¡‚n7M×£S3»“¨T9æ
¬‘€ý@ þ“€&Ö7aÐ險]ॗóU‹ŒìȬ÷tÍFF»ŠÒ÷DN¡*?þD¯1€–ŽÀÙî´.¡Ÿ’AÕ꤈JÈ8Ǧ<d€jõ#ð;RõÔ~Ƴ-¡ƒâxP¹(׎ÞÆf’L€ãžÏÆ(@Œú]ãm
ü!_ TD@
ÒÆ„!¬Ç„¾Ú7<¤‡JbD¤ÿS"MR¨u’/`
ÐéòŠ}±^Ñ0_C‡=ù6é%À+Ê`ÑK øY¿vmƒ^¼T¬¿Ä¦,Àâd1¥SAU~üÉ^Œ€l.P»OÒüu‰	8HéÀž@•ðv½ôÈæÏ{FYÕòú¼ýÊ 2ÇKÊ¢9Š,Ñ^àªäGï?—ä8&¯¢ç_9þöÈŒæÈYÊfS/Núãæcˆ¡ð]⌠f{
ïúBm_HÛ*hµ“ ´hI’¯c€Ièˆ6U:Ð&¹ÿ1ÊJ¥ÖÿK[¦æpôÍU« ˜^î~ü1<°Ü¥2 ½¢¢¶¹^~¾¿´¼´õ²T[Åö°ó}ðÁÛ|?P–ѧ¿	Ù*U©Ê	.ÿ»ŠÒç ?£(ýç—ûËÄ€øI¢‘ÜØH$_EüK"€¤t|Bü=˜°è d"*_!¼¶PÝhUùº•Œ>NþŒîâ"×KË)úûˤHÔì½ ßGßAã;'´^îÑ"5¥‚=Êð7Ù‡p¶3¬g/J2Â_A_±ÀÞo¤›l[ëìõ$5š»Æ{Cbrá?$ÿ¬àõƒjXçxTÖ´:•òS$‚þÝÿß%è2ü(øþÁ
@ÖÓ6s]ÂÈŸE$ß›x>-P?PüÀŸ	D}8SGã
¢æÉpR‘êA„3‡õû@²}ç;I²­ðç›(ç°}çÎx&
 ÷s $gðÏ,½PBü[¶¶¸8ó¤eáCî=×5¨€Þƒ£5ëÚ–¯ÕôCäAÿŒÝ?šö¯b“¡°¬É_Üç¢Ç¶}ÐqcÅ—ú[ñ¥K‰Í*
¨Š•«þw	dª¿ÒîÞ]FX^&
@.p0â-ë¡×IB/À|aŠtòB"@àñóßIÐ'fàü­x^
(C"¬é·¾?ÒAØ~#Ó ’;xCo¿‘dǶ"el–ÿž¿þ•`/–pÒovàÕö¶X&½ºÇêêE¶c=¾m-n#+0ǵ|&-Á„¢ AŸó{ÜûI¨èÀÖ!/½Ð`€7óWo½¹«^¼}z_ Vbð2ÐÀËÀ/O.fø›6;ˆ7X³	t:¹péìø¬]@U,5øgà¿û±üøñy‰ÂÿƒÏA
 µçÙÝ«“þݱdžƒ3ÙŽM²åØ’ãp’ßq5€!hH¤L0VŸg=Ò†aZhøsg;Û‹0IHØNÀí”¶?0|%ùP
@Y€
&bîõ×ÓñŸMüŸ†?ý‰#ý?áºð5mG˜×Ý?zSXÞ}—9ï¾{û]‡½=›ö8t˜xOd­/NþØI×@Pøo6ÏÆ{ ·óÐÃY`€ð€ÿøl2®îþªÐ4`5	ûÿˆ––—$RÀÒçKƒ%o©ï€Âßv2øÑ ?^ªÚЯ?˜L“þ¾Ïܬ¾³4ï¡	à§|0ê æ“	 ¼!¨5Ò`à?¦õ™Îo8™MöÆM@©f>€bÌÏô~C.Ü	=í.»À,Î6ºü™-h%2`ožð¿Óì_XÜY@$ô€*àHQ‡áý‡ƒ¥þ¸àp¿¿4L–ЏWïÿêô£N	€Éš ?þ¥]ÿ"‰ëfIüK‘†5\OËõðïA³`õ¿qÇÉœ€ä¸y')¦ï(
PpP@NyÀ~`Û p|3ù&Ëꘜ‡«íÄFîìlÛ½E¶Ó{¦Å¶Ù„g8¬¿þú°.^'ˆJ`ŒÉ$üéOáÓ†y¯\Ú¯Eé˜ï!øÃù÷I|ëv™ýÖ›ì­]"v{ö]Û¾ý6ŽðêØa6ô™Î.0{ãå‹Ìyyc’1€Ý„£À;úqÄ/ü©˜‘âÿìüWùñ'R.i—4€»hÿ.K	\Z¾}
ꉳwÀ˜Lú´˜ü
êô£¥>&ä1Ð/j
ÿ÷þÆÅ"…ÜÙŽú½šÂÿx§ßlU€ä
•ï’áŸßáG%€<`?Ê6K:ß´H	Ó_2$8u½níôXoŒöÌc]üÁ³æõáÔ€ÔŠÎúOC5¸ð|	¸Qw6Àl/|ßfŽT›hÖß7mt¢‰ÀÞ}û6K=ÐxØÊÀ2޲/þ±
ðÙ4á¿©´úN’\¼Û¹Iaør€!þ›šP¥Çž`Ùp è.œ\^<¿ôùàùÁçè
øFð .(}XÔa³-Ûó9Éܧ­êlx${  HéûCÆ—BP„˜ˆšphS[ÛuÝ0†3¡{°íþ¿Å ûï
VLn“í_ø
Ç_
 ÉÊ™ûŨ8ƒîö¶ì$äæbÒöê™ÎÞÞI.ìl÷Р궆"„·AÀ!HáDØâ'B™è¯-H´Öµ}‹Õ.~2Ÿ2Ìú}+`·ßeö»EzK(OàÅ?fìâ\´µ‰=fúÿ¤2àŒ >é×Iš¤ä
 ÄI–Ó0€Ka¹@öÁúïãÓò5À¤1:îQ¥Ç`P*0ÀÃÛvùóó0ÇÕöÔCð?CÁïtN@'5J¡½{‡!à†„¸G›ü
mÃÞж³yÀÜÛgb?—‹Ñ?>p AG@’ Òc¸Õ¨äd;;gm¸üšã³Ã:³‡‚œ­ÀÐBþ„Æká³ÎCÀ2@Mîâ¯Æ…K0EødÈR-63gú@Hl¦SJ0NäoÀÀ*?þËy"€iÿgÓ€ƒÁç4°< è÷m̲÷åq"ŒäíˆE€–›óæpCžnOMxWËá‘a6ü°€m#PÚ.˺ý¿(p²£HÀî&y€ô^¨A›õ:hÐv2¸Áu„u-ˆ1AoRûlˆO|‹á, ‰6	À`ègo¥a@ìÝÒ
ƒð¼ncPÚ?jzûlŽÿý"T€®åèaCU~ü	–•°˜TPL~NÈ_Æ9À%	ª¦Â9^ÀCRÒ) )ŽRmm›{ssþÜfÆáÒ6è3CO­ˆ
­1p¶6qÓÌc¬þÌÐw§„—B‰“üio.@>íoerü“°cŠ`ÝdJô‹ž)Y¸üRÐëC1šöšÎ¯Ùo¥ Î
€t2p¶DÀcÌõs€šéKìiA„¸\ÊÓ~U~ü	–ø?ÖrSägª2Àý%äÌ •ÞA?>K—œBplÜhZ¥³"à2™6¥œâb=©0Ó2? ËÀ°•ðeÿ”å,`Z6 ëvëÓ³ìö»šJ±/¦M½å°°6¥¾Ê?¹²ýlppWËü—(€ò‚—œt·yV¬jKZ}HGm§‘fœ§	ïùÖôêh+[ †IÚˆ?ºtàLÝß”µ8€¯u:0³«•ªT¥*U©JUª2­àêgÕ·P•ªü¾>ž¸/9.È ¼ƒÇõŠ…é1À¹Áê{­JU¾Š²³½Ý)/0ÒŒÜÙ {Hò¯„ÞZî^Æ®+í>ëó‚U©JUQ‰èQ”må7 fö751œ·ô%DŒÅ:y—@ÇUÐó¹	!µ¶‚Û,t0\q_
ð}“/ýœÜ„ý­Nµ$bUªr4D›¨îï3LóÁ‘a±èß`Û;ô¬µi*€Ç˜˜/Ћ.A\x@]Ú)¥)œ›Q–a>ÓË”ôµ'qCàßgf3©°då9¨JzCŠP˜²+§×—äíÄ”oíL­¡Ñ€%Ý2mý‚™ôÌóõOÿ#±Ó;oØ`ã·ŒÞþâ¿û¾!~20®§éUP•)&€#ç§Ê½žÐß?ŠL>øË¿4äá²ÑÜjFÑY³ÇìŸ;Æñ/üü1ƒÂ'Íþþüí·
àÇŽü±Ñþ½÷ÌëkŠ©€'e «8´©±†Ÿ;;7wtÇ·kþ»kzŸ\}óªNÉhdnC¸ù/-}á/Ф¾~AÿÊWtüŸ×Wð´ò¶ÞÝ÷ÿê'¥
Ü]·o~ÿr
Tùñ'|=1??¯±Â…I—{½ÞÎåâ
ñNôѼŽ0ñÚ_êKKËÿJ«£$9ëø²#I„ž~ü•Ÿÿüçÿ\ÓÅ“O>ù=­¿Ù·ß}wFSÄÿõ¿þ±q=Ã÷Œë‰›Íï‰)
Àš“ƒ1‡3v²mÄÌŒGÑXWÖm[7ØÕ?þTä¨Ûé’lhÀ¢XèŒÊì_ü÷F0P’$=F£Û+z½ý}Ãâ`v¿o„¡&Á•r×çƒù@»ABÉ¥«Ë½`¡áÿƒwjµ¢AøÚÆkº
0ü륿^jPwœŒ5 ´mÇÒûw½P_¸ú…?üðWtà‰'Ÿ(êgß}çw>x§`€ðÓOü©Þßp0ÔU€°ÙŒ“i`†ÓƒÙ\;ó€
`¶j£‘þFwsݨ¿úÉ›†<6Ç_fÙÿÒ¨¾¹„Yÿçæù:=óøF†	ÀþÊ´X`n.,¦YUzì	Of"0VŽg‚ã*“š¼sg{ûNþí¿õQÄ‹ú7^ÔÛÿ50€&ÇãîX3‚q9*ÛÑ6Çõ¤ëéç»òá/~ñá­ý'Eý
Àëh¥¨ÿñ§Ÿ~ªŸ÷7Ôå8‰ã)`ufzèD)žvÛð°¨fFÑv/˜Ç_ýÄ”»1+á߬—>+áßH9ü›A»­˜2û~éøùùÌ‘*¨d]0¢“­HÙ#oƒ\¼ã	Öø·7JíÿZ,/kò8<ÖêÑ©'5yÃ3ŽÿÅ/®¼ð­¾aö­ÌþùŸÏ®hãméüo•äØ÷QL"È¥9¯ ”Vû¸Ð1ë?)iäcsIRÛ²Ký‰éç+­ßm¯”7	`‡\¯˜æ©òãO´Œƒ±­
hûÈŽ)ì½øÝ4ëÿzÉq‰Ë±^)­º\:ðÿá/Ìós½þwzýÕ7¯N½^\üjÚXή9,ÛÆ*¯§[ÚÉóÐþŽy¾½ÇoçÐÃú¯òãO´ÌØžô³i23’Q³SŽß¯y9amz{oÇíoO}UÊNÀ*?þ$Ëlº6y쬇ì¯?vÜë©Ê^¨òã«õªR•ªT¥*'ª8C>p=aá¹Üå•|²ä
']ûž'£ÑxE®'¤s$Ù¶VWqYñLvXè9ÎÑÿêå­ÕßîùG‡·þV®¯BÀ	/Âp{ŽGã1Ü£ž+ Û«pþÚJFðÃ/óü£ÿÕË«[ÀXFýʱŽ÷;ßÅCêGáh”Ë+ûŸohȽqïÀþ|ýiçóƱjõí¯¯B€†…’>TÞm{»$—÷Ö¾úÚôþ£Òñå½9Ëç¿rÈõ”û›"ï»’ððþÌîÁ—mëâ¯?ûÎÅ'Ÿ¼¸ú(ø‘<ÏÉÛ×Þß— /Béõz™¼ŠA›[[zû•óøEóxüÑëç°ß8_ Õ_,_”¯Ï¶ñ‘Ê‹û_ÿиü}>߇ÇÔï¸ØÓåößWû
ai»²À”·wLy¼P©ýÕÒæFIÛ¬/”Ïÿá²)wž0åhÆ”'ïM—£x¿ùχ¢Gw
	$û¾?§Ë#½ÞBøLÊ)0ü›µ¯Ûuãx¼þ|í|»v±ø³ïù’ý\^ADëõ‹u,½L^½¿
ÀÖè~qüâŠy}ȚܻÜ3d¯wN?à^Ÿyæõâºìu`%×÷ý<á.÷ë‹éõ?»§·y5ïý	‘@Vß>ðûTwA]L‹vÊcQið{?Ú±¯,?yHýŸ”v&|o2½ý¾%¬›r9Cg»ô%”¢q^+µ_.@é"ÊÑ<åó_)ÿD§t}¥ýÓ’:÷jIŽÃý>5j„0Xžïшé¤!þ¼Ã2y|ÿþýq&`ýÊ™€¿i{Ÿvüâ¨;÷´þ@%Îú{òüƒÿïÖßËOfõݼþÙyeFôý|xþùüóÜÿì>Ø,«÷?+Ž_Y4û»<å|ðMÀÙfêf=bð ëóL¹n‡H£Tžß÷ó
‡š¼¸XŸ¿œ^ÿwöôï×|Ï7Žï™ýù€xl‘ʽèC|¾ óÓïýí[¦<.ÀÕR{¶\º÷÷$×ÎWÚ¥ìÃ]«4ø•¥Vº÷KØ™”ä¨y`¾¤”b‡wJáøã¨4à—Ú÷Kò „OQjÿáîôóGµÒ€ÿ'Ó€xÿXhOŽR
ž‡2À.zíL}6¸ŸÕ'ZAGøáß´½¨ÛóNÑßhDô¢ÉdÂfr¡õÆõ„PfFÆñ£ØÏå•üYX(ê3
€äûD=Ë‚?Ùñ‹Dy ¡”ú7¾P¹Çs¥ó'þí™ÐO@òüžö¤òbïòåËÙõﹿ{íö¢ï‡ÈHùñm½}¡wÀçKoFs¹
¸9ÍÑÊ.©6/Å—å·, IDATTûjI.©¬¤Ø¥ »dþÚ½’<[’½Ét9>\ˤT’o•ä…²P’—KrlOׂÊç¿R’/r}Ÿ–äWK²Ø?|Ø—h
váfèÂôPöÏœ	üÞyF”<¾ø¿ŸÕÿØxá⯟\¸¸zŸêü Œºð›¶¢îûEãØìÎ7S’ÇÓä™pe&4ëc­Á¿`¿ˆ
ÍùE%ßß䯮dÇc½Ñßâôë	çæJçOö´¿˜ÊžWÂóŠz?Ù6Éõ}?ïÐ/.^î]Vòg{ÿ?£x,ŒãËýµ
†ƒ>_
È’
ÀJ*+©¬dÿ²’
ÀJ*KödÖÎgªìCsÅ/¶sÙ”£Ó¦\RXI`‡«ü`à ,—-pÛš~¾=€C^Rø‘<–¼’î(w¹Êþ™óçÁ(è¶S¹;ü²ú‚¶î£b`iú›¶÷l°Šþ.Fÿp¾°$kõ0·ÍöáÊÊJ¨·_Šõz$€•ƒû»È·VV‘²zü|Fûó¯®×7äø‚^ñ¢ÞÞóº^â‰\Õ3øÛ#ϵÛûô_’/v{I/•$öÖÇåã{%¹mÊžÞ¾³øÿ.v2Ùú¢*@òû¥°P–(©T_2‚/åó¼6Ýb%#hOüuÉ@g¥%Ùekúõ…“éòAé€8"t“n2î³Ýó'ýv&'÷ƒ¼¾ ë>Ê^zðë‡ð7LÛÃûzq©ÿ¤·¸hÈZýbJÛh+ÁŒ&â^¿²tWÆõ'WW­-ëüÊ¢m­ZyýùÞí÷•ç9¾0¥½þ“ZQ
ù˜m£Ü>Âù.jòg±§¾}Øõ¶MÙÓë/$z™œßõcªÉ!*€8¦
à•T€Òñ'KCz­4äÿII~¯Ô^6^Ž)yAvÊ^6ÕÒÓ=€vYA/µÿ°D ;½’Wc¦äõø´$¿Z2@úü0BáýÓ鎎ýÉç‰Ú…œœï.fõºePƒ¿,mßM£¿¸Ô7™+ÉZ}ŠÙ>W΄…ÿ<1]0é$#°
ÇÂW2@IÎëW/þzõþ?Y°.Þ·~²“@è9YûRírÿÉ™’¬×Ÿk—ŽgVΚ<0ëWö^¿.o©
'¸¾Ãå3áñÚk²"UŽxüE]öà­rûöaço›²§×/^wz™¬Ù¥[êK–íCÛ³/õü¥¿¬Çœ	¦ËÑ!
™¹<}„—^RV€@%ăÊX9‰P>Þ”µzKÀ*Ê,Dدý5ÖrÿÓäsír}Ô§´_™ÞߪÂ?3PدÞ~~Ïû×›ùû®À¿_LÎÃËö׺?3ȤwDB*⡲î@™y>€ïDÊ8àx4ìÖÿèÜñ®çP™þñië‹ö‚|æž?õÿ©Y€}ê‡É#þ¼(·Ú¾ÿ	/`£âp€÷؉Ò;‚L‰@XP¥ö€€ïíøCdt>Ìñe™Æ~Ò¸ó(ú;¶Ì2€í[?ýùÛGm_!à„—*?¾Zàd—¸#TZp÷dúñ¥ù¹¸4|-.[Ú|ç#Xàë—ÿ_É¿Ûë°Îέ¯èTI‰ÊþQ‰ºJÇ—‚EXšÿ‡]A·SÚX”y¥¨ˆÀ›ZÜÒ`AhÍ öæ“;ßøÆ7ް€kyùü‹¦üé§Ÿ>TA|Ö'øÉSn“íä€M’íƒkw¶·;ÇÃÿ-‹±ÎÃÜã âhÎi§·K1Jv·äxÃd;1ÀÞ1;·K`Çâ0²K’®„ 
„3é…†ìÍÏàÒ£(7é1åŒaPÀýðÞ0ÔóÅ8aGY@üÅóóWFÝnwœ=¿ñroZ}³ÙÜçøv»÷Kõaø[\Ÿàk,|—t»Ï’¦Ç&È…8”Cíˆm†[ëìèÁ«’öÍàÛíÎNçÀ‹`=ƒ`ß`A¼\\çà€çš¦\
r,1³;Ϙõ¥]»JJ?;̰“®mlˆû’1O“È&K×f:â¹ëz2Ç­[‹ÿƒ¾«ø/Â7ÿGý$Ï"?1?|øÃþ0ÔòÅ¿'¿¶€xRˆ¿8ZþþJ8uY7Éë‡ÃḳØÉäf“­ÿM] ™íÛ˜ïÞ~ê©fÖþþßýÝ}óø^²¾ÀÉ”ÓÛàBçÂüçæ1c{uN¡ïžƒð.‚å†ÅSd0Œ£-3€Ç˜‘o õþ˜… Ë³:’lÃ7ÔYú‹Ÿ`{°öR
S.‡9³”ŒV6q#€Ù&þ1Ñ‚1n|Ti|ÿÀLǻ،¹E‹[gA¾Uèü%ÛfBÛiÍö.ä*i„ï
¢ç“|ã¿ú†–ONés¥õ€¤üýz=I€ÆÌz\ƒ#“gx½tü}SþôgŸêr<ê65 Ð~ªÝÌ×/ø»¿˜×Óëý«pÚú'UNñðêôôûú
œVQí,…šI
a)k3msP¬Ü)áßì“C6
ÿš
@WÒ“Ú´6´.b	;¦/.MdÈ»#"c‰utè” jt/”tYrÈC )ëÜÜ)ÔfrJ=㮸AÁ·ìæâÙ[gµÛ¸øSñ}®û)¸q£Ñq5Š<_üq³8‰•å›c>ÿ¸7ê•Öˆ…{@>|IÆ%pPH”ãÿpD@Öž‡Ò<þþgƒ)ý¤*€’ú˜ÿz@~Q‘@Âé’Ïl€4Ydÿ”ØA=SØ„1GÖë￟¢¯%B	ॄ
§µÜD¡!pëf1èßn/ŒogrccsóÚúµ\IûŸ¼õÖ/µÿÃpðí4á	ô×å’sNáŸÑ…—“{Îî.{°+L&¯~|Ææ¿!u/Óù>
@1õùÑàxQ#þŒ5 ·bƯðÿhŠ-¹h¿mo›ø1#k0ÁÔÈÝOlÃ`¥ú†m7¬éßrûç¥þó-Œí]n­;ºÆËÜðFÛv²ÍÀÆ1:Î=:E~.ø–ºW.i6™ÁW,ô´uø¸ÊFS»uF8¯zA€/@  ×£#˜‡°‚†=Ÿ)ÒÁõ;2u›±Ý	€Í™¾!C4êìësÐÈ/€5’í; ä_Áh|c<þèöGA¿bhÿéî'wùË·Š/|L€AT²¬ât}IÀ'C¹û@<Ø}po²û÷ƒA6ö+= û“[VjûÞÿ|/t“ý|”¿úpêÇy'3þÌLø^0¯*ì>"Àܨ‹ÙÇË/Ý+[ÓóQËíËç?¬›˜ß®ÅÛ0žÛÝ8·XÒ±Aèäú +ä2 Æ]í~ÃõsP;`v†X©ØP²4…`„;Ú*€ùŒ"­:™ÀEH5Àq$Ý"½Ú	0€Ì.(”Ê	]—À"¹Žú¨;7sñ¦xß^X(LÐÐÖ×7
íî[o}öËâÛ£½ííRˆø'ð#üHýð„†ý!ß}0îÂÓîƒÁÝÜÿGO¿.+WöÀ>*@£a}ø«i7è©øTAÖìÌ|33³<2x(ìQx!îz§vÇÐOv¡²:™þ’€~8¼ÿYœØÌaÍô–cnV€Ìð™v”­ÓÃ’>u0ÛÇþÉPW.G1@˜éÀRÔ3@Â(ð~½0É@߯‡ó=‚ =‘ûlÔv
ŠÂõn´Ð(ðíZ^ÿÖºûV¡´cÅ$¹œ«ÁŸ@f S­pã¾3Ü}0ÂøïÁn1hÎŒsc 'À¡`)‡ðÝñö2 Ÿ†ž™a¶ÂnUŽ à °°ü¶¾:‡Z}6ÄÒŠ:q¾Bý¤ÇÓÕø“ú5@»ØJ2€4†n‡l€”07(ÀË{'@ÀÕ@#†VIX…ÌюЖDKîhN@Æ ,Ü—L€uÍKûØš†D)á
‰n
¼$
@QW°;yðÀÞuað>x0Ü£d ½q{\€u\ æºúÖ`ŧ~ŸJ´³¼'­ *Gd1
À¶ín±ä¢†~†®ÐÜ>¥¡™ú€Rz†lÙvftGÝbÅÆE:¦pÃe¾½BGªQ¿5Ù@›³¤^gÀmôhnT
4€q^ß° 4X¡1€ðÙ[ºµ˜py†÷Ì — LU€	ì;Ã`ì>+Àpäpãöo2°þásCðüç~cݽšBm‘3 +¿¾[§rð|øÉ¥ªTå0À³ƒ|”Èè`c&e4Ëf…`Fl­Lšá¯Óëéý	8èa~:ã|À%®b¡1€_7͵5ÔÎr†Õ¾s˘Xµoܶµ´€ôyQP~Ù7#3‰$O‡Å©J $"€{üÁäÀdò`÷Áƒ4ÀôŒoÿæÆÅ,€F¾±¯¯´o Ðø7¹À…ð‰Š¸(8àʯ_k›ØÌþ+ìWå>v¼jfïYÀƒ±Pàh`e€ƒþŸ'2€[¨3K_Æ}œ¶½ÇjÐ×[ndÌ“Øwß2	®Ñb¤£?'€T®(Á²ÞtÐ@¸·û`ø`7OHcRÿ&'«oýC_'_ˆÚtà†.àèqÉaè‹ÿW®8W4ð}¿Òþ«òÛuK²½Ž¨Á{Ý$…í:oZôËÙ€7Æûž –þƒÐ€.€ƒ*q*P=Uå÷2Iõü6Ë+A)ÅFOßñ’½÷¬Å2NÆ_æê‘¨ÄæìpN¯ÊÃ1@·øòM—µ¶výÅG|.cV€d#ø“¾BFÂÑÖ—œNÌ|¾ð"…É÷_= {u
c†cg'Ÿ¾Ç÷ÙåÅG©{Ø–çÕKxʇ뫳ùyÿ62¿¯ôÿsHªouÞP·Ü' \Ôýæ—kkS,LÇvX9ÂU+‹‹¿O`l”þZùÇé¡qhÿùÿíd-¿J™¯¬­Mgwèûþ{ïiû_–öö1ån2F…ÒÑ
y4Ž‘…ò1FH—JŸO×)µy„¡ÈvTãêvÀÍ|i¶?EpY¶”<ŸA¬T/…Žm;A¶.Í›û®ú+oÏ{èV\ˆ²|BxîÅÐSõ–t}\¾#Ì&Ä«Ô?Ÿ§b8ïIùêû2»:	CPèüùÛ¿¥ï°_Ê~Ú‰Ÿ¶ò%a°¾_:ºQ±Ïð]k6s+€¡a‘ĉW÷²™ÖвÇÅùlæcƒÆ^˜ü™&ÇŒÇÍDÊ£]²ç|ä–àp1§Á·<~ù©ËÚΪeoÙxg:âgµ;¬ñLãw™Z)à[ú;æ
!V¾,…öNqo´47óþ'0ޱYÒu‹¡ÀL¶{qscmÚÿZöw؇¿Èè$Æ™ßSÉøxT$h³v;Éd$ l•Þ°£ñضÇùv^<ÄY6£íÔÅç¢ù)þwÓút‘u‘ÊÙ¢ë|H^Á¼ž;f{.á8"I·jµ|‰È®û>üv´à‘#à¶Ìê§êŒÌx!Ëpý{¾J@–òs‡Âû©xÿU9Wuò·ÞDÊyOáðHçé§u¥÷ÎÓOkK¢rñé§÷~íG^S-»ªÙ}§Ñ:#½Ö¥B	Ñùùòâ¼q¾æ;øïËþ{ͦ?LJqt4ýJp+t‹I–'\BÿŸÈHa4j
‚ûÔ9ër³ùÔSOI+»WS¶³$¸ªDÓRŸù]Ò)ðй%dè…­üfëÿ‡VßÆÎ­[‹Ú@¾p{ae!4k°kk/ýg׳”6,Æ{;Q+ÚäÁl6íU𤵖¹s³7_ÜX,Ùhzýp(û¾ŸÛh,Á¦+á‘mE”Ø Ø£lŽpg›8ÎÖy”Ø1kç—7ŽAÎ’”_\ø"<¨œsŸ»é>)PÏø¼ŸÒã<¶(ûjDÇúyŽO¥p@£ÈÛ3Û€ÏK‘E"ºí‹zàãî-xxçÁɽ¡|U??çsÜU2Á4Ùbßd¯Ê{á›ßWtqõUøåýù»©“«W?õæç'“𪺀§ár€,5­D®E=uoʼniŸŒFVgš$V,›Â¤W‹Âl=„V³€ô’<!,ѵëî¼q¾fbßgÿŽæSÉs˜ -ž‚~ê©´Í…i7øZw|·;N5L°¯4€'žh¤þô[|œ§._…åòåËDöªµµúçÚÀþ:Nuü[Ï<óÌï’ùý1}ù¨$^˜Eªžÿ÷+Ðàßýxÿì÷ËåŠ4eO:ëyKËù|6ÒccõÀ@ŠÙƒ‹³Ü€àÐ9Y0œ´¶Z‘x@'žN½Îu#üqj„x5=\ãW?:æ)ʳ‘êÊv¤I£ÌîÉÃLÕT”{‹6‚_qˆPø¸=‰7”`ôƒ}x”°Bš©d|õd°¿™Ñ}›w2†a0‰ÑÉD‚†¦™J¥¢º<{"e%¨nÙÏB4(#å$NèëD?D-xT,ô,ñopšú4ˆK”9†²
üpŸ2WWþÀÈwÜÅEý9yaÕŒk2f…Å—’ï| Àe<Ò'tÿ1ìA†<áhÁ„é,÷D<ŸK³´œ/ã­=Šq„ãtÐÿ×[
¤.ºY¯Ùcä8•s-Ã’¯H1²Å[>W8PÒü[&ޝ½T;ªÿò†ñï> þ¥3f s9¸H‰’Fìl›H Ió)ûpâ^ÿ~á
Àæ¬!zúªÿPýôÓ³àOœ[ÞupWø×8}œ€•pÒ}aþ…cÏ¿¸@ùûk•ÊZtƒþ—òË%‘,Å£û@}Èå½üì€Ó(û@!I¿GÇY#èªçƒ·qÁçse€3¤¤å÷×½ú¸2ë¤%uÑ´2†ÄÿölBÆ¿D¬^çþÿ6®ñoñ¹ç0XHÀßùhí¥ãÿþËýˆˆ``^óòcõp
´x›ó
Ï'€4öüÈãðt{HPï+=.ŸÂ
'¶ç
àʳŸ^	»@ý4*€ƒš¬Š“Ñ„àÌ;Ü ú÷KଭIwxÖË„åª8>g€`Â
Ôl„ʼþÂÜÂÂüü"g?£×jR\2ªë•J"
20Ï“âØÄv‘n¤rŸF£ðo®ÔCâ@ç$ƒ+‰íÉàÒˆoS_PÆmø2ÙˆJ€ï¯‡>G½®Ì¢
»G÷·ž2Œ¡”&(‚PÛÀí‰üÂI…ˆ
€Ù©SA­OùÐ?9\õ¡ÔHà”s„èÍצ›†nŽ„€’3s\>ÿH„ÇEÅÆÍ¸üÊH>£É¡Äg8t,ƒY¶1ä$­±1Êê^:죦kw8€WsQp„Ìuà—JA샆ìäMË'nM5Œ“ècR\1í¦£¸àÄcš…ç
x¨ƒ?~üFí¸S­Ò_ò¿X^Ã)Õä Y˜o,érö‹(àvñ²ˆ"OÃË(à?H#$ý??»òi4m'`}€h³~º~z²(ÕŸ/Ì.›
­ò÷ÿÿOEúþutH¤9Æf¹0†ähÆñ$¯ÏÏÎÌ*±ØZÅ(%ª`€èê¹Lb´u©‹¶q'$	Ý…^“‚µZ=VÞ#ç¥â%‡F¨Ì¢á¼‚#Ѱ·IGì(n¤ëMSÙÖSŒÞ°Ž1OþþD¨¢©YÅ!Ý,Šƒ	Èg‰$K@ÀÑŠ%wbªe~¾³ä5ižô±¬³áÀŸ:ñÚtògVHù€þV‘©Gæø˜°e›RÛ6•QåëBÁoDÛÀUƒ.>į—&LªVf®g€³;ž/£©€À´Ã‡Ão¬®¸ä€PèÁ¿?ÅÑ ›Q²iW&x¾
/–šøÜsFºàßlÇë7ôë%ç8Ê›!yˆÞØB£@úöóÿÛ&
¨gáO˜UÊ[åi6]&+f&pÒ“ðóaÕ`xp>#øc´9ÉxšaDpçj¡ø;Àÿ¸aŒ+ ë#¼Ï£ôhÌJW ±4­%Ïò/Zæ9.þŽþûÑ£GkzÍ5ÛÑ£Y¥€ÆžJéíÄi=­j\¥þÙwH«nª4ŽÐ2ë§®–Ë—¡wŽÏó)=›õƼ:©×ëÀ§Àà3ûâì €fåSÊ©‰DµZ†k ðå^\µ=¯¦ƒÎOËm-²I
zéhGȉºÄ!FR>=ø¸ÉD2Ü>¼iJQgùO&’’J¤¢ý	(%?4W#fJÓ­Ô¦¥‚ûÕd‰¦	&Ð{#ß0‹†ïw–½f‡ú^?;’¯nDð-Æ$¨Ç3ŒÚwÂM ®·8æŽIÓùz@‘^Ò2fȈBñOƒ)ÉP†§Ò£
$Çß"`ÖúšÎGŸ€#–)‚â	‡›f|¿üýYLZörÖ`c1¼±ðîqÓé´„Ïþ¦ÞÑ„žógÄ>ª=Ê#CÿB1Q,­ÖX¨ƒ9ÿô¶ÊÐ[»VrñH´–ÄPžñiÂã
'ê¯#pQ ‹# Ñ_œ@0Ûáú+•jµTª†¹À ”Sª6Ò(ðEõAd£ONÔ9ƒ˜"p¨îȉ1`3J#M„A¤.žÐ
¦É;™”·cPù‚@ã+éù—äÂlL%ö5†À?¸ý¡æ g_9;r6|wìŒui¨ž$Gt2òZhâ:	zاá’	D—Ò êc|ÁèÏ™ÁTi7ãùs£e2:tСdÂ!W>åPi™Ì¿‘
®f{ÝËîôc$Ã\б :@=éŠÌl×ÿü|ðoHKø=6›&n%©‹ÆY a‡|>ÜÉÅL×tİÁ–yp …÷$Aù˜9JŽë¿½<¨w^,\D=ê2x`{e“²ªëáÐÛ¥~?tF‹`~þ ó@+UKz©TJtb4Õ&½fÛ Ýç-'¼ AÄlœäBï'¶½utÉ æ mó~?˜W\7-“ðÇh×ä…Lâ´E%êœ!o÷1™À¢bhcÒU­>6\«Ç»G—HjQÖ{˜¡ÙZ„Þš*JBv"ð)Î2i|ÊLn2ÓäÕ6±óø'~àÎËùGçä¶ïŒêrEÁ2H>ä|—¯¾šö?ŽmbÌÁ6‰Ô÷‹@ã5x-N‚{36~WºøÆBúmsôÐ.Ç2Š‚ÍÎë„t§uάǬ˜t²»×ñ]3@NìéKØÑjKqÂjA‰Jg^pÏ·11B«Ø-„ÙfÕ‡˜ó×"Œ©&iw¾–sêI»IÒâ'Ax1«HÚåèL˧ï*fñ%Ýn½?çjaÖö韪™~Ü™‚™ú¶eÏ/X­£ä9Lë·~{-Ñq‹³:ìPdŽÄ~û-˜×
FZ&öÛ”u3uÚÄÌUóPê¨ýÜžMo}ɋ̓A˜ÕÝmk©W×õ÷1Ï»[û•¦i_Çí¯ãö×qûë¸ýuÜþ:n·¿ŽÛ_Çí¯ãö×qûë¸ýuÜþºãÖ–à©ÌÞnÆ'¬
íñ‹ÜHJàP$Yáúšu/_×êùk"Óï_ª›j§®
¡Oá_Ö¯¾c9øGyÜX0ÁÕ«8¨ÄÌÝ·Ö샤ð§9àù±NœŸ¼ÍÞ>ýÎá=¯½vûµ×ÌáGé—Ä"=¢&qQ_o)—ß"ôÀ›KhÁ?¼ðþ?v8é@¿A;ûßΖ4­tvä¿õ³õqijÆpZ¾<]"&~š¼tü×õú%Q­6?ošà½ðû…… ŠláZU×ÈÒÈ©¥¥ü©k»'Dªêòè®,õv-ïâ+qitQÓX’£"¹‹­_E—j}÷-Á(ÎÓ¦ª$ž~Š_Âß§þþÒ…_×ßü‘8ÿÛoŸþ,}ãóÏgö2‡o?º9Ž®–Y©hw×â©e­kz·óëZ-6Ã\í«¢„@Ú2€Þâ-ôÛŸi®T)—Jå³!þ‰Ž+ÓưÀ¿f$ÔþæR½¾z	Ú$åËÑ.ž93ÿÂÂÂÂ/¹ÿ¤ž÷jµ‰kþÛZZž˜˜9²$ðN½eo×®]¹Ý»(O^ÇèÊbƒ±Åß4E*ÛÕõuÆÖw¯¯‹7(:1Ÿ¸ô÷õÑ›Ó3?úÉ~„l‘J‘ÏîÌ|®i‡ï¾Ö
ÿzí¡¾§ºGÝÌu/Î ûý]»®õèÎuƒõ¤íàh¥vÊ¡Oý&JurÉ‘‘‘³åè¥d23<œ	V¯Ä¾1*·#¿®{Ë˧NMŠå¨É™3gÆ÷↓E‡c¼|qÜàÝŽ.-/-ï>2áOEuÞàÚîl:˜c$À™3‹ÍÆßfW×oÝÚ½~U¸º^t(M˜˜Kÿ«Ü\nxøG?=%{ûwîÌÌþìö!ƒvþ µ®žÄðÖ¦«k"g· Oí¾¹ q	 +Ochd,öJÜŽD|;|Ï!ÍXzI怰¶©?Íe¿!¸ÉäH¹,½¢'²…B!\¬nqql,f¶‘ãuÏË//_
ö^<3ßÿ¿;À®dŽ£ù¥ƒ»vOÊU3¥†î}w)÷Ý,KóW¨²¸ØøÍf ëÍ«gÏ6ÃË!“4cZO…kiþŠº9;7\ìéÏþîÿqø¶Nig =}xʼnl±XtÑ´ÕymM[}ÓŽ&íWsÕøs¬ãñ–ÉÔÕ»|ÓV·Sù”<]˜”ŒˆBºêK€~C•Ü\²¬$²èÔʤÂÛð?6Þ-Ç×ó˧.…Á2}q~aÿþýÒb´õ±¼”9ª-/ç&‚÷§Ì‰ðÝk»Óï
 yFógÉäÀCÍèýœ¢ó”–ÇèÑœ=<]ìéχ»ieb]ÒÍ ±	’ŠíO
7c³Ø2ªNIi›$fÇßÀŠ¥
­ŽÇ3ÛŠ]2uÀLTÊ÷@
oô±ßo‚ÀP“7t–ÞcEêXK퉊+ÈñãÞò²|üâÂøø´´–^Ÿ¸æMDæ¹¥åp+¥iœÓ˺|!
s-õϵ3¸FU ýÔ̾².1€.×ã|€ÀgiØ

àÈá40J'üëjŸŒ¨ø$1tiV\¤Ô	ai¼QóDhŒ`¯1Ÿ‚±aé$±ãÙHL˜©ø Œ¥
Tÿ	Sb”ÑßgÈ¥°ßÚ Ö¿ûû
W¢4
ð—ØPÆŽüaÌ×CIOŽÿzyùÔ¯¥ãõùéééù(•¾î…ƒ€Ü>xíÚR„êuï/®
€Çýü£ª¿6-KVÎŽºîÕ`ƒISr婸'Àüì»Úçß½=€–ž¨;>Ç~K)XË1|Å;xÛì¾C•1[éòGTÁVñOÍáøø¦¥P”9ïÿ™ò†¥ªþ¬Z2Œ’ªüû1€~ã€+'iYfbg
ÃÒŠö˜Ù¼'þúÒñeïÒ¯-;;¿m¼Ø^}b"š5VÇA€‰Ð5¥,mxËñרˆRèL?ª~î†Ó蓵曙ŒûæúÕà…É"¥‰p)(’ÿ‘›3ƒ	. /þì°vãóß™éàÌø:7D•Ø”ôÀüpfvÓß-Š"¾¥†•Û[‘\¶¥êùþSqü3[WûÿØfyqq_ü£Mª%EøÕúøï·€FJå³R‡i³‚­]‡°8ƒp8uü×—¢ý§çç;‚°ZrâZ>˜”,/{cËׂe3(eõ¬~ð »‹Š  îjŸ¤iÑBW›MwÔm’õàôEj&Q¥ÏÇ?ríá7E/KiÑü̹qàn¤Z=B»I/@Ôþ[³â
Âî¶0KYwÌ”:¤g+‚>¶L5íã_æÓŽõÿDšNDà5Àû¶®‡a€z­Þ¿ñû- €’›,•¢qè/3…Œ\?ÊÀž±E¡.P¿4ÆÁ8MXuA¨ûõdKÞ’ç-Kà¹KŽë8»°n{c‚
À‰$ÑÝÑLT;‰³Têa>BþGDËéA}+!o¾qýúõ‡ow\NRÙÒÒw-KÎXñÛ´ËvbZ2¾™e™±…0ZðoÙqüË…–ø8p­Ÿ (Ôëý`¿É­üFn$)—‚(0iÒ‚ ]º„%–ð;œtqñLˆ¿¢š§!œpi"¼¥5êe:ßypÞÏÙçQ9,¡JàS$HDÐ?Æš° øêovØqˆã8‡oߥâœ[R»´5LÒ=DHH¯µÔúÆͧÿÇðOØðˆô,†œñ«åÓ–0èÇ-õš¦÷Å¿)·d2+qæ“9›mU2!J¹¾ÿZÿD¶Å’n4hxø\e¿E‡ÐDìüaùèg‡EIúáÏhÇø_ÐCnïÑƈáŸZVìSÙ¶%‹Å¦¡­+Ø!ü‘ÄtKýÞ¿ßz¤]u³¾¥wØZKq\ÚíÝ»¤­1­DšÒíúõËC<ß·[£|צF6ñ—(‰làRÿVï·'µ9áƒÒÿõ øöŽkh3kSÇ÷‚êãÿòý[¡ßžˆÖ®ö$Ú“f‘ÐÑ6¸cý:~å(ÇpRNþ¥¾‘µ¹"Æt,³ÚA½åø^b%ͳÞÊ„`Úª~:ϵ{°”zÏË?†)<º}Ìçböää¤bÿå_þeß~´[­n½½|è¨)4ÅÃPtØŒ«[ïJqZËãR÷à7oc`K€Æ$µØ[Æ£qñ3Kn¶•oó¡ƒHNInu%?|?3Â÷°òþèšSÿҹǔJBjÄÓ„ä9éqF®GÍ:íÂÏÅà¯0À_òýö-o¦šffK:;ñòDrZ£Ì€¯àðhEá0Ó´ò,¬ÿ3ó–Ó¨tØâG‹éÙ¦úþÀUÔâ|»¯Jl³.Oy”`qÈ+3†Öó¤½#ãÅW¯©×ßÇçr]Ã3FJ×6Oü_ŸþÜ0€:ßm	?…øñžÇMÝÂ8œ/OQ‹ÓLØaØ?…ÈÄ;.{Eí³Ôgï+
 ›ª1ïÖÎÅðoÊÔݶͬTÏ_÷Ô9»ëm Žø'
þ_ɼ¹œçéààäòmˆzÛñ=|О{.NZŸþüšN	u/ñlµÿ:Wê}Ÿ1‡HÃ×%~1	"(ä8D£7L"…ã3ê˜1PÄ·Û±áoèðS)™¿tõªz…ä‰RÃ¥·55O«ë±ˆ!
.Ö¥ëJ¬>´S*qe 1€íâéÒ¥i›"W)„`Rœ—z~L(Ž€f8þ¹+–㋜äóùv#€D÷WP™/Zy¥·ÐúðíV|Úó|=/“:t‚9½+åþš†+Hˆ•ÄÔGëªÀÇ\ž.ø')­«ÿO¯Å|dY•C¯w‰bœ.ZJWø†ÃeItºeö{y€‹¨#ð6:ExÁ¢¼A$Ð
Ö¿Ñ%m¥&×3Rùᩦ8&'Z{»¬µ¡çòZçUˆ²ªHøÍ‘ðÅþ(@¿i´%»U ‹ûßñ¨ã@¾ã,¥DÇ$¢§=^SñÏ‹~ñëQ@Ëü×èX+‘4=æ4Œ©|ÏÆW/_ç×#}'$®‡´¸>jcÛ¼H8²íÓzÔåç•>?ŸÏ`‚dp©”åëcázá&‚Q£”…Ó}³öHˆ;SþGè§ö[èÄ^¨)³ôî3h‘ø$ØJC”j6q7—!EnˆÉë;ã_­ÇkÁ?¥ºŠç–Ù³<%;¹e¾ ±¾uEcZü›ñÄHkŸLÔÑ@I<.†MçBÿÔ¶L3$èþqa©xª'è-ÏìßöýSé’Z“ïÜ|ë™*Âjc-sf†}³¸‰[bZ5ÿÊác­·³Þeí&¬(T··à=€ÎÇÃy­‹‡AŽwõ>´xÌ.¾È21¨© •B€ð‚÷%Äó(
ðße­^£¶R
½|<™’ùÏ_ê¾ßú
—œŠ¯j!uÁ¤µ?ŽÏIKb‘ümðù­Ö;Y´à¿ÝùH§sã戂½ÞŠpÉån]?C“Ö¾m£`Z&èîew˜iW@î€J>‰R4…
Nz„3¯ú‘øÚz5ð,KÆ?PF òŸ€ôÕ¿uèü=ÂИW׉Ö=§{ùتSÒ–•% ÷Æ¿`kÁ¯©NÈ¥·á\rº3þqmçGˆÿz§´»žQÖÛŒ¯¬ƒ_Å:úÖ€üòÝ8ÂTߢã÷[Ø9Ä#|µZ$§Ûà¿Å½ÍxÛƒ/°“<áGÁÿX”nÐVÖù|”ŒÒÂI»Ëë2_é±€@«]벆q÷‰Z®º¾ùÊ âå½®eþÀÊ©þ½Þoz­“„'íWanSðÚKaÑjOÖÿÊü qü÷Òÿ1„“ö0ïøñ¶Øÿt]«?¥Ê¦ÿФ—ÐëÇýúmËŒ@þ”'kËøoÙnêd0 ª}[†ÿ·h?Zf~H¥·ÙÖô[¿ý™´ÕUþÚÕª¦·«ý/¦ßz7Öÿ
¾°@5ù^µzûSø©V«}è\iVW³ß¶c»°Á	 d€÷ U5`ä{ïý ¤Ó’±§×ÞxCþÕoÛ§ÅóƒcS¤Fú_Ñöo'6VW'&"	Àà=€ÿÕ÷d		`oZÂþïÛ¼ëFäShŸ|"ÿê·'·¿·bs‚ÄÀ7xçámç	ù–qTªÑ‡ûü¥G7ÁçÆ¾«ûöM ½}û=Þ€ªŸJÐOÊíåàÓ€öûVpA"€7¾‡Ð㓾x²›ÿֲœåCĤ	Ùª­Ž#ƒàAlC™qpkçW¶ãÆ“›ÈÆ¥Ñ(|•Deî×_•??Í÷ƒÿ9J¼ù`ãþý§&ÀXEo@û”3ÀÕ÷®~ú)	 •PÞ±à_Kÿ>2È }ò½7øO¿=É­%ߟÄõA÷z ¸œPؤ¾T‡½K1»ÞÑ,Ÿ¾í´an¿óŽj_ZŠÙÒþŽSƒw«i+˜¼IzlÞSf‰¶iÛ¶íT*ØÌM<÷Üs#©Ú|?ñÏ}>€îâGË3µ:@Øñ¯îA{3ú¾¹}/f?©‡ù×þð‡ßï›Xظpbßľ"p»
nÀÕ«ÕOoûâ ‘T	 ½wÏÞ(à‡–î P|ï{}àɆkþlŒ¬Ö³”­jšUæ¬/Ÿ:µ,M‹ð?U—íSK§–{y)Øç=}éÔò¥Ó®Úï,ZÛ	ìeawØß­ÕßüÃþþSÃö4	/¤d¶+¶íø¶ý2gn[–bÛ##–Xуã?5l§,ÿÏ=wêàH*	-ßúù«þç«
ü–ª‹×ÿn5èÄõf¹òæ›Ññ¿*—K•È.ýêÞË/ß{Öõ—(ÑùßÿëýÞ÷’¡„¸¿º:#~,ðÓj⽫ÕêíÛûô•ˆýñ÷îÝ+Yˆyëê…÷ï_’	 ÿ'¸k—E)Ò… 5,…tñþîç\®ÚˆÙV·C(Ù9}iùÔ¥Ó`ÄÄ÷’l#~”íKËòþÇÿ©S5A	„™¦
xÏó0À¿©Øÿ’Í·AÎ[¶=lÛVN mdÙNŒÈÛSÀ/©Àfúÿƒ€aoæóŸ¯Š\ûîÙ IDAT×_"õëÿßùNmF@øƒ7+åÒ›974Ø•rh—ÿŸÜ{6çÞCÂ(•Ê€ÿï}ò½«Ù—}ÀOàÕÛ¨·}ýÿTlbóôž={#°GÆÿê¿]ì_¸ 
€Oú€'þ^þ\ÏôXfé¶cÑ*À«sŠJÉÄ5®À…z½£]“íºS¯ÇìÓ—N
—êŽo/½£ÚõÓK1[ÞŽº¿¦<ˆ>€ƒdåP€4-øëlÑ<;P€U°L,ɶ5³-ÕüøÀdP@ÊßÞú}´ûüâó]	·×ê»vÕµ*.øM>p>(•Þ,JÂàv9´K`ƒðì/
÷Þ, È¿8ÿú¯?ü^öêËÜFÌž%;tü<
XýTó	ôB^ôô¿@ç_ظ/áÑßxb9×®ˆ¤®@«°©\¾E¯‡û™lÖ®;n½Õ¾D~·nƒ€ø'®+lê¸ð¾ÿ؈o"ð»5›âôé̵ÿÄetKŸÿJ5ú|€2ƒ
ìñî/Û%a?[øÅ=Â0hö¿¸î¿f×_&eZâ“lLˆlŸÀx5€öi PÿKüî#?ð~ï{ê0À†ÿðW¿=‰л§5¥@Öj™Yþ´2£W·”@zÝÍÕÉÃÙ>žÌÖÜS>þ…MÝ•ßÿlß[¶)ØF
m—Ñ-}þ+Õ+‘ýšÀ¿°?ps%yÿÈÆE¹øgý/Ù«?$e€“"ÉŽøÿAµúÞÕ«ŸJøoÓÒ1[
¼!$?¨ØFít½vº‡Ð·@0pÏÕɃڎo;Ž˜3ðÁlÀ¿o‹÷7cçÛªmPó}›¢mZ¸(²´½÷ç¯VÅõ—üÏ3Sõ<·K±ã#[ì”üÝ…ýCìÿE€þ…=öíÛÉ÷ŸV?ýAâ½Cþ8àƒÜA’¤˜ ¯¶“(8Ý}Rþ­-1ÿ%uêœáþ„¡ÎÙ·]Ç
çÝâùÛmGo^£[³ƒ¨?õmF7w=xýÕèóà:ߤ4S1JDœd—0köÆáC›E‰'ðáT@Iðþ«Õê§ŸÞN>D-ÀêjEÛ›º{	DÿÓÎ(ãhJfÏmnŠàjbtÿ9'‡­$ªŸ±\*
 g‹¯jA"<äOùˆÅ 1þ‡õ@} ôÛ¦ãOzsž˜tàGÓJ(xß¾|hó¬ßú­ß6Ñl”hPþÌµÞ Ü~ž®Ú¢ÍÍÎÍÎF³‹ó‹óóÑÃüWï¼újôðê`r0™²S6æâO[M¨M+:“ð°²RÄ%™iY¦Ÿ¸h%m~‡‡“V2•L%¿Z[[[O¥Ö±
_ý§OLØ*Ú`2™L%©a&tÝ„ßIË4­þœCýögO´q€7ú!¼‚ö/ü(€rh€W8,èçæfÇÆþðs@¿¸8¯iÿ3ðƒ ¿sçÕtšÀW“ƒk{‘ŽOö²þi–®8‹,M™Vœ*NN­L®¬L­'‹ˆx[€>ŒL!@[[?»µTjXjÉÔ`ʲ¡˜#	‡oôï€~û3'€Bà¿Q4~ö/À~…×5ÑvJ±ãŸ›­¹Ccs\`Çø÷m‘kDýWÙh*-:e~mèçm{/›ãß©8N¡O(ôüS+SSðP
(:Aßü
ÜÃñп#¬ýÓú:¨€µ³/¯­¯®ã6™L;™`	j™*°ý; ßþ¼	€ìÀ¨À `ƒöoìƒÞÀŸRþ€Ò¡æ
¹cÜ
@éF«9ާq7€K¶#•Ms7 58}{
ûyŽð^¶–fföb¡PpŒB¥Â¨19€ðxz``e²¸b$ƒÞß÷x×¹-$ÀÚúËëë_Aûh³k_EÐ<@“ !’¦aÁGCéß.>øq[¯‡oÓ2
ù¸âF£ÐGà@à øC‘¸Mô©p4@€ð¯9îÐSà Àü"­æ9N
½€yìÿFS©ƒv’#E>í½lʲ¦3ê8EÐ3MW°ÿØàLö¼÷ǵFB8ˆÇÁÔšÐþƒWáIjp}
}A
à,€ÇAͤ
Þ?<À³d²¯¶iëUO©
bìÅ6y|»zx¯‡ïyy±¥	1”úº^¿£NâhEˆÇËPãóÖh 
üí_À?n“`{CØ@s€Tn
ƒàþQx€ÿ¨F‘î$‡íA®î¡ƒO%=lš6+ÙŠS|>ðEÇ4@øúŸÆŸ§Á
p66˜aË–Ýãð\WÛW²ü4MŒ!$)œ1™ÀµŠúAÀíÙæÒØ:ÚtîÇ—/_þqh6~üãŸüäÇp‡­ÕÏ·ÖÃë¼I«ÿÈ6ÁÅÃÞ¿. Øíð€¥üòò²´ŠÆÒ2¶òçÎ]Z>q"4ó§NœŠl\
Í…FºØ¹|NZ±ÀËçr¹v+ ˆ8 Àÿ(Ðhøò?R`ü;p¶!·¶0» ð_ó<œ€3ógþwŒŽŽ¦F™O Ó#„÷°µ4Àøî|±è²6	}ÿÓØv==ðô”SDúÿ¤ Nß©A;@þÚúÚWøKÁ?ˆ ‹"	˜¸@“ÙnOüÏÙcciɦà¦.Ì]nxcaîÝw?þñ\؃·Ô×w®Ÿo[¯ß¸~ý†”\öÑ„#äÆõÏn\ß_Øz÷÷ÿù³ëÿ|™ Àÿ¥ú¥üR„ø·ÙιåK—êËç|³X<ïÕµó§Î;¾s®'Ὧ(vÍ‹¶Sí¼×^8è ¿ F#øä€ÏÂCà:s³ÿ¨Ð	XœøG€NÀWS6z÷ ó¡³G ÷²)5³BñĤƒ@Aÿø±˜¾÷Ÿàž–-¢ð·}¶yè£88#øÑf‚š&3Ì„d}Ø–òûû…ôl.Úcsc¡MÉ\ãòåÙ7r?öí…¹çÿ9ŸÚÔ×w«Ÿo­‡¤܉ã#ž þ¯Kö
íâß¹!@¶ÿó÷Á/øøÏùˆ;¯Õ—#ûÜò‰K—ÎËúŸœ?uJÓNÏð«… ¿÷àTýM±óyÙô@h+wý8€4`]¿ä€èú|€?«9c†Ò œÚV.×00 ¦ii¶#½C(v°4†÷’ÃìãP·{Ù4E˜<8Yt.f1€âñSS–%€°‡ýQ@8ÐÀ þá+„×Öþ :þÁÿƒ	pü-Êð÷6á¡OÛÿÓÎ4PÀl!ÝÅnü¸Qð]²à,ÌÍýh®àKõómêáyÏŽx'âWí÷ÉûÚ
Àÿû¸Jz Ü!pÞ‘@œ ˜/,xu–êùå%É>wnyù\᜘!ˆœwNÔ¡ÿ/œ(†ó þ!Þ7cçÁ6Ú1 qœph€jðQ8@ÔD)?ÎØ˜;–r]$xÌ{Ú˜Hv¤Ó£iÀþ('£I僈pTú€ð^¶–6+ÎÅBñüd¡àT²l€ÃG&'“1ÀïÜ10ÎÀàªÿCX_ûC4ˆ†)t3LøzißîǶaøOŸvÜé¹Bšt·,âx`/8îàŸ4|{+õóíêáqÒâjáþmì÷5÷}ó·oˆ5ÃD}üà]®ŸÛç΀wÀ>ï¸'ÿäp1ª¯÷bõ÷›±Û1èúñ7Fù…MÐ&¾Íãâwƒ¢€?‚h`=ìüü@‹è`çณD?û`€öñ½lJÓf|Œw
Ž“µÒÔYá
À'€)ÇN
ÀLð<€A?@Ppô¯¯ÿamý*Èd0þÇé!•JX4a%L;	‡S«ÜŽ ëú´›k^¶ï²£½àæÿ‚¶V?ß¶^s]MÞ?nßp9þ
Á@.à_ë–úõòK±úùV»è+°Ï»9ÿb»ç怃A€‚s±R¡Ì˜šÂ æL
LM6OH*ÀB\söÑ€³k_­ü1Ÿ¬™ÃÃ"Cº}ôtè÷œ¨/}O‡,1ú'Ò0@Êí_ø¶_
Ä·þi ô†æÆBÀYDü†>@êŽÍûvèÇa¾^6ÕÒ@‹4eimjr¡¿ýÿÀä¸6 8Šbq’‹_ècßö꺈pw@Hþ	ËÆq@JÀèƒéÏ a<p«õðjÒ°·T‘[ÈáÙ@#ÐࣀBè7x5 !ò„M¨È6Vrôs'žÌÎ.rôs'žÌÏßáèçN<¾ú*÷ñS</•âA¿î6~ÙiJøGÑ+ÅÉ•"ç€I§89¡_Dx
A„r\ãc€A9ÐpHœhß³lŠe…}tüY0€Ï
܆íñd~;•ã÷Ÿ Eƒz`ÿ÷ì,R€ÿs³i¬
òq~kFy¸óêè«)îÞsý½ÝËöé³1ü]ÔœI`¿ä?G3ÑÿOâËÆœ^¡ÿy9 ^M½ü‡?|%ºÿááõŸbïà~I–4™Éxª—m™´?Øoý¶É¦oª=ÀŠêÿ7c÷[¿=éMÊëmwÇ›&»›¹¿û–|=ŽTÙ€õ¿¦™5Ó¼þì&kšÍŠ	¿„=ĆL3cÂ/ÊúwV¿µm®ûD]ŽÇÿw‰è¦Mc ¤›íèÿD×ÏrÌf]ì‡ufœˆ8þ³Ð8püWÌJåb¥Ò¬à×ÀñŸÉ2æ`þó^~T¡€ÆÖ€çmñŒ7ÖwM!©yçòKµVÐKÉ9uè–qyÒÒ´+ª`P›Ù2üAH‹è9WÚÁ¥”Çêʤk¹màŸ³C÷Ól,±[OÃù-n[ºeiVÙ–”`g­aË_{'m“´Aˆ†$Þ1kgõ¬ ¼ÜŸk`æovÏ‘#»wÙ`Ð&¨ÿ‹ƒƒ·tÈÂîßgÌܳùÊ€¡¤°c£½ž]ìü×h§ýûí‰o»s££»—£rZíÀôV$€ë¹nÎU9 F X_/í`ÚêÝ7æˆbÇH/¿<ÑND©@cyMaœ/$Š fëºÂc&Ó¥Í%¶¥L:/Tä~Ø;\ôŸŒÕë¸TO4ý€kgGªHk6à5ÌeÌêøH€lÛ3à	Ðfh¢§­\enÎZZŽ˜(Ñãçð@~ˆ!ê3á£Ø:	Õ€”ûûçFýøß}dD3š¯þ+•[•Ê`eý"3†x÷äz…Œvcÿ›€ŸÁÇ%;‘H(6ÉdôÈÞ9
;GM…†ú`´eYc7ŠÅ[j¿çæ:«oëgs9©œži\¾$“ƒíi›š#ªK Ø$>Fe-åã)&crú0+é†n?áþ²”*h7iÒ[Ô=e:¨T†ø‘K็ݨ€ð<$/d€,%L]1­Ëê„=§‘œn¦É0P€, lþvÃÉ1èáÓ$­Y„d­´>¬ƒA²ðÕÀ¥äÒdK XÚ0‰Ä¼ÜŸ3Öÿ£ø·@€P¹à[ ,
Û‘`;êΘØÕåˆuá×÷áŸd'R©dBÞn•ËVdïÜ»Ú^i»644¤õÀۦ-þ'HÔÇ6Ò££é†‚Ob€ºwZUâÈ9ILO#4ˆp$27“qÝLø3)èW©€{ä¨ÒcêÍcƈzÉu8§l‘V¥>üÐ	þ¾ÐÚ
R$Ä=|¸ØrÝ‹è:yù‚Ù¨´s:‹_QЛ³G5Àn´>8ùmØoØ2 –áÛ–aö t±ˆ"£ñÍiáàk¶!‡œ"/÷®(èú÷ìÞƒ¡À4EX¯T€*ƒ/6)E€€ûC>ò÷»lTÏȶ €È¶Ê/—ŸµB{çÞÌÎLf¯tüSCý(ÀvjKË»NHÀtzb"=-á‘O™¡ØžLÄC‚	€Ìp¶cÀÙ•ëé4gÌ4e‚r·•L‹©AÂZ^d},–«›24Æõ±þIœT† ž‚D '¼ŽÀÉgÒê©M='ƒe‡™=LFQ€æ'ÌÔÒ¨¸—¶DM#Ÿ`6}èã5Ý",(Èæ!MÎ~&
þ
p a`”+€lÖD:þAðn
^¬T*à˜™0Û}W]"nO(v"‘Œ|°×_~ùÃ×C@&³so´}è©~p;5²´|ðà„t‡OסMË×½Øb¡Þ麴¹.ûø¼~x&Úî7À¿¬‰AÈ@Lœ‘G½[ˆÒ¥z)k©#ü¡¿ÎÇ>‘¼‹ñCœ.´îðç*$½×¾áåÎ
"²!¨ùà±£ž÷§01ô¶mð˜žÀžð(„)aXrhzdØc¹0É)¯ÿ`ÏÐ(ŒÞìßZ¿h X;¨ï²Ë Å@óc‘½þò‡/Gî?º£ÑvÖ'€m…]_:xÈ6´“÷6/¨
aŽ&`c¦àÉ»ÝÀ `ä ë®b‡E°äyÞrÈ/5OïÚÁÇW.%c2vë-î‚^½ÝX¾Í§m-="õàë"$Æ^éðÚÿ¶ßu“aÿU“÷ôþ8^ô¹s‚rŠ÷Òò¼
þÁ(†+ŸÒ´ÈåÓhe}ý"&€ÀT@*¢€8ÁT@“O&žÃÙÄxßßÞ¶{Û{%û©h{¿=ñøÇ.LîŸõ麾ÅÅ?ÕþQ-Ÿ%±Å¶ÿ†z>Ïk{¾ˆ!–¼üR8§ß¹5ÀT|ËÛA¬èݸ¬@ðÝ€ŽØæÚ£—Ðy·µPÊû¤Ðá°M ½ÕÓ<
ˆIY¬ÿךа~ÑÄq!ŒrýŸáÛ–ð6ï±ÛÛö–ì§žŠì~Û vçäÑ®ýKº¿ÏóáôÐH1R‹#Z­ Q½¢÷\Øœ<ŠE/Úl}ÔE³€~ß‹GÔÿsüóúª5‘0¸BYì!Afúÿ!qPjpç c™xð‹)?;4ÔÇÔv¦ƒ?ñû÷Ä£®ë]	iqb¢k]™Çüiÿ$½ ¼ò9¯ÿOc•¾?hV${ÿ‡6g€Tê‘]K¹ÜÇP¿=FѤ»¤ÿ–óikSëÿ}»³©Z	ØëýÖoß`Ûduþ7Rß’;´d2‡yq\{Q<Ÿï´ÿÆÆÆ#½Ä*´?éw’ü–Í|âô\)Ïióì‰jÓßäÉK˜:»™Ý‚‡8°77?‡ðb1ûÝž âÅÇ̾È)`zu5þžÃŒõv¯³iHÅ~kùüÖλ7‘Øûm‚¿\OÞÛÏtÚp@é!/á¡»¶¹oöü%£´i’hÝ“¸`j‹€íLˆº	?hKÍìê¤S¦9(ãcuUÁt^"€ñ—qÔVƒ/úüàˆûÚðÆ ¼‰¶¡ù¯7ÁNPM™ð¯ÌÎΪORü¬þÅlê´ÕÎ ©‰}@Hû&¶Hõäí:}N†ON8ä¼Å°Ô™-hs+—Ûfçicó
`ºZxÈKÕÒ&(¢$@©Ô긌vžÑïÏ¢½ÇôêFøß¼yóÜÍÕ›K7ob	¢@ß¾|>¿O:ãÄ„:!ýÅ«ÙàÙíŽwysºÌ›å
ã¯{ýdU:6…Z|—Ùê,œ®z;”<‰D2†ýè}>ìÛN (K€PH/ñµ£çŽªJ¬7„7~©
ÊÍ-àžUbpž›ž››îæàÓþ«ÓÓsÓ-Ô›"Ž ­}ûÝRµç§Hž¨Œ	ðwsiôöT=	Å]Âð¹ÊXd
€D‹­ê±¼&$€¦A<Ÿ‡ÿàþü¿¿zÿ~Ø¥çóž—1´´Ì	`)ÌÝœžž¾°|û7‘ÎÝ\¸‰o& ï!I€‰‰ÕÕ	‰šÍŸ6#wÿ¶ÀaÇêÝéi¸Àé0€`ñ6$ +ñýKuéóÏžœ­›•ð>O"õí!¥žm`o_”'ÒÇtów‚Ž_$ž’(±r©µ·/)ID»”Ê,Nk´—D§ååJœ/3†äÌñi…!fà_°žªÀ½¦þ Ò´ÉâàPUýD1Mfõnxƒ–îVe—ú~7çºL~ŠP½#€]|€ó1y]B\1I'Ýc2GàÀª¬l;Õl6#?Á Ä €ãô¿úÿ«>ŒOLŒçáÀËBœ;áñ?í€vó¹¥¥7
6ó¨"ÄŸã„D_5›_…ñÛ·1äм}*uhºœ	àþ×àòÒ&|âýã_ž>=¾ÿËpÃ1@ÿ±“Úm)èÕ1eÃ`êþ³/?{ÿެ>~@ª'׸ÖÇÜR'B|÷ð5¯=)ÊQƒ’Q®0î,ÖË—‰•„º™µ(€!4©ÜëÓæš
Áé™;3¢±‹‡Š=s'„<*È‘ÈÆƒpq3!k„æywìÜp·*y8¨qü„%iˆ"Ð|Äÿ¨ë»ö¨õ]œ³}å(úÝQ7¬WvÝÑ“=ÂN’ÑnÄr—‰L°»¼·iÚI €ð~͘Pb©áȸ€. hUÀw|"0!\€¥¥e•¦#Xziõí¥7Pˆ.=€‰‰}y…"ô7úUx½ÙêmøWµ"
€?m	at€&ÀpÚ1@ ¾<=>þå—aŸ~òØjuõ¤}@HªîR¤R©û/?ûòýÔàvRa=¹0‹““ÅãùÉÅ€0ó|òÄd¤ð_—B\M qB©¼nJ˜e…šFYØMÚlÞZST9]S‚®«Œ1wç·3a`ÎhÌÜiðN^¼?a&T;3a€8PÄ>(‚„2‘6; ó–h*’¡t÷jا#Ø«wïÂé–î®GfÉ7Kì†NÝg@?ίÂØs°B†în7rxª“”+¥‹Ün5ÝZ‘ªi¦(@˜¹ŸÇ.}<’àƒ)”ÃÜ×VA´à_œ›.À9	ÿBø·›Úo\xiõ7"ÍŒ`B’÷‘\î‡ð'€ˆþG•SÀCpWãÐv„à$‡=ÆÿNú°±±q¿-ØØ¿ÿË/£ ÂFµºzá˜Ô_¤‰TRV÷$¸ÛФzrÿwÎWïÊø‚Ý»GÑ+>„ëÊ™<@®ÄOŠ þbRþdÿ±pu°¦àø×¢¸Ø *spXÜÐÚ*vþ(îc8é±Ißf˜€šïnÿo¼´ôÒM=ò™„NóÄd¸ß'€Ÿ~õS¸¼¯Â0À-é¶‚þ IDAT
ÀÿCÿH€~‘8§m´(-P÷W7VOF1̼J€ýý "X]—cãœ&‡¸wïfŒ·¨õä˜DÀ‡øw΃YŒ$“ç£úèÑeÕ/j€0è§•*å„ꀠÄ
Õ.Ö”Â\´r+)Öœq§1ùûÜ#¦çwî(^?2HIÈ^½ˆ¸3i¸hñ¨¬TÏ9Ð_
8¯T=tW&€=…¯€»?ðð1"ÀpzÄ¿øýŸs™J@¹ð±‚zv¡teíÄxA"ßjb §ø¿¡p‡ïÀà½(†Ðeׂ°Á9?¸ìË%€pÀo¾ñÆKoÜ|C†8H@Àê…ûhM”?
b·¹øcUëDûAÁKpL!€ûø0ÀFäûû.~íðoìÞ@[Ýpó™g6T]¦{ã÷nÞ¿)Àà6SR=¹_YR,Ff¸U%àƒ7ŒnèJI·ˆô‡¨”cA¿Sã†Í–¨žÜáÒJkš•­/uðÈ3ZxÐþ95ê>A㎤ŒTë|-A¿øÀAµt(rêùx_õnénäÝm÷à{”"IŸsC¾aTŒ	ü}•Ïrø‚|n¶F>¯pÒ•€:. ·Œ(uÀ49þƒyYóyîÖÀ”©H kGØÏŽóÝñ€üĸ2
à€c†!¬jHúoø_ðæK€8ÁýU?ðÕW~ðvú<
øÇl¶ƒÿ`üË6`0ÌdÈ$Ä÷¹|T@ˆÿÕÕ›@7ïEÂ$¸Éà븇ÿïÉ
ÀLm˜ÛG(õäŽÐRÐb Rüb˜@:l7
 ÅüZó¸J ë(@û1:50=ƦcÀÓs­ã~Óò¨*€®´í°D@	ÍÁg—?rµ]žP@Áa@øþêëºþ|Àð5J-&‘ñjûq@›N muD„
ƒ€)zÐ!b®1=tpn€Vý±»Õû¢‡žÐÆŒç#Dq¾jî1Ü	@¿€Ð0Èçœ|/þ5ìÿ} úÇÛ<ó~ߎ€ãß'€/¿ß?®=ø¬¬„³áK€Õ˜ÄôP„ÇßèTïÝ»…ù4­…À
Õ*|e«Û‡4¥žÜýFâ‹™‚$¸
‚]RJí6ÅÆ	Ë]‡7ñú\Ç\àéVJàŒ¡¼Ô-h9B¥ni¥R‡—ü3ŽqΤaŒ 5˜»
Ñ8 NºgwÞ(P?ÝÄ’~“çÀ`W˜×B<¢ðEïFÐuúÂÝp LŸ	fN€ÆýÆF˜
 Ÿ[Òá'hþ9ð„R# ú¦öÕOƒÀ?ú±¾Û·«m	Ñÿe	plÀ'NFH«’—#zû¿Ü¨ÃÛÀ‘ Rœ„Èå?W÷"zÀ¯LKm#üjr_|1ívY‚jBðæ7òøé­n›V7:

`o.½ß˜&þ¯V+•Tsî•÷šª°û'É`ZaäÜߨ¸p#)ã¿ßû?^ð»žø-°Î¦Zï¿<ПՊ’íŽJôà Ju¦FV¦zÎg°25¤6NN­LÊ©°ïTob*z:©M*~£fÏùä¯(ömƒÌ?L=ÿÃ(ö²Ÿ§åòÑ€ßdGAŒîÍ¥sBDS™ðïT¯ü Z(\é0*7Øæ(^Z¶/Ü¿pÿã—úøÿÓ€UPîà–•+L%Qeµnu×,>§
“zmL®U¶êUvsôR˜€éÍdà‹Sò|ÅÖù¦VŠaµÓÊÀÔŠìZ$¾ì'c]¾c¨>˰^­(ÅM‰˜0Û³ž^&€ù¸Ð{©³½!dÿ¯îÝ“R]' ¿ŸÜ›Û+ øß™Ù¹3—
pÕ	Ø¢÷“׫Aà…Ûï|üñÉ?æOÿ7|ø«¿ù›ÿ³(ÄY¼´qàãû«!$ûáÀÇÜ.¯S#ºaG)ý%cðw”]f&$…˧Wd:5Lÿ5OIõ#©—€  ”H0ÔÄ”é¿ùHQSOOE€ô¯LM§&¥)L`y>0'¥ùœXÄ@%Àÿ¤SœT]†)%lØ•	è/6Í/˨>N&¡à_›íUÏ?¯ÖóÏÆCªGP"¶¸²–b²øU¹\ª¼8íŸMî-VwBø¹,ÇÿhTŽÄö˜éJ´Ú»ö«õõÔàºoc1r,
pçã;ÿ_/¾îßü0™}å¿»à®n„ —ÞöÛcë‘(gëôÃrØ‚ÝÑëjCQK¾ÛL	¬Œ²„i%¤zZjX8ñ­„jÉ’‚ê顾±__>WýÈУ·Ô5UôSÒ JpW¨Ý+S»ž†N~JtúÐ]OâvI¬À+rösq*7`}ªh€£`™c*Æ	“7ˆ®Çf‘;ÀÌŒµËΘá”"ðQw)ó	À—µ‹vRÿùÙùy¥ž6^ϯúLY©·Rë¸=öÂoV*å7s!ìý·JeÒɹEÔr9Äέø;¤Ó¹œ™Î¹ÁŠÈ¼ñì³ÏÞ˹¥×ýe,
pì€cï;ægß^w†^¹òßý÷o
¼táVìFê+€ÇÛXàŒ–Ë ,©G‹+\į¤	@ÓËxÆr6ü	o÷Ddù±ì5SCÿœh0ƒ¨BÌ0M¥ÊS6O5IóÈó ø'Ãù|É/Ïg°2 Õ?Åk´¢(ˆÄCùãóY}˜”Ã/ñCð}iv"!ù÷óÝëùç[ëùçÉ@ªÅC‘$ÁÎ¥ò›…BIȲ׹ß]¡àfRqr£™ÑB¡"€¤tÚL
iAäçNepp½PxæÍO^o ÇöíûøÎ±½{ãåCä:¼ÿ•èý¹×A“]œC|CV}xÌíwTRü¬Q»ªÀêä}ºâï+‘ÂÖ9ï)Çm{¸¨´U¢­ƒ„T£º”s¦¦ºÍg€R`RÑøtðÒ
8åã—!?ÕúMʺ\uVQq½a}_…µ}вܡ?D=ÿ&bf×õñOx@Î|ÝqŸ$à`€à?´ÓŽ‹ø÷íŸÿ:Á(€ã"þýEõc@€¢mìÛhyÞV/ll¼Yܨ‡
`¨|ìN@—m€±å*keÚåx¿¬ýlò¬–„ÑΗÃH»QÆðÏè6ŸÁd±e>ƒ¢³²iðºL:íÒÙ=Ó9ßn>x‘µñk[«çoëòoµ}àæJA@õÇõ\.'»$7W‘í´›ãøÇòÉÏu<˜àõOü(€^usWH´ÿ±÷þµU¬äïïæ$ü¿¶qÿ5¹.€§¬n„1À;vôú¸ƒ]nàŽ9BÖ&¤ýV¹“§úƒÔãS¹Kï<ŸÁdÛùp&DG
ûunNÏ
TcÚÃ\ÿÃÔó?’¦ë%"ó®cv%²m´EÿÏGþÉ'xüëþÅþÿZ˜ˆí¯ÒîýyP™£ÓÃ’]/äß!§O»Y´©CÿúC¨ãcò!ç3ø†¾ÉTà0@J	ˆKŶCÛ³ˆòÿ^ÿù'mÞþ'òñ~*`k2ãÆ}Å|	Z”ßâOp|ïùscËßÜŸ.LV2»¤ààÙëŸt<ô¯;*lôAÔoýö(Ò¢º3@ÿ;û6vàßÔœ<gwÞ	—¤¸¨¿Ëp.­¦¦UšZ³]l6ÎÝ	ó´ä5SJ›á4âþÜ¥ kf,‘MXY+›À¡9p?Bˆ
ç½oó¨ˆjcnOMÒ´œ„‡••"Ï)òçHÆqôW5í™òÝ¢“Nk¥7Å\`.ð-|
_*ZØ÷ë"̧G×{yGörvG£¡5þ$^Ê/·‡ƒ^eOnc˜Y¾Ë:ìå¸ÎVóÏ‹ïðÆëy¨Y*—Ìr©d–J8™8[k2ãZv­™Ý½+[Ñ´i@>!8÷ÿ4>å‚´Y®”y¦õÁ_2p¡Î™D6›Éš`€ŽÕ!”ýé_Ðóf~¯¾-ÕÊ"‘%4šH`ò1üqy¾?ÕŠSE,%XYÀTƒ¢Qüá_ü)àL¬V¯`r©ôÌ3ÏÀùðÖ×µ…mFãçã21ÒÉ4|Í3„àiš‘IœÌfN^†ÿÙÌŽ†poŠ%§¸™Šçk~BBâ¡ÆÚ®ôä€>Ìžà¶É T8¼—NcSõøÅV‡Ý‡ÿùóç‘ç-fVJëfy½l–ÍC—`»šk•µ
‹±òß> ü±Ì×ÑâC‰%±¯h WY¦`Éd€€,&:#]ü€a”±i€ÔnðYúã™L@5pÑ
žß
„ÒâÊÔÀÊÔ–`¤óÅTñÊääßM^‹§9CæP"á8”zö™Ç?ÀŸ?	„ÂJ$‚y@ùð€T`œd';øõž|þù“Àú¼´¡<Œ~³,ͲmËŠ¢½ãã[Æÿù+}m_ÀëÑY#~ÅiÉtŠ—ÛÌÉÓÒÕûõø®R‡ãøŸçP4X©²¾^©¬¿U1+Ì„±µìîŠi®ÝªTšLk’é…™\ì.À±½)«F“ò €ª¿7Ëfw2O
»3ËÌ&ˆ€2vÊÈ„6'è­÷°ÿçYLønH(À(†ÁwÕÎÌ/òƒ¨19€ðxz``e²¸bSÅ/&''áçï@|ñ…3´#Q©H$r¦i–ËÏ º„¼_ÀïÎeaZfÒLÀoT¦ýø#ÿ ÄØÉì@p½ÏŸlð¥[yu§Ò£ €ØÎ€~hI+Rûömÿçû°}pzĪXË}‚ZU±æ×£3©wnïz|7¨Çw]©¿Xäpâ'Ð šyˆ•X³¹»RY[»µ¶V	`LO7é™t#NÏ4fàª)3H¬É!kbK·q)nÎÕjÉåäÈÎGvìlÖJè²7
ºú€»
ÿÂÄc¿ƒFMaÀþ74톿ɠ+Øÿìp¦¾ŒÚ“_ L~1å8CVåµ×*æË4¥gJ::š¾ˆøG€ÒD2iYƒÀ–Ÿ$45Ä<99òîÎïî|þùìå/ú¯¯pèð'ÜÄ|*J®&@ÒJZþ‘Òé-á¿ÏÛØ`˜€Îd?Ÿ`Q‹F£8Â_©ž{žZ^l\vÃÒ;¿ßuT©ï^8ŸFõøÿ'Nœâà,‘Xký-ø¿^O ´»Y9RAøßâ ;=Çѧqù2PÀ4ظVб6°÷Çåy«ø*À*dö‘#»wìÜ™µ¤”[|Ãnžý. O0³Ý±rñðÀý›7´£H‹À‚ üýOãÏÓXaì€øbrJÀÚ&€
ls Ñ,ÑíÃÅEÿ|3€p8QÒ¶’€¸Aß¿HÝâÕ\.dŸ·ÿöÝŸÁõ>ÿ_v^>Éc$ÿ+èbtÊWbM£W&í„-a!%ÁgN„€‹b¤÷¤7ÿÿøÿì3Àvh^¼ÝÀ›5êÿ1Y-ì"9r¢Šÿ¢[üýe7V_Œ’q±ÿ¿ü{7ªÇü€"‡ÿ‰S§¸[áø‡p/¿ed5s×­µÝ·n	ìb»ÈtcæNúÂ~„âL̼
 	>ƒX—ïö]øÏç48þwcÈZY…À¨¼eóÚÅ„°i…Še÷@c
€ÏCt£ø‡ÿgt<€§w=m×Ó¼¹øwØõ1…<09YÌÚV¥òZj0eýöo4³iò!ÑÏhúa[ x­ÿa¤”|ioêOøâàÿ·»w¿û_
Ù—þ¯Ü†WŠ€²Pa{¥O•¥Wšmr«0.@Û³gÓøôÿh€>’¶/þ£r3Ö{}y¦‰\§xù÷—ƒ»³ø.º—â“ÅòÿQ=¾‹„!Ä?Wp@e½"ð.@å ˜U*·¿èìÞ•ï?ø¿|y¦‘¾<7mÀ½oVÌ
ü7›ÜàøÇ%äKF¶€Øç°{g&kJ3k!­R†Î>ñVâV"qÙÆj% oN˜	p,€¼ÚQhÇÁ
˜×	è?6 d€"‡?—S“_wíN厤Þ:2bßù›ÙÑ,ÀÌÂ+gtÐ.À—F¡¿†^Nã/:Îvâx…Ý?ûÙ»xµ»û¿d.7h@=£¢(JU§Lu­ÒÇÁX 	`| ôÿ\ëCi{ÆÑ=€;‚º‡Rü5?ì§žú„ÞR@»]¿ë^þý®ßÄCÑ_tw]–¦èr€ àQ¬‹.À©SpÀ(¡óÏñ_©”­¦a®5+·n!þo­5TšÓsÆ4@zærzzÚhV€šæE&¨ý	@`”²f!Àÿ‘B!“UÇ£uEavÙ´#û
ÇbœLè 
ûÏkZýøK«7´ù¦n¬pñø‡Ç)À<`ÿxòç€+»†wZà¶ifGüÅÿYXXÀ0À+ð%&’ƒƒ#ØìÁd2ÁïûEþFöra7($€wÏ\.¡¸p…‡:¸&½	b&Q
"øH4.¨÷\`“>Àp®­ô±´M€²¾<ƽtÆëÑ£d• ‚#0*HCÍïF¼#(€Öãñ¿¨F_äÀC(ü @¹TÁ1Àÿz¹b–Jéfemmí¶µ]Ù¦a ¸Ã%ÀtcŽ0¸•Y%Q¹xѬ 3€ët‚û.ϰ²ÙÂNÁ;¹Ðc
Á^NìNXà›8H‘0HOqˆÁ€ýÏÜÐn,_¿®-Âþ“Èþ8šÿ
Æþ¦¸€¾ÀNèõ“Gì”mZ$GG‰ö!žéŒ¾pF{¾7t€!@XI3œFˆj~6°q9û|aç»ÐýÿíîÏdÜBÀf]>.jHs´4[ë©c’ÀJZ–˜x{_@›“ç¹íÚÊRJÛ²Õ=N¹Ã¢ztv”:¡Ê¤ J=º3	€—‹m‹E¥¿ˆRÀÕã»—Åt="x‚ÿ (Û{ãÝ|«dÙ5ðná8À®æZ³9==
`æÎÆø5mûý&tyÆ»5!€D k²ön´wîÄ€.ã_Ǽ?K€ài<°h‡1°¸xö¾q•³Â€Oà `ßÏ&‹éÄPÆ5-;›½ø7L3=£i3gÏÀ¯W0è€Ú"9˜½Ã/ýõ|ñ ²ÿÙŸíxw§ýüÎFV¤y÷ß1€ÓVÜÿ§ò_¸M5µºk"áåݤÜ
\ƒîÿ?ûøßî g¼áÑzÕ=êÑ1Ãçr4#_k=>ûÉÕz¢ß墧 öÏŸàÀF¥TI‚ÀþŸ•Qc7_`-«MOÏÍÌ4 é™9 €2ÅQ@T¼´‰³ñ@µŒ˜Ùlö)‡Ÿz*›ÝiéQÀŸsËÄ¿Ç6c<“ˆ²M0Šó.”óÅb3dBcj
C€˜05€
à€É/Ь‘vÝ!+•͸s Q‚7í¿o2ƒÙ@ºŽéEƒïoM4Œ 4•gœÌf?~þg;w¾ûîSÏãõ†`ÿΣ=†Ú¿¬´|Þµ„Ø·|ó°rí|ÿÛ<`†CÐ]Böos9xù­T€ïUüûŸà8Z ~`?€lùÐ[ÉÊ[ËÄq2£y(àR[kîÒ0
x¦13ÝÀL éiÌÿ-üq ŒÝ fÝæUŒÌ2³G
¶½Ó.`6p‚øÃ<iÔržn¿M1)H$b0ö©õe/Ÿ÷üà~‘ ¥÷l&°ÐÇÿ6WŒè];,\ÍdÄ»]ëñ[+YÂD ìÝ0ú'j‡²C,y(a›‡ „Ä}v«¬UšÍµìî&/àyÀ<Lc¶‚ÑÄä½&5"çã3ff3 2Hh&~Rž¬ùéýšv™R ûM›§:ó4ÀŸØ§2‹\|B§&Wú+ÐÿLâDdè` ‚Ô4?<Ðh4ÍÑÙf“™CäCMóK	àÙ̇å9&üPæ¡æò4CÃl`ÌÄë}úÀ?Ã5
ŠN¼Uoº!þCc@ñ¬´år³ÙÌY&+•À“Ðô…BùÿÙ{»ß8Ž3_¸ºªkª9IKž1§K”ÀvF4mÊ$5ž1 -Ñ‘
Çšd™	ï…Aôh±Áb),"@`‘‹X<Œ"ï^¼WÑAnÖÆöf³'wÙØ¹Û«ä6ÿÈû<õÝÃJ–ý8gJâ«?ªª›õû=Uõý´ûA/2¨¨õ€ÂØR8‰±ç¼÷]ÕÞÓÉ'j1P]ïl0¦E}»)ðÉzž+Ìðÿß]øO«¹nzxÀëd½µëµ´fñ9¶¯p+ѯ_WˆÔŸz…’Š[,ìíDije0.¯ÅéÀ`NÛåÀz%°ú"ëaSãOsz5QµXmððÖß™–“©×ÿEy=ÿMtAZo^¡ñ‚ž‡mà*ñÄùT”sql ^äzÁœoï{¦½îåÔÿ«öžÝoŠÿ££ÿ³€ÿ.×ÄEüÛåœÞX~Æ}–ü¤ë¿]­:—ÚÓ¸øõ_Ì×ÖÞb½x)ÞÐ_S.äÿ…;ßÑÇ*½è+˜¥o.ý/GŽg{{„Hž][{ñ
Ø„Žž$ócCQ	wgÆwžÜ-x·$tz?î•@‘K™Ûš9G²Éd¸•eùú‰é ø|v*µð¯ŸÍ¡nôŒiò,ßc¥7Åùs¾NeJl!66b±194ã€V~pLBxV€.¥ß|åBåÔ%ݱo}ÃN\MOŒS´òÚ˜Ms¡Ôö¯îß/Ÿn´ý#HøEì‡.ðYpiÙæ¯tòîŸür/\8ïG`ºÿäR÷ÏB°€)õ«=¹ä…àçš\}`Oϵ,«¹ÛpÑN.ód>ÉÌ¡”D×ÜâL},:Å sç/íîÊ]GQÐT™ÿ8sKË,Bß‘ñ”CÀ]1HÒüÇÏBéàyµ€3ëˆrœF©¤Өݵ«katÕ±7·Krå{»þÙÙ1WÉiéø!8b£Z8Œ9E€?¥ï±Ø‹ÿðQpöýß»áþ1(Š75 r^wQûQâŠûÏKÝQ™Þ}7`q|š2çÏÄï
à IDATÿ‰—¸‘M‹Röo~5N­`×x[}d~Ð?‚ã$PÚk¯O‰wh‡ø_ào¾ËüjßÛï[>éw{ç`6E…/Êþ®Öo{*«‚.-…º»·´(U±¶´tü¾çVpYf™ëÝÙì…³"YXõZHîªÃûi¥(kƒÌ¡WÉö»y¦$­.ñ>ÏS)õp¡¼ç4®ê©GY&@ˆ2[Fv?—,ØÚn<÷+L‹"À¿RòE2PM%ù`®þ2OÇ
SÑnN¢<ìî¹WÐë-”ÿ¾ù‡
-ísœý¸±°!(|‹	O3Hxseåv«0ÿþȳ߽_œD>àÿMÛ?͈©cÊÂà/½à?*ëDïÝzOwatˆ¿ú«N§L&üðtàÓ	¡¯	`ņ98O.”àþ1Âû}˜ù(ø1
EP˜Úœç¼µ|"üÊ0Ö…Ç—ú+dݸ*(ãŒÙ
ä?I1@ ôÜúã7a€%
³´Hóq°·\sGæeÙÒë‘Å“ÌJ^e$õ2?©ÕÓySÞBÖ@
@$ycÁ@ ç,Büm6‡ÍÁ¦/-ãÙ»ëT™ÁÆXüƒ´Ï÷ äÕµ—ò«jÆíU€û¥K Fàœš+H–¸>›Æz?û}ãÄç+”8ô«Ñüài~-ï55ŒƒP@2ò„XBè.Íá}æy¾ë6§Ü3"PÊrc¸ìó9'½Ñ6ÞØ¨KÎ~yã
ç9uÇóIÔ\¡"2JßþðÑŸ 7ÿÉkFxß#âKåÖ›À>‹7­½óü…Æ…ó^šá^^êŽû“ßÕKð¿ê_ÙèQÿùîû.À-Ãõ~l~GœD­7[ÇÀ^RVW^_Yy¤õ
RÁŠ%TB¾»_2>øàƒÖqøƒW(VTÁŽÞzKEmðnÚ+üŠü…úþ«hñ< c¡·~ÿ‚ÿÓÑÿO^6­âW¹CØ­ÿ÷oB2b<"^Æc>Bú|3_«lÉA´'³^îriLDYbÊ-ÜŸŒeuž¤ó‰Ùjn„Y,ä—Æ‚‘é‚qÂ\}àá¦KPXo0ðçïÃao¨ò ;g²w€ÈKúbÀ‘࢞]’—@êKÇØ=²ÕÕU­èëi6å}¼C£›ïÜ8ãæ@W/}ñ©W„•à0€9ôæÈ@ð^¾¿é&Þ£G©#€ƼX/e0 g
óL¤i/Oãî},Ý-˜>uä7èi‰Qüsܬ«ÊߨØ04]­S¯90̹Eÿô'¥Ïz¯_¼ÿ;÷Êï»Í:Aò¿ù&À›V@õü…¶~ðGôÜŸFþù*tÙêKVøO·È»· i56à—Áo”Þ“tô´šVƒhåH?…¤Áа‡Ô4€¾.xŒ!øÁøÊØZcù­€>
åÿkV
ÐøÇ 0ËoÕ}P¬õõ+0Ný+U#	­€œ{~ÎIÿÿ k^W±ÙáŸyä[ï‚ðî»/n0µºO:|£J bfµöÕ¼ÏVË—œÆÎE–ñ:KÅéÓÁß,gTJšZ›·V# …'õÓž#5¾°`|e¸¶ˆ[‰¾YˆæÀG‰=`bÀx ²ÿVŠf¥o¿ÝÃ|f}¸r!*€;VW1ÔT—!˜[(\O	•S¼ï7nÐ7	)­€^){‘N¢–ý(ÿ™AOÞë
$ZãyOZ3c4èšï	`ˆ°ü‘¥3FzyÔC] Gà	ä=ãXCc™4>\ô¼9ŒÒ´s*€”oTÁØ0&U•_tƒ
€s½¼J:À§Qð~à¶ëÜ£ôG‘[D þÍÈþ©€’jžÇ1¨Fàßu"
 ëÖ»ÖŽÅ~ôWãÅŒÀ›oúÜK)þÒdà5þÅÚ&¶"°óÎܹÝ×ÏøåÖ-ÃÚøÿƒñ¨"MxÝÀ2Î}ËÔþO"|W_}Iü^(­ß@¿†“°Œеڎ~­©UCÿø.0À­wÿx똸J…ä–2ŠA3A—eZAè÷£k{ÁÕ™„•ÈÌec¶´ˆ¶€’×&†@Ðüg8Ñ¥–k€è±xT”
 ö(Q5ƒ^ÚdC·ZEf -™Ò¬¤µÛÆ‚À»0È.…Ïc·º
d¤šáÛ«®§Y¨ä—‹ææóô#ô†×¹WÂ@™úùN9	JqŽÏaá\ðRß@>=z4êzúBÒ»iš¸‹>}ÙÞ.²+šêÕÑe„Z>6hуúÐF
À:Û AÆjÄÏÙ‰C+9	‡7î½:úÓŽ¡' PÔ%-ç¥ö"Êìè¡¿ð&4Ý67ßÙt|¢?Š(4¯ªwùuGJ®yÐN@ÕÿM	’N‰RÕÛyÉKÌÔò61üK«'ÀŠVÜ4”„…8oU˜û_}ù¥Å?À ˆpüà÷NÍ(k(ûѪ0¹·p#Ù·”ðð¬ùÕ—[uaH°܉zYîuѽ¤4AC¨ï‚ìÿ#è7`-1í°“ºÊ3@Þ4yâ!'Òˆ9¿öW
TA¥ü~þ	ôß_˜X\š˜#AE÷ù¼Ù/åUÀ@¥{	*âTøÝì	ƽÔhØÏ0)­e†àˆhÆbû¡X˜\Ú?pðž
5
ÐÃó4íáÇÝÒ˜É:”'c§dœg1! zžyYäIžz}ÿFc
à:’+ÞP8áÒ´Âr
h9P¿æF)Å+ñì<"Ôôé4€^Ná|nœðF2ôJ^¡Z<šÀàž¾¹&\huîbý¢~C‰šå
sŽŒ	øøû/ƒ1ÐÿH t£
Pò¡Y3@É~òÎ;ä=ø~ç=T@òó*c¬UB,€ÿ`Òäˆ3Àå•ÿÔø\Ó’	€Æ‰· pÎÓIc¯¿®,€×¼ çí<†ûn@=³š€L@øÈ{_Çy¸jò5K*Èí[dÙ€Wþ" •¾üÊ·³@ø`
€ú?™Ü*ÿ®¤ÿ_ÿ,æ¥|äó+MÝ`qœ–f^Då}Pá§þ¼<ñnƒé¼Á„qªó2§bó÷‹›À%©ˆ½Ì>“þï`€,£À„äêÕÜz	xŽ,Á½@JÀ"j •¼ÓXóƒDw²FC *­ŽéŽÖ9 yÀY½.õÞ‹†e¿C> ƒPÁIÀb÷Ó«A<¿öz‚Øa5Ðƒã  žP?÷ýúźVI 4–㺄ÄÎm!Á´–B
ô•4€/ÿ_•nítýóÂ…ÒJaPTgÆ{Þ#ïøûïá¯ZRÍ£¶ª€]-ÿO ¥þwJþ?M¾(ì;F ­VÓ‰`]¯;P~¶†
wtÞá5˜@%o`ø>ÒPÿ_s“‹pþ÷[êk
xÅÿWÁœ­r”|­)Пó0þŒ|½ßd6ˆ|ôKJ£%‡ÿ~½«¹K9_7—"Ô/ðÊÖpP½æÕÀ•¯žr¨æN¤o2Ú;˜n:/vò0ó~sIü$;õ†8™y5ËÕ<ž«™³àÕW–eÆÆoJCˆ¢5Ï7ï(ìß(ϤÉKƒžB°Ä3ñaA°ŒÈ\Tà®›	Ø£e×ã%þ Á˜”½^
Ržvç(ÑŒÖÖp€ä$cœü{Q!òœ	¨À•oz²!€ßýNÀGá$ú߇ãboü{£[™Ð~VË—÷¿üû¿WÄèßÜ|ï½wÞÑ–€Pã€/ )gàqkÔ,éè„›ê©@Üû%•ƒÎ˜ÍjŒñ¥4$ohPºÏkn	}€
7èy¿4¨E>(
3”M=¶øúk¦°e²\7`lMë“	àþ—ÖWzl°D
;è˜	@ŽMzÄI·¾‰p°”SÚ[ò]ó¡¿Mæý¦l6óÐÏOs/’²LÐpb
*ÿ±É3VC/ þ2øÃGcžTG½Æ°IE“‚]Ý4Ðk‚9Ýë¡{]W¾xÎ}j‹c€1YÏJüKV1¸dZ¯›’gª} ¡*I„H<þÉ1ü¯P*@"Løt°°é¡Éb©‹`âo”tGôÑ(ìãåyŒáà ˆË|ÖüXüŸ&nÈÔ¹ÄÿjñPÀ†€ëÝÆ”TÒѪÎ(¡!þõôV;ð»ß½¯Çÿß/Þ7~Àû÷@ì·ÔG˪Ü8àM­Ð‚ Ú; ùÁ
ìh@ÍíP¾öÿ$À²b§4P2ZFÿ·ÁièœbX÷-h.Љ!€`ÒÃWžþ¨Âý0 ŸhÿŠc“e-øßRz€Vú××'¨f>Зvõ+óÆZ¿/ÍR«°q*ðô‰Ö|\Ðc/ŒÖÌq¬ë"
O‘ylЄ¼wƒ1–É(Šd¦o`Q–E4pÑC‡îAy½õäÎÖÔ~\u=±…†Z‹›/œU]žÅój“.aW°|,.j={ÐÌDÉ¢>ÏCuýp ö'Á¦ùÚ3h*/efÀ«êœ˜ƒÓŒ˜vÊÃõ›ÇÝÒ×>>{G/¾FI_›V^·¯®e½^Ôs1Ôªêµí˜^j¼¨Z£Œ¢ÑÎ>êê§ajB¯ŸøÏTûwq€‹Ì¬Jr>	
”	]–1½Çž šðzDý†òÄ_Ći;Šš_ †‘1%vô¿xßM	‰@«Pú6:Œ ü§gá×øP_T€ÎÕ̱Ó7uµy«Qc¾ùÞ ÙtK­§5£:ˆxB¼‡×çê°ê¤
¾wŸEÀÔÈXL,¸Ê
ÎU1LA`±¨«Éó¦:ßÌsµw8ªü@­ët4¿HEO‘¢(‰C‹ è,¤È៹A:ed½ìÆ
ÝܾÅQsÅ?!R›y¾žÓTû5 å¨'€ViÄŽ€FF]ûÔNÀ‘3ÒåÞÞn™åÉø)GŸKÊõ騱éÓÆ¥ŠïKá߬fÞ%äì5¥qACŒçŸ¾¢hBl·ÂÍÿ+üœ`T‰JÑÔ.4⨟H7.ìþý/íŠØ|xÀ¿œ…SÜ&tG2Mãµðfà›q0¡º7‰k%˜Î….€` ó>!~hÙoKÿƒµ•>
'˜áO¶ci½´èW¿
7>Âx(¯[¹Ì´µ™Ÿ—q+Ïÿò¼-°3_Ñ5ê?98 ­5¹†`è¶ve;T%¡8c³ÅYCùÝ,С©//w[Èíð<™/»¥m8²~¥OVa»c¿Àµó…í}N>Ê´¥›Õä9rztšÔ1@·¿.MO
ñ5·[îîÙkZã.ṩ;~R…°?O&´Ù¨°Q“‚ù[ÃÏûÏŠ´à×d€ÄOñ@^‹xø@Ï*æpEûYEG5{yÊìÞ¾]¶ÏǨéò;Ôå°›5éR­I¨  ú¿ÿÄå41ø¯T’|7@[­÷wøgm	ù¸²¤`¸Jȵ¥K’Òq
ÀÆ„^7¦a·²¬àÿA»±p¶c¯içPŸ¤¬•7ìLÖyŒ€;Œê—(k_^Ú£ôà»SÑîÒR«ÝòpæyŠZ~	@bùÝ?g–_ýÇ¿lµåat4èõyßòxLÀuú³Ö$£C^«¶Ü@ö<ΣQQÆåÅ‹8Åõÿ,»xN.ZðÀŸŽ®þ²[©ø——ï,חˆd—î¥k{öï¡–MÕºjI ñ¥éSû7xR´T¨_ŽÇÈ8i·Z‚µi›‹ŒâÙöðóÏû[þM­l±M}	øs\0&DE…/•ÃÃ±ÉØË/¿úûå—§â¿Ä|Ì=ø`(‡8Pl6ø
ÿFC6çøË|N|gî;Bý¦5€¨ÂÓÊ,˜Ø‹ã¿Õ’]üZŠm¾Þ%­Ö’ÞÀ~©ç¯Ñv«¬ÓÇ…„n»°9<í”Ãm¬·kuwûAÄMÀt^¶Zy·†ºS:{󇕷êqk©ÅZ—%àÚg4€.ÜÞmµ×¶Ý]ï¶,I­¼åËxùU`€îááa§Ói?x€:35縀 šÈ\ûÙ•Ö•Ö•™ˆÿS#hà)\	Ô=e ÓùôÓCoøÜÅÏ.~Öúì“GíÏ€.Êz«]o?u?µ€òŸ@÷_]‘ŸT :?¡dw¸›[
 Õjtk˵®™G9yúÔh?lÿð	°ÀXX>kØÆqØjÏ1x?jÿ@€úc6„ŸÍmãØFSÀÜD¨T„òC*P_˜Q‡7^®èÝÔ_Fa1 c@B¨M"}0TP˜”´¹Ø¸T+•hæxq =‡²øp?XZ‚¼T¶Û‡æ|hÇ?«º½¤»2ÊÖÏ Q¯·:5 30²Ðn1ÐÆ¿Z±eíÖzK•oDq½óxn}¯søx§‚ÖzðæöTûlù-l#”9(Š­Eá¥íËÏ$‘¯¾ú—pú°åt:ÐDèšó­]=Ø.=qÃèWÞøÙ•VY5p_¼‘´_y¥–ŒÁ·»þéz§û)Ø?ûtÖgŸµÚ>/’dÛZ£GõŽÂÿÃÏq–èŸÓÏïÆ»Á.Úí‘]²kð_Ãç­éÚÐ5øËA¯g¼qÑnþ9ÿn¦¶Œé¯ãƯɯ-´Úúý(Æô^>@?ý[Û¡ël=@þ§èý3N@üooþÏD“Ò&m*3àÛ0@Ø[Ÿ÷ú
`hÅ¿&€!(þbnî;ßùÎÜmmÿGœG3?À‹ã_w¶±yAW~ 1OÕ_­]ê@fd¨eíë:pÞR‹tNŸ†oÿN­ƒÒÖUмv44-u¬ƒ\´Úl]•o€ÇÇwàsï-Ôé¡]­öå }¤ÛÆöÍiße´ž)¥íˇÿ]ùª¬ƒòrˆDò Ó¡Û2ç[]=Y/^o“õ{Ò±íc¡2nøxP{»sªó@"*NÜ€äÓõõõO	šíEPC¸ §Õù´Ýî¶\¼˜Ï)n7ŸŽ*I ÕR¿Ý‰´üa­fÙý"ì—¸<è㮎Pð6nŒø£ÁG¡·‹ã_Òøµûc´Á÷ŠŽwH{Ôý·µÐÜÞbÊòghúk P¿™ÃÛh÷À'0«ˆx:1 c
ûú°íMÈH8¨ƒ}m
q]ØËXЊ¶ÿ±‰3?À‹¦¥vEuv`¤«¼—+w ctËuÈëzºg
lò5ëÄo·y7¤¸¥®‰'³@ô&J0¸ºÞ½j{øN»^ïìa}{ĺҺ¬Ûgª¥Úc€¶š‹D)­/Yaùz2)pO‹âj €Öƒ‰»þ|««$&Xíëëë¶ÁìJå8GñàÑÔó©'dìSt~ŠíýÛôY­õiÔêâ¹vMÏV3 õ©3ø~N>ÿ|ísÀÿCSŸHp
°ë½C2ö‚ ÇÕåŠÞ:ç¿$½ŸTùÇ]e†~Ô.xQ¨
"Iø¯ÍÓ­eã#0¥TøWaÊôßDK`;8&Àç÷?Œ#ö¹¦øâæ°ò˜Q9t°o¤·è-ÔkÞ¨Õ‡‚SNÉÜÜ¡ø[´ÿ$­ˆ$ø=ó¼@Š—ÚLu‡oµÇÜ⾩Úë]§Ä„Õx}×,>ã/À*w°þ ÍZ,‚›æFh·üüvöêU‡ÿze§^ª¯¥'탺ýÜnwŽt+`þ–ÌÞ²BZ—¯À‡øoµàGfÙƒ±ó†PÐÑu3ËZo¬Ó‘º“¨ç3
ŠŠOKïç³Ìækvä£|SÚ×k0|?$ð(€%е Â…䥈«Ì8ANüà'm ó œ‹^»Kxÿ:‰½K‘Àû1™-k+‹ÀÔpð1Œ6>hÿüù?Wر¤o"#¼l¿ÿÜ'jPÖj
8D¹ |nÿåã¸F$D„{9â÷Í/4@€‚#‡Ÿ’vè“:‚`¿`Ô_ÖmÍ¿üN»-Ô+éŸ(B#^m´Àf!6Î]X½²‡õí….ònk¯[n€¿~i©Kºs ÒWêKrÙ„*ß9	[‡ÝO»!¬=é¼
SÒu°ð³+%Ç<@7ÐhHá]Z€Mü:³þN€‹»8
ð™¡4t9¸½àE
ϧ8>‡ø§fVöûa¯´¯IùïSÿXExª”‚a_ À=þ¿ÜŠø~Ìý[ÎË7÷ÿÛ/}pks+ªÜùç; ñ£Þƒîâ§sj PŽ6Ñîj€PóŒÒ>¶\
Œùâ1@àlkrOö4¹aÝ$¤Æ4çûŽÔFÐ&šáÿ€jùì°[rùH«ôëë¥X­³ŒóËuÊÖ#·À¸µÔ#¸.ÆèvÚV©|SÝä¯v‚ipݹËaû®¥ö’Üÿ Eëõ·êÚiåÚýË¿ì~Ê>åÿcçU‰ â¼ðÆ÷ÈúÏ‚³
´ô»-?óS=Ÿ{YØ õO×-Ô>ÆÂ Y
	 N—l€&ìíi7=á(‚]ŒèÔ½ÝA°K€~?~ÐàéǸài÷c5¨@É Ž
ÿý&kÍᘇ%í΃OÀ÷W_ÌÜÞàw´ÉϹ˜ûéÜœ¨à/L޶*jïT¡ì›(0Q³¹É¾‰ ñ=5?
¡7Ty.”
øñŸƒ`6ð
†€|¿\¯¸3Þ”Ðe­NI"v8¯ë7;€®n·Jìn+˜û‡ñpïî±úÃ|çÕN=øå¥r{[sºësí
£8Á†t•Äryö)$èáðÙ5ü¡Î?è~«ëT‚+ëXô•’ÒêkOÆŸÝ€–È£Gðy?ê¶µ@ê8~‚F† ‡þZ	0Š€„*€z?BöUòT
Qp-ÿ…ÑPÜÆŸüñ ÛžkY@›^CÞÿáÁmÔùðŸÎá`œŒ3#ˆhÓÎÐ?L›y¾ùp—½¸ ‡ˆñáÔPäw\¶ÝŠÎD}d<€ªo=¬ÿñ«9Ïxþò\«2¥½(`)EµÛ—]Ì›˜sRê0 Læ6ˆaé<Ž3®« ‹Ñº³¤cøWFO—L~>5øw„ðYÖE 0ÀgÿÚN·ÓjYåCFã§hÑf終Ðö<¢ÔóÒÆ²9 ·Ñûø)ò1Îä`n5`lÿ&֜̕z4†¿U“{™5ð×
Ÿþ–ጠ Ô*ÀsHs¨ ¢ƒ	 Çÿ•_¯ÑpßÍw¾8úžA þëê?Hùâo×××ÿ–¾Lp茎þÊyÌgðBÀ(¡® ÚZÊ»¹¶8ƒEu ‹3Êô.³ªZ}Ý/¼ƒŒìêip.«1P±»õ¬Äˆ|<Sߺ­ïñãÎÅÎ㹋ußžËØ¾ÉíEy‹^ý¦éŘ\ÊUùKR•/%~³×+‘gfU°µ'ºëjñ 1˜í¸jà˜l<€±çS6ƺ4ð™r'|¦Œ¢z·ûÜÐú¨ûÑG]Åìa	þÇÙ0Ê0O¸],Œ}±Òóâ$ÿ&€2JñÊÄMxB°IÔŸks›UpÒ/Èü9c¨y€"3¸bìþ9\²8‡sÑ&˜CÀŒÿ«éÀ8@+,»»»¿p'Ãa˜W‡Ü¨ š(Õ8!ŽmÐ÷Ûðª08˜&¨ IÅlðEôÿt ›7àó&f8²Þµ#SÇã`¶ãs5 ¦ó¯ÑñLùj}3WËé/îí\ìî\¼8Èë¶þËX«;±½½^®—ÿ÷0‚‹ä’Â7Ë—pa0.6ᘠÎã~ˆL	úö_i™…ºW®¸åû¥xcÏY41ºð£ÚâGŸéæ|öÙgšTX÷#h;¥æ=
™%0ô©fÚ"¨šàjÓƒaÏ^`ŸWM›ŠD8ÐÆ(@	ha<€Òúk¶ÙÜÄð(ÍÍÍŒ@xŒf¿JJЇÕ\`t
”	Àá
˜jüß8…›½ÃòÛF\‡4þ	¯$œ¼þ‘D@šÄÊaY‰+³™@/ÈcëÿU¾Ûe“Ï膹±Õë㹓ã¸òmþâ¤ö¸µÇÖ óxO@퀟2ŠÆ›_ΗßÇñÕó'=2@©ùŸ0VÞì^fІH1wÚàú›ú÷	#
éxȨÇȘڊA}5éwøX;ÃØÚ	¨ç+AàpÀö¦™*ˆ36ÍáíMÀ—b‘Ð,¯:LòTJ™r¥ÄYVÅ8æY>MÐbT‘ÀsãÅ´W}ì4Ô×þf-ŒÆ[8&ÌUà{>oÏWÙÙòߣ`>®~hÖcµÀ_´tÄ„
âÝç
©u{±˜uõYš(ÀÔ²¸¬œ÷ò˜¬e_“Ô´V/5ìÜɸÚX8[óÀ…P“×ÕÁùûkZ”Û*¹Ûˆ,#¸™v*Ìf¤âRv	 Î*à‚Ë¥¥$K«K/ KãœNÛP^œ70MüŸ²Ïg6,„Ž@Òë(ÿ
”ü;ÿ/Y´%ðãÄBž›€@}ÍN8«ƾ´da¡üvjÒ@ÿƒö„muã½=¸ý“üBbÉ`–f©ì#¨sÉÓð*_ñ»-Vø*œ¾êîÄa¢'K^­Õ“ªp=>á•z«s¾üœ§IEuú"ådo·²—uT2lOhóã
ú7š	œF+Àªç
Y–ðDÈ4µf>Îu“”§K«««Ø„„úÓÉ
€ŠÛ(G½Ñw
žïÔ)x>MI!bvÙö6wxzçõņ™Ð?ŸŽâhT¡òÜè\è4nqø¬f‡ë¬ØMe6î…ó¿/À—–â¤Zqø¯fIle¯¸‚cMUË"©æ|¾âŠJø^qq>­8¾–}êñ[£ªò@òCFàr0m‡Ç	hûœã’¸Äè1Î`K,Õ‹ox4à@¤Úè‚eçç7K€ŸœÆÕD¼rÊ=_r=áq›öÞYXÀCùÞÎZ³©	 ’òGtôX©:’f€‚öCË\íœå§Ë&"QáþË|þtÀA”ÆqhíÇ8Ý~33«*"¡u€ösxiºËgÝ}–Žûÿ sð´Z±€ç("!oи‹
æýfS<ËJ})=tÏJµšHÀG\µ @¹Î71Õ9@©ž¨ Ê½×NÄâ"Ð%•4½,×R'¯e–BpËhŽ‘?Qîã^ÄŒ<À#€ÔWÆñjÊ+"®ð”EÖu†ñdi̧óÄ©ßì5Î÷›ãú¿LUœbîùDÌcÙöî5ç¸wp¼WF@gDoLšÎ+ŠEwPB?´s]"œ‡d
€ÿ{ÚrÂOUO&à¿ê4€N‡·ÛÚ¼ã4`þ]»:E?.™‡—RIfÝ}–ŽÈ µ3–¬É;ÂD\ê:<–iHd‘,-ùl5[Øå¨µº*‹)'UmÈ/P@$±zP™'¤T¯]Ÿí®<½Ì/{|
Ü%T€þŒ¾=«K¿ý6cB«%XNîQÃDª]â˜â¸·ÛÀÏÇèZö¯¯S›ó¬úÌEº²²’:-ž%¼fÊk Ú’¿Š
ILtu£¡ŸªšµJòð¡2û9üâ&»9fRìÊËÚ)ÌÓSŽcM}*!èüm5=±k@øÿ#5)ï_‚“äføŸ¥‰ ×S¹¼Lp¶›ÏW9e—óÀ}-F	ìTô¹JSÇ1úÝÒà~ôjSAµIhcF@sé×ûƒb¯d÷Üõj;UŸ5
ø»\^N&ÔVS‰³Y8ªÝ~Ã_€i+Þ2¦TÍ	§ïĸ_¹pnOT&ÂòûÍó`4.H1ǽzxN‚çjfŸiïbs'Á¹P[Sì¬!=àêfÿhd8äUøñð¡÷Äväõ%Qú{àkÿ‡SàÖÈý}D°Ï;í t„‹iTûnüÝïŠ0$ÀÌý7KÓjÈ¡W°”ç-åÓ´^ΈÈlž
žÄ¡›*f,4b43ÌïÀ…óÍ)uñÊõMÊï–ò¢¼$Ø"M·Ÿ)à_0´PC`´†¨”t¨~”tÒÁ!ÍÆZ¿¡æÄÿL”ìÇžd²ÝN}±‘s

‚;š8@('@âÝóC†FÄCxƒ~ö{L˜‹š‡zKøüø’0oOÅ ÎøúâŽr
 £y$Žkÿû Ïø¼ñLúÏÒÔWEI=|F>#¸ÅçOGd	Ýi%öUPù­ÊŒñ8£Q”¸A¯ç¨¯”GÇ_"‚†=ÈVVš*jö(GŸŸ3ø£ÞÇIÖ½@ ýó^h®p•Ýg>¶—ÙÒrBváioì ©Î'~³t¦tä¹ÁˆæØNSÞÇ‚W?‚úô( ØJ0ñhÔ‚(Ç.Ъ˜õóYšêÄÆÏŸ–6)£·¼i¹àÕ hÂV«`«C7@üÜõ¯…y¨䵯Ãi¥Pcnê£ÆBAä«ä NИ„nǘÓp=þyRÞûN€BQÒhð‰x¨Q$‘ißbNv«U¬Œ,:§è|ÊKSAÚ³ˆFÁb(½ ±ç?=–÷õÅÇÛ
ÿΈkø?¼T’™
0KÓðŸ"@*âyó(ÁR/QÇþíÂÐ)ϤÆß
ŽrU¹@i•ûHÑÏQÿ÷!¿ëú3ŽòUí¸ C
WÍóK¬z€ð„º)%r“KK22>ä¿¿gû3Žûc—ó²H¹”œWÅ¡¬pµ<4“Rí1É¥L¡"Ïd’Dn/¦Jó›	GÑyøý<+»…‹P~>Õ^ÀclÚ‹§á¡wm< b•æ?.§õ‹ÕÇ´ç?];]~?A}ˆzTx)§1‘!&y>[,;KÇáf”Ï€"ñyuG@ë?)€ðô %‘Äf‰¬Š Ö¼ªxÏUÿåµË—×t„ƆÃa„ä|`v
è7åË¥$V8¨H Kz90.¿ÍV—Æã&"\®Ü8Ÿ?o(ar<÷|ª½1< y?„ÝYÛÁÚvÖ"µÉ8Nª @ØxXð¾Ój5šò>j§ÆÞ¯/ÖøÇu@^`„…|o
ê`ÜY‡Ÿ¥	P^]rÞFÐK89Àø~÷åxÏ]?;v;›T¼ qX0^]Z•fþ*.˜p›ðRyÎxÇß¹Sj0C•©25€)ñë¿ëŽÐË€ÅÔxÈVös–féÿÌÔû30ã‹wñ6¦Å˜¥YzvÊóRöÏa½ÑXˆNªoLYn_p·´¬¥÷ã1ä¥ÀúÇ€‘?³…ªI/gv»ÿÍ^Ï3ß?{ú0Ð6ÄÖÖÆF,6¦mÕ5‹˜?K'㿼ޞÁoµ•ãDéɜđ¯¯×;©:v;Ÿ@jŸD¹ÌEî–,ç±
Ô‡@Î’ËÓg3SÁ·^D_è[üpØIÚ…,­wf$ÒX«íéÓ-ˆ
±E[¾§hŒKSÅ×@–„R*r(þ?K«ÑóÈÙ±+"R«û›",Zâ7sç{¤lUŠ0?̃ò@¸Gƒþ —·«‘вÕÕ<¿Š*>ºþqK€HP…WB±
Ëž¥„ï>¿‡Š/
³KÙÚÞï÷û¤ÿN¿áÚOTHwsYß‘Y}AÖÃÊ)½~ÖøI4VŸièÿol`.Ú‚_ÞØ˜ò0ͯ¥ÎÌÒÿeøÊ=:Ò=‹ùýç¿Ç«îÈÓ‹Ãé6JݶkíÔÊ;'ïŒ:ª­µ°£cýõéQß5z{ˆÓï]Vâ®WQ,ôT õ+H'Q‚b>¢ŠÔ™}“ÖË“Ð]Ê
‹¦R@¬\ÿzh/ÜÞôom÷¨4¼
&@ù¸€·{6(¸Êø¿÷½z6µ.¾ý„…<:"Ô†ÙØùßêÖÞT†˜–ÿž³4KaG9R3{eDêYRDúû:íQIc–—£’O!Ïœ0{ùé™*º@S_ˆÿËùÛo#‘ÆåÕmŒÒ¨ÌhŒ8•#R»îE„FŠPEQʇÌËpöë‰&Qd‰¢ê^`ÇXÝ¡»±¿ÕïSbÕöè!\!AÕÆnäba!û(/HÙ¤÷5ÈOªËÿQdÚƒö]Wÿ"°œÀ/8Èü=w÷fÝ}–Ž	lè—”PG¾›K8Ì`oÄ?E"Jq…—¡µÚ¸/ŠƒQnœˆcPÄ"jû8	l8Ü?þåÇX_aÝ äÔù·® µt“b‚âˬÊAõÞ™R>rTQÞf„Ž»,öëDŽ˜§+++¥§\|xo¸WÏ¡eÿþ6¡
§#<¼­ž=#kôØ_{BÊÊ ŽºŒU™¯RloÕ¿Ï©L”’è©ÞÞi%Ù`k4øˆ¢Øoœo”èßçL˜¥i/‚ÒƒQç=Žú$¢eda÷c£°JM†â‹::AûÏ긠p³á½l¸ú@'·÷?ýøÃäYþöm¬¿d‘Øû푼¼<‘Då½bA÷_U î’j.MLh`DÄÍ”êdÜ#IV¢æØ¨e0Ù6•}…%5Ø; aË»=ŒFTi>ÆÀn{%£Kï0ïƒ+õ0†Ý^ü!@\Á)E×ßÖÆ‰®o¡P±$ç´qX
@{‡ÒÙPà,M÷w´faïVyç³ ÌC:ú¤ŠŸœ¦TÆj¡6Í"×åjJX1RCwþ© 1Ø­«Ïà1"?%Áfï˜ÐcõÓcâNÉ"ظ+m¯„?.М"Ñ޼IAÙbyb€.É‘{¼R*/R1‰œ¦Qý×ÃÈj°ßoôM9Ðüî¨ÔþÞø´%Ü-µQ{ÿá_ˆ±`Päé‘y˜b„=zþ`À°@ØÍÍûi³4Ôz~6%¿ß'¥|tôÅ	zti•>
EX¹ø¨4µGÛ1œ&>à5rdó /ñüÐOÝ1 |У=e˜á>OP´`jµ\‹Ù‹ÿ|°8îpþ´HΣAê8³ÖX,:ü×ÀoÀúÖËé›_~>Ejz(PßSGæÇ鯝g`fTȲã_s§"5ú·]Wƒ€6=ï—3ç¶¼™
0K“×QÈ*ïPæ÷—ì$€¨ôöм –Bùf«“ñ÷5Tšc⛚GŒ7®ƒ	09€-G
ÅÎúú,MHj“ntÂYÍÍlïÙǮ̚6À<:B¿Zn÷¯6 Ž\qyánÝLÙ	RÖÔê·ºVÒq-¡òÇ1@×çÊÇâÁ üM9´íÑ1ôØ`¨ÖÃ
LLjò—»Þ6;ÔËKL/XŒÔ\\ü‹ÍVW3¡Ö«•¹pWdÝþXø wxÓ^7ïæc+P‰ '<ŸaüÃÂ9÷÷¡yûýp¹!û¨k¨f€9¦~40s©Fyx}dFHwï6Íf³4h¢ÎQÍbˆzT®—âŒ]«_™9giú£¨‰R2j*9ªÝë8ÕN-ªÕœ6À ™»}¬J™tÛU£jȽ–×ë©ËXýâWÆT<L*€«¯Ô‡àòåö¨x
¡Ã¡€Åë¹þ¸
XFú.V¢’*€ˆ³8Ã_¤TçY°6`E?‚1RVgJñÜàDDÿ^¨gT` ‘V»}û»£ÑÈ-ø5Z~?
h¾¹×W0HˆzÞAc‹‡½k“áZ€
P®o„ñ‚%Ú¶<–ïíîÍFgiäcûÏçÇö£//úgÇWükcæÀ	ñ üæ„úÈôöœñ¯i!òàd@5u•ˉÍy†ŠTbLWµlªãM:Þt賞Âiùù"KÃÕÀãí@Qws`û ¹æéÊŠ-n«”ð¿¶hÿ–DÑó&P@¶µ%Wý=û=9Oev¨±%ôyHå¤Zí•Ò0ËÀF%ÂhÇ̼d±€9¾à…””ô#\X”»×Éü6±¨Ë[?üÅÆ3Ùæ˜D›³ž>KS ß—ýÐDVù ?ör9(ã¿78Ù¥òu1@H³V_±Âô`#æH€ÿö)d¥Ÿ÷óðæÁao°´¯)›¾89`CèÐ{ÇA
”++Í]ÜÖ-`€[ÿëÖ­­[j0GØÚ
´ˆ¬™ïÓT€ÅçÆ¿’Ìÿâÿ2TºŸ©|ä{y~PR e6(˳²?
Î÷xXs¥™çùJÝYÑMÒGñoT€¼ÙïçMýv¿×|èØ×킆Ÿ{
›’ÁpØZ¥a»5·û@0J—ò~‹ô·úˆ¸WfX[ø›+a¿sÒô”-š½Eoʗ׋!ªÙÿv"¼LéÍÍÍ› ÕßÖôoŽV¢¼à‘ƒÿÐëûÀd½¼ Á"[D;á,áÍœçMîv#\n6£• †¢^m`–olÜúá­_üâÉÆ/žÜ²ñh,~î`8 Àg}–ާ…q %æ{„y%æJNõèôéÜÌ2§ß“æJt³™ß̵€F`3˜ÃÐvWeˆÌ›JXküôAþ³ƒm1à±¶Oþ{vò/rC¿ÙP4±¸,ë÷#(ضGf««ZÐæî
å}šO
Æ@ÁXÜe–“pâJÙ†?õJ)öûd»gŒIÖnnöû7sL—ôl{ûÆè;80Ëÿ”ÿa›Øc½hTÓDnÞ?kõÿ~seËtÔßï'Ö% àןlüð_ÜrñÄÆßüÜz9ÅÕ‰øK>c€Y:®È^õ‰[øˆÖú6´|ç=È3šN·¾7à•¾´fA…8ضˆÍšŒö¡ÖTF€rýihooo›¸X¿M•Ê ·ÝÛÒ@µ¯I°
·pVóoͯR¹D—>ʲ}€T߀Â?’Té%¬/v“¼9Ð8ËÛ¥x§ðùœÈß¿¹ÍhaµHúûPãM¥#º@xpú†wâÝê)7£	~G«Pa…—q»ÒÈO؎´	pàLž>±ñþæçÿðó
j·	r°Ì:û,MP@væÁ”4yicnå͛۹'Àsû`û üAs;0$ȼÈNÌj”5û7WhS]ÑÀí®›‹XAæd|XLzo÷×úskèÂm•Á0P³Ù4
TîAUžgÐ0šAûšD¾Qøñ.Pÿûaäî›×××üŸ£¬dþ¯l”èW@C:x% e5x?àMUcé–n0~Ñþ~xdPv±ô¶®@3¹l€°\À­[ׯoܺ<`L€ŸoüÍÆ?ü\_ñÉÁ Àþ¬§ÏÒd
dÄbàdËÇò ¢¢Äcî@ džA€š>ʦ„"ÐÉm¢ƒþWØÍœÖt¾Ñ@¼ä}¤Û±úÞ~û õ‚ö
zƒ`ð£Íï|xº<7RÀàts¥ï]šûù~ßzçÉ~/ßoæ[[dГ4èu0¢C@?àèïßì3«€ùpa1Oj ý|R2™nöo^Ax¸Þ 𹲃€Ô[Âø¢?ÑyÜäU­1àB€[âÉŸÜp1…W>9 }ÞglƳ45å‹A6-Ÿ¼{ 4AÄ–}€åɪ+Í`Xlé&€Òöey“‘ñåúšo÷·ß†*}‰½+
;@å€p_ÁXy++êüëÿHŠŒ°¿ßìÁAÿü% IDAT£”ÁçÀÚ8C»‰ŠÁ5Zr–ôœièFQòÇôòEœd›ègžêûÊØ4~'“Ûúÿåoù`DPuÿ¾¶0À­'O6Þx²qÃíÓØøažÅMå
Îgi–‚ài†órËù|hll€A¼ÒfõA=ÔqsÊV< €(.	´þæ"
êô¶ß~{;¨ÌÞÃA h˜R^óõ¦:o¤å>1`ÖìÑ}Ús°N¶B)ô—^ÐÍí~I‡Ï£`X ôƒFßw&}	üÿŠÞÒ ä?ÜÀÔ
×?ñF@nýnÀ¶„¨ú4Öq?·žÜºuÃÇ ?ôçn¨Ppÿ9K³t<±EÐ-çór*@ÓéfhÆêu6 ÙdÔžghàâw»^úË‚q¿Å&õõ5¡ªÞÛ †]uÀ*@àP2Ø2»­Ê»mãXÑßÔÖÿþ¶aƒÿÓS_9¸I)ËÇð¿Ai(òáùš¡©µðc@Ç
^¯æ%oð¿NJ„ˆ—NlÛ(Hׇ\ñø
æ?÷«…š@\´Ôþgi
üY4h²¨9°çÊÛõþj}.Qìå€1\woÏ÷Qd¬ö(Ê2@Ïdla âšgÍ¢ºRùðËû{ùbSÇéTë}q±mO9Ô?¸å
ok3D^ZÑk좫™Z»·¿1¶¯œ†Š‰Ô"Ùfn—3(_-†ÆÉ?žol¹ãv ü|ÆkÈ¢}û~ÕÍ‹—ÝÕ](2:(Ç@½E„æ[|=7ùWo¹÷¿Õ`ÑO–K³>ÔÇu4w@ý7žlŒÅð\­œi³4þ¸ÍN¤WÜ?;¯y)Íòv½ï}¸XX­ßíÙ³'ƘP~¾¨¶³X°ãçU<u»Žܾ}[åoßVËrM<la&±~™K“Ípå}nÖßãØ'Â¥ý¾XW®>ý~Ýa<€ñço?[¼¼ÇáŸn^w4êF ¹¿6,’®\ÕmXŒ˜¦»òûo,DÑr£a× G-ÎÇ
Ñj-ð
ò?ŒP^\Ít|ÍâÌÒD(/·?9OŽmÝ{|5ýøÅ'ŘP~^^ð
@y­=› €LŠ€{ªõ
<Þž5vï»×܃[ïÞÙIï/@—s>zDFž2(Ï{Fß wȽµ5tâæwÖÎðjr¦ÊI̵J߀§«.°Ð…R=#œÃ¢Ó‰ÛÛÕÚf*pH2vnœ\?ïÍÍÅYwŸ¥ã½ †]Ýbòò—–—«ªË©o׳¬¶Sœ>z£=gTJêÐCj J'I½¦º°h0Âö ¿§÷E{g«¤Ü†çØ,öö®]³[%I&ôy2	1x†Û"^¡9?ω¨îÌó(Iª{D^R[˜ç¨úó=Bý,›&ÓI89W~KãñNà·ÜÇww÷˜]xï®Ä—˜îܽS¿«]€TiL¡OŽô¢´§%øÚˆþ{;÷pØÝÙ9C•¨Y£¼ñ!pQ#pÑ0žT‰Žÿ‹öƒOâê™¶×€øY÷8ÅŸ—ä3˜¥ÉIY ±éÑevü¼wJ"6T	ØÒR콄’³HˆÔšýYîí\ÛcµÜé
;×®í¡ìäÊldOUh”¤4ZÌs:hyxÞ‘€‘çRINJe
R“€ è=e/ÈìRF€(2ZØ…çÛkUó’Qãrâ̹q /ÅØÙ‹¢½kŽ9R
;9KÓðOxõùóÊÄ
ôgNw®­íCƒTüßßD¬ÐßÝdYÞ`‰qªó’£BŸZ‰ˆxŸG$Îä	”ÿaÑ7ðG2sÂM$uÁÄÕ«Z…’ãµ9÷€ÚŠ˜Wñ›ö%’0Û'X¡÷ö°ޯ˜Ý§ÑpïÞï£M×”ÃcZÒh¨ø¦wÔ6,{¯Üs OJ&ˆ¨5ûIЀ*‹™ù{Äzo+
@¹DLÏÆgÃyEé&+e6
8KÓÜ€¤´^üYyÔ(YèÖ2¦ë° ’GÂ3D
7©ûA
Fõ ¼A„^V”Ðiæ[‡èëÝI)Î0éjxOÑã€y¶šå¡Ï€˜PEYàæØ»¼æã•(§ü‚RQÖá…`‰gÄÔã ÷îÜ»KwPú ºè¨T (ùo´‚;wP¸·öŠ[Ë“”'í5Ê	þA¸#œ	Ôü£üGîÅ}PC
â&9[0K“S}‰¹É¿ÏÊ#–h¸
!+J[{0ôË™€?‹6°	lþÀ=ï,Í’'€AnVì«òM›ošÕ«¹Y^kW·‹UU^˜z÷ëgÅÐø…ë9×Kqó\¯_ÔË‚¡E@fUp9ÜÏßD)×ËdÇâÀGfÃhÀõÁ%`ƒÈ=ãB·FL‰Àp¯ØÝÙÓ„¶»·cóú‰ïÝÙ¹‡ ·ÿf=ŠFTP³8éÙ%½Ì°	·;OyÅ\‘2‚wº`L½ÞÄ´8”è×ñØøúìïýà{ÐèÍè{3˜¥I`VÀ?gÞ+a¬È±ÌIñˆ`¯ÉÇ¿þøýîØx<€À¸ˆ%l¼î×Ò³À,ÎgìøóØC;Ç8Eå	‘çÄ	±7Z.­Z…«Õ3L¯f5ð´xÓ‹¥Yò~;VRm¾Xò›”?fý¶Ën¶1Ù ôéNœX´ŸR:ö|UR®§ÏCü¼Šv†pícIäñÇ¿îûz®ê>@qR<€cïg–f©ÜßtÑ ‹M>v³y!O²oP~!Ú¼´z¨àm'2e,ì®p:ÖÜ6 Àüór†‚Ûc<
ø×1qa!ä“v@®§Ïhrðy"þQŽ›æ©ÊåÅsGG!·‘ðô„„Ü·=tù³nÀK†¯fY›q!„(ŠXS5€Òû™¥YKfLÍôŸ*ÙÃ|œdV¢`<€o¢–¹Õ­Õ\æívÛ,×Y\¼,³Òäc€XÀ‚¾c<€8>pI¸¯§ÌUyÎ	™3tøµAèÇj90Ü.We;Ë<¡äiÂNÿXSñä9ðÆx†ßâs_\lÄä‹/~sÝi“¶/+æ–þwgöƒói4žÉ‡üc¸`4@~¡~žOŠ)@TüOò?ÙÌ0KÓtX=Ï?¶Šºž¶g‰ÃÅšqZ Ä
EÅÏ¡-g™ó«g±…³¼­ãd¯]^d4º|9¸ã`ÍoÕmmj.ÀÁ'ª&.Š»2k;™–å4Í«n±A‘H “]´IDŒbÁ0N’î)>Ö³Äþ1‚¡@Ò¢°kp©<÷
šÓÑÑÎoÈêýÆE4ºÚfãï<¨-Ž+•"T*T<ÝX5fúa80¡$Mêõe.–c”ýEÑþQÛÂé%’¢Qí›Mž¥)¢B¢‚,ìTÉ%kË,V†vçúK×Ò€1F½íñOãƒÉ>æ
öZÝéìY#.rÉÛ¹š	 £EHìµÅ×0žÆ8Y~«¢_’¶EüIv µl:Ècn%~&%¥€P
ê
ÿWYÌX‘9@?`„Æm.eýê²Ö9ÐÆhg“íýBù È“è$ñ¯5ꮂrA9=t*6;’õ/~#â£ë_|¡	`àdºÙõȼ J;¥ŒVÜëª0N±SŒF­²ª 3`–&&qÞ.–ˆ\Ò&£ikÉ£ž¹Ê/Ò›ãBÅp½	sí4,ûÀjuÄâ …šHÐúG¸l~Á´‹¢RÑ@&)Ü@èÚ„Ñ‚3IÂiˆ e´Nrûé„u+=%Ï©Àѽ€W¯¢™“¡âÌ…œâï{‚ºq¾¸édrBJñª$9õJB0Þ7P;,oRà¨Q¯‰‚ÅmJ4tY¬ã8†ë…ãN·i%ò.Œˆ	x=õ½Šb€gÞ¶6¬Í9h1<;­pP!€bõ4IÔ¸@´ú¦¢R0»àý°™
0KÒvB0‰A…¶øò€®/g«u@”x\dãðÂá_hŸ\ÀAª Fjà›xÈc€†/²`ÛË‹‹—éâk*¨TÆ
4à¡îeí$T7(à*u\*ìäàQÉ%Úõeµ:8bú;ˆ~g«Rm`Âp&૯¾ÇÊÝz³*Í1¦xB‹ÂOš–ã¤ãWF]{GDíû8j4µstT×ÎÀ-*(ÀGu£ôTD ÍJÍŠy¥°èÄé+H¥žî•ŒN>4À9òŸ8ú%C
´tÇ‚2 ‹H>i$VˆXŒïG7
fi–ÿ²nNYÛ‘3€°^6Zã8“€g¯Äe§OÇ$Y“‰n.¨e–™xh<˜=*Ù‚W…½)h’@CPcu۞Оð›kG ÔãX%_G	ÑëïežCCr½ýÍ󫯾ºL¥š%¯âHéýË_Eqý¼Úì[«Ç+ FKñpâQ[œê’®ÓŠ9,(¯›@&Ð0¢:@}42NÍÞ°Çör¥kaµ•¥´6ÍÔëÞŠ¿[ŠÀ†¯ïã_âé"nƒ²QZ(xÚ€ÆÿùÎ'Šâ'VÖó0c€Yšä%Æ©*¡±39ë:ÏK3CîmèLP˜ÔÚÄ.­ge¨Â«å@Jꢰÿ ,¾æIØÞå1™Ìƒ‰¹2ÚöòK`±@ßG£Y¾%qö*,mTIòœ£€©±2F©¼Z×¼Íqœ-Óøï0ÑY__÷µ?{qa†EWVD3F;Õ'bܧg«G>#€u|Ôe Ã“åÑéÑéeôœô†CRä`eᆊj€4.*ÚòÑ®ÕH?ŸOÎíÅuýPÑSüã€nõ£6/„à?Bg nð…þ_°Ñà*f〳t‚ÇZîz5J.±ÙŒâ@~L‚ÀþØAM<€ÚÀi. å7Œø‡¯á8 &–´ã¢4*.7”…¶A4_28Ô&Ëo-cxa	 ?ÖKP‘Á @…Ѻæ/PB§ë—þIã{ä:|±w»ÜïF|
*Æø©M
< ¹p„ýFÙí‚
_iÓåÓ§Q›JZp„;˜Ç…¢‚²;6ÏÈX^€ÿœUB>¥8¤wô±iYÁb%þ@A4ÕEH}<ˆA1c€Yš’íqÐ=°«„ý“(uŸ¢]ž©¢TtkH“½Ý`AÆÀÛ
ÊDæÌÏ
d—%jȶôpσ2•Ôüp"€jÎ?{Ÿè륫Ws=˜Ï1Ëqî‘^Œýë€1<ÎúzÇã߈ó’w`¥¬2O€'Ì£#Þ>::j‹ÆÑoœ	¡6ÖTÊñþõÿ;ËæÇ$œú'ÀÆ`ÃÄ@í@ˆ)ªöšp^h¥‚®aT@ÿyÓ@8$p!e>˜Å˜¥i
	ç¼)£Ü÷o¦6™
🢟.è°Eib^Ì•ÚéÔj”ñÌ,\[zÿµ0¹~¢»5m“’íD‘j	‘Í]Å_áÀõñ˜Úù+\ðEu\¨wjDE<¦A‹‚%íÀÀQkt,Ð#lÿ;rEvG„˜ŸÚÓ‹Y…ѨwG3Øð åC%¿À¬RòùXýüLŽV¸Ò„Ó@û9ïP³ž>K“êÜ…­„½8ãåü†«ÿäxØœ<×—k€<;€&°(sñÖUûŒzRèö¾Å&€{Ü^/èõzú´HtüÍý#¸æèÿgïm{ã8²tÁȈ̊dM§4`e’¢+¥âPtŽI‰T¡ªÚTC(SJØ­Ka’]n½žF¡¦¡¸-qv]yXà—¶QPKêžýØÝðÂèiv÷~™Ñ…vgï®ÖžùV,Êö¼ìÅdˆ*VVåKd2ž'žs"Î	øÇÒ|†Ê Ãuô£úð_*F©9Š“Lå¨.fò0é×7ÔzË_Hµ
/ôáÚdÈ®¦®ÿF„ƒ€E™Éþ™pûé|¸à}ö×çÈ´¼oÌ€øÏÅï'ùgwŸ@~@“óýKó$UÈåÈ3æŒÝ3ù¶ñ—Þë„錙óe9Ѿqâ##ß"ÁÄ)j=eîK°ÎÏÀbF(ð_”EÚ¡Q?ÿaÔÏ·À°ÿ/»Èôù§Zã×_'è³åàz,©ÛŒúdN¨v1ô¶š>,»g|/(ÜÔ ¡%Âì
};4°o÷üt}…¬Aš°Ÿž=pq,Ò·¹î·k’ úÚ|E)Êyí7€vk„yÑ ¹mŽWÿE™:8E`.€$@ØÁþ"EŒ>>³\N…"C°­6ÚîÕv@H×÷*|½býÐ?û	þÜtÿ×cß0ÏcÌä
=²ð‘œF„Aÿ8æ~rª0dñýˆYâó1Ûèy—ûv¼$»ý*EQ5yuv>€÷ïM½(3[³<{¹<òrðùXÆk q¦µŽ+af3÷¶÷B=,õ¶ûå—¿÷Ü߫Ӌ­€B§½Q¢Ð™o‰8!ÀÿõéÑ^r¡Gž }}ÉÝ]¨ÿ8êïÂVàºØûûž¢¥QÍ.0n÷#¢>õ7p[̆·ˆoïõø×„…³‹6G2ýiÐÆl¡Œæâêb>)ưìÏÎc/í£ZjÆ@D=]ÝÐ8Ù‚'ŒOÚòüát?n0ni$hH+•òW®Vó‚êÂ÷RP­RH‘A«Õ*ŸÉ¿ø8àžûÅL€¢œmïã€õCxo¢b•Ûc
?/D¼Ð8–Mȵ­iEKaNñ…¨ô5þÉ"2Ù£ª«ò¼ýöÛ3Þþ•dA"
€:€ëÓ¸ËÖõéu“%~%Àe¬ÛE‰XÔÇ­ÐG£Ð†Þu7f, !yCLÎBBÈDÛ$pÔf{rjvŸ›)BsøW÷'³r±’M|>ÁÈQÿ¨Ý¿uCúbœ„Œžt¤`á)ŒúV|y`‹ZýÜNÕ,xq¬0˜ý8*(WýP–¹$,elE}f@Qfôw‘gDÐg®Ê¬Ž“ˆ—U±¨=Vц%«º¿DÔ„¼0‡ÿ ²:ˆ"Q<•@Iˆj•	™àí·Ù¯~ êƒgƯø3Öõ¬êÕó<
ª>"r*œ±/áíâNxÙU¡‹€	èòqPÀÇ	»»‘ë‘vØäª!Î>(0÷wŒ'Ä{òüôt†ä'êþâýG›_ÈçóÅæÎÞî÷ºwî‡ý~¯¦×0à_ú¢ûr„/y‚7²dï´Û¢†,
“™UŒŠ2~/ˆµ IDAT9Á8ò…P€€T·Ñ@¨…²ˆ“)‰˜mp÷ˆ¢ÅeZ(3æ©ÍUéïƒÖéiü“@­u«ûã €¶ç­&^¥ Ó͡†æ¥~VA n……ÒÜ`€$ɬý5ûýÛÆïߦoÿÊøš¡WÍÀ>Y]0©Ï öZP€ÑPI„¦”@ÏKÀé!Áø×¯_÷È.ñ=ÚÞ
r†IÚ%JY;õb–¦\êã¸GhžË|$~êù`öÕ¢tÊû÷‘4Át´«Ñ2#ãØV‚Ç\‹´/TJ’0©sh œˆ‰À$!5µÚ¬zÐóÛÆ6[ž®2/[{m‘³r+ (³œZÐ%SC@ä|ÖÍòôrGh€‚Îú.^Ä4ªÇ˜`À#WC*¬`¬±A\°@E l¥]Šr]ûúë¯ý•á}-}dįmÈi€r	ÀÈûd,¥Ò« XbŒ¦¼˜J³ã¹|!LßoomliDÜQ×D¶‹×Gwö—ø”a>yjq‚€÷GÅIêÔgš!£žÄx†µZ¤~':€ú	ȸW‹ÇE0ˆ ÄȇˆÇ|‚ÙB¨pÔ‡úüÕØ_h©êJW#¹
vvüFµZõÂ-µSÙBüSEÛŠ„ä¨h!Š2³¡emxØNœxØ •=ªrƒdß™ÆÏT!ÚìÊ|†~7”xòíNgT)!ÐÁ*A½o É@*€·ßþ•Ìðµ…
V7^/WŸX;G4…¥@›¡É҆Ѓj¬€GèƒL؈MÜ!ðÜØ$¨ù¾/|µµ³O<3Ÿ)h-¬'¨ý肺¿'ím„¤ü¨&ýwî`(ÖŸt˜¬Ž– ¹@D$;YH2ÞG"+¬âªšž‰#%œ£þ±”|¨¸úC
ÀÛŠYYˆ`ï‘rkÀßfLBm„AÑÖ‹2ÓcÏœ7¿ÏÒA)¡ÐØ—í
÷H5ÉdàÞ]•šU¬j8	•ꆲ˜(‹éÏ„ØóKD«.	ðÿ~õ{ö5ñ´
fÅsõ‰
ÚÐÓ3
õ°Š ÐŽÊ^r˜ðF¾qÀ±ОIŸËÐCîã <øY"¦a&±ÀPó·È.t¸
Àâär›Êû—cO@ü|ðQÖjòÂÝõjÒäQiƒ –H’!ûèçÌ:I
LØÉµø§ùq{ä+ZM\€a‘ã±0·¢-Ïà‡U/Ú
MÍ›{yÄ”€“®\ŠFり2£„d
_Ñ?äœ``QâC›ø 7Ñ
$M]l¥a?žzèi.hÿoKøš$ÝÉJ’©ú`$pä{aj‚øŒyaY³7Ô'ð<]¼·¡»@LÆ0‰°Úß'™1rº¸O
!°¾ál`š„–à'bÆó‰zÐ{£Çý~/¡6ŸB¥’YKÆ®ž¨1måÂ}Cb3ãÌdíö—³¤8©DÇÒ‰`ÂÝú&€§FD{¯½Ï“k¯
ðÝ8ñ;¥(Y÷õÛ*æ.«Áåܲ0@~md–#ìzæ’_z¢Á׿ú!oÿ
5À×)vYx~ý0®7LòB=Ÿb>ÝE'ùÔªâîu` úí-5Ä'ã}7¡–ã“Pjä<€òþh™€÷—šÿÙçQÔç÷)*x&Eœ Ár~šzY‹ Ÿ@šIß-	
ãÕêÑP­r=ØÒÎ@Æ¢b!…(ÊL ÌXYÕÉèÛ¬fe¥¦—õ°c,JÌêT	b”˜ØYÐçêÒ² M³ßg,ÕL96
dØ2fK‡ÒB*—èÍ\$%(LØ2i–Ö(ÍN£càþ.Ì|>8F÷1â7ÊÕ?¥CZÙ‰R\²O5–ÈzdÈ!’Av. ZÿÕù¸YEØ ‰”ÎÓŒ¢ªj4(|€E™)"Ì	šà!·-³…ÊøØaÐ9ËðÒx>ŽÒãfp#t‘ý4¬ÃY5ªå —!/Ð?“àkÙÃ…òzÉ\¢©ú±hW¥äŠó ƒÁõ£¾¡¯›©
¡»z~ŒÌäex±¬‰m€$ýÈJòcl7ÊÜ~þþ¦Ÿ†!âÞQ¤(Ñÿ2–|¯òdfÀ}à´xåé',vbÕ@æ¨.æòTäÀ«Ì€`;—@L²zaÑÔ‹2þØBe‰Ën«¼.£kI²’=Qá¶$—ÀHO(ǯâÝýIð+¢'Táúé©|_+ûA>gÖgwWÅÒ’8î(O§òx«^ù«20Ø#ÑT>Bôþaœ Êä úìIÞ¿˜«Ø9÷wæùôŠŒ¾¯çæWu¨>ã–…×çó–z´X3tô½&ºžRœ
"`»šÉ@É;œ\d)Êy@òáõùíéüú³üÖtxüôËg9/@Œ¸|>€éú½6œëü®\ðð»æ`q}Ùy7tæYL?Ÿ¾ÑÏà›òÄw?]±sž·Ê —nQùªæökòœùû¥(ÿƒ‹i5¹mY ^-Ë.™¥f<{ùSnì.õkþôß$ˆý\ôñw+Ã3oþÍ
öû_nùŠò/ðNįMm¯ýë^.ZÔM˶¹Àè~Q²-NÏ©Oº­\üª~Ižß;þԩ悦÷¼t{Õõ}d€ìòæ¡~#þýïBhµYø?—²Ë°àeXoÀâ÷º—ýõnÝŠ	ñ”ß6áÇ<÷ï+Oí-½(gÊÖ‰¶Ü\sÏmcøüÔ÷ßµT\·’=}è{¾Zhò-þ£(…]Ò~°H”ΫÌ>=Ø3ãéî„D®6@ˆ‘~‰×~u•ú8 º®’šÈ|ç5€=D¾Kìl´9Jë;\ޱ?Ô©¹OüZí$ëTÄy:|ÁÈçÑó1Ôq Ïb±KùLå¸uh%
áûÚ5¤€Ùù–dôc —ŠÖ^”³j<€g§È¹d¨YM¾TBIIó
à	ëÕj}Qª
ËÍñêNI&ÁN2aû®›à‘Û—Ð=ç(´|çŽÊe‰7ùaÿÀµkX©‚Š2Ã~¼jí¿ÉíhËÍõºøy<øß?«‰YUD(8[T½î.‚*°ç$`%¤Pêîî•dðè«úh$³Àw0ü3|`¦«ò|~¨æy×½zTG¼ûuÀ•»¯…çã߯Ñ뜹ûƒúmÂù´V_¾Ü/Ë@þÐߨÚOj‰ûa—ö»Ó”@Ïïce€"z¬çKØ/ZÔr.ÑDTýª¨&³xØ-œ
Äl|ûÚíÛe‹—áü(!㎄báÙ‡èu1 (3º¡­lû$ÚH­û[þZòuoÊ$ð3XñÁdÀïÕ.—E!&å
ëíVGÀbµîºx~´þüí?¯‡¼Š¹2a`Ân	àL„êúeKÖ/T~€0¼sçNu—¢­øNvªÒ ˆ¢:" V¯G®Š,¾ƒ¬A=w¦"‚ó£W‚ôbÕòVn]0ÿ2ñ/\Nª³‰5%ÏÀãíÇøS]^"U'[H£ªú»» PPÅ7>‹ÿ;€îp‹S{qÑ´.©þÜ9º«
L2ÏËÇ5P”›Ïgøo_+sî ”ÕT`³,„'Êr6œ-BÇýy±:XQf—ß©NXèrÛÏ@ TOÝ€ôx½iÒ»xñAꥃö6w]­Å{"ÃHZ‘ãr¤êºU¸¨8‡ÍC­ðǶI	ß¡@Ž¢dî\¨ê—laýIæÞ@ôìlFy2*@®.€ðËÕÈèÁ;¡›íÒ£¬ËA„”&KéD»>Y{KòîyîïÂ…XmŽ"@tú¼†Uòø1}¼,†C©Ûëh‘œD
XèÇèÈ]9ϯ€—}ê·×·yY½I&‰>"ƒÊ×ñ¢ |»ìX¶c•”ð€Þ\ž²ðΑœ"¿ÀQ^SØTÌMfä8¤5ô©>4>@ëÅ>uµ{ÙAñBôÕU«e¸]§‹O¿èÊPBZ]HÌqD:P‡ÜÖSf$™;ë{áÚúMíL› >_sF£8e‹Ô¢'S~ýd$°…·^k¥‡G}éT=¸ÝµµXÅ÷WÓËo†»Ùç%ÿ÷†àY}ã7ÊäD•³wïç£(Ÿ±“gW&Q5]دîKÿh*y;·M„½]`•¯™·cO©·ä-MÏüõ‹6^”s¼Ø²±ŒQ{ÆN×ü؈XFYÙÛï=ˆ­D> ¤žõGÓP•£RZQ”-„¿_Gˆ"«ÇÖ¥×üß‘õSÅž¯
€(ãÓ›ÊâQ;Pc9ì#9…™ÍíÍÍ´vK[ù§ƒ½­W)¹?=·y$Séý߯¨bR}ü8Á”gU`€,¿†SŸÎôÓ¯¦ &Á¥å­lÁ+¼Ó±Â]R™ôÓªïFõþE9ÿ“CTäÿMΡÝýZN#Kg^Ú³ø½žŸt0 6Ã,?HÔ³
Co£¨û–,õвc+?_U¿ðœú)›>éd™œ\,Ô“›ÒÏzíÂ8%ëÄý3¾»4ÅMÝŸï_˜YŸÇÃíÇ H’ëŽw»™úøùa‹2'»¶çt&u³j& X·²p; Ò`l`Û¨^0@QÎõF÷¡¹íìܹhͯ¯å¼€hÔ3m:]×kZk"ÌöÙ¬ŽˆŒ€©nÕê!-0W>¯>¯©àßÏ\€E^¤<¾Æ3^-ª×jµÔ‹š!‘-ÜÛ§¡¶"nE$|ý4ÀA—d}dYŸ¿‘Èðq2	È—öRæyµ±XoÊÊAü_Êìà’ÅÔ†@Àß³#8×ÿ<žê_ˆ¥87"à¿îÏä ¢E"DfÑNI>í1ÿ€÷µ”Ð¥%èèE½=75(ê™ÏêÐb³=‚‹”
`[zg¨C=²æôõwÃ|}^W?4$†õ®«Ç6#ÅrSÅû±â—Ã	l¢ q%0ªÒgeù.qáϺ?]uõ!âÿ¥~[í5´²ã¢„e-.ͽœ	uØÉÀte€Ý]0úê&üß¶l°
´	àåâ9<ãÝ]ßäE[/Ê,üßdÒ¸¤Ç¼/ÑãgìuŸJG˜Ÿ|B¡$.9`Jýž›sÖëªÅ3Tä€çÝ Nx>_™1:UÐ	(¯¿»›¯¥çÖGä@C¤—ëu¯ê~YÏð<¼ê­®êõǘç…8w€fUËf+©½ì6Y^Âø…ž»¿3õ‘@¿¨¸†SjÙ8êÓÓí™,’™
X½(_
€ø‡ªÖ“q"Àm9+X››ÁôdºÝÝÈ+FŠ2] 3ÚòU¸îÖ.Ìoo­nÉ(2ÌŸ£¾7\×SÑsjî$~ÙMé¯KÑé˨·Š[‘án»j6 c‹UàcD‹—àû²…L€$ü­2\¯¤¯W*2õIëçÉmßót8-Ê}¹\·Jÿë]uu~-5ïÇÓá‚ÞªÜf†Z/Üó’|:hY¿Ç|a9Ÿ|„>úµµdçìýÁ‡››xô&®+®ÎÅã¾êtðQ§33 1Гñ=@˜cYÌI.W­²Èˆ¢cø-£úP„»„KÃ# ç·¬\>€l0¥—DJzE¨PQζ?€•.*¼>³A{
qxõg.×4yÏS“¢’db_/ÈRu«ŒÙ<”
ÀG€1€ýyõ‘Û^²-é€DFðËp)ýµ$„U,	ìúªÄP‚ÜŒ@…ãÆÏE™û3êkFöþ.\ÀÃ/\Pa¶£Qþy?†Ç/«|ÆÉÉ	~¿â”Œeë?ôäÁ@~‡ßš–cé„#³òhGŠËùë€RùJäÛ¢ÁeL!ø¶§ãÓ§G¦¦ãå§3äâùmÕ±ÄÍ—&À·¯OLG^6œßS=>ÓŒc^_½î©|¼]®Äôý06# ÿµù¦ë÷Ê€3	fÀÒùÈ9Ï[å€'§	9À2ÏÍàé´*pPÿ¢Ì,&5y.ù·Ž,¯Òêk+d~·Ë›f˜!3ú‚I®óúc~osú„f˜¦ý>§Ô¿cÒ…ô³ßœœ˜úí¿Ò,¾5¢ÏÍÖ¹ùì¢å›”ïçÒëåÛÒÊŠjqß²	¼Mn-ž¶’Y.—rŸ(Yæœýì0ë†G¡;!MŒEð|WD…Ľžµ€awb¾Ö$ö3¯ßâ~Ëó1k”!þG¸¢~kXqRQ~b‹'­_Oxœ³oºp;wFëÿüË”,gh¥¿4
I8¶D‹7[’fæxÐÃéË2.ãAÑÒ‹2£l¹lu•¹[)üq›èe¨ÿÞÆêuíÍÓ
œ^g#@ÿž¤¸­ ì˜
îbÕ¬.^âÕEÈ]o7'J¼(ç‰ÔŠ¥ñ%=Ú÷áºæP_ÇwÏU×t}Óð7%!X®u‡Þê*å	XÜ÷·¨{ŽO'(°z¾ûÏhzÌÀ•ÞŸ¬ðü+;‚g‚¹RþFü5gè ?18†é¡øé8d··×Y|š‘K$?+@R±|µ‘ˆy«Ùj~ú)¼"œ½À¿…ŠÈÊ…l¥(	þ}N<»¯Àõù¶·}[¢‡Küó»ÞÝ»5¯Ç½º†Ü¥y;µÉ]ALVÐþU@{ðo2@ /f½[É@i`:ŒJ
nÀäš÷z¢›oE>³ü¤ÇçAäEWÀ»jš†iX¦”×]VÏ£=n1µú˜RÌBè͸’þû@kk9?‰Fëé/I%ЈýìgÛ_|A¬ZubPrC.‡Ó3?§'Ÿ[ˆZyP²è‰Rܲ·kŠä^œZ<³<¸è_ì[y·«ò
B­Q4šŠôƒÛÉýø‘eb´±eEÅTÀ¢Ìv)1“1ÎÓíííÛÐÇÇñ}ðýÝ»ÐëÅ.tºT7Ìv ¦‘Í£oºø½îzàÝÔP…ËQF­C êPÒ>¾æ¦ê®¸G@wxÇá>%:»X*A83…ˆ“«¥5<Øß48vóÒ=€›:ݶ¿6Ò9™o%p¿¾ægÖ6ZKÙ¤äÂer9>~›óŸ~¶©kÈ%~TZqå@¿‰81œÂûR„zÊ´ÍmŠÀmí³C—~€Ì§.Yå\ôE&–_¯´€øW
 9™|:ü·ZÒ/H˦]æe]ᨎEˆ6+*ÚzQfŠ^sànf¶¡Qg×ö1W|ßLþ¦ë6¬dŒ‹doÓ3¿ð¼/¸§ xˆÔ…eÒÌwÅ®çU2Ž–Á£é ¨Nà&Ó\Á͸\·4e°Þð#Åó<ô“
üz®Z@sJµä‡	ê~-—hx¬½eÆrÀ¼`þæÂ…߀H5¶©O`ÔüF½Î4
ÄWa™!㇣÷Cm
Ø3€Ø6½¦6-¼?æ‚zÄ&nš™‰¼Ì É¼“ô'Ÿb_Z˜å»œð#@ÉŠ©ÀE9Ÿ8›ÞÞN7÷Ù€³ýì×››fÖfe««œ%^x“n2¶i¥ËÔ0³kNÍÈ.…'	ÀËÙƒ¼u1]?ƒscJçÆíÕ""Zœ€ºÉ\ßSÂÊ£Áô×3ã õ(ŸyZkkkõôþ~ÍØ¯­”2~FMþäU3”2õ*«3¸ ä\öç±™±»‹à§F¨>p,jÙ6f#Ç+eO­øi3fôSü"þ“ªµøDBhþ›-åQ´ÊVâTà’P‹uŠò $¿rÌJÏÈÀ=üþÞÝ\·(쬹)‚¢¥››|ªÉåΪ<# ÎÀô€¶‘?ž™S‹çò¼„—cc,ÙÄôrŒr"›«Æ¬šŸÉòçGS	CA¿Ô9«gîï׿ÎÞßÃ0žüLÕ´Z§Fu™Õ«õ*^Y‚¡üΜìÊt'ú.¯Àή¥öJÞgùØ¢ÂLðŸ	–ÙßT>€&Ú¸eS{¡l›vÎm`Kƒå5^€¬¤&÷pûÞí©íëë	 ¹ç2fæô%c4§¨Mžà•ÑÌ»õÝJ¥’
€+¿DŽ+æðÈsõåèÕ33_Ë.>»köòn{´o²Ç×8÷­0ÅÿºÏrþ2@¼aÖϽ?¸Tè‰~4H°_¯ê•{dõ¸•aµ0¤2Ýd%lLéÍ8·íÌ
em~"ÜOL8°—"ªó·p%zõ(€m.ðžÚòùkå\0Ð{¸}o;¿½o6¢JÓ¼W»ÙÍžfût&|©Ø²ìæ¾/™S'ÈóG¶Â}zÉ6ìgGê˜tpø4ãİ,>ÕŦ„€±	j,ðÜçõ›_‹ß¤›hpë‰^\ˆìýµÝÏä ƒ™»`¤„‘ªˆuLòËÓî7ÈÞú36>·eh¡ˆGâ»(›eý.dñó§a¡Šrþó€RÛ	àïâ¶i¥@õ±¹ä@^cã°›™éM¹X
¹]oJªp茖ø szÀ«•‘+ˆo“äðÌ“z°‰Û\¹%{Ògt5)1×7ynæ“ald;x9˜@Ì:ÿþž þàügñ¹ˆZÒTÁTŽ9˜Ž@$ª:“;@ÿv&
€Ì5EvÛÐk¸&ÏRN°ÿoéyÿääaüü)+4@QÎqæyOoßÎö°°À&–F#Ä"A;³ =Ï1
lRì¢c
ËÜ*¥”eâÛóhí
ºƒtÖ
ó‚ê³”ôÐKРÍZ¼ÍîGpº„‚X<ÃOÿöà\Ý›ÝÁÀó<µ„¯ŒJæ)ƒfð79Nš#Hy"Jpü,ÝFÖ…ÙÛï˜ÉTƒâ ™baßo]³2’?0ƒ@dÏ¢U3+b\£­É§þ<	ÈÐK?ÿÿE™‰l3ÖOâùý{÷Àì÷µ
Àºü¾ž«É€[ÏUà¼[OFá¦n7¥±¹
sC—5¾#^}™@1Àî®tË“=‹aÁ,­_à-éú±hW‚ãêಗ5¢ûý¿{_/|&€¯"~½UWÅ'«peßKü‚~'‰oß00øw-Œ·­½Å²üÿõoâgäK³žäÈ)m“tN€ï:ý]dPŠN…4!ˆÎÛ±ãç›"Èä(aÀôjöäÌ·¯É0«Bìõõ™>>Ÿ`*Sùä˜`f´ÿŒ;`$w¿çߟNyr&?ŠÂ¹þĘ~~ÄÈæH™Î¤79û¼Yz9–8Dd4ð9ù0ÕÏŠ¾¿(ߦ˜¹·¦””B'˜¢ˆüÎæ¿âõrçõAäõÌ¡ù
{Òh6S‡ îÖœà¦eÑ@Úh&]Ô÷¯)ÛògféP%ç;3¿•²âþÿ\nã=èG¦½÷Õ¯¹²ð6<6‚ð¼Y»‰üû$Àèœ|›M
`®Y´î¢œ_šsy@ÌáЖÂÿæ.þ·‚,ä†öJÍ3ðŽ?i6gð¼¬#‚ˆ§s’yf:$ux3LkˆõÍ@2<
›
ÖõËÀM©þMØÖêtšW·€#Z)bÞ¼÷ZJÙ‘?³ÐO:PšôÀÉ7ç2ðB
0Tp#hEpr"ðAI	Gíi(gn^l8¢×Ã_Èfæ~å$fy˜ZhÞŽø#Î9¼ÿ£³øhlø¢‘åüÔ[U€Öˆ8ðVMn[6·¡Ùnþo¾IÚ[oJ	¦Þá#ž¦Ý!C2œîßÍ4&X§ÐýuÃ÷üI³Áí™Dk¾„ø‡žÒ>¡{C¤€ø½\,N§8¿~Ãù;®KWFÚ IDAT?iQضÚ[@[Md¡Y¿'iùôÿ''ŠNb-@6çGñ\ˆ%ïsÀ?öþnÅ["틃 ³±µÑAüóûŠöÑXà\À7¼Tó6øÔwQÖ·*µ¾W´qH#%,FÏà={†èçÏFÓb©sò‡Îf#Œü‚Šr¾ ‰ÎŽaÞuèXÊ«6¾Ù7W¯z¤í¡t5G#=ØÄGÍ‘©ÒR!0iʪƒOzø†ë62øŸ4«‹—š“‰}…ÏÔÿÁ|i¿Ä*€Õ!eÍõÕ¦Ú}\=™ Ù‘ñ‰¢Ñ±|§©D†ézxþޝ-·ýæ÷þîVãÀ;hâ-%;Ô÷Ix±">3«ØííŲ̀ÿüó…3œœ|~+™uÄ[YÁÔD¨ÿ]weÉ»ø½ï]l4ŸŸlýº\Ô0&G*m¿˜aÛˆÐñDÛ=1pæ"®¨Ü\DÍP‘ úþ÷Ce(™’FŸ}Šè6ŠÃ%iì8ùð|v
 (çâ¿ÑÌ“UPÏžÚ¾E“ղš«Z½4×ðnÝ$—.77’©´šMÓl^orÕE+MVÃi¡‡ÝŒãÉf³"šTþ7
¯ÓlN®\¹2Kÿ·[­ÁüAÐ>:j³±ÚxÜX÷X­U}þͺ)ñx«ÍÎf§9Yõ×èó76›M—o­¬à„¹ÉiŽêï'Ú_O*Š1ÃvvnooÏÎáýþ…“NëÂÚùÞ(hµž??À¹9Œ-­¼XyÑxñøóæ €ï{ò½‹ÍÉIçùIc2
B~Gƒ#;2É•bö©ñZD(éíÖüÀ{m6j§T:’*
JBõ~ôᇟ}øìÙgŸ|øá‡R ?à™æéÎðæƒçS4ô¢œçB›Û¼èXEà5´˜[cî•Q\:¸ßC𻤼N´²‰çÒæj“´ùß|tê®k®®BÓô$žÉf£UF¬Wß\l6¨qèAðý¿h=Û´žvKÐÂ—ÍæÜ®ø×ço`}Å~íUèó›
P1í@RS|þ†ëïÍ•¿»Õl´`´&„»nGߘtdA“ר¹Pì6Ù¾vo{DrÓ£“™Áx m^¾ÜD×¢Æ?ØÙÏ7[ç`¬¼xÌÔxñ¢;¼x±rñO&€àÏ'Ÿ­ÉÅ?¹HþöwznüO~'i@¥D/õÔAaü†Tš¼ßмšhÃAr)t&Ð%3zöá§Ï>ûв>üìÙ§Žä™FŸŒž}/ò|›C¨N³	ϧ0Šrþ€&
ÙÆ-h39CÌÌÁ›€7åè2š£QÓ…ŽvºÀÿêcÒºx‘WSü·*­ÉdÔ”N« ‡ýuK@µÚ@¯tÛãbõlÛ>j=…]ø?8BÂÁ°¹õ{Ùˆ@ë›xÝÜ6ôö´]é6ÇëóÃOÇ{Ó ?ààŽZMË…¾_ßè¨Ù€¦ß¤þÍEع½CȵÅÒ6ÅU÷Òê­½¥2k‚Ùqwàþ´c“µ@ln>'h? àÈDsÅÚÖóf³Óp¶äE!tà¿ðþN*÷p¿÷€ÃÊÐÃuU#Ò‹z±‰P©Äì‰NE9£Cjᙣ›Ÿýø³O?ýìÃÏ>{&	Œ´(ü!2‚ϧ`€¢œ3Ð,56o1ÒTäòÁ¶Í	·±IÎA:€\{GÍŽ·	|±‰¢uH¡yVVA¨W†ZÌ6›àk¤"¶x
ìuÕáÕEœÌ¥6ÃØm
ÑàõBºÔX‡í&Ñ>à¢Íx™Ñ^mœæ}*¾ÕF
œ_-õÜÓXí[·nMZ&ï¤ß7:²Çk éû~3ö€l—ðe'ƒÿFsmmÍïõ¤
|‰÷§LÆž67Ÿc}Ÿc^Tφ4¹›•%4Aû>Çp§oèo$°ñ»(øÝß*Bõ{tc¼¿ôÂ~¡ˆv±óO×÷*¥÷Ûþþ÷åhQH¢ï¿MFæèYóÀ³g£g&šÜ¶­?~fÇÑ
"§&Ñfá(ÊL 'óaC‘-Ùe+ÛX7 tŠ+€MTªA™”T,±iUc¶eElÒ‘ú^4&”5˜1iÊ^l±J¥xnÌnŽ"(u®5&t$+^>®Ÿ^pŽ5âÉö¢ínµ;%ÖiÐöÖJ;–pþ†¾:â¿Ñ88¸µõæ›'Ôäüø{M()ÉTQµº“O|¬êÛYS‹ø5ˆ¼?`Ü2FÏsÏç…oWpäC`&à?z>v{$ê“¿Õ§÷Ã(ŠbüK× ŸÏH¢î_?¹#ˆÚÀwèü3à³O?´3Ã~öq:ÀՒϧ1,{QΖUD‰Ýj¤îhvðœH—OЭÌ€ˆ£ÁC“¶¢b$¾ìVìg3­a†F¼$Zm€ÍÜ8o&Ž(
à¿îýu•:ÁK‰}9Ü€âšub¸++¢3’¾$VV‚˜ Ò󠀯Açyð¿õwÁ™ï‰ÛoÄCzd§º¸};çøü?t’Õ;G’¤°	€ßdÏuu?ÇI)\÷…¦4t9t âN UvÿH `É0@%}Ô³kIpñýâ’¦wä“£#øñgÿŠˆ=ú s<<0¼þ°Y´ö¢Ì*Ð@nMÒ•8;¸•sã÷—²lnv‹ÒĤ¿­ 3ÎïmR¶™ÍàÓ#¸é¬ja~µƒylfâÿÁõ¶Zz…ë¡9væ^À‰©G®øàm@Ÿ4 ‡U&@ç—ôyçÖ­ÎsöÓˆÿ3ßëdŒÅÕa;×®°íÛ™)5U”ú™Y?${8ÉV:c¨üÝ“X·òBÕÈ(!ˆ)
:ñˆíH#ž…¹|=PÙ™û’àô¾B…ËÿÒ… Àå   =ûdôɳT4æÀÊi(ÊÌ€’mc³¤Fxòý­F–ب•“ð-Ë­Ì& «ÓieŒ@ÚåV«ŒˆÏiŽBÀõZo¶â)È 0/×;“‰Œl5[_Äÿ¤³9×,1é[—V:\¾¥*à»Ï¡ÀúâEGôûI+£ðX°ÍE´:²;zÀáœûC7`LäóÏ?Çûýi§¸s40šñ4Ê Ýï÷á¿Ñ?BÈ¥ìF½üß§z˜*zèýÉ;*Ýç8è39€k²€ŒžeøcÒiÎ.À¢œ+&͹I)îs&·šÍ[S
(+F£Æf"X«bA÷ÖJºD™¥®Ól%›ÍÃáìóòLK€ÎÜÓ7[s­Ä	Öy´ÄÜQvƒZ*ØDüã à(YX­Z0Jéj£1×èM½(³¼€ØCÝ@Ùã·S€ïUŠh=ü¸8@Õ¨ˆÍ4xð}dG9á;·Â@bwü&³óäÀàéÓÖJëéÜŠHë·~#í„§ê‹ý-zõëªeÌ[õåùWe<2ñd\2óqu9öໞ!£‚c{¢ã§ëƒ³U©ÌL`Iq>€©ûƒò¼³©G5¼î„Ò(ÎOá€ÆO;?ýi)-ú㣣£ñQ;¶	˜ÿÀ7zât
©fÝ/KL«PG#à™Ì“8+ÐÀڣ˲SD…Ìj €oh 1€ŒÎÁlßj(H¾oh•
jº LÍ€›­t«Âd4>«¨í×ç€VÝ•Nwe%òE|ýõÍN,ÃÏÔ7}þ¢“ó~H|3ƒ
ÏÕù@~j‡ý¿C>`€YõI®x¦>ñÔ6®ª¾v]¾pUB©êç·ó×Ç|aòŒçÞÑT}ŸçÂù_èSd4„bøŠJ;âtDó£Î)j¨UÒZýû¨ïäÉäœäë¼|˜ÝŒÊû)V+Ê¿›ò?t‘š7¦¶ËÒlvʺR ÙŽÛ$Wã99WåÌÝwäJ„¼߃hSù½hÇ'´³g7“¨hþœd#Áñk†ŒB±åÿ·Åþ†ïW^Ï›­×²…NâýÏÌG²€§t®.dñ'´¹œ–£ênéßD8WEmñ—ø;ï¾±Á­wÞÐKŸµh0Di[v¿æ*æ8în`pôUñ?’®Œë{{R€>Îxr:µVKQŠòoRêk=èujƒo»¿”™k¥Ügg’è'ý§t¨Å¿òÖÒJ
ìd×Jònû¼Ä$`É3ÂÑç•ɳe8¬~[ñáò'„¿á¼¡”@ÙvLþ¾Ã‰c9pV ^^G>°•X²Úº#Ç0ßxãÀúå/ßPGGAû Py>Ô¢êÆÅ˜«æœ«æê*à¸Às“lľä¯+ÿÐý‹îž'2æÈ“'ÏÿþâVÑè‹’š°r*«7N"çJçÎØ¿´–£‚Ø*6s–î.¿'íüð½÷bÂXZ‚ó¯(üŽn”Ž#ÇÅ6	yÞ¸¡€ë”ÝIuø³¿þëgùÕ†ÕåDtD¾ïO'ÀõÒ"å7ð‡s×Y@0Ë–í ˜–ó>X2Ê}‰ý¸¼±dÛ΃Ú|mݶm$€_þòoccý—ÀRÒGo¶EßFD­öm>oç5,”ÕùwaÀsë>&÷=?ò—n¾#°L§hõEÉø°¿oâx¯—éÏ·ç—Ù¼ú`™
Ö®ôÈFYÑ™k®‹YJ0³4·f~h›öû<’;ï-kü//'`
Yà-ÕïW†ªÙ	¤@ùÿ›íMP7r®d‰\•ŒƒàÏ>D Àòò0Ci®,^Æíí¦
”¾Õ„0œÂGÎàÿ},#	ÀšÿùüÏ]çç–…Ëõ
Ñ«9b~Þqض üõõu\ÙÀ؆Æ@m¬'
€yÔT†òT¸ÀegaÁ½zÕÄY	! _â¿îz^°°×õ‚½îF×{þ}8êTrÀ“ïø‡4¦ˆ ]à]Ê]p,+o|å?néÕÐ
àÚ¸*جYО­µy½X%[¬­¯¼1X—ÝFs¾¹¼ü§?úѲ¦‡ÑòÇW>þñÇWæ>Ñ¡(vƒÄÖ°óÞ{Jú¯íhü¯0µòž^p»¢‚:‰Æ½?9€ÿ¿ÙLðŸ]gàô€b¨ójµ>̬­ë¾ñÆÀ,Óí9ɬ&€Ÿ¾€séßß:à‡Ûe*ýóy:ÿsN)j5[ 5OJ8„¾ŸƒØàü¸Kq||4î·8Æã7ûc \mèÊÐK¢°ʈÀGÈüGž°±··çÁÿ½n±K%öOÿ˜µ`´Ó ¾AâëEYf€%¸|°áɧpý‚uáp€U(€¢à²;kµZoÍï)Ûž3ÃâkkÖ2˜öì°1¬//¯¯m6Þýë–e˹ò£+“9°F¶3Zž·>þñ•+Ž4°Lö×
’?|ogÓ¼§o1ƒ¿{è¹¹àzuLhÿls“«'yö†›ísZVìôoZW)p}í¦ê˶EùÁÖúAöÏs6÷óŸSg^2˜üã(:¨ûuq•˜ëëï€!ïq‚$ÀMÑ?îÇ3¨÷‘p‚.¡ÀJ±\5¬ª½Õ=×÷ëutŠ.0@·»±çyð/¤ąÞ°Ó?>×÷YM-y ç
øFþb5ŸiÆÖËÌÀmÃïQ#Ëý
.lyz1‡[×A (8¯
 ÿ¦ÿ&[Ó­‰ñkmyyžÛó”òÁrÏX^fƒõ·Y;nÖtšó?ºÒœ_V€¯1c4r>¾b­IÀÞ_N¬M{í5 €å÷j½t€‘µ•·@xª{¦NÅ©ñÈå°žo“Íœa{3é߸îL•ðÿð¯ŸQúÑ_ãÜWìþëõá²½°ý)|=ßn¡]c<hP®ÜsÕ2—
@Ú À.ñˆÔ#ö»mÒ†W!µ?;%ÏÓÎý¾ðjºÿg¸È—ß«áR_$îñ{øÈ{I‡OÑ7xœ[§ x<âP˾Pà¿(R@é1¿ö&•	/ìeÆ·æ—¡×›Ÿð²õÁÆ`½uùòÚv ÍyÆ–Ôl:ó±
à|l]q®Ì쌤ж˜íP–®vMjtç]`€ÄãÀºç2hÅájÎ0¦âÙ4žßØÔá\/Œ£Öø£õoÂo 3ÿU^ˆ)À7Z7Òê8<ÊØÜü#(£] %^þ¹M^R¹“:K§gëxþwL ¾¾nšï(ä‘
Za~Þnˉ¶eÃq†dµ"²ÉÝkaA
t„!(… D}Ûëôƒ=$)ÿAü‘¤Ÿ1
±àû®õú1þ}œJŒS›ýt„"khö£ °<‹zYG åüzAEQŠ’ùþZ½×3ü¶nYk@†=¯Úž\®Ó_ôÖÑF°æµ¦c-ÃÇók?ÂgÙqFk†õc¿Ð…\‘Ò‘Å^âÀÚZLJ0O_gªÚŒY8
(gÚÿ{ÿdî«Æ*7q8ßûÿþÿð™Æ?çÕ*nkø×|W
€”˜uã7~a¥^@:Ÿ¤Nçº$S_Íp¸3ï$¾4À¿í˜=ÉH€‹óu9'çŒÿ2€N@À?ÖªœŠ&52Výž€zGöºmž'<‚4`ÀUO÷¹!Àȯ^j1ê‡4
ÓÂÏH#/þ ò|iõ+úÁ¥Òõ-êP`…EÛ/ж1ë@4_f6_ã ¤-–ßÚ =Cºîpâº3ό暘`$ÇaÎmQ„'Ó^ÀµÔ{kÉȼâz²žUA@ÓÁ‰—Á“­?ž¨—ÁTMþÑ3Ó¼
€bö{$`W«ñé£ÈW±rÐ	È’î_R &I(ÛÿûŸÎËR¸¤°ÿ–iöjêv8_ß(ó
½{¶¿i;v»?–3‚9ôüTMí§@¢¸ÞÊ‚S^(Ïë`=Ï––°’tʈzO0@o÷ð§Ož9 e0Õ(e^ª¨"J#÷ø…¿|@ýxÛ—[‰Ïв䚢Itp´e0‡M¿(ÿöÀ>t¥éH·AÀr=ˆ­×0C§¯«–¬eΜ÷àý÷Õ…ûOç9˜‰µ’øwL$%LoÓ§#
Hø¾Çš8ý¯Âñ®€+æŽ&€ˆ,Jü™æWO.(pº€'Jü§Ãž!×c׳›üeþµï=6´DøGŠðãÕsk“2½21/ÆŠ"ÛÇ€59ùxºw`â­é#2^IWdzê…quRZÙüÀ Ѓqû3bƒ€È…tÑ G¥6Õ ÛÜŽ¥¿ÞM@GJM¹ª—ZÆ£Êeã®æoŠQ”¼ÏMÔÎï”pY=8?P€‘¹ygÎB%	:B¼WSiü×eßoª_D÷ÕòŸBà( nÙ”ÄyB祗±…ãÌ/È
/Ų]½îWA
0;€Lk~ßÓ'éË®¬ÂŠã<¡ñÒÃI4¢aø’ôÐ?û†¥œ‹RV¯ÿkJþw,Òµ¼gµJ’®Í$‡¤›Œ’[![­èËu»úúzLûZ`0i$øW#¦Rˆ,lúyéx$¢ÖëYŽZǧ†€øW¶Èƺ$€~?ÎõwZ@^Ö¢)IÂyW]Ž3]ôÆ:ê3@[FJÈ1˜ž4k1óüöÔ}³äEù÷¦2Ø9蜹Ï75ßóVôü–UaS|¢Si*ükÅœ=$^½‡1|}}]!Â;QŸ2=¾U×T‹õ¡[ÂÃÑ|…Q-eO¯þk¶dF
X”§EÌÞ¾íñ`ó¶åam|i4.¹äÉ?Áï*·D…‘û$°«†TO2ÚÙÖÞ½{ßòrKKòuÆ´&]WoqÉáýgrÙѱEKÿy˜…0zÑáôT¤$ TÔHwE6ªÓR2IºªOã}åNO_&µ`ºŽ©óyÀ5q\«õ¤*ÃŒä<6ŒT=K‰ÉÆ”ÕTæ¥JÙd¯¥Ï¢efù-	@¤˜’=XÚç­yŸ;XíàŽ˜‰GGB4>ý Añ=|è~ðPááï£7ß–£’ŽN´A”/@3ßþ—Ü>ÆUîí(›W¥Ð™9+V•{";©±Y½yy£JéºNÔašÃư47ùꪥÜ
K/’ÓUÜ
¯Àü¸¨Aqº2€ÌAº¿ïÝwqÇ}uE¨(€Éá‹\·;C9ô¢à¯N)0€¢¸ ç%®c©œ~( êã\¿ E*Š(¡Lå–7'u‹¡ð?yŠÿ¹bøwK¥r9¹…¾L#ÞOmö²§E)JB‰‘m’Y1fAJˆch×À”EX¯göoíGGm\äòÑñ‘øàƒÆC PΗ>`-5R	ߎpR­ã÷k¿1¿`“¿ø_öw`¢fPé3“ˆæ©.Y¨з…Zh`°Ñ½ysãrµº~ÓŒ;áµJÿ0Aÿ£[/S
¨pJ0™)«¸@N‚Þ`0èŠîJWT…ýýýÿ)€I
À%¼­²J¡Œé…ýšÆÝï{Ýñ¡z>§§O(=}õ¿)øÇJW„A¯†ËD}`Ìj¨È)ª²2Àïþ¾	 ÞÎM¼åR‰|xÉý@Œø÷ýº]¤€Øó2K×ä/vîÝU0Œ5€¬3µßÝøŸïýr[ˆ¾‡ —Ö®nt7»7/ƒ¸©ˆÖ¥[#Ëv¾z‡“¿ø§R6¾ü'm˜d@˜+b¨ ‡tÇc €îÊ KuT@"d¶sM „?{ƒîà~uX'ÐûÿàË/$XxÎBÙr$:HüQ AêŒJP÷øÇ§ øÀþÊ»ò”òËO··±ËgúÛ%kõŠÇ«•H2²R°@QTWÉåú2˜l#ÅbÊu&˜1ËYNÄCw?ªøŽàå¼@âÊuQF7ตLðè¨ß=>z*àõ„ýÿ/~ñŽÆîî—5Ç÷£:Žc9®óìæ1ºN¨ßßÑ ›´gƒš˜LçÑÝCÊ2do×€E{{{úvsocPÛ¸Üݸy¹J×»²Vͯ&æ.Qî\6øýOÐÙÞ¾üÏ/‡Ê[H*„â*À Hzó=èÒéJ—ÒÄâQv€Ò2Q%]ÃEìmû¾d€&Àÿ«ÿúƒW`œ—ì8`ß(qU낵pÜ?>Œ@¨N;Ñ61ÿpßÐ@ÀÈúÊu¯L(ÿ
ÿJ Üç®
  ÿg…ÌŒ?EÃ/ŠF%SàǦ:~ç#Þ+ml“ñ:ˆ08 IDATü "B!åðß?
Ôz¨âai)@qfŒºZûèø¨?>FÊ8><¢Ôõ®6~öAýté'òðõ]†ìðyÛ˜G°îÞ½»wˆ €kßu±lÒlƒáÄ8K_<@ŸÖ÷zoÖ6jÝ›”PðÉÄ*þl´„hüûþÃíÿ6|¹ôrxƒî^½Jñ°­j]¿çï­(#ÍvÞEÊÙ—"Ði’¡…KY5€%ŽÇÇ~͇úƒq÷8"O¼Óx¢ò%2Àé+Žž$P¶0d9¨øû}øxˆ”ðØ”EÉ ß`ÌÐ).n\*ñÉWtä>l_~Š4ÉùuÿÙÜÎDëî_¹U¹e©‘Ï¢ñ…° R=tl!*à£O¥À”òcÉð[töÐFú¨GããñÞ@:‚„´îD 	0dÀZz#8F€ÝÜ!ÈzÉ[ò]÷’{é'¿xø_€jë5§öËJÀ`_‰€ýýýaùÒbyÑ¢/à’¸ù5̓îñ“'K¯¼/…[¯ˆC…yDzV攵`ßú}ïøð0 5üËH1Æ¿¢!x1ÎN¡â &ÖÓÑ•+“íÉWOIÙ,Ù¦k¹¦}Á¾n—cåÀ²Ã@%EE)Šš'+Ûˆ„®317âæÜ'£xvâð­)lDGÑx¼7Žû ÚØùC7·‡” ²bÞ¹ýxÆ DMŽ	ÉîTîø°ÿ(à_]j4>àþ¹D÷úúFÍ`2‹>À…#è‡mnQ`Ÿ	ïîνý!0@Lål_“¥@&›=ÜOÔíþÃPùÂðòú ~ãf
4À`}0 έ–šb\ZLpóÿûpøÇ¿øípk‰ñJåªêH)üÂ'2ðI×À¿A°?Þå/u9A¨²ò/YÒ([èÓ@—Æ’7î"|ùƒW§È_¢Àÿ+Ö‚½4¿°j€ôÆÇ@Wðl]0Õ8c T!Àÿ=â †w9	€pÓb®ûô«§£	wÍÒ…XK¥’uÁÆŒa_¢_¤^¥’ÉK…P5mWZˆ
? ýûsŸ|ú©^iRf·#Š$ !Eâ÷š§\ÚÌGý-H€Gj ”«VÝ7wXb»ê+6Xþ‡ýÃñÞáñÞ¸D½KÞÕ«^ãƒ2ÀO	©Õ¨ãG¬¶¾Á"Ÿ!ÌÛÔ½êB7©€Ýݹ»¿~ÀÇ;j2UyºâÕ—_¾:¥€û%{aÅÃpËåbéÊ=tûº;ºKNÉöh´½=’YPŸ^M³J¬bWFK€´cKd¼€ø¹‰ËŠm¿(ÉÔó8ÀL™ÐI|2gfŒ–YD!@ž
è¡°Ã„ŽƒG¢G㣽âT€ŒûÙPúuF\ÑõûðB¯Ò‡Iãå	¼„ø÷A µÔPH/ ½€mÚý{@°sOxw• ‡ –<’Ão`Ï—£ÇÊ…ÖaíÓ}s£·Q%7oVõ„y—sÔœ¨œwþŸÏÙ¿½A©èT8X Ê’î
p>ú{ÝÌ	ù{÷Ý}$òî¾r¢‡‹2›Uà`ã¬4Èééé—_ŠŠ¨Tþ+àÿ´Ý>±n¾`[‰@8$QôµG“ê…A%ŒítN	wrò_iô€ç޾šŒž20î·¹!˜¦"nWè¼Ú
`q$Â(Jv©Î=i³0S@2¼&C_#ø‰(‚%÷ƒ ŠŽÑ@SkiKCmôýÁK?…+\Ú@€«7/ý„`*o™: ¶Ž9p|u<ïØ˜8t^¢
!;CeÈ:yš±´ê ‡:Ö-ëÃãc‚Swz=„þƆb€xMmó®Ê©»¶]¶ÿñÑ/øãšçá
ŸîU9è2œ!ñȸ·Òí
ºïïÝ{èbÚÙg²ÿ7ËÔ”óÐ,œáÒã½c´N_ýàVIöÿ§§tGÿUd¢|¾>„§€ÐÒ‰T«BÝG€ùüô˜úî(··Ÿº.ñwòÕSþ”`‚Ã0ãL
ä
…–¸Mé,Qfsê½L¨!ãS R᱑œ%ÑÑvG­v«~*®M©eÏÊr(„F&úý>@ÛŸ=lÐæñÀu}p n°Î<®åAñ—…’7šÛÀIP̨EÒÐcIg˜lŒ1Ä“`¬ÿ7,<´ÕÞ%Ô7ª
·pE0­«è¬Óð…òBÙ±{–G‰Ê.Žæ?Õ.9¡°WCpñé€í/û ö¥*_ZT9xØ"&Ju²7FÇcöÇÀ¿ó}õƒ¼¢§‚;IìÒ×€iŽÑ	¨õ“#@§[¸w÷.Çi îbF”í§
0òž~õt›<%L2@I/onlQ™tÁH8œ£þ§¼ðåÛx§׎ãWÓmõa 糄±ÀÀã
#ß*ÒS4X:E3"òk,Æ?&rðxLÌ!ç"hÇ;¼ÆSÅÒ’˜¡hdUúÐûþÿ¦ý°ôZ°Þç
T76dí~Ëùk2‘#ã…ký#ü[&ý‚1îV8Ϧ6Àûd¬'¨KìÃ?ÃЃ¥pe9&	ÿË—NƱ´´äyH@÷¯o¼úÒ{]3¥`è³[e<ý᱇"Ã.à_rP€Nl¿wWf3öîâoŒ òNA
J×K°k©TÑìÿÌ)áXÌ*Ê·µ¾Ûþ3:÷$|Iÿ
Õkgf؆cØð‹Á?uj€Ü=Üû$Mîe8e*gôþˆýÃC»InHèV7ªˆ'Õ%:“‰™Þ!;¨}ÿ˜rüñŠŽŒ’sŸ5ÇÀi’Ëån0–LcD÷ƒàþ —0½'àq‰Éwl,µd%ß	—¸)MÆóðÓãKþ™_—–8:áà)xå2isˆøGäüe"çrkgofÐ,Šr¦¼F&’=PÑÀm5	 1*±œ{¸‘d´M÷ç²$ùu½.rINÇ÷šç&°ÓA‰Ç{ãc%EÆÙƒzár›GßÈȤ£Éd„oô(”¦&±úçC"w J¶—{Sµ·ÎþÿE‡\ ¾(¯…ìôqä<¾´E^¸Ã¶h‹öžú3JpÈäÔ’‘9³µQÎÊeÙ¶eÅn(mmÍ×YB™·šJËã,œiÍjÑG÷qf¡ú<÷ù{Ý1PÔXâŸL&HðßÔ&O=FÕ%TJü&ù¶04Í,Še¨2Ï€•]ÌÌâèuÏ€•e™„8g½òæô†y¦çÙe£g™èœõWÊ{H‹R”L‹áÍ‘šø#LÊ…Ç1¿T¼{{meÞ«Föh/ ´½÷¨´ƒ=AÌQ«Õ	´š­,þs
Ô`f²^7ÂßVð÷¸W¯×X¢§‰â€i¨„šVÿÊfïïõID¢½C=ð¦6`o¯»d¼7&pWkb5ÉÈj¢0¸iø†a¢ðàšrÎ..è—’ÇÍ×€_:²;cÒ+'29w¡žO"pQõH†È¨øêÚ_™–™Éu&UI´k‡`4ÌÔ#û¬åØD¾š%3‹MAf‚ÿ‚Š’-Í‘9©‰!Bàâµ\S.·»' €âTÿöÀŸîµ÷dÔ
­	pǤR@åˆíê¤	‚`zQ¼êÆ¢þKrBšRÿû ÿ½$‰-¹sç!¹aýy»<)›±¿ÌDñ™´Ú£1¢cü¡Ö-c\eWÚƤ«	 ‰æM`.ÎÇ=Š!ÄÌ÷L\;ÃâÚ|1Sβø¹Z@öï&±(Ïì
`e%ì•=[‚mͰ3ìþNWA^ƒ¯ÿTo›iFùÁÍ?üaHÌ?dÎ’Ã?	ØŒ2=‰—bBþ漋EùÔû€›M>JÐÅ9¥! Œ~@{{k«Ý–¿ØÃ´ÿÍæ­ÖpŠ¸Í™S€ùx›žú”RS†£&€ý}`¨…,p"áî®ä€däÀn–šÖBbH W—€Áp÷èp|ÈÄÚ`ûã"»È{Ò@(L&œ7ñeBF@Ezõ} “c"~ì9W=d³¯y^–5o•³;X8‡¼¯~LÌ·ìVVÎ`8.7ÿ¼kÆ·b^3ÿʹ¦ñ¯±o¥‡Î~ HpV`¦#ʦM€æ(­^	7Ófd“å?vn?J'1 ƒúñv@0Ú{{Êãï¡Ø¥ÃÐÕl¢ˆD*}Ý ÿ@
ð†ý-¶wÀ?S÷‘KW÷½ÞšJ
`÷þ}¤ÕH¥\à“…2™,8™^ÖÒõd¯
!pî;ê`Ps”•Vn@þ§E67‰Zžº­Iw"º‚¢ ½%c!%ºAÄÕ$@|<›ÇÆ,óq>=àô„~>5êÎ1u•+€zÝïÕë5ÿÿeïíã¸Î4ÑSçœb{ÝVTèî’MUÙ¥„t¯º%ZE‚º¢(¶\
pˆî&á,5Ú57DÊc9¦0@n°œàJ4D2šŒö+¾×Ø
Çã_6	¬‘ÑîÌìÜè¾ï{N}5?l'™ÌÞ›:¢ú»««ºëyÎó¾çýh`ù+˜—Z­ØÐH;Å­SÉ	Ö?6ÚH0±Ý(d}µØí^šFXsÖÖÿÎ$'\¥”³CùÀb.ÖÒEÀ
p
A.Øî—GTÉ	+œÃû!žýê?€»;²‰¾Qí>ûLÇ=«ïOÊl.ŸÂ~v%}é+@ݤk.B³¬Qø‹‘L)³‰€‡ÓÑâäнõÚÿÄdg:s-\¸W¿‡v7Iúáŋ܇:)=‹}ê9εÒO¯ÄŠTfìX°àƒ Ñk`-íHÀΘ	þ`*' ¥ëÂ]ÖGîҹݽtéÒi €:_ÃÕ±ÙY@¾…–.Bá_ 1 ©›'7ÉSÏðýÜà_{º¿ùke~‚—ñŸ		³œº3º0öWÙ˜Œ,h7 jÑXœüÅÀùå{fBø[QÚ²j/Ìál¯‚æî¡÷ÖTº¤Ð©—[¯c“	@ø·üÔ¦–´Î0¦O`„<@°¾›ô^ítÒ©ÕçöQøÇÿüwì4;&È:?¿£ ãd±h‘Y/àÈ:–[€
ŽàŸ‰ÂXŒì3Ì/|p?Š Fÿœò³éø ØÃ‹©1ÚºOøÒ—ÃnÒ',ÓT€øÚ~£¡¸‰›@&—iÒµö",„ÌÀÕ@8©q×Ôq8ä¡Ôø™Ã)Ó€b€|,À)Cu8Ff"²óåA¸šï ¿sð
â°·§>%BöNeÖ˜šÿ‰W÷¯@d%ÅØ·kÅÈÌ(Ck4°Ôµ²­¿êsk©OÀ	€.ö5½ò†óÑÅÙÄ„ˆãYðHÔÿ¾@·bê莂
0‚z¿¡	««­AÖ©)¥§²ä
Ôd€ƒÀ®š@
øç³ä`ÍÂ>°f¥>£Ä•‚¬Ì®3MnYÒ"=!?;´“éÁ–½â¨»‡?Üöò?Ç a™“ŽNÐÈòH€l(ЈP͇‹QŒO_É* M1¸ö—>5Gklk:2HµšÊ$³GfhñÌ€ý©‘»ðÚÁ20@Ã4þ[«ÛŠà\>uªg³]:u*㨈gIUï:)hÈÀªå·µ训ݾíXÀ¸h†V’€zD¨ás¡÷_Uñýª9‡á÷8qpðã·'K
`Sùòå•fœºÒ´„0
û¿GL8ú¤ÉTõ¹…ädð€.â+Í’Ù< œ	 à4ô
Ôµ< Iƒ68õ@$¨±Àêv{‚зía|%GQaPC_0
<=MF2€¥Ã”`þŸÅHeÿ'ž¶$ÇÝ¿"#ÉÓù8`ç€ÉŒ‰p  PG^Œb{Âå®'óÿ嬥~A…hkôm:ùÎF˜oAøò\¡v[_Ã_“ŒGö¢°·x9”w/.û·Ï¾+·×ºJÔÉC6«à‹ßè 駱ˆ¥dÿsÁÿ7ø±œƒòA~‰„)Îúbü¦#9yžñ|l^ÙV½bôÙtØ#×_P*ÙêIOeÑ•Jq ®¢Š¾·L—k0ò[§·Op—îÚ¹JJò™eûbÄ=z
K4ÑvC1Š¡Î‡ŽŸ™äivÆÁ½‘y=NÄK	 …}?mÄÒÆ]
¡ñê[E0{Þ–l‹Ù¦iÚ%›ð¯’dM;eZ¨TÄb¹Ýn[¼Ñh$`«ÅÑM‹öªíG™C5…P/±ì²ý•ªäýöþ³‘¯×9hÈgj_ÇVgñ~‰.ÀE”0lE™WðÝ·2áÁ!†=ø‘ïiÂÒ2ÇÆ,&ôèWø×…Ø>ü	ÀvübŒ1øŸ:ÿðaqîøÂñ¹ŸÎóaÆjq/âI™îï±gq+^C¿>#Ý#:ÉEŒâ;t
­ýÉ÷·Ô^¢â_ÌŠ6le„‹Q¿iLØÝïùo£CÀF«€žv'-*èo”ÅÉé‡2ÀÒ0ˆx럟rIà£p"L½ñ'Ýš›ì>€ïº5¿VûŠ"µß‡ÚÝÊñýÎÁÙ<¥€0ìˆètb¨ãB~=®ê“l?¿ÿt_P'0Pä#þ'ðà[cãæi3&€°…øoµÂHõfûÐú	âÿ³ò'4ýÏ‹Ç'îÕç§æPŒ˜˜ý¼šT’6’¢Þ1.Ä3c¯ùéPŒºÿƒè$4C¨†á•²
â¶¶€us*e©,
¸Ÿ*Ì4©`‡­	 Tj6K ð1óžI=@>Ø•
?	ÃqN.-5–§Ñ@ö˜r§¦\9¯pÑÌ ×ÝÀ?¶$¦Ö0Òm€nÿøÙ¾Óáø¶H	`5£Ý3.ƒïkÐ/ëtR|‡Ú¤¨c¸e.œž¡–ð÷÷±ñèÊßZ1þÃñÉ–„a—ÌÓ6+)øÃáÀüµZ-Þ¢ ¡ŸÜ¹páâøÅïª=~lÌÕï=œzˆ¾€bC1@2¨÷{¡ä½ž#³ß{öh/*ËŒÑØ¹TòÇ·xì'ŒäùÃÜ@§6.ÇNô¨áÔ2d{¶
Èö<¯ico?»Ô´›6·°&NûM³Ùüó²])óÀÿ¤Ó æ[oØæ”œš²¦0á¯Ì'€°™OÝ4j	À—¾¬ý¹nâè´ŽWûÂàâ§àjBYPkÎj†:ýli¾ðC(@©§‚EÅ×î=ÐþûØ	aE'„~ˆ U–7-{$+îÄ€ò¿å#d€ïÎÌÌþàÂÅ•€Wüüçó=õPÌø/†Æ?ó݌𺠖þˆ}ª¢ÎùÏ:µÅèéZ€šóSR >ä4˜àrÓ^±kÀóôiôú’×lzîI×;ûÅmÛ3›ð6œòLÖœlúͦe5›n¹ÂÇ„Óèâx`ßò§ªþ„[¶Aç  ÕjJò¸.weM
õ=¤"õø¯,sÈýnÈÄ*‹'ôµŸŽ1¢‹
:)£g°~&¢7Wû<>\A`ÑS`x!àßÕ·	€")^Äl±0B`´²ŸÜµî^¸03sáCKJ”óÿS?¯?~\#ãðS¡—Œ
¸ª[GàÏùIñ˜eCÆU³N§âÐE̶ü›¶E.l“p©­‚Åßl’®÷šÔÜÎõ’
¤À-åhº““¾ÛlNN6YÙîZ1@ð=eù`œq&&ì2²úájÄ”ÁoaPãq,~/…lŸõ󂪎“Þ½†¯Ùô±ˆQÓE‹b¥±âœÄO@¸Òæý)'€ç'ÈÉ Eñ\o›fÙEG¶qK«ùU}guµßïdˆç£é³3:ð[R
aÐS‰éŸ¨‚”:¤ Võ:@÷D„nägX\Ñ#Û°XÏEá?„Û!zÇ¥5^ªœ²¬qò0£2æ£E>€ŸH0.`jµ`Æ_ÿüç?7Äãùâ´/FÊ®ŸƒoÖÂÆÜUã™ÁŽzýÁbS&À³õ'2·Á¬}¿–ÜAÝ¿ÎÒ’y€æ{ŠZî
Ðå¶=D›¼ÉMÖXBèO6]8ÀæÆNRMAçdÐ@ƒÁwƒÐñ#Ðúñ:Y„ntE f0m“$mÅèm,ÄéxµŸ‰†Dk#~þwDç	@j_Íÿ ®ÉD÷t	X°È2`â¶T9qŒeFÐG‘n…Ö¸¿9^:])	^BüÃ×ÝBõ?À]Œ°¬ŸÀV”à¯ÿõ_áU〠Ã?2ÀHöˆÈ;˜ÛΑ'ˆÌü¹Àr¶õkðÔkÉ}ãÿšÕåsP0,Oê¡`M¼ßnƒügTqüÆvÃS5¯˜^à`P–p\ ò•
(×4¬Ó}luV“î)[(#Àȯ`lõH:8Âȼ&$“C† ò¹îÕá«øGP®ˆ”JÔŠ4¤GPü%>”ªÛ]FPøø…Ç\¼¯+|€ÅÐŽ/ßÉ£Wäôº8XÝ"kŒ¼žåÖÆ”‚8ðfn°£lP±ženÀÎÐúÇÊ(=úƒÿèbo¸]s:H°(ª>àšª/à« G?uažŒ˜Ò–m—Qü«’Z¼¨P¡¸ß9¾’‹üWõÄB;lÿ#<$$VI„9θȰØOXC¨"a ¾7Âto­’„?MÍÙk…œð¯S:@ÝšFýa‰bú/FÊÏ€ÕlI©Q~8PnꀇÐÈUÇÀnÚiTÁHr|׃¹§zP'“hX Å
ø@2Vøñ…‹uÇV„ãàª%ÀŸÂëqêwQˆ´*Y+T„¢±–½ŠWä_ˆXÅhBLPM·ŒôÝ,ö(ˆ”Œ\/žÑ¯ÓQ\ã
ÄloQ¤èHØv$2\QÂ=ÂܸTo…Bˆ\º€ü0NÄÝÁÈÈbú/FÂ~fýëÀéyÔDmˆ£žÕ£ö	@p	ðugЄ¹žÇM1"°¢_³©Á!ž •¶Ñ„Žc0Uÿ/A$Æà
E‰GR›9úíShì°>O”é	äÊÿÄâad%éJ¯Ôø^e™
°#,Ýî{æY+³<ÓÛáé¾q(q‘PŒÉñ¥"ލ±?.2Š€Î}ÏI»àxFLð.ò„¡64â‰|äY²[êÍz7ò~€_í¨s¨?üñüÁ¦xVw~GËrDoÅYXŒ¯Üìiãèwã0LWeî9òg‹l“ŽãȬSÌyˆº|§ÿuÎ÷Ò^=“}ÀMd9¬È½ÒÀ$ûý\ŸŸÃ†W«e%Qœ)@Ã4g+Ò03½‰UTgM»N„™}rþ¥WŒÍΦÏ6ÆÆlÙ¯gÿWÇî°sÔuG•o?òEIé–Ì­bü¡]QŠÎè–Š†ó	ü½”Ä!vɬAÏÿöö¦¿‰†4àNÐÃxEê#|/ÐÅ&kn
ÞŸfÎÞ2ä¬4f+úhºïy]¬Åß]£ƒ·°Ý€·ÜÚÚâ[ßþ6]áÝ;³³[³ðnÆT`ºî”i—ËøBÿt÷RYç6!ò±7Û;ŠùMu®»„8‡¿êæÛjO¥õöÛþà	@%*[Ì
}zÚKÀàâë8ª.1¼©cÝC˜³ëÊP6ñM¦ ¨:2*ïtÔ͹‡Ö´Ã"ÛŠXZ™ðnLù™
cU»d[~â§p#Ó/?|è&N<ƒICÆé¾»U¿[¡‹à÷›,ð·Mßd†«lx_4œp7aCxÑà™%¯d{È15 €³æ×&†9Ãò–iXÓ0+? øû~ÝëõúÚ´Cõ0YÉ÷Té‘­÷AÎ_¸p.ßGп?{Ç2ï¼Ç4·øŦåNMþ…aa9{||jjª\.)
ØÛÛ§K`€C›÷9œ;jñƒÖ9å¦$!–a¤Ž€·oQ™aÉåÍ[
 ™¢NEdB˜;„­7§=Ñ‹Íô¥™ÌÈ/í›ãÀÿ¸[¥³ÁŽ˜Eö­›q“Ìkˇƒj5È3
àLÛ;ŸñÐOeûëL~§Ì’™>bZU³dU_k×ߎ¢mÕ½PëÿXwþƒíß
I÷7Ýím`€mx.ðÝ&¼{’`µä–67]>ÄX`›ÁìÍ/{5ä䤻ø››½…ÞaìVÆ4H€ þ=À×늮·6íÕÆá›Røe#lm¡×aöýYC1ÀÖÖìÛüÞì÷L۾ÉL‹9®c—­©óS˜­X6M¸?>Ž}ù{ ¢=¶¿wxZ2VL|÷Ý,8Õj5­Úî8 Æ(½À¿±Ü¸zu%¡)ß~ÛšyûæŒ	PœÿÅ€…*d…(0‡‘Ðó˜véóSŒ™åü
ÎÕÅñ*0F„‘¬œE0ŒæêäzWU€üÈ´™‚ Ú	ZQ5xÀûÓÌ‹¢d{ÕRÕ>“á€ÿ™R¢	ÆÆMÛ,K«TUß•mƒI‘X”\‚‚ºÛÀÛa+T
~ñ¾À.!ÝÕíU×ßìMœsU/à/Û¸àÈ0Q؇'}´€ykVgCÊrîyë@Ý®±Þ­wA*‚…%ýÀ*‡\  ùÑ
"`^ñ½ï}TØM8F`yÂ-UŠs–b‘ɸµõ>2ÀþáߔҬTÄ”(c¡ÎÇ+¶eÙ•JÂz{äàp@ˆk×Pî
$€ú»÷æa(‹p	\ÎåÀeªMØÜÃ~õësä’ÀË+++
b93sóí·oÝzûæÛ7oJ^ àà$éÏaöYÖiy¹gt‚†FKRAÔŸÊ,l´7Úƒ6k³´a„Ž@š„ˆ%"Ÿòz-_ÔÆþ°ÚjUÑQ°3
ÿwB­ÝπƷ«<™ò)ËW[Ä8Ê ±9Ä™’&€&¼m'®}¬-`$ÙÆÕ°€A³ígW	rG¬,ô|d‘ð,‹›4‡»,Žë¡í›•2וõg+ø}yݺatÌ´ëš èà×$5ò¾*ð¾!”oÙâÿ}¾µÅÐaÈͱ
(À“.c×ü—í=ö\Õ]Dü«XwjjjrrjbByÿÿ/¼ðRàÖ¼[T]eô#l¯õÂóËíö2i€+@+p€}ß»…$p“P0@@¿U»"8a`Þïõza¯¹®ƒmqv…Ù½Ÿq¶Q(s’&%Q™;'tÔ|ŒEët>qç~zO§P'@ÇÁ4[cÖw©X%i“Ç€?ƒ5«é}3¿´K¦^€·üV˯ ÀÉÝßÖ0\eG˜Ëo2ráÈ>LÙÛÛ››>ù}ß2©ªì„úLô½ä½“«z(s¼uU.Åáž,›š0Ì2)±….&¶±¥—ÞÇùýý-„ "–`ÖGy„0…m~˜SS%U
EÔþþÞžAÁV0ûOÀ³ï¾;OøEÀ»h¸€}GJg d!Ô£N§e´Z°?WgbyŒ€+$f@ýß‹ä{Ào[…(ž2ýþîíQ›€¤'DÏïõpG±t"
su¨Û`ÖW•GY¯4ë¥CGÉ…PgáB€jÿÉÎÕ3(ðE¨3þf
$ÂŽÚ¨eóªiñd©mýª,™I…«
BÙ,™	#¸À™•}€	JðôÙíÅú¦FÖ*^î»›z¡ÃDü›€RÀ^6r@ûô×åyê1‡'n8Ø䤼ðmÎ)¶™_ø¶~?@¾Dà ÿ'qƃQž³í1)ÏÛSS.UG}þÜPÙÕè
8£O€@€À¹wožÐÿúÞu€ˆ\Žæ~u0¨ª¯7ÄL`ì±¾
Œ.Œ6Ùh =¢ 	àæÌŒ,|þÀíÛ»,âxB{„üžï5§…Z
NLtÀx#¨*
 G'ŒƒS·"íÄ駤Ñáí@³‹û".›Qß.ñdñ¿üÅÀÇuq Í>@6v,Hg{aˆ†@†X¦ØèðÜ9Õßžëmú1€-°åƒ .3ê:¾çºqŽ¢$ú0Mý~o}Býדevß¶†:t
пÿ/\Pàý÷ß79·m´ð3mÓ³n£‰d».PU“¶(Soƒý_ÆË#äDü£T€ó®òÌÏ¿‹Í“@™üÁ¨*NfýjþÃ0ê;@\d¬¬àJŒÆ?0ÀÛ7g¬‚Šù]ýÝ]:¢TyÏ Šs"Y	„é*™Á°o/.2[	£H—|[•I©£3‚rþe‚Ñù6€?ÜÎdÿfi€ ÞÕÛT¥~ÊeÄ5>`¢“¬OïPþk1jrHøW÷•ÀeNo¸ƒ¹@0ÿî9æãÍ©)P$DH‘¨·ŠÔߺ÷õ¹¾–Gò„LWÿ
(Æ(Àµ~ô+hùïÄÄÿîð†Øõu†¶`ßÄõŒJ®à…¼sÇ\¹sýÚµ³Ó_ǧg°/oZŒ?à/ÆÀW7¤0ðô¯V]VuÕ)åœñD\R·î6à^\¬Mœˆ) ˆ°H]²Ê÷j©R:ž"ŽÙK9­Õ¡'ÞóFH@¤ay`q[–að¯Í»NFæl´Ûq¿°±ÁV6ŽÂ?Õ"ð{j'{k¬ëw©T9ëÂ- oN³iº×õáÎÊÒ5&–¯Áß’À~åq•н}#Áÿì‹àïúG_|4‰þönî²8 œ»Ý½ÍÖ.i—¦ÉÍÏ+Z[¿ÿþlúqýúGg§åWEÿbd€/~6h®êÉQŸ+Á ucQyâÅW^tï'Îôëµ0…ãÖ&tèOäG‹0—&„5ñjé@µ)7.Oa€|,åð/ê©óÁóÏz£*ÚõC˜_RÎÊ]Õ¤±«…¿˜Kñ1É(@¹-£~/'ã70Ýé8ýïa²4£t¸±†wÄzoÍC&˜ö™×…ù¿;
øG¼/]ƒ¿¥¥¥•¥x4þÙ›À}$>ú.¯ôÑG}tSl÷w·Ùöî\´»{{í6¢g‡íî°Û—nórÙôƒ2˼‚ -αv¸´®ôÕ@ÄPP@1ðœnú?ûü³øôp¤ëH!«%”O0Ç}ñüy`€óçOÀÙ¹èÇ=;1±XwEùÿÊÓf•^ÍOáI®ßÒR,!(®__Já¿ÏÏžïy†áÍ3€bä¶RHb¢¤¸±Í|w"nvèìj;f.‹ÿìÆ0:C€þÜ|)˜á$
 Á>‘To
…y¦{F-Ö1>hzz½ÇèEKËp¸ð­$øgŸì¼yUˆëoŠ7Apq]ô±Xq’ªßçúëG;;|gw§`çöíòç"Àä•Ëfùûel§Æ¥Õ^±àòÊëß툟=·åBƒN‡ÆâÕÏ€ž|†@`!‰áìÀj}ñ<àÿ•ó'^¤us`€ÅF#ÔÏž¨-‚‚Ž‚ìæ,í|73ÀéÚUpýH,Aç}»¯%Ïö1áìô‘€ÒŒíÿñéùqh—þS[œC»çâù¯=ò
äD@{¤KËBø~Ûù±Ò[ëuAìw{ÚH_÷º^¯·ÞeêVV®	±²ÂPhøïÓÿx¯¯^}óêu`À_P™ÿ0ý#¹ö£Û·wúýh­ÛßÙÅÜDv¹R~ñ+¬iIËZn·W`\]‘ᣅ˰t:,+0¥öäs`€ÅEŒ(uqÝ]p©¶ê›Z›˜pƒE’ÐQåñ¨³^H‚ã…c§a{ÁÒõ%œýáâ±"6ꢞY¶ÞÙ?Îìb9'X¦h¯0íŒþ±èŘ·Ë9ñ|ñ#_BõÖ{‡ÀA/€×ƒÿÊÀívðoŽ}½,€^@`€kø	/b ®ìïk¸~uåú›`\¿~E00û·aîviþÇq»»Ó?LþÚWQ™­Ø•ïÛ/V”fÿå«W–¯\¹¶Ü^N‹´š™Ô8åKã¦ÿ	›Bƒù++ËÁÕÆàóÏ1èÓs¨	‡Á ¬êY?ÿ"*€W^¬Çh`ÿ×NÔj5×YÔÓ½¯Âí²2̈́׵
€/ÈÁ/b'€³[_ÈõªðÏžÍÛþÉlYïþ‘ZªËWŒà©Ž‰”œ¹‡çæ£=Zç´×úÈ€Ÿq¯éQgÂØMÑ	°sþšÂ?ÀÀïM{Ýiòˆ•+W––®-ƒýmùšÖç{ûð½	VÀ›×¿øèêÌ×…™Àn¿ÿÕöù»ÝÛð@ŸÓB`¥\–労L]fÿ«×®\»v}åêr2Å‹¼ "ÿLœ¥"$į¨×QÁ…¸,£ølðäóÆ@MPÂA î`ºæšž?&Àùóu×a‹hÿ»5·6q i¦aŒ2€Y)¥À°Ý\+0€ÿõ_Ùî9õײoñÀÖOÕë#L	 Pv20·;÷ÂÃx_7 ¾‘ÇßèMLô&Ö—~(=ÿ0ý7›M/Æ?ؽõõ5Ý´pz4¡Þ8-V`ê¿‚*`iIK€}Tâ£ü£þÿ裫o¾ù˜Ñ6¦gcÙS%úÑÎ.h	ܾ„04¥ibîPy¶Ì¬ååöÊõå«ËËËW®*Y/°ÎO®w+VIQ¦ý³ñ+¯U@AÆb°¼|ué³k`þ]iR:ÕMß'Ð	€>€ó0ù‹Ew±v¢áž¨¹gñú¡b€Ì6ÍWK©“¶çfÖñ˜KK×Áˆ˜>«ìkÏЉnFXÚh™FB1-g}ýš§Þß~ÂpL»_Ы8ÿ¡“?Kèì¯O¬§žÀ\*±ÈJ¿‰adP$â~
G¯KV?^®{Ø0ýO\°Œ4°²GO¢`LŽyþ®+OÀG_|„a	b»m	Ыû;èôw×"Z
4ËX¸R‚¨°Æ•F»}uŽHÏ$þŠl¤bäÿŒð…Hmn0ÕÞ°`€?xX\¾:h<¹öšpV8.–™R¸èpN¼ø
'œú‹ØW£†øwê`œE¾KL?uó	k‚Šg1SP:áfšÁ’,#Œ©»uQÏàñÏž…YöìÙ?V¦ÀIáò˜Èý™5 @ô}•Y¤}««Ø6$òyÂB8»ó æ'ØF;­†'ú½WÖ×{p‹h¶Wª¾›ù†8,‘0¾‡a@˜Uà+è!ôz=À¦»Ô[‡—!!ˆ+×ØÊ•¥•åe\Ôd(@põMvý*ÌÿWÅ›×ÅGøJ€Ý]ÍQ àë÷ûk]ä0ËÃÙ¡Yþ¼2T¤Ñ]æËWÚËœ€%	Ùl¤?™ŸýÍG¸ãupa´ƒØÆà3uvHWJ.ïªE€ó/ž»ÿ<ü¡ÏÐ=áÿîÀ@ä;Ùu{Aa@V¥òjIUÉÌöåKKÂPh
À²5N^–œýãé³~š`ÔâUDÁ	ûVrv÷|ŸÖÖÕ²èÝUÞDO%ØóF¶‡fºÐ/z=#ü®O¨òGí¶066Úí•Äû¢Z3€ç÷âÚ?ìõzZû+ð°ŸùtOp±ÊÿŠBþÒµøãÑýwAÌÿ7¯sœú2óú@*m9Âb­áîî®
d±ŒøŸg+åY`€2[Àåò•ŸpåÈÄ™…ên^¸‹¡gƒ´é¢a,>Wé½€LK«ên´ ÿÝçÄy·^Çi˜lÀ~Ãqj
"GyÉüxޝšf¥’fÛöG'À/–("(~´žoX«ŸIø;¹›Üä5+“ËãûêFŒf†ï(Ü„v]‘‰fˆñ4ÖÌ
Õ„ IDATæ}TÿÊþ7P¬´}Y`¥Š@á†öÒ>y<©þåS9a3]a€°²Ô•XæW4ò؇ã[üdQå.]åW‘>‚£½z]½?MÄk2ZþÓÆéÏ9ÎÂå,_YæðÎ+”uåÊ—7\1
D‹AçÁ`eQ%Ð]ÕùýØœZkþë0ó×É@+uuwÑÅPÀEg±®òé=ÇÇš|A¢ÄDéU똻*¹Õ@úÈ—°”S˪Y–fù…½õþº¿Þs't¶Ÿá:½\×O¼€s†ØÛM	`ƒ£ Å?–@ê¯k|lò}])`ƒ4µß…¯ CÝÆ=•pˆL€7zkB]­©ää.˜þêJÝÑ£®–Ò/àû‹ß݆àö€	èþöœÊYŒ`êÇý]¡®0 \.W`PŸ±«¸h³r…ð/®|…ß»8å‹1âB?ªUn¸ÊJÄêSç$½áöØÿÚ@ùÐ]§µý™¿›=ÇÒïEÿÔ¹êG†È·Ï¿qÙˆgÄ~K ÅÀä‚`	­”}€LQŽžð¨|€v~z_Ý%v›žö²÷—Å2<¿l,³t¡îý7’¾*®þ«ìjº=ø8¯OÛV8
¬Í<;DèƒÀ†³§fO©Ï[¹ò›µ4/F1ξê~ÕÕ³E\Œ†éÛ‹‹TÈPDÿâ1òû$°¼¼_
›=j­(z"—`P9ݸʙ12}üÐ|‰ï¸ç£¤/y}zÿ”ºžÊó÷oòŧ~1ô(Ÿ:Â_täpޝKƒ£éýöÓEý£gÏâ ÏÔ#ËKK™v¶4¬¸IÀÙ*;ËX©‘bF#w¿T:GÅùçŸfœlŸaíÁ6ðáfÚž;êÑ~›Ô
|øµ€×.ƒºX:«VÏpQ­¦4ÍÙot³5>ÙOvåÀol|ÑüŽ~v Âûðý-ê#>A^Ï3@xÈ­ìxmanîµ×ާ€&çÍôÞ^¶´MÐdÅðìcƒ=û;˜s€©€¹s1X˜Ÿ(TÍÍ* ¿Q* ×E2XÖàZ“€´gq©Lå£3 á®±€~õ¥—ÙË5}ÓǪcn¹`–,Û.™¥SX‰Ô¤Ï·áŽÉ°}¯°†æ,jp}¤pœÍo5éZ‹ÆÒ>$~¯çc·%7À¾*ªí íùgÎTcô[_Ì~1Èä7u©µy†vâÀa "dƒýÌ×Yxážf€@02CÏÉ¡þ%ä­1‰å×
(†ž£†Ãrön"¢ÿÕl‘ gaޱ……¹×ŽÛ¨×äºfŽ`|ïé#µú¤çO§{‡ îö>~Dø‡Ù¿½Ô^FPç+PZÒT±ï³ÁÙR¹Ñ8[.i¼Ÿ=Ûh†wV3€4ggË¥r¹tÊ$ðìŽÿ‰ª/Ÿ¯¢—0xI1¨?‚í»Rï—4MÁ*R;‰Ÿ/lŸÏm¼Àðšô[ßjz¾çGpø8碹¸l¡¿¹Ðó#?ô{ØŠ¨zæ›gª(߃BMþk`Îb«€šù}·{‰ Y?-g´ˆdŸÜcqE!ìêðÎ¥‹c“` ÿmÚòKxŽE’Ø›°ÿÀoºèb1þàñ?»µ5Ì(PaÐìã²Lt/ÌZ™wÌi8NOú“M{úlIÁ³ªúfvÖbê›paÏ'²V”¡ñÑbû&ÛO ðAÇâc€MžØ€ÿsOd'\R)P{ܳÇÇK¥’UœüÅÀù&Õ‚pòM$™þUJ÷0Çê <ç’æYÖMK<›¼¸­ÀÞSœäù§®îU_~©Z«úØ[´Z«!p\Ĥçb0õ§$Í û9ErAÝ
‡¦ä|ȹ’€â“ƒ4†[e©} Ü	 €ØŒÄ9ëÇÕ8è~Îáss¯þW}c$€uþ=0åÍtÀkN6=ƒzîÆŸ?zô\»ÉO
óÍâ ë%Mû©)À¨€Þ2„´Ù²v @p‚–‰Â°±Nï¨pÚo |%òýÁPQÎú~+Œ×W¡µ*ö1ƒ×¿t¾ªIÅW^‡³O1i£‰QŠG¹ÌÔ=Z&ÌýV¢GÐð×½Qá¦Fz@Í›=Áñ¾¿ÙóEí~ø?sF	*üP:4ôàAxšÿ®¥)‰;…鵿‹Ô©d$@Â?ë°ÕNG3€Z€Œ‹}ÈØ€Õ_ÿ!
¦¨ãüb÷¼HD™x@¢KbÀõ¹º³ ¨Îhe\¸©ðàMî½fá¯Ø¸ ºÂYI‹zèÓ³pu&~ôþ‰gþH
 DlãùOÐr]"J9`ÝÌß³.Ó³c¦ÏÌ1౨F\ä£Z‹pEÀ¯¦ó«ˆpû‰¾…÷m;ýü(ýüá¸x`8Ô„GhPo_ç`åØÜ졲ùŠà°ƒ*zÕæ°KÆï™™Bç®ï2‹€FÆñ/ûü0b	ðÁ*P@«£Üø-[L7„Ãî<Áãzç‡CÔ06F\œûÅ 3tŸq\WÖt(ÄD0
ÀÏP@¶*œ9ÃpÐ	àsÊ¥§‚St”™˜lRJÂ?NæÇ( ¦³‹…iQ¢‹eBðÏž}¬’ák`i™!d®`Õ=k6fjIà5¿ÕÌ~©ÉR¼PÇ£`úx˜û¸¬‰É¢“‰Ôyq9ržý¹>A'e&¸øPµPñW”"6~øÁÏ1ÆÈ¼iÒ*‹¡’Ýöu[zÕèC(…›=;ëFÝ!÷ßÏ7Es2“y£ˆEÄYwT(À²’’>	ˆ©@Ï’T;\d¢½,2xÄ7)›fÿ2زqVkÈÇT]-„,›ªÀAù~0
üÌH{1k/Ѿ	ÿ¥—3øN·ÏŽ¿/%EÁÀ`JÏgº_x܆X{à
íôŒh¢^O}Џ	@ÇZÊü¯a¸~D/Õ[6â˜]¡—MM)eÅ_Ù«­,(C„HÀÿá;CØÄàZ\ 𛓆º)[Ò*D@Ý5[d²^Ù1	ªñÏÜ‘σ˜Ìd
ýÅi¸?S3óü‚€dûËí
jA®|€Ì²tÇoIçpÐhCJi¨„@x¦Ñèù A1Ë%Õ-Ü,•p_? óƒ}qç_~I·¯ÖÛþ—ÜàÛÂ8„$þÕÇùÔ8\ñ= Ì!ßWåCz껃™_í€ÔnÀ‘ï×sÁ€¢xžn–󪀈i*ü'oN×1ñB&^¤ ¾#tïô¸Šä†‘é§^Œb$òþ«¾þhüÇ¢ÿÀÆ ¸¾Ÿ4‚<ëÛ*@Ïb­ô½¥W*'^¥ã-žæÈc2®zƒºÀÕÛS6Àèö¿ä¾$䣀+Œ­Oª!ÄK÷0!Ø`QP„∯ϣ7yªö˜­60Z Óéd¾bµ–a$¿æ_ÍR•|,NûbïH
Ô/K=ölÊeí!ͱì=½™
ªjgî=8;r–Ôý•t‹K.=eÆTt<)í'+•Ò—/‰eŒyÈ­ã‡ÃâÊ*_ç]Ù-X‹Ó²¿¯&-÷0þcqyÔ,8‚ž?Úc‚³Ý0Òg²ðp껔ؚy7kÜÎ<ŽH‚–Õ²çÙ
ýc˜\Äþ÷ç´FÉ9¨âÀSmIïq_E‘S±2Òm„ïfñ?5å+ðºz½Ÿ®õµñŸó÷ÉÌåð¸2#‹™Ë¯ðYu–cœbãøé¾íä0Xx/™‚i©ZRö~F\[ÎâÝXëºôÛŸ?W„×Y
ØÏ´õîn7ÓP°(îÑÃÊ”³D«‚~9–;QΠ°[ís£-{¡÷ˆíÿdƒva°èhU·ØÃ¨Aœþ}Žþ;fÛ˜Å`Š–+SSÙû"òã0€{L‚÷+MæX=ÉÑ$úå†Í*é·9Ä§!—Ã#µÁ"9"Åâá¶[þ»ŒYÀÑPfEñbïGJÿ$>;†½¨ÇÆÆL¸ÒlUQüjCdzÑÐõ÷A`*CÐD 	ÆgÏý´?}«µËv[–H¬†ç´eűYS5æñ˜hò²Þ|”ø¹”
`n…êƒ1ñûoî1ƒ‘}|C®<É<
¦X‚U,Âå(às/U.†ú0V…€]–¦m–ÍrùWŒãŒø¬Ÿ(]€™ß‚9O
|M0¡£Núï†v;e§¥åd­6²uï¹—ˆ€VØ¡m®†úýž={öè9àNhßöˆP­{ãTß8ÐöF-:!M=b߈ïõYL¾`öp' XG»d᪮NØ•ÿ%sª–¦ùQPõÃ+0ðï°€܉¯¤œ^g➃Q¥Ò¬9FÇ­6O¬ÜbÕÓ§AüË!i(Lj3!	­xS,ê12í«E„ŒKb"¶ˆlHS•Ë€þ²‰éEè_1í;y4×3†KNü ±,—~¬PíÕ¿ZÄn9ã`}aÌá7m˜ÐÁN7K*0GG°øÉ:V«ÓAãÞB«Oß{ôèÙ#­|¬È—BÝVµùG]îN؉ƒé3&auJjÖ®,ØÒ.x´þiqœs;f€Šé»îTšÀ­º†‚üwøðׯ‚_Žÿ>IE+‰•nÍÞ/ݪÌþ_:-áOb·—‡÷AXkez•”j=Oü/o,.b÷꺳™|½ªFo`TÀdCN4È£‚-]ë‰	€í„@”M6JfP8‘žc©ïŒD7Xko/e)c&Ù/Là”ÝÙþ ɽò"á8kMZ¼Df¶Ðõöc¾hµ(vMX¢ÕÊÍpº"?Æ×l45PV}ž´3’îÛN¿ÍÈ€òøcì®ôÒ¾EÀ¾Ž°1;Á²xE¥ÿØ•1waª§ÀBßr)á`ÚÕ0qzÂÕÝ8
‘÷ì)dá„îLGÆ(ê-ôñ¡áXå–	,P™¥O«Þ¾4¼ø2\þíò“Á“Ÿ~ú`f¦Œ{o¼1¼1¨>y2X¬b+1ÃÒšU†)‰²ÑhL`‰T¨û# €ècd€ŸÆŽYf’ÇuÍÄ›Z,âŸ-n,.¦«uUúôÙóäœÖKÒL
$€p5o
ž€‘Y0È`{¸­’ii
 3f÷£‚

Ü!’„v,ämèÛ*ÄŸXÌŠŒ$!^…Ï>R;£Bžà\å{`üƒú€²m0¬˜²’,ÛD
€
çî+ëŒ@1LMùÖ€iÿôÄÄÄ«¯*ü[)ëŬƒi…Þ¯lˆþN´s{mçöNt›<— ïÍJ	Ìr~‹¾áéO‡÷Oú)ü¿ÿ)>39ùÿåÁÿÆàæ¯^}£Z}ôüCË4g±è1E4&ë4¼FC²úüÇõè§?ÝéGðûUÍ2âž6´Ð©cšcVá,˜ª»±‘@²Îe €dåæHS‹0$±m¤®BÝË/ç
PÔ`¢5΄M+í$!ÔÆžϬÒÊÌü╻ɿl´ý¸›§ÐL,y•!Z:FÙð’ç¿¢ #3î{—š‚+`úc¢3„Ñ(ljß"Ž‹KdÙ%rVløæøT,õôéW^yåôéW”Pd=)˜aả.'‚:¼¿{{­qÿC,7Æfålà>ŒOaþ‡r¨Ä“òwÊÿö‰KÅââÅ•7âfìXOaÖÉ f~d€uJ‰p¢ÚßÝÝéïîü4YW±qò·i=ðEHé¿,ð_MlcOÝhˆ—=2’9
^s‹d”zKt¡¿‘ÀQj@h*°ÑÿÐä÷R*ö‚œ2Ì®BˆG¿|¶—㜄’R,]Èø%ñ{Œ"Ý>T{OŒOEˆ±‰±À÷:”9D‹•Še©ò~‰‰<5E¥Ý©Äè´€0Ð	hî_=ý*RhKæˆ*æiÅó¿ZŒ«ïôú·{É|ŒiL ¨ Pcïãüæ:?Éš¢S¬TW«ñ*€0ÅL‰A
Ïó*'ÊAû?ê‡áOëIó–rœú«¯àè°¬±üÍb’Šñÿ³€½ç‹lãù£G"ñÈ?e\&¾4Ðþ¸N–øì[1¤¦ºÁ2sTÓ)È/¡k•’wì…Ùù¿óA˜yWëÑþ³g{yðÚíDè14tBTð­ˆ{z-á9	rŠôÑ™©&eÌÜõ#!šm‘VçõŒ9%¨-PLÑT§c €>Òþ§‘&\r®ò’£F¦TUÏYÏqœ^´Sû;šlU‹k–ÏÂG¼„õ…ï¿tÿåûò¾
-F}ÒæöÌdzü+ ®¾±æ°ü‹ ¬1Sâú*Šë^C*
ë?uB§ÿ1?*È2¹ÅÍÂ(
"°™÷ÑDŠúÎeq9Îg%Û_&h„­Œ—ÎÈØ¿Fê–Ï;ãU!
•¨‹.»çÏÃôÕ­N¸ÚÉ:%=Ú{F…„c‚ØØ`ž’£kð««a(Yꇋ™½É§’y}¦ô¹r+ºc˜‚™Æ9Ù+v&å	û
Ï“X­Ì0??Z
WᘰÝ¡ELÏÓ² <`Ã­Ž¡onHÄ4KEÊ߈N¾Ÿa\LõðMŠ3Œ¤çœÃ‘ëüp*ÿú‘‹"%¸ú<ê3Œfd‚ÎÓ§1¨	+ëéN&¤ÔÏv£§ªçW¬©¦·ç!‘”À0TuÛø~"-’FJ
°‘=Àá5”&†¯W-}U À0V)áQŒªca¸SSª.ZÂ¥G¦¦\W•1³00›È÷Û
ÉŽÅs1Šñûv€ÔÈ3rýUNnÆVèï_iHésTîÎHý#ycä€×•¦Þ=øÎ*«æî÷ÖÚ…jõàcîÁ»‰k…ì¬ãÓøÒœËâ¤-Æïÿâxü³/}œ®6ÃØ]¾²²´ò¯‡Ë>˜£ñçÇåB£ÿ3t31ü×7ÅólFÎ&{=iå«^ðˬŽ^$oþûþîn±…Ö¯ö±¼6ÀÄlGÅ‘/ypî3ب8wŽQÚ@ÁÅø2€`£Ëx9“[UÆÙ!Ã1
H+^X¸;sg…/ý~ÀÉ€™)øá»„äÍŽ‘NôÕW7f¶¶ØÌ
øÛ¢û›››»Âs÷ SŠÑ/+:–4ÇÓ—
ªÂQ	°uW¿÷gÿßwºu—‰Ö~F€»QteðÙàÜ{çÇøñÝïž;7üFQ}ƒâ\/Æ©?®.§€gÞ¹GgýíʸŀX8q÷uwÙÌÌÝ6Ç ‹ IDAT~ÀÒïþ´“¡Æ¿†ÙhÃMw3q*Ò°‘W䫲Ùð¿5³6³5sƒ,gsw·¿	››ñá>Í*¥ž{Æ= Í
KŽÅŒã^8âÀ7Uýö–~°ÿÿpâïë©§ÿ–ÿB_wü–œ§øÆ‚„ƒ?üSV<ùîwß{ïÜ@~mð¤8å‹‘¿^›'_¸ª¬yPÖßsî½pƒÌwæſź5ý±°bÆS‰Úÿ.âÿ.
€ß¥ø’³ÝqT(<†ï†fÈè?Ÿá³Lß-œ÷ApG‘bˆ™-2¶äÌÌ
üœþ7§w‘ÔëùôÏéëú%ñLî@gF=ïU16®@\­~~ÀáþÆÖ–¡ß³ûî=7›%ýð„~»G±—¯Ž:ÄŠDƒ÷þì»,ï­Ê5¾ûÞ§%`@ÌûU›úPŒý4åëzU¶7¨ºnmt1þ…ù{ó;÷æl¿¼C­ý·;´ÛmñÀùÒ¯—
àxÀˆøº–-H)þ…Ÿ{96ÍÐ}3fÈ€öÿ9va+»p‘3v"Äÿ/Ö,‹Ò`keè	_(ˆ¿Ät‡Á{çNž‹·òòû÷AqÝgj5³_d­V±_Òßî@Öâ$0À“Â(†@ó½`Ê嬂Ñy|Öþ1ëÄÂKKEšß{áüéóH÷ê/8OÞyž7˜¯'ç“õÓ
`þßGüŸ:õ§Šðë/Îò^8F™` 2CVÙ´¥ûí©¶å››¯§ ß¾•ÆÍüå—"Å¿èßÞÙ´OÍðÇ@ÿ2OýþWø…‘WLšãI„“+Ü'ƒAþõ[‹Ãøý{ó#ðw'}ØY#?ÿ+†þ¹÷Îmñã#Ü:—a	Àý™÷o(&³&+æ€>¬Á 6x2µÁ À1"tµBd¶¬oR×khqó-ë-Ûæ”¬¶sïÞü§OèÚá €'ï¤è´ž¢ÿŸ=%_æüÔ?}qꋳ½u͆ŒŒlRŸ©ª%Êene— Q0äÃD [Ö˜4iH¡ÓóEE}U±µý-dVë+€œq.ô¿
Љo6œ0Kà.>ù÷¹gÝ»[‡Ê(@	po!uNAäºÈFF(€*„Šÿ乓'ÃW{Y=Â'Ï}gþ;cú©ÝxùF‚Ôÿß7k™(?µÿÅP§w¡ðãìœ$¹][þ·Þ²‘†€gž¿ØŸWF€2ýù;ìþNrFY—©§Þ>Ù—ùåº|ê/¿8;½®Âä°Q¦¡{z$BÃÈDý[¦0L»½q9on®Ïë}øáP¼õ–Â?õ<†*#úE,ÙÑŸ/´-Z@-!\†Â“/h÷+¼ÆýæO4EÎ	hYe7®(¶üäÉ•'O2aîÝ»ÿüýݳ³°þ¾ïF¾û,âe@LÞM£þ¤<7rþ1|9î-*9àÿäüw«fnð™	þY¹R›|õå„‹ƒšË(¶¾E©‚
#
—*Á‡‹¤½œÜ[&3ßÂ’9€Æ°vÐHA¦!`úS`5˜|ŠÎºË—ÿÇ?]æÿôÏ|ú‹én<݃p6$ÄBú±˜•)C$úF_Ô3Ù0B³ïµ²K–N´#@Ï(£eþ
}ޤ×dHð·H¹½6Ñü¦p³o_·íÿkîò“ÿdƒÿÝ7þO7&;÷v²Ù®. _}#E(u£)@œ;9/.?Îì²syþ;óÆcqYÙ078Ÿ©¥ñÌ•²ÉË•$z‘øâh 8ý‹³+†E†áÇ-Õ² €Ø“
ßн…ç zþ`ö¿ð×ÓiÞï¼cï(€‰·@ý«Aÿ_þËïüË	ðï)`q©‘¯¡R‘Uâ²fƲÛsê8ýG*°ŽÊ
ÂÄPd äé “¡tˆv"ü‹fs-?ý#þKú¡n¬î'nw¼†èÿ¿C3†XØÙ™ŸßÉ®€ðI5ÿ[¨ðUŸâÔ3qù1Ÿ5.xä²ówkÆ0n33âFœDhV¸eò
7SüóE¼, ¸ŒqÕN7ŠR»[$	‚0û†1„K>€yÀÿs€bà™wÞèL|¯¿|LÀÿåþçõKÓëë¿©«òØa,£#ö“šå(o¾š)t"Sf¾¿p1~ãË2DÚÆœòíìyÿêƒýÈÊÁ£f¿¨ë¤‹Iuë_³ÕUR%Á™8H±™®à’óòƒOëÓ7šf}ifæw¸ŸV|aÝB‹ñ/3ògwû°´“ÈÏ¢_P<²‹µ±bqÖþ[ËÂ{cÃÁïä(À²xí¤l±jÒ:YÃж“ÖäÉ#NyµÆ+¥ì£WòMÆ]ø#·÷+ƒ¯ý8-;ómösúJåé]ŠÓõ.ry{eÓ÷ò…øö$˜ÍÌÌ|Wÿ÷ïèÇ)ãWLBÊÅ™ZŒßé¸ߨ䈠Íj*6R”¡URŒ¶Ô°v« ¯(àå?Re6¬“˜jX«T‘°'@j“È “µò]3W;4že€?Iþ22î~ïÆË5ör–Ú|%äE)ŒÂßÉ
ó†•:LÉK¯\ªJŒù¹Ô­ªì½º+Ëï=¸ù Õ+Nµ³ÃÄ6…>!€>yÂù¼ñÇÚq2/9ŽK
6^Ç?‹½Î(Æ×³½£`¯ãƬT2<à´¹b€+#[óþ£Ôvådô*•ºÑ¨³xll8[¾ú)1€eŸ´í-i×jªj¯ØÀä/&­xbãK@ãjWTo"íRÿ“ÿª^1
ÀL*üÝ š,8°ûÍdËDAder	ë¹P¡Ý‰¨¿Ûß\یӑ»k—º„|É奮b€‹õ¿»Y–å)H“=Þ¹´¶#Ä¿÷íá}öäÒU~é6qçhüÿÕ_åà[Èâ†e,¾þúe`bƒ	£÷U—åcãöqþ0e¦ˆ+ó!€­6™2À`¥Öæî“¼P:ÀcIT€ÏÜÖå§—ŸîïaÛ¶¥ÐzñÁ«(\üHï1Ìÿ/¢ò·Ñò·,9I$RथèÌub/}ã¶“A1€–*Íà
ÒôÚ¥Wt^Í%¬v÷?Þeµ”¾¿\«¡Ä@Óf, ôÍæLöN¬vûŽãîþ¬·¶©;ó]º$׺—šX¶«*_iÂ&Í›ß|`~Ó’*êEH®‘€¹Ëb}ç}òÖ“ÁàŸoï(¯À_ß÷ʶsë‚w~üãïf0/­÷£<ÌÏů·Ê\|ѪX¯s«8û‹A÷Ù2 Î&UÁ™¬'ràñT‚œ2ï&0ƒ“?¢ŒÀDM¾òÅ&ÑÚ`%‘e¦µ'èGë_c’|ÚÝ·¬ýý=ÎO0À/]<7{’¹ãèxï³9ÜM§·¹–)‘íºQos×ášz—º—^yå•K—ºd­“cð⃿a‘À`¹½þKÿoÝç—ÊfÙüçÿ—½·ýãºÒï­{«o©Ge†…î.¶¨®¨[ÓRÅŸDƒ<4Å‚EþZp1à즣ÅÀjôíù0RKãdMyõaàG€D쬂°À°ÆY'&Çžx€öì`2˜×/“ÿgϹ/U·š¤,;ɼlêŠluu½tU±žç>çÜ{ÎÑð?k/‹’ð?ùßà“ÿã²%ÀâižoOÙÊ¡8½\Ëå£_6¥¤¥Ú‹Õ2úÓÓ¡f€VkºE¢Öô´’ޫނ׸ô™Þýh	˜…·•Ê­4k“5 }£ñð
¹zÔúá€(Í4÷_Iç¿À:E…>ì{ƒbá	9(&''/5^„—”’hKšç6j•JUÖÛqPíçþYûµé_Ÿû½W¿Þ:ó{sRÓ4€ðåmÃaØÿ!œ6ÁÓoA‹Ìì
vS†ö‚v˜ÊT¢òð[üÕî6Š€íVîœs}~Å0#yÉSd€…þú[;ë7ÿàñ‘M]÷_ÿuç“KŸ]ʼ¬žhÙümÇf€ÿm!‹¥R`oOAx§Å|Ie3ص}»Ýn”„†$ú£h`	`LÚ÷<ïû—ôèt rëÌÛ·þ‘ªnEÔªædýÎІšPàwî‡ð“ãŸi8y
¢ÜY§ð_qêE§52€Ü¬€Æ¤#GtA]æd€ZNÇóôê…ÿëÊg?šö§ÞøýeÎvë÷^}õ›sʨ	oÏšp=š®³NX诇ª@œû^‚vÃé°×
†[Ê؃ÿ6“;ÿ8ìíIÔñîo!´êÜvÔO\1‡qùé†ý~}çÂðMÔ²ïöIމé‚à¤] „¢à^¯ø÷fóóóËŸ”³Ê¦(sB«ºVØ¢xžîaî­‹ZÀ托~í
!—3Xh„€³9t·žïz
#Øßè4Â~'Ì\€qÔš‹[ssúyÄÈC†0‡7ã@ß³ñ"Ø“º–þAú³—&õ<´hŠw£æºµ,ÅÐô•…+?úé´¿f@r‘t[_Õð¼uëÿüoó#¸$'c€7Ø[ëë×ê½sikìsþÁ^$áÞ »a»›{C`)ê¯ò9ÉE×¼ÏyÀ@wÍjÍï/L¿Ùé¸
ÿ¯âYYó¿ÿÙ%{¶@»8P<´àÅÉ
íqÆgóËó%þ˦O˜4W3	@A¿FaîŒPï¢úÕÛ§}âÄ¿}«q4³ä”ëOVóòÚëûÏëÙ„@©2"„Y¡#&
aÞ*ß+<åºä°ü‹#
PB€t©Y^Qó'k
_K®L_ù,ÌÑÁ4o9wÜrn}þö`2üoo/8šÞXgo„¹®ipŽÄÀú~å°ÀÞž<`w—ô†R¨‹˜k9[Ûc—ÃÉ7xþ°f}ôûát¸Õ—ÃÒ9ø+Žp>ûŒÒçûƒò#)SÇ`e¥œ
\¶Ü(©,îmž‰ˆ1uO˜vG¤]‹t¹\†ôü
7ð6ÎUECÀ(ÇFí”õëþ†ZF?Ì|€,O@bú0ÇÑ$P €â¢GÔ@ ˜t&‰o&± à GTUÔàß)m“¬\ÿìGdóG?}ɲ)Z7ôètÿltËyÛ纃 	 Âoayq§¥. …îm5PMYg@MN:ež>J;×éªLx«ÃÓ’‚æ„‚#Ž]#”cÙû<ö¤ŒB;8˜
"ˆ0+|×€Ä=åTkÂÑÓV®;?øK0Ó7¤†ysŒ½ª¿{~‡­¼-%|Üaìú[ðŠ£€)ÜŒ9ǘrÈH¢óÛw,…µ{=²glï­\áö‰‚€èëòÛ>ú}¼c®gâùÙ›køÁ;ïdµ×«÷ûŒÅÂ'GÊ¡–í·ÿX$hï
ÏÇp(“S)üøá§¥Câh¿|öÙgš0ýÄ-ødáí[Xo›žriÍ ì”
øwÖéotÌ"’	•GÔËx*m‡)=Œ•I"H¶jÍÎZÒÆ÷“X‰¨:€äCŠSæz*nµv
“jÔ0AïÊõ{ÉØææOªC•uN}ÿôûø“6€^}ì
ªN´¿ÚEÚDøYšÒ½¡¹úöz’òjÊÛ¯š¬“®YÒ¿O?¢ÿž¾¿€øàO(OSòù^ÞÝÿe+ô¯Å¥Bql¶ŒìY|{AbómööÛÐ>üƒÏj5–÷9'‡×3ÍAÅժƷÈ7¶v@>`¦@¹òwOr3V’‰®-®øSôTí”<¡S
š{)¼þèÁ%IÔÉÑ9ÕßÂÀ?‚ämxãd'¦£ªrH*€¼CeùåÈdTáŸj‚‰a6pŽÄç×úp4_­ŽndÿuüµKü—í×GEÑù%Sì¿¥<'ähŒ{ñèÜö‚+28JXUZµùcL³#æ´ãhÊR¹’Ð)ÊÛ¬fG÷ÇööTc6–AäèÍ9&ãÐÑôk4ãKì—m¬¹çä«k;’ÿc3„4Åånwlo|VÀÉÇÜpœÁ®K	(ªð}"Nš	ï{Çó|§âÕ5]Þ¯pßÿµÞ=Lÿï5¿pî²,âlÉeËÚŒœÞBÎeÏ#ç&Šý7!ÔëþÓ§	y5O£6ëVÚ±4J7’Ô~ž=Ûe¤äÞñÐ<Ëù€ß½ÁoÜàwÄÍŸÁø»ï½wS!#ºühúžË¡¿§<×så¤ÿªïzžwêY0XëO˜4_T·XLéHçcùª°ÿóµ±íù8îíyHñÔZÉeSíÂ?šÁñ­sÙã~÷;þo„Ìs'៑ÖìÉûøFØl†ylM7
6¢<—ûžð Îô
èu&<ó}gÅÝA> 7îÂ%ÝôoÞ¾ÿ®ÿî{7%þc ˜ë)1XN¥ây5Þ.ÿU·RñýÊIê\óSv_?¶h‚ùŽ?ÞÀµw8AAXbÍ%G¶ßQ©²é€|ÇbLG8˜×Ê'¿læŠÒ8ê¦jž«jßýãï|Ç}ŽDô+~éS$‚}fáŸ$IÖÿ7‚°Þ0…uºÁ€4ΠïùÐI›ÉîL À¢“M§¹hŠw?†Ÿ»w±læO|oá¦ïºüî{`ÄqšÆI‚µãóy®€r”H«>
@>ʛڂÄõ€” ø¦ër1+„„¦°:J³v:ȧ8X¶ÿ1ë‰_WÍöu="·gÖŸ‚oïàЈ™ÌÕ²ô„?2ƒíK# lFºqEݬ—m÷ôwþâ’LZ‰ðWþ6Õé?¶?J“ K²
ôþõ Ùlë?Úˆ’Ü	¨X¨Œ¨JT8hH Q…{ö»üw5@êXGðîàîÇ î~|6ú‰Ã._9õÞ»W˜ó\`ÅI%««)hè”ýSžƒ¹ø}—»ë
`@xë´"pÂFΕ
Š p«(‰ØÀ׌žšÊG›c4€ì Õcñ
=7c#æUÄñøo¹$µÂ½êÈedĨíÂévwvøÎya(—3|?k³iIeC€ý,ΉÌh§¿sû©{Œ`ÓÏ!ÆvŲ¹O?ûL2À¾eÿ,âGTé°f“Ôë
<€
’v™>€9îe·KÕ`>JÈW‡‚‚÷$ d^A>8{Hàîà,šËïÁWÞƒ£Ü|—K´˜ø6‚£ûÖÝå^Å‘u5¿âŠJ Â…™Û5ò+¢ø>,ø,G„È VØS5UGY´Ÿ‡„7J£Så¹ 88°îçlÀl·fa}ä2zþ|ê{ÐsG™å߆à¼Õ2®KqYïŽ^xÏ&Q)ÊF”§çjçn_i·o·OÇ=ÖSm•¸Òï)á¿“nÀ¡ºCMáô‹/N‡6	<`Ÿe5¶UÑÞ¬r€©"Puª«˜¢®ìtÚþX
PŠ_D‹GL¡*Ÿ%2DB%Óg9 Ÿ;g¥
`Ï®\`„ÿä]¢PO4þÑ
ò}¯ÂÐP‘ê½R­€ÝîŠ*0
ç:šC£<=Z¤‚?euÀƒ5À@ž/
¸A	·u€7Üä;ˆ‰	û6ƒ9Ã*"+åu~O®?o@ÈM…§E€[¥„ãÓÁÈ8yrþ¼²_›À E8b0ŒÒÙx-MG¥#°lz`ýÔ4¼"9 0#ŪW°8­P
ø7k$PhÑÆNº“BÛla>0„_ØQɺ?xœyôWY
Ú?Ш Bˆ’—+§ÈM|‘Ué*Hð¨§\ݯ§\
Uw§j®‡Élº20*M£Vdy¦¼\F	Ö[LU3>BA0ྣ¸~Ãq¹xòΟ¯ÚFc.ˆœŒ äú#ÀöI©'ôP©pÁâÌåÔÔKæÎÜéfœ8O)ÛÛç¥Cr0ºN£Ù”²xT:Ë&&€wÎÊtùŠ]ûG˜ÿŒÓ-Œ¦§Ãpº…¹2`„ôvªÝn:ÜîlÆñú»ð?ŠäàþãÑ~úN.,	ÐQtÒ(€ˆI@¥ºðˆƒ)íjOŸÀäa²’¨RÍ®çHü+èþôÿwyS±ýÄ—üÄ#¾¸ùîM¢|€þÕ$‰»`–K âpèE³]v¥V«
áiß}#% "°²;äû¾›Yƒ‡ÂMe5•F¢†tº:ƒluzP­ìYÀè«-àa­7øGÏ¡p]
ÿ5tiGÏ
‡Šn«›îléðíó]ʶ•€ÅŒ½u~³ËâÁh¶|ö˦Œ€(ŽrÇv{¢Ðç‹ ÝÊBóuNâ<Ì
iþ¥ð%êy=!(ô†Ä­±-¦F­Ž?{ ’@¯üÑJïZ™¸±§w³`Yª]YÚ;£hô¼ ÞäŽ8{÷.ª€71 €@…Œ~ÑP|$ÙËž’n6à0xÝl§tâ+1_)ØìÜ–ªtÀ(¯ @UÇoæ.¡0É+£g—ed IDATœ?p(ÝÞ»gÎõ*®í8 žµË|2O²¦—s«^wB1€Ã»­V7›ÇÁywgg[Q(@„cž	\öÚZ)Ê6ÞÚÚ
PÐË+ð2ÌÔÅwzú-`˜,<ÝÙÔº+á±n7zzÂÕCO˜"ÊkWG`MÝ¡¦Ý!“¯9þ±ëçh ŒŒ­šbÀÏ~Ülx5Žð›hØß|7—?•©¡éJ`_Î6fô”pÜ*Ñ•Sž†ð|…Í_±²êú™›%"Ñ`ºf0Š2ü0Zb@
âF–“?=¸—[л{Âf€±õ$JGÒ¯Ô@á?%
}~€ÿn«Õµý²]CpW¯Gé[o¥QT@Ù´ËÉ
9RagÙBÅ´€Å0T»á‰a/Ý®ZKÁn‡eØ6œ–±qáðH8ËÓ<"féê¡ñÊuÁ°‹·A70»ˆL&t4Ó]F­(,ÿMPÿsÑ<;ÀÉ€ØÐ€, ´TvÆr¤ç8ÈuŒV|#ò¡ß÷h­"	 jð?Oé¼ÈKø¶°[måj
±ëQx%	4þ¡eÀß{{ߺ2À	ëY”àíJ"8;¼£QUN	G3q«Ûhe·{§‹óvärÀ`tý­·£x¶$€²‘,þ^#_…çËK‹ñtVô®½Uñ±&º–æá»y$p¶<¶½´‘óC²z(w¦ŠäG”FAD˜ÔsÑʧr¢.n˜ÍÄ	4Ðs»nEž3*eìÿwï:õ³ü㻎çÓ6Tƒ²ëG(áX#ž¨œbȤà÷O;Uõ¡yÕSꚣy<Ù°aò™D
d¹FFf£¼:px¯ßtÂÁ@ÞÅÁ(K@òØB\ëzLT2Ƶ×^œ$ú†zUªt4Ðw8Ii·ëÍq¹Û•¾ôŽ×é[À@¥ lY,*+pÂÉÁ§ã¡«¦üüIá±ã;·7‹Ùã]Çœþð€‡’°ïGÈ7Üû®€Â=‚ø÷4¡p‰Ü
ZÈ’Ç	Àwïò³g¹ÿ#4rÓÿ¬¾ì¾ËT2Hâ	úY@4˜ó\cÌP«žªÉ„Eåd¼3+Ÿ‡¡¼0dß#<à@zù™Ä¿¼¡µ~¤GX!8ù£R©À5Ázqtý‘ì
êpŠ€YÔÙ$ÖßO/S“¯€fç7*@ÙNù—!/Ï7ÏXOdžP•‰,ßßõ\‘³–B$Ë e2I×j€»Rú8Ž˜Œ-€@Eµbšç:媑ü&¬†.·Zí‹o;6¿
9!
ô—*Dˆ±Œ!'ÿq¬ŒŠvN’“ïxžâdm¶$€²iÇ{æÿ“ïÿk)C–½üÆïж•™z½>ÿNÜâ7™àK;.ü²)äy}kéP£_9Ìï?ˆT–+ö²ÒŸ‘íßøFýxî¯^•û¤žÛ{౬ޝ/ý²áýÝÎÊÛÊ×Aõ¿Œ`¦¼¨ó›Ìsû¼€¯T¼ð²úöçŸþí[£Ïò×¾õé§þuk«^û»ûo?X~-°Í€0zñ$àŽ#êÎJCfŽw§º¯[G2þÎÛçË›¥Q·pòBÚ“ãyIŽcT¢Â+Â)ñ_6©øƒ.	CÖ&²Àu°Øè!Æë8_õ0þܫڳ_«µâãÃÇRX5§Žt{E |:¶þ…âz6ÊCi\¿ZÒ½fZ%h¸äráÕ˜f€ Õ
§_×ëþ§ÐþúÏÿÅ{½ÅÅÛ¯,ž~¥-ñÜðøþòòkËÿaã!_üº	þ‰ÂÆË—_þz8ËXÄ?OgW8÷ª`r¸¿¿/gKëûƒÓðм׳|+2”ªÀQ2è@MStµ8Hÿ³Rhןcx0±Ó¢V‹ÍhÆCÐÿÿœÒø[/ ãoïÀƒÄÐ
2wq0!Rö?`•û^J½Â³Ò¨ºN!Gæ˜=Y¯;MbsNk³(båêCB>½jèäߟ(±Œ.›ap95¶ØïKè³"þ=°ä<˜HCýá´›Àx]ìÇŸF·n¡	 æç­u®¯\ýÀ_ÿù§È½½6¤€ÅEìöï?¾ÿƒüÛ}`€×pû´ÝFˆ€bBÕ=‡Q6°½†}†ÿJÄOTá-ÜCÉûÐÇóL ãL?P®Îi&)óó—Y`[
âãÙYŨö“ÿÓqÔ³³˜ýD€f æ @m
'thÿsL(x	ÿ²¡`g§Àîl¡Ý Ÿ•CóÈ`iH=’8VÆ@‘šõ³ÍŒÜ
‡gÝÍw¸ºpu-oº2b3=¸¬îàÔxd€jÎÐÿ›ixÄ?X5œ Œ@ÿÿ¢T_GøñG`ò.9`„ðÑèÛ@š€1ÖÿßB@H÷Ú’Ú='€îÿ÷ðÿàþk¯=^F‰¤xø"dü_á?D;@*€étV  |‡€Yÿ<ƒ V3‚T«&²‘—Y’D€kšÙ	*dšj¼“4ñ?ûÍĘÿ8éÞ䂹^áïa×]wüÿeSøo1²Ó6äX ¨Hõ\º/¾j+ѸàWýâ¹S´ÂfÓ2ÂEÅusÁpõjgíêÙ•ºÿ‚OáÁhð€T
GHÉà÷ÕäÿuÉJÿl.Q‡PMÈñ0Ð¥
p4ÀôG£nI{áæ~.Èà£À>F£ð¿²Öÿô[ýo}
øï“´×ØC¸½Øcàÿ>àÿß~ðƒûËÃ…iÚFÌOG˜…Ñ8Füøã˜2Ç™uPÿÑ‹Óè”WÈU°3âÈuë33’„ 7 ËþáâlÅü¯@ÔRF4tHn±&ûy¢8$ÊHž3˜cCøÍU~(Û)hìÃÛÙÊA¶¢¸Ÿ
€_©VmhÖjcøw
]N½6@ÅÊÖ³••™O¿q•çø5‹PüÍÈy0Ð]<
и€~‘ÌVÖûÒ
x¨ú6ÄÿŒBHÁƒàß
•`zgÂ4ú°÷AŒôüí~ŒVÀç71@J@ÿ[ø"cz{’ÚÀœÀïÿÛîßGø4Ñ)˜Fm¤Ì‰Æh6ýÐ3Ï:«×1y ŸÑ¥ÍTåeå‘V|§º¾ëäø§VôÙ¸0Άf‘f­Ää`OØ&?“áÛ`•RCàsLx舸œX6ts
[ÃáöN6ÒMÉèP3øw«€¯<Þ¾Ùpœâ´x^TøC³ n¯]e+WY>Í›ðü‰Û/˜Cþû|¤*gá:\Ïd$þX_G
x¨MZÇ Jpd
Â0 €ÐÄ:~4úÑÁ?2ÀU€Ã¸zý[ý>@Dj
\¦GÚrÐ?¸ÿX!V·Û|ƒvû3'Â΃™c¬¹K)˜žï*C»®û_tNÀ¯)£†²:¯s^ÇxEš™yüp	›ýfN6g7ûÍÃØçÛS€]ÏšÈá³å€ìøñô
ʧ¿l>>[;;ZPBsøø©øÕ
k”&*Émžë†ßïƒ ú\}ÂûP˜•aÝáõf÷³¬A2Èb¾¶2ÀÔ4ŽlúÞ/@'/äbŸ÷ûxPw—e¿œ£á,D"ö!.àZ	ÿ¼¸®ŠÎ#n{§	%?ÆçÒ€Û÷û,³“åþ8@¯¹‘pïÇ ?È‚w£Ð®uŒL ËmC?ïÈÎ]p—sÏ­‹úLf‚ãöTjy‚ÜLbr肎ÇÙ¥€Áʘµ7ˆg‘rEÏ
G~h+þgý½¹L,¸(ñ_6©º]À7i·5þÕ0À¡4@âª`R–˜§(8¼˜
) ÏMX¬Ãú°Ùׇ*.×p€…á2¦lM?ƒ¼þySX%'8îÖ}¶La‚,à8„
Æ“@Ç<;F`Gƒ™õ…&Â,XZL— ¿[™Ùè îá•§}ÆòÁ1%ôÑyá‹{1þ—EãpN˜5^ÐYéb(Lx&ú•åω(GË&ñŸ&I·ÝNb2¡¦®Ø?TÒq씈շ
b‹Å'¹&'toLÓÉ	›#ËŸ!FŸ1×Þf	öŒ
wüðG—ÙÉáøc”оǙÀ€Q?r`v$Ñ;®þù‰'$ç<ò±Ì"!úeÃ~>®Çñ¬¼s-9‘#ƒ8{¬§ß¿†v=Qù‚z@Õ¨!¼Ì‹ù+óbY,Ä<ÐCzçNt‡&ÁfÀPVœ¿ƒ••í¯c«„nà¸81ÆzcœÂÖÂÄâ894›—5ð/„	ê›-^^[+2@áør
}ý¤^UFW>üeCÉ;È<ŽÿœD³ýðÚŠQ°:Òõ¥c(@	4âb¬J–ùüà3qE,_y´Œ{IÚí»ˆÿ£'Œ@÷øgŽTúU²±ú÷™?Ka,ÎzN¿ÆéY§9
ÐëµõÒ­[p¬æ…?Ó 絈õø²A4lC+=@Ì %ü|Æ`"œ±è‚vI,¢ˆ›î²ì¥33Ý00ø‡UÖjRõp󴧖݈úb1ÚßÇ:¦úõù,
c•ÉÀ3‹­mGôÒÖvêêÙ|L¸z~™–#D¬\mm¯Õ²Ù~b4jm/¸-ý·çzÞÔÙÒµS„ûûº.G±P·"²{ç^¿X>ûeÃ.Zûð[gú ó.f£ÙV,ç£Oú×øü¿_g3†8ðωßy´0XöµÉÏHÑ/†Ãa÷ÃèNüqæ?6þ'Àr|õÉF’A!SÙ™?1Óþõm˜À­‘n­¬¨½š—V7ÌõTdœ—„›"Jè™ïÄþ_ºè%	(@XØ<ŠSG¤¾ÈŒ€Þ^Zï.e†t7ryê{‘éâEêôÿrs¹(ül–?RLýÖƒtÞ3" ‰¥+®žvÕju[n¯›ö2|×EÒI£HQÕÑí^%^vB]÷ÁhaTíjWæ†KÞÖP«ºë85¿ãª™>Xé`nnHæ.^œ–ÙÀp$ÌÆ×féœ@7ªKÏ >PõOAý;}‡Ëâ; ˆü Ð0ßGüO¾öè5÷3±ŒC
›ÝáÎpØ;HÓM°ñQý£ý?@ w&ÉæîÙ§ûyµÌzÞýg?~hK51ÜÊFšƒÂ¥DfV0ŒŸ7f€´ÿ~NêækAm»Õj>U™¦àeÕûØ^/
Â¥0Ã?öLí³ª—bñžžÚ\Dh×`¶cßP‘ðæoyÍs““”òJ%˜ÔfP·›7í¹ßl¦Ãâ4NHuRW;-d	 }-á.Œ2²ÕudÝÆÑò.ãQ‹«?ŸëâÑÔ
èî¼<±3¤½’Ê&R@?ž®aŽÈȉbçZÌшÕq¿ÿi½.£Ô¡ÿç4V=Øü²˜Ÿüdò/-/,Ï϶ 8¸s›œ©€?A	?8·wc#ÙLVéþçï
ÔA2ü3gÍ8g210½øWÈ_¸uK™çš·,SÆGè›üþk®,¸²±»Ãnï ¥)zù¥P½V¤è_M67þ~?á™v2ŠN€~Œ®­Á3;óÿ‹‹ŒöÔLe&#ûÏ5›ÆðEÀ4þ¯Ï4v®¯w:
ÿIÓ(a–# 53ÓŠ2~ˆ0>_°é(KyÄáAòܽt)ÌÜ~”!ÀÆÓÖ3<Ë?Lôi8H:í<`tÍÜ—;¸Z–%Ó>µ?íqU›W‡þ©oáŸ{Ö„·"+›Nªr‚iš
޽¬…Ÿu˜ëpî¸æøWW®ÂúÖ¶P	”<²ð@m?ÒäõºÂíõÌÙwˆÜŽ¢8AÍèIÉEèþé|	€ßzÀ‘ÃñìµÙ:Rš+ @@ @†Ã‚ºTL"Jø|eyòÀÿ£exž‚Í(HïôºÿØ=è¦r¶ÿh ‡ô	ýp>xB¨cͬ‰ËŒˆ•V@gíc%ÿ4XTâaaetKOèsufýÂ?#ÿF¯w4Þeá¿\$G©ò*ÅïB\EÿéÁSNÓ(g€ V„p¹Zíºù°zÊIŒ›SÏ	ÁŒºÑ'g1É]¹(§ò$i’p~2	䊺b¼"W×V¸·N¡.`=ÿ;¶?ëûh؆=Æv.¢¦* d€¨Þ~ìþQH-_‹Ùµö—sûÜé3•?âÃ4þó8hž /bÑîn÷Ãñ¿âü	pG/ÖÞ–¢•¬®‚Ðy¼©îˆ¹J?Æ?:ûªv5Ã)dbqqIÇ(ç2À-œ¬¬bbÛ×ehîÃ7×Þ„îíMõØúá×ÉŠmÖgÔ«P#À~n °Áœ»Ž-hÆPÞ>xÁdËÝH	{ƬQóŠá‹®É€åºNa4Ù‹ðŸ§>@ïK’îv–4Œ3Þ¬aƆ¢|€ˆÿуn^»Û”€³X·'¯s*Œí‹Ù’lspóæ.‚íS@Ù¢k³2@ÇÄ<â8( P£€ôx3ÝH”2ЇLï£æ	³Øù0žÄ›ñ8x,€3‚ÀºVE|VÙÝ×aAn“o]€Ò°¦†Ñ(^\œ8mààjJ¸u+	â<Ÿ2ËÖ×`›7Q<PŒâ7…3&¾
P˜P+0• ^O#,G,ÿÓÊz²®ü_Gãjª·RË1FPÆªŠ±¼š¥àÃï¹ÖÁã9²¦´Ñ˜”‹“†ë[­–LaÒjm«©ÒÈLæüä¤BÜ€tå0€
Ölu³ía‹^ñ…Ùû×Õþ…£©ëß™ƒCÌÍÍQ+S`Ù~[}Ú
àètÀˆqJ
	2F°~ši±ã`@Àôç*^@/ʼüyXY­o…à@?‘ó¸Ìàã`ô1#ú‰5@ûøèÚÍãÝéôÒâ¢ÿ.Vþ*qøXc××(0Àõ7ß\SY‚ÃA†y¼³US>—{©•Aˆ+%‚ÓËL½·Ê‰SSn[ ó…@Wãfìèb–±ˆf'%	šŽ&–ÑÍÖËÓé¶ìía¹Kóìf*÷;šÜ}nn‡þ
јeûÿSI˜ão_²ÆÊ®¿ïHü³ÝšæëÆvLMq†ë58‘VˆÒ뺌/˱aCøÕíeÂ;¤€['§	akˆª‡kÚ†`c)vЇ”È.|ÀÆO¢¸½Î<Æ
g{ÌþÄZ[=–a„ñ/`Çì`­ï¶¬”dŒÒcn
|ÑÚvJì—íûÏœ0"‰Æ<¿î/ÅÊZ_-H¸˜`ìÑ3öë1ÔôÖ_¶ª¨#eÚ²}¥‡×=9¿„POðpö†î3ŸM:nlÒôèFÖ„ü‹ò‘‡ð|ÿÞX5cr¸v|@¦µ¢/ðŒDŽMQµz äøã'ɸÎÓBæ”øé3NÁLbʯW}Uv÷ž}þ‡iÒÁ"ÇÊV¶ço­hô¬š_täYmùGxöz6[ÙátPd€4	íMTìNÃþ ÈKA’óEpݱ„ûû!Ö4PvyKgã?l8Žhd_™6ŠÛGrÿƒðøã'Q8®"žÒÐÎà†8QèDètÂâõ¤òe~…ô`ìz¢âæô#½Þç\¼D¿x<³¹WÖ.›~¤î]ƒèç®IRјV''Ò|ÇÒ£gl/]o
ûƒF#Žö1æ.é0´„q2îZÊ6SŸqž€°Õae:r;@Nƒjé^sC»¸qCf)b{'„9_O%æ27äÑ"3ù‡-“°ñ¤øý¶Ù ¾Ÿ†ö
+˜ÑQ6ÙI¯wÁx	¾Ëo4l	 Î¯æ•Ï}Ùþ­€ù¨?aYÞøF#êrì	g2Ÿ\JX£·S<ì Š¶í‚(`I›$öê'´MîÐ~`]O´EncDŒ‡ÌÏ8üá~û©eu+U³/H†{ϸׯ‡×;Y'[%jXͳq„»¸¿uy|³y´›´ÑEA-üÓyy>JèPæ‡''6B}ƒ—?<Ã'cß/oƒÚ Äï§y¯O£0ÞŒˆN7Ä(‹”OPW¢‰±TRê IDAT”c5\ß•ç—1†2xL”ÝÙrÄØ3fÊG5‹ÚïO6Ú9¬À®œ¶IÛë…ÃÛ¿½UÞzOF¶â¥°>µjÝâH.·Zhû"×^dHêöe3--(ö–䣓ˆFǶ…ãLÚi-wzC+O##;'Ï¿bÄ‹cmÀÛè€yÜ0
Ú€ü»ƒ,…N‚³:ž×
 ,'óFç©\}ÞÀ¡,j…çV=°“ñ,=H±€a©¢×s—¥×­“áÎö«ÛðÆ€p—ÈýóÆ«:º¸i#"òl"ÛBÙljAûOý¤!²¹ÆËðeäŒ&«[„JÛÖáâd7nåQ°á\„eÊŒk¡¶¨¹.ÆÃõgÌ:NÉeË8èB‚¢ÍŽv@šž]ï4ò>qR²Ž“÷ñé°·cgºŒ¢SºDgâ´Í94‰¨¡X¦y1¼@ÍÉ Ï+™&&q—ë`>Á3‰FÐ'¦rJ¿ÂÓþ!€ý>Upî2<Ø#IàßÉN—õë¯;Yáë¹¾ÇX:^%Ö œÚßæ¿ìøpŽQ26ƹ¯ÆA3€/À{l¶bâ^ùëׯ[»S¢¾_o=‹•Ió)pÙª:8´„ZuÁëÏG1éK
F@­|òË&!3tÛ lò8CÄuPý±v,ïÒÓ^Úë‘Â#[ù ÈD¶ÚuC
¯µ9L—å8s>JÝš›#‚¢‘û+„-Wdãê¡t"¤Ù<‚ÃýC`€}ëpàŠå±X"é=ûjúkõ™ºE‡ëë´³nø^•Èä\nî4-ìO¬ãGælòötS ã
o_túö&Od9öÜx}}=·AuÌ÷ŒlX}J$úvÁê$j1[¡Àùù¹Ëè6NLv*Ûo±Ð)ÓWâ´’+€IÒïô'ƒ\Ä2¨-†=Ò³kÍ™öˆˆ&-òóŠ0ÄEN¿wÂC1<¢Ð•ûçøOý^Þ	Cd‹ûDI€Ã¼¯ŠŠõ°³=ðžuzõ¸S+oÿzŸ\Ï,ñ®@’EûÁþ={R8¾:›‚Àª Ž1:ëâG}k¦Ï‡O
€tt‡îäß/@í®nÐ(2¦:ø01Õ˜á@¹–«ŽIbÅ®%”
Ÿ™ d¡=;Wwݼr$tÿd2È<@žO“Aù$ÐËù±ÄVXô´Ešýz¢¬!-_‹0ò¹D2q?ì.Y}49æE}Øù$IÃlš&rhNÐ÷ª¿bÙ€ÿƒ=k²>C°	 Cèºå”9õݱý-#Ÿª©³)Ü`)n0žÖ:9ºnMõ{²üäÉáa¸¬@n@ôp¯œÂ÷Ó8ŠW“$dB® FsEæMh|ƒÇ^?œNUl9£•í·ÿ4ʸ<º„W8¥Üe™H•#,ÃgÜ€Þ?ž0Ë&½lÚ³ÊXÃÒ rûvÁBH™#
…Ô¨Z–Í&ÄÙf–ÎcaçMÆ`uLX>Ín_öþûDK^õ=lÂ{ÙåÓ:üÄqv¾ëëë„e"œÉΗU«E‘3³g#Ï8×ßû*4PÇã¤ò¸l=w2°'.øä0úðÉ“ã6û~À²
øßh„YÚa’ÙÍ$Ùz>~~1n–NÀ²„Ížpç8P¥çêa0Y$CÊt|Wwr¤#ï¸ØMü=%§áEûuð/;Tú©qÌšÉ!A&ñÛ§	¼hOš\ŽðKC­pk†ç€áJðu	®Щéxxjl`&
†T·ZÕz—¥ÐööÒ4Ç¥XïÀòûÖÕzI^Ë÷ïí¥úþxU/;¾:<)’HUø×,Ëøa<š‰ß}°¼ü$åÄzý}G¾?ÞŒ6J7’8ÚÀcljŠ.Nb}@ô–à°.¨(¦
&×÷ýüüTld•ñÀeÓ|ÚÏ$¡ËTB	üŸ°(ÃgÉå¼»Vñì4ŠÔÑ
\j4þ£‰	|"'&,ü“4óȯ Ô„éóœ$T¾fßi¨i$—"%
‰	µßGG ‰ß—|‚Û«œa(t‚aËs௎¯¿€ÝèÃÊÌþ½”eç—"@+”‹NžÍ.œŽ&À(QIG	Ö&‰ÕµP€;5ñüO૞˜ó5PEG¿?ÝÜÄÕ°Ó“é‹d>¹/	5çÏÌõˆÂùá	–P¶c	¡ø`°±ˆ|PãèN¬°=;i{µL-¯?>µt,ÀýÈ÷!KÄô'vÌ»f˜ý}6¶ûøá؉|XXÏL€×ò'²„ųÑ©2€¤R+e™¼/Óóâ'$wÁ‰ÂçgøGbîý“îBÇuŒ xö=l·ÍA›Ïÿ×Ênï\r ñN0´kÊg»lÒ	ÇItg±è÷ªÉpWœDªù3•CÌÕsHòˆ¼ù|äWf P.†“#àÕ4$¶äˆƒ
lö>Ê2»µ¬OþèQ@ŠØq¿BÞ=ºÎ4½à\]৪Ø×§¤]pr	¹ºªßèÓ_üÙ¸OºØÀ?ôÛd3µ:ʰÂìËõ
¹Á&nÙÈü¨Ç„3SûO”¯çÎ¥ùþt·†Ùÿ ä€²‘ú.'ÁÖÎïÎÖIäëèroÍÊ^2Ëq›u÷¤°Î>¡öTb÷H€ºÅGàjo4-¸!á£æhÉùó¢ju¹¤··„ç“.½TAì“`ùâÒÅeè<‘haƒPnzaܶJÂÆqp1 ·æS€xb’ÁÉ—‰,âÔ0šÞFÇÜ|Õ“Õ{¡âºsÁÈö,	âz(üݼÜà’=&"Úi~~ÁåÐ:_ÏEJàêê¢A#ié=X$aF9©±‚š™ó0ûY¸3tÿóó\!¼n]Ü
T߯¾oT@ÙÈQ—´>|q'ºi–	;
£k™UP‘Ø•áìæ!¦:à=ïtŸZˆ§ðYtÎæ0í) TÙz› FÓÿn5ö7ƒß2~ÿ`ïw1Ø,¸ôˆºòò#)[°ÃdÄÄ'ã4˜hi,Þ,_þ~¡ä
×[£ráËLî;ÀªÄpE8ì
™Çð/Ȥ꽱ú‡KÀåvx2	}Â"×ͯR’+¤Ò`3ÏG,¸þ~n–`
r"²©™`Áö)K3ød:‘h)›L¼?:Œ–2“&ªU|‰ý?¥Fµ¦·ºm¥ý÷þɈ]*ÿ²²ÛmG¹Õë~Èu5`œz{m=ÕJžâS_g å‹8f“ps âÝÍã¿{~¹³«ótu3ZÝH¥@z{8Þ”5
:;J]UÛÓy´¿ù‚ÞÁp±½··' s*/û•G”?ò_^ö¢ä²,É«è(I“4jÒíPÑ¢c]榇[årRR‚÷ÝCâŒF¥(¦oÿâa8Ž®ø½™Î®~631“Ζ¤@÷"+1g¸O³èS‚ÃP«»«IBwqù`7aIºJâ^¦¾ASOyVzõ˜3mñŸ—ÑþÐIkMŸöö™}€?zÛ….¬m&Ã3©˜åWH’ƒœÔÇNžSÓå`Ò3UÃù«˜Mà§ìðô)×ÖCo8”aùòÛww“d÷Îî;»¦Fð§&³\¾F9ø¿Ê.]úåeǹú)@°´‘ D³H=añy }šJIÐ1—iËJ ”/.ïäfÖF‚ëuâV¼ü;$™:úAþxtéJ)Êq'hµYZ7œõk×t	<ÍVàópîa~fO?ÝŸ²æ÷²Sf`¥AÝ…Ÿ§ÔIòZžé^šîâï‰d€ÀRòDzû iÑ
 yÒ“Ð(³Kƒ²‚Oò§hrp¯î×´a$X8»»’ß&Ý)Ç¡Ì
‚<လq_'\Â?]º¼ÝÿeøýåÒ§ò<7Ë?Âß:8ìd@eA…|ò2±³"Ãl
‡ù¥À€émp%fZð’bK\è¦äÿü%YxŸ0—e+WJ	P⿾;­Ív	ó!X˜w³ÇŽda2	bõ„îGOÙ¼å Vh ÂmÕN:І±Ã˜:Ð/ÕBx>‰iYòêvÿëVŽŒ‰çÇE†¶òí1鈈)
Èw0A”aÊ-F/Ê?°’ð’^çḈ®Õä,¹4)@ê‚c(
ž«†J®.,\"—.9—.-\i£{êÔ"´Ë~Á]]ÊõŠd;\·83þ>†‘éþ?ðœ]’¯Ç!ÀÿΜÓæ/i°¯Œ…é’ʘxu»a˜"a
0ÐÏÄ™ª'qnDܳow3=ص¾#I6vó9@)¡‚[s‚(êÁ7“aÃP¼øi1þŒeÀ—_ɧ0–cGm¥y†L´.01ã	joLÜŠ[õò
ÅmûV¯Ûë¹Äµ3ôÕÕìò\á3¡
ë{ÊUŽ·ô?ÂðÒk!ŸÉ”ŒåÙ|?°oˆÈo¡½=º93©Hèa$wƒšõÁ|ê¿›bMçya¸ä컇ŒŒ.…¥°l±Ã£î‡Ý­_NæL7%´2ÈÄLfÐhsÝ4âYïTEüú4W›è¨ÊÇ’Õ]{à&tƒŽwºŽv!ÊbÑy[ìÙñû€èá½—ý¶hó¡ ‘›˜c,2‡VªÚ±GlüWAMxã•?>°TzˆUì™èÈð:é øÑ½¦f
Éá
°oÔ  ×ýð/´ËU%‰%à݃Ç÷ p;Ð¥©Ó"âöi¯/2Ñ¿˜üD2ÕÓ«@b.¿Ó™Çá ˜w.©HP‡8èR©ÊFâzËîî^$ÐúO0¥Ålî€~9Ã3	Kì&§&ö?¦6“ÕÕU²ºqÇì±±±V³…ÐÍ
ÇYݰìÿÜY™¼ K¹ ?8(Äï“gÝø/¿\1øg¶3=l	æ¼Q} •I`Ú@¬¹vÕŠP)2ÀþS‹Q:›g.åÔ‡ÂáA‚N@ôJúž’I 2'ÇÂü¥Ë¿d9¶á–¤E	ðøþã¢BÝ×ܼ K$yE¼ùŠ´pøO"½¾ãÌãuïáÌ¥`~øc£KNùüÿ¶7îÄàû³nwˆõÀ>¡ƒÁ¤6Ù8@–eŽQk–—êÓ§ÆdÞ½Ov3•œàò¦el¬:l•Ó1ó¸‡2›s«Ù°B1~?@ý_ñ€<íÈeþ7åøxjj--|žÀu<[µÿÁÓr'†¬ÊcЯ&»¿¸ó‹ìz©0ä\—+ü«K‰´‚_¸4yáò‚Ý¿'yÀ,>	`M?ÒÀ¤ é%™>ÃëË;¶o\ LÏH3ÀCu7@\šïpãRÜG	pÉ)M€²ñèNõºQ:ìÊjÀlž MxÁº÷2¼,Þ’P±kœc|w¹®‹«ìì©
LJÇwU¥—}Sš—&›¦ƒ­äñ²p\9
Pî!3ƒ¹B«	×Õálp>Yü¾Â?Z¾ ®ãÛ´X2ñÉKK‘ÿŽZIsºÈ¿Ÿ-é­£¥ÈðƒøàƒL0ŽÇ7ùŒ®êQ@}=XA‰R.OØUû¸wÐ$¹°péÒ¥_^ú¥¥SK/?Øüà¾ù>•£€*ëÅÜàÄLú!,ZRÑ…xy,|!‰Œó““ åýë¹Â?Î`N‡w¿á%¢ ÄÙHüa”ìÝ'1ß±Î_Rñþa¬ãÉ•}©±J¹+áÀ]Wšœ2Ò”>•ø—Û“ÄT»7p£Ùó|\¼=ÓÇ×L"ª¢¸¿Š¿?8ÈtPÌ’åû•ÊxQl•wIÇÓ«C˜âÝš`Ž~ÿR¤Î/KN€À>Øÿ@w•y<¾ÌboVw‘p6€:××_–] ‹À˜p,.à(à¥Ë ˜¾«h"jò	Èùß7ë©9ß,gý˜í]Ê.é„+–/4‹¶ÎþiÚݾWÖáy´ôáþa\6É â'Rþsƒ%;},þrxʘ§vHûÑ„Gâç‹ú–ˆ‡ÃcGz4€½=|Ä*þ‰×sÒù='lOŽä(®ßÍ—…ËŠT¤¶væj]XÀº~…ñÂõ‘ÇÏÈ?@
Øø
eažp¿‰\æfÙ¶›Êö[Ý:}Ñï“ô>‘‰hÓdP'î|æ?å%¹¾ãŸ9ãøÍ¯´7F–ÈwAûKìôöÞ±r£‹Á`ÌÔÒ±
|pÂnµÎ²wôEˆÂ§Ü¸aѲ¼¬Þß2ŽÙçhÓåÓ_6âôÿèB¿w.ˆÒ±1g´êÑ­€®%…nWTÕ솕3¬<ýÿ. /Ô%nóL–Ã÷q^.óÝæ1Ø~&ìekrò\‚ïÚâyп·÷N6T9\ÀäÂø96¡ ;ÀW¶¨Oëö½{mƒpõÐî\©„aèù§*ÿcÞEgyyù_¦¦È­’û ´‡?/,–YAËÒ}ï{ònÈúßý³þþ™ܲñ/D…-2kÁ®ºXÍð/u\ü& iË
—ÙK¾À¿Ë]ÿŒ—	qÿÁBj¾í·S‡%€¯ ¿}\W„JþíÞ/ÞùGý…L™ƒ'ë²Ñaéùþ)À+öÿ—/ÄàîåÁ€«ãdqñöíÓ¯fûAE †ñÑ?}ö\³yæL…ôòÖõÎ_QØðÿ蟧¦‰šZXàø«ùÜŇøg%ðÇeMç_‚¿lª]è¿×„~?ôçúÞûÞÖ•‹qM+{”(œ3ÏorQ*Ï4ôPÔa¼"ÿ5f™/šøg¼
+|Ò´–ܦ€w”>gdñ°Šã¹ú NÜsõº(¤ðš8WXÕ—„ZÚ~Òž†Á´üg'5B>ööz½ö/ÞÙøcà²3æŽ#>†@4ÅÀá7>ÖøoöO¿M1–ôûa0¸!×sìü§Ï5å‹#W¢ï­ëë`½	èÿ=ú—žZ~$ÄÔ?-4¦$þ™I$Þ—¨˜Ÿî‹øW{±4Ê&	 ò^t…/ºí¥÷šTŸV§Iг}k˜kCªY¯‰%ùtž_`g¤Â8e‹\ûÏá8íW
K ‚-Eßtòf]Ó°,”OB~
‚E¨M‚s®¶°’ùMT?œ°Óò¥<}Içæj§=?ÁÒ¨=3;oÚ·tDÐn«!	5pÑëAïßnÿÃp{k¡ð@¾ìƒBRø÷§ð(´>¸¬.(èo·Û€IJÀˆþï~÷†²öExvá?}f:¬8œ.?ÆÊgÿ¿’Àrð/ÿ¼ìˆöù?þ§…[·”@ýel›ìçc?+…@Ùdÿp¡°¤ë·à¹^ê_èƒH€Z)I+nË%rÌ›tk«>¾YažÓ̦Î1F›Œ;;Rì«ãŸW|KäŸq¼ŠO2°{ͦy¼Ï ª<Š	Î@¯û¹gΜÁð¢Ý~àÿ\;Èsøµ'~vÎJÌ)—WõZžK"Œ¿	 ·ñªyáÄo¯—š©|ÁžÄÿŸ··‡x>ÀZ¢À˜ègë!'À!¦|4è¡ÿm0x—ÍÁ€Ü»
ÀGôܖºuQ¸¡’‰ˆæô¹³g§§¿~¦	4P!ÀËÚ‘!$ø—eç_ÚçOkü£ð¯"0Ëø°ÿõ•
gÓø†•" l„_èS‡$º´ñ€&qCÔ¨ˆ|×b*[/à±jê:‡¨(<Ú®OÙW"€‰ãúQÈ×ëW\§B*¹yàá)ø†@‘4¥WPÀ§NùgØDŸÞ"ðqßÊá´]kê=i{/yÚ	8r$"I»jÍÀ¦«¯û8AIoöÞÙ:0ÎÒ½Ài·÷þtk{{çÔæ àþ´·Ÿû®[ýÚ4uI—ÏAêãPÜ›ðNŸ~ùå—O·ÑÀ±>øîŠöóƒôjNŸ=wîì×ÏM‡ÊHÙáþþõ¿’ÑÓAûQ»ý¯·ÏŸü;]ÃÈÕ)×Íë3æ?{hj…ð·œ~1„Ÿòñ/H€ýt“é~§ß'ª^G”’¤EÒ-,cÏõ0?gŽÄ¿ç“jž¬ް²é1Áš_1Ó|»è›“=.t›grhVTrÀfî09“/ª­3ÀÏp€kvˆÀ‡C·N@Ûˆ@W­‡ÏS§GæH²Ë’Àüp³‹Òƒ= ]Xðßù¿½õΞ>¦@ë¬xÁ•Çžû~ÍŸB`
Oû,àÿîÁå9o:ÈÁâäÄËgÏž^Ü»ýÊ=9½€zØ0l‚ùöë_?6…f‡ö™\h·ïÝüÿÎÔs¾#d6ÿÌ
0½?`¿Óø ›_i6]J€²áózA´Ãé─N_›F fœ‰0¬o­˜ñ…5+U’Jß¡`=Ë‹b‡œ»Úæ¬YËnhëIEAÞÅãÃíYA)ÔäسâË6}‡Y;9ŽQ’,Càg¯þóÞ‚@–|?mIrޤïë 83(@ä#”‚H)S&À xçííw¶2Nx¸¾@ 8@¥à7nÀêÓðÊéÅÛ¯L¼ðÂmYºÛ8–V5^ãàÄ­Õj^m‚Ëþ—]~¬
hG{y¯Œ†}¶¶\ ‚•œòJ¢‰ðò¡ÑäÀ-ÂÖ_€kh:ô`1Eˆ X”x8ÈXLOóö°€¡d€½wzÁ?¾³µõN{OðÁqŒÏrà_ó=U¡wôpÁû.:rPà•Î6&þTn—‰«*fÞ•°Ù	0=¢
€„´¼ƒ2Ô	w®ýÝïüÎÔßþmw[h€9()þ¼l­ÿó‡ÙøàE…þiIåã_6Ä?
~|ÛQsí#¬Lg¦’â Žó	!»i”Ùé’Ï4	NÅE'öLøµü¸™ïU¹ðªH	²Hpç@·¡Ø)„èK$[N@±³Çý$E¸¹‡íåf¶IÓU|•‰Ší Ý~}È‹Ò,€;2
&5ÀùIšÊ@iÀ{{í­îžDùÏ¥/P+&2šúÚ)•÷xÀÁËß­‚
pšÊ«ðBcbÑð_E8üÆ <ÃæÙsg›a…ã=ôñaÊ¡³$v®u®ý÷¿ûÛ©‹Û;Ù*¿Uš IDATߣZu™ñÑþœ°‡hHk ,6c/²°DÙPàKwŽH	 úqD	S3Ü)NÂQ-^rØ«*	u€f‹‡µœËF6Aƒ	ÞÓ–FýaíÌŠž@™äˬí‡åÎèå	±ð]¥Z ‡Âd·&Ë<$Ë£#ò‘ÂB%BýÁ	ËÁb{1Eû'IHºhÂ¥"óp$Àª­ÎÞÒÖö;ùä.®fù¨%ÔÿÕj!‹ô/ŸΞÕ 4&“‹¯Üjñ]CT.9èì¹sÍP}B÷SÇÁ‘…ÿÿ~­pq›wµhBà0Ný°&@ë[áÓ¬([ÖæH%@_?ÄÕñ%Þ²ïÇ™>?¨V”™
ŸU**lÅA…€‘§<‹ÌƒQÚÈ~ØD/G'pÉÄÍLà&mš¡ÑóåAeP<Ú,Ç¿%„šìˆfÔÐÌŸ÷±z§GàŸÐ^è·æÎ͵¢èý,ï¨`…”CŒ’”„‡[=®À³âIÊ–wý)9W:ø¿ü]€¿š(
Û‰‰àžš	È—ôa$Ž	€,šÒõŠhw‡™†ðíÚÅ©LO¡@2	𭱇ðÏ܃ié,á_6ãÅ#-9îÌ9ƒƒD+>qû!?©}"À‚⤎ýr¶Àñßp¤¾0#Åà¶ñÞ¸°±¨6qŽW­ÊÑú‡
üüM…Ñ3Ž$×(¬Ùû|wÀþ¾ ‰¢–º=!¾ö5Wè3ƒÓ½{÷‚üŸë™Å“müÿžÚð€VX­ìÜ9É8O€‹îŽcnö5”×@Ø•?1C©·À¾ßšH¦‘ËÊ€²™'›Îu»”̵ºs¬“s‚Á Ïç¾G=îs•€‘bt°'82Öæãþ3X櫟¡ðìèV_Ê,å¡õ„¯G*›™ÃE€b(Äñ¥¿- pµ˜r/bþ‰~ǯ§=öìe=	0·¦|%'g›ƒ»Yï.IgB×ý
¤äƒÐÄ@*V+<ëVB³‚³Cngøï\»·¿+¤M4Ö€òo[”ÍrøéžhêîþD›‘Á@|ÿßå|DzøÜXˆW¯éŽç'ør‡×»q<³{…ð Q,1Ž–cêhpÁÂ?yeìpÜæZøËQÅJ®+,à¿x€ê1aY®g…™%P¶²ØŠQë:Ð= '™Õ9‚žlll<9òñ'óÿ™..É^²2ý¸›Pÿà™aÅ„€Õð~;…ã-¦©" [°sBL/A0ôÿxw§'%iàÙ°Æ%¨ãìÝ›!ž_{Ϩ‘¯}áè&û•UWÙ~‹Ûe	}6*°€$ïE£^?c4ÚýcOÞ'ŸùßþƒgCñðŸcZ¦è„Å4CÎF/I,¾KÉ6ÙÖŠãö‹‹i¯§:}ÕÕò¹ÔwiÚ£$x¿Ý÷¶d"3°ìÛð¾GÞém÷zò|_«?%·ÓÛiõômPêmŒ=H·÷¶õ›i0qob¯ª@¸Ä­âL¨Ú{ï€üjv—FSiù4—í9ší¯¾“êö{;;Èj¢P­«•’
œØ³ J³¬ é=¹6ÐøÇri:3à´S²—`ÉÂ@ÍFäfÞ#lØ~ÿ}ì±ðü.¶q.ÑÖ;À5¸†þ¿ÒÆ>·I'«§eìQ—1•o/Ál¬{÷z@/{w‚{?#â²[«ù~Uxµ©œ(ùÙ‡ÙåHz'Í-z¼”e{.øs3[E–´Óýÿh€cÖØMðÓ“Â7šÔQ>̬¯`ÓÌîï3Ê,€äÉ£eMóó—°2Îü_€x^ø«90Úû©tÚC)€‹[gLן·_™RF¾'®¾ÒN’^[ÿÚØ¼WßLIЊz)?#ü”ï^~ïkµšçÈ3¤º$ºvlȲmºÞ°éþÇꟕ­l'õ·*W¬3gƒËÀFvw:¤€Î‰©^®gŽrù*âêlÕx(ˆ€å×°Ø_ àûèøÄvÌ·®N#šË+qdŒárÅL…a†
+: ¸R™'‹WÍr;¨ÛO¢ ªçÅÝú½6NnÊMV{«=Ùš$˜]cœÈ
eÐç«\zn#Ê\Àˆ‰EL¦–]à ҌÏ&>Iïý÷åÆÀp­T;‚ÛS’S’d²šbnŒ;î‘6мO{é½ú_olnö¢VïNoobÂx~åòOnÖ¦j^Ô<…k&ÿÙÕÊ<®q””vÙ¾*dàè_\¾<"Ю²Ú½¡”Ì+O
XW)¨Âÿ¬©%ÆšO–¡'à“ùK—¾¿¼üÉkóóËÙ÷]y°Rp´ZQ^+˜ëõˆ…ÿ(ʧ֑`þsæ¯ä Þ,xêM¬
šk‚‰¶ðêm%½W%ØWÁÜÖZåµ7$ÖU¾@é O—• —hqq!{û™€l˜q €E`€$E)ÐÆyÃÒñßS‘èôª§A7üì½ÿoו/xëÞª®b?7X]¤•.©…Øi‘l«ÉaÓKq•¶ÉÂTSªz8ì¦ o·§ИL)e‹~B~ˆéÀ㉴֊ ü¦'/G–ò²LàÍb¥¬¼Yà
žíÙ}óvßþ{ι·¾4¿H²w¾, º"›ý­¾t«>Ÿó9çžsn	^/µKàô3ø¯@MF£]@àb°qHÏ~%§g^{m“‰sTP)WI|܆ºm$£½ÉUFÎH¯òtì?ö !_@Ç–u D÷B÷F&»p­¶7ì6^¤ëŦU|عE¶xN-§±­T¹‚?FwvvüZm§)X
À©[µk·G¬V*7ÞÞ…ÿ ˜xâíJ¥ál¿›÷ôhm>8*l_C€NÉzZx#ÄAÀ‡s“%5‚ @’Ѥ«Š)Npn7d6¾¡Í4¥ínÛ=œÓhÈwRˆoŠ–òbí)ö:àÍJž)EÁ—4
PAû?៽XyñíØ(`ç€=ðt<]å¾bO¾*nŸÄ;®œ“L~󰮎9
•dPPS
ÆÓòe2Çå¢aćSS‘“ߦõöÈë/a8˜!^ /{™Ä¡/ƒ¥×Köò2Nô­Áº¿¾.'S`{t¾«¼ØOiEÀ²îBШyèðaì:ÖlnúŠ™5M£úÚk_Ìf†’‰µæå‹ñ⦴Þ-ï1€\Ì)Ùx)Å:æ¡$€Â?h€Éh]pÚl€4yš¶—(¦¦@Ü–žôèím&Èùßi6w¢Á­ñÚ­kãÖþ\Å+ìíß¾Áª1ÅÀ¼žd×ã^"`Óö‰x^OÐßs†ýhY.´^XÔg±ŸXAhD>:誋P $‘NìáŒ]ÔS(Ó~ò4p|ÿ6†Ú¯ÃÝåè1ëÁú:ìs[ÀžAÏ#“,Û›è!íï®|7–á¤@@F»ß+`¢éß¾’ëf«û——.e‡rUÙx½·tZ}OKw­„š.”އxÿjɨÐD€þh Êj#À¥»!@šýsçØ"Aœ€»
ÐgÛxÜÿbøUW݇ÿ)¤€Èí¯¼Í{b€^À{#AûŸÐºkò|Ïë½Û£»Ÿ˜^PÂ`舭ۛùçGY@’Ú²!PX, 9cª„w|©˜žóÔ»‘FŸS¯cìàøÁKë8˜¿/á³CO=à¯0YC,¯|÷»ºvÓì6¸íq…e½‹ý„'¯W'³Ù\´ò‚Ö3é'˜Œ[Dt~Ú4"˜ŽG
šü—€²±º8	L	€Ó€v›Éø“¦®.M½&7P@q´(0	`üÿS;†œ¬Œÿym¼F3aàOT…V©&ÌRQ„kï*‰@žF&ÌÍM°îÚ^8BgXÄtâlžQŠm¼È…òw|eã£Õë Òƒò4Å€á5_®ù‹•Êð-ùþT	u@ðºÍVÐË_éõ—Öù¥§à-Øü)ãÿ/•ìR++ËðçäòK60¡}¨](x÷ÁðçÀ³ÏèÆÐ›¬úáÿ€–ŒòázËE¯—àÒ4 t<6„™@4€à¿À@„è·Û8Àd@ŒÖ˜*b²
 V,jìv‘ic€µ\Q@$Q@t½z“¥6¸pÏ㊽¯»^ïãäöNI+9½µJ%‡¥X8Ø”¨”í…¼z5t8¥§á´ßnèÇó|=Ã`á²½RJ‹	€¨@,œÀ„£—^X÷1UWS
žšz©´Âئ_ZA?å%¶BÀÚ'áX<èßô€.›ø›œ[ƒØ“EöWøZ/˜
 ÂWµ½ŽB:Ò±¿`Jèëòf“õ˜xRÑÆQ/½vNá_ ôY(FGáEÉÅÑŬ+Ö0˜?”rW÷MÚ/!‚ž»*ù.UÞÓM ±}iOÿ€’Þ(Á[@ÈÌ^‚-žßˆb’ÍAôˆŽç«½pz¤äòç˜ ßÑ–|(×ÿ
7G‡{„)9À0÷·D5?àŸÙ'V–×WN¬¬¿¾ŽÛ¯Säï»%{å% €Í•Mà‹öKË'W¾[B&X.a.à¦Ñöpl6›sÓ´¸¦Y˜
†)˜¦í
j°À“:DhaG‡ÔõOÇcJ€]™öd00òÈ	PªWDBH"IÅ		Ì0Šä¯üÑò#	Dy€{/Kñ°G{úìÚ;‘Üw4ÇÖJšæ ð1<Ø™à…X_Îe´•‚ñ55¡IjÈŠcÿÈ0ø&ûàæœ		d21“­ÑÀGÇi@%—¨¸Ïg'N”J¯ŸXy‹‚|F°—KOm.¯l–@j¼´ì—–O¾T
–O‚ý7ÚÚfOÁh/jbд(ùzþQ—&:Y’`qF@2‘ë¶ÇïH _zôÔ·÷@24/ô9Ü€‘ø
þŽ9ôŒlÿ‡ÿ\'.(&°KcDI‹a·£8Ò`ÆÕÿÀß
M½Uö÷€ïçô(î°Ú\!(u0P¬I€Ú`½´¾¾¾¼ìKg2˜íå•åÈñðA1,Ÿ<‰††IA€]Œˆà„°ðŸ=L´d	/v)¨ýéHÇ?òxçìÙ3gΜŽo­Û<1¨*-
˜ÑÕS6>ƒQÎ{ß©Ö6ŒŒiXFþd2|ßAÛÜ;}úÌ™yõìOþøÞO8R}°Û3…û6aW†a⦎n»Ž£ï¿cžþ¦ãKEžÔÞéÌÏîGÂÑZ_·uð6Ô‚ 1°3–Nëƒrîà0k5âõ6HD¸x aepÑ=³öÕh­·Z6?ó›3Àíÿðÿãoüñ=ŽÈ×™n°í`·°³Œ19ielÛpl‡h×xä·1.b‹”Ò!{ÓØŒ}‘öVïÃ+ý#žýè§­©ïŠóÎèé
…B«å8…BܘÀЈ#îá¯wtÛ¹Ã1mÛ4%è\FërR…x-—3D!îOÈ;-À½m×¶¶lô#Züô«ot:×.~Àgþø'œmoc&æö60€¦Ñªd\vö`ÿðWñôðü0«£iûÈ(—;%€tPº[©gé¼G€ÁÞÌR»ôezóöüé=¡}ð_JÿC‘tü‡@(
4¸Má?6vÌáÜè3tÓý0à&¼ÚqìŒÐGCâõ¿“
ÐMµÑÀ‰¡@(mm•ìV«Ôjqþ‹7îþÛoüàOôû*á›±`c›ÝÞfHˆ¬?ì4 úÇpÚßææÅËMM
.§Šñ—¦J¥ç§¾€7zg_œ¢¬6\î»èÞ¾'OÛÿK)cÏ'ŸžWê¿Pˆ í;fvĵɥ×uÒ:ý7ÚE\»ÓAÿ¢	<	àÇ =¶±Çºió>rá÷0J[ô·èdß8òÆzã?ýJÙ–¥X$à.¶o·ú&'¿299Ùg ¤€ó:^`cÇÇFdàÁƒÀGõ>ÀåË)¤«klZ“Â~|ðw=ö¾þ̽T  ØïýARh‡ÙÇÂÿc2€|2†~Éôl¬kÛ…–´ð þÉù§›ù­-g~€ì8ܦx ×þœ’2
XÎ8†aæT‚kàÅ[&W€G’D€Çêtžþ·?<óâ/^é ¨“ü¿xq €ŒÑ7™½#›ë3ÀëðŠcÇ‹lldd€ËA ÿ«öE!¸ï§Žþؽ^|À/ð^_?p"i7D“¥<á¢v¶$”R¼bÖâ?b÷{žÚ}bæcøúÁ{ö(ÔS	ìS²Žà¸#c+«@®
ëgÐÓÏdsáN­TœŸ/Ú¦étj5IÍV«éysšT&huÀ;È€r†@or}ž‘ÓvËvéx
ÐùÖ+wد¯á=¾Í~¯C¸ÝÇ5ZMÃ’ø˜´2 Š…•±±V!'@`ÂSð`ý~€)¤áO™+¥(Îø_Ý[_oØ+»x ЭAÊ^Ñ¥”xP|cÐÒ‚xð(E±ë	~0báø_$„
…,ÃÔÆ u „ØSAÏx"aÿ=çætçøÿöê*x6EõÌLƒyF6GP???ê8Î@ µÜ2ægfÊŽa–‡
Ã’€Sˆú‰Œ@ßÁöü«D¤:wît~ý
ükIpfKE¦Ý¾-:óLÀ%5&áƒÃ¼ÂÊ	ŠŒA	Pš߿œ@:ÈB£x>éx}øw0þ÷´¸w+€d[ÏGüQ±ÛDóÇ	êðGDä  °‚û8+P8ÿÌÇ>¦dáÍZçšsq«# _ Í5æ
ð×媫™LÙ _#š4
Cpçx
düÁúKGÀµkw~1øëk×(ªÈ~ÿ{m±X‹‹/b&ì-@“Æ'
x('ÆF€"!ìâƒõÍ‹<¤Šá?›ðOPmµ´–§Zð¥qŠÖìÁ£Ÿz¨‹ÀÌGYì‡Çè;~€‹‡Ppáè4¹æŒŒ´\œjG€Ëéý0Ðé8ŽÙAÜÚ’@È
*I¦IøÏ”3†*Î-Ëâö!GØH®Kqb€Nghð¯-	€³Û¿-âSK‹KÛTè!Œ*:cx²c@™€á?Qºÿ¢‚4Y0h«Ÿ·K¥©ÿ8AÔÒ´@<ÕÞ#‚‚=Úcù$Ü/L÷ÅêÞŒÇyrÿ a¤0Àe×%°+¨y6Rù¦e¨”ÀÎkwîHån`Д«¨PÒ^ÙÄ	™Œ|ÆÔ
nå2àè˜ÔZ]/„@ÜÿðÓì?ýá0—°ôâà¿Xœ_ÜF0„`¢[22¶2V€ósœ&IæqùW>ÜK@:¨ËÕóSχ¬Ë÷ÀMì`Ø3ígè_ÿ1ÍÇž&”Ž>ûÒÇø4ß~“/ŒŽô8Á±c\Gßßu§“	·fŸ%í¿m›;dÿ;˜	D®)4ªé—S:X~Ýü› pä	>·VŸÉÁü¯¯Ž­¬’ ižbo¼ñë;òHÚbgqI[Zœï,±ímÜÝdNâ?7iÌQ,Œ_Y+èö(HŠàb 0øvš”Ž”ÏGT…-ñpQ¿;ñgwbУ¢ûïs÷3IÔÙ…w}ðŸâ[Ùïø|4θˆ9@ø;
,P:VÀyþL†B<ƒ¸Y£Àzì˜$õü˜
H
Àà—ÍrÀE\è‡JØ8ä C ¬¬®S" 
€AöcýÃ_£âUcjƒlûöíù$净a`š²SÁ z(:ÁEÀ/._H	 ¡€Ÿ×’%óðîÔß/”ˆc¡§kü³¥siPí6wÛÅiÛA/€Bøú Æ¿“n suÕ¶=ÿfaíüÑ´‡h¹s>pâÄ€L¢y €V	ç¿J„ôÆŸþõ+O#Èö@š$ðñÇ‹IÌœ¤‘뛄3Бut™®èÀæâ2ö4j ‚ÔHGéDÈë‹—‘?1ÅAŽž €vûÀ–ÎIû»#®Šý¡0ÃR ªæÑ‰L™Œf›Šõe°©ûËÀB5 .'<Â?F0È¿úU‚ÿoýÛ_¿A»Â·ªî?ÛÛƒùï³úrx‹ɲ"‡ˆXàS=qš
œŽt|±—)“þ¹#Ó€¸þŠÞh`*¾P0Ú~CUë‰ü*0J	âüÞW¿zä;rä«_ýQÄ&B¶$À±šB*kwe¡n'6HËÓ¡$-\ÝTè’Ÿ¸[Âù¬Ê…JE¾ 	/X]ÈkÛ‘9¥T`^Q={Fõ€Bt¾|ïÞ2ôñE*6|r@ô©cmÜoÜ*ŒŒœþÉOþãÿü7¾ÿýïÓï'Ÿ<øä“ïr“Æ8ü›™™ùü›¹¾v~Öàž¼iŽnÊZ|tÂÁ·Ûí¾û®üywVÓk5»‚'aËiýZïdjò;ÛÇx#v´½60ÁEõúõjµR	+ãkw«ÕêÝ»w?­àèëÏçßzú•¾þ[?ûìg?ûÙ-z²zj`À85`YÕÒ®IEâ€]ŒÃÀ)5lø°_~õÕÞ|óÀxç7?zõæ/?ÿ U8ýƒwÞ|ó#øÚ™Ó#Qúb»·*Œ	L–"à	‚ÛHÖ
¯èµŠI™k[àkÚpíŽWà"—k‘&Õø…ð%mËLé…J9+”ªÝ5Þçû²Â[÷–—­rJŸSB9ùŽZM±ÍñgÄÁ¿ÇGà¯N2ëûbÀ'Ây©UX^…ùôé3oþÑÿþŸî#êé÷Áææ'›H?ôWÿb¦°V][«àOeíçã73D@ÖÐöõ•ËeÄ?Žî컳]ͯÕj@¾DøÓù _ßáÄXÁ³5Q‘Á&ˆÓ¬Tÿkkw×>•ЗÏå~Ö*wëÖ­·àÙjNÀ:EwK%£‡€—ô­­­lSŽtÀÿGo¾³‡ÎüàÍ7‰„µË@j´äHð¤Gÿ0D]©VÌšYëšœ„20]ת€ —¥^àl CE%¨TPI“þ¬Hà_Yí­[[± ?ÕPœ:õ–ï+8«°'›?ÍüC0ØÃþàŒðf“‹€~³5ŪÓÂInçÌO~Ðéî?øqÿÉæƒû<Ø|°¶öóµÊ͵`Øhx 3.D¼Ò‡‰ûΰÃv†Ë݈ÀþÏÎ
°øº^Ñ5­·øÙj\f­¶cÚ„{D?yý@ú‡]2ûSÜ/¯­U‘ª“FY*€·ÞêëëG!{ëg·~v
p‡0Œê@­l”­Ò.€ó+•B蚘!(@	àw 	àƒÞ‘"àIw:לn [ëÖ*5Àÿ¡Ìäd9“9—åÄÄ88‰sEK2pøç:BΖaåh¡Ú„ýºãDàDµ*kÜ
ž9uêÔ½ÿ°¼
û ØÈ©oÅ–ÇÑh_2†Mêc§¯„‘·M`€‚í€ùwÎüѾ	—üwºíM@=Œû¿ºßþüüƒÉ¯’ j€
fÆ3kkRTÖúÇäÎ02@&íÒxW9³³@ñ4[¯Ù\ÃðšÎQâ×ÐOÒwð#ïìÔìAQ©1S­NœZ«““wQô¿õÊ+ðÓ×—Ëõ¿Õ¿¶F¿\àÔ€Q…Ƈ¢ÁïU@6r€NàGo„¢P©Í IDATT€©þãgÞ“p	à͈$þLãs5R<é¹fvï:U³VݪäìkòÏþlÒxcÈ•ñŠ&ŠvŠÅ9x7u¿Âyåc®{¬d;!«§ž”ümÀ%¾ó[dù?Ð?ë¿u‹ìfÞ¨žúìÞ[€Þ*pþ´=ÿìN…®ËàyH˜e{òäI`:6À÷¿rãä'÷›šh6=ÝÁ6yßœít¾ƒü}BûW¿úüÞ¿P^_fî̬­Í(øãïχû2à[4'	€Ð­Û?]>Ø~$R¸æŽf‚,Ð…ž©eŒ£΀µ.¡?EÕD~¨`W@6þ”û€r¨€úóýy WŒj 
ÞpÊ@©ðé§:pÑVD¦N p€©ÀLÀ2úIQGD¶ü¡ÿÞ{ïýRO:€¨¬T3NÙ±îvJ@.7<\ît+ºÐ<¯»SôFGu™,ŒþÍ/Z!HŠä¾om
Ô¶ÀÁÕ‘øfõýêûïW‡ªÕ!ù:\ïo}†ÐæžS@û_œG

@»ëI9~’:o^6<Ø€±yÛGu~æÌYL†ïvßüèïþî~û~áÿ«‹Èí¶Ä?¦ÖÏÀÊ8à?3³J€µµ¾aÕ×ׇ-4'Ùÿkºƒ¾?(€Š¶CB V³)$hëW)4‚Å<@:òÀ‡çljÈ8sª?[«~fLV˧>{ßß÷Ö[o½.@.ÿôõ·úÞ*ƒô	P=%	``RÿôSãïÿþÉ2ðO/¹4ˆtÂ"
€.À;ïœ!øÀ%„ðNLÿþ›7_–#EÀ>*³[­
_+—3Øìáœ59ùgÙ¯d­_ÿ°Üvt@ýNÓ==ŠÃ£€S8	À¶…l@OQæ¿ÿÂn(P}ß|¿Zýà?T%àÊÝSÿù׈0eΞ‡Cœ	PrìÞà¿®G€`ä¤Î›ÍïÿâÅO6>ùD2À¼Þùf+d¹ýÿg‘ñ"ü\D
М´Æ‘Æ×䯆2 oØíêº`8™>0úèv:@àƒà@”;8)€èYJH5ˆÀ4­qp7àÌ+(cþŸÁ˜4ÖªŸ~ëÖÏúrý¯ô÷÷?»b :`TQ ”k¸øÌŒ¡+
(e2%‰üÆ‘vÅü@2@BœF>@
ˆ@âáàõUŒ~ôÑ«)žtP©™•kî9a‚íúê‘ìᲯ½0”»óÃòðÑa^ôα"¶´pDaÄ!q®Ž­ºÒËÅ4Í6oõoý/·äØ",ÌªŠž:önõóÿüµ«WÕœ¹]²çaþÃjôú	_äD€ÝWø?ysdíOÚAžþýöƒMÁç9?‹%w`þ»ÝWÿÝÓ¾\$ü_ˆ€*ã‚¿2>ž0ˆ2¡00\Ƥ= Ëêëéÿî»$$HPá/êÊ@ÿlðû¹œ ‚«!k~eñÏÉ
 à38еfLNLž/÷­¸õÖ­[†1l
*ƒÑ¿Ö<„²Q(—kVFÿ1c~ú)0(€ŒB¿á4 §i@Îʤò|$ƒ€H’ÞyG•ýWðÿˆ´ŒOøÐõJÅÌ\;6vó!	€
`G—‰S€¥ZvÀMÇ€Mr•
tÊ:…ò~LýägŸ½òÖ@ÿÀVÿ-Iý‡Êe%ÀÄD­v÷èý§¿øàíÌV†@B»‹ë&­1Ç,jEdn¾,çcxïÇ(
Hâô”8¤V7IðÄ€^ɘÃv·×+üà¼kX¹ááW~XÆ4¹"có£¥9ÆvJÅ9¡¡ÍFóO³€6æå¨E©Âäõ[Á_Ûºe«RÎU=ÿ?Ùþ“¯ýoW;¿ç%¹%rl™-‹ýôu@n€Éöà8È<ÜÞxpßߨŸ¿8+§î^}ùå›ñ;0ü—ýÍËrXk–YÁ@hû­Pd07 B+è8Ê2ŒÌ°2üáL`W5
ìØhÖAñHüëä Бv€t 
 ’VU&U«Ö ¿\-
¶Þªäóù~‰ø-Ë(àÝ»˜
`?ý©”Ÿf2nÅ@†ÿü:6M޹(ÒŸ›I	€@A€˜ç‰ðßË2d¦¤™€)è•ÚD­jÖ*[åk.ÌŽãºVvx¸|§œ©è XqÞë?ZœS°?|0‰«Í`$Lhá:µÕ±PþO­¦oÝ: µwbí;Ûro»yï÷WÿsÌ™3Z,Îz¥’Spˆz'Èpp@G)ŒóýMíòÅËþƒÍïû@³³!ú+¯¾|óç?ÿ‹è7é·)G5ƒ¡ÿq>.ÿ™¾ëå’ë“àw°5ïð¬ÌœU>à`_Q`B0IœD Û|ggGæé[%U×®[¦L	:>ÚÿÉ	£:19Y­ôçó†Òÿ@’Õ2Øôîb>P¹üÓŸþÆœ±f&ÑÀY€’î*û¯´?ÁîwHþüòæËQãþ¯Þ”s£åˆ¦ÿÞÃ÷JëOA)žô@¥[©ukÝ®nf®a\¿\0¬§ŸΠ
Wm#çðí€ÿ-ØAUºÆÂla"obHVŸLtF'þ`â;ÿýwUûùÿ6€ßob¦Q³éyž¬Ž	c€ÿ²ß„¾Æß\£ÔŸ„üZX
@`fp?ÜgDÙ%ÿñíÅ@éïh/V(ˆAK$1€-ØÿÀ@/¢CðÇCþ1ðÔgVumÒX›DÀÈ•‡‡Aê¿…kv•Ëx\ €2Šƒ<ŸÒ4@I@æÈÿ;:ªncºÃ5š%ùeÄ”
øæ«ä´[2Ó_&·þ
ÿE1AU"à	‚|VZÃ{ÌÙ†ñn¹ÓéGŸîvMc@סÇ;`ù‡]YÄ1­€$<˦i[[·d‰€ˆ*	ˆ&à8ÝA$ûÍYã÷ïÌ‚ÂÐØ\£Ñ`ª>NF¸)ÓêÉî«jVÉ
Â×4ùšïã£ï|§ûj÷åŸ~ãü‹¿ú¿~ùÞçÿ·O¡ßððƒ™¸öqiïgfúúÿ××2×Ç«à€_10¢ßÉd(8K
€|0ü;W5ÍÆI]Íûéÿ5”ãDàÿWìšLv—€ÆY€SյόO'»“ÕêùÉɾJ¥¶•ÏßFëNaxðî©rùÔ]£|Ê*ëº$š(a€ ƒð·š•Šé¦(âC‚51Ž7?!$ ÷,ðWLAøWèoµÛ)žx@­F£n­ÌÄ\ù‡-ì—iY\טZŽà¤¾2v¡@vÈQÕ¨"aå£zöd¹jôêD¥kbÝá„2ð…Qxo£è9aÌ l‹Kõ±|	€DF£b=øè£WÁùÿÍ¿ù«ßýÃüÿ×Fˆ|j¼;×bŸôþš!	Àº®8 r}f&c;ÿeÓtœwËï*¡@bÿ2XJül<òôÚN¢êHãã’rª˜ôÙgUã³µjy@ÕXû¬R)÷çÁù—ðGP­ü«`ýáæTUÏ3™„p]$€k2ó€Ôå-|óx÷=É4«‡¹¿	ø±ªöÁÔÿËäI?A¨60EÀ”%¿¶*6ùÄŒs}ø˜#õ8 \Ã4ððÃr`Ä=ÍAs=.Ðý²Ã.Œž÷@”{#‰ƒE„òßþÝ¿ûÆ7~÷WÿæþáÿùüóÏÿëß6BäÏɱjp¬	ÿU×ërÌüÎÁ
ƒò€w2*ø7û®Œ,vk2ÖF_—Å@’$þM[5Ö´ÌÝLS¶̸˜tê3,G¯V?;µp+B?Œ*¦ã¯eõU«5C×¥ýÏHüÓ$ ~Ì&¦ÑCkè|B[
"B?äúÃÌ_ÌýSáÂÓQ uÒAcõÄÊã¾US=2ÿ¬'¨=¤íoi£NùÆÞ±÷íæ=¶ìNjþã|ÏÃ_nàÙºû¹d<œQ_¢1S:Òñ¥ÆÊ³Ï=î[
ùÛD‚î~	HÁ7øþcõ΂ÂÓ£	 g~a0ömMžÁã.ŒÐnž'Ýó<<_Ù^]üL¨˜*.ô‘R@:þiÇ4"ßXyî¹èÁãø
¢l!þO)¸{ꟊs^‰a’3œx¹Óñòh¢Ýý šx?÷…¿#óÑàº=+%ì¡+îZ*Ú®Q,zÞlz@§“nÐŠŠºü°LXi²5ë#ýt9—W8œ^ÍéøÂã¹gáÚœ~vÚÈ
>{°˜=xd
m¡ð¯€Ĉ„½{$Ü7÷yn8>~7¼ù®gHØíUžGpð׋´¼•,±.í3 ÔçüaOÜ$æW÷¸Ö†%Bj8PØ7ðˆ5L8!så†ÀS‹«¨Üi?J\Ó™.NÌêï>Y+½ÔÓ±?´§sÖà ̹ƒíŒº.çæ9§î”ú¿{WÝÛßp
æip±îö¿ÿHüDv³´W+ÄbÞ)›¥ÍR8äÚ!Úþ.@à:¾Z½ÈÝe‘qÌ"èf{)§àmx^V¢iÄz(ü™®‰Õ´çVw½žáº¥PhpQ,ZVÉ+Á9á‡@àŸc·k@À4Ô08Œ{ pþM+«?Ü(°à…ZÑ¿ËÏiÊO:ÏZÙÁAÍ|ØÚ_OÀ
{5àË5Aèþ÷ßbìÖÏu<÷)׉eònŸ^Ëô'œúÒ@ÿ0ü¨‡ÊöGï/9ó|‰|):nÞØ@“ê¹ýcˆþG@lá&-fggëñ#¯àm@T^1ÖêjqU{¨‹¢&v—®Õ«Àºº!ž†Wl˜0Í¥%`€‚qS.@ó®ªÏʾqzàoIƒseG fôʨBM Åõr¹œfYI/×LzÊ%QšÓ	ðΑíoÌaðVÿ]Âÿ]¶o¸üÅÀ§·ÐsÈ$xÆüÄ,œáRÉé¿j9¢…pÓJ›AÉaÃHõN'onÔëVwóÇ­Öº
bË5y&q>³Ñàž‡i^Êú‘@ˆâ‰b¯Ô«Q´ÁFZ«°­Ôf†e„ih¥>ó¸Ñn·§¬vÛ›:æºSà`œ«ŸcKç¶oßÞWCëeHM†T £úCY¬\¢õÐ×Aa£×½26ŸO0€°ŒB!:çºCit1سÙA®	$ML’
´éé¯÷HîšM¼Ûß÷îÝÐ~î=ÄÒ‹³®³”x"g$Üý ÎµÀëOúÔ‚
Äׯ`a6R$˜ŠÀ§:°Û%nêõ<;x  ÖÕÐçÖ3Ã\ÃÐX:;[_šUj¡HÕ+zA||&Š1À5¡™‰ÅÝ0²á*{.@
Gäë¦zqÊó×k·Km÷˜{lÊÓ9|4Cãuf˜Ú¶©è$&„}«Ý¼ƒvSæíVñod­ž€EÒÂonô|ý­\¶0¢VnžðZ­‚—’@:Bk08x`œ[h¥J±ýL4€,ô¹¹†„È]0ÿýý‘à†24¡–œdØÎÒøg"p5ðÐ$ 6¶øHqâ0@¯>a°‡ÄHDïv)®‡æ?ŠìÏÖº3»¤œe`€"Æï‰|bT
®k™ˆ$nŸCãßz.ˆ$€ü6ŒPìò‹Ö¡¶G“BçøE S™~û¨'ÚíH Ù“öå¿¡%ãøànÀ‡*Œˆ1
\×4­H‡¼pÁ¢ð^üMë¹ø§§KÓ¥Ø2
" 8pþÝU1@€³êÙscp_\p!À¡Ü.ëã¼À¸òŠ5ΙŽ|’ä4à”/{ÜD \$~æì’V.Ã_éR{2@1/¿Wöã)v»½‚¡Q¾|‹åWC	 Od¢x¥Q„}ƒÌ0Zbæ9MK¸±Ðj¼€ùÚljêСÀë¯cÀxŒÿ^áù…ß/x-$@àû^K¤¼Ð¸‘x%ÁÒ›2­}=ùD“¦çP6‹'¢( §é`Ó½c†»´˜¹]³Räu?äÑê¢=€Þµëàr–ñÑà’[Nž€âÐþ³eä
ðöÌ‚,Ш	Š.tSï=ÉäXMD(sÊdŠØ?Xô¢wÈR“àù/ÕÑ058+íP Iü7y“‡é‡,ð?64,ëѳ{€{pi¿•õ¬–òθÌÇYєұÿÜ3JÚ×§®v07G¡€f£Áîªé¿»aFM˜	Æp=.„ûœ9«7Rèá<]Ð;HæÁ
©»£Ç@+ˆ=ŠÅ¢¸nzì±€Î3峜ffÙÙY‰ÏbFÉÜ$#ŠðÄâSÓüòZ«P€H3dÖßjázx%0Á0¥#AN@¸ËvSˆf“’¦‰©C؇…¾Â¡Gf5

€›­è+xéUŸŽØç|ÈU$¦µ$¨àX¦†?¦…i@…,àÕ4EXEèºð„1€è‘®ðzàù¾OÑよ0ò¦îað_ˆ00¨#þÅââCj¨T9„íîr<Öl]«Ãï¬`ïa¼¼7B¶+1ßµÓµÞzωçòñÛ裹öÚð‘0Qö’ÎMÓ0þõÐê«Gí¶ú(AS§iS¦Ûçm‰ä)î:ãˆ
…ð€±¼NáML^* 5ͨ„÷ 7%$w3hÎiÿD§îî”FØ/AY =6
³'ÜèÇŽº¾¿ùZ”ò´7/^l;ô¦ HN9pˆÜf ˆÇ{4w§ÉÁë³Zx‚>h¼/oÃBè‡ää:C‘Ôðöçž%î1ñ+0
xèÃ/ÜD.Î3À{Î-;gF'íIvZ—룡“8$Ä!Ø•fá·l!E˜ÉÏØ{Ž7Ñ
Ÿ÷é¥ L‚í\òQ{B¶pnNšñwµYâa‰]LJ,©DÛq†±ßïfÉ&`E…TÀ”lJ²èݽŽ0¸Ø1ÛÇ~
/ïæ"y÷q¾‰O"Ï Páñu°ðWŸC«‹€ìŠc8ÇsáÚJB"ž©¥B	Õ{‡”"1µ(Á÷á_àÞÿÀ´È(ÿ‚#÷Oxù=:ð/Ϲä_xž›óܽFXJ'ÂhŠÒtüÿ`€ø·Yé WŒaâÂÚú1”²Kßµ÷<ÙýG8M¯ø¥­ÍlÛþÿtà°Šÿêý~2ñý¶í’mëûʯƒB}Šé,<‰è4öÙ…‡“-@>y7½²ÓñÅ@‘À5Æ:Ø£¾£ä¼™+'Ö
\#ïшë/àrC1€ºe½Ëd€þeNpat<!Š^}ŸWMŠ8Z”…Mš’E>h‰íÒS%f÷rÂÞ{é
‰·°KOâ•+5öå¾@?]¾ß~0y6åWÊKIü—lì½h†èµÁìÛ˜}€ÑÄè?óž¬8w[äó‘ÓÓ‚Mç±B)ÿÕUɈ{wÚò,ÿŒ^÷éPcil7þUiÀ¾„ ò:ÃÈâ(RI\Ò·&ýd(¿N='´½p-š†Jî^À›nNñà¿|MoøË@ÝÝ
à€æ&6
$=-FŠÅÑ‘Â(–-Ô÷0€Á\l.
$1]xäùÆ1–ñ¦ð¾íÙ=f<ÚZŒÿ¼ëËïê\·'f€Ðèý~L<%“~Þ°òfÙN0€”ÿމ=F¦¤ºG
àŒâüÑÛ*ê7<W†J-Œ0>÷¦§öŒyù!w5TÂ,b"p{æ™ôÒO®ü£;ÂÊ	©0$ð_v:Lt®	ר_\♌Œ`
‘°™Ðã4 ÍÐðGÝÀÍn£©‰¡ÂûÏ:Å¥†TáVrF0îÞÕSh˜bƒwi6q´0Ztê# FFösàÌtnèR~‹)`€¬qè˜gS¸{›£$;±K÷ÛlGDÁ¼k;ì& Âb’3ã+€Ú•+Ò¾ïþ~DNñ} œ`ŽS.;²¸¹ù¦ôÜRijŠÉY>j¾¾˜˜,¹ñbeb2†¿ŽY.}½ºð?ðJôètVyÞÍsÉ>üçÀ‹¾gçÍÜ3ùôâOZD×íM
¦ÅÍ0lLKñùç§A;¨Z
 >6z¹êBKKlšNImd¿„\1½Tœ¼¦DbxG—5”	õ/ó"×:`þ»ß*‡Çï?â'«â3w™9irÁ»²À¦P(¢P
X]Ø'HfâòºŽ‘çˈDìÄ5º¨¶ñ…ÑÜ€"8Èû]Ð&®ü‰yófFæâ<Ã2™¬“óìnHb—Jï¿¿cÇ~LžÙî1p´•ô&èh©
¤ÛܦµÃeü¯v¥~åÊΕ+µ+{¿ŸF.R·sR€9Îìâl¬4ÍqpÍT{ê°LÜ¡èB,†ŒøêåÁ‰8ÈãôAQíû¿ŠN¸n¥²ªÿn>§rëRü§ƒìÛb½åÍÏ÷LY\Ä8;ìä)×vt™±£ HŸ¢º•ö
¯o’ÙBBЀ÷ðÚäÔÆßâ\å£bWAu1{¬X,Λ]ÞMj|?0sn$<¼¾ÃY>[ôþÍI<Øèè(Ü£X`qüƒÝÇ!k€È'€çÄŸ.è×)œÚÀÞÎû$&>m$‹bç¿ëé> _®Ø£GúÊÙúÎ|pý~p@àû3†ï'gÎeüfAäè,ÊÎÓNÙ)/E ipš=5uÈV–'D”™t£RyêfLÓ„Y˜3MøTrdþ¹U¾Z©Œq÷VEçóy†µNi`:"ð–¼Ö|½·©To™m—˜ý<ÞsFÿ;âÚâ5å¦)nÊ€+œ)`È&hn¥HÖ-]ç˜T¤KµÑäì`^¿Ì:LsþºÛ<Ö÷ãr{3×Ó0¡¬wM&|}Ôcè;æ-ì‰P忎àWaTŽž# ØŒ_ÓE¿²ÿðQß&	@¸ðk»qüïmø>Ñj%ÑWΞ={…œŠüÉÐJgðýÐr%XLIƒàïŸ~4€³¸´¸H“ý(4ð?e³ÿZì<5Ñc¿)OöY' IDAT.Ü÷§§…ŽˆÇEcàã¸è`ÿbð黎éH\2{êBM³'2>ðŸ
ÐaˆÌ–/k™”‘
@ö³
=Rƒ“é·äz>²hW`>ŠF³~^q#¾õ#x Šú1ˆè'|~£?`Ø0D1À¤,¡ÓCuÀF™(z£Eoaa?°,:IØÂ²BR1²Ì8€FGŽ„Û)…ó"¢€þ…äé¾.ã¡ùa ~ölý
Û¹RßçûÁ¬ÿ0 u”8³K‹õ¥:N‚2U²Ý©Ã T²±,UˆP.*•ŠH€_K0€À¹¾‹ñ òVƒ'XÀä\aàcCâÀu§Ó?j,.Öë±r.pZ”DÇH­g¨Çž´ÿ7Yìa!Ææ»Le§
ÒPÝÄ‚Æ5¼H¿õ£nh	Ò“k|uÔ«zÆ0h­7kH©ðf`Ø@ËÄ	8#M%Ø5Öí!*	À>(ÉøuGs}?-üˆ…V(4ô9­Uæ‡.À•Ú•+g÷~?{fÐa ÇÁƈWâßIük\hç´ûAÓÇz£(5ɰºv'\Ï`z:e€tD³œ{î|}ÿWmŽÐ/Á5Ø›|¶AÓìx¡£+zÉaO+µÌ*s—@—q£I&Ëg?"7\€D1®çô\<#Á±aö‘°«žŸ¬8ÅÿöSØ@;kY3›kп0ÂjXO5žÁ³D\¿ˆv|xæaÿáÒCGz;õú•Zýì¾ßµVªL "“ýgˆY‰¦ÿJ%áºSSaLPΡhÚAÐûtø¾O=M¢ ²–«&Umêr¯æÒ?òªÏÃEœÌ¢IL9‘ZÒ€v§ø]ÃÛ”åB‘JvCQ´,ºxÃòZOá_.+Àü}‹Q6÷#
 ÷ëïÂtB6aÉÄ ]Yñú£Åý@&kÈÙ(EÖÉ¢‹#ó€ð„4œfÔ“Ùú‹%€3@!é/	€[àk¾¦‘àW(˜ü~(HP:„ÞÊ
œÙ6;» g\p°äðOÉD!¿D†Z²‚RŠ%%`A“¾È @Î^¹!¹JäÃôôÒO^OõúbO/!zqYؾ{3¬h˜âŽÓ[4Ùm¢Kh—=8Ôîæy²õÚùSËŠ0ïGßêÂcÔ?ÄgªAèi/>™¸aˆÉÂöZTÔ*Š££EØÇèèè>Å2ÂÌdyÖÂÕ˜Sè–	7bÓ”F†Ò“³½m„Èç±@'š,$½á·Û~;hðã¹í•+;;W$„ß~?êìµøZª/,hõ…¥xÖ)¹n	W]×\×=2‘ð
µT˜šŒÊ™.ëuIbÚS„;=Md›Çí­!ñœòɸ.˦…š„HÇ“N"6ÏûØ×=e©aD6(1²ndÛèú¶ÔåÙ»ƒÄN„(\ d`Æ.П}K¨—ª~W
B@Æ
Áz†ˆ¨@žJ½<*ÏÐ?ºþµL†Ã?ËÄ<¹E6K‡ÜœÂŒõú„ ÝŒZ•‹^2Ô\j z¾¬è+SõõÑ͸b\Ñ4¸Áýíù~˜ªøU”ïOÀ9ÓB›š¢d`µs–¨†{ºÔX8‘/M{É=
-ÿ|ÂH¤1¤c]ÊÁ¹i¦ŽGt¼Ùƒ%Ú"#'¯óGïK„Ymê}?:º‹/4­§i…H6ĉ(%ùòÃ:Š„ú¤f=ÛÈýóƒKmEo§$¶9`J~Œ^Þýýì÷]övèpÔŠGBÈ @Hœ  6弇²’ß_Ô›I!B"½ôÓñ¸QÂ%ÆÖþé¤;cÇGVÇŽ¼ ;îè¥~ÁYlã)ιÊýݽÏ
çXÌËET@×”«ì.˜}HÔÌìisZ(zÌ+FmŽý6F.Å»ªYèîý÷LåÓÔ¾ˆ6ïàatƒ¾*;
kØ,í1’ŽƒbÈ­
õÀä%»¶µ‰Òò/Rdþ½}û€ þ£žW8~äÈ‘Æ@¿=e³×÷GeÈrØ8°§{@O™l¨ÀÿtÞPÇq†ç›½ëší^C¶*ÿÞ´¬¬i
eå‰xEF‹ž¤¹,!-ئ×}ÕæÔß÷?‚NpZSÎÿÞÏm.whäÀ¿0͈DØæ5¡ÿÚ-b€Pø«éuŸŽø²Ó™X‚«äà¨ðtžÛv)_Kt¿‰àÿÃÞÜjð8ø?ÿ=†åÀì{¯}oŸãé…ãÇÇFFAÀÏêØØ>A	d€©öT¯ОËsõ"˜!(
ã\N3Ò"Ø÷n¸†®¨pÝ¦Md€iêŽL 	£Ýh°ùØ÷ý˾5*Ÿ7
k¾8_Ĺê¸ÓܶØ
ˆìf;X©k†‹ûù1:{ÀmÉâ¦sîN#þ5µ:œ‘“*„{š	y7gå,¤€óFôÿé«À¼—Z•Z-¯eÛ	ÄO/ütD–Aq¼d?D zMÁí÷§Ç+ŒMâÚ$ÅÐe›[lõ¬c½»ÁˆgÞžÇý, Ÿïî+Æ
#«^alìøêêX(£»•žs³Ý¶Û+YúõÍAÍ‹åeÆ–W’º‚¢×
ϳ3„LE¬WêšhØÍfƒ7Ôí˜,¿hoü›MÖà
:­"h~d`pd0›µæÇp*£)p‚£ÝdÍFÓ# Ão´‰ð~—Bj»¾oUœ£›¼e·¸ÐÂÅü¡9<—Qò£ÍqiWÅqÌV“*$JviªxSv¬p·W5¦¥—:µ²Û7ìd¼¿²K^7Mvu'Sç±k‡Ý])ÙºvåÙÜlAMÙÕ`DOtÃÓá:Õ¿G 'üT…gçøÇc…ÕÂØq¸)„9¿¢§¿M½>åN-ô|ˆ0E	kr¸·øO®íç=¯E=quLÀ?’O·{ž‰zLõÜ4€Óó9J˜ð©f ©]]!ÌŒÍk~~Þ²€²¡9§ŽéMüB}ë€ü•vhö><ÑÀ§£ªBê.àßXŸ^Ï&w©ã8œ‰–0ÚZ"²@@`€nmÇXµ<³K^#ð‚ eç¨çÎUÆvÒk?8nÐ5qƒî’Éø…ÿžeodÃŽŠÔÏ€1s„jW¢ÿ4x~BÔîi0äóQšŸÞ=¯ëçüç¿v²Á¿à2ý	ÀCè‡?ðTsô-&§{ß]pÝQ÷õ…oÞ#wà9qWoàØgy„ºçMËçü¹ Xx
÷Ò•÷ü+Ý.Þ˜õN§^™›#ôs­®Ð…â¿,kD€
ùÔ?z@ æŒÓ²2Va~0Ùà&Ó¬«¾"øÛØÐð©•ð
Ô'³mùµÑÜu{lñÃQàí0Ëé‚g¨ù¡@®2Ì@œlÛSþFÃoxRã]½²så**€4$˜rÿqÑs1Âÿfîs@"˜zйhÕ]*¨ €õ®ÙÅx]´êíy~¥Ðcp7’)ònÖdù@Úèîy]Õ|T?@á*½€°:R8žЉoT€.×Ñ‘ÑÑ…?t‹õÑ?|}tdd”B‚²ø@E+<ø¯|OYáŸÏƒ§6þ9f·«gÎÃ
Ü1MVŸœÆ¢¼¹9£èV
¨R¡	¸	×çô«}ù
<²8TÎ7:2ÆMnZ™ù¡ÁÈÓi²}ü퀅iÒ¦©zhÍâ(þ5õ”ªÞÈ™\SÙÔòÚ"vññÎJ[ù†!6õœ•IŒtÊþ­©àߟ*ìêU¤¨«,L‡
°iÚ¹¦†òÛí¿ùü½™_ÎüôÝwÿèva}%I ºfD»—Òf;t(ðJwÝ áþc§Úœëæå“Ýï±óç_’л~°øw	¸3vü0Àñ±ãcž·J0å9²¶€*~þ#£#ˆØSQo-ä(6
>¸çKéoªG_óTû_É^˜Ÿ§Aù6%üÿÉõ}´¤Ün
‚ Ý#ï ØððCÏŽÌsP|hh0vbtµ#Û0É1ÒCéF—k\
],œ2­œaĬF›„|&˜*þWN‰)3—³„l›&T˜€þ 0eÛ¥)ú²½Vø¤-%€tÈ^ö€®EaGÝðØ{€ÿóïÞ‘¿©f­FÏF¦®Àe3J‘monmnnm€«žÕÙb=ð¢0 k0W7q[0²€M€mÁÿ++¾ks>vü…#/€PSÕAZWP¡Tðþpô›#÷ðÁè.´ê,¾?–Ã
6å '˜C@M€~éJÇÄ2p´9ðx”›Û$‹¯E=K¹~ðü†
‚°1M·¬°	ÞÒl‹ØðI¯è—ûQVu¤˜4Ém;jÀ4¥Ñ7DObÛ`¢Ç¥Ðb•Ë™‚«.ÁÂ'ñï3UŽ…ø÷ƒF@³v4¡²s5
¦#œ	휈ãqìmd€³wo¹úvb–Z';¥Ç
BÿæÖ–?æ.yAÔ`è¡Ë>4¨üΫ(=5ßöÙ‰èpäÈq­0Vˆç)-&1eP,.ŒŽÜI¢#.ˆ×
m1½À”À§ÏQ$v—ú0å|«Ô+ìÐÑœÃ|@=2ÿ°»Fˆ‡á_“>£€¥FàŹ^ôÓY€tă˪S¼¤Þ¾ù¶Ÿs~¶ž,Ãz“ÿjºMà¿+±Œ$ñŸ±ÌDíiWïêßC;¬.o€®»¢ð$1vÃõÂ;r<¶ñ"Y¼:º€øÀM(b]ª‡/zÉyÀ€s/$€.Æ/Ìó2€‰€@¢! ²ÿ˜®KÌsãiØÑëÐæÆÜ!2Ê£óTt·8
”k'#%þ-©"|Šø‘9ß¶è8WA„O醵Ì\‘t9—H¶K£„個êý#u€o‘.MÉÀ
ð;ú¯¤4€+©ƒ"
@&YhŸÿv符õ¬â©õ ´þ»
r<×K$êéB‚Ñ
ðÂ4=›Škÿ8HKgℽ'à…#cqAK0A_ÈYÀÄùÉ(9ÇzøFƒ (¸6¡Þ=O퉺¯œ§O€øoÌáM³É¥5X8÷ïÃ9A¡Á»ýË~{n£
øß .ÅœbQŸ	=ª,jÒá”WŸgLNºWwvÞ—ð¿®/[!ýãlП`#2ú 2™Ä˜Šœ“tMMÂéšE°½Âa›ncF!¾I§ÓšW×#¿!ìoÚT/×”FC–Ü5IÖH.]×Ó>Gö	ÁO7qsÓ4â.òH£âêW®í*ü{…BÖ{á…Æ´žz>…æQXþ?RÔÂÕ´ÃHïéFí3Øî ¹¾«¡è®úyu$HøÑëa3!þ,îow”=Â{ýDÿ‚0j’Œ^&(t–zΧù!mô~=;Œ>9l!qo'ú!¤àOG<*=äˆPVgÏ«[twïòöÔí–º]ÈÕïöî{‚+W5g™AG\Ä8aˆWÐ(+&t¬L&Æí#ꉰ×CFw’VÚ›”!Ê=—Üþömγz~Vç碕‘A«xA3ïæŸa,®Gߊ:k‹Õ‚Ç4ëÙgkg1ð†íj™o._æ\–*i=" Î®!þ;SA‡g©”‘ðU$RTŽÆ–È0tff®³ìÚÚÚõÝW7f.; å)óŸË
èš–9Òe™.lŸÏGÌ)~xw£ÝÈ/ÜAÈ<ó5v2Ÿæ™gL)Æ'*€‰	v	¤
ûöÎ%à…WŠ3òaeÿW»y\¯/¿š—ûß}<$ˆð¿ëx¾ôn¬¿QC˜ëX¸¨¼%ðòøÇÑJç»·OÇ/¶@èTH€ú·–WÜ“cuukÄ?Fæ-˨3qzžÝÃ6ïôâ<‹VÀ€n0»„ÙèÔŠF^³ö:fxϸùi7¯Ö£o
ƒ1þ³Ì³‡ÄÆÆ!Œn€g˜§Æe®š&û‡AµN}á¿Ø¹6…K”_³êr19 0ûÆÎ
~c‡/2C§_k3××nâíLô¡ó2ù&ѧoiÓãƒ(´&}€d~€=}é:•Ûe­™»þí¿G8+À3'OÂë'OžÌPa’€*`BEúw¾Í:—dmìäjç,“ϸnת½Ç‹à%&õÑœ`¼vc›Þk©äÞÆ+ܽÀ·Ý||¼ÞíÓ‘2køl‹bZIËt—WVð’шæ, Ó˜_¨×þÓóà€Ø8=Ÿ1å’
Ä%pBcí‡Áw@fÞ+}ýë¸8u´•™€‰‚çmdƒÁì†\á–òÈ7j;QPK*\9ßW¯/üat®•®acq8Ð#Úasþ&ãœëÀ•ÅÅ%²ÇÎZ¦;™[á@ŸÈj<›g²x·ûnùzkÉŽ!]få¬Ü@I„øÇÕ}`ûîÑ_ "s¹µ™ÿvãƒà¥vcAUKdNžœù`2ßW/NO½
¾Øx»äñpA2LT¸}£Æhå€ÔT?³
¿À.|Ü…ÿ…ßî»}:žôQ«`FX@P#Ùoa3k‹¹V–‚€fÖÊYchœpð®´Ó%¸o¡ö×±E׿¶dÀOÖ¢LÛyVòš‰‹?—ÓraK¯ÐÞØh?ÈnlPž›fb­=eªs~C¥ÎɹxÂK‡ü»“ÝÅ®víÂ
™R?GÞ?››ÃdYŽËðr¶”ZÄ ~ææÍ™›Œ]’[÷!Í1ú€Ýr¹Ü=ÛZ­x«'dh>gÁw00`庺*¬^:Š!ÁKײÖîþíÆ¿¯/µò³wd,¿úŒ|œ	À¿ôÈ ×;w¾}GG)~'àöù£9`Ä`UÍ
$ާz|j?¿ÆöOhÂíÛçdæ_3œº>Ào·1Ýì:ßt<áö#€PA¨Ђ¬œDÙ²$d
žåÙºiâ$Àé{GüHóðƒêß4uݰx²ï½Ÿd€Ò4»IÝñ$·tîÕ,5BŠ!*€ÿßÿ¥Ì¶d€Ý盎t å¯( ]ã,¶¹£nVvÁ°P·êøÜéÓGççç›góó"câº÷SÆué–²êZýMƒÿoÛ¾lÉÊØœÑ;Éßn·llÈÅ0Áò³sçø7v´°†ZfΦ#Æ»þ“ãxÓEá?Áœ.$ÀÁâƒSh×gª$üo^šÁ“W@0ñêãUê•úÛÝÖäêzt22€ºÃ®_ª’IýÅ%rÛ3ÖÚÍÊ•+/ÎÞ	¦_zööÙ;ן‘¯Ÿ<‰A5ÕûŸ˜˜âbòzçι=ý…ïç6ÅãAÑBÈ®'ùÕU´ÿ™ÝÇ£ÏWƒU5Å·ûxQðîç:‹Kç%K3†òê~˶_,
öÛíý¶O¯þtÔ”@9-'²C&v¹Ç«©žÍfLŒdAÔ™@ÿÿ4RÀ⼋K_™àu£À!¤¦òŸM{_÷¦í¹õ YÌnß¾Ýs
Ù©6{жHésœ\düÆNí†&seEÜPhÝîD·{A›œä¸€vÈ\0—¾38pÙº‰„—K37ãà7Õ¼ëí+H$ñ%Àü!§«!_’}÷o¾|Ó­\]X˜½Ó~vúöìÙDhíÚ<ù'@8ît;òø·qFŽšŽK~ù]K{\
‡éÈ»ò¢Âãmoþ9Ö8·”¼t.–ÿÈzä}%€»Ïöéx²‡PPá5¶ÞÎ’õwérÉšÔÞÓZ¨ÓüŸ†çïe.p&™˜X™wØ$Ä01/ˆào³Ò×§¿^bþzàyñL·¸->÷¡@špœXB¸¡E‘²8Å¥;1..`L4Àx÷†ŒýƒÐÞôe{2p˜ÏNÄ[!þoFûäóð2€Û­T"htMÀ¿Yb´l^ÿîàöÉç¯.-œœ]zvèÙgÃ×Ožä	êK”Uˆ™ŒQPmG~²ÄP„³ðzr±ŽðxreuAy"oû6²í¹¥Î"¼âß
dœÁB	 d`;I!Ñù¦ã	'M(P«påH4äéO=¨¯3«¾€Ð˜‡îÝ;ÍŽºx—B¸¨HÌd6-hI¡@š|ž¶§m¶>×ÂÕªCpûc–ìó‰€A¸¾F5´`ÐøŽÐâœý0¥_t'¤Ð¿qáÂä¤%mN.+Ž‹tËÎ¥ p“ã£ÌdåG `ñ§		 ¿±káÌK–¿„p§ò—@˜ÏZ1°¯Áë˜;!&d@PJ`|ü;öí;ñgib—Ñ¥¤€íó{Ç¢j-Ö»<»:Þípªd1ÎïÕå¤Ô~
5Ýo»ÝÝS’žo:žô—…J&0]yågéOÝÌÎ#ô
„’€Q€¨×‘d5¢d@»Ä°%-E7Míþñîº?ÇZ,Ô ØíäÕŒqy´³êz'›@ãzÜá"ªÍ	€Nöä8ÜÄ0Ã\Ô×§†{tˆaàú:»ëƒ2j@zøÙÛ¸‡Ùaì]dÊ‚œÑ‚´¾K IDATS£í/¡ +ƒØPîFïëÏ¢&Æ/M"öý¯]ê©¿‘Û‡>ºˆÂ€‰×ó{®	ÎX‚âãÉ`¡þ—äz¤²ª3ZÕ@ü6þ {Ï7© —Š­¨KÃ4hQ*µ–VÖÂD+kˆºd€ùÓGÂu!N,0,ƒðqÀÒ4M÷ƒ—É9Ò`-Ÿ…©)p°Ûû£H@†M†ÐCÔvDÈR9-ÂÒxwbbü(!&%_h¸ªßèþ9Y@ç«5UPŒÂdâÇ5-ÙÉ=ì¦÷¸‡»
|7àÐÚg{íåµÈ”>k°w¿>§ui|âµ×.Mªúå]ÇW|Ö§åöžßî÷÷ÖCìzò
µ”,…À6áØDe€°]e/é¨Ô*òz7²Ôà"“‰¬Y™inPÝ-0à_›¯kÚi™”hê†Ä¿
€MO—¦¦Kv¸Ü-ìa!ÂtwY›ôB’ý„Æ¢fQÄû»]´]7˜GÝÅY‚%–5WYÔæHOtˆÖZ>Ÿ§äóŠW@þË#☃¦…þ–0,UÃß³={ymÉ&žÖ/ìÙ¿˜¼¤%Vß³½tÒe¸Ñdbïöû½?îǶ÷ý,ì0BsBÓõ!K“I<‹ßn³b—½XÜût¤#æe±„Øã1Ѝe…óóx—Úiv]e¬6MU@Æ¿dsn'6›K¶äØ7‘(‡×ÑŸ Û§7vÇCóh+)^â{âœ{>JÉû†fhá7 ö©E\ckb60ØÚ»ÿKb2Ù«g÷ë´H°i0ãÀóÛ÷[Òö:=qNÍb?¡!KÛÕ.!	÷÷éØ}y=¤>œ°•ƒÛK¨zŒ:-JÉI18Í÷÷^õsÁ/|ãæüQSpG?_eïÝýð3¸[%~Ð…&ÂÖBÑD ž®¿ßùŸ[Z:'£çH,œ+µ«ÝþXÓ8ÔWÁ±}!W·&E!dË$ìLš&ÇùÑùùøf~iq	¾˜èfñ왳gÎÄ7g&.\€4.\½zá*
ùì¿þƒ?€ÿšöGrÕ/ŽË—/·þ_öÞý7ŽëJÝÕÕU]]Rõ‹]ݤivȦ$7ÕfD5›mÑC^Ž#Z–B%dà9ðƒ°“í‰gÆsޝ(–
ƒ˜IÈ‚
Ÿ‘	ô²áŒO®Æv.`NÜ›™ÎA~¸þa~˜ÿ䮵ö£ö®~´5yÖêçfwWU7ëûÖ·Ö^{ïk×Ôýµ|­–ç¯äÉà+Œ%'tb$€!ãÈzôWN©¡ðÞfíüù—Ïùœ—«ŠææØ]v×V`Ù¯~ôêó¯N­ãlŸéð“çRë)d€wÂLšwpÄSqÏmÛ7ß»IÒwSJÝ»¤q5ªYí=þÍÍÍ‹ù$^˜H!òÓVÚ±nôûŠ즜#{3%z4%	P~)€Æ#¥t ™Ñ×ôgü×à¶	 ?/à¿	·3úo
øŸÀ¿Å€ßü_åÀïþ/pà÷Ddq@»v
àŸçÀïYÞXMNéÄbæøsJÅaþ4À_ð-6ü77×Îß<¿I}«b¦;>«Åà‚ò±h
;õÑ?~ô¼º:… óÀzåÃõÔ§Ÿþ šÀVÆü
ÌëOßE§ÿkTßB³ÿ½§Ö)\]çBüøÍñí›çÿa§ùMJܼyØàæMsŠÓ¾íÍî|ð)ÎÉmo2åú ëOá%BDèÇ	ÒiD¾?^ùüxAäKð“€;~Á¯~O=|O™dy„?‡>g§%öÅáø%ÔHìÖ;þNïF4\µ!–°À%é7İòÍókO*¹$à‹e­?…îyŽÏ=õzhÃ3zúÁ¼ú?ýèÕÿ´>
ñç·¯øw(p¼î“pÅb—ŸP_¦
ß{Jô}]D²¹IOï¾§Bâu#ÄÇ·—¤löÞMB>Ü¿¾þúMëîMAŽËÂl”ÿ¾Ë>¸óww–ïØöc)“lÞC"îhí ,yw`Oø…@ ð€@à"	€ ß’øÇ€nÿß›'è¿ ñ?/á/#kú2¸V#èç%þk¬
P©…ɉØ(@ΰz¯¡&ìm¨H{}c}µA"ûÜÚ9`[ÃÔâ¨NRuÊ;yrîä®wóæûàU¾{ãÆc€ÿÕÒ;•×ÿËÖ‘¬LúIþi\ICLî‹_¹{S„þ›ÿpq
Ý7ß[‘ýîìöÌú*_/;6¾½Šsƒlž;‹‹ï2òü\ÜDÀO„†¡ºŠlPoÞyéÓ
¤4\ÉâÈñóøßâ
 EUO‚ž8»FÞÿ‰'Ö(	ÇIÞÿܹMJ|ã›gÈûãg(	 ¥?ׯª€`ƒïIéÏu@Í €šBþÓŠ¢@­‚J!a€Äöϱñçz	lCÅå ºWùR›pš³5¬b)õn`oݽûÖU\Làƒ›¼ùßÎ?{ápøOÿ%’©¿ûÑD²gáò4­Æ¹¹‰Ý„ï‰9¬ÿç.Bp÷½÷VîÞå#ƒ6Ø3O=ýÔ3lãÎæøvb,%¶¸à@)€@ãzÃz,tBùmoÚwî¼ùÁò¯ïo¥m)Èýc¦K“¤þLJ'€'D€HçD€Hß>pçÏÁO9ÀW#€÷Üùsðã}pÍÌD
ïáû׈Œ±͉ä4O¬¿ÅÇŸS¡1¾ÒõS¦l½„‡ ¾>‡š4€Zýkc•/ŸA˜Ç?¼õêØ«oݵ4>¸yóÍ6A_¼ˆcô@„¥ÊÊê`€Ode¼ÓØcàôižî?‘ñµ2Týï?œ§@^̺OÇê*-ÙkõŽo¯rØÄ´Â{ì¦õΈ>6à‘KB[Dpçú37?½c"CÜÊßϧÛäý2ÊpÀµÿšL¬qí¿)›\ûŸ‘‰€3­–ôý\¨H@è€^¾Ÿë•à™ÀêÓÒäóÒ÷s@a€Á,d	$Ö×bãÏ-¤åX4f—Ö	ä
l¬3@ÿ@°µ¨t¯C¹Á»ˆ®¾ú6>øÞ÷V¯mn®§RÈÏ­†áfà[¹óá‡wþîS€âï§76H<ÍÖq`[Ô€>ÿâ]^ð-Ò‰ø_Gˆo·@Б¬CÀ¿ÂDÑÛÝ»ˆÁA¥Bær™|×¾¹ñÁ;››ö×ÖPõS]	óxoñ\ –Ùh€¬ñ€H<ÊSv`àψTuJÔSWÀ÷Tþà…y•ÿ#ˆÒ5º#Ô_»¦â€ü5•ÿ#àÀ?‘œÜ‰íi½ãÏU?€\œ2}ÞõEÌœøþÏÇÊIVW×94ç³o-¼…3
ž$:¸¶úäµkëäƒn€X	°Zyý¿|¸ú)¢ú4ÖìNŸ¦ÿgןZvYß$´Ú<ýž½g‹ÂU±¸6N9°Þ3¾Ý*±*Mбþ£à¿àU~”
 rƒRH·Çx]î?¢‹ßظþíg€Òl~Riä즴ÕBæŒJ€4Fÿ¢`í,ÈŒþE'Èžóç0úg¾ùMLªBåú5ø^Ô8¯ºU'€k:\S€"	È(¨õD‰%6ÔÔøsœLÝ?ºˆÿÅu>…ÕÆ:Àïè>ß§ Œ`c€j_çñ»¶P{úYd€…µ›«•gï<[aw>\…¨žà4 /jiÁÍsrëßó7W,FýŒë9™Dýÿb|{©„
R©_\¹›²îþ#¹oJ`!P®…±PöÜ´®?rýÛÖ&û„i=€)!,Ù	2RœÎò4€è¤Î¿MÎx¡Î¿3œ¾Ù«^)€ïÅÀ|MxþAS5†è¯H½Ðÿ_í'g{b=øãÏG?l þ×q>Ï
çÖ ÌE„êƒÙUWÀ†u€Ü»'A´ó.AÇYrcuõéM¼{>¾yçÖ³·NŸ¶WWù¼ §OgNS"PUµž¿(ײđÂëwß[çÍU\`[L9¤E2b|{•¦ƒpb°~ó=ÀÿG‹ã5@Š]¸ô…a€+rÖ£ë׿kLhÞúy6 £ê2LPà/‹ή¥À_œß
øÿ”>
g¾Úà뼪Ýf2{`ý®%×ëµxÀ¨¨ãÛQ”Xê™o§ØÍ»+7×SèøÉÒÈ)B	nèÿCü<ÆO={ýÛMÜÓ&ÏüG™Àh´NŠŠ‚9ö¹@„ÊMô  òß=H¨üψ$Q rß35À«¢@å"ïOϪ*ûÇû®‰2•¨V*ÿRKÀóHÌ´žñêxntcgÿz£Q¢¾Áø‰MÒ»gq±0-3ÝÎ!¼å¼õ÷înƘY#}ãüêûÎ;½sçS>î»ÙbñkÆç¶d‚ÄÚ˜O?û´\àÛrDݠÂØñ}€ÀÉ @¸‰ë኎À²uóîÝŸê¥À!JûoaûOÁ<Ë
‘Ã0`«ú?ľ óÿüŽEÕ@¼(ªâ@Q5PKKÿ‹±<ý/jÔ@Q ÇÿhJþ‹Z@5@ÔÔˆªÔ0(	PNÎùÄvúާó›0ß°Ç?õúŸ;wöìY,s¡wQOàެßXÒöwßrl|Š×M‰n4Ûs#,•îX?‚Ý,Èa>)=ë/×ÂÅ®XðÚ‡ubˆ”c"3°aÅ¿ŠPÅ‘È%ˆªj¬1øë§?ýi4A‡‡%‡Û?‹$Ä'ä2exæ?Ń¢ƒ”pÿ)‘
ä¹ÿµ³âþ,Ïýož÷çyîÿÌ7Åý7y0êäÀ(àÀ¨3P_
Re¢(
âd€•€NýK‚Ë`ÉyŸ˜á;£Ç>—4Ò¾!jþxÕÿæ¦îªÅkö66x°±J£l­Œƒc|2Ž6…­ÆÛÛÕó•êjWîT+=ƒ,©ó7O4â§×ן²%ØV@áß7׊=qbØG0nÿa@£¡?ì‹
Ê'û%€ÿM÷3^-LÂëÓ©éIAžG÷
ÿÓ&|ýñ¯Ç	`td49Ñ ·û 2
p—¬!í°n§ù¬Á_Zõ¡¯ˆ‡_‡…‹°N§à¯ò‡vO'€¯<ø•¯ì“:©ÔÒo[NMs+HHá2
ŠRñÝ<ž(€Ä`U?“:vÌHǨ@¹:àýŽ“	ËSãPö³~6ç;åv®Lçk¬]œ(á6ÆëEþº¥½žïÀë3Σíñ¾ÛC-ÌÛ{ìÛ£££ÕžÎú3ÎÌ”ÛÓÔ^\9ôüâ¢|ãbC}¾“oàö€´íÿÛ¿éÛO•ï•mÙ~ð+…iÜ?>bûv»ýâ‹/~ön1ŸÃ¶ë¨ãsúïÇ—·/oÃõã­íéõrÖŸœÄ×Ëb¾Ÿ
ʾØ?|7ãû¦S騭ýßX_;–²ÓU[ŸwrµV]×ð¤Y&Ѓ†ÔZ¸¬…€ïçàÆ?AýçsA®\.D›C/^‘^‡÷–ÂR˜õ=NÑç‰j€èø£Óœü.ÌÓmž€|V4ãûÇçßïèmÀÿ¨_ŽÚ3>8ýÀ¢
ø_ìpX”ŸÐ>ŸâÛOEÛoÿÛ¿µ£×Â÷rjûDðIí¶7;;ûbµ‘Ï察›—íËHtù˜À/àÇ,îåû~>œ-øÑFз—N§£¶D~‚þÄ@Õ²‹S¨¬­Öj£½dòy-G‚ç*kÃ3€œkp‚f)KuïT.[¸w•ÚÞ„°"¼?Ëå0ô³ETÕVôy®ÚŽ_ž™Ÿ§Ï—ççE·y‹gÁ¢÷§ÄöŒýCûûßÿñ¿ÿý¨=Z&íé,øÿÉ&ýijü¥-ªí]Ô·—âÛO‰ö¿ý›ï·Ûe¹B‡÷ßs]W¼ŽÀÇ÷C( Àì»ï¾›ÏýÇ;ƒímðü—û#V(‹÷ûåüÂV¹ ?`l/•JGíÿó‘‘‘äÄOL„Ô»oUÉ4@õâÚúÅUUER©¦ícÇÒµ|ÖZÆqÇN×&ˆrålnÏQ:ž¾õ|îÔóW•À	 ò÷‡å<2€}ž ßÁ6ÀT:½œ?*€R¨÷‹ ¾lÿûZ{´Œ0½>ù à¦Ü_Àëwá}~ŽoŽ·ÑûcÅöéu¹ýAÐûEðïy¹Çû¿£öÇÛ@ð1WýÜÄûË…­í¨
`l/NEmáúé~DÌcÏè’Xb üΰš`€JmÕ:qÞN)	PɤS™@­\WS™Œ“ÊÔ&&2dýCÙ —“óy€~o¡õüóÏßmL`PàgC¬Ó	ävŸ@¾CÛ›)Ëí™ÛO©¶LÄ÷ßÛ†°yTµ§ýCbåL¬ÏßhL4ðn¢ÏëX]“ÁÒ\|Ô^Ÿ°=;•RíT¿×Úîh&_?ãœùÂÛ‹·wœ…7™"E<üõ ‰fû½ÿ¹öösÛpÅÇÛÏ‚l°¿ý'Ù¿ÄöјN;ZŒ¿j¯»¨óa–¾:ý.?™NÙNÊcTùë8E~¾Qí¼Ù øãÕ›è}Ú6´mhÛý>ß³=+Õóúüc~·Ï÷¶Mà¯ïfv÷ýù½Ú;NÞÃ"ˆ×³N&²Ù~ïôo·9þŸ´ý ãøûÛ¿ê P1@b‰ø·ÓѽÚÔÚÅUÚRvÕLDs2¡“IgRø8á2™,¨Ü\6ãðÐh§R
¯Q'è}ý m €/õùÞ6&ÿ(ÉìÂë»÷kû;;²]l¨×}¿ÍÙ~ïî9 €­mƒ¶ïÓç÷³ÿXî/9Ùë›L¥¢N€Ú:ÀÔÅ5Yd³J%“’CˇÙk¡=µ&Ò`èÞÎÂù–ãµó±6¯ù!ëûúAÛ”3øŸïÛæpÿ¶·6vÝc‘oß×þÛÛ÷eÚ9qÿ‰õ·õcµTjõ˜|muõâÚ:H€©š€x¥b¥R•
1@Á$ãÕ€LŒÍÍéðˆ<o§x0Aî¿Ïëm|‰Ï÷m«À}ÚÞ>ÚAP‘ß×!€Ë}ÙŸHŒ$î?± N›õš¿k­OÙÖÔúº\ŒÓ2ïµúð¦€׺^®íeø	ksÀÞ×Ú&÷%>ß·Ý¡®Àû·½ý´ýóö}b€çîËþX’Ll8ü-kª†ºqŠ€S¶×kŠ´q³„üúì¸À3Žç¤2ÚR4"0ôý{oïË}¾o»³Ö¹ÛÛO;Èz_çyÀû²¿ÿ‰íÉ59§†@¸¥5û¼_Mª«–ÎIi«éémá–¾~ж8ÉïÛö~Smßûµì/É&v͉sÁÐwg3¦Ÿt2ñwxÆÕ~rŠí<~|«ëfÛ²†lï~çÁfÝè9ú }¿ÿC—ŸeûÂ¥w.]Øn_qi¯vrN'¶›ËÄ£‡ØÒÆ)îÅÎx/Î^`l°l÷†':Y8qêÅãêд-û>ãÿ`nõ|AýнötûòÖ½íwÙÛÛ­K[¶öj''ubûÇËŠù×8åô`ÿNm“AÊý4wüØIo­kxÎ8Þ¨3Tmm“oôI¿¬X9ÓzÍ	¢¹1Ó£wpo\›Ø¦æïãñ·Ú72Éé‹j•/Ük_ºôõ#¶·/_Ú«œÕ‰
8]ûàÿ-í]íõÿ^`L,–ñ=ÏüºçÌsÞϘø°ŸYÕ'íË8Žc€§´×½Œ][Wmœû>c§Ôت¥=
~cÙÃˉâßêÁ´W@鲯±_³¯V1œV«ßn/ý?àã/Ü»¼½uáÒÛÛÛ¯èíù>íä¬OLâÕ3ÎÁÓñ30Ózë=í\\_í9G3ænÅBþuËÌdÌ
ÀþÍ
>³nù`€Q#§ðìÓÚÛžq@vÆ·Œã±:`öºåEz%íáD¡é!{­jÃm½Äð_îÑKº"°ö"cÇZµû+-àBu«Ø¾¾}ûíöÛÛ—.]xeë2o_hoõ¶“ó>1ë.rµÝé÷æ´v±´¾?Cía>¬ûCìí™XÛì€Q,pñ¢lÖž­ý'í™ôhÆ ‹Ì¨1ë¯cºX{ÝNk!¹—Ží]Ë1$ÁD-þƒTõ/T›èIÆ¿/ø{CÀ8iÇøm­^`š¤ÐÚ’ om‰ç÷._j\º÷Ü…Ëÿߥ--h·¡Pû‚j_íäÄO,:å"8÷h™ mϵt>(ÚëÃgª=ÿöJþ
ŸýÞIšÞ?úÃWžªYOéú:myF8’Ñ€íµÓFÊ‚ŠŸ¢×Ó¦xù)þFÊñáüWLü÷L«\©€ub‚'0%IL 8½ùU ;†ÿ>°ýÎ¥íç>¾tÁÿøÂ%
ôß¹`;ˆµ/}P;9ñãFñ½L=yñÓÙ	2ÖÜ\Ô«œ?TŒ¡1Ç%ÖŽÇûwâ]Š•kø_ Å£?džzêé§µáJ>àËÎhø÷2Öhôzà•Äò…ÌÈJ¦Ð¾a-.üCO!Tÿ¸ª¯]À‚Ø÷«¥J‹Xô”îé0I¦Íj«¥[J
\Ǿ}aûùþVkûRûylÐÕ°
<Åvrâ'ÖG±Çû«2€»Eù=Áöú°&³cø·§öƒ¦áßNÅòŽo"ÆüÛÑß®±odMÛ³tžØ³~_ŽÿZb¯UÌ$ö}ã|R6ó%N<"qFc1R€-%Øö¥Ë—æýmß÷ÛÛÔÕíìÛojÏcû=9ñ)?æé˜I#œX$2Æôlÿ±óÛ®?ÿ{ðÀÊŽŽŸ“'céà ÈèqF³f¾ð½#¸:Û¡e†/}
zîj¿HlÖtÀ¿q@ë½9{ýñú;Þ}àÅŽ/Þ_˜†.ÜåÙ6Dþ—ï}|é…öÇþùò…-ho
k'g~bèìÒ†C÷bé9ˆ§ÿsQ@}Ȥ½£ƒ¹ÄÛ{á?ã;FB?0ü0:êÇðot ØÞ¨p{ÁhO…Á”qÇ­>9=€±†áÝ<þªxKríû}cNL¯ØAÜÿ÷0€|vïÂö¥…ËÛ_‚0ÿ•·‹FûùË=íäÜOŒÙ7cIgCØvšôþ\ÔÉ~(Ögmâ½Ö“ÿgÃ^_ßÿÆË£££Cþ
¹íùf|â´ãøÇ±Ž¦°{ño|½V††k*èøgô×{Ê‚XFd4Ö!˜ÑÚ˜½ß¾wá…{íÿÕ¾þK}÷j'gÿ·zúœb5i6ŸJxÅ¡]V&Ï[uÄÓ…qôy塸‚²‰ÿrOüoì0pF{JŒMMn×útºé¤5a¼^›0ñÿ´]­TþxþãrÉU@ôVÆôþ`ü³{Û[Ûí¶/\Úºpy{~{~¯vrþÿÁ«ÿ·ö(ÏÄÒÏ¥¢™OØÔÌx8c›ù9{ÕÔñv/þóu¬ñ‹ÕÆñoŸ”û|?{˜ƒíy‡ÿùÎõ^~ѦO°âÙ’¶qâCñφâŸmo]Ø.¾M÷4ÚŸý3Ý_îÛNdÿ†¿žŽè9CëuÖãùÿXFauÊÜ_¼íx&âøgñÊf:€¥Íð€]õË{«9ÈÀ›Þúß¡Ÿîñÿ½j£‡ö:œÖ0¸toá"$þüÇ[{µ$6ÔœL<@~úözÓŒcòMŠ
k÷lo¶†‘ IDAT}âÄ÷K—•Ë÷wàžãö@·mùãF—ž»·=ÿ18øæ÷.ìÕNÎðÄK,±ÄÓ­“ü‰%ö‡‹ÿŽÉØëNãË©øø¶vöxýÇ¡[ñ¨!ö“Xb`€aЂh|)üÇð¸³Å@­¡ÛÛÒ‡GhE„„
û=·rÙìhmô¼!Žx³Ý0t“qˆµb¨Ýîà{{ú¶†~0½e¸û8þñ-±é-mè@b‰}çêÕ«ßù
¶ë·nݪßÇí1tÔ?€C¿£1” ¬{GLt÷P#€¼e|:N[qˆoi/2Àˆç-c[}ôØ#N 1Ý®þÅ_üÅU½}ëÖ£ý§¯µök¯½f´_~ùe£ÝŽ¿ÿuóý?øÁôö­É'oé¯wÚÿÉx­V3·ß.ÄÚÆþÿzà=>¾1LÑ7öù½Zƒ¨6>Wàà[ˆw¸¶㿵“:ôàßn‚z+ŽÎ8Šü''€ËzûÊ­+—M@ÿéå\Ž€ùzÛ|ýõ×_7Úó7?ÐÛ·,?h@ûñ޹ÿ™¶ÙNÅÚm£m÷ð½^¿±qÁp°×ëp[€OÞ±5Pô@2öñhÅÅí 5à
-¢œ-	þ®®\1ÀkzÀßüào†*€¥Ñ‡†*€‚éñc
€ãß÷‡€éÓ{ôùfˆÐ9ÄC‚èà(~‡í´Œ^€0	$s¢›-Ö­!
€'$ZIÇ@b¿[9€›ûÞÀèPØ«/Îqûü–¼ÈÄðÙÓ°sÊ­ж4y`~¢58dû}7Ÿ_w×á?¦zB|[µ†tÕÇtOGÞ–.Z½ïé!€–‘lõ8ý0²I&0±ßs0»â°wÏïè	zJob
`(ܶúT´b Õ›¶ÇøÄ"Áb¿Ï ûÿ>øÝ³ˆ§³ÚÙÿ1Ø“†EÜ[½èI´z;€àž€‰•œ'‰%6À6†„F<(؃†fܶöªóÝÚŠW÷~ùa¼-+!€Ä»o6Ôo
ëzkíÜç½%–Xb‰%–Øì¥ß߯ö»¦v‹â–Xb¿.s_ú=f€Ýßß¿R©(ü3™bñË0ÀD´˜q.g¾Têû4±Äÿÿø‘ïÿ–sÀD¿<¿;Jäힹ߇RÿŸc“cxOVAøáƒd€z¶®ãÿ/á2ÐÒ)°a`ÌâV"Ôc
s&!€Ä"T‚Sã¥ÁøŸø5À;z‚©FmBš±o•UöØ^-b€3¬Ù¼¯ð€ëºcûƱ899÷cÿcw¬2ÀSÛpmàŸL5WVVü—éÇ	
œØØäh¹œšäïcDÿ“O®RC@:›Ödý_~çîwŒ`eeyEQ€ë8é”ÐôpþèÿU'€FcñßI 1¹@í%WàÿCpV¥?¼3H[÷ûk0„
Ά†¨g~mþÙÑZ.q@üW‡(€	««5°Ý3›Ñ‹·ß~ûÿ~UDÐétÆKy©”çEí\´ö­™[3‹÷îi0
Vçà"þA¾K”­,// ±ÿš¡þÏ”€DNäðbrÿlXØþ ðĸ¶_˜+¤æ
ã…þþ@Ç¿ 
ÿUÿ}UŠîRÍà­ÖÉFçÕñêÇ·MøOyãÊ|ÞF Û?¼·¸X]üúñ*  2cäÐ#ˆ­L§ž©q“
eI“c“¹r¹ÜXnr’ÿúljjujJýŠ.„àЇt.ŒŒDÛO¹jÀÄÄDSOðGê
(áØæÅÅÎb'!€Ä$þãd2"€áø0×z¬ôØÙB!<*ñ_(Íap´`f¦bÀb`à$Ø£CpÂT:Øo¯=:G1à½Dþÿ¨çdEÔnèí{¥{_ûÆ£7¨-R ¦¹s]ƒÜeôÿËFÀ‚rA€=™›œÌÕlØlŠE|UdŠrÀ².0R7
ŽT@9@ë4ð/fHët:„ë‹@p©´àÃ/¶½ÀqGK÷Y•ª=Ú²](UþѾ×ÈBˆádÔ†ãß¶Þ*UÿêxÒ¥*âÝ&|÷o¿Ý9ºlgôD`Ôˆð×4öÊòÀˆ™4UÑX.7YWõ9O>9ŦVW§4D§R<¤DR™´ç¦YT
Ñ¥‡Ô1,&øO,Lÿ JþAÀ`³-Ëz¬:~ÑÖÚ…êøþñ áäm0RF=ÁfüxÞªŽÏéÇ“®Ž{ßÚ1ü361€‘f‡Æ³WÌÎ÷<›Ì½†¶qÀ)™Ô/Ä?3 rSø ~"¦Å×Ídà^Ö*%ðOl þVþ~xŸv`ƒµ.Úfûøgf›¨N/	\'›½Ç3;ÏFÕØ^ŽÚÃm…!ö]áŸ1&?LÑUC4†_¸˜ºt	–p%öMqü³?4«îmïI&Ük+	îSÔ{<ØÆÒûl¾ž/NÖ‹yóâøGȰûB‰%ö»-Qj=ùÝþFù<¿
0ðü©T1
˜XbV4Kì?Ø
Ò’ŸâþØoùômÖ]j'ÿ¥ÄâøÀ­|ôQÔrbÉpÖé°£Õ´;_lÿݽßR:ü[–·Z;g¶«‹‹z@¯÷ˆriuV·ê¿Ñc_ÂÚä„ì“*ü‡}á¿2»¬€ãan*êèïLOw°S¬3œÑë˦mm-îE‡S/ó
æðñþͤ†XÕÅNTºdO·g,9ç&àßd€éé™~šaÈõúžŒ±—æÐÆA´ÛÌ
\–H€ÄäÉÌB?ô³><ÆÏ<¸ü—gµ¤¶ÃÇÈ8L?ïLcs…­L³éˆ–„6à1“Ëéó覘>Ôuqqk«ÑØêsÿ¥Né‹‹«5FÓòÎ÷ÇWîÃ'ëàÝw_4€IíñyÃÿëàÔ9n8¬Vk5¼V«ô>ê´sJ)¦~Tß÷³Üú>À>Ö&/%g~bÿ,KíûŽm[6	ÀƒÓ3ãdX†;rῲÂÜxK/
	ÆÆ:¹ÅÜâ˜$€9]4¸mE¥)E>mMQá?Õ9œÏNí›&ÆÇÇ'Ðâ°`ÀE‰ÈN3l†: «Õ°þœ¹qãÆ»º âzñ}ìØ¼Z|€ ƒ¥8boÌ];ðF{i·m2õºÇÜpÖ$€€®†¨²ì”-
³„¿‡6¹hS€
˜08]Ðmh.‘Ÿqa=D0«—µfœHzXv‰€'¦ùI[X-xR4:c³‹9 åùÒsÊ]¹³³‹‹i ¸ÑÇ‹ù17Ÿgn¾¨äÿa8—óƒÃ€Fä(Ì6Çm¸LJ¶àëÀ¿¨\2}Ñ0Bd±hŒE"ôOGpãFpNKƒ`qø²«ÝhÌ3¹œ "?㺊À‡aÄ!í(§Að«DàÍÖ³nÖ”Ș±±<À)*nÈfáÿ®‡ÄtÓY,áèêlB‰EàF
 ŽÀað {å#=€ÇѲDšÎiûî6–8vEàtitTâ_À¬Ré”6ÛEcOçG‹x¤æó¡¢‹àJ~àøuÑ{@á¢	@×Bh·Z†ë¿	øP¨¦«ºnÎuM¨™¯+8ûnx#|÷†¢Œ+Õj5Ž÷Fãða €ÖáêÚÞ¥b\QŠ×ÂqÝpL#¯˜¹"P—P¯þ³uWÇ¡w¹b9 ëòÁé?ÚŒÕAeùKÙä¼OLSJ0bHA1žžÿ#6¿
œ“ŽçÌðD {ƒ0ÉYjÿ£K…B§à	|,.ÌÎÎÈsǺ̩­Í."<—†¢.2‚ÄÙÐ
³Êÿ»E7vüà°¿:=©CœÉÄ_‹@-vñâûï¿Q‹8”Íf]`@1—«2ŽŒƒ@™?"šïž	ß}Hàœôÿxë0"( Z80eÿI]KëÇ\œòpÌþ/Q%ü»Z h|Ðédˆáû²¬Ñ&ðs‡@phNsq³©áŸv@ÏKL€`A›ÂGÙú@Ì8Œœ^EùUáFGGKà£äò|™Å‚*@jNë˜ä/òL€§P¢'ʸP,N”ÜØÊ\Õj§3)2Yës‡Š!0Oé¸÷oüäÆû
ÿEø²u‚ªÅ|>Ÿ«VÇU0>Þï4:ÓB¬Qðîk/*@Ës`‡ùjä‡7hß©LÆBÿ/	ÀÅ€%tÃáà¶…p—ãÐè:r½SßB àD@)ÀC€@iƒœf)XS%Ø0uér|´Bn?3ƒ™@Ï |sDhrÊŸNSdhüs(¢~€Æì좣®`=f8È|䉊(ŠEE&,rÂ*àÙ+	;[ív«5¿°à‹ àýÔORïI„zéäñ\.GS)èà4:ê-k7Âð±sа\-Ö8œ'pÙá|¶A9ÿ1І㌅B鮌<*
.ê‘ZÀöý‚ó‚`Yÿ!€Û!dàf	 T,ue‰HlÄ;ÅÔäìg8­E€ÝhÓbȹW˜žôû¾Æ0˜Å8 Ã3€¬j1À"j„tI¶Æ¬”§W-LL¢ÂUø7FN`Ü+C6ïÃ¥à«:!xÿ'æx ‘¨“Ã÷?Ž
`\h3è¾vNåX§Ö "¹ÂX¥Ñ™=å#3Ä”yÇ-pÛœXŸajt!ŸàïðÈòÅ<fþ%ìXÙT`%èOl „1°"ð.Í÷a€`-@Xá'¬7íû³³ÿ±\nqv{H׋1µi=
!NV)‡©™1@\‹A0¡1D§fÎZÎH(Ÿ¾0Ïü)?o‡øߨ¤T=H€~nH‚`â3è¼ÈnèÝ€Rµu{V ¬™eY?"äK#7F}B€¶„?.Â
JÙRùQ&€¡úÏR —üøG
°±Gœõ‰õ'€t“!pS½X Oh-EÈŸNOƒÿŸõ$8:c3Ò‡ŠJâ”V	àAtÀmKe†dÉ\¿;¡3@M÷¥M
¢91±÷ÄÿBTø¾
ÿ2@P娝* >=ÿgϲk:°
­‹¢‚‰
ÆNóïI€(:NÆ×…ð?¬ü9þ¾ñߤœ®ê×-²R@B‰
À¿ qÂdÂXµ¿"€„
Ç* æ8ƒ†«OCàÏF)«\g1—[ÌqÚ?JxeÑÉnýBƾCl‚³@ÔÓ?fŠiz%‘ÿ“Uýý=”K}ðèœßI½nïÂõ],+"€"€ö2d–ª@àc-ؾF
áA…õŒð¹‰'¿D!@©…I 1ƒôº±tÿ ý—±Êç0
þLu°ÙÙ蹜†Ò|‡L¸. ˱ðGÝ4 ÔÀ„1-f‹w,	PoR°,:>û¢@o¼ïûÏÂÛžõ@®¹G云
ȤT1à\Â1wøgäüÃÙýCµçE<0\øMa¢; AÕ9òÁþ¡}ž²xz/.nQGàÖŽÊÚ/AÐ>†	qOÁ”ûÓœ¯­‘ü×¼\¤úÆÙÓƒ¾/8öX–µ¸-}±¡–Ua€Ú‚G}†^rV'ö¥°fü)øô(û‹”«l¶'Œi½Kì7h¯üÙ+¡'ðï'”JõR½ØlÖyd™óàƒ“ýãä}
÷þäeu·Ÿ=îomÒAyîÑì§¼&Œ9{Ù%‘ü‰íÛþìÏ^ye@¾ï9_\_Dk`„¬R¯„¡
P¯pT›3N>˜ŸœÜ‹&';Xì_kÝlÌùzø2Ù Äj®¿Y‚ÛñæLsìá= ŸÝø^ÖqÏŽãk?xÓ˜\¹èh¡–¬N/nrŽ'¦ìÉØÒ þ1€ƒ}N÷Å£J«V©É‰ðšM;UoÖK¥±z³BÙ9#/N~5ŸŸŒM¨YÏN×ëXx“Þ“06®A`{p×wéþµ^è8Ú`Ήðýü—šÍæB®;ÛÎúýÒ
Àÿ¡œ¬2p²¼Ïßó³^„ðÿ
µy}0cÖ
ÇÉJzq],H( 1íäÁyö% ôÿ®xë‹ ïýsÀ'e³Yg  À†B¬R³áÂ&l¢óoBP©Õ™FTéRüêWó_5 ÎÔ©sZÀøääøÀeާÓLJ›:þñÒmió“¼Føÿîw¿QÀKýË/i0ž
A.—S!྄uIp××óvqŠ>fTbøï4rõ\yù¯
¿sÖ÷<Ÿ ìëú?ê©?@ÁË‚BàdU¯ –HŒÛµR­Æ‡ÏLü¿Bq@_š‰ãß
€sP‹C‡¼!`ÑòÞE¡ôÑõƒ@à³V­ÖÂ@Öµ,¿Ê4HCø‘¦ñïÓuA¼ŽoÀÎÂÄ>ÀÌÔqAO^œººW¯.iðÝW®^½úÝW4
p9Nà
ÀÙ\ –gîX©ùðLó᱇ÇfÆÆJÇûRã}÷ý~¿Ît=7–C ‚kTà¿ãtPx>‡,PÍÎi|äy…BY®×èþK¥dÊáÄ„÷˜Âu6&:5¸›
`>!ûNàx€ä’Ín‰@1I$¦’€àÿ8žf‚²¯¼²½°€°ÐWCgÜ´«MqE¨ 4ìTâU¾®›Ë*3pÁ”ƒL
Nž>^gÍÀÆf•&ŸË¦†4Ó‡@¶ÈT ÍP°i‘8¯•&	@›.ÓÔ‘“ÏFA
aß@W#öÝ«pùîÕ«Jÿ¿Øé%•t‹ããÑ`dÀV JÿKÔØä.×íUÙ¬KU˜>iP™L‹lFÕcÖålnñΣNß·yÇtÕêáÇ£B&‡k’àq¸¥¢Ÿd‹48à±ñ${’ŸG@lm÷%€ÓV†Ï[ëZ‘jø@$ b€©,Í0(ÀC
p8þeˆÓ6k±j	€_r“v)ÅJ› *ºUŒÌ¡¯çÌ,–Îf£fh“Ç@Q–HÈ\@·«á5Àk¯}÷»Jÿ—Ëe÷%³À„•Úø¬¹yÕ>çüFi~:ƹܡz”PÁ£„!@“1f.8N ñvœÀƒØ\P"°XL²‰)
0Q;}Z©H$ÿö`þ	…¬õI¡š
Å£‚ê@Àœ •ñR
/Qÿ>fôÎ>›€§ý‘ª)í¬NZ¯¹5eu-…–µ´éFŠ,"ֳΧÃJ…å:þÑû_Y$€o{ñ2)€(´0½)‚¿`TÞ àÌ·HýD?•b
±¤¥Æ²sD&öæ,¬çµHýOÊBŽýS¿s‚‚çQ€òT@’HL8uEÑ€m³P‰)ǵ,ËɏЏã÷„†
ñ|V%¼Ž£:ÊÑOÔxǣĵ2¿¢€î0«|ê\š,ÛR ˴ᮘ*ÃÛ´:Ò¬>áE
—õ¦åvû-·w6ôÚk<Dð>µ.?ýô"—u|ëà„
1!©¿Ãäü b:FŽÑ«Gj¥2–TõCŒR¥@Lìã#€ƒ¤³ ÆÙ&FN6[.k *9õã‰Àk\	ˆj m†þ¤€I1é4'Ì8ºûT÷p³Sp	‘´×9úé=ã|XJ©¤ BwƒlXµšmgÛR¨‰ï
È:²ù¿ãÇ5àËm§‹ƒž§eãøT“½€\ÿI@’&|E<éVÒð‘¿L¢¨9ü£ï“Á´EÆ’uLÿéÅÀ4ÕZÁ&Ržà 4õpƒý²èxp4±5ÙKI 1!zF®a@3Ñòüq,dæjøç	 ²l4O”^ãïX|h|îÇM(j 
~£àœOw§&ö%÷Ÿõµs\7¿FA´ÿj»gücÙ}š~粞YP`ÒEˆ§Å’˜’‹EyQmŠÀl6>;ÅçK±d
@Þ	üäƒÅøˆÆXƒ"Ç¿þm±“ÁzÆ$Ø`3õ£a7ö;VŠM©ûˆ%4Ï£]¤ÐPlK™z0ûu
x‰yR³À/èyîâ”_è	 @.Úhé,0GY¥AýÉx Ä~«L%üàwó¸÷m<æþõ%Ý’BŸÄ~߇™/úñ±ß"õÛˆ=Þo3×bM,±>öe§ˆËÜ¿CÉË÷ùc>¯NgoTNïãï{b,ã]‹M²mÿ×Ä_ê•k\Ÿä;×÷EÑÁù}@*!€Ä†@‡Š×²q™kNWU.÷‰æ£~³LŸ	BÓû=ÓúÛóÇJÇzßRHxo[Šù@|o~4Ó¶:¾ è7;Q1ãêàŠq†ªò¾Ö›çº8ù9SµNle/lîÎ|Æiìî4®ã“înãúŽñ¦wÞј> Ír8dÆ‘jjàìf'“ó?!L?ë_¯žã+è%‰ÿ´Pú™ªO,ZÞ“°ð.­üÿ±>€<44bÇöåÁhǸ}çè±£:«,‡}€$×q]ÂìöKí÷€š2-vJ€:ƒæ¡µ
Ì8’Ieú3@+‰Ôë59§–X¯¾­WøÒ	@ÔöFþ?-dV_kbÐ.ôà_c€.€¯§Tõí±cñ>{à#à$¾,°'nQ)’q|~|^\X3j^#q9ãþÛ§µ\$5|9(ôÒ^¹²®ýùÄç\™ï´P´1ÆÿœÄØ£·ƒÆû×'ƒ¨£Á.&þÀ}¨ IDAT3øaóšÄèЬæuºïô•x)¸¦T9´`ÉÉŸ&h‘ŠeûÌÀÃ?¢¼}:òÿô ¡Òœ	´  §èTc€.ºÿ¥Sx‘àØ±cÆ'òˆÏ°šÏ#@S,ãã„8Ψv|Ú‰íúÅ¢^_Ì[Å<<%iQ_fn?äÛ'èÃÅ‘‹àúh+ àÑR«¢‡ÌïìÌ#ôpÆ<°èNî\¿ÞØitÞ臻ÿ®€$€´ÐjÝæÎ_Ã	¸÷ohø–Äx8 ;•VpòäÎÉÿ‰)8]ë§kÙrß¾€rœ˜sôh®šðÜ´RTwofz«Î3º ÁwÝS’ÿfp8…@'4ó”ŸòäAS±ã+Šù&øNéCÿS§Š¨ô‘ˆV¢ÅvÌí3—LÎ`‚P-ÀU&Hq‘$wE¬˜ˆ‹5:…ˆvæwÈAƒ˜ï«ü	€OIÀ 1Ùh\ß	v®ï6."üë;·9êYFü”i®ÿ­Â|ËÈ1 Ä#|‰ïTŠüšßàøNžl!úwHL®uút üI0'ÝéÀUÖáßG9*»O¥Ò¸ñ¢S=ïÔ¼cùcf§ÜaÌFTÃàæþ2>™>ÇÇ	oªò(XQÌ=Ð^^^¥øbÛwi~ÌJà9€H¬¬x®+Ý?zÿB£ Ö=š§4
¾à1Ê0ž˜|»{ÓˆïÝ÷ÿòº"þ R€\QelüIú­Âèíá?â{)"š‘…Ã?ÅvæNJKR€‰	€£ñûÀ|™,ÐÔ, Û†SÑÖ~¡ÄËp²¹Ä‡äd7`WÊ”ÀQÀH¢søRŒŸ!@Ð{|~²¦ˆòE
Ðóê(ÀÿëcûâþÇ –Tð·èÞ%"Àçˆ|À¿Ì‚ûçØôÏË4€1ë €OäI€I¨Ý»ï“x‡Gï0ý':K)P52õzŒ–þÈ •H1ôþØ€ɹŸ%tUxìGe°`¾Ý– øÛ¶QOÀ"ø ÉôbÀCà‡"þH3#…ˆG %éBê–8úœ:¼ØñuRêøÀóO`âO0õíñêçX1&¶Ïx÷¢‹TÀ(gà$À¢Jôà‚và(€@ì àG;žöÌ€À£6.~ûÑ)ú×	€æ	G@Ð*”Ëà´ƒMÿZˆ°§à_TîˆÀBÒ	˜˜"€jÕê_(	 <ßžÇ	ì	!áï%`ù§*Ž–­ê,É»Q¾:­]ú™€–õû€v|Í"é´&_s„zèájE5ÀXïöùpgA’%£`E»çø' @Ó;Œ§A³<ø`:ZÛ€iÐß40úÏD¯2¨KhÊà@H‰›"€Mü’œû‰q¨²ê€¢7!±	_ó¬Íñ/y /€¿qFá¢÷9Y.2@QV¤=Ô9òÐCÌæ=”Ô( ̳Çy;ã;ï=¾f‘<½ Î("ÓÒ
”D –5¶Ïˆ(
ˆ*‚>Êû‹ù;œ\@Ö:Y?L?8Èñ¾†8OÚP}âò3¾¯¢¦X/nL1@SÀýÑÒÁ­?Àñ	è'Ë&&= s”‹Î+cqÜ"ÐУN'68Níí¢Ó9Ât	 =p@ù¯%œ¢Zß¶=ß³,;åùŽÝ÷øšbä¿6f÷´É„——]Î’´í
Þ_¥úÔZZ°!d† t°À)š’S
øÇîÿ@¤oü
ý—Œôßã¸×˜0@ŠT@âøë±"ŸxghðîóÌ$€^³Hþ«$ÜCÆCÀñ< p^ÞáôÙ¶í[dAïñ{	 Zeú
c¢`eEvêÛ—`¬"Úw€¨ìtD@ðÃͲ0Ä&”ñmò=•[ÜÇ?‡2.”vMÛý	@é-
 ’J˜¶=±ÄJ˜¯Âé7h¯å&Eø_ý5‘YQ=ø¯2mÁ<Áïb&pÐ&\ºh¦?NWîA|{fÖŒôý¾ ™¦Ž½_5†ÿ¦öÐc^‚üÄ~ßíˆQ°£JwÄ·´í$‹pKìÚ|æy5ÒÊ1
×0Lå‹N¹R6èH¥r¤Ämù_Œ@7nþgffúxÍõ˜ÓÜ|8+¢GpeÈ!oooß÷ÿŠšè£Û½­OcÞ3GâHÏ^šMÎëÄ4Ëï›vwà_#šµ[vQ×)ÀýróQøåTÙÙ'pÔßF€üK÷_öo|öÜ}Lð@¬ÿs}ƒ=õtl§GOãÃ%xMð§¢20‚¢¾¸ÀÁ	 «ðÊ`Ðö¨í,ëyú7é…?ÀlB‰ô1ý•dt|m˜Ùã»î!¾j%Muíóóàü8R€ŠÒ­ƒLÈÕ’wZçWÅ|Ëd¥2©壯ÿBÈèžB
ÑÏñ°Ìþñ3
øXDuê:ÃPg€••Oþ»ýà…ÀË1øÖ·¾9~,ìU»{¼­À7¾Ðˆ;¢-Èê.¡¿>[O&NL@ð?dR,}ˆíîãNÅÀàZµƒV»ððDl"üñ*ßöp±H«o}oøàðÃoôÄnkR­\.›
 È8…7þ–Ÿ!þáþÆö«#Yýqö((¡Æ{rcƒd€(çiìd=¬kJ ³Ò‰àȺò üó òÛ_„¾uæŒú“b¾Ø‰,ÝÖ˜ÇF€F"pû\Ôëarò'ÆûùGè>JƒéK}‡ÌÞîîî£ïSèþý†‡WšºŸÀðWÐí†ßþÅ€ÿt…‰‚ýB¹@îùQï6É·>ÿ$np]ž–ͪ„ù“1qOv9Ôu
è|j€`¾Ã‚ÿ…íò	Ô€åoù‹3€ë•‹þî.^…àÿ€¬ ik!€þwü'†öùˆT ò’
óy¸æC…ÝÝÇû⟗êbÙKÖïxpµ/èÿ9pŒ¼ýv£Ó813sâmñ¹ØÈ‚=Ø A¥÷
¦I`JÜ
ÒÖËûÿ¾–(¼}ª+²”`Éh‘!?Ëž”]mf°«8{²ðŒÌ®|úù
=[ÑÜW#€üy$€A€ýü_Ó~…åý×]Û2i€^ȸ鴛&ü¯ÝÆÝÝ–
€ø7Z8àÏt`(ÿÑ’s?1Àÿ#€§Gx
 ¯à¯1@ˆUr!>¨ žÔÉ6“ëÜøxpÍÊdÅM‰ÿ3ùÝÇßÝ9!ÏëK@Äý)[…ÏÛUö•)7ؽ}û”xJèÿŸöÿÄ(@t*	÷\ÿ3¸r¼/°3gž8,p&€Ù €Ïáþs&Ý~wI>cÛåãêj úÉðbež<Ó‡h¼5¯µîF‰À®Ô3øudÔ6“€æ«ÕäÌOŒGRSGâßd€¼Lꂸ¿`<àyYÿ–WEn4 ðÿøâ1Øß¹Çwgö§Zf°¼
ç»N]"æR¥L¹\&÷_ö#!|ê”ˆ>#øŒE1³"áþÁÿOÖ	@=@õ3O„O	ppV€8þ[êÊÈÜL³èߨl¼$ìs
ÐB$KÀâ‹‹‹¤hΞ1GWæ|Z7-KrFi€8THŒ™I5“VôQ@1H‰Å4€+CPÁ!
Q¼Ý˜Ùm;–olœÛÝݧ×oqàƒ` Òdz]["Jðñ‚ŸGeµ\èíî)|ö	W7n0xšS.À`üHÄx:°D
Ñ#ˆÃ
>ý|ùsu<‘S"à¯Á²Qy!‰tÿÀrÚÒn”<³¸øÀâ·þD€›Â€›vS|o·ˆ…Ƈ€šî5±Äh0›FÒý	c°;ˆ\æ«ånõõ{‹jN ™™]"€ü[´ÆØObî¿¥upˆ–eàÿ£EYÙ);˜ÄKV¦	nweÁÿ'Ø ã¦ï+˜>ºNA<‰€Nà“AÔCVWxýüÓO£×»‘ ûëÀD‰Âÿ×8þu ±J|È2{
8à
üÓüÆd7 Ü/ét¦)Œ¾(€Ä4ÀJŠ4øG‰ÀÐT°Šv9ˆQ.Ð2±õnõY6@ºÏèèè²öÇì3€A¾Xˆ«—$܆«b€ocPßœ _Àø4y~LŽk
`× øMêgTQÐʧ++úá0Sô€6ÅÁžã#–u 3ñÓ.‘¼]Ž·06œÂ„ÓTÊæ¥ à;ÈÇËߤ?P´iÜl ñOÐãyèlVyiWS»
Љ
;¤ŸüdÔLü™µÈèó4@ÐÀ—¾’X	Е`¸¾66Óãã"0RþC"@¬0
öâpº’˜ÁA¡ ªÜ?åø‹áJßøßøÆ´/*p»팾Ev(TÃ0Lb€Ät`ðð_‹Bs°,2Àn¤ˆ€Ü6¹É¿lÖËjIÀbTþŸ±ó=ŒÀèOÌ?š–@KñœêCL	ê	ä­ŸÇö¥€<0>==IÉ'J€Çw£°'ä•€˜œ•øôs
ÿè—"Ln#öÿú…Èýhð5(ü
€	äÿITÀ%€ç¦"šéše@TŠÅJ±((«ðM 1aÈ‹$ I€HÄ%urL´ÛÀm¡$ö½HÄ /7:ЖÙrÿÚ]*kmc€&ú€Ìö'7l||üè×DÛØXz'±×2†Æt°"	`I•.É'¼x;b–
¢o#€­õš CÿoýIŒÒâWÕ‡}	 ‚P™¨E0@bR0ÿÑê?ÔÇ«æÛÒ„Ì€–Š*õµ~ޱcânß–Í^¿¸ËUþ©DaÃmýñç= ¶Ï†ñé#G€h
#Ø5€ºÖ;O€Ï?ÿ¼÷À*ã@5Dà×ô
àÀ—T
@ˆ†-ÅMý^èø‹êVá)@BB‰í׆Nì7m¿H~‚ÄþC	ÀÓ	`§ÕŠÍ{Ó3MŸiîç೑‘a¯ö¬DÔhüZ®uûšüë‹þØÑ£ÉYšØ´až±rWG瑎ùvZü¢¥¦§í™ð#e+ËØ-Ìïcº¬}ã?\bû/–Šq؃ŽEE9¼ˆ†1ÝnZj]ÿ½p¸@ŒšÇ¿Ä&>Ùív…½Ž¾ôXr"'öñOKÍG6gŸÕ{Š|ß½Ÿ¿——æ16Ùœ4g¸ÔÀ¥y2çØé Išh4áßçøSu‹F J²ñ‘"	gc¬>99Ö/_N’‚¢9C%Þe
@Ëu•€ÿ™#J0¡Z-=&`‚§•3úTeeù|“|#ó—øÿÄ"ÿŒ)·%Žñåæ›¨š\PÐudÄ@`'à¾$-.ÆOyÒQ?í	`~^tÈ9õ4Œ멟ê‹& D:N„iQ€‘ìx
ðÿÓ	@ið‡5ï/$ް“ÉÉÉ &çœB%x)@ ñÏC$Ëþ
`&Ró-$̶FOÈ	–Šv(£1f“P&dc.?!€ÄL %ãñùñ°Éëjà†ÏY@ù?¸::ìH‡9A1°_ E‚vxÀ0ÏTA]Z¨@l¢_c’°©©©¾ ÉržT~º[7 Ã7¨€Æ/	„=üpOøw¹GrjÄ¢Æ{Yñ-Æ¢ÝG÷¨
° ¢7žDè‹úŒRƒØj§Ø…Âé@’Âc:þ~ö³Äk'9ÀÄL `L,4ëùPòËc¾uöµÔ	8CÍ
÷K3Ö•ó¼ë`^1€œX7 ´±8§§Â)t¨S"€X@'&0ü2ø0‹•Qþ
œxŠ|‘XS â_^þu3Óþ/ÄŠóñHƒÀýkÏ[ó“•<ð³	ÐS`6“¡‰i9Õ³¿ƒ'®"6&êkðt!¸8Ò£GT€VËû5 Â?ùH”СB@l)NÿÊN›)ƒ@~ÍÈ?TŠqè4::ôtÁ…@Òóçó²»@¯…òý¬¾VŠX7<®€’8€€Î†8ByÀHÌ	鈰h0àe0à{Ær% 1¦¼
/îw9R›—vž<ƒ$DŸï«ø´µªPæ­Z21tÔè8ã•€±€ Þ
€¨Á	#`Hˆÿ¡£LhË¥<®X'%ÿ!ã¿V(@Eƒv„1vdà?¨5ßÚãÈë€~6àþPAØ6°–¨ÚQá¼%¤-Ò>¨_ìTQƒ¡E'8_LhÀKÒQPV(¼ˆÕu"ü{ƒ€Ô?8ŒÄ€¬ÃQ)@3è`0|4ÀÃ}å¹Y/'b€ðˆaÇ…S…†ÚáÕëÀÿ‘qÄêù †!°“ó>±Ä~“6™ü‰ýÁÚpù’v¼Óíÿ‚Çød ja°iaÛ,Í,˵iÄ"å–³¿´}|\®fŠ{ö¯²ýaa§ÔîWO/òglqð6Ccêv>½¨úɬ‘œ…‰ixž7$Jlµîß®àÔƒx8.óÃ!Äs½ÁóñãnwàpÀ…x;^œì4K!ªù’ö… ‘ï£’Ýø„a–Xæï9|ðïäxg\j€ëׯ³ë‡®ºþ@ü«áÕ«´Fg€Åˆša49x DÍ
㳋uURäÊ•äœOLCÍ#AðˆŽ“ìŸÿyö~Àø}•½Æx…„=øÆ˱\Î$€›7·Qïü¥ „A{À:qbøOY|¨÷«þ!á‡õeÅ]¦ú
|š
AõúͰ>ŒÐ4¢š™²ã9ºèV=¬&æ?q®'^‡»¢¦pÛ±#NIÆY¼råÊbì£1ÜÓjg"™Ùèò¥‹€äÉ€ÿ—¯4øÚ'‰%F½\§;­Ø²%€‰‰‰ÁP«=ðÀMx¢¡¿^Ÿž@€|tåpËiøpÙ)ÿúx€ù¿Ÿ5Az1°¬Nªƒ˜â òËåÑѲÈïOXEﺾœ	Àn¤˜Q­d1K›¡h޶¡Ÿ½I
5­1€×»ÂÀ)_—àܶb”.æ
¶b«=¤ÀCþ™è„ÀÙZá÷-cõ¸tû.PsonÃóÓ°÷×6N''~b‚ÀWzZ?µ\Ý+"íÍŸü×Oz·›“«‡ðN.µWÃá󳬯3õ–ÀÿƒÓÓƒ Èñ4œð„>~µ,
bªÞáïÙR±T,ú¥¢˜€À‹ëi¶Š¬}¿á ŸzM
$ÁÁ'€FGŽŒãŠ[ÄM"€fXTé?ÿfÐ7q€'‚B.˜!	pê³Ï>;59ùþô‹/¾È!Î
LV#ø4)ÅÙˆIðˆ€W•Ê#üóå
 iDˆ0ÀCÍ<:cÛ¨pæŒXQ€êšŸùùÏ#ðïÏýósŸ+ ‰Â 7ÞÀ< @”™;Õ>Õ+ŒƒH1¼ª €ÄÿCf@SçÎÇwÅZ†“øa¹|ïÞèè½{Ëœ:+/ÿÓëW:	$Æ"”Éž‘ˆä?/Fki1ÀýäÍùOþa#€q=
06Öœm>¦€ÆÔù:ñùIºN¨i8@\T†¬»0=ýâ©S2ü¯O…õ)žð<À©¤M€òÌìQòƒKæÖ}6:ÊÑi€¹¹9^ÝDƒ 0 Ò€36’@ßVI#–êè4:Ï EðïÿüØ?þ¦F¸|’°€ãÿ7®\¹~½Ã®_ao<Äh¡ÓV»=ßâëý¤dàj},N月ÄQ°KðW!
ÀÌ?¸ÒIzÓ³F¦Ìœ1æ?Ó•(Ðð0!fÇ•'áÄÃdz D³³À5Eœ$þ''	ýh|~Žå€
G´®Ã?tòý£ z¼ ÈbüUÀ;à!T ÿ-Zd§|¢T®'¦àïÎÍœ)@ºWi@ÆsÌÄ¿Zª Á~þÿçR€ðç
@Kj3¾ñÆõ7B¸~å:pf溧p8P‹¯v‡
àb }@lùf¥(øáËn¢\9ñè‰+WH,"€À$€ø$rÿÙx÷'€ÿO"¹. iäÌ$€.ˆf›hËÕrüÃý¤‡Ÿr'NP-}."€#G^d:`P'€Ç4`‘•$P;Äl aá1€Ü@€Þ	prnÎI;ssÔ	ˆI@w.J2ÐÿLsÇà5Ê"ü•xóM†‡½ù¦‘ÕPÀ®¿qýõëW:W@Ð
àÝnëTk~þÔ)&ÀÆ„¤ÞÀ2~ß|3oJ€h-C´eW'€+H'HLÏ&/öÉ'Ÿ”0£f.H=.zD6;+ºDïø?
ð(°ÕÿƒA IDATv
X ð¿ôç“ïëb
‚ˆ)¢2¬«š tBZôXTñQ0eP	„쯲€àÿÓpÁïàì)p\ôJ LŒh¥ˆþŸ?óŒ–|SËš€žüÊ•×_G@:@—Mã!êâ9
5l[‹8ðC10W[Ž€»¼ìjðò‰ééI)Pbº0ÛCçŒü„1£ÀL²#œˆPHtNS
 zßääØÄÈñ‰ã#‚8`Œ: ¥ÉÉüô‹Q% æi
9-°A!J5†ÈØ–`ðAU!ÀÜ\šÖÞå$†Ñ?áG¥mcÆú¯&¨³[Lë¤RHml æ¯tT·HJpt©×‚w\ÚQ·%“üÇòFàqJ(pÝeµÜrãÊÌôÒRB‰EY@/ðâÀ†À°qêЀÌàã‚)˜ytìQ$ñ—†ÌÆjƒùîôt„ÀN'œ
1
P€ ÏÁ<`ÔˆYôÚD‡Ð÷ú£ZDÿnÚI»sBÅ`€2\vPüÏt @<Žz«h„"ü;Îë×£uºàÿe©3J/?¦
Ž1}ŠêÜÕ€@J€+N/H 1=ÿÓ¸ñåvØ@h@s‚=:96y<
"Ò©BAÇÃÆ‹ÂM1Š!€¨À¼5 Š+’Ô ýþ£,Ê̱“˜8yRœQW>Æ€ä?…‘xæçÏ!ƒ¨®tdǾ`[³(`úH |Þ €s$?wN‹Ð$°K ’B Ä†ØàŒÿæ¬Òï1üÛv§áÄiÔZf@{G£W	ˆ0â™Ðà5<ÑÄ@˜T“Žàç,–Òô•GGG™&XX­²jõdÿ¸†ö«%GD7`ÿÿùÏÿ¯	n‚˜þuQ }¿Œqd@ò^	=	pNX”Ä@_li5	ØoNq4½ßþƒ4GŸ<ÙÉZpÄIþ±‰ý.[™"ÜÛÆßF%b£êownæ+•¿ü²ñGßìî±=€ŠZ¯ß§ïå²46h-.½ìŸ`í`Dv‹ÎuçðlŽžöÅÿ>¥OÏ_Bë¾ÿAÿÿ}r.'¶£.0‚?1Àm]…Þ–Â8>«F4tÎh°Î­Ž1ë„ICf[Ãá¶/kÕ3lfäÄ%—`Ðz¼®Ëç	絈¸dˆ	Xw±‹øw] €Eó[Ë0þƒ>¾¿ûYÏ|bñ@~Šîû¿óq,JÎêÄ€ÿ²oY–_.s :8…g¯ïß¾-´°c(âÛÝÛK1
ˆÜõhƒý²1=ý2û%<ânù3p»Åf|9óõŒwk¨ûg':€öÚ û™‡Oœ81P€)@øo·Ó.ÿ˜u‚#Ùì|tÈùï"áÔaz2"Þ—7R,ŽôÀó½ kÌXÜÿyÿýÿß?žœ×‰íßý>ïE
 ¿Íº§ºð0
#æŽû·—–F—–ºKú	®fµÿåè/ùòËÓÓ·^~¹Ñø%'€[ì+¾?s«,aïèStìr‹ðßá“x^9¡Må
ð° ™?×WÛO0Äb‹},¸ƒù¡í´…ö¾ ð<ç(@ÖÕ‘@®GåòÒ¼Ü![â_ü|Åb\ÉÃûŠy§'L"ˆÊžÍ(ÓêÃÖPß4Z_Ó=þ|? LNüįbóË…€e–QŒÞn·gÛÈ@Â÷óR8zÞE°„A¨â˜»(ßþËÑ—_¾uÀ­[·®ü¿ˆÿòè­[l´|ŸHÐñWײt­qå0@§W2ÀYüë×Ïž=9~d€@Ç}œNFiÍÐþ<XXX œÎHžŸ…ÀËzçœì"|Ðp»séCr\²Üi¶(F(Iò|ÃbÑ#€ãˆúÂ0ÂwXÁß\:Íù1xCëÜE½ÅÄT {@‰ôÿêë…~¿;ÛžíŽJˆƒÍjµ{ˆþ%¸[Zâ Vãö2ÀýÖ40ÀôâËW¦ÿ·Ê>N¸ð¨‹ ëÄ4@·Ûè~&*W'Nà2¿üå‰Gg.èÀÿ:@ó¬&üÝý³±B[½Ó~XÉ€J¸˜Xpû+ ¸µú1: ÈŠDà)×m4:bEÞ@ŽãS VÞ
ô ï8yàâåÈ¡ï°>ÿr-„^C¹¤K€]öóø{çÃD$&%€"Ķ‹øoGƒíýÙ쬣€H¿èrp‹àÿ#h•G¿ò2›^œF
0ý2À¨ï?
êÿQ°2Y'ë9^Ö‰Nè.ˆýî.Åà¿s¯U4¿Îg:pªÕwÇÆÆ4xØ>aŸx8%ýÇŽøGô÷WÀ¿@à*ñ¿G, sm©è¨	=rÀ9?h¸ÏËéÇ›àð›ÔëÀ·?8 ñ_@›† Ñ¿{0ø“ÿO 1Êú úÿeKNjÑíþÿí}ûo\×uîæð¼¥á<<Ãá"MÎö™¡Æ|Å1cB²E12,Äðmb$ŠR´n"Á±ÃZ¶I7½¿ôãÞ&(\¸°BˆÁ$P  Á6
©ÆM(¶zcõ·¨àH¿¤È]kíÇÙç̃”lÅn|ÖpÎ9{Þ3<ß·¾µöÚ{Ï¢8¤¦ÅEî~›àg¸!ð)@°u®\¾ùTy‹¦çnäÀŸãÄ|­Z,Í
zHHxõœ/@ÜÚÿøÊòñe¦rèjNÉdÿþ&ð/1‘á¿s,P¥Pú}–à6iKà@€, àŽÒ—Àc9Ÿ ‡ô$É@€Li@Z¹\H"€t^M€Ð’àÓp÷?ÛF¤}óhD\X»ü‹…Œò¥øÜ3@+á!๬íC]³‡ÍòžƒâÀkCð3Y©–‰¢¸|î\ùÜMñê¬4ÛªðIø±—	@u-‚{ð”¼XýÕso"þëo]ËÇOŒŸVßä­¥×’RYB­O i€øiŽ‘þ·t}Ä&… OLùPô}'·±àÍÎÁzh¥o9˜g`t	 ©ø’ØÈ	@0ßÓ¨i>û‰×ZãÏJ˜ås7gô¾y!’¸ÀS©ßû=üè¯.üêWGu”ÿ¢ìÅ£ßá~Ü<éŒøÔM¦)È#€äÆ6pÀ!=0i†0À„ŒÜ&Œ*ï£âÿæ–¨üWX¥qùOÕ¦,àhY@¾&dl¥ò¦‹ù0臿
ÿIê‚×&1-Fs	ü<ÇÇUÀ\°0œûeuúƒêŸ$°m›×ù¸¨ýÑû'1²ß^ ׿É@*èa餶Ö/@d©ÀmÊÐ/õ¢$ÚJ Å‘Ó%5ê[g¼3a
À%ÑGجJìEòø»}3hEÃEðÃ@ve]øîÂÿÃ÷÷çYL±QÄÏ;p^¼\N$·PðnkÛfâ_ÕX,ÛÛ%¸êu< ý½€^Y 90îÄøsÙ›¯Þ¬?ékcã–ÇÇ?¾¬	€¤bÆ?q´&à`hÝÊh#˜
‡ÿØsb0æ™8:%
ÂZ”ÿÑ·Ç´Ö§zÇš=%X+û‘>„gUË£å*‡?'€2öþ=ØÐƒÎTÏðù–h}FN¡ý
ü@+¡¯w”ÃýèüÄhâþâýñ¸Ÿ‡¥ŽýŒ±}€ÈêD"A|ˆhíÎÐòD²Àb½ÃpÑ#¬>'Bòê}”¬¨—c,T|A
Y$€7+ìM$UZ´Â	ð?.aŸÔòt•áJ€p„5@°öÆ$³'e¯™Ä@G(éÖµ:à‡ÂK}Ó(AœQTL¢°
ÌÁ¿ÝûœF«4*G  €<å	ÿÏÃZ%A±ÈÁ…•&¸žóã(M&á:Ge2àh5 €D4k,b#¸S «Kr@Y/íAÑB`Ðÿ¿ÝV€óv[º8Ga€ÂÿV©Yà(¨VEÀhXì7%¬ô¯๿´ÖìXˆe€¡€RóéO ¿­C£¦¢uÀÑD*ªN¦Œ”ˆDÇÇG¹ó'ÿÆ	 DÓ¥3~¯ÎÞšVVVÂÀÑPí…HÇ‹uAÿ€€.P“Rý¥þ¸ ¶ `‰\è¦Câìmct—ˆ0°FJØÖ9À>Ëv_N¤ /¸	syqP]¼¼Œ•¢$ˆ‹‚|r@=¡>ÀP/wý$ÿmáÐù.ÙGGµ0þ¼m炉?Ñû|V_&å¿,ÎßÓúùÏì²6é
Ó¾<“®?àrýßéªø›$½dóùè±ÅÆúr{_ ÷g<-6¬Í‡è@ ¿¬^ZúÉ=¾¾Úµ0}Ø=À¬Š¯U€cþŽÕüî=Ί@ßn:ų€j @Ç2¿=Ù…@9ñƒo*拆÷ñ ¡Øv1ë+ûɾVCܺØ+'lÛÀ‹WÛNħ|lûj=ÌžÔþº»tçrVâ±ÚAãÛ#Gêa¯ÙV$à9Í'â“•¢!¿WÛ®ˆ#íYáœ@çoíù¬„ZV¸‡_h;<(ú¨‹ïf>¸ÿrÒáœIZΈÏûØ4¤ò/¼÷ç´ÙtRöjÀsÝÝiÈkà·šôG!8zäèÛŽ­ºÛlC	ƒ¯ümÐ!)n§ì8N©$j_òvžÙ•ŠmUlÛVÏš0Àd4r04Àp¨8Ô‘†¢p8Ô
-BÆêð1l6u¢‚KŽa;¶i¦ÇŽOûØ47Œ'^
	à‹ÓIËN#øù¤Œ¥„ð/ ?@_%
Áí9àmüS`ÚíÀ@ð¸ü7@©\æP,s!P­V¬ªeW­J˜cþ|ä¥ÂƒÙá•_\9Üšû•Fˆ†R8|8ò!u׋þ›øûI1%»à"61ĦËn“ðoÕ¬d:?+•jÏ!@2=KúßÒêÛ¬xQàÔ2h"ø@\¸´}äÈöö‘·¼}A
€”í˜Ì¯ø*^05HØpE)` @€Ø/–%€ó¨TªÚ“B0¹­
ƒV&£Õëd³É•üÚ³©Á!IØ…!€¤ðÓ1Û¶ˆÄ·Ù2Íø×zaY*“‰üOêõ”øð–i
Bø¤-8ˆÿµˆÅúÚ)¢‡ÔèhªEB/Èý	pðàÂÞq°Å	ÈÃþ@ÐGÁíÑGß~ó˜ø7MZíÇ”oì„	À0À»#¦
8Ž[,:ü%þ#055959©€ƒ¿î«)ÊþG² Ÿ/ü’^YY	…–	 OQhç« \ƒÄéê„þŒ¾‡ÿ[
A<( ô¤…” /C9ÚÄ›&r9Ô¬ZÈWèDÓÎ(_0@-¥7šH(HÑ;–réÿRßSß»c`fКM²`RNkV¥L‡OâÏC€}Š]ô*üøx˜Š´ƒq
(ü‰‚JåbÉ)”‘ÈûPψA1À$à’ÿ	ÿé£õUð/èC •…ÊB£d…AÈVtü›ÉdÒŒ2€ÈIš¦åX¦ÓÂßóƒL&BŠ0
ïÿ‹J€ºLŠ€…
 ÎįĤØÝˆÿ€B>ί	¡D7Á¾Œ$€ýA0ÀѬÕÙÌr	@Îz66fiER>'§FomÀðÕ+&–à3"t¶‹càop—Îs¥dpЍJâ
,T€)gÁNƒyC-=‚â9 `&æ)®ëÀ´A•Æ‚b€À FŒÀaYÍ›ô<#xKKÚ(ðÐMzi•Ò™&"Åÿcccºb@oïØDïXïÄŽÙR!€EIÀXÄq?ÂA,œƒ§ \kaɤFHVŠ3¯{~_Ï|OϾ}$RûGGçSûµlG´ÌúÏrA@ÃÜÃŒ€
€À"ü[B4*€V-p¢ù6LÆqqÒJ…Àf‰ªê
d ûi(“ƒ@.š&z\KMIJÀPkmS€ëƒ‰ÀzpÌâ¢A…#:,,ˆ(ñ?848¤1À2QžåáÌãT*•°`‚,Ä¥^%>¯¶1¾Ä¹zþØX¯@"Ð&(€›èÅ£H+€¯½9NÊ#0XøG7ÕBi¼®L6‹i¥ŒÔ™ûz}~ß¾A)ßß–"Ñ>7$f•ó—gúSXœ%åŽø7ŒÙÙ€À2Sª!à
¡¼º`AãÎà 3^Õ=¼
H¸t €jÑ$àå@,ú€üH À?å¤ÄÏ2RZð_€H Á8W‡(	0¤€(@ 
³‚ÅI’ PÝô&5EŽùI’Áo­åý€äáø8æd¡‹½½½u¢ñõ$`L_{s/íY˜x2-Ñ›TÕîáŒ?YŸŸstÊíǤؾžž:1S” ÷éîý‚h®ýþ¢èÜé?•p÷Ø*„0f—ý„ŒàŸÉè ËÒÀ¤A€3ÎhÊÀ#:¢W,ŽW‹Ì):ÿÕ
¦«=	@ù½`r2Ck]ÀA'
°:uˆ‹YÀ!(€ÃAÐ3=	÷0È>—‰¹×4à?~àñ3ß©'¥åýÜýcjÜÍ_®w3ôBP“€±µ
€_»äÙÈ´_](@°¯´€$€	€ýûþÉú‹E‘þç	~Kdý”ÿw‚˜@‹nèÿëÁôÿ!pˆL1¯%¦àõ$$ðïç0š‘‹a{0ûoUPWu-?®wHÌPpäH”‚µ:áÃé—Åô»!°ƒ>.o˜Î,3Q¯g^OÊÀ§É(Bp=o¿+g# ]“‚ Ë1âB ØB9ñ/O8œ;y. ƒ@H¦ŸöqøIšâîŸçβ«_&ÙfyÜdggiÆ©ÀÁëå°CyNA؂ӓIphøþ¸ ²A²žñ¨¾\*ñi9K%Êäí<Š[+À'EûC@øHê@uM®†	€-ƒÐz#À{ƒÂd5]bRJ¼ÞÑÇ/‚ÿî~œŽ@ÍJ´Í…ÿɽccc<„0LÛ´áÏ4â$`l¤¸Âµdû¢7%h&T{Ò-€®_äœq§z°»úÕ4=øO~ì±Ç¦~Â	Àóz<ׇ«—#pÌ>¬zì³Ì¾ŽÐŒÿÏøkí`¤àÿÌçz±
à¿^î_(–+ý1ÄÖÆ>÷,Ñõùz{ØxrWü‡ÀL¹) Õ>ïþ@À¯£ò ç†nøIúáíÑí'ˆ@̺žç㪮G
«Žúh0€£ »û^ñÏô €:	”ÿÏì‰	¼[m@¥Þ_\è/‡–PŽ-6ÿŸwžxÀÿü|{øýnøw#Ðcº=ÁMH?$€ùëÇC€wLWg€ßþöÃôöö¡?d?!èɹI¹WðVV2NŸ©ÀJ^›¥ûã§:â?[(p
 ýh¶º%:i({4:KϬµGýtÿ‡<{xÂ[‘Iêòí*EŒú‹°+Æ™€ØÚá¿ÓÔú‚u~'7íü|4
ðC>ÜtR=N*eªæ~`ºŠà±›¦&œtÎÉAÀoÙì‰COüöÃ)"püûÜd$@ÇC8 麎#ÀÊL½>³rL½‚…ÿ°Õ±Jȯ|!øgMñª•ˆàßk‡,ÈDß_ì¯öÇ[kKæ“a0ÜT}è„Û€K»—߈ÀB#!¹š¦8å]·Ç÷Ÿ7óF0í<þk°€Üœ“vü³öáö°ƒÃD·1m«_aø´Qþ¯äëþLþØ€ü
Œ¹{Â?	ú¾6-è=ã¿óª,©f°‹ÿ×ç)ó}ܪ¾yñI›¦¢øxcC'€ÖÐþõߤ҈pÂ1€þ?PçóH‡ï:›n(C.Ú]‚³¦è°»ËÆÑ…ïøhq8{B€cc
ÿ†1÷Ãñÿš2¬RñþûVÆbðÏÚû €~Vʳñ<ëWIÀ˜b‹0@ä|
3@Tl´Ô{·(ð)À"y”vö]}¦óøÿøõ㇖í2]7mæZ|d¼m»î,H
Ûäj³îî®ÃÙÂᕱ|·Â?csú(™Ù0\› Aþ?HdY;¯‘Ê=à‡àHÌàI•νÀ>_"I@ÿ‹í´ŒíOΆ½áöçd¸Ó§ÐÜ‹!þƒÖ¯ÍÇlj<"ëK§GL=ñ„"°Y)zº1móG.¬©~€¦úøpN‚iÀ‚œÀç¯ùÿ{¶]ñ_IM¤2¨î«ö¨¨@)¿¾àÇ[GhçÆ.ðÓŸþôÁ~:¿ŽK;}fXøð	¸p@|ƒæ‡UþEÛô¸m­»íÛ5Uýøx`•
ð9ð¿«·R¬”u?øG@ºýþ±íÂî¬~ÉІ‚a
#€'¦¸t[NϬcsˆ´Kt³Nøwÿ…`N ¿òeÑtl R,“ºÀƒ<
ÿ,f€Ø˜…R†_ŠM=ñ!Ï’y?©Bíû}‹Ð”`4¦Ná¿©v?+¶yè [gû‚F°~)
 ˆ^
ÜÖÕÝ-GÿDÚ_ùŠèÑãS‚ÞÏ’ÒñûãJÀØšl``t€Û¨Øtn;¦m9Øçæ:¦g;–c:ªíºÍí5cm­±&ìêšaÙ–aÛ&nlÓàÓáÛ†iÙt«mG߯õ§^XÐ÷SÄX¹·€(Ò/úU³¥¥¥øLŽíþ`t”À6*¡¾KÛq“ȦcZŽÄ
W²AãõP›ßí®]mTkÆÕ«W×,Ó$¼àôNHD`!àÌXVôý¤K?3¥êyÍ–òXÉ[¶÷zæJ
@&÷k4šÝf~¼áÃÕ­Êð5†äŒFÔAÂ;IÂ+³®‘6/€¬Ú–Ä/UXˆÏõØZÀè¿ÐánmÓ)è†5<๭ÉÉ„	¨·D€ÅÛkk‹W‹WQ,n êÑû“°‘pb*`’D¡÷óÌä™à3;f*¨È—J%¸"ðå¿Ùtô;NhÇiê0üA«ÕP"3€ly[ˆÿí~Ek·ô|h±Î
]üÓVµëYèS	×V
–¶u»"€m²Ð;B¢i{;>ócÓ@üñãŽmLJ5==mÁŽ,Ôú€öÄ䤅å<¢‹ÛY´ÖÂþ®6À?^»Šs_"šQ4;¶üüszrJI¾rˆ=€àO§Ké4ªÔS‚¦àâsêŒÐóc#—;ÜÑÑ–íþähÿ@’Ž-T‚àȱ(Ü0	À·lÑFxòöÚUpû‹kW¯6Œ«?ö¼f“úGùO!¿­Ú"À©&$þ'	Àg6åòy\Àf7ìq)Ê~}zGêTØ:8ÜõÀ¦£‘íÔ|àÿý:íîQx^Ÿ×"Ç÷€?bñr6UFFb
_½G½VWyˆl6“é¥.!ÈAÀXÑ®ºÁùùò`Kü/ÙK:”·ËÈÜÏŽÓ8ÍùTÀ/Æ
 ¶€F¥ÏÕ( Ôö¸!˜ú}npÎàobÑ¿ãʶƒ©@lƒø¿ÚX3À÷Cðcc
`oŠ€öH–àÔ"õ(2’Îd³æ”ÌÑ–ð3òýÛ‹«ÀÔ´ï—‰êõ‰u]¦æÃîY¦*uêÔ—+Èår¹^_5@µZõýTݧÕGÆô¾mû-ëmS¾"[Ê@}o&“Í2*˜@R©Ô›Š«ç³­à3©ZÐ_&@8„¯68>8¿øÿÅÅÿŒOýØÕÑßÔîï'¼{xìš!àbºÏtQÐ>Ñ6QP{
¢ÿJ}?W×®Ú”ï3Aì`PÄÀŸ9ª’\
HYn)`;}ý²)	Ì¿ºZX\
e¦¦g4Ö××ÿëZ´>¦V2䉲Z­6/ߊÖöEà ~xx¶ <"€Z“qÆ‘XW
€Ðï·OØL*€,ø(dTÐÀ±EM3ŒÌûóó¥Á–ø_âJá/’ï;`€ÿ Š>þxûãÿ\\܉ÏýØ ŸÅ7*tÅR·BV@"‘°¼ƒÍ9šžŸû{×!ÐGÚà÷A\ýñA\]¼ºÆƒ~Ó€ï¿ßetaw 	
`4è•Ý€Y?k™JÚ³œ‰z@³yä·VU
Gÿ3ü)ëëÙzVÔ<ù{‡çîjœì”d±0i€}ž7ìmõü‡€ÝL,•.•jTý5Ÿù-Ü$ø;Tm›ú°ÌPf(Û«­7:i¿ÞäÿÍù² D/¨{DìS@g€m¾J	`\e>&j`ÿ3@l0@€°§­€ÉC+‰
ïoÑÀWóv=D¾h£6àmìü!ÀÚšAÝ2ìçËSðÎË@àmNj3*ðŸµØ´HÚ;Góž¦þ‰¨¡¾°?%	  ëÿU°”èý #±fsÐp]g„~¤PÃÃ^àæÀ#ë€Þ¸ÖxŒï{^ªäyŒH£÷‡ë‚oã¡@>¾–\|Là? €l¦×G
Ѻ!üP¹~j>›g/¿lΘ¸dáÿ%¦ (IáúÇÄ@Gñ/Úý<€
…ºX™Ï1“<ݯÚ"ýïæææ
üf^„!À%mª B “KÑ/h²ö@ö?pŸŒspeq/ÜNæˆX©€lH`fúqÚšëÔàg¤Rÿyp£/Óë`‡Íè> ·6òðèÒpÊK‰Xh¿€ä± S‹Ù˜$¨Á•ÒRooïß[ƒ‹*ÔàÿåÍÍ—1÷2àßT€°_â©*Ao'€ñHä°÷Ä&l ‚ú6mï †ˆp×rSTýµhç³yyjcùüýå?ÕHø‰”ÀJä,DZ×:ª](à‚˜ÒGÙKýÏS¶¥*àÀM¸s$x•4¾Ä,Ïù!üg5e/%âžRD¹HäDñOOõ<{|Ø®¥˜èX 
ðEÁ	W,4_Æ6¦	mÕè³0@o¯ €I€àÛno¿P~y./c¢ÂL&“p
 œŠ$ŒF’‡‹±ûM#€y¹ÕÂmS”ú"Ðy\sˆ¼‘ÇAó‡àþ¯^¥* «ð^Þ÷‡èç`¯åÿDàôZ]ð$ vå?33CõÙ4JKdã(à)^ŽÔZ ¼aêìðK¨Õ8H¹P­•ØxÚ£‘kèÿá|©(uDB2¼°íÛðê’à{ù½½™!9çÎ/¤¥7û/¿¼"/)€`"­ƒoQÖû²0|Ìâ^€Øh	Þûޱͫ|(Ò7-!ý£í¼ l“üÇDÀâñè*ö%@XLkãò~¢P\d±(J9JR À3€ÓœÚ~éTJËÈפÝö”ãY8,Ìü±3k‚XÐ
 v^µZ´SóãrXͯÁ]~]ò	­<îã–¾À›_/dù‚6ºç
$øqÂ>›§eLiü†¥%˜ìã_TÅ€ˆ~þܾ@lšiwYþnë÷c­vïQg¿ÅKþ£m¥ ½f€0‹¨ÿ×0ˆ9?ÓkÓŠš@;(
Ä?ïÀ 9ë3+L,”ÈóAù’0M
 ý—N…js›ð/FËÓvØö°€
äyw€×ïÁ‹ATy}x%Šó%þÁ‚`K‹Î!æk5¨þ¹ÛD8+²«ãIKˆgðZ@ù˜O±PAœˆM(%¹B=pmÚäíÒaë¶lòÙ|žVÞp)ð¿Šùÿ«8ˆ—£ÓÇ@/âm›Òá÷ÃÁ@Ùìäl6‹½MsíUøP€’ìP‡,¤ÿ[€Hu~{È#{}Ú	¬2Ïfó˜Öç`S! ÓÇe?Ç?HxÿÍÍ—·±;@( Sïä@CëÔÆ0ñ¬°¸06Þ0¤ÜU÷[û6¥úÈésÜ·n
  ×OÿÆvÿ¼óŸúe[tÚÑ÷“Ÿ³ýp5†}Ñ¿‚‡
nÿ ϶S6³ÄÿGÁôc÷<"Xƒ~w€¯»ùTóæ×ÅäöâHÝBÒ~Ъ§Ý´ë%½$˜—†kb{ì±Ñ±±±ÇÆFa7:úØcÑv!Cõyº€ioEo|oߦK,üQG¿zLÍìw"°çpCÅs`ä´óøíxYuÒƒF¤mc_ˆiaq/õDÛ÷úÑŽq›ž†Í
\—c	þ3p5ºcøº›8üÈí’Ü4À>™ô»ÈnKÔá"	`ßccôÑ‰ÇÆ&{l,ÚÎh€}ÛæOüÌ3¿IÝB:]`ìþfйË1µ cvuu9'N8æs7
¦IØG€Ã¹dR‚Ý%ð'Õv°m;žk{pu<Çöö§í
Õ¦7A$nÿqFFàŸFø¯üåiozåØÓ@ÆN¢{iÇà4à,Y1bh¾Ô[ÝÊ)!í¹I¸¦“ ’@­	 ¨`t þ±	ôýc”_Œ´þ¹Dß•í¼p€Ÿ±o©Ôç"€½O–ú`v%dW>ÛýÜ+7.ÌÍBÿ?wêÔQwôHž`Ȇ‰m#™4lÛ®`wƯ§7þaucC¶Å/ðÌ3G:àßNXK!´º
`ñ?í}ÿô4I̽֬¥în˰1â`ï/ßï¡ ØUŒîC¿×±‰Ñ‰±h;Ï@
=(öÌ·¿;äƒû¾¾¾Ü–v÷|
‡úÌ/`­_ûõtÝ-Iá²»P†qÏÀ$8ŽÓeçŸ{`|?÷þ&ÅÿÊ’®i¸IÃ5pmJŠˆQü»4gþaZ´ñ=^yfò™Éc7Û@ÂXºxqdäâÅ‹<ð}Î+ÇP,ÖÒ7Œ‹ÖNÂŽ	 &€öЊ’.1äÆZ@oo¯–@°càÛÑ ½Úý™Q@¾I¬_+í„ü6«Ÿ>]¯Ó¿ùÜüV_£1¯iî·Ð	þÑÉø[0€>_(Ÿo@vd1ÎB> Tà	àòsù¼ižš“#'æNy*ü£0’ŽØÇ+µAx$÷I€pWWg6VWO‹6¾ÇÍ¿æ¿ûûW^ióÕÖÐóÓžr+€ÿéïŸö¾?jÀê^ÇoÔvv¬ÙÄÅx.Á8ðÛ_TÀƒ³®”È%Ó¤þáDö\™(ÀE'€„"€±±Ñ1ôøèð1÷´û¨Ú¿ $@“8þ›ãìÓã¿ùͧÇÙñ€Àý0¡ú¶¶ÍÂ¨ÿËNîB-”Fÿ¸
( _‚go믹oß>E¶asH @ôŸ5ÿŸB  ï!x./pƒ·9è]KÉOŸ¶7V½€^¹yóæÈ3#°kÍÇÖûÅ{ï`¬üåÌôÌ÷¿`úéc+ j—œîÚÜÎNÂÈ1bðw%×Óêr$$Ó(ÚôŒM€Ë§ì?!þe»oµUöOP@“X9þéñOó›ä°NQpú4G2•é6¶þzA‹æ÷éÓ†âJ
0#
 c Ôr(xÉ}=xáIÀ.Úú`À¡¿`šKfÒó(HŠØq
m\¹™€&K!û‡äÆiï”hÿà?3rì•Wn¾¢¢€·ÞzëÙ `€~öø##leå©™ééÏ;
O{:a™fí;ÎŽ;gK¶# "Ò?l<õOà‘Hbôqž®@‚jKàæÑåó=J:¯ÍÛÊùdZ)DþopËÀ©^`ìÛIlðÿ×ëšH÷õEÜú0"̽€æùCmÕŸÞCÆ5€E?•ùàßxu?¯ÛÁïhš”úOŸÃäR„`²mÓœ*XY
ßÁ„àÆ†¹±ºqZ´Ù+ÄÅò3Ç2€üSo=«¦L<¦À>x*;’Ížþ¾‡i€ìS#öRbi§fYƼí’u1F@LQ—6¼Íä
@$“nðŸ&*ÏçzHžæ’€®¼>ú<æí\_ŸhsøÐB€ øÍñ߬ @hL°Ósbï
€°®œ¾—Þ×—ëD^t=m¿S@D”Dµk®¿4XÀFWÒq’]8Ã	lº]ü99u™^ûþT
 ‰mÀ¿jÛ†\õØÄPÀ±
´yúeÞ†`ÿÌò2&Õ'|ëÙgŸ
’€ü@GÞÙ‘‘üH~ßìéL&ŸÍŸÁùÃjKÆÒŽéäí¸ üÝ/¾ZßqMd׃#4'€‡Ê?¤MlZRïO)dlôõííÐô"…L¦Y ðð¯àSÐXЉl^#€tëÛþž“zñÿ‘@"Jáÿó!ÈjÏ,É…B±Ã@?9waößäøÇ `‰§þIîã´µ
Cµí¤|M$7_ÞÜÞÜÞ~Ù!Ï‚"‘0.²÷ÞÃ`
ÀÊSÙ,ö´øa›?¶T3
{éŒeƒ˜3¬8	Àž(@É3i0ªbIèFðP+ñþÄÄÄ*€	Œ¨Cüó¶¨: Óœ@ïOŸô8ì…S§X£ÒX_Ÿ}õ€Òóªj^ÏL¶IˆÀ—‡'Z*5Ì@,®ã_A©¡òÙc¼cÙ<ºÿ9Q	ˆ5n؈@Œ›²€ÉC€äËÛ/Óp Þ¦q}——ð}ë­@¬]Ô>çSYB~Ü>°cÔÌ¥%{®f°3W]#&€8ØýRu‚øOcG@:­Jê†ËC­KGÃÞ,þ¡˜.ûrû‚vPœ¡ÞÀæ:€|!84ñâðÌÿºš÷“ÍgZh€ÛâŸ&Qa€ÑyÉ@£)m°‰G6væ±gŽÙp-Nâñ?Á©9Óód	0æü=Ò@ŽlÛI¡NLá iòá¢rãàÓÏ;vlPâ»üÖ²j&Œ¾Ãî@Ä6b+áØ;níjmiÉŠ'‰	`oI.–¦±„-‰A² ýX`þTn"Ö¢Pôþ	`/àòY,ªKã#þë’û™ù¶_Ùkuã·öþ“5U	@ð®{¦W‡`?wêÖbw ðùvÐÄ¢mÓÌjr½œ=)ܦ€ã$€ƒþ¾µül°jб¥¥µµ5^äƒø/ˆ$À1+ï˜sö³f—¬3 ÖbÄ!Àƒ¾O’ïçA7`[Ëä)Ù‡e¿”
ˆ´ƒ:Üä[U®œà!ì”\9KZŠä¿òÈZƒÍ?¨_¬©ë<_©À@˜ÆÓ+OçáŠÎ¿ÈÇ`o€C¥À¢ÇÏ£R*pѶi^uB¼(
·Aÿ²ƒˆ}™°Á·ž}V	FÖl[T˃ô'ÀàØ1kÇØqjo-Õv–ÿKñ` ˜ö~Q9%@ÚóÒm*üCÀ;'Dùo´Í;ÿ
² ¹ð¸,ÿYQGMªùïXøÀÏŠfÛ|õ"Óàçó<ˆy€õýóŒ
¦‚i˜nÒm¹!ðîˆq¡6¾ÇApù¡Y~€Oû'ªÈãÃcÆÎR短Õv¬ÿ±Ýþ)ð(ü§ÀÊÀ݆#Ô©˜Œ*Bm¡üE9P¦°°ûX€¯´ñª„aÀé'<-(jBm{“ˆg!¼bB åº4ó™.6¾xÑ8sÆH\Œëbû:šœû¾¬¦6,Uá8t-¶?²YA©¨Ûáa.K‡Úv:îTdúè#>‚_Ηaúœ4_WyfîªðPjËã‘ýìpik	'Á˜×F®§[6–Ô†¾UV[wˆ±Ë7/ǧvláDV>2ÞMà_e¼DøÙîÄKkaÓœ!n²=<‚qÀïûõiø´ÀE©–Í"²~kàÛyÚÛœj4+xµR­²ZµYØà°/Ýþoã¶ €Û€§ÀÎÎ{;`°ÄìHzÓܾ¨M†S)ÒjOLqÀÄ͉øŒM÷‰ùb™[;üÓjÈkþßÓ€ðOcÞíN
`ìË"€y\±^¨3M࢔¸ÈÏÖK#6.ýWEÿ_+U@©BA€›GY84$îëíí@ßøø´a€¿rü»iw'=™†½`/ôï`·?å¯s[~=Œx²‚ôúrÉøœM'€R©\,KaÐð“r::¤8ãä)v½tz0£tñÚŽ}”_¼±Ëý¾†ÿüg@p1ÐB½U
 ðÏõqØ×YÍ®Úöõ|@ìz…Õ*U"d…‹–Ë”J”Ëãã‚x½ŠŸËlC·!À õÃU—/qÐËË>û?’€(ãñ„ï—á6yÿÛ߿ߍ
UŽdÅn±ÅFø/ô‹ýÃÿrüC€3þk¢ÔIË¥¬Àá§=/3¤´kÑEN`…ž¥ûŽ•¸u÷îÝ[º’Æžo­½ÿÖS‘öÝF¤¹ÿúõëªMˆPîáÃ
>ùYIs“s}\4Ø%$€Z	tÿHž‡D¸°—}ÝfBð+ãåÒ#©G‘d:Hs¯ö>ú至žâðÿ·ßøÃþ ÀE?†`|¸…åÕ¢€÷vÜ÷øCüS´
§%¥Pà
¤´ö8^/¿™ë¹ùfœˆM#€r©4l
‹S¶ÞÿÌ2C¾ËÑàͰ_[‰>Ç%@@Óßø†ÆcýÝß\¸ðO*¸{çßÿï]íµi•1­}÷Îwî†ÚO=n7Â÷ÿÇïþCk7®Ãý×5

ä~–.âÀ—Àääd—D¥q ŒÄ*•øè’]¹.„?_ÜT¹lP©”RƒC@½ƒRXÖ@V‘ì’*äÚÂê2ºûF—%Cÿ{ÈøÓ§E†Dà†’€2ˆ_¶@à‡ÖÍ›—/÷]¾3@l2ÿ'ly¸.¦Ì³€3-ñÚU?o{ƒ~)79˜ÁÚÖ´„û`zL1ÀØ?ý]½Tÿ›GU€ý÷;w:À7"!x~Ckÿîÿüî®Ð_‡àzŸðé#¬© Ë$	%Qˆ8	 dƒÀ@€’˜D¸~½$	ÀÂeNÿññê#%N§@ƒ¸¾JooKÓáCÿÛ"@ :¥,šÄÿïáU(·efvévðí8òù.É’ìr ÿæeø‚q. 6$€R±4}]tÿfÓZ?À—kJ:g¤¨åØõªmתy9
¨&7í–
€ýí_œ€ouXð¸éñaØ‘*`'pûn nw~µËob >ÍcÛ£!´÷–™–ví(ü¿J–Õâ6@ÕX®Ä’}µ‘öÐôñ¨Öéë•Jà8ô=€ÕÍXT„ݾ{ß>y»ÿ.ÇéÿØöΑàOßü×¥yMÜöG¼ÄÛçµ$»§š“'§§§Oždj-
¯iž½U™FäÓy-ßãÊdôi}Nî®êïm€2
“Ù‹zz¸Û/§öôýæ¥K››—6Á66áð")m±´b»W*ñYÛ—fئáeü¼Ö§<üüy €óçÙÔ”"€pOÁê­iI4a=\O<û,pXÔþÊÚµž‰{Á?æaMŒÑþy¹\Ž]b›€nÖ“ÈôdX/Pcû%ü+‚ú—6.mÒßž	Ç	‡`` @¿ÁŸ-¨ú´Ñý1ÄöåY.LîpaªÌ\V˜–¶¶8uþü”p0#7Ãq?SÓÿvë.l‰N	,/?»¼|‚ÉEí¯à¥„ÀIvòüÉ=+€“:ȧErrXÐÆ¿Lwèùâm+åFYÀ"qÀžŽ\¨×iÏñi”"—†±´´€`°¥€_°XkÓ4ã³6¶/ΞþyV„{ž\ºñê'"âÝBMÉ@#€sÏkøŸ^þ7 €©éU¬¾;±|ðyà;,àÊgWÿRBD|@…áÿóä_œÒ9ÙúÜøŽý+k<èrÉ$÷M&Ù¥ÕKŒu#ÛìÏdzzBQ‡b K—4Xܸ´ðsXX ˜óœü¿±Ä–&ü	‰@@ÏèþÑž¶¯ø£ý¨^¬ÃVK„{^z'ò”wšn‰-¶Žp6Äb„'€O^½!S^(Ÿb§§Ñ»Oq€çžƒËÙ³Œ¦‚˜ºµz‚€©ÕU|ηO|›?ùYˆ¤¸³z‡¸D€¸7ľïg‚Á¹J<´#€þŸþÇÛ¶ÿ[g·Î1vVK¤
|rã“Úë
I€ÚÇOƧNOþ<`ß¡g;lu
µ?šˆPP:ðDˆ>C˜’ Öjzz|¿ïg1&õ/ùùó-£zbŽÂ9 ÙBà

	
(•Ë}ô‘ŒÐùã”8‹ÉE¶¹)Ñþ¿'’@Q 	`ñÒÆF;H²èŒ¼„û…jeADÅ‹…áòß™ B„ÿ¯ÙÛÿÉ
 €öÀVûûWW·5ýFŒGþÿ%$€w^Rè‡Æ‹/¾¤QBD0ÐŒ“±	;˶ @8G~,ssnZeoÜ`ìµ×h<¸ý8L€!x8þÿ"vˆ‚€)R”	\æÉÀeìÀ(
ØŠ|Y„?€ý ÿO‚µ…6 å[|®;ƒwÈÕqÎ*•?*Ëê|À~Ž‚[A@F÷þØ$°¹¸À4€¸¯4Dü_dJP
€ù!€ßøÆ
M„–ýcÅâÌLqU¥hdÒ@àP€rùï¼ó’h¿#o©B€à 6áþÙYŒÅÀÏSî/Ë1—i3~¼þúk¯¿ö
rAážñÏüÉódŸê8€}×Uÿô-Yû·Œ™€€>ûì
OJðØŸ¡AàûÏŸ<ÿ牢8wîœ$¡m‰û‘¨Ìg¥(@½€aÈåriµž8$#"€Í&ØIÐaôWiÙ
P$€+60J@ÆýWo°=Ò Xb‡õãN’h@‚Àû1?¿DÖ™šû(cû:Zp{ö¹çFþê¯Î"ú“|Žo>˯êþ{½ö‹_¼öÚk¯cûÚÌÌÔÔã\°7Ÿÿîw¿‹èg
›^Å^@€?Äôô*‡? Ÿ@䯀|ö'ß/ÀÅ—Ù7ÆP`Wå|€	N¶Ì°³•*wÿ-óedäx€Ýå©ÎNÔÿ"$	pIÀ­MñœÍ™M-`ÁK†¸ì À‹Þ R”à‡vã“W™–ƒôS!Àf­š‘ B€‰ELO	DŽ>ÀP•µ¯dŽíkÆ@g)‘Ç£xD~¢}²Àÿ7^«½´ÅØãüù­[>Â,þó(àù7†ýÓ·V!@¸%²++Ë+'ž]æà3ðþŸÝE¸dý9N3Yû8C'bðü_€ÛGïß6ˆŽ¿Úè@ˆ}d®ú0 ‡ó§ûz	„M8¼uJð½à
r¬ñp#Ù"&ÀP›úþ
E„	€©n€O^	 vjJ3‡ÍH¨êqFKW‘Œªý¦h€Çñ¹áÐ@yü~"žte‰ùûÅßÖ^ý…^/a
s÷\ŒO€Ëwߤ€VWoÝ`œN,¯,/ÃõĉÃX„¸¿re"€Ï®L5@&ÃSâ&ìÌÊη"ÑÑÖnÀ‚ÀYä’Ø€ŠxÆ?—Þhœ˜ØÀ–n\Ò	 ô&xmr±áeºÈÿÜ9ážq*€† €Wo|òIÿÀ§Þ>tèжTiPŽ$Vøo"d€—ÚýÇ+C1øc2Ï3Â?fž'à½.ƘììàX§O¿ÀóvX@˜1¾ÆY¾ãÓÿ®‚ô¿…ا~@ŒýA<¥@|Äpë
Üw厀?³µø,›¢N€à† ö?)Ÿà8zñ!øþ޵À¥ððœ>œ(0 Êö‹¤?Wäé(…)I›m	€_)•Ä«Š@dŸCX ÞPk
|&60P`z•Ô¡U ÙH‹(€òÂ^z'B/½Ó–اq'`lÊÀíúψŽ@ìH»Ñ!fµÚ/Lóà$…å'uP•@öƒ˜&"@ÀØÓO¯¬<-À4f	¦¦°è˜›žl–eôÁz'OF\¿ï$õÅòv!€òGLf°9>à’†՗éQ•ªnGIžW”äÿ‡ÂI¶ —B_E€SH74(„¾Î¡UvèÐÍ& äò›4UÄ[KëG	ð<)€³ììóIAnt„éôô馜?¯À¹€P òÇžD8¼²²r˜*ˆ"€$>»Óú3a¾?4)‡%´€¯ÙÅJûNðQYn8‚ðKöådTðÑ£d8/(¸„EÁ›—ÚRúôšÍþµÈd'^˜xëÆ«¯þoèQM8±:³½zh»4ÛKD@l±©¡{–wäñr@—g¶š`úYýÇ€"€d`Vc$€[«²`äÈá#ŒW}ö<âÔ©©SŸ}v§%ü…nÃ7wX`ŸÜàÖ–úáf´J@“µX`¨ÉbÿÛ^€Hã–f,:ÇÄôéÓ§§OË@ärA[„'Õx`V[Æ"Ìÿ9˨Úq›:55µ*F6	ìÿï ‹c¾ÿÔa4
‚¹ðh᩽ç=Õ–…GðlË
È	`qs³M€uF«ÃEðß”Î,vxnl±}Vøª~°„a$˜‘ ]"‘è’Œ€wÀÍ	_X÷,a'lÃ>k'кŒûéÔ äßýNÝ„yØÃ¬ÁŠã üH?Ô,ž­+¶?¶
†
¯æG”ãZyHYÜ1âÜБáûëëõjµŽ;߯ú8£nÂî>w¶†atš¹«òê›_üN˜ €F34þ÷D+ ãƒÞ3tww¦óB!>©cۻфÕ_­ÏôsÆÞ}—òd‰zÂðêpØüq©l’,¾ß_Gü¯×aWï’8p6aÛF'üW^m{§\GLÚpküZçø—4€·5fh‘áñ[ªŠNº(f€õÐŒÑi\‡†ÔÀ¨ØbkG_{—ýüç?áÿ.%Êë¾Q'ðëHÌr+Á<ÏÀ$÷z P©Ã@Ÿ8×ã“ÏKجƒ¨T^í0Ùxÿlx¸­P¾_ì[IÝÂø¯‡ …t+0À“OþßРê$òã=¶½drÑåãw_Nþ—¿¼ÓIkß«óW`€pcÝ_hGÀE­„ã9ÎKÔëUòÿ•õõ	@ tƒÿ?wn4€
¡­5¢óðy^0øoM
àpø@ƒ@g€ù(°&@ðëßlý7ÞØb	Ûž@3Þ#·ä«`úZ"¿¼sçή6Ryú|ðÁ?v"€wÙ» `÷sfðüÞzÂÿ)À:f\‹%“Ž38”ðÁíO þ¯Nøõ§Û>îtôœaÝvüGào¸­?ºn-	@Ã?â¿ão½N4(i¨@=rX`M$ $€€bˆí^lˆ»I9Ö´X:ÄÕJ%ê_‚é=zùò§¥€ *Õ|ðÁ§Ÿ~°;¼‹ðׯ­û×ê¾íÚOëë>œüœÄ?@Õ¯W($DaìÏŽžC`r]´÷_ìˆÏð®îþû4ÀÑß–TëwR°½)€ÅV
`~¾ÞDQèNt‡@„
‘”Î`L±íAN£3T+(´î\	÷è—ÅU@ŽMèzñ¯@D<ëçÀ»ïJ€+0ÀµŸ‚ûÃ…‡qtÛ¦þÖI$Ô×'àØî2gGG·¶FG{{»„„ÿ‹ï¿ø~[üƒ÷7ܶÑÂ0ã!@€`€Lçà΢~Ø”6ÐÈ@Â9Ê ë‚twP0ÆlíR½M©gs3ʇÂ!€Nß»&€|h±Ñ
¸ÓÑêDU#€¸{÷wï’„Óyþ/ÿð‡(€k×Ö
píÚ¢ÕtaþßÐ`` R
HS$³Š	 ¶v PˆTý	à¹þ+¿¼«Ò€P6	`~}}~~ôàk}¢ú+—ÊIÏsMǵy!ÐFp¥RàÞ¢
Øï¥"x_À^ðßÇB½Ãí*D€Àÿ}Àžþ=tó@¤Ö5І°C¡<'>ícûJþ•_ÞQ™DŒx)pâÚh	`kâz #‘ u~’žã¸®õÜ:`b?Õ»ú¬ˆ2À6ŠLu¾¶wÿ/ †<@`ÁÊBP"PËFrQ K9xœœ˜bûj˜À=H€»M÷ùó£¥úÖ<ü~(€²„“ô’öR
°^¯òŠ@ßïBÐÛÝ6!j5 ©,±• ƒGšuø'º÷þœÐPÃó’IÀœŒí+E¸obk´à/o•Ë£e¿¼Å‡1æx̱Ë‚àü¾Oè‡ßeÛ	£ìàzŸ¨ÕH ávÀ~§w>xà=Ÿã"€ÿ±1öÿ ÍvûA˜§IEND®B`‚tome-235-src/lib/xtra/music/0000755000076400017500000000000011012107763013532 5ustar  dgdgtome-235-src/lib/xtra/music/delete.me0000644000076400017500000000000111012107762015305 0ustar  dgdgatome-235-src/lib/xtra/sound/0000755000076400017500000000000011012107763013542 5ustar  dgdgtome-235-src/lib/xtra/sound/Sound.cfg0000644000076400017500000000206711012107763015320 0ustar  dgdg# sound.cfg
#
# Configuration file for the Angband sound events
#
# The format is:
# name of the Angband event = list of the available sample-names seperated by spaces.
#
# Example:
# hit = hit.wav hit1.wav
#
# Look at the definition of "angband_sound_name" in variable.c for a complete list of
# all the available event names.

[Sound]
hit = hit.wav drop.wav hit1.wav
miss = miss.wav miss1.wav
flee = flee.wav
drop = clunk.wav
kill = kill.wav destroy.wav kill1.wav
level = level.wav 
death = death.wav
study = 
teleport =
shoot = 
quaff = 
zap =
walk = 
tpother =
hitwall = 
eat = eat.wav
store1 = money.wav
store2 = money.wav
store3 = money.wav
store4 = money.wav
dig = thump.wav
opendoor = opendoor.wav
shutdoor = shutdoor.wav
tplevel = teleport.wav
scroll =
buy =
sell =
warn =
rocket =
n_kill =
u_kill =
quest =
heal =
x_heal =
bite =
claw =
m_spell =
summon =
breath =
ball =
m_heal =
atkspell =
evil =
touch =
sting =
crush =
slime =
wail =
winner =
fire =
acid =
elec =
cold =
illegal =
fail =
wakeup =
invuln =
fall =
pain =
destitem =
moan =
show =
unused =
explode =

tome-235-src/lib/xtra/sound/readme.txt0000644000076400017500000000130111012107763015533 0ustar  dgdgNew Sound Effect For Angband 2.8.1 Windows 95 (beta release)

Changes since Alpha release:

Altered sounds:	breath.wav
		death.wav
		flee.wav
		hit.wav
		kill.wav
		

New sounds:	None (no new events yet)


Useage:

Unzip files into your angband 2.8.1 sounds directory EG:

C:\angband-281\lib\xtra\sound

That's it!

If you wish to use the sounds for any other purpose or wish to include them as the default sounds
in your variant of Angband, contact me at either:

tim.haywood@ocean.co.uk		or		timothy.haywood@virgin.net

Legal Stuff:

This is a patch for Angband 2.8.1 (Windows95 Version).
Copyright @ 1997 Tim Haywood
Not for resale.
Not for release with original version of Angband without permission.
tome-235-src/lib/xtra/angband.fnt0000644000076400017500000001000011012107763014504 0ustar  dgdg00000000fB$lllþlllþlll|ÒÐð|>–|bf8pàÌŒ0hX8pòÔÈÔv0000000Öþ|î|þÖ~88 ~8pàÀ€&ffnvffd88x~fd8008 0`0~~ 00 |Ɔ000FFïüfbf|fbbfü>FÂÀÀÀÀÂæ|ünffffffdøþb`d|d``bþþb`d|d```ðI>I>I*""FH„%˜db!B88>C}EE~&___.8T(`HLLLP @|þ’ @ HL^~^LH@@@@@@8°@ ````p|^(ªª¾ü}}>8>AAA<~ÛÛ~~~~~Zf<<6www]kwfÛµ,VjVj~fÛµ,VjVj~fÛ½<~~~~~|‚‚’‚’ºþ"BD„‚‚bpبØp(‚88DDD800``"$(€PB$?}F|D|L|T|ü<Angband adaption code.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

/* hackdef.c
 * definion of hacklevel for iso view
 * 
 * Hj. Maltahner, Feb. 2001
 */
                          

/*
 * this enables somthing like a bigscreen mode but keeps a
 * resonable clean interfacing between iso-view and angband
 * this requires changes to map_info() to support clipping.
 * 
 * Hj. Maltahner, Feb. 2001
 */ 
#define USE_SMALL_ISO_HACK
tome-235-src/src/iso/simsys.h0000644000076400017500000000777211012107763013764 0ustar  dgdg/* simsys.h
 *
 * Copyright (c) 2001 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph graphics engine.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef simsys_h
#define simsys_h

#ifdef __cplusplus
extern "C" {
#endif

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif


/* Variablen zur Messageverarbeitung */

/* Klassen */

#define SIM_NOEVENT         0
#define SIM_MOUSE_BUTTONS   1
#define SIM_KEYBOARD        2
#define SIM_MOUSE_MOVE      3
#define SIM_IGNORE_EVENT    255

/* Aktionen */ /* added RIGHTUP and MIDUP */
#define SIM_MOUSE_LEFTUP            1
#define SIM_MOUSE_RIGHTUP           2
#define SIM_MOUSE_MIDUP             3
#define SIM_MOUSE_LEFTBUTTON        4
#define SIM_MOUSE_RIGHTBUTTON       5
#define SIM_MOUSE_MIDBUTTON         6
#define SIM_MOUSE_MOVED             7


/**
 * inits operating system stuff
 * @author Hj. Malthaner
 */
int dr_os_init(int n, int *parameter);


/**
 * opens graphics device/context/window of size w*h
 * @param w width
 * @param h height
 * @author Hj. Malthaner
 */
int dr_os_open(int w, int h);


/**
 * closes operating system stuff
 * @author Hj. Malthaner
 */
int dr_os_close();


/**
 * retrieve display width
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_get_width();


/**
 * retrieve display height
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_get_height();


/**
 * creates a (maybe virtual) array of graphics data
 * @author Hj. Malthaner
 */
unsigned short * dr_textur_init();


/**
 * displays the array of graphics data
 * @author Hj. Malthaner
 */
void dr_textur(int xp, int yp, int w, int h);


/**
 * use this method to flush graphics pipeline (undrawn stuff) onscreen.
 * @author Hj. Malthaner
 */
void dr_flush();


/**
 * set colormap entries
 * @author Hj. Malthaner
 */ 
void dr_setRGB8multi(int first, int count, unsigned char * data);


/**
 * display/hide mouse pointer
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void show_pointer(int yesno);


/**
 * move mouse pointer
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void move_pointer(int x, int y);


/**
 * update softpointer position
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void ex_ord_update_mx_my();


/**
 * get events from the system
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void GetEvents();


/**
 * get events from the system without waiting
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void GetEventsNoWait();


/**
 * @returns time since progrma start in milliseconds
 * @author Hj. Malthaner
 */
long long dr_time(void);


/**
 * sleeps some microseconds
 * @author Hj. Malthaner
 */
void dr_sleep(unsigned long usec);


/**
 * loads a sample
 * @return a handle for that sample or -1 on failure
 * @author Hj. Malthaner
 */
int dr_load_sample(const char *filename);


/**
 * plays a sample
 * @param key the key for the sample to be played
 * @author Hj. Malthaner
 */
void dr_play_sample(int key, int volume);

#ifdef __cplusplus
}
#endif

#endif

tome-235-src/src/iso/world_view.c0000644000076400017500000002617411012107763014606 0ustar  dgdg/* world_view.c
 *
 * Copyright (c) 2001, 2002 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph<->Angband adaption code.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include 
#include "simgraph.h" 
#include "world_view.h" 
#include "world_adaptor.h" 

//#include "walls4.h"
#include "walls9.h"

#include "hackdef.h"


#undef MIN
#undef MAX


#include "../angband.h"
#include "../defines.h"


/* from isov-x11.c */
extern unsigned char **iso_ap;
extern unsigned char **iso_cp;
extern unsigned char **iso_atp;
extern unsigned char **iso_ctp;
# ifdef USE_EGO_GRAPHICS
extern unsigned char **iso_aep;
extern unsigned char **iso_cep;
# endif /* USE_EGO_GRAPHICS */


#ifdef USE_SMALL_ISO_HACK

static bool is_valid_position(int x, int y) {
  return x >= 0 && y >= 0 && xfeat;
}


static int get_feat_wc(int x, int y)
{
  if(is_valid_position(x,y)) {
    return get_feat_nc(x,y);
  } else {
    return FEAT_PERM_SOLID;
  }
}


static int get_info_nc(int x, int y)
{
  /* this is for Angabdn 2.9.1
     return cave_info[y][x];     
  */
  
  /* Pernangband 4.1.5 */
  cave_type *c_ptr;
  
  /* Get the cave */
  c_ptr = &cave[y][x];
  
  
  /* Info code */
  return c_ptr->info;
}


static int get_info_wc(int x, int y)
{
  if(is_valid_position(x,y)) {
    return get_info_nc(x,y);
  } else {
    return 0;
  }
}


static bool is_door(int feat)
{
  return 
    (feat == FEAT_OPEN) ||
    (feat == FEAT_BROKEN) ||
    (feat == FEAT_SECRET) ||
    (feat >= FEAT_DOOR_HEAD &&  feat <= FEAT_DOOR_TAIL) ||
    (feat == FEAT_SHOP);
}


static bool is_wall(int feat)
{
  return 
    (feat >= FEAT_MAGMA &&  feat <= FEAT_PERM_SOLID) || 
    (feat >= FEAT_TREES &&  feat <= FEAT_SANDWALL_K) ||
    (feat >= FEAT_QUEST1 && feat <= FEAT_QUEST4);
}


static int is_wall_or_door(int x, int y)
{           
  const int feat = get_feat_wc(x, y);
  
  return is_door(feat) || is_wall(feat);
}


static bool is_lit(int x, int y)
{
  const int info = get_info_wc(x, y);
  
  return (info & CAVE_GLOW) && (info & CAVE_VIEW) && (info & CAVE_MARK);
}


static bool is_torch_lit(int x, int y)
{
  const int info = get_info_wc(x, y);
  
  return (info & CAVE_PLIT) && (info & CAVE_VIEW) && (info & CAVE_MARK);
}


static bool is_only_torch_lit(int x, int y)
{
  return is_torch_lit(x, y) & !is_lit(x, y);
}


static bool is_blind()
{
  // PernAngband variant
  return p_ptr->blind;
}


/**
 * Calculates distance from player to point (x,y).
 * Uses the distance guess from cave.c
 * @author Hj. Malthaner
 */
static int get_distance_to_player(int x, int y)
{                                
  return distance(y, x, p_ptr->py, p_ptr->px);
}

#else


static int iso_access(unsigned char **field, int x, int y)
{
  if(x >= 0 && y >= 0 && x<80 && y<24) {
    return field[y][x] & 0x7f;
  } else {
    return 0;
  }                       
}

static int is_wall_or_door(int x, int y)
{           
  const int atp = iso_access(iso_atp, x, y);
  const int ctp = iso_access(iso_ctp, x, y);
  
  return (atp == 0x01 && (ctp >= 0x70 && ctp <= 0x75)) ||
    (atp == 0x00  && (ctp =='+' || ctp == '\'')) ;
}

#endif


/**
 * Draw ground of location i,j onto screen position xpos,ypos
 * @author Hj. Malthaner
 */
void display_boden(int x, int y, int xpos, int ypos)
{
  // unused in Iso-Angband
}


static int check_wall(int x, int y) 
{
  
  int o = 0;

#if 0
  o |= (is_wall_or_door(x-1, y-1)) << 0;
  o |= (is_wall_or_door(x  , y-1)) << 1;
  o |= (is_wall_or_door(x+1, y-1)) << 2;
  o |= (is_wall_or_door(x-1, y  )) << 3;
  o |= (is_wall_or_door(x+1, y  )) << 4;
  o |= (is_wall_or_door(x-1, y+1)) << 5;
  o |= (is_wall_or_door(x  , y+1)) << 6;
  o |= (is_wall_or_door(x+1, y+1)) << 7;
  
  
  return wall_table[o];
#endif
  // jue: new algorithm as suggested by James Andrewartha
  //
  o |= (is_wall_or_door(x-1, y-1) 
          && is_wall_or_door(x, y-1)
          && is_wall_or_door(x-1,y))  << 0;

  o |= (is_wall_or_door(x  , y-1))    << 1;
  
  o |= (is_wall_or_door(x+1, y-1)
	  && is_wall_or_door(x, y-1)
	  && is_wall_or_door(x+1, y)) << 2;
  
  o |= (is_wall_or_door(x-1, y  ))    << 3;
  
  o |= (is_wall_or_door(x+1, y  ))    << 4;
  
  o |= (is_wall_or_door(x-1, y+1)
	  && is_wall_or_door(x-1, y)
	  && is_wall_or_door(x, y+1)) << 5;
  
  o |= (is_wall_or_door(x  , y+1))    << 6;
  
  o |= (is_wall_or_door(x+1, y+1)
	  && is_wall_or_door(x+1, y)
	  && is_wall_or_door(x, y+1)) << 7;
  
  return o;
}


static int door_direction(int x, int y)
{                 
  if(is_wall_or_door(x-1, y) && is_wall_or_door(x+1, y)) {
    return 1;
  } else {
    return 0;
  }
}

static int calc_nc(int c, int a)
{
  return ((a & 0x7F) << 7) + (c & 0x7F);
}


/**
 * Draw objects of location i,j onto screen position xpos,ypos
 * @author Hj. Malthaner
 */
void display_dinge(int x, int y, int xpos, int ypos)
{
  const int grid = get_grid();

  int feat_nc = -1;
  int obj_nc = -1;
#ifdef USE_EGO_GRAPHICS
  int ego_nc = -1;
#endif
  
  int shade;
  int i;

  // relative to view position
//  int xoff = x - p_ptr->px + (SCREEN_WID/2 + 13);
//  int xoff = x - p_ptr->px + (SCREEN_WID/2 + 13);
//
//  new (jue):
//  look at cave.c, panel_col_of and the places it's used...
  int xoff = x - panel_col_min + COL_MAP;
  int yoff = y - panel_row_prt;

  // try to use output of the term package
  if(xoff >= 0 && yoff >= 1 && xoff < 80 && yoff < 23) {
    // floor, walls
    
    const int c = iso_cp[yoff][xoff];
    const int a = iso_ap[yoff][xoff];
    
    // object/monster
    const int tc = iso_ctp[yoff][xoff];
    const int ta = iso_atp[yoff][xoff];

#ifdef USE_EGO_GRAPHICS
    // transparent overlay 
    const int ec = iso_cep[yoff][xoff];
    const int ea = iso_aep[yoff][xoff];
    
    ego_nc = calc_nc(ec, ea);
#endif
    feat_nc = calc_nc(tc, ta);
    obj_nc = calc_nc(c, a);

  } else {
    // outside 80x24 view, try to read map

    if(is_valid_to_show(x,y)) {
      
      byte a, ta;
      char c, tc;
#ifdef USE_EGO_GRAPHICS
      byte ea;
      char ec;

      map_info(y, x, &a, &c, &ta, &tc, &ea, &ec);
      ego_nc = calc_nc(ec, ea);
#else
      map_info(y, x, &a, &c, &ta, &tc);
#endif
      feat_nc = calc_nc(tc, ta);
      obj_nc = calc_nc(c, a);
    } 

  }



  shade = 1;
      
  if(is_lit(x, y)) {
    shade = 2;
  } else if(is_torch_lit(x, y)) {
    shade = 0;
  }

  
  // did we get some data ?
  if(feat_nc != -1) {
    
    // check shading
    //	printf("%d %d -> %d\n", x, y, shade);
    
    if(feat_nc >= 240 &&  feat_nc <= 245) {
      // old shading
      //	    const int shade = (feat_nc-240);
      const int set_base = 240+shade*9;
      const int bits = check_wall(x, y);
      
      
      display_img(316+(shade%3), xpos, ypos, TRUE);
      
      if(bits) {
	for(i=0; i<4; i++) {
	  if(bits & (1 << i)) {
	    display_img(set_base+i, xpos, ypos, TRUE);
	  }
	}                         
	
	display_img(set_base+8, xpos, ypos, TRUE);
	
	for(i=4; i<8; i++) {
	  if(bits & (1 << i)) {
	    display_img(set_base+i, xpos, ypos, TRUE);
	  }
	}                         
	
      } else {
	// a pillar 
	display_img(set_base+8, xpos, ypos, TRUE);
      }
      
      // fields with walls never contain anything else
      // so we can quit now
      return;
      
    } else if(feat_nc == 0x27) {
      // open doors   
      display_img(138+door_direction(x,y), xpos, ypos, TRUE);
      
      
    } else if(feat_nc == 0x2B) {
      // closed doors
      display_img(136+door_direction(x,y), xpos, ypos, TRUE);
      
    } else if(feat_nc == 0x8C ||	    // a between gate
	      feat_nc == 0x20 ||	    // empty square
	      feat_nc == 0x16E ||	    // brick roof
	      feat_nc == 0x16F ||	    // brick roof top
	      feat_nc == 0x176 ||	    // grass roof
	      feat_nc == 0x177 ||	    // grass roof chimney
	      feat_nc == 0x17E ||	    // grass roof top
	      (feat_nc >= 0x31 && feat_nc <= 0x39) || // shop with number
	      (feat_nc >= 0x576 && feat_nc <= 0x57D) || // trap
	      feat_nc == 0x3E ||	    // down stairs
	      feat_nc == 0x3C	    // up stairs
    ) {
      // this features should not be shaded
      
      display_img(feat_nc, xpos, ypos, TRUE);
      
    } else if(feat_nc > 2){             
      // this features should be shaded  
          
      // floor
      // known grids get shaded floors
      if(is_only_torch_lit(x,y)) {
	display_color_img(feat_nc+2, 
			  xpos, ypos, 
			  get_distance_to_player(x, y) << 1,
			  TRUE);
      } else {
	display_img(feat_nc+shade, xpos, ypos, TRUE);
      }               
    }
    
    //	printf("%d a=%x c=%x (%c)\n", nc, a, c, c);
  
    /* Hajo: display a complete grid if the user wants to */
    if(grid == 2) {
	display_img(6, xpos, ypos, TRUE);
    }


#ifdef USE_EGO_GRAPHICS   
    if( ego_nc != feat_nc &&
	ego_nc > 2 &&
	ego_nc != 0x27 &&
	ego_nc != 0x2B ) {

	display_img(ego_nc, xpos, ypos, TRUE);
    }
#endif
    
    if( obj_nc != feat_nc &&
	obj_nc > 2 &&
	obj_nc != 0x27 &&
	obj_nc != 0x2B ) {

	/* Hajo: display a grid below items/monsters if the user wants to */
	if(grid == 1) {
	    display_img(5, xpos, ypos, TRUE);
	}
	
	display_img(obj_nc, xpos, ypos, TRUE);

    }
  } else {
    
    // outside of dungeon
    display_img(32, xpos, ypos, TRUE);
  }  

  /* display cursor ? */
  if( 
      high_x >= 1 &&
      high_y >= 1) {
      if(xoff == high_x && 
	  yoff == high_y) {
        display_img(7, xpos, ypos, TRUE);

	/* only draw once, wait until next request */
	high_x = high_y = -1;
    }
  }
}

tome-235-src/src/iso/world_view.h0000644000076400017500000000310411012107763014577 0ustar  dgdg/* world_view.h
 *
 * Copyright (c) 2001 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph<->Angband adaption code.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef hajo_world_view_h
#define hajo_world_view_h



/**
 * Draw ground of location i,j onto screen position xpos,ypos
 * @author Hj. Malthaner
 */
void display_boden(int i, int j, int xpos, int ypos);


/**
 * Draw objects of location i,j onto screen position xpos,ypos
 * @author Hj. Malthaner
 */
void display_dinge(int i, int j, int xpos, int ypos);


#endif
tome-235-src/src/iso/walls4.h0000644000076400017500000000723211012107763013632 0ustar  dgdg/* walls4.h
 *
 * Copyright (c) 2001 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph<->Angband adaption code.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

int wall_table[256] =
{
0,	// 0
0,	// 1
2,	// 2
0,	// 3
0,	// 4
0,	// 5
0,	// 6
0,	// 7
1,	// 8
0,	// 9
3,	// 10
3,	// 11
0,	// 12
0,	// 13
3,	// 14
3,	// 15
4,	// 16
0,	// 17
6,	// 18
6,	// 19
0,	// 20
0,	// 21
6,	// 22
0,	// 23
5,	// 24
5,	// 25
7,	// 26
0,	// 27
5,	// 28
0,	// 29
7,	// 30
5,	// 31
0,	// 32
0,	// 33
0,	// 34
0,	// 35
0,	// 36
0,	// 37
0,	// 38
0,	// 39
0,	// 40
0,	// 41
0,	// 42
0,	// 43
0,	// 44
0,	// 45
0,	// 46
0,	// 47
0,	// 48
0,	// 49
0,	// 50
0,	// 51
0,	// 52
0,	// 53
0,	// 54
0,	// 55
5,	// 56
5,	// 57
0,	// 58
0,	// 59
5,	// 60
0,	// 61
0,	// 62
0,	// 63
8,	// 64
0,	// 65
10,	// 66
10,	// 67
0,	// 68
0,	// 69
10,	// 70
10,	// 71
9,	// 72
9,	// 73
0,	// 74
10,	// 75
0,	// 76
0,	// 77
0,	// 78
0,	// 79
12,	// 80
0,	// 81
0,	// 82
0,	// 83
0,	// 84
0,	// 85
10,	// 86
0,	// 87
13,	// 88
0,	// 89
0,	// 90
0,	// 91
13,	// 92
0,	// 93
0,	// 94
0,	// 95
0,	// 96
0,	// 97
10,	// 98
0,	// 99
0,	// 100
0,	// 101
10,	// 102
0,	// 103
9,	// 104
0,	// 105
10,	// 106
10,	// 107
0,	// 108
0,	// 109
0,	// 110
10,	// 111
12,	// 112
0,	// 113
0,	// 114
0,	// 115
0,	// 116
0,	// 117
0,	// 118
0,	// 119
0,	// 120
12,	// 121
0,	// 122
0,	// 123
0,	// 124
0,	// 125
0,	// 126
0,	// 127
0,	// 128
0,	// 129
0,	// 130
0,	// 131
0,	// 132
0,	// 133
0,	// 134
0,	// 135
0,	// 136
0,	// 137
0,	// 138
0,	// 139
0,	// 140
0,	// 141
0,	// 142
0,	// 143
0,	// 144
0,	// 145
0,	// 146
6,	// 147
0,	// 148
0,	// 149
0,	// 150
0,	// 151
5,	// 152
5,	// 153
0,	// 154
0,	// 155
5,	// 156
0,	// 157
0,	// 158
0,	// 159
0,	// 160
0,	// 161
0,	// 162
0,	// 163
0,	// 164
0,	// 165
0,	// 166
0,	// 167
0,	// 168
0,	// 169
0,	// 170
0,	// 171
0,	// 172
0,	// 173
0,	// 174
0,	// 175
0,	// 176
0,	// 177
0,	// 178
0,	// 179
0,	// 180
0,	// 181
0,	// 182
0,	// 183
5,	// 184
0,	// 185
7,	// 186
0,	// 187
0,	// 188
0,	// 189
0,	// 190
0,	// 191
0,	// 192
0,	// 193
10,	// 194
10,	// 195
0,	// 196
0,	// 197
0,	// 198
0,	// 199
9,	// 200
0,	// 201
0,	// 202
0,	// 203
0,	// 204
0,	// 205
0,	// 206
0,	// 207
12,	// 208
0,	// 209
10,	// 210
0,	// 211
0,	// 212
0,	// 213
10,	// 214
10,	// 215
0,	// 216
0,	// 217
0,	// 218
0,	// 219
0,	// 220
0,	// 221
0,	// 222
0,	// 223
0,	// 224
0,	// 225
10,	// 226
0,	// 227
0,	// 228
0,	// 229
0,	// 230
0,	// 231
0,	// 232
0,	// 233
0,	// 234
10,	// 235
0,	// 236
0,	// 237
0,	// 238
0,	// 239
0,	// 240
0,	// 241
14,	// 242
0,	// 243
0,	// 244
0,	// 245
10,	// 246
0,	// 247
5,	// 248
0,	// 249
0,	// 250
0,	// 251
0,	// 252
0,	// 253
0,	// 254
0,	// 255
};
tome-235-src/src/iso/walls9.h0000644000076400017500000000777211012107763013650 0ustar  dgdg/* walls9.h
 *
 * Copyright (c) 2001 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph<->Angband adaption code.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

int wall_table[256] =
{
0,	// 0
1,	// 1
2,	// 2
3,	// 3
4,	// 4
5,	// 5
2,	// 6
7,	// 7
8,	// 8
8,	// 9
10,	// 10
11,	// 11
12,	// 12
13,	// 13
10,	// 14
11,	// 15
16,	// 16
17,	// 17
18,	// 18
18,	// 19
16,	// 20
21,	// 21
22,	// 22
22,	// 23
24,	// 24
24,	// 25
26,	// 26
27,	// 27
24,	// 28
24,	// 29
30,	// 30
31,	// 31
32,	// 32
33,	// 33
34,	// 34
35,	// 35
36,	// 36
37,	// 37
38,	// 38
39,	// 39
40,	// 40
41,	// 41
10,	// 42
43,	// 43
44,	// 44
45,	// 45
46,	// 46
47,	// 47
48,	// 48
49,	// 49
50,	// 50
51,	// 51
52,	// 52
53,	// 53
54,	// 54
55,	// 55
24,	// 56
24,	// 57
58,	// 58
27,	// 59
24,	// 60
61,	// 61
62,	// 62
31,	// 63
64,	// 64
65,	// 65
66,	// 66
66,	// 67
68,	// 68
69,	// 69
66,	// 70
66,	// 71
72,	// 72
72,	// 73
74,	// 74
75,	// 75
76,	// 76
77,	// 77
74,	// 78
75,	// 79
80,	// 80
81,	// 81
82,	// 82
82,	// 83
80,	// 84
85,	// 85
86,	// 86
86,	// 87
88,	// 88
88,	// 89
90,	// 90
91,	// 91
88,	// 92
93,	// 93
94,	// 94
95,	// 95
64,	// 96
97,	// 97
66,	// 98
66,	// 99
100,	// 100
101,	// 101
66,	// 102
103,	// 103
104,	// 104
105,	// 105
106,	// 106
107,	// 107
108,	// 108
109,	// 109
106,	// 110
107,	// 111
80,	// 112
113,	// 113
82,	// 114
115,	// 115
116,	// 116
117,	// 117
118,	// 118
119,	// 119
120,	// 120
121,	// 121
122,	// 122
123,	// 123
124,	// 124
125,	// 125
126,	// 126
127,	// 127
128,	// 128
129,	// 129
130,	// 130
131,	// 131
132,	// 132
133,	// 133
134,	// 134
135,	// 135
136,	// 136
137,	// 137
138,	// 138
139,	// 139
140,	// 140
141,	// 141
142,	// 142
143,	// 143
16,	// 144
145,	// 145
18,	// 146
147,	// 147
148,	// 148
149,	// 149
22,	// 150
22,	// 151
24,	// 152
24,	// 153
154,	// 154
155,	// 155
24,	// 156
157,	// 157
158,	// 158
31,	// 159
160,	// 160
161,	// 161
66,	// 162
163,	// 163
164,	// 164
165,	// 165
166,	// 166
167,	// 167
168,	// 168
169,	// 169
170,	// 170
171,	// 171
172,	// 172
173,	// 173
174,	// 174
175,	// 175
176,	// 176
177,	// 177
178,	// 178
179,	// 179
180,	// 180
181,	// 181
182,	// 182
183,	// 183
24,	// 184
185,	// 185
26,	// 186
187,	// 187
24,	// 188
189,	// 189
190,	// 190
31,	// 191
64,	// 192
193,	// 193
66,	// 194
66,	// 195
196,	// 196
197,	// 197
66,	// 198
66,	// 199
72,	// 200
201,	// 201
74,	// 202
203,	// 203
204,	// 204
205,	// 205
206,	// 206
207,	// 207
208,	// 208
209,	// 209
210,	// 210
211,	// 211
208,	// 212
213,	// 213
214,	// 214
214,	// 215
216,	// 216
217,	// 217
218,	// 218
219,	// 219
220,	// 220
221,	// 221
222,	// 222
223,	// 223
224,	// 224
225,	// 225
66,	// 226
227,	// 227
228,	// 228
229,	// 229
230,	// 230
231,	// 231
104,	// 232
233,	// 233
234,	// 234
107,	// 235
236,	// 236
237,	// 237
238,	// 238
239,	// 239
208,	// 240
241,	// 241
210,	// 242
243,	// 243
244,	// 244
245,	// 245
214,	// 246
214,	// 247
248,	// 248
248,	// 249
250,	// 250
251,	// 251
248,	// 252
248,	// 253
254,	// 254
255,	// 255
};
tome-235-src/src/iso/readme.txt0000644000076400017500000000016311012107763014245 0ustar  dgdgThe iso view sources will reside here. 

At the moment this is just a test for CVS access.

--
Hansjoerg Malthaner
tome-235-src/src/iso/world_adaptor.c0000644000076400017500000000735511012107763015266 0ustar  dgdg/* world_adaptor.cc
 *
 * Copyright (c) 2001, 2002 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph<->Angband adaption code.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

/* world_adaptor.c
 *
 * adaption between angband world and simugraph data model
 * Hj. Maltahner, Jan. 2001
 */

#include "hackdef.h"

#include "world_adaptor.h"
#include "world_view.h"
#include "simview.h"
#include "simgraph.h"

#undef MIN
#undef MAX

#include "../angband.h"


/* 
 * Highlit location 
 */
int high_x = -1;
int high_y = -1;

/**
 * remember targetted location
 * (hook is ToME3 only, for now)
 * @author J. Frieling
 */
bool iso_target_hook(char* fmt)
{
  high_y = get_next_arg(fmt);
  high_x = get_next_arg(fmt);

  return FALSE;
}

/**
 * Highlite (mark) location x,y
 * @author Hj. Malthaner
 */
void highlite_spot(int x, int y)
{
  high_x = x;
  high_y = y;
}


/**
 * Grid type, default is grid for items and monsters
 * 0: No grid
 * 1: Item/monster grid
 * 2: Full grid
 * @author Hj. Malthaner
 */
static int grid = 1;
                     

/**
 * Show shadow below items and monsters?
 * 0 = no
 * 1 = yes
 * @author Hj. Malthaner
 */
//int shadow = 1;


/**
 * Set a grid type (takes argument modulo 3)
 * @author Hj. Malthaner
 */
void set_grid(int no)
{
  grid = no % 3;
}


/**
 * Show which grid type ?
 * @author Hj. Malthaner
 */
int get_grid()
{
  return grid;
}


/**
 * Turn shadows on/off (0=off, 1=on)
 * @author Hj. Malthaner
 */
/*void set_shadow(int yesno)
{
  shadow = yesno;
}
*/


/**
 * Determines i-offset of the watch point
 * @author Hj. Malthaner
 */
int get_i_off()
{
    const int p_off = display_get_width() >> 7;
    const int mult = display_get_tile_size() == 32 ? 2 : 1;

#ifdef USE_SMALL_ISO_HACK

    int i_off;

    if(p_ptr) {
	i_off = p_ptr->px-p_off*mult;
    }

    return i_off;     
#else

    return 47-p_off;


#endif
}


/**
 * Determines j-offset of the watch point
 * @author Hj. Malthaner
 */
int get_j_off()
{
    const int p_off = display_get_width() >> 7;
    const int mult = display_get_tile_size() == 32 ? 2 : 1;

#ifdef USE_SMALL_ISO_HACK

    int j_off;
    if(p_ptr) {
	j_off = p_ptr->py-p_off*mult;
    }

    return j_off;     
#else

    return 10-p_off;

#endif
}



/**
 * Ermittelt x-Offset gescrollter Karte
 * @author Hj. Malthaner
 */
int get_x_off()
{
    return 0;
}


/**
 * Ermittelt y-Offset gescrollter Karte
 * @author Hj. Malthaner
 */
int get_y_off()
{
    return 0;
}

                                     

int init_adaptor()
{
    printf("Preparing display ...\n");
    simgraph_init(672, 480);

    return TRUE;
}


int refresh_display()
{
    display();
    display_flush_buffer();

    return TRUE;
}


int close_adaptor()
{
    simgraph_exit();

    return TRUE;
}
tome-235-src/src/iso/world_adaptor.h0000644000076400017500000000473311012107763015270 0ustar  dgdg/* world_adaptor.h
 *
 * Copyright (c) 2001 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph<->Angband adaption code.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */


#ifndef hajo_world_adaptor_h
#define hajo_world_adaptor_h

/* world_adapter.h
 *
 * adpater between angband code and simugraph engine
 * Hj. Malthaner, Jan 2001
 */

// I need angband's bool
#include "../h-type.h"

/* 
 * Highlit location - use read only! 
 */
extern int high_x;
extern int high_y;

int init_adaptor();
int close_adaptor();

int refresh_display();

/**
 * remember targetted location
 * @author J. Frieling
 */
bool iso_target_hook(char *fmt);

/**
 * Highlite (mark) location x,y
 * @author Hj. Malthaner
 */
void highlite_spot(int x, int y);

/**
 * Set a grid type (takes argument modulo 3)
 * @author Hj. Malthaner
 */
void set_grid(int no);


/**
 * Show which grid type ?
 * @author Hj. Malthaner
 */
int get_grid();

                  
/**
 * Turn shadows on/off (0=off, 1=on)
 * @author Hj. Malthaner
 */
//void set_shadow(int yesno);



/**
 * Ermittelt x-Offset gescrollter Karte
 * @author Hj. Malthaner
 */
int get_x_off();


/**
 * Ermittelt y-Offset gescrollter Karte
 * @author Hj. Malthaner
 */
int get_y_off();

                                     
/**
 * Determines i-offset of the watch point
 * @author Hj. Malthaner
 */
int get_i_off();


/**
 * Determines j-offset of the watch point
 * @author Hj. Malthaner
 */
int get_j_off();


#endif

tome-235-src/src/iso/simgraph.c0000644000076400017500000007071411012107763014236 0ustar  dgdg/* simgraph.c
 *
 * Copyright (c) 2001 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph graphics engine.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */


/* simgraph.c
 * 
 * Versuch einer Graphic fuer Simulationsspiele
 * Hj. Malthaner, Aug. 1997
 *                                     
 * A try to create a graphics engine for simulation games.
 *
 * 3D, isometrische Darstellung        
 *
 * 3D, isometric display
 *
 *
 * 18.11.97 lineare Speicherung fuer Images -> hoehere Performance
 * 22.03.00 run längen Speicherung fuer Images -> hoehere Performance 
 * 15.08.00 dirty tile verwaltung fuer effizientere updates
 */

//#define DEBUG 1


#if defined(MSDOS) || defined(__MINGW32__)
#define USE_SOFTPOINTER
#endif

#include 
#include 
#include 
#include 

#include "simgraph.h"
#include "simsys.h"                

extern unsigned int   class;
extern unsigned int   code;
extern int            mx,my;             /* es sind negative Koodinaten mgl */

#ifdef USE_SOFTPOINTER
static int softpointer = 261;
static int old_my = -1;              // die icon leiste muss neu gezeichnet werden wenn der
                                     // Mauszeiger darueber schwebt 
#endif

static unsigned char dr_fonttab[2048];  /* Unser Zeichensatz sitzt hier */

/*
 * pixel value type, RGB 555
 */
typedef unsigned short PIXVAL;


struct imd {
    int y;           // offset top
    int h;           // image height
    int len;         // data length in entities of PIXVAL size
    PIXVAL * data;   // iamge data
}; 
                                

static int anz_images = 0; 

static int disp_width = 640;
static int disp_height = 480;

/**
 * Tile size in pixels
 *
 * @author Hj. Malthaner
 */
static int tile_size = 32;

static struct imd *images = NULL;
static struct imd *images1 = NULL;
static struct imd *images2 = NULL;


static PIXVAL *textur = NULL;


static struct clip_dimension clip_rect;


// dirty tile management strcutures
            
#define DIRTY_TILE_SIZE 32
#define DIRTY_TILE_SHIFT 5

static char *tile_dirty = NULL;
static char *tile_dirty_old = NULL;

static int tiles_per_line = 0;
static int tile_lines = 0;
                                  

// colormap management structures

static unsigned char day_pal[256*3];
static unsigned char night_pal[256*3];
static unsigned char base_pal[256*3];

static int light_level = 0;
static int color_level = 1;


// ------------ procedure like defines --------------------


#define mark_tile_dirty(x,y) tile_dirty[(x) + (y)*tiles_per_line] = 1
#define is_tile_dirty(x,y) ((tile_dirty[(x) + (y)*tiles_per_line]) || (tile_dirty_old[(x) + (y)*tiles_per_line])  )

// ----------------- procedures ---------------------------
            

/**
 * Markiert ein Tile as schmutzig, ohne Clipping
 * @author Hj. Malthaner
 */
static void mark_rect_dirty_nc(int x1, int y1, int x2, int y2)
{      
    int x, y;
    
    // floor to tile size

    x1 >>= DIRTY_TILE_SHIFT;
    y1 >>= DIRTY_TILE_SHIFT;
    x2 >>= DIRTY_TILE_SHIFT;
    y2 >>= DIRTY_TILE_SHIFT;

    for(y=y1; y<=y2; y++) {
	for(x=x1; x<=x2; x++) {
	    mark_tile_dirty(x, y);
	}
    }    
}

/**
 * Markiert ein Tile as schmutzig, mit Clipping
 * @author Hj. Malthaner
 */
void mark_rect_dirty_wc(int x1, int y1, int x2, int y2)
{      
    if(x1 < 0) x1 = 0;
    if(x1 >= disp_width) x1 = disp_width-1;

    if(y1 < 0) y1 = 0;
    if(y1 >= disp_height) y1 = disp_height-1;

    if(x2 < 0) x2 = 0;
    if(x2 >= disp_width) x2 = disp_width-1;

    if(y2 < 0) y2 = 0;
    if(y2 >= disp_height) y2 = disp_height-1;

    mark_rect_dirty_nc(x1, y1, x2, y2);
}

/**
 * Clipped einen Wert in Intervall
 * @author Hj. Malthaner
 */
static int clip(int w, int u, int o)
{
    return w < u ? u : w > o ? o : w;
}


/**
 * Laedt den Font
 * @author Hj. Malthaner
 */
static void init_font()
{
    FILE *f = NULL;

    // suche in ./draw.fnt

    if(f==NULL ) {
	f=fopen("./draw.fnt","rb");
    }

    if(f==NULL) {
	printf("Cannot open draw.fnt!\n");
	exit(1);
    } else {
	int i;
	for(i=0;i<2048;i++) dr_fonttab[i]=getc(f);
	    fclose(f);
    }
}

/**
 * Laedt die Palette
 * @author Hj. Malthaner
 */
static int
load_palette(const char *fname, unsigned char *palette)
{
    FILE *file = fopen(fname,"rb");

    if(file) {

	int    x;
        int    anzahl=256;
	int    r,g,b;

        fscanf(file, "%d", &anzahl);

        for(x=0; x 3) {
	color_level = 3;
    }
    
    switch(color_level) {
    case 0:
	load_palette("./simud70.pal", day_pal);
	load_palette("./simun70.pal", night_pal);
	break;
    case 1:
	load_palette("./simud80.pal", day_pal);
	load_palette("./simun80.pal", night_pal);
	break;
    case 2:
	load_palette("./simud90.pal", day_pal);
	load_palette("./simun90.pal", night_pal);
	break;
    case 3:
	load_palette("./simud100.pal", day_pal);
	load_palette("./simun100.pal", night_pal);
	break;
    }                         

    memcpy(base_pal, day_pal, 256*3);
    display_set_light(display_get_light());
}


static int night_shift = -1;

static void calc_base_pal_from_night_shift(const int night)
{                                                
    const int day = 4 - night;
    int i;

    for(i=0; i<256; i++) {
	base_pal[i*3+0] = (day_pal[i*3+0] * day + night_pal[i*3+0] * night) >> 2;
	base_pal[i*3+1] = (day_pal[i*3+1] * day + night_pal[i*3+1] * night) >> 2;
	base_pal[i*3+2] = (day_pal[i*3+2] * day + night_pal[i*3+2] * night) >> 2;
    }
}

    
void display_day_night_shift(int night)
{
    if(night != night_shift) {
	night_shift = night;

	calc_base_pal_from_night_shift(night);	

	display_set_light(light_level);
	mark_rect_dirty_nc(0,0, disp_width-1, disp_height-1);
    }
}



/**
 * Setzt Farbeintrag
 * @author Hj. Malthaner
 */
void display_set_player_colors(const unsigned char *day, const unsigned char *night)
{
    memcpy(day_pal, day, 12);
    memcpy(night_pal, night, 12);

    calc_base_pal_from_night_shift(night_shift);	

    display_set_light(light_level);
    mark_rect_dirty_nc(0,0, disp_width-1, disp_height-1);
}


/**
 * Liest 32Bit wert Plattfromunabhängig
 * @author Hj. Malthaner
 */
static int fread_int(FILE *f)
{
    int i = 0;

    i += fgetc(f);
    i += fgetc(f) << 8;
    i += fgetc(f) << 16;
    i += fgetc(f) << 24;

    return i;
}


/**
 * Laedt daten.pak
 * @author Hj. Malthaner
 */
static struct imd * init_images(const char *filename)
{                                                   
    FILE *f = fopen(filename, "rb");                
    struct imd * images = NULL;

    if( f ) {
	int i;

	anz_images = fread_int(f);
	images = malloc(sizeof(struct imd)*anz_images);


	for(i=0; i 0) {            
                images[i].data = malloc(images[i].len*sizeof(PIXVAL));
		fread(images[i].data, images[i].len*sizeof(PIXVAL), 1, f);

	    } else {
		images[i].data = NULL;
	    }          
	}

	fclose(f);
    } else {
	printf("Kann '%s' nicht lesen.\n", filename);
	exit(1);
    }

    return images;
}

/**
 * Holt Maus X-Position 
 * @author Hj. Malthaner
 */
int gib_maus_x()
{
    return mx;
}

/**
 * Holt Maus y-Position 
 * @author Hj. Malthaner
 */
int gib_maus_y()
{
    return my;
}

                     
/**
 * this sets width < 0 if the range is out of bounds
 * so check the value after calling and before displaying
 * @author Hj. Malthaner
 */
static int clip_wh(int *x, int *width, const int min_width, const int max_width)
{
    // doesnt check "wider than image" case

    if(*x < min_width) {
	const int xoff = min_width - (*x);

	*width += *x;
	*x = min_width;
	return xoff;
    } else if(*x + *width >= max_width) {
	*width = max_width - *x;
    }
    return 0;
} 


/**
 * Ermittelt Clipping Rechteck
 * @author Hj. Malthaner
 */
struct clip_dimension display_gib_clip_wh(void)
{
    return clip_rect;
}


/**
 * Setzt Clipping Rechteck
 * @author Hj. Malthaner
 */
void display_setze_clip_wh(int x, int y, int w, int h)
{
    clip_wh(&x, &w, 0, disp_width);
    clip_wh(&y, &h, 0, disp_height);

    clip_rect.x = x;
    clip_rect.y = y;
    clip_rect.w = w;
    clip_rect.h = h;    

    clip_rect.xx = x+w-1;
    clip_rect.yy = y+h-1;
}

// ----------------- basic painting procedures ----------------


/**
 * Kopiert Pixel von src nach dest
 * @author Hj. Malthaner
 */
static void pixcopy(PIXVAL *dest,
                    const PIXVAL *src,
                    int len)
{
    memcpy(dest, src, len*sizeof(PIXVAL));
}


/**
 * Zeichnet Bild mit Clipping
 * @author Hj. Malthaner
 */
static void
display_img_wc(const int n, const int xp, const int yp, const int dirty)
{       
    if(n >= 0 && n < anz_images) {

	int h = images[n].h;
	int y = yp + images[n].y;

        int yoff = clip_wh(&y, &h, 0, clip_rect.yy);

	if(h > 0) {
            const int width = disp_width;
            const PIXVAL *sp = images[n].data;
            PIXVAL *tp = textur + y*width;

	    if(dirty) {
		mark_rect_dirty_wc(xp, y, xp+tile_size-1, y+h+1);
	    }

	    // oben clippen
	    
	    while(yoff) {
		yoff --;
		do {
		    if(*(++sp)) {
			sp += *sp + 1;
		    }                        		    
		} while(*sp);
		sp ++;
	    }		    

	    do { // zeilen dekodieren
                int xpos = xp;

		// bild darstellen

		int runlen = *sp++;

		do { 
		    // wir starten mit einem clear run

		    xpos += runlen;               

		    // jetzt kommen farbige pixel
                    runlen = *sp++;

		    if(runlen) {  

			if(xpos >= 0 && runlen+xpos < width) {
//                            pixcopy(tp+xpos, sp, runlen);
			    memcpy(tp+xpos, sp, runlen*sizeof(PIXVAL));
                        } else if(xpos < 0) {
			    if(runlen+xpos > 0) {
//                                pixcopy(tp, sp-xpos, runlen+xpos);
				memcpy(tp, sp-xpos, (runlen+xpos)*sizeof(PIXVAL));
			    }
			} else if(width > xpos) {
//                            pixcopy(tp+xpos, sp, width-xpos);
                              memcpy(tp+xpos, sp, (width-xpos)*sizeof(PIXVAL));
			}
			sp += runlen;
			xpos += runlen;
			runlen = *sp ++;
		    }                        		    
		} while(runlen);
                           
		tp += width;
		
	    } while(--h > 0);
	}
    }
}

/**
 * Zeichnet Bild ohne Clipping
 * @author Hj. Malthaner
 */
static void
display_img_nc(const int n, const int xp, const int yp, const int dirty)
{                               
    if(n >= 0 && n < anz_images) {

	int h = images[n].h;

	if(h > 0) {
            const PIXVAL *sp = images[n].data;
            PIXVAL *tp = textur + (yp + images[n].y)*disp_width + xp;

	    if(dirty) {
		mark_rect_dirty_nc(xp, yp+images[n].y, xp+tile_size-1, yp+images[n].y+h-1);
	    }

	    do { // zeilen dekodieren

		// bild darstellen
		
		int runlen = *sp++;

		do { 

		    // wir starten mit einem clear run
		    tp += runlen;               

		    // jetzt kommen farbige pixel
		    runlen = *sp++;

		    if(runlen) {
//			pixcopy(tp, sp, runlen);
			memcpy(tp, sp, runlen*sizeof(PIXVAL));
		        sp += runlen; 
			tp += runlen;
			runlen = *sp++;
		    }
		} while(runlen);
                           
		tp += (disp_width-tile_size);
		
	    } while(--h);
	}
    }
}

/**
 * Zeichnet Bild
 * @author Hj. Malthaner
 */
void
display_img(const int n, const int xp, const int yp, const int dirty)
{
    if(xp>=0 && yp>=0 && xp < disp_width-tile_size-1 && yp < disp_height-tile_size-1) {
	display_img_nc(n, xp, yp, dirty);
    } else {
	if(xp>-tile_size && yp>-tile_size && xp < disp_width && yp < disp_height) {	
	    display_img_wc(n, xp, yp, dirty);                              
	}
    }
}



/**
 * Copies and shades colors
 * @param shade the amount to darken the color
 * @author Hj. Malthaner
 */
static void colorpixcpy(PIXVAL *dest, const PIXVAL *src, 
                        const PIXVAL * const end, 
                        const PIXVAL shade)
{   
    while(src < end) {
	*dest++ = darken(shade, *src++);
    }   
}


/**
 * Zeichnet Bild, ersetzt Spielerfarben
 * @author Hj. Malthaner
 */
static void
display_color_img_aux(const int n, const int xp, const int yp, const int color, const int dirty)
{                
    if(n >= 0 && n < anz_images) {

	int h = images[n].h;
	int y = yp + images[n].y;

        int yoff = clip_wh(&y, &h, 0, clip_rect.yy);

	if(h > 0) {
            const int width = disp_width;
            const PIXVAL *sp = images[n].data;
            PIXVAL *tp = textur + y*width;

//	    printf("textur = %p  tp = %p\n", textur, tp);

	    if(dirty) {
      		mark_rect_dirty_wc(xp, y+yoff, xp+tile_size-1, y+yoff+h-1);
	    }

	    // oben clippen

	    while(yoff) {
		yoff --;
		do {
		    if(*(++sp)) {
			sp += *sp + 1;
		    }                        		    
		} while(*sp);
	        sp ++;
	    }		    

	    do { // zeilen dekodieren
                int xpos = xp;

		// bild darstellen

		do { 
		    // wir starten mit einem clear run

		    xpos += *sp ++;               

		    // jetzt kommen farbige pixel

		    if(*sp) {
			const int runlen = *sp++;
			
			if(xpos >= 0 && runlen+xpos < width) {
			    colorpixcpy(tp+xpos, sp, sp+runlen, color);
			} else if(xpos < 0) {
			    if(runlen+xpos > 0) {
				colorpixcpy(tp, sp-xpos, sp+runlen, color);
			    }
			} else if(width > xpos) {
			    colorpixcpy(tp+xpos, sp, sp+width-xpos, color);
			}

			sp += runlen;
			xpos += runlen;
		    }                        		    
		} while(*sp);
                           
		tp += width;
	        sp ++;
		
	    } while(--h);
	}
    }
}


/**
 * Zeichnet Bild, ersetzt Farben
 * @author Hj. Malthaner
 */
void
display_color_img(const int n, const int xp, const int yp, const int color, const int dirty)
{
    // since the colors for player 0 are already right,
    // only use the expensive replacement routine for colored images
    // of other players

    // printf("color=%d\n", color);
                
    if(color) {
	display_color_img_aux(n, xp, yp, color, dirty);
    } else {
	display_img_wc(n, xp, yp, dirty);
    }
}

/**
 * Zeichnet ein Pixel
 * @author Hj. Malthaner
 */
void
display_pixel(int x, int y, const int color)
{   
    if(x >= clip_rect.x && x<=clip_rect.xx &&
       y >= clip_rect.y && y> DIRTY_TILE_SHIFT, y >> DIRTY_TILE_SHIFT);
    }
}


/**
 * Zeichnet einen Text, lowlevel Funktion
 * @author Hj. Malthaner
 */
static void
dr_textur_text(PIXVAL *textur,int x,int y,const char *txt, 
               const int chars, const int fgpen, const int dirty)
{
    int p;

    y+=4;                               /* Korektu amiga <-> pc */

    if(y < 0 || y+8 >= disp_height)
	return;                       /* out of clip */


    if(dirty) {
	mark_rect_dirty_nc(x, y, x+chars*8-1, y+8-1);
    }


    for(p=0; p> b)) {
		    textur[screen_pos+b] = fgpen;
		} 
	    }
	    screen_pos += disp_width;
	}while(base < end);
    }
}


/**
 * Zeichnet Text, highlevel Funktion
 * @author Hj. Malthaner
 */
void
display_text(int x, int y, const char *txt, const int color, int dirty)
{                                        
    const int chars = strlen(txt);
    const int text_width = chars*8;

    if(y >= 8 && y < disp_height-12) {

	if(x >= 0  && x+text_width < disp_width) {
	    dr_textur_text(textur, x, y, txt, chars, color, dirty);
	} else {
	    if(x < 0 && x+text_width > 8) {       
		const int left_chars = (-x+7)/8;		

		dr_textur_text(textur, (x & 7), y, txt+left_chars, chars-left_chars, color, dirty);
            } else if(x > 0 && x < disp_width-7) {
                const int rest_chars = (disp_width-x-1) / 8;

		dr_textur_text(textur, x, y, txt, rest_chars, color, dirty);		
	    }
	}
    }
}
                                          
/**
 * Zeichnet gefuelltes Rechteck, ohne clipping
 * @author Hj. Malthaner
 */
void display_fb_internal(int xp, int yp, int w, int h, 
			 const int color, const int dirty,
			 int cL, int cR, int cT, int cB)
{
    clip_wh(&xp, &w, cL, cR);
    clip_wh(&yp, &h, cT, cB);

    if(w > 0 && h > 0) {
        PIXVAL *p = textur + xp + yp*disp_width;

	if(dirty) {
	    mark_rect_dirty_nc(xp, yp, xp+w-1, yp+h-1);
	}

	do {
	    memset(p, color, w*sizeof(PIXVAL));
            p += disp_width;
	} while(--h);
    }
}
 
void
display_fillbox_wh(int xp, int yp, int w, int h,
		   const int color, const int dirty)
{
  display_fb_internal(xp,yp,w,h,color,dirty,
		      0,disp_width-1,0,disp_height-1);
} 
void
display_fillbox_wh_clip(int xp, int yp, int w, int h,
			const int color, const int dirty)
{
  display_fb_internal(xp,yp,w,h,color,dirty,
		      clip_rect.x, clip_rect.xx, clip_rect.y, clip_rect.yy);
} 

/**
 * Zeichnet vertikale Linie
 * @author Hj. Malthaner
 */
void
display_vl_internal(const int xp, int yp, int h, const int color, int dirty,
		    int cL, int cR, int cT, int cB)
{
    clip_wh(&yp, &h, cT, cB);

    if(xp >= cL && xp <= cR && h > 0) {
        PIXVAL *p = textur + xp + yp*disp_width;

        if (dirty) {
	  mark_rect_dirty_nc(xp, yp, xp, yp+h-1);
	}
	    
	do {
	    *p = color;
            p += disp_width;
	} while(--h);           
    }
}

void
display_vline_wh(int xp, int yp, int h, const int color, const int dirty)
{
  display_vl_internal(xp,yp,h,color,dirty,
		      0,disp_width-1,0,disp_height-1);
} 

void
display_vline_wh_clip(int xp, int yp, int h, const int color, const int dirty)
{
  display_vl_internal(xp,yp,h,color,dirty,
		      clip_rect.x, clip_rect.xx, clip_rect.y, clip_rect.yy);
} 

/**
 * Zeichnet rohe Pixeldaten
 * @author Hj. Malthaner
 */
void
display_array_wh(int xp, int yp, int w, int h, const unsigned char *arr)
{            
    const int arr_w = w;

    clip_wh(&xp, &w, 0, disp_width);
    clip_wh(&yp, &h, 0, disp_height);

    if(w > 0 && h > 0) {
        PIXVAL *p = textur + xp + yp*disp_width;

	mark_rect_dirty_nc(xp, yp, xp+w-1, yp+h-1);
                      
	if(xp == 0) {
	    arr += arr_w - w;
	}

	do {
	    // FIXME!!!
	    memcpy(p, arr, w);
            p += disp_width;
	    arr += arr_w;
	} while(--h);
    }   
} 
     

// --------------- compound painting procedures ---------------


/**
 * Zeichnet schattiertes Rechteck
 * @author Hj. Malthaner
 */
void
display_ddd_box(int x1, int y1, int w, int h, int tl_color, int rd_color)
{
    display_fillbox_wh(x1, y1, w, 1, tl_color, TRUE);
    display_fillbox_wh(x1, y1+h-1, w, 1, rd_color, TRUE);

    h-=2;

    display_vline_wh(x1, y1+1, h, tl_color, TRUE);
    display_vline_wh(x1+w-1, y1+1, h, rd_color, TRUE);
}

/**
 * Zeichnet schattierten  Text
 * @author Hj. Malthaner
 */
void
display_ddd_text(int xpos, int ypos, int hgt, 
                 int ddd_farbe, int text_farbe,
                 const char *text, int dirty)
{
    const int len = strlen(text)*4;

    display_fillbox_wh(xpos-2-len,
                       ypos-hgt-6,
                       4 + len*2, 1,
                       ddd_farbe+1,
		       dirty);
    display_fillbox_wh(xpos-2-len,
                       ypos-hgt-5,
                       4 + len*2, 8,
                       ddd_farbe,
		       dirty);
    display_fillbox_wh(xpos-2-len,
                       ypos-hgt+3,
                       4 + len*2, 1,
                       ddd_farbe-1,
		       dirty);

    display_text(xpos - len, 
                 ypos-hgt-9,
                 text, 
		 text_farbe,
		 dirty);
}


/**
 * Zaehlt Vorkommen eines Buchstabens in einem String
 * @author Hj. Malthaner
 */
int
count_char(const char *str, const char c)
{
    int count = 0;

    while(*str) {
	count += (*str++ == c);
    }
    return count;
}

/**
 * Zeichnet einen mehrzeiligen Text
 * @author Hj. Malthaner
 */
void
display_multiline_text(int x, int y, const char *inbuf, int color)
{
    char tmp[4096];
    char *buf = tmp;
    char *next;                        
    int y_off = 0;           

    // be sure not to copy more than buffer size
    strncpy(buf, inbuf, 4095);    

    // always close with a 0 byte
    buf[4095] = 0;

    while( (*buf != 0) && (next = strchr(buf,'\n')) ) { 
	*next = 0;
	display_text(x,y+y_off, buf, color, TRUE);
	buf = next+1;
	y_off += LINESPACE;
    }                    
}


/**
 * Loescht den Bildschirm
 * @author Hj. Malthaner
 */
void
display_clear()
{
    memset(textur+32*disp_width, 32, disp_width*(disp_height-17-32));

    mark_rect_dirty_nc(0, 0, disp_width-1, disp_height-1);
}


#if 0
void display_flush_buffer()
{
    int x, y;
    char * tmp;

#ifdef USE_SOFTPOINTER
    display_img(softpointer, mx, my, TRUE);
    old_my = my;
#endif

#ifdef DEBUG
    // just for debugging
    int tile_count = 0;
#endif

    for(y=0; y> 1) + i_off;
	    const int j = ((y-x) >> 1) + j_off;
	    const int xpos = x*IMG_SIZE/2 + const_x_off;

	    display_boden(i, j, xpos, ypos);
	}
    }

    // Hajo: then draw the objects

    for(y=-5; y> 1) + i_off;
	    const int j = ((y-x) >> 1) + j_off;
	    const int xpos = x*IMG_SIZE/2 + const_x_off;


	    display_dinge(i, j, xpos, ypos);
	}
    }
}

tome-235-src/src/iso/simview.h0000644000076400017500000000252511012107763014107 0ustar  dgdg/* simview.h
 *
 * Copyright (c) 2001, 2002 Hansjörg Malthaner
 * hansjoerg.malthaner@gmx.de
 *
 * This file is part of the Simugraph graphics engine.
 *
 *
 * This file may be copied and modified freely so long as the above credits,
 * this paragraph, and the below disclaimer of warranty are retained; no
 * financial profit is derived from said modification or copying; and all
 * licensing rights to any modifications are granted to the original author,
 * Hansjörg Malthaner.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef simview_h
#define simview_h


/**
 * Draws the full iso-view display
 * @author Hj. Malthaner
 */
void display();


#endif
tome-235-src/src/lua/0000755000076400017500000000000011012107763012236 5ustar  dgdgtome-235-src/src/lua/lundump.c0000644000076400017500000001251711012107763014074 0ustar  dgdg/*
** $Id: lundump.c,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** load bytecodes from files
** See Copyright Notice in lua.h
*/

#include 
#include 

#include "lfunc.h"
#include "lmem.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"

#define	LoadByte		ezgetc

static const char* ZNAME (ZIO* Z)
{
 const char* s=zname(Z);
 return (*s=='@') ? s+1 : s;
}

static void unexpectedEOZ (lua_State* L, ZIO* Z)
{
 luaO_verror(L,"unexpected end of file in `%.99s'",ZNAME(Z));
}

static int ezgetc (lua_State* L, ZIO* Z)
{
 int c=zgetc(Z);
 if (c==EOZ) unexpectedEOZ(L,Z);
 return c;
}

static void ezread (lua_State* L, ZIO* Z, void* b, int n)
{
 int r=zread(Z,b,n);
 if (r!=0) unexpectedEOZ(L,Z);
}

static void LoadBlock (lua_State* L, void* b, size_t size, ZIO* Z, int swap)
{
 if (swap)
 {
  char *p=(char *) b+size-1;
  int n=size;
  while (n--) *p--=(char)ezgetc(L,Z);
 }
 else
  ezread(L,Z,b,size);
}

static void LoadVector (lua_State* L, void* b, int m, size_t size, ZIO* Z, int swap)
{
 if (swap)
 {
  char *q=(char *) b;
  while (m--)
  {
   char *p=q+size-1;
   int n=size;
   while (n--) *p--=(char)ezgetc(L,Z);
   q+=size;
  }
 }
 else
  ezread(L,Z,b,m*size);
}

static int LoadInt (lua_State* L, ZIO* Z, int swap)
{
 int x;
 LoadBlock(L,&x,sizeof(x),Z,swap);
 return x;
}

static size_t LoadSize (lua_State* L, ZIO* Z, int swap)
{
 size_t x;
 LoadBlock(L,&x,sizeof(x),Z,swap);
 return x;
}

static Number LoadNumber (lua_State* L, ZIO* Z, int swap)
{
 Number x;
 LoadBlock(L,&x,sizeof(x),Z,swap);
 return x;
}

static TString* LoadString (lua_State* L, ZIO* Z, int swap)
{
 size_t size=LoadSize(L,Z,swap);
 if (size==0)
  return NULL;
 else
 {
  char* s=luaO_openspace(L,size);
  LoadBlock(L,s,size,Z,0);
  return luaS_newlstr(L,s,size-1);	/* remove trailing '\0' */
 }
}

static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap)
{
 int size=LoadInt(L,Z,swap);
 tf->code=luaM_newvector(L,size,Instruction);
 LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap);
 if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z));
 luaF_protook(L,tf,size);
}

static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
{
 int i,n;
 tf->nlocvars=n=LoadInt(L,Z,swap);
 tf->locvars=luaM_newvector(L,n,LocVar);
 for (i=0; ilocvars[i].varname=LoadString(L,Z,swap);
  tf->locvars[i].startpc=LoadInt(L,Z,swap);
  tf->locvars[i].endpc=LoadInt(L,Z,swap);
 }
}

static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap)
{
 int n;
 tf->nlineinfo=n=LoadInt(L,Z,swap);
 tf->lineinfo=luaM_newvector(L,n,int);
 LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap);
}

static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap);

static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap)
{
 int i,n;
 tf->nkstr=n=LoadInt(L,Z,swap);
 tf->kstr=luaM_newvector(L,n,TString*);
 for (i=0; ikstr[i]=LoadString(L,Z,swap);
 tf->nknum=n=LoadInt(L,Z,swap);
 tf->knum=luaM_newvector(L,n,Number);
 LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap);
 tf->nkproto=n=LoadInt(L,Z,swap);
 tf->kproto=luaM_newvector(L,n,Proto*);
 for (i=0; ikproto[i]=LoadFunction(L,Z,swap);
}

static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap)
{
 Proto* tf=luaF_newproto(L);
 tf->source=LoadString(L,Z,swap);
 tf->lineDefined=LoadInt(L,Z,swap);
 tf->numparams=LoadInt(L,Z,swap);
 tf->is_vararg=LoadByte(L,Z);
 tf->maxstacksize=LoadInt(L,Z,swap);
 LoadLocals(L,tf,Z,swap);
 LoadLines(L,tf,Z,swap);
 LoadConstants(L,tf,Z,swap);
 LoadCode(L,tf,Z,swap);
 return tf;
}

static void LoadSignature (lua_State* L, ZIO* Z)
{
 const char* s=SIGNATURE;
 while (*s!=0 && ezgetc(L,Z)==*s)
  ++s;
 if (*s!=0) luaO_verror(L,"bad signature in `%.99s'",ZNAME(Z));
}

static void TestSize (lua_State* L, int s, const char* what, ZIO* Z)
{
 int r=ezgetc(L,Z);
 if (r!=s)
  luaO_verror(L,"virtual machine mismatch in `%.99s':\n"
	"  %.20s is %d but read %d",ZNAME(Z),what,s,r);
}

#define TESTSIZE(s)	TestSize(L,s,#s,Z)
#define V(v)	v/16,v%16

static int LoadHeader (lua_State* L, ZIO* Z)
{
 int version,swap;
 Number f=0,tf=TEST_NUMBER;
 LoadSignature(L,Z);
 version=ezgetc(L,Z);
 if (version>VERSION)
  luaO_verror(L,"`%.99s' too new:\n"
	"  read version %d.%d; expected at most %d.%d",
	ZNAME(Z),V(version),V(VERSION));
 if (version"
#define SOURCE		tf->lineDefined,tf->source->str
#define IN_FMT		" in %p " SOURCE_FMT
#define IN		tf,SOURCE

/* a multiple of PI for testing native format */
/* multiplying by 1E8 gives non-trivial integer values */
#define	TEST_NUMBER	3

#endif
tome-235-src/src/lua/doit.lua0000644000076400017500000000227011012107763013701 0ustar  dgdg-- Generate binding code
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: doit.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $


-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- open input file, if any
if flags.f then
 local st, msg = readfrom(flags.f)
 if not st then
  error('#'..msg)
 end
end

-- define package name, if not provided
if not flags.n then
 if flags.f then
  flags.n = gsub(flags.f,"%..*","")
 else
  error("#no package name nor input file provided")
 end
end

local p  = Package(flags.n)

if flags.f then
 readfrom()
end

if flags.p then
 return        -- only parse
end

if flags.o then
 local st,msg = writeto(flags.o)
 if not st then
  error('#'..msg)
 end
end

if flags.P then
 p:print()
else
 p:decltag()
 p:preamble()
 p:supcode()
 p:register()
 p:unregister()
end

if flags.o then
 writeto()
end

-- write header file
if not flags.P then
 if flags.H then
  local st,msg = writeto(flags.H)
  if not st then
   error('#'..msg)
  end
  p:header()
  writeto()
 end
end

tome-235-src/src/lua/basic.lua0000644000076400017500000000761711012107763014035 0ustar  dgdg-- tolua: basic utility functions
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: basic.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications.


-- Basic C types and their corresponding Lua types
-- All occurrences of "char*" will be replaced by "_cstring",
-- and all occurrences of "void*" will be replaced by "_userdata" 
_basic = {
 ['void'] = '',
 ['char'] = 'number',
 ['int'] = 'number',
 ['short'] = 'number',
 ['long'] = 'number',
 ['_cstring'] = 'string',
 ['_userdata'] = 'userdata',
 ['char*'] = 'string',
 ['void*'] = 'userdata',
 ['bool'] = 'bool',
 ['LUA_VALUE'] = 'value',
 ['byte'] = 'number',
 ['s16b'] = 'number',
 ['u16b'] = 'number',
 ['s32b'] = 'number',
 ['u32b'] = 'number',
}

_basic_tag = {
 ['void'] = '',
 ['char'] = 'LUA_TNUMBER',
 ['int'] = 'LUA_TNUMBER',
 ['short'] = 'LUA_TNUMBER',
 ['long'] = 'LUA_TNUMBER',
 ['_cstring'] = 'LUA_TSTRING',
 ['_userdata'] = 'LUA_TUSERDATA',
 ['char*'] = 'LUA_TSTRING',
 ['void*'] = 'LUA_TUSERDATA',
 ['bool'] = 'tolua_tag(tolua_S,"bool")',
 ['byte'] = 'LUA_TNUMBER',
 ['s16b'] = 'LUA_TNUMBER',
 ['u16b'] = 'LUA_TNUMBER',
 ['s32b'] = 'LUA_TNUMBER',
 ['u32b'] = 'LUA_TNUMBER',
}

_basic_ctype = {
 number = "long",
 string = "const char*",
 userdata = "void*",
 bool = "int",
}

-- List of user defined types
-- Each type corresponds to a variable name that stores its tag value.
_usertype = {}

-- Tag method to provide inheritance
function tolua_index (t,f)
 if f == '_base' then  -- to avoid loop
   return tolua_old_index(t,f)
 else
  return t._base[f]
 end
end

tolua_tag = newtag()
tolua_old_index = settagmethod(tolua_tag,"index",tolua_index)

-- Error handler
function tolua_error (s)
 local out = _OUTPUT
 _OUTPUT = _STDERR
 if strsub(s,1,1) == '#' then
  write("\n** tolua: "..strsub(s,2)..".\n\n")
 else
  write("\n** tolua internal error: "..s..".\n\n")
  return
 end

 if _curr_code then
  local _,_,s = strfind(_curr_code,"^%s*(.-\n)") -- extract first line
  if s==nil then s = _curr_code end
  s = gsub(s,"_userdata","void*") -- return with 'void*'
  s = gsub(s,"_cstring","char*")  -- return with 'char*'
  write("Code being processed:\n"..s.."\n")
 end
 _OUTPUT = out
end


_ERRORMESSAGE = tolua_error

-- register an user defined type
function regtype (t)
 if not istype(t) then
  _usertype[t] = t
 end
 return t
end

-- return tag name
function tagvar(type,const)
 if type == '' or type == 'void' then
  return type,0
 else
  local m,t = findtypedef(type)
  if isbasic(t) then
   return t, _basic_tag[t]
  end
  if strfind(m,'const') then const = 'const' end
  regtype(t)
  if const and const ~= '' then
   t = 'const '..t
  end
  return t,'tolua_tag(tolua_S,"'..t..'")'
 end
end

-- check if basic type
function isbasic (type)
 local m,t = findtypedef(type)
 local b = _basic[t]
 if b then
  return b,_basic_ctype[b]
 end
 return nil
end

-- check if type
function istype (t)
 return _basic[t] or _usertype[t] or istypedef(t)
end


-- split string using a token
function split (s,t)
 local l = {n=0}
 local f = function (s)
  %l.n = %l.n + 1
  %l[%l.n] = s
 end
 local p = "%s*(.-)%s*"..t.."%s*"
 s = gsub(s,"^%s+","")
 s = gsub(s,"%s+$","")
 s = gsub(s,p,f)
 l.n = l.n + 1
 l[l.n] = gsub(s,"(%s%s*)$","")
 return l
end


-- concatenate strings of a table
function concat (t,f,l)
 local s = ''
 local i=f
 while i<=l do
  s = s..t[i]
  i = i+1
  if i <= l then s = s..' ' end
 end
 return s
end

-- output line
function output (...)
 local i=1
 while i<=arg.n do
  if _cont and not strfind(_cont,'[%(,"]') and 
     strfind(arg[i],"^[%a_~]") then 
	    write(' ') 
  end
  write(arg[i])
  if arg[i] ~= '' then
   _cont = strsub(arg[i],-1,-1)
  end
  i = i+1
 end
 if strfind(arg[arg.n],"[%/%)%;%{%}]$") then 
  _cont=nil write('\n')
 end
end


tome-235-src/src/lua/clean.lua0000644000076400017500000000237311012107763014030 0ustar  dgdg-- mark up comments and strings
STR1 = "\001"
STR2 = "\002"
STR3 = "\003"
STR4 = "\004"
REM  = "\005"
ANY  = "([\001-\005])"
ESC1 = "\006"
ESC2 = "\007"

MASK = { -- the substitution order is important
 {ESC1, "\\'"},
 {ESC2, '\\"'},
 {STR1, "'"},
 {STR2, '"'},
 {STR3, "%[%["},
 {STR4, "%]%]"},
 {REM , "%-%-"},
}

function mask (s)
 for i = 1,getn(MASK)  do
  s = gsub(s,MASK[i][2],MASK[i][1])
 end
 return s
end

function unmask (s)
 for i = 1,getn(MASK)  do
  s = gsub(s,MASK[i][1],MASK[i][2])
 end
 return s
end

function clean (s)
 -- check for compilation error
 local code = "return function () " .. s .. " end" 
 if not dostring(code) then
  return nil
 end

 local S = "" -- saved string

 s = mask(s)

 -- remove blanks and comments
 while 1 do
  local b,e,d = strfind(s,ANY)
  if b then 
   S = S..strsub(s,1,b-1)
   s = strsub(s,b+1)
   if d==STR1 or d==STR2 then
    e = strfind(s,d)
    S = S ..d..strsub(s,1,e)
    s = strsub(s,e+1)
   elseif d==STR3 then
    e = strfind(s,STR4)
    S = S..d..strsub(s,1,e)
    s = strsub(s,e+1)
   elseif d==REM then
    s = gsub(s,"[^\n]*(\n?)","%1",1)
   end 
  else
   S = S..s
   break
  end
 end
 -- eliminate unecessary spaces
 S = gsub(S,"[ \t]+"," ")
 S = gsub(S,"[ \t]*\n[ \t]*","\n")
 S = unmask(S)
 return S
end

tome-235-src/src/lua/luadebug.h0000644000076400017500000000245311012107763014203 0ustar  dgdg/*
** $Id: luadebug.h,v 1.2 2001/11/26 23:00:26 darkgod Exp $
** Debugging API
** See Copyright Notice in lua.h
*/


#ifndef luadebug_h
#define luadebug_h


#include "lua.h"

typedef struct lua_Debug lua_Debug;  /* activation record */
typedef struct lua_Localvar lua_Localvar;

typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);


LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);

LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);


#define LUA_IDSIZE	60

struct lua_Debug {
  const char *event;     /* `call', `return' */
  int currentline;       /* (l) */
  const char *name;      /* (n) */
  const char *namewhat;  /* (n) `global', `tag method', `local', `field' */
  int nups;              /* (u) number of upvalues */
  int linedefined;       /* (S) */
  const char *what;      /* (S) `Lua' function, `C' function, Lua `main' */
  const char *source;    /* (S) */
  char short_src[LUA_IDSIZE]; /* (S) */
  /* private part */
  struct lua_TObject *_func;  /* active function */
};


#endif
tome-235-src/src/lua/ldblib.c0000644000076400017500000001021411012107763013630 0ustar  dgdg/*
** $Id: ldblib.c,v 1.2 2001/11/26 23:00:23 darkgod Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 

#include "lua.h"

#include "lauxlib.h"
#include "luadebug.h"
#include "lualib.h"



static void settabss (lua_State *L, const char *i, const char *v) {
  lua_pushstring(L, i);
  lua_pushstring(L, v);
  lua_settable(L, -3);
}


static void settabsi (lua_State *L, const char *i, int v) {
  lua_pushstring(L, i);
  lua_pushnumber(L, v);
  lua_settable(L, -3);
}


static int getinfo (lua_State *L) {
  lua_Debug ar;
  const char *options = luaL_opt_string(L, 2, "flnSu");
  char buff[20];
  if (lua_isnumber(L, 1)) {
    if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
      lua_pushnil(L);  /* level out of range */
      return 1;
    }
  }
  else if (lua_isfunction(L, 1)) {
    lua_pushvalue(L, 1);
    sprintf(buff, ">%.10s", options);
    options = buff;
  }
  else
    luaL_argerror(L, 1, "function or level expected");
  if (!lua_getinfo(L, options, &ar))
    luaL_argerror(L, 2, "invalid option");
  lua_newtable(L);
  for (; *options; options++) {
    switch (*options) {
      case 'S':
        settabss(L, "source", ar.source);
        if (ar.source)
          settabss(L, "short_src", ar.short_src);
        settabsi(L, "linedefined", ar.linedefined);
        settabss(L, "what", ar.what);
        break;
      case 'l':
        settabsi(L, "currentline", ar.currentline);
        break;
      case 'u':
        settabsi(L, "nups", ar.nups);
        break;
      case 'n':
        settabss(L, "name", ar.name);
        settabss(L, "namewhat", ar.namewhat);
        break;
      case 'f':
        lua_pushstring(L, "func");
        lua_pushvalue(L, -3);
        lua_settable(L, -3);
        break;
    }
  }
  return 1;  /* return table */
}
    

static int getlocal (lua_State *L) {
  lua_Debug ar;
  const char *name;
  if (!lua_getstack(L, luaL_check_int(L, 1), &ar))  /* level out of range? */
    luaL_argerror(L, 1, "level out of range");
  name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
  if (name) {
    lua_pushstring(L, name);
    lua_pushvalue(L, -2);
    return 2;
  }
  else {
    lua_pushnil(L);
    return 1;
  }
}


static int setlocal (lua_State *L) {
  lua_Debug ar;
  if (!lua_getstack(L, luaL_check_int(L, 1), &ar))  /* level out of range? */
    luaL_argerror(L, 1, "level out of range");
  luaL_checkany(L, 3);
  lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
  return 1;
}



/* dummy variables (to define unique addresses) */
static char key1, key2;
#define KEY_CALLHOOK	(&key1)
#define KEY_LINEHOOK	(&key2)


static void hookf (lua_State *L, void *key) {
  lua_getregistry(L);
  lua_pushuserdata(L, key);
  lua_gettable(L, -2);
  if (lua_isfunction(L, -1)) {
    lua_pushvalue(L, 1);
    lua_rawcall(L, 1, 0);
  }
  else
    lua_pop(L, 1);  /* pop result from gettable */
  lua_pop(L, 1);  /* pop table */
}


static void callf (lua_State *L, lua_Debug *ar) {
  lua_pushstring(L, ar->event);
  hookf(L, KEY_CALLHOOK);
}


static void linef (lua_State *L, lua_Debug *ar) {
  lua_pushnumber(L, ar->currentline);
  hookf(L, KEY_LINEHOOK);
}


static void sethook (lua_State *L, void *key, lua_Hook hook,
                     lua_Hook (*sethookf)(lua_State * L, lua_Hook h)) {
  lua_settop(L, 1);
  if (lua_isnil(L, 1))
    (*sethookf)(L, NULL);
  else if (lua_isfunction(L, 1))
    (*sethookf)(L, hook);
  else
    luaL_argerror(L, 1, "function expected");
  lua_getregistry(L);
  lua_pushuserdata(L, key);
  lua_pushvalue(L, -1);  /* dup key */
  lua_gettable(L, -3);   /* get old value */
  lua_pushvalue(L, -2);  /* key (again) */
  lua_pushvalue(L, 1);
  lua_settable(L, -5);  /* set new value */
}


static int setcallhook (lua_State *L) {
  sethook(L, KEY_CALLHOOK, callf, lua_setcallhook);
  return 1;
}


static int setlinehook (lua_State *L) {
  sethook(L, KEY_LINEHOOK, linef, lua_setlinehook);
  return 1;
}


static const struct luaL_reg dblib[] = {
  {"getlocal", getlocal},
  {"getinfo", getinfo},
  {"setcallhook", setcallhook},
  {"setlinehook", setlinehook},
  {"setlocal", setlocal}
};


LUALIB_API void lua_dblibopen (lua_State *L) {
  luaL_openl(L, dblib);
}

tome-235-src/src/lua/function.lua0000644000076400017500000001740111012107763014571 0ustar  dgdg-- tolua: function class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: function.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 



-- Function class
-- Represents a function or a class method.
-- The following fields are stored:
--  mod  = type modifiers
--  type = type
--  ptr  = "*" or "&", if representing a pointer or a reference
--  name = name
--  args  = list of argument declarations
--  const = if it is a method receiving a const "this".
classFunction = {
 mod = '',
 type = '',
 ptr = '',
 name = '',
 args = {n=0},
 const = '',
 _base = classFeature,
}
settag(classFunction,tolua_tag)

-- declare tags
function classFunction:decltag ()
 self.itype,self.tag = tagvar(self.type,strfind(self.mod,'const'))
 local i=1
 while self.args[i] do
  self.args[i]:decltag()
  i = i+1
 end
end


-- Write binding function
-- Outputs C/C++ binding function.
function classFunction:supcode ()
 local nret = 0      -- number of returned values
 local class = self:inclass()
 local _,_,static = strfind(self.mod,'^%s*(static)')

 if class then
  output("/* method:",self.name," of class ",class," */")
 else
  output("/* function:",self.name," */")
 end
 output("static int",self.cname,"(lua_State* tolua_S)")
 output("{")

 -- check types
 output(' if (\n')
 -- check self
 local narg
 if class then narg=2 else narg=1 end
 if class and self.name~='new' and static==nil then
  if self.const == 'const' then
   output('     !tolua_istype(tolua_S,1,',self.parent.ctag,',0) ||\n') 
  else
   output('     !tolua_istype(tolua_S,1,',self.parent.tag,',0) ||\n') 
  end
 end
 -- check args
 if self.args[1].type ~= 'void' then
  local i=1
  while self.args[i] do
   if isbasic(self.args[i].type) ~= 'value' then
    output('     !'..self.args[i]:outchecktype(narg)..' ||\n')
   end
   narg = narg+1
   i = i+1
  end
 end
 -- check end of list 
 output('     !tolua_isnoobj(tolua_S,'..narg..')\n )\n  goto tolua_lerror;')

 output(' else\n {')
 
 -- declare self, if the case
 local narg
 if class then narg=2 else narg=1 end
 if class and self.name~='new' and static==nil then
  output(' ',self.const,class,'*','self = ')
  output('(',self.const,class,'*) ')
  output('tolua_getusertype(tolua_S,1,0);')
 elseif static then
  _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
 end
 -- declare parameters
 if self.args[1].type ~= 'void' then
  local i=1
  while self.args[i] do
   self.args[i]:declare(narg)
   narg = narg+1
   i = i+1
  end
 end

 -- check self
 if class and self.name~='new' and static==nil then 
  output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'");');
 end

 -- get array element values
 if class then narg=2 else narg=1 end
 if self.args[1].type ~= 'void' then
  local i=1
  while self.args[i] do
   self.args[i]:getarray(narg)
   narg = narg+1
   i = i+1
  end
 end

 -- call function
 if class and self.name=='delete' then
  output('  delete self;')
 elseif class and self.name == 'operator&[]' then
  output('  self->operator[](',self.args[1].name,') = ',self.args[2].name,';')
 else
  output('  {')
  if self.type ~= '' and self.type ~= 'void' then
   output('  ',self.mod,self.type,self.ptr,'toluaI_ret = ')
   output('(',self.mod,self.type,self.ptr,') ')
  else
   output('  ')
  end
  if class and self.name=='new' then
   output('new',class,'(')
  elseif class and static then
   output(class..'::'..self.name,'(')
  elseif class then
   output('self->'..self.name,'(')
  else
   output(self.name,'(')
  end

  -- write parameters
  local i=1
  while self.args[i] do
   self.args[i]:passpar()
   i = i+1
   if self.args[i] then
    output(',')
   end
  end
     
  output(');')

  -- return values
  if self.type ~= '' and self.type ~= 'void' then
   nret = nret + 1
   local t,ct = isbasic(self.type)
   if t then
    output('   tolua_push'..t..'(tolua_S,(',ct,')toluaI_ret);')
   else
    if self.ptr == '' then
     output('   {')
     output('#ifdef __cplusplus\n')
     output('    void* toluaI_clone = new',self.type,'(toluaI_ret);') 
     output('#else\n')
     output('    void* toluaI_clone = tolua_copy(tolua_S,(void*)&toluaI_ret,sizeof(',self.type,'));')
     output('#endif\n')
     output('    tolua_pushusertype(tolua_S,tolua_doclone(tolua_S,toluaI_clone,',self.tag,'),',self.tag,');')
     output('   }')
     --output('   tolua_pushclone((void*)&toluaI_ret,sizeof(',self.type,'),',self.tag,');')
    elseif self.ptr == '&' then
     output('   tolua_pushusertype(tolua_S,(void*)&toluaI_ret,',self.tag,');')
    else
     output('   tolua_pushusertype(tolua_S,(void*)toluaI_ret,',self.tag,');')
    end
   end
  end
  local i=1
  while self.args[i] do
   nret = nret + self.args[i]:retvalue()
   i = i+1
  end
  output('  }')

  -- set array element values
  if class then narg=2 else narg=1 end
  if self.args[1].type ~= 'void' then
   local i=1
   while self.args[i] do
    self.args[i]:setarray(narg)
    narg = narg+1
    i = i+1
   end
  end
 
  -- free dynamically allocated array
  if self.args[1].type ~= 'void' then
   local i=1
   while self.args[i] do
    self.args[i]:freearray()
    i = i+1
   end
  end
 end

 output(' }')
 output(' return '..nret..';')

 -- call overloaded function or generate error
 output('tolua_lerror:\n')
 local overload = strsub(self.cname,-2,-1) - 1
 if overload >= 0 then
  output(' return '..strsub(self.cname,1,-3)..format("%02d",overload)..'(tolua_S);')
 else
  output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.");')
  output(' return 0;')
 end

 output('}')
 output('\n')
end

-- register function
function classFunction:register ()
 local parent = self:inclass() or self:inmodule()
 if parent then
  output(' tolua_function(tolua_S,"'..parent..'","'..self.lname..'",'..self.cname..');')
 else
  output(' tolua_function(tolua_S,NULL,"'..self.lname..'",'..self.cname..');')
 end
end

-- unregister function
function classFunction:unregister ()
 if self:inclass()==nil and self:inmodule()==nil then
  output(' lua_pushnil(tolua_S); lua_setglobal(tolua_S,"'..self.lname..'");')
 end
end


-- Print method
function classFunction:print (ident,close)
 print(ident.."Function{")
 print(ident.." mod  = '"..self.mod.."',")
 print(ident.." type = '"..self.type.."',")
 print(ident.." ptr  = '"..self.ptr.."',")
 print(ident.." name = '"..self.name.."',")
 print(ident.." const = '"..self.const.."',")
 print(ident.." cname = '"..self.cname.."',")
 print(ident.." lname = '"..self.lname.."',")
 print(ident.." args = {")
 local i=1
 while self.args[i] do
  self.args[i]:print(ident.."  ",",")
  i = i+1
 end
 print(ident.." }")
 print(ident.."}"..close)
end

-- determine lua function name overload
function classFunction:overload ()
 return self.parent:overload(self.lname)
end



-- Internal constructor
function _Function (t)
 t._base = classFunction
 settag(t,tolua_tag)

 if t.const ~= 'const' and t.const ~= '' then
  error("#invalid 'const' specification")
 end

 append(t)
 if t:inclass() then
  if t.name == t.parent.name then
   t.name = 'new'
   t.lname = 'new'
   t.type = t.parent.name
   t.ptr = '*'
  elseif t.name == '~'..t.parent.name then
   t.name = 'delete'
   t.lname = 'delete'
  end
 end
 t.cname = t:cfuncname("toluaI")..t:overload(t)
 return t
end

-- Constructor
-- Expects three strings: one representing the function declaration,
-- another representing the argument list, and the third representing
-- the "const" or empty string.
function Function (d,a,c)
 local t = split(strsub(a,2,-2),',') -- eliminate braces
 local i=1
 local l = {n=0}
 while t[i] do
  l.n = l.n+1
  l[l.n] = Declaration(t[i],'var')
  i = i+1
 end
 local f = Declaration(d,'func')
 f.args = l
 f.const = c
 return _Function(f)
end


tome-235-src/src/lua/enumerate.lua0000644000076400017500000000413311012107763014727 0ustar  dgdg-- tolua: enumerate class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: enumerate.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Enumerate class
-- Represents enumeration
-- The following fields are stored:
--    {i} = list of constant names
classEnumerate = {
 _base = classFeature,
}
settag(classEnumerate,tolua_tag)

-- register enumeration
function classEnumerate:register ()
 local p = self:inclass() or self:inmodule()
 local i=1
 while self[i] do
  if p then
   if self:inclass() then
    output(' tolua_constant(tolua_S,"'..p..'","'..self.lnames[i]..'",'..p..'::'..self[i]..');')
   else
    output(' tolua_constant(tolua_S,"'..p..'","'..self.lnames[i]..'",'..self[i]..');')
   end
  else
   output(' tolua_constant(tolua_S,NULL,"'..self.lnames[i]..'",'..self[i]..');')
  end
  i = i+1
 end
end
-- register enumeration
function classEnumerate:unregister ()
 if self:inclass()==nil and self:inmodule()==nil then
  local i=1
  while self[i] do
   output(' lua_pushnil(tolua_S); lua_setglobal(tolua_S,"'..self.lnames[i]..'");')
   i = i+1
  end
 end
end

-- Print method
function classEnumerate:print (ident,close)
 print(ident.."Enumerate{")
 local i=1
 while self[i] do
  print(ident.." '"..self[i].."'("..self.lnames[i].."),")
  i = i+1
 end
 print(ident.."}"..close)
end

-- Internal constructor
function _Enumerate (t)
 t._base = classEnumerate
 settag(t,tolua_tag)
 append(t)
 return t
end

-- Constructor
-- Expects a string representing the enumerate body
function Enumerate (b)
 local t = split(strsub(b,2,-2),',') -- eliminate braces
 local i = 1
 local e = {n=0}
 while t[i] do
  local tt = split(t[i],'=')  -- discard initial value
  e.n = e.n + 1
  e[e.n] = tt[1]
  i = i+1
 end
 -- set lua names
 i  = 1
 e.lnames = {}
 while e[i] do
  local t = split(e[i],'@')
  e[i] = t[1]
  e.lnames[i] = t[2] or t[1]
  i = i+1
 end 
 return _Enumerate(e)
end


tome-235-src/src/lua/ldebug.c0000644000076400017500000002646611012107763013662 0ustar  dgdg/*
** $Id: ldebug.c,v 1.2 2001/11/26 23:00:23 darkgod Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/


#include 

#include "lua.h"

#include "lapi.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "luadebug.h"



static const char *getfuncname (lua_State *L, StkId f, const char **name);


static void setnormalized (TObject *d, const TObject *s) {
  if (ttype(s) == LUA_TMARK) {
    clvalue(d) = infovalue(s)->func;
    ttype(d) = LUA_TFUNCTION;
  }
  else *d = *s;
}


static int isLmark (StkId o) {
  return (o && ttype(o) == LUA_TMARK && !infovalue(o)->func->isC);
}


LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
  lua_Hook oldhook = L->callhook;
  L->callhook = func;
  return oldhook;
}


LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
  lua_Hook oldhook = L->linehook;
  L->linehook = func;
  return oldhook;
}


static StkId aux_stackedfunction (lua_State *L, int level, StkId top) {
  int i;
  for (i = (top-1) - L->stack; i>=0; i--) {
    if (is_T_MARK(L->stack[i].ttype)) {
      if (level == 0)
        return L->stack+i;
      level--;
    }
  }
  return NULL;
}


LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
  StkId f = aux_stackedfunction(L, level, L->top);
  if (f == NULL) return 0;  /* there is no such level */
  else {
    ar->_func = f;
    return 1;
  }
}


static int nups (StkId f) {
  switch (ttype(f)) {
    case LUA_TFUNCTION:
      return clvalue(f)->nupvalues;
    case LUA_TMARK:
      return infovalue(f)->func->nupvalues;
    default:
      return 0;
  }
}


int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
  int refi;
  if (lineinfo == NULL || pc == -1)
    return -1;  /* no line info or function is not active */
  refi = prefi ? *prefi : 0;
  if (lineinfo[refi] < 0)
    refline += -lineinfo[refi++]; 
  LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
  while (lineinfo[refi] > pc) {
    refline--;
    refi--;
    if (lineinfo[refi] < 0)
      refline -= -lineinfo[refi--]; 
    LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
  }
  for (;;) {
    int nextline = refline + 1;
    int nextref = refi + 1;
    if (lineinfo[nextref] < 0)
      nextline += -lineinfo[nextref++]; 
    LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info");
    if (lineinfo[nextref] > pc)
      break;
    refline = nextline;
    refi = nextref;
  }
  if (prefi) *prefi = refi;
  return refline;
}


static int currentpc (StkId f) {
  CallInfo *ci = infovalue(f);
  LUA_ASSERT(isLmark(f), "function has no pc");
  if (ci->pc)
    return (*ci->pc - ci->func->f.l->code) - 1;
  else
    return -1;  /* function is not active */
}


static int currentline (StkId f) {
  if (!isLmark(f))
    return -1;  /* only active lua functions have current-line information */
  else {
    CallInfo *ci = infovalue(f);
    int *lineinfo = ci->func->f.l->lineinfo;
    return luaG_getline(lineinfo, currentpc(f), 1, NULL);
  }
}



static Proto *getluaproto (StkId f) {
  return (isLmark(f) ?  infovalue(f)->func->f.l : NULL);
}


LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
  const char *name;
  StkId f = ar->_func;
  Proto *fp = getluaproto(f);
  if (!fp) return NULL;  /* `f' is not a Lua function? */
  name = luaF_getlocalname(fp, n, currentpc(f));
  if (!name) return NULL;
  luaA_pushobject(L, (f+1)+(n-1));  /* push value */
  return name;
}


LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
  const char *name;
  StkId f = ar->_func;
  Proto *fp = getluaproto(f);
  L->top--;  /* pop new value */
  if (!fp) return NULL;  /* `f' is not a Lua function? */
  name = luaF_getlocalname(fp, n, currentpc(f));
  if (!name || name[0] == '(') return NULL;  /* `(' starts private locals */
  *((f+1)+(n-1)) = *L->top;
  return name;
}


static void infoLproto (lua_Debug *ar, Proto *f) {
  ar->source = f->source->str;
  ar->linedefined = f->lineDefined;
  ar->what = "Lua";
}


static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
  Closure *cl = NULL;
  switch (ttype(func)) {
    case LUA_TFUNCTION:
      cl = clvalue(func);
      break;
    case LUA_TMARK:
      cl = infovalue(func)->func;
      break;
    default:
      lua_error(L, "value for `lua_getinfo' is not a function");
  }
  if (cl->isC) {
    ar->source = "=C";
    ar->linedefined = -1;
    ar->what = "C";
  }
  else
    infoLproto(ar, cl->f.l);
  luaO_chunkid(ar->short_src, ar->source, sizeof(ar->short_src));
  if (ar->linedefined == 0)
    ar->what = "main";
}


static const char *travtagmethods (lua_State *L, const TObject *o) {
  if (ttype(o) == LUA_TFUNCTION) {
    int e;
    for (e=0; elast_tag; t++)
        if (clvalue(o) == luaT_gettm(L, t, e))
          return luaT_eventname[e];
    }
  }
  return NULL;
}


static const char *travglobals (lua_State *L, const TObject *o) {
  Hash *g = L->gt;
  int i;
  for (i=0; isize; i++) {
    if (luaO_equalObj(o, val(node(g, i))) &&
        ttype(key(node(g, i))) == LUA_TSTRING) 
      return tsvalue(key(node(g, i)))->str;
  }
  return NULL;
}


static void getname (lua_State *L, StkId f, lua_Debug *ar) {
  TObject o;
  setnormalized(&o, f);
  /* try to find a name for given function */
  if ((ar->name = travglobals(L, &o)) != NULL)
    ar->namewhat = "global";
  /* not found: try tag methods */
  else if ((ar->name = travtagmethods(L, &o)) != NULL)
    ar->namewhat = "tag-method";
  else ar->namewhat = "";  /* not found at all */
}


LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
  StkId func;
  int isactive = (*what != '>');
  if (isactive)
    func = ar->_func;
  else {
    what++;  /* skip the '>' */
    func = L->top - 1;
  }
  for (; *what; what++) {
    switch (*what) {
      case 'S': {
        funcinfo(L, ar, func);
        break;
      }
      case 'l': {
        ar->currentline = currentline(func);
        break;
      }
      case 'u': {
        ar->nups = nups(func);
        break;
      }
      case 'n': {
        ar->namewhat = (isactive) ? getfuncname(L, func, &ar->name) : NULL;
        if (ar->namewhat == NULL)
          getname(L, func, ar);
        break;
      }
      case 'f': {
        setnormalized(L->top, func);
        incr_top;  /* push function */
        break;
      }
      default: return 0;  /* invalid option */
    }
  }
  if (!isactive) L->top--;  /* pop function */
  return 1;
}


/*
** {======================================================
** Symbolic Execution
** =======================================================
*/


static int pushpc (int *stack, int pc, int top, int n) {
  while (n--)
    stack[top++] = pc-1;
  return top;
}


static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
  int stack[MAXSTACK];  /* stores last instruction that changed a stack entry */
  const Instruction *code = pt->code;
  int top = pt->numparams;
  int pc = 0;
  if (pt->is_vararg)  /* varargs? */
    top++;  /* `arg' */
  while (pc < lastpc) {
    const Instruction i = code[pc++];
    LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack");
    switch (GET_OPCODE(i)) {
      case OP_RETURN: {
        LUA_ASSERT(top >= GETARG_U(i), "wrong stack");
        top = GETARG_U(i);
        break;
      }
      case OP_TAILCALL: {
        LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
        top = GETARG_B(i);
        break;
      }
      case OP_CALL: {
        int nresults = GETARG_B(i);
        if (nresults == MULT_RET) nresults = 1;
        LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
        top = pushpc(stack, pc, GETARG_A(i), nresults);
        break;
      }
      case OP_PUSHNIL: {
        top = pushpc(stack, pc, top, GETARG_U(i));
        break;
      }
      case OP_POP: {
        top -= GETARG_U(i);
        break;
      }
      case OP_SETTABLE:
      case OP_SETLIST: {
        top -= GETARG_B(i);
        break;
      }
      case OP_SETMAP: {
        top -= 2*GETARG_U(i);
        break;
      }
      case OP_CONCAT: {
        top -= GETARG_U(i);
        stack[top++] = pc-1;
        break;
      }
      case OP_CLOSURE: {
        top -= GETARG_B(i);
        stack[top++] = pc-1;
        break;
      }
      case OP_JMPONT:
      case OP_JMPONF: {
        int newpc = pc + GETARG_S(i);
        /* jump is forward and do not skip `lastpc'? */
        if (pc < newpc && newpc <= lastpc) {
          stack[top-1] = pc-1;  /* value comes from `and'/`or' */
          pc = newpc;  /* do the jump */
        }
        else
          top--;  /* do not jump; pop value */
        break;
      }
      default: {
        OpCode op = GET_OPCODE(i);
        LUA_ASSERT(luaK_opproperties[op].push != VD,
                   "invalid opcode for default");
        top -= luaK_opproperties[op].pop;
        LUA_ASSERT(top >= 0, "wrong stack");
        top = pushpc(stack, pc, top, luaK_opproperties[op].push);
      }
    }
  }
  return code[stack[stackpos]];
}


static const char *getobjname (lua_State *L, StkId obj, const char **name) {
  StkId func = aux_stackedfunction(L, 0, obj);
  if (!isLmark(func))
    return NULL;  /* not an active Lua function */
  else {
    Proto *p = infovalue(func)->func->f.l;
    int pc = currentpc(func);
    int stackpos = obj - (func+1);  /* func+1 == function base */
    Instruction i = luaG_symbexec(p, pc, stackpos);
    LUA_ASSERT(pc != -1, "function must be active");
    switch (GET_OPCODE(i)) {
      case OP_GETGLOBAL: {
        *name = p->kstr[GETARG_U(i)]->str;
        return "global";
      }
      case OP_GETLOCAL: {
        *name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
        LUA_ASSERT(*name, "local must exist");
        return "local";
      }
      case OP_PUSHSELF:
      case OP_GETDOTTED: {
        *name = p->kstr[GETARG_U(i)]->str;
        return "field";
      }
      default:
        return NULL;  /* no useful name found */
    }
  }
}


static const char *getfuncname (lua_State *L, StkId f, const char **name) {
  StkId func = aux_stackedfunction(L, 0, f);  /* calling function */
  if (!isLmark(func))
    return NULL;  /* not an active Lua function */
  else {
    Proto *p = infovalue(func)->func->f.l;
    int pc = currentpc(func);
    Instruction i;
    if (pc == -1) return NULL;  /* function is not activated */
    i = p->code[pc];
    switch (GET_OPCODE(i)) {
      case OP_CALL: case OP_TAILCALL:
        return getobjname(L, (func+1)+GETARG_A(i), name);
      default:
        return NULL;  /* no useful name found */
    }
  }
}


/* }====================================================== */


void luaG_typeerror (lua_State *L, StkId o, const char *op) {
  const char *name;
  const char *kind = getobjname(L, o, &name);
  const char *t = luaO_typename(o);
  if (kind)
    luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
                op, kind, name, t);
  else
    luaO_verror(L, "attempt to %.30s a %.10s value", op, t);
}


void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) {
  if (ttype(p1) == t) p1++;
  LUA_ASSERT(ttype(p1) != t, "must be an error");
  luaG_typeerror(L, p1, op);
}


void luaG_ordererror (lua_State *L, StkId top) {
  const char *t1 = luaO_typename(top-2);
  const char *t2 = luaO_typename(top-1);
  if (t1[2] == t2[2])
    luaO_verror(L, "attempt to compare two %.10s values", t1);
  else
    luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2);
}

tome-235-src/src/lua/ldebug.h0000644000076400017500000000074011012107763013652 0ustar  dgdg/*
** $Id: ldebug.h,v 1.2 2001/11/26 23:00:23 darkgod Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/

#ifndef ldebug_h
#define ldebug_h


#include "lstate.h"
#include "luadebug.h"


void luaG_typeerror (lua_State *L, StkId o, const char *op);
void luaG_binerror (lua_State *L, StkId p1, int t, const char *op);
int luaG_getline (int *lineinfo, int pc, int refline, int *refi);
void luaG_ordererror (lua_State *L, StkId top);


#endif
tome-235-src/src/lua/ldo.c0000644000076400017500000002404611012107763013166 0ustar  dgdg/*
** $Id: ldo.c,v 1.7 2004/06/04 13:42:10 neil Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 
#include 

#include "lua.h"

#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"
#include "lzio.h"


/* space to handle stack overflow errors */
#define EXTRA_STACK	(2*LUA_MINSTACK)


void luaD_init (lua_State *L, int stacksize) {
  L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
  L->nblocks += stacksize*sizeof(TObject);
  L->stack_last = L->stack+(stacksize-1);
  L->stacksize = stacksize;
  L->Cbase = L->top = L->stack;
}


void luaD_checkstack (lua_State *L, int n) {
  if (L->stack_last - L->top <= n) {  /* stack overflow? */
    if (L->stack_last-L->stack > (L->stacksize-1)) {
      /* overflow while handling overflow */
      luaD_breakrun(L, LUA_ERRERR);  /* break run without error message */
    }
    else {
      L->stack_last += EXTRA_STACK;  /* to be used by error message */
      lua_error(L, "stack overflow");
    }
  }
}


static void restore_stack_limit (lua_State *L) {
  if (L->top - L->stack < L->stacksize - 1)
    L->stack_last = L->stack + (L->stacksize-1);
}


/*
** Adjust stack. Set top to base+extra, pushing NILs if needed.
** (we cannot add base+extra unless we are sure it fits in the stack;
**  otherwise the result of such operation on pointers is undefined)
*/
void luaD_adjusttop (lua_State *L, StkId base, int extra) {
  int diff = extra-(L->top-base);
  if (diff <= 0)
    L->top = base+extra;
  else {
    luaD_checkstack(L, diff);
    while (diff--)
      ttype(L->top++) = LUA_TNIL;
  }
}


/*
** Open a hole inside the stack at `pos'
*/
static void luaD_openstack (lua_State *L, StkId pos) {
  int i = L->top-pos; 
  while (i--) pos[i+1] = pos[i];
  incr_top;
}


static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
  StkId old_Cbase = L->Cbase;
  StkId old_top = L->Cbase = L->top;
  luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
  L->allowhooks = 0;  /* cannot call hooks inside a hook */
  (*hook)(L, ar);
  LUA_ASSERT(L->allowhooks == 0, "invalid allow");
  L->allowhooks = 1;
  L->top = old_top;
  L->Cbase = old_Cbase;
}


void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
  if (L->allowhooks) {
    lua_Debug ar;
    ar._func = func;
    ar.event = "line";
    ar.currentline = line;
    dohook(L, &ar, linehook);
  }
}


static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
                    const char *event) {
  if (L->allowhooks) {
    lua_Debug ar;
    ar._func = func;
    ar.event = event;
    infovalue(func)->pc = NULL;  /* function is not active */
    dohook(L, &ar, callhook);
  }
}


static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
  int nup = cl->nupvalues;  /* number of upvalues */
  StkId old_Cbase = L->Cbase;
  int n;
  L->Cbase = base;       /* new base for C function */
  luaD_checkstack(L, nup+LUA_MINSTACK);  /* ensure minimum stack size */
  for (n=0; ntop++) = cl->upvalue[n];
  n = (*cl->f.c)(L);  /* do the actual call */
  L->Cbase = old_Cbase;  /* restore old C base */
  return L->top - n;  /* return index of first result */
}


void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults) {
  StkId base = L->top - nParams;
  luaD_openstack(L, base);
  clvalue(base) = f;
  ttype(base) = LUA_TFUNCTION;
  luaD_call(L, base, nResults);
}


/*
** Call a function (C or Lua). The function to be called is at *func.
** The arguments are on the stack, right after the function.
** When returns, the results are on the stack, starting at the original
** function position.
** The number of results is nResults, unless nResults=LUA_MULTRET.
*/ 
void luaD_call (lua_State *L, StkId func, int nResults) {
  lua_Hook callhook;
  StkId firstResult;
  CallInfo ci;
  Closure *cl;
  if (ttype(func) != LUA_TFUNCTION) {
    /* `func' is not a function; check the `function' tag method */
    Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION);
    if (tm == NULL)
      luaG_typeerror(L, func, "call");
    luaD_openstack(L, func);
    clvalue(func) = tm;  /* tag method is the new function to be called */
    ttype(func) = LUA_TFUNCTION;
  }
  cl = clvalue(func);
  ci.func = cl;
  infovalue(func) = &ci;
  ttype(func) = LUA_TMARK;
  callhook = L->callhook;
  if (callhook)
    luaD_callHook(L, func, callhook, "call");
  firstResult = (cl->isC ? callCclosure(L, cl, func+1) :
                           luaV_execute(L, cl, func+1));
  if (callhook)  /* same hook that was active at entry */
    luaD_callHook(L, func, callhook, "return");
  LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag");
  /* move results to `func' (to erase parameters and function) */
  if (nResults == LUA_MULTRET) {
    while (firstResult < L->top)  /* copy all results */
      *func++ = *firstResult++;
    L->top = func;
  }
  else {  /* copy at most `nResults' */
    for (; nResults > 0 && firstResult < L->top; nResults--)
      *func++ = *firstResult++;
    L->top = func;
    for (; nResults > 0; nResults--) {  /* if there are not enough results */
      ttype(L->top) = LUA_TNIL;  /* adjust the stack */
      incr_top;  /* must check stack space */
    }
  }
  luaC_checkGC(L);
}


/*
** Execute a protected call.
*/
struct CallS {  /* data to `f_call' */
  StkId func;
  int nresults;
};

static void f_call (lua_State *L, void *ud) {
  struct CallS *c = (struct CallS *)ud;
  luaD_call(L, c->func, c->nresults);
}


LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
  StkId func = L->top - (nargs+1);  /* function to be called */
  struct CallS c;
  int status;
  c.func = func; c.nresults = nresults;
  status = luaD_runprotected(L, f_call, &c);
  if (status != 0)  /* an error occurred? */
    L->top = func;  /* remove parameters from the stack */
  return status;
}


/*
** Execute a protected parser.
*/
struct ParserS {  /* data to `f_parser' */
  ZIO *z;
  int bin;
};

static void f_parser (lua_State *L, void *ud) {
  struct ParserS *p = (struct ParserS *)ud;
  Proto *tf = p->bin ? luaU_undump(L, p->z) : luaY_parser(L, p->z);
  luaV_Lclosure(L, tf, 0);
}


static int protectedparser (lua_State *L, ZIO *z, int bin) {
  struct ParserS p;
  unsigned long old_blocks;
  int status;
  p.z = z; p.bin = bin;
  luaC_checkGC(L);
  old_blocks = L->nblocks;
  status = luaD_runprotected(L, f_parser, &p);
  if (status == 0) {
    /* add new memory to threshold (as it probably will stay) */
    L->GCthreshold += (L->nblocks - old_blocks);
  }
  else if (status == LUA_ERRRUN)  /* an error occurred: correct error code */
    status = LUA_ERRSYNTAX;
  return status;
}


static int parse_file (lua_State *L, const char *filename) {
  ZIO z;
  int status;
  int bin;  /* flag for file mode */
  int c;    /* look ahead char */
  FILE *f = (filename == NULL) ? stdin : fopen(filename, "r");
  if (f == NULL) return LUA_ERRFILE;  /* unable to open file */
  c = fgetc(f);
  ungetc(c, f);
  bin = (c == ID_CHUNK);
  if (bin && f != stdin) {
    f = freopen(filename, "rb", f);  /* set binary mode */
    if (f == NULL) return LUA_ERRFILE;  /* unable to reopen file */
  }
  lua_pushstring(L, "@");
  lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
  lua_concat(L, 2);
  filename = lua_tostring(L, -1);  /* filename = '@'..filename */
  lua_pop(L, 1);  /* OK: there is no GC during parser */
  luaZ_Fopen(&z, f, filename);
  status = protectedparser(L, &z, bin);
  if (f != stdin)
    fclose(f);
  return status;
}


LUA_API int lua_dofile (lua_State *L, const char *filename) {
  int status = parse_file(L, filename);
  if (status == 0)  /* parse OK? */
    status = lua_call(L, 0, LUA_MULTRET);  /* call main */
  return status;
}


static int parse_buffer (lua_State *L, const char *buff, size_t size,
                         const char *name) {
  ZIO z;
  if (!name) name = "?";
  luaZ_mopen(&z, buff, size, name);
  return protectedparser(L, &z, buff[0]==ID_CHUNK);
}


LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
  int status = parse_buffer(L, buff, size, name);
  if (status == 0)  /* parse OK? */
    status = lua_call(L, 0, LUA_MULTRET);  /* call main */
  return status;
}


LUA_API int lua_dostring (lua_State *L, const char *str) {
  return lua_dobuffer(L, str, strlen(str), str);
}


/*
** {======================================================
** Error-recover functions (based on long jumps)
** =======================================================
*/

/* chain list of long jump buffers */
struct lua_longjmp {
  jmp_buf b;
  struct lua_longjmp *previous;
  volatile int status;  /* error code */
};


static void message (lua_State *L, const char *s) {
  const TObject *em = luaH_getglobal(L, LUA_ERRORMESSAGE);
  if (ttype(em) == LUA_TFUNCTION) {
    *L->top = *em;
    incr_top;
    lua_pushstring(L, s);
    luaD_call(L, L->top-2, 0);
  }
}


/*
** Reports an error, and jumps up to the available recovery label
*/
LUA_API void lua_error (lua_State *L, const char *s) {
  if (s) message(L, s);
  luaD_breakrun(L, LUA_ERRRUN);
}


void luaD_breakrun (lua_State *L, int errcode) {
  if (L->errorJmp) {
    L->errorJmp->status = errcode;
    longjmp(L->errorJmp->b, 1);
  }
  else {
    if (errcode != LUA_ERRMEM)
      message(L, "unable to recover; exiting\n");
    exit(EXIT_FAILURE);
  }
}


int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud) {
  StkId oldCbase = L->Cbase;
  StkId oldtop = L->top;
  struct lua_longjmp lj;
  int allowhooks = L->allowhooks;
  lj.status = 0;
  lj.previous = L->errorJmp;  /* chain new error handler */
  L->errorJmp = &lj;
  if (setjmp(lj.b) == 0)
    (*f)(L, ud);
  else {  /* an error occurred: restore the state */
    L->allowhooks = allowhooks;
    L->Cbase = oldCbase;
    L->top = oldtop;
    restore_stack_limit(L);
  }
  L->errorJmp = lj.previous;  /* restore old error handler */
  return lj.status;
}

/* }====================================================== */

tome-235-src/src/lua/ldo.h0000644000076400017500000000155211012107763013170 0ustar  dgdg/*
** $Id: ldo.h,v 1.3 2001/11/26 23:00:23 darkgod Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/

#ifndef ldo_h
#define ldo_h


#include "lobject.h"
#include "lstate.h"


/*
** macro to increment stack top.
** There must be always an empty slot at the L->stack.top
*/
#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}


void luaD_init (lua_State *L, int stacksize);
void luaD_adjusttop (lua_State *L, StkId base, int extra);
void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
void luaD_call (lua_State *L, StkId func, int nResults);
void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults);
void luaD_checkstack (lua_State *L, int n);

void luaD_breakrun (lua_State *L, int errcode);
int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud);


#endif
tome-235-src/src/lua/lgc.c0000644000076400017500000002055111012107763013152 0ustar  dgdg/*
** $Id: lgc.c,v 1.3 2001/11/26 23:00:24 darkgod Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/

#include "lua.h"

#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"


typedef struct GCState {
  Hash *tmark;  /* list of marked tables to be visited */
  Closure *cmark;  /* list of marked closures to be visited */
} GCState;



static void markobject (GCState *st, TObject *o);


/* mark a string; marks larger than 1 cannot be changed */
#define strmark(s)    {if ((s)->marked == 0) (s)->marked = 1;}



static void protomark (Proto *f) {
  if (!f->marked) {
    int i;
    f->marked = 1;
    strmark(f->source);
    for (i=0; inkstr; i++)
      strmark(f->kstr[i]);
    for (i=0; inkproto; i++)
      protomark(f->kproto[i]);
    for (i=0; inlocvars; i++)  /* mark local-variable names */
      strmark(f->locvars[i].varname);
  }
}


static void markstack (lua_State *L, GCState *st) {
  StkId o;
  for (o=L->stack; otop; o++)
    markobject(st, o);
}


static void marklock (lua_State *L, GCState *st) {
  int i;
  for (i=0; irefSize; i++) {
    if (L->refArray[i].st == LOCK)
      markobject(st, &L->refArray[i].o);
  }
}


static void markclosure (GCState *st, Closure *cl) {
  if (!ismarked(cl)) {
    if (!cl->isC)
      protomark(cl->f.l);
    cl->mark = st->cmark;  /* chain it for later traversal */
    st->cmark = cl;
  }
}


static void marktagmethods (lua_State *L, GCState *st) {
  int e;
  for (e=0; elast_tag; t++) {
      Closure *cl = luaT_gettm(L, t, e);
      if (cl) markclosure(st, cl);
    }
  }
}


static void markobject (GCState *st, TObject *o) {
  switch (ttype(o)) {
    case LUA_TUSERDATA:  case LUA_TSTRING:
      strmark(tsvalue(o));
      break;
    case LUA_TMARK:
      markclosure(st, infovalue(o)->func);
      break;
    case LUA_TFUNCTION:
      markclosure(st, clvalue(o));
      break;
    case LUA_TTABLE: {
      if (!ismarked(hvalue(o))) {
        hvalue(o)->mark = st->tmark;  /* chain it in list of marked */
        st->tmark = hvalue(o);
      }
      break;
    }
    default: break;  /* numbers, etc */
  }
}


static void markall (lua_State *L) {
  GCState st;
  st.cmark = NULL;
  st.tmark = L->gt;  /* put table of globals in mark list */
  L->gt->mark = NULL;
  marktagmethods(L, &st);  /* mark tag methods */
  markstack(L, &st); /* mark stack objects */
  marklock(L, &st); /* mark locked objects */
  for (;;) {  /* mark tables and closures */
    if (st.cmark) {
      int i;
      Closure *f = st.cmark;  /* get first closure from list */
      st.cmark = f->mark;  /* remove it from list */
      for (i=0; inupvalues; i++)  /* mark its upvalues */
        markobject(&st, &f->upvalue[i]);
    }
    else if (st.tmark) {
      int i;
      Hash *h = st.tmark;  /* get first table from list */
      st.tmark = h->mark;  /* remove it from list */
      for (i=0; isize; i++) {
        Node *n = node(h, i);
        if (ttype(key(n)) != LUA_TNIL) {
          if (ttype(val(n)) == LUA_TNIL)
            luaH_remove(h, key(n));  /* dead element; try to remove it */
          markobject(&st, &n->key);
          markobject(&st, &n->val);
        }
      }
    }
    else break;  /* nothing else to mark */
  }
}


static int hasmark (const TObject *o) {
  /* valid only for locked objects */
  switch (o->ttype) {
    case LUA_TSTRING: case LUA_TUSERDATA:
      return tsvalue(o)->marked;
    case LUA_TTABLE:
      return ismarked(hvalue(o));
    case LUA_TFUNCTION:
      return ismarked(clvalue(o));
    default:  /* number */
      return 1;
  }
}


/* macro for internal debugging; check if a link of free refs is valid */
#define VALIDLINK(L, st,n)      (NONEXT <= (st) && (st) < (n))

static void invalidaterefs (lua_State *L) {
  int n = L->refSize;
  int i;
  for (i=0; irefArray[i];
    if (r->st == HOLD && !hasmark(&r->o))
      r->st = COLLECTED;
    LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
               (r->st == HOLD && hasmark(&r->o)) ||
                r->st == COLLECTED ||
                r->st == NONEXT ||
               (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
               "inconsistent ref table");
  }
  LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
}



static void collectproto (lua_State *L) {
  Proto **p = &L->rootproto;
  Proto *next;
  while ((next = *p) != NULL) {
    if (next->marked) {
      next->marked = 0;
      p = &next->next;
    }
    else {
      *p = next->next;
      luaF_freeproto(L, next);
    }
  }
}


static void collectclosure (lua_State *L) {
  Closure **p = &L->rootcl;
  Closure *next;
  while ((next = *p) != NULL) {
    if (ismarked(next)) {
      next->mark = next;  /* unmark */
      p = &next->next;
    }
    else {
      *p = next->next;
      luaF_freeclosure(L, next);
    }
  }
}


static void collecttable (lua_State *L) {
  Hash **p = &L->roottable;
  Hash *next;
  while ((next = *p) != NULL) {
    if (ismarked(next)) {
      next->mark = next;  /* unmark */
      p = &next->next;
    }
    else {
      *p = next->next;
      luaH_free(L, next);
    }
  }
}


static void checktab (lua_State *L, stringtable *tb) {
  if (tb->nuse < (lint32)(tb->size/4) && tb->size > 10)
    luaS_resize(L, tb, tb->size/2);  /* table is too big */
}


static void collectstrings (lua_State *L, int all) {
  int i;
  for (i=0; istrt.size; i++) {  /* for each list */
    TString **p = &L->strt.hash[i];
    TString *next;
    while ((next = *p) != NULL) {
      if (next->marked && !all) {  /* preserve? */
        if (next->marked < FIXMARK)  /* does not change FIXMARKs */
          next->marked = 0;
        p = &next->nexthash;
      } 
      else {  /* collect */
        *p = next->nexthash;
        L->strt.nuse--;
        L->nblocks -= sizestring(next->len);
        luaM_free(L, next);
      }
    }
  }
  checktab(L, &L->strt);
}


static void collectudata (lua_State *L, int all) {
  int i;
  for (i=0; iudt.size; i++) {  /* for each list */
    TString **p = &L->udt.hash[i];
    TString *next;
    while ((next = *p) != NULL) {
      LUA_ASSERT(next->marked <= 1, "udata cannot be fixed");
      if (next->marked && !all) {  /* preserve? */
        next->marked = 0;
        p = &next->nexthash;
      } 
      else {  /* collect */
        int tag = next->u.d.tag;
        *p = next->nexthash;
        next->nexthash = L->TMtable[tag].collected;  /* chain udata */
        L->TMtable[tag].collected = next;
        L->nblocks -= sizestring(next->len);
        L->udt.nuse--;
      }
    }
  }
  checktab(L, &L->udt);
}


#define MINBUFFER	256
static void checkMbuffer (lua_State *L) {
  if (L->Mbuffsize > MINBUFFER*2) {  /* is buffer too big? */
    size_t newsize = L->Mbuffsize/2;  /* still larger than MINBUFFER */
    L->nblocks += (newsize - L->Mbuffsize)*sizeof(char);
    L->Mbuffsize = newsize;
    luaM_reallocvector(L, L->Mbuffer, newsize, char);
  }
}


static void callgcTM (lua_State *L, const TObject *o) {
  Closure *tm = luaT_gettmbyObj(L, o, TM_GC);
  if (tm != NULL) {
    int oldah = L->allowhooks;
    L->allowhooks = 0;  /* stop debug hooks during GC tag methods */
    luaD_checkstack(L, 2);
    clvalue(L->top) = tm;
    ttype(L->top) = LUA_TFUNCTION;
    *(L->top+1) = *o;
    L->top += 2;
    luaD_call(L, L->top-2, 0);
    L->allowhooks = oldah;  /* restore hooks */
  }
}


static void callgcTMudata (lua_State *L) {
  int tag;
  TObject o;
  ttype(&o) = LUA_TUSERDATA;
  L->GCthreshold = 2*L->nblocks;  /* avoid GC during tag methods */
  for (tag=L->last_tag; tag>=0; tag--) {  /* for each tag (in reverse order) */
    TString *udata;
    while ((udata = L->TMtable[tag].collected) != NULL) {
      L->TMtable[tag].collected = udata->nexthash;  /* remove it from list */
      tsvalue(&o) = udata;
      callgcTM(L, &o);
      luaM_free(L, udata);
    }
  }
}


void luaC_collect (lua_State *L, int all) {
  collectudata(L, all);
  callgcTMudata(L);
  collectstrings(L, all);
  collecttable(L);
  collectproto(L);
  collectclosure(L);
}


static void luaC_collectgarbage (lua_State *L) {
  markall(L);
  invalidaterefs(L);  /* check unlocked references */
  luaC_collect(L, 0);
  checkMbuffer(L);
  L->GCthreshold = 2*L->nblocks;  /* set new threshold */
  callgcTM(L, &luaO_nilobject);
}


void luaC_checkGC (lua_State *L) {
  if (L->nblocks >= L->GCthreshold)
    luaC_collectgarbage(L);
}

tome-235-src/src/lua/lgc.h0000644000076400017500000000037611012107763013162 0ustar  dgdg/*
** $Id: lgc.h,v 1.3 2001/11/26 23:00:24 darkgod Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/

#ifndef lgc_h
#define lgc_h


#include "lobject.h"


void luaC_collect (lua_State *L, int all);
void luaC_checkGC (lua_State *L);


#endif
tome-235-src/src/lua/lua.h0000644000076400017500000001740211012107763013174 0ustar  dgdg/*
** $Id: lua.h,v 1.2 2001/11/26 23:00:26 darkgod Exp $
** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br
** www: http://www.tecgraf.puc-rio.br/lua/
** See Copyright Notice at the end of this file
*/


#ifndef lua_h
#define lua_h


/* definition of `size_t' */
#include 


/* mark for all API functions */
#ifndef LUA_API
#define LUA_API		extern
#endif


#define LUA_VERSION	"Lua 4.0"
#define LUA_COPYRIGHT	"Copyright (C) 1994-2000 TeCGraf, PUC-Rio"
#define LUA_AUTHORS 	"W. Celes, R. Ierusalimschy & L. H. de Figueiredo"


/* name of global variable with error handler */
#define LUA_ERRORMESSAGE	"_ERRORMESSAGE"


/* pre-defined references */
#define LUA_NOREF	(-2)
#define LUA_REFNIL	(-1)
#define LUA_REFREGISTRY	0

/* pre-defined tags */
#define LUA_ANYTAG	(-1)
#define LUA_NOTAG	(-2)


/* option for multiple returns in lua_call */
#define LUA_MULTRET	(-1)


/* minimum stack available for a C function */
#define LUA_MINSTACK	20


/* error codes for lua_do* */
#define LUA_ERRRUN	1
#define LUA_ERRFILE	2
#define LUA_ERRSYNTAX	3
#define LUA_ERRMEM	4
#define LUA_ERRERR	5


typedef struct lua_State lua_State;

typedef int (*lua_CFunction) (lua_State *L);

/*
** types returned by `lua_type'
*/
#define LUA_TNONE	(-1)

#define LUA_TUSERDATA	0
#define LUA_TNIL	1
#define LUA_TNUMBER	2
#define LUA_TSTRING	3
#define LUA_TTABLE	4
#define LUA_TFUNCTION	5



/*
** state manipulation
*/
LUA_API lua_State *lua_open (int stacksize);
LUA_API void       lua_close (lua_State *L);


/*
** basic stack manipulation
*/
LUA_API int   lua_gettop (lua_State *L);
LUA_API void  lua_settop (lua_State *L, int index);
LUA_API void  lua_pushvalue (lua_State *L, int index);
LUA_API void  lua_remove (lua_State *L, int index);
LUA_API void  lua_insert (lua_State *L, int index);
LUA_API int   lua_stackspace (lua_State *L);


/*
** access functions (stack -> C)
*/

LUA_API int            lua_type (lua_State *L, int index);
LUA_API const char    *lua_typename (lua_State *L, int t);
LUA_API int            lua_isnumber (lua_State *L, int index);
LUA_API int            lua_isstring (lua_State *L, int index);
LUA_API int            lua_iscfunction (lua_State *L, int index);
LUA_API int            lua_tag (lua_State *L, int index);

LUA_API int            lua_equal (lua_State *L, int index1, int index2);
LUA_API int            lua_lessthan (lua_State *L, int index1, int index2);

LUA_API long         lua_tonumber (lua_State *L, int index);
LUA_API const char    *lua_tostring (lua_State *L, int index);
LUA_API size_t         lua_strlen (lua_State *L, int index);
LUA_API lua_CFunction  lua_tocfunction (lua_State *L, int index);
LUA_API void	      *lua_touserdata (lua_State *L, int index);
LUA_API const void    *lua_topointer (lua_State *L, int index);


/*
** push functions (C -> stack)
*/
LUA_API void  lua_pushnil (lua_State *L);
LUA_API void  lua_pushnumber (lua_State *L, long n);
LUA_API void  lua_pushlstring (lua_State *L, const char *s, size_t len);
LUA_API void  lua_pushstring (lua_State *L, const char *s);
LUA_API void  lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
LUA_API void  lua_pushusertag (lua_State *L, void *u, int tag);


/*
** get functions (Lua -> stack)
*/
LUA_API void  lua_getglobal (lua_State *L, const char *name);
LUA_API void  lua_gettable (lua_State *L, int index);
LUA_API void  lua_rawget (lua_State *L, int index);
LUA_API void  lua_rawgeti (lua_State *L, int index, int n);
LUA_API void  lua_getglobals (lua_State *L);
LUA_API void  lua_gettagmethod (lua_State *L, int tag, const char *event);
LUA_API int   lua_getref (lua_State *L, int ref);
LUA_API void  lua_newtable (lua_State *L);


/*
** set functions (stack -> Lua)
*/
LUA_API void  lua_setglobal (lua_State *L, const char *name);
LUA_API void  lua_settable (lua_State *L, int index);
LUA_API void  lua_rawset (lua_State *L, int index);
LUA_API void  lua_rawseti (lua_State *L, int index, int n);
LUA_API void  lua_setglobals (lua_State *L);
LUA_API void  lua_settagmethod (lua_State *L, int tag, const char *event);
LUA_API int   lua_ref (lua_State *L, int lock);


/*
** "do" functions (run Lua code)
*/
LUA_API int   lua_call (lua_State *L, int nargs, int nresults);
LUA_API void  lua_rawcall (lua_State *L, int nargs, int nresults);
LUA_API int   lua_dofile (lua_State *L, const char *filename);
LUA_API int   lua_dostring (lua_State *L, const char *str);
LUA_API int   lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name);

/*
** Garbage-collection functions
*/
LUA_API int   lua_getgcthreshold (lua_State *L);
LUA_API int   lua_getgccount (lua_State *L);
LUA_API void  lua_setgcthreshold (lua_State *L, int newthreshold);

/*
** miscellaneous functions
*/
LUA_API int   lua_newtag (lua_State *L);
LUA_API int   lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
LUA_API void  lua_settag (lua_State *L, int tag);

LUA_API void  lua_error (lua_State *L, const char *s);

LUA_API void  lua_unref (lua_State *L, int ref);

LUA_API int   lua_next (lua_State *L, int index);
LUA_API int   lua_getn (lua_State *L, int index);

LUA_API void  lua_concat (lua_State *L, int n);

LUA_API void *lua_newuserdata (lua_State *L, size_t size);


/* 
** ===============================================================
** some useful macros
** ===============================================================
*/

#define lua_pop(L,n)		lua_settop(L, -(n)-1)

#define lua_register(L,n,f)	(lua_pushcfunction(L, f), lua_setglobal(L, n))
#define lua_pushuserdata(L,u)	lua_pushusertag(L, u, 0)
#define lua_pushcfunction(L,f)	lua_pushcclosure(L, f, 0)
#define lua_clonetag(L,t)	lua_copytagmethods(L, lua_newtag(L), (t))

#define lua_isfunction(L,n)	(lua_type(L,n) == LUA_TFUNCTION)
#define lua_istable(L,n)	(lua_type(L,n) == LUA_TTABLE)
#define lua_isuserdata(L,n)	(lua_type(L,n) == LUA_TUSERDATA)
#define lua_isnil(L,n)		(lua_type(L,n) == LUA_TNIL)
#define lua_isnull(L,n)		(lua_type(L,n) == LUA_TNONE)

#define lua_getregistry(L)	lua_getref(L, LUA_REFREGISTRY)

#endif



/******************************************************************************
* Copyright (C) 1994-2000 TeCGraf, PUC-Rio.  All rights reserved.
* 
* Permission is hereby granted, without written agreement and without license
* or royalty fees, to use, copy, modify, and distribute this software and its
* documentation for any purpose, including commercial applications, subject to
* the following conditions:
* 
*  - The above copyright notice and this permission notice shall appear in all
*    copies or substantial portions of this software.
* 
*  - The origin of this software must not be misrepresented; you must not
*    claim that you wrote the original software. If you use this software in a
*    product, an acknowledgment in the product documentation would be greatly
*    appreciated (but it is not required).
* 
*  - Altered source versions must be plainly marked as such, and must not be
*    misrepresented as being the original software.
*    
* The authors specifically disclaim any warranties, including, but not limited
* to, the implied warranties of merchantability and fitness for a particular
* purpose.  The software provided hereunder is on an "as is" basis, and the
* authors have no obligation to provide maintenance, support, updates,
* enhancements, or modifications.  In no event shall TeCGraf, PUC-Rio, or the
* authors be held liable to any party for direct, indirect, special,
* incidental, or consequential damages arising out of the use of this software
* and its documentation.
* 
* The Lua language and this implementation have been entirely designed and
* written by Waldemar Celes Filho, Roberto Ierusalimschy and
* Luiz Henrique de Figueiredo at TeCGraf, PUC-Rio.
*
* This implementation contains no third-party code.
******************************************************************************/

tome-235-src/src/lua/ltm.c0000644000076400017500000001014311012107763013175 0ustar  dgdg/*
** $Id: ltm.c,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** Tag methods
** See Copyright Notice in lua.h
*/


#include 
#include 

#include "lua.h"

#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "ltm.h"


const char *const luaT_eventname[] = {  /* ORDER TM */
  "gettable", "settable", "index", "getglobal", "setglobal", "add", "sub",
  "mul", "div", "pow", "unm", "lt", "concat", "gc", "function",
  "le", "gt", "ge",  /* deprecated options!! */
  NULL
};


static int findevent (const char *name) {
  int i;
  for (i=0; luaT_eventname[i]; i++)
    if (strcmp(luaT_eventname[i], name) == 0)
      return i;
  return -1;  /* name not found */
}


static int luaI_checkevent (lua_State *L, const char *name, int t) {
  int e = findevent(name);
  if (e >= TM_N)
    luaO_verror(L, "event `%.50s' is deprecated", name);
  if (e == TM_GC && t == LUA_TTABLE)
    luaO_verror(L, "event `gc' for tables is deprecated");
  if (e < 0)
    luaO_verror(L, "`%.50s' is not a valid event name", name);
  return e;
}



/* events in LUA_TNIL are all allowed, since this is used as a
*  'placeholder' for "default" fallbacks
*/
/* ORDER LUA_T, ORDER TM */
static const char luaT_validevents[NUM_TAGS][TM_N] = {
  {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},  /* LUA_TUSERDATA */
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},  /* LUA_TNIL */
  {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1},  /* LUA_TNUMBER */
  {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},  /* LUA_TSTRING */
  {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},  /* LUA_TTABLE */
  {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}   /* LUA_TFUNCTION */
};

int luaT_validevent (int t, int e) {  /* ORDER LUA_T */
  return (t >= NUM_TAGS) ?  1 : luaT_validevents[t][e];
}


static void init_entry (lua_State *L, int tag) {
  int i;
  for (i=0; iTMtable[tag].collected = NULL;
}


void luaT_init (lua_State *L) {
  int t;
  luaM_growvector(L, L->TMtable, 0, NUM_TAGS, struct TM, "", MAX_INT);
  L->nblocks += NUM_TAGS*sizeof(struct TM);
  L->last_tag = NUM_TAGS-1;
  for (t=0; t<=L->last_tag; t++)
    init_entry(L, t);
}


LUA_API int lua_newtag (lua_State *L) {
  luaM_growvector(L, L->TMtable, L->last_tag, 1, struct TM,
                  "tag table overflow", MAX_INT);
  L->nblocks += sizeof(struct TM);
  L->last_tag++;
  init_entry(L, L->last_tag);
  return L->last_tag;
}


static void checktag (lua_State *L, int tag) {
  if (!(0 <= tag && tag <= L->last_tag))
    luaO_verror(L, "%d is not a valid tag", tag);
}

void luaT_realtag (lua_State *L, int tag) {
  if (!validtag(tag))
    luaO_verror(L, "tag %d was not created by `newtag'", tag);
}


LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
  int e;
  checktag(L, tagto);
  checktag(L, tagfrom);
  for (e=0; eu.d.tag;
    case LUA_TTABLE:    return hvalue(o)->htag;
    default:            return t;
  }
}


LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
  int e;
  e = luaI_checkevent(L, event, t);
  checktag(L, t);
  if (luaT_validevent(t, e) && luaT_gettm(L, t, e)) {
    clvalue(L->top) = luaT_gettm(L, t, e);
    ttype(L->top) = LUA_TFUNCTION;
  }
  else
    ttype(L->top) = LUA_TNIL;
  incr_top;
}


LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
  int e = luaI_checkevent(L, event, t);
  checktag(L, t);
  if (!luaT_validevent(t, e))
    luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
                luaT_eventname[e], luaO_typenames[t],
                (t == LUA_TTABLE || t == LUA_TUSERDATA) ?
                   " with default tag" : "");
  switch (ttype(L->top - 1)) {
    case LUA_TNIL:
      luaT_gettm(L, t, e) = NULL;
      break;
    case LUA_TFUNCTION:
      luaT_gettm(L, t, e) = clvalue(L->top - 1);
      break;
    default:
      lua_error(L, "tag method must be a function (or nil)");
  }
  L->top--;
}

tome-235-src/src/lua/ltm.h0000644000076400017500000000204111012107763013200 0ustar  dgdg/*
** $Id: ltm.h,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** Tag methods
** See Copyright Notice in lua.h
*/

#ifndef ltm_h
#define ltm_h


#include "lobject.h"
#include "lstate.h"

/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM"
*/
typedef enum {
  TM_GETTABLE = 0,
  TM_SETTABLE,
  TM_INDEX,
  TM_GETGLOBAL,
  TM_SETGLOBAL,
  TM_ADD,
  TM_SUB,
  TM_MUL,
  TM_DIV,
  TM_POW,
  TM_UNM,
  TM_LT,
  TM_CONCAT,
  TM_GC,
  TM_FUNCTION,
  TM_N		/* number of elements in the enum */
} TMS;


struct TM {
  Closure *method[TM_N];
  TString *collected;  /* list of garbage-collected udata with this tag */
};


#define luaT_gettm(L,tag,event) (L->TMtable[tag].method[event])
#define luaT_gettmbyObj(L,o,e)  (luaT_gettm((L),luaT_tag(o),(e)))


#define validtag(t) (NUM_TAGS <= (t) && (t) <= L->last_tag)

extern const char *const luaT_eventname[];


void luaT_init (lua_State *L);
void luaT_realtag (lua_State *L, int tag);
int luaT_tag (const TObject *o);
int luaT_validevent (int t, int e);  /* used by compatibility module */


#endif
tome-235-src/src/lua/lvm.c0000644000076400017500000004602511012107763013207 0ustar  dgdg/*
** $Id: lvm.c,v 1.5 2004/06/04 13:42:10 neil Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 

#include "lua.h"

#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"


#ifdef OLD_ANSI
#define strcoll(a,b)	strcmp(a,b)
#endif



/*
** Extra stack size to run a function:
** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
*/
#define	EXTRA_STACK	8



int luaV_tonumber (TObject *obj) {
  if (ttype(obj) != LUA_TSTRING)
    return 1;
  else {
    if (!luaO_str2d(svalue(obj), &nvalue(obj)))
      return 2;
    ttype(obj) = LUA_TNUMBER;
    return 0;
  }
}


int luaV_tostring (lua_State *L, TObject *obj) {  /* LUA_NUMBER */
  if (ttype(obj) != LUA_TNUMBER)
    return 1;
  else {
    char s[32];  /* 16 digits, sign, point and \0  (+ some extra...) */
    lua_number2str(s, nvalue(obj));  /* convert `s' to number */
    tsvalue(obj) = luaS_new(L, s);
    ttype(obj) = LUA_TSTRING;
    return 0;
  }
}


static void traceexec (lua_State *L, StkId base, StkId top, lua_Hook linehook) {
  CallInfo *ci = infovalue(base-1);
  int *lineinfo = ci->func->f.l->lineinfo;
  int pc = (*ci->pc - ci->func->f.l->code) - 1;
  int newline;
  if (pc == 0) {  /* may be first time? */
    ci->line = 1;
    ci->refi = 0;
    ci->lastpc = pc+1;  /* make sure it will call linehook */
  }
  newline = luaG_getline(lineinfo, pc, ci->line, &ci->refi);
  /* calls linehook when enters a new line or jumps back (loop) */
  if (newline != ci->line || pc <= ci->lastpc) {
    ci->line = newline;
    L->top = top;
    luaD_lineHook(L, base-2, newline, linehook);
  }
  ci->lastpc = pc;
}


static Closure *luaV_closure (lua_State *L, int nelems) {
  Closure *c = luaF_newclosure(L, nelems);
  L->top -= nelems;
  while (nelems--)
    c->upvalue[nelems] = *(L->top+nelems);
  clvalue(L->top) = c;
  ttype(L->top) = LUA_TFUNCTION;
  incr_top;
  return c;
}


void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems) {
  Closure *cl = luaV_closure(L, nelems);
  cl->f.c = c;
  cl->isC = 1;
}


void luaV_Lclosure (lua_State *L, Proto *l, int nelems) {
  Closure *cl = luaV_closure(L, nelems);
  cl->f.l = l;
  cl->isC = 0;
}


/*
** Function to index a table.
** Receives the table at `t' and the key at top.
*/
const TObject *luaV_gettable (lua_State *L, StkId t) {
  Closure *tm;
  int tg;
  if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
      ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
        luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */
    /* do a primitive get */
    const TObject *h = luaH_get(L, hvalue(t), L->top-1);
    /* result is no nil or there is no `index' tag method? */
    if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL))
      return h;  /* return result */
    /* else call `index' tag method */
  }
  else {  /* try a `gettable' tag method */
    tm = luaT_gettmbyObj(L, t, TM_GETTABLE);
  }
  if (tm != NULL) {  /* is there a tag method? */
    luaD_checkstack(L, 2);
    *(L->top+1) = *(L->top-1);  /* key */
    *L->top = *t;  /* table */
    clvalue(L->top-1) = tm;  /* tag method */
    ttype(L->top-1) = LUA_TFUNCTION;
    L->top += 2;
    luaD_call(L, L->top - 3, 1);
    return L->top - 1;  /* call result */
  }
  else {  /* no tag method */
    luaG_typeerror(L, t, "index");
    return NULL;  /* to avoid warnings */
  }
}


/*
** Receives table at `t', key at `key' and value at top.
*/
void luaV_settable (lua_State *L, StkId t, StkId key) {
  int tg;
  if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
      ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
        luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */
    *luaH_set(L, hvalue(t), key) = *(L->top-1);  /* do a primitive set */
  else {  /* try a `settable' tag method */
    Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE);
    if (tm != NULL) {
      luaD_checkstack(L, 3);
      *(L->top+2) = *(L->top-1);
      *(L->top+1) = *key;
      *(L->top) = *t;
      clvalue(L->top-1) = tm;
      ttype(L->top-1) = LUA_TFUNCTION;
      L->top += 3;
      luaD_call(L, L->top - 4, 0);  /* call `settable' tag method */
    }
    else  /* no tag method... */
      luaG_typeerror(L, t, "index");
  }
}


const TObject *luaV_getglobal (lua_State *L, TString *s) {
  const TObject *value = luaH_getstr(L->gt, s);
  Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL);
  if (tm == NULL)  /* is there a tag method? */
    return value;  /* default behavior */
  else {  /* tag method */
    luaD_checkstack(L, 3);
    clvalue(L->top) = tm;
    ttype(L->top) = LUA_TFUNCTION;
    tsvalue(L->top+1) = s;  /* global name */
    ttype(L->top+1) = LUA_TSTRING;
    *(L->top+2) = *value;
    L->top += 3;
    luaD_call(L, L->top - 3, 1);
    return L->top - 1;
  }
}


void luaV_setglobal (lua_State *L, TString *s) {
  const TObject *oldvalue = luaH_getstr(L->gt, s);
  Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL);
  if (tm == NULL) {  /* is there a tag method? */
    if (oldvalue != &luaO_nilobject) {
      /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */
      *(TObject *)oldvalue = *(L->top - 1);
    }
    else {
      TObject key;
      ttype(&key) = LUA_TSTRING;
      tsvalue(&key) = s;
      *luaH_set(L, L->gt, &key) = *(L->top - 1);
    }
  }
  else {
    luaD_checkstack(L, 3);
    *(L->top+2) = *(L->top-1);  /* new value */
    *(L->top+1) = *oldvalue;
    ttype(L->top) = LUA_TSTRING;
    tsvalue(L->top) = s;
    clvalue(L->top-1) = tm;
    ttype(L->top-1) = LUA_TFUNCTION;
    L->top += 3;
    luaD_call(L, L->top - 4, 0);
  }
}


static int call_binTM (lua_State *L, StkId top, TMS event) {
  /* try first operand */
  Closure *tm = luaT_gettmbyObj(L, top-2, event);
  L->top = top;
  if (tm == NULL) {
    tm = luaT_gettmbyObj(L, top-1, event);  /* try second operand */
    if (tm == NULL) {
      tm = luaT_gettm(L, 0, event);  /* try a `global' method */
      if (tm == NULL)
        return 0;  /* error */
    }
  }
  lua_pushstring(L, luaT_eventname[event]);
  luaD_callTM(L, tm, 3, 1);
  return 1;
}


static void call_arith (lua_State *L, StkId top, TMS event) {
  if (!call_binTM(L, top, event))
    luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on");
}


static int luaV_strcomp (const TString *ls, const TString *rs) {
  const char *l = ls->str;
  size_t ll = ls->len;
  const char *r = rs->str;
  size_t lr = rs->len;
  for (;;) {
    int temp = strcoll(l, r);
    if (temp != 0) return temp;
    else {  /* strings are equal up to a '\0' */
      size_t len = strlen(l);  /* index of first '\0' in both strings */
      if (len == ll)  /* l is finished? */
        return (len == lr) ? 0 : -1;  /* l is equal or smaller than r */
      else if (len == lr)  /* r is finished? */
        return 1;  /* l is greater than r (because l is not finished) */
      /* both strings longer than `len'; go on comparing (after the '\0') */
      len++;
      l += len; ll -= len; r += len; lr -= len;
    }
  }
}


int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) {
  if (ttype(l) == LUA_TNUMBER && ttype(r) == LUA_TNUMBER)
    return (nvalue(l) < nvalue(r));
  else if (ttype(l) == LUA_TSTRING && ttype(r) == LUA_TSTRING)
    return (luaV_strcomp(tsvalue(l), tsvalue(r)) < 0);
  else {  /* call TM */
    luaD_checkstack(L, 2);
    *top++ = *l;
    *top++ = *r;
    if (!call_binTM(L, top, TM_LT))
      luaG_ordererror(L, top-2);
    L->top--;
    return (ttype(L->top) != LUA_TNIL);
  }
}


void luaV_strconc (lua_State *L, int total, StkId top) {
  do {
    int n = 2;  /* number of elements handled in this pass (at least 2) */
    if (tostring(L, top-2) || tostring(L, top-1)) {
      if (!call_binTM(L, top, TM_CONCAT))
        luaG_binerror(L, top-2, LUA_TSTRING, "concat");
    }
    else if (tsvalue(top-1)->len > 0) {  /* if len=0, do nothing */
      /* at least two string values; get as many as possible */
      lint32 tl = (lint32)tsvalue(top-1)->len + 
                  (lint32)tsvalue(top-2)->len;
      char *buffer;
      int i;
      while (n < total && !tostring(L, top-n-1)) {  /* collect total length */
        tl += tsvalue(top-n-1)->len;
        n++;
      }
      if (tl > MAX_SIZET) lua_error(L, "string size overflow");
      buffer = luaO_openspace(L, tl);
      tl = 0;
      for (i=n; i>0; i--) {  /* concat all strings */
        size_t l = tsvalue(top-i)->len;
        memcpy(buffer+tl, tsvalue(top-i)->str, l);
        tl += l;
      }
      tsvalue(top-n) = luaS_newlstr(L, buffer, tl);
    }
    total -= n-1;  /* got `n' strings to create 1 new */
    top -= n-1;
  } while (total > 1);  /* repeat until only 1 result left */
}


static void luaV_pack (lua_State *L, StkId firstelem) {
  int i;
  Hash *htab = luaH_new(L, 0);
  for (i=0; firstelem+itop; i++)
    *luaH_setint(L, htab, i+1) = *(firstelem+i);
  /* store counter in field `n' */
  luaH_setstrnum(L, htab, luaS_new(L, "n"), i);
  L->top = firstelem;  /* remove elements from the stack */
  ttype(L->top) = LUA_TTABLE;
  hvalue(L->top) = htab;
  incr_top;
}


static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
  int nvararg = (L->top-base) - nfixargs;
  if (nvararg < 0)
    luaD_adjusttop(L, base, nfixargs);
  luaV_pack(L, base+nfixargs);
}



#define dojump(pc, i)	{ int d = GETARG_S(i); pc += d; }

/*
** Executes the given Lua function. Parameters are between [base,top).
** Returns n such that the the results are between [n,top).
*/
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
  const Proto *const tf = cl->f.l;
  StkId top;  /* keep top local, for performance */
  const Instruction *pc = tf->code;
  TString **const kstr = tf->kstr;
  const lua_Hook linehook = L->linehook;
  infovalue(base-1)->pc = &pc;
  luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
  if (tf->is_vararg)  /* varargs? */
    adjust_varargs(L, base, tf->numparams);
  else
    luaD_adjusttop(L, base, tf->numparams);
  top = L->top;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    if (linehook)
      traceexec(L, base, top, linehook);
    switch (GET_OPCODE(i)) {
      case OP_END: {
        L->top = top;
        return top;
      }
      case OP_RETURN: {
        L->top = top;
        return base+GETARG_U(i);
      }
      case OP_CALL: {
        int nres = GETARG_B(i);
        if (nres == MULT_RET) nres = LUA_MULTRET;
        L->top = top;
        luaD_call(L, base+GETARG_A(i), nres);
        top = L->top;
        break;
      }
      case OP_TAILCALL: {
        L->top = top;
        luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
        return base+GETARG_B(i);
      }
      case OP_PUSHNIL: {
        int n = GETARG_U(i);
        LUA_ASSERT(n>0, "invalid argument");
        do {
          ttype(top++) = LUA_TNIL;
        } while (--n > 0);
        break;
      }
      case OP_POP: {
        top -= GETARG_U(i);
        break;
      }
      case OP_PUSHINT: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = (Number)GETARG_S(i);
        top++;
        break;
      }
      case OP_PUSHSTRING: {
        ttype(top) = LUA_TSTRING;
        tsvalue(top) = kstr[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHNUM: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = tf->knum[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHNEGNUM: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = -tf->knum[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHUPVALUE: {
        *top++ = cl->upvalue[GETARG_U(i)];
        break;
      }
      case OP_GETLOCAL: {
        *top++ = *(base+GETARG_U(i));
        break;
      }
      case OP_GETGLOBAL: {
        L->top = top;
        *top = *luaV_getglobal(L, kstr[GETARG_U(i)]);
        top++;
        break;
      }
      case OP_GETTABLE: {
        L->top = top;
        top--;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_GETDOTTED: {
        ttype(top) = LUA_TSTRING;
        tsvalue(top) = kstr[GETARG_U(i)];
        L->top = top+1;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_GETINDEXED: {
        *top = *(base+GETARG_U(i));
        L->top = top+1;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_PUSHSELF: {
        TObject receiver;
        receiver = *(top-1);
        ttype(top) = LUA_TSTRING;
        tsvalue(top++) = kstr[GETARG_U(i)];
        L->top = top;
        *(top-2) = *luaV_gettable(L, top-2);
        *(top-1) = receiver;
        break;
      }
      case OP_CREATETABLE: {
        L->top = top;
        luaC_checkGC(L);
        hvalue(top) = luaH_new(L, GETARG_U(i));
        ttype(top) = LUA_TTABLE;
        top++;
        break;
      }
      case OP_SETLOCAL: {
        *(base+GETARG_U(i)) = *(--top);
        break;
      }
      case OP_SETGLOBAL: {
        L->top = top;
        luaV_setglobal(L, kstr[GETARG_U(i)]);
        top--;
        break;
      }
      case OP_SETTABLE: {
        StkId t = top-GETARG_A(i);
        L->top = top;
        luaV_settable(L, t, t+1);
        top -= GETARG_B(i);  /* pop values */
        break;
      }
      case OP_SETLIST: {
        int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
        int n = GETARG_B(i);
        Hash *arr = hvalue(top-n-1);
        L->top = top-n;  /* final value of `top' (in case of errors) */
        for (; n; n--)
          *luaH_setint(L, arr, n+aux) = *(--top);
        break;
      }
      case OP_SETMAP: {
        int n = GETARG_U(i);
        StkId finaltop = top-2*n;
        Hash *arr = hvalue(finaltop-1);
        L->top = finaltop;  /* final value of `top' (in case of errors) */
        for (; n; n--) {
          top-=2;
          *luaH_set(L, arr, top) = *(top+1);
        }
        break;
      }
      case OP_ADD: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_ADD);
        else
          nvalue(top-2) += nvalue(top-1);
        top--;
        break;
      }
      case OP_ADDI: {
        if (tonumber(top-1)) {
          ttype(top) = LUA_TNUMBER;
          nvalue(top) = (Number)GETARG_S(i);
          call_arith(L, top+1, TM_ADD);
        }
        else
          nvalue(top-1) += (Number)GETARG_S(i);
        break;
      }
      case OP_SUB: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_SUB);
        else
          nvalue(top-2) -= nvalue(top-1);
        top--;
        break;
      }
      case OP_MULT: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_MUL);
        else
          nvalue(top-2) *= nvalue(top-1);
        top--;
        break;
      }
      case OP_DIV: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_DIV);
        else
          nvalue(top-2) /= nvalue(top-1);
        top--;
        break;
      }
      case OP_POW: {
        if (!call_binTM(L, top, TM_POW))
          lua_error(L, "undefined operation");
        top--;
        break;
      }
      case OP_CONCAT: {
        int n = GETARG_U(i);
        luaV_strconc(L, n, top);
        top -= n-1;
        L->top = top;
        luaC_checkGC(L);
        break;
      }
      case OP_MINUS: {
        if (tonumber(top-1)) {
          ttype(top) = LUA_TNIL;
          call_arith(L, top+1, TM_UNM);
        }
        else
          nvalue(top-1) = -nvalue(top-1);
        break;
      }
      case OP_NOT: {
        ttype(top-1) =
           (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL;
        nvalue(top-1) = 1;
        break;
      }
      case OP_JMPNE: {
        top -= 2;
        if (!luaO_equalObj(top, top+1)) dojump(pc, i);
        break;
      }
      case OP_JMPEQ: {
        top -= 2;
        if (luaO_equalObj(top, top+1)) dojump(pc, i);
        break;
      }
      case OP_JMPLT: {
        top -= 2;
        if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPLE: {  /* a <= b  ===  !(b b  ===  (b= b  ===  !(a 0 ?
            nvalue(top-3) > nvalue(top-2) :
            nvalue(top-3) < nvalue(top-2)) {  /* `empty' loop? */
          top -= 3;  /* remove control variables */
          dojump(pc, i);  /* jump to loop end */
        }
        break;
      }
      case OP_FORLOOP: {
        LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
        LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
        if (ttype(top-3) != LUA_TNUMBER)
          lua_error(L, "`for' index must be a number");
        nvalue(top-3) += nvalue(top-1);  /* increment index */
        if (nvalue(top-1) > 0 ?
            nvalue(top-3) > nvalue(top-2) :
            nvalue(top-3) < nvalue(top-2))
          top -= 3;  /* end loop: remove control variables */
        else
          dojump(pc, i);  /* repeat loop */
        break;
      }
      case OP_LFORPREP: {
        Node *node;
        if (ttype(top-1) != LUA_TTABLE)
          lua_error(L, "`for' table must be a table");
        node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
        if (node == NULL) {  /* `empty' loop? */
          top--;  /* remove table */
          dojump(pc, i);  /* jump to loop end */
        }
        else {
          top += 2;  /* index,value */
          *(top-2) = *key(node);
          *(top-1) = *val(node);
        }
        break;
      }
      case OP_LFORLOOP: {
        Node *node;
        LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
        node = luaH_next(L, hvalue(top-3), top-2);
        if (node == NULL)  /* end loop? */
          top -= 3;  /* remove table, key, and value */
        else {
          *(top-2) = *key(node);
          *(top-1) = *val(node);
          dojump(pc, i);  /* repeat loop */
        }
        break;
      }
      case OP_CLOSURE: {
        L->top = top;
        luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
        top = L->top;
        luaC_checkGC(L);
        break;
      }
    }
  }
}
tome-235-src/src/lua/lvm.h0000644000076400017500000000174011012107763013207 0ustar  dgdg/*
** $Id: lvm.h,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/

#ifndef lvm_h
#define lvm_h


#include "ldo.h"
#include "lobject.h"
#include "ltm.h"


#define tonumber(o)   ((ttype(o) != LUA_TNUMBER) && (luaV_tonumber(o) != 0))
#define tostring(L,o) ((ttype(o) != LUA_TSTRING) && (luaV_tostring(L, o) != 0))


int luaV_tonumber (TObject *obj);
int luaV_tostring (lua_State *L, TObject *obj);
const TObject *luaV_gettable (lua_State *L, StkId t);
void luaV_settable (lua_State *L, StkId t, StkId key);
const TObject *luaV_getglobal (lua_State *L, TString *s);
void luaV_setglobal (lua_State *L, TString *s);
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
void luaV_Lclosure (lua_State *L, Proto *l, int nelems);
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top);
void luaV_strconc (lua_State *L, int total, StkId top);

#endif
tome-235-src/src/lua/module.lua0000644000076400017500000000271411012107763014232 0ustar  dgdg-- tolua: module class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: module.lua,v 1.2 2001/11/26 23:00:26 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 



-- Module class
-- Represents module.
-- The following fields are stored:
--    {i} = list of objects in the module.
classModule = {
 _base = classContainer,
 type = 'module'
}
settag(classModule,tolua_tag)

-- register module
function classModule:register ()
 output(' tolua_module(tolua_S,"'..self.name..'");')
 local i=1
 while self[i] do
  self[i]:register()
  i = i+1
 end
end

-- unregister module
function classModule:unregister ()
 output(' lua_pushnil(tolua_S); lua_setglobal(tolua_S,"'..self.name..'");') 
end

-- Print method
function classModule:print (ident,close)
 print(ident.."Module{")
 print(ident.." name = '"..self.name.."';")
 local i=1
 while self[i] do
  self[i]:print(ident.." ",",")
  i = i+1
 end
 print(ident.."}"..close)
end

-- Internal constructor
function _Module (t)
 t._base = classModule
 settag(t,tolua_tag)
 append(t)
 return t
end

-- Constructor
-- Expects two string representing the module name and body.
function Module (n,b)
 local t = _Module(_Container{name=n})
 push(t)
 t:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
 pop()
 return t
end


tome-235-src/src/lua/package.lua0000644000076400017500000001563611012107763014347 0ustar  dgdg-- tolua: package class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: package.lua,v 1.4 2002/01/03 13:45:08 takkaria Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 



-- Package class
-- Represents the whole package being bound.
-- The following fields are stored:
--    {i} = list of objects in the package.
classPackage = {
 _base = classContainer,
 type = 'package'
}
settag(classPackage,tolua_tag)

-- Print method
function classPackage:print ()
 print("Package: "..self.name)
 local i=1
 while self[i] do
  self[i]:print("","")
  i = i+1
 end
end

function classPackage:preprocess ()
 self.code = "\n"..self.code    -- add a blank sentinel line
 -- avoid preprocessing verbatim lines
 local V = {}
 self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)",function (v)
                                               tinsert(%V,v)
                                               return "\n$"..getn(%V).."$" 
                                              end)
 -- avoid preprocessing embedded lua code
 local C = {}
 self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded Lua code
 self.code = gsub(self.code,"\n%s*%$%]","\2")
 self.code = gsub(self.code,"(%b\1\2)",       function (c)
                                               tinsert(%C,c)
                                               return "\n$["..getn(%C).."]$" 
                                              end)
 -- perform global substitution

 self.code = gsub(self.code,"(//[^\n]*)","")     -- eliminate C++ comments
 self.code = gsub(self.code,"/%*","\1")
 self.code = gsub(self.code,"%*/","\2")
 self.code = gsub(self.code,"%b\1\2","")
 self.code = gsub(self.code,"\1","/%*")
 self.code = gsub(self.code,"\2","%*/")
 self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @
 self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword
 self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword
 self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword
 self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword
 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
 self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
 self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ")  -- substitute 'char*'

 -- restore embedded code
 self.code = gsub(self.code,"%$%[(%d+)%]%$",function (n)
                                             return %C[tonumber(n)]
                                            end)
 -- restore verbatim lines
 self.code = gsub(self.code,"%$(%d+)%$",function (n)
                                         return %V[tonumber(n)]
                                        end)
end

-- translate verbatim
function classPackage:preamble ()
 output('/*\n')
 output('** Lua binding: '..self.name..'\n')
 output('** Generated automatically by '..TOLUA_VERSION..'\n')
 output('*/\n\n')

 output('#include "lua/tolua.h"\n\n')

 if not flags.h then
  output('/* Exported function */')
  output('int  tolua_'..self.name..'_open (lua_State* tolua_S);')
  output('void tolua_'..self.name..'_close (lua_State* tolua_S);')
  output('\n')
 end

 local i=1
 while self[i] do
  self[i]:preamble()
  i = i+1
 end
 output('\n')
 output('/* function to register type */')
 output('static void toluaI_reg_types (lua_State* tolua_S)')
 output('{')
 foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end)
 output('}')
 output('\n')

 output('/* error messages */')
 output('#define TOLUA_ERR_SELF tolua_error(tolua_S,\"invalid \'self\'\")')
 output('#define TOLUA_ERR_ASSIGN tolua_error(tolua_S,\"#vinvalid type in variable assignment.\")')
 output('\n')
end

-- register package
-- write package open function
function classPackage:register ()
 output("/* Open function */")
 output("int tolua_"..self.name.."_open (lua_State* tolua_S)")
 output("{")
 output(" tolua_open(tolua_S);")
 output(" toluaI_reg_types(tolua_S);")
 local i=1
 while self[i] do
  self[i]:register()
  i = i+1
 end
 output(" return 1;")
 output("}")
end

-- unregister package
-- write package close function
function classPackage:unregister ()
 output("/* Close function */")
 output("void tolua_"..self.name.."_close (lua_State* tolua_S)")
 output("{")
 local i=1
 while self[i] do
  self[i]:unregister()
  i = i+1
 end
 output("}")
end

-- write header file
function classPackage:header ()
 output('/*\n') output('** Lua binding: '..self.name..'\n')
 output('** Generated automatically by '..TOLUA_VERSION..'.\n')
 output('*/\n\n')

 if not flags.h then
  output('/* Exported function */')
  output('int  tolua_'..self.name..'_open (lua_State* tolua_S);')
  output('void tolua_'..self.name..'_close (lua_State* tolua_S);')
  output('\n')
 end
end

-- Internal constructor
function _Package (t)
 t._base = classPackage
 settag(t,tolua_tag)
 return t
end

-- Constructor
-- Expects the base file name.
-- It assumes the file has extension ".pkg".
function Package (name)
 -- read file
 local code = read("*a")
 code = "\n" .. code         -- add sentinel
 -- deal with include directive
 local nsubst
 repeat
  code,nsubst = gsub(code,"\n%s*%$<(.-)>%s*\n",function (fn)
                                                local fp,msg = openfile(fn,'r')
                                                if not fp then
                                                 error('#'..msg..': '..fn)
                                                end
                                                local s = read(fp,'*a')
                                                closefile(fp)
                                                return "\n" .. s
                                               end)
 until nsubst==0

 -- deal with include directive for C/C++ header files
 local nsubst
 repeat
  code,nsubst = 
   gsub(code,"\n%s*%${(.-)}%s*\n",
        function (fn)
         local fp,msg = openfile(fn,'r')
         if not fp then
          error('#'..msg..': '..fn)
         end
         local s = read(fp,'*a')
         closefile(fp)
         -- extract marked code
         local T = {code="\n"}
         s= "\n" .. s .. "\n" -- add blank lines as sentinels
         -- extract one-line statments
         gsub(s,"\n(.-)[Tt][Oo][Ll][Uu][Aa]_[Ee][Xx][Pp][Oo][Rr][Tt][^\n]*\n",
              function (c) %T.code = %T.code .. c .. "\n" end
             )
         -- extract multiline statments
         gsub(s,"\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Bb][Ee][Gg][Ii][Nn][^\n]*"..
                "(.-)" ..
                "\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",
              function (c) %T.code = %T.code .. c .. "\n" end
             )
         return T.code
        end)
 until nsubst==0

 local t = _Package(_Container{name=name, code=code})
 push(t)
 t:preprocess()
 t:parse(t.code)
 pop()
 return t
end


tome-235-src/src/lua/lcode.c0000644000076400017500000004603211012107763013475 0ustar  dgdg/*
** $Id: lcode.c,v 1.4 2004/06/04 13:42:10 neil Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/


#include "stdlib.h"

#include "lua.h"

#include "lcode.h"
#include "ldo.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"


void luaK_error (LexState *ls, const char *msg) {
  luaX_error(ls, msg, ls->t.token);
}


/*
** Returns the the previous instruction, for optimizations.
** If there is a jump target between this and the current instruction,
** returns a dummy instruction to avoid wrong optimizations.
*/
static Instruction previous_instruction (FuncState *fs) {
  if (fs->pc > fs->lasttarget)  /* no jumps to current position? */
    return fs->f->code[fs->pc-1];  /* returns previous instruction */
  else
    return CREATE_0(OP_END);  /* no optimizations after an `END' */
}


int luaK_jump (FuncState *fs) {
  int j = luaK_code1(fs, OP_JMP, NO_JUMP);
  if (j == fs->lasttarget) {  /* possible jumps to this jump? */
    luaK_concat(fs, &j, fs->jlt);  /* keep them on hold */
    fs->jlt = NO_JUMP;
  }
  return j;
}


static void luaK_fixjump (FuncState *fs, int pc, int dest) {
  Instruction *jmp = &fs->f->code[pc];
  if (dest == NO_JUMP)
    SETARG_S(*jmp, NO_JUMP);  /* point to itself to represent end of list */
  else {  /* jump is relative to position following jump instruction */
    int offset = dest-(pc+1);
    if (abs(offset) > MAXARG_S)
      luaK_error(fs->ls, "control structure too long");
    SETARG_S(*jmp, offset);
  }
}


static int luaK_getjump (FuncState *fs, int pc) {
  int offset = GETARG_S(fs->f->code[pc]);
  if (offset == NO_JUMP)  /* point to itself represents end of list */
    return NO_JUMP;  /* end of list */
  else
    return (pc+1)+offset;  /* turn offset into absolute position */
}


/*
** returns current `pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block).
** discharge list of jumps to last target.
*/
int luaK_getlabel (FuncState *fs) {
  if (fs->pc != fs->lasttarget) {
    int lasttarget = fs->lasttarget;
    fs->lasttarget = fs->pc;
    luaK_patchlist(fs, fs->jlt, lasttarget);  /* discharge old list `jlt' */
    fs->jlt = NO_JUMP;  /* nobody jumps to this new label (yet) */
  }
  return fs->pc;
}


void luaK_deltastack (FuncState *fs, int delta) {
  fs->stacklevel += delta;
  if (fs->stacklevel > fs->f->maxstacksize) {
    if (fs->stacklevel > MAXSTACK)
      luaK_error(fs->ls, "function or expression too complex");
    fs->f->maxstacksize = fs->stacklevel;
  }
}


void luaK_kstr (LexState *ls, int c) {
  luaK_code1(ls->fs, OP_PUSHSTRING, c);
}


static int number_constant (FuncState *fs, Number r) {
  /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
  Proto *f = fs->f;
  int c = f->nknum;
  int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
  while (--c >= lim)
    if (f->knum[c] == r) return c;
  /* not found; create a new entry */
  luaM_growvector(fs->L, f->knum, f->nknum, 1, Number,
                  "constant table overflow", MAXARG_U);
  c = f->nknum++;
  f->knum[c] = r;
  return c;
}


void luaK_number (FuncState *fs, Number f) {
  if (f <= (Number)MAXARG_S && (Number)(int)f == f)
    luaK_code1(fs, OP_PUSHINT, (int)f);  /* f has a short integer value */
  else
    luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f));
}


void luaK_adjuststack (FuncState *fs, int n) {
  if (n > 0)
    luaK_code1(fs, OP_POP, n);
  else
    luaK_code1(fs, OP_PUSHNIL, -n);
}


int luaK_lastisopen (FuncState *fs) {
  /* check whether last instruction is an open function call */
  Instruction i = previous_instruction(fs);
  if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET)
    return 1;
  else return 0;
}


void luaK_setcallreturns (FuncState *fs, int nresults) {
  if (luaK_lastisopen(fs)) {  /* expression is an open function call? */
    SETARG_B(fs->f->code[fs->pc-1], nresults);  /* set number of results */
    luaK_deltastack(fs, nresults);  /* push results */
  }
}


static int discharge (FuncState *fs, expdesc *var) {
  switch (var->k) {
    case VLOCAL:
      luaK_code1(fs, OP_GETLOCAL, var->u.index);
      break;
    case VGLOBAL:
      luaK_code1(fs, OP_GETGLOBAL, var->u.index);
      break;
    case VINDEXED:
      luaK_code0(fs, OP_GETTABLE);
      break;
    case VEXP:
      return 0;  /* nothing to do */
  }
  var->k = VEXP;
  var->u.l.t = var->u.l.f = NO_JUMP;
  return 1;
}


static void discharge1 (FuncState *fs, expdesc *var) {
  discharge(fs, var);
 /* if it has jumps then it is already discharged */
  if (var->u.l.t == NO_JUMP && var->u.l.f  == NO_JUMP)
    luaK_setcallreturns(fs, 1);  /* call must return 1 value */
}


void luaK_storevar (LexState *ls, const expdesc *var) {
  FuncState *fs = ls->fs;
  switch (var->k) {
    case VLOCAL:
      luaK_code1(fs, OP_SETLOCAL, var->u.index);
      break;
    case VGLOBAL:
      luaK_code1(fs, OP_SETGLOBAL, var->u.index);
      break;
    case VINDEXED:  /* table is at top-3; pop 3 elements after operation */
      luaK_code2(fs, OP_SETTABLE, 3, 3);
      break;
    default:
      LUA_INTERNALERROR("invalid var kind to store");
  }
}


static OpCode invertjump (OpCode op) {
  switch (op) {
    case OP_JMPNE: return OP_JMPEQ;
    case OP_JMPEQ: return OP_JMPNE;
    case OP_JMPLT: return OP_JMPGE;
    case OP_JMPLE: return OP_JMPGT;
    case OP_JMPGT: return OP_JMPLE;
    case OP_JMPGE: return OP_JMPLT;
    case OP_JMPT: case OP_JMPONT:  return OP_JMPF;
    case OP_JMPF: case OP_JMPONF:  return OP_JMPT;
    default:
      LUA_INTERNALERROR("invalid jump instruction");
      return OP_END;  /* to avoid warnings */
  }
}


static void luaK_patchlistaux (FuncState *fs, int list, int target,
                               OpCode special, int special_target) {
  Instruction *code = fs->f->code;
  while (list != NO_JUMP) {
    int next = luaK_getjump(fs, list);
    Instruction *i = &code[list];
    OpCode op = GET_OPCODE(*i);
    if (op == special)  /* this `op' already has a value */
      luaK_fixjump(fs, list, special_target);
    else {
      luaK_fixjump(fs, list, target);  /* do the patch */
      if (op == OP_JMPONT)  /* remove eventual values */
        SET_OPCODE(*i, OP_JMPT);
      else if (op == OP_JMPONF)
        SET_OPCODE(*i, OP_JMPF);
    }
    list = next;
  }
}


void luaK_patchlist (FuncState *fs, int list, int target) {
  if (target == fs->lasttarget)  /* same target that list `jlt'? */
    luaK_concat(fs, &fs->jlt, list);  /* delay fixing */
  else
    luaK_patchlistaux(fs, list, target, OP_END, 0);
}


static int need_value (FuncState *fs, int list, OpCode hasvalue) {
  /* check whether list has a jump without a value */
  for (; list != NO_JUMP; list = luaK_getjump(fs, list))
    if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1;
  return 0;  /* not found */
}


void luaK_concat (FuncState *fs, int *l1, int l2) {
  if (*l1 == NO_JUMP)
    *l1 = l2;
  else {
    int list = *l1;
    for (;;) {  /* traverse `l1' */
      int next = luaK_getjump(fs, list);
      if (next == NO_JUMP) {  /* end of list? */
        luaK_fixjump(fs, list, l2);
        return;
      }
      list = next;
    }
  }
}


static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
  int prevpos;  /* position of last instruction */
  Instruction *previous;
  int *golist, *exitlist;
  if (!invert) {
    golist = &v->u.l.f;    /* go if false */
    exitlist = &v->u.l.t;  /* exit if true */
  }
  else {
    golist = &v->u.l.t;    /* go if true */
    exitlist = &v->u.l.f;  /* exit if false */
  }
  discharge1(fs, v);
  prevpos = fs->pc-1;
  previous = &fs->f->code[prevpos];
  LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here");
  if (!ISJUMP(GET_OPCODE(*previous)))
    prevpos = luaK_code1(fs, jump, NO_JUMP);
  else {  /* last instruction is already a jump */
    if (invert)
      SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
  }
  luaK_concat(fs, exitlist, prevpos);  /* insert last jump in `exitlist' */
  luaK_patchlist(fs, *golist, luaK_getlabel(fs));
  *golist = NO_JUMP;
}


void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) {
  luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF);
}


static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {
  luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT);
}


static int code_label (FuncState *fs, OpCode op, int arg) {
  luaK_getlabel(fs);  /* those instructions may be jump targets */
  return luaK_code1(fs, op, arg);
}


void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {
  FuncState *fs = ls->fs;
  if (!discharge(fs, v)) {  /* `v' is an expression? */
    OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);
    if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {
      /* expression has no jumps */
      if (onlyone)
        luaK_setcallreturns(fs, 1);  /* call must return 1 value */
    }
    else {  /* expression has jumps */
      int final;  /* position after whole expression */
      int j = NO_JUMP;  /*  eventual  jump over values */
      int p_nil = NO_JUMP;  /* position of an eventual PUSHNIL */
      int p_1 = NO_JUMP;  /* position of an eventual PUSHINT */
      if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF)
                           || need_value(fs, v->u.l.t, OP_JMPONT)) {
        /* expression needs values */
        if (ISJUMP(previous))
          luaK_concat(fs, &v->u.l.t, fs->pc-1);  /* put `previous' in t. list */
        else {
          j = code_label(fs, OP_JMP, NO_JUMP);  /* to jump over both pushes */
          /* correct stack for compiler and symbolic execution */
          luaK_adjuststack(fs, 1);
        }
        p_nil = code_label(fs, OP_PUSHNILJMP, 0);
        p_1 = code_label(fs, OP_PUSHINT, 1);
        luaK_patchlist(fs, j, luaK_getlabel(fs));
      }
      final = luaK_getlabel(fs);
      luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final);
      luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final);
      v->u.l.f = v->u.l.t = NO_JUMP;
    }
  }
}


void luaK_prefix (LexState *ls, UnOpr op, expdesc *v) {
  FuncState *fs = ls->fs;
  if (op == OPR_MINUS) {
    luaK_tostack(ls, v, 1);
    luaK_code0(fs, OP_MINUS);
  }
  else {  /* op == NOT */
    Instruction *previous;
    discharge1(fs, v);
    previous = &fs->f->code[fs->pc-1];
    if (ISJUMP(GET_OPCODE(*previous)))
      SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));
    else
      luaK_code0(fs, OP_NOT);
    /* interchange true and false lists */
    { int temp = v->u.l.f; v->u.l.f = v->u.l.t; v->u.l.t = temp; }
  }
}


void luaK_infix (LexState *ls, BinOpr op, expdesc *v) {
  FuncState *fs = ls->fs;
  switch (op) {
    case OPR_AND:
      luaK_goiftrue(fs, v, 1);
      break;
    case OPR_OR:
      luaK_goiffalse(fs, v, 1);
      break;
    default:
      luaK_tostack(ls, v, 1);  /* all other binary operators need a value */
  }
}



static const struct {
  OpCode opcode;  /* opcode for each binary operator */
  int arg;        /* default argument for the opcode */
} codes[] = {  /* ORDER OPR */
      {OP_ADD, 0}, {OP_SUB, 0}, {OP_MULT, 0}, {OP_DIV, 0},
      {OP_POW, 0}, {OP_CONCAT, 2},
      {OP_JMPNE, NO_JUMP}, {OP_JMPEQ, NO_JUMP},
      {OP_JMPLT, NO_JUMP}, {OP_JMPLE, NO_JUMP},
      {OP_JMPGT, NO_JUMP}, {OP_JMPGE, NO_JUMP}
};


void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) {
  FuncState *fs = ls->fs;
  switch (op) {
    case OPR_AND: {
      LUA_ASSERT(v1->u.l.t == NO_JUMP, "list must be closed");
      discharge1(fs, v2);
      v1->u.l.t = v2->u.l.t;
      luaK_concat(fs, &v1->u.l.f, v2->u.l.f);
      break;
    }
    case OPR_OR: {
      LUA_ASSERT(v1->u.l.f == NO_JUMP, "list must be closed");
      discharge1(fs, v2);
      v1->u.l.f = v2->u.l.f;
      luaK_concat(fs, &v1->u.l.t, v2->u.l.t);
      break;
    }
    default: {
      luaK_tostack(ls, v2, 1);  /* `v2' must be a value */
      luaK_code1(fs, codes[op].opcode, codes[op].arg);
    }
  }
}


static void codelineinfo (FuncState *fs) {
  Proto *f = fs->f;
  LexState *ls = fs->ls;
  if (ls->lastline > fs->lastline) {
    luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int,
                    "line info overflow", MAX_INT);
    if (ls->lastline > fs->lastline+1)
      f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1));
    f->lineinfo[f->nlineinfo++] = fs->pc;
    fs->lastline = ls->lastline;
  }
}


int luaK_code0 (FuncState *fs, OpCode o) {
  return luaK_code2(fs, o, 0, 0);
}


int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
  return luaK_code2(fs, o, arg1, 0);
}


int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
  Instruction i = previous_instruction(fs);
  int delta = luaK_opproperties[o].push - luaK_opproperties[o].pop;
  int optm = 0;  /* 1 when there is an optimization */
  switch (o) {
    case OP_CLOSURE: {
      delta = -arg2+1;
      break;
    }
    case OP_SETTABLE: {
      delta = -arg2;
      break;
    }
    case OP_SETLIST: {
      if (arg2 == 0) return NO_JUMP;  /* nothing to do */
      delta = -arg2;
      break;
    }
    case OP_SETMAP: {
      if (arg1 == 0) return NO_JUMP;  /* nothing to do */
      delta = -2*arg1;
      break;
    }
    case OP_RETURN: {
      if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) {
        SET_OPCODE(i, OP_TAILCALL);
        SETARG_B(i, arg1);
        optm = 1;
      }
      break;
    }
    case OP_PUSHNIL: {
      if (arg1 == 0) return NO_JUMP;  /* nothing to do */
      delta = arg1;
      switch(GET_OPCODE(i)) {
        case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break;
        default: break;
      }
      break;
    }
    case OP_POP: {
      if (arg1 == 0) return NO_JUMP;  /* nothing to do */
      delta = -arg1;
      switch(GET_OPCODE(i)) {
        case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break;
        default: break;
      }
      break;
    }
    case OP_GETTABLE: {
      switch(GET_OPCODE(i)) {
        case OP_PUSHSTRING:  /* `t.x' */
          SET_OPCODE(i, OP_GETDOTTED);
          optm = 1;
          break;
        case OP_GETLOCAL:  /* `t[i]' */
          SET_OPCODE(i, OP_GETINDEXED);
          optm = 1;
          break;
        default: break;
      }
      break;
    }
    case OP_ADD: {
      switch(GET_OPCODE(i)) {
        case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break;  /* `a+k' */
        default: break;
      }
      break;
    }
    case OP_SUB: {
      switch(GET_OPCODE(i)) {
        case OP_PUSHINT:  /* `a-k' */
          i = CREATE_S(OP_ADDI, -GETARG_S(i));
          optm = 1;
          break;
        default: break;
      }
      break;
    }
    case OP_CONCAT: {
      delta = -arg1+1;
      switch(GET_OPCODE(i)) {
        case OP_CONCAT:  /* `a..b..c' */
          SETARG_U(i, GETARG_U(i)+1);
          optm = 1;
          break;
        default: break;
      }
      break;
    }
    case OP_MINUS: {
      switch(GET_OPCODE(i)) {
        case OP_PUSHINT:  /* `-k' */
          SETARG_S(i, -GETARG_S(i));
          optm = 1;
          break;
        case OP_PUSHNUM:  /* `-k' */
          SET_OPCODE(i, OP_PUSHNEGNUM);
          optm = 1;
          break;
        default: break;
      }
      break;
    }
    case OP_JMPNE: {
      if (i == CREATE_U(OP_PUSHNIL, 1)) {  /* `a~=nil' */
        i = CREATE_S(OP_JMPT, NO_JUMP);
        optm = 1;
      }
      break;
    }
    case OP_JMPEQ: {
      if (i == CREATE_U(OP_PUSHNIL, 1)) {  /* `a==nil' */
        i = CREATE_0(OP_NOT);
        delta = -1;  /* just undo effect of previous PUSHNIL */
        optm = 1;
      }
      break;
    }
    case OP_JMPT:
    case OP_JMPONT: {
      switch (GET_OPCODE(i)) {
        case OP_NOT: {
          i = CREATE_S(OP_JMPF, NO_JUMP);
          optm = 1;
          break;
        }
        case OP_PUSHINT: {
          if (o == OP_JMPT) {  /* JMPONT must keep original integer value */
            i = CREATE_S(OP_JMP, NO_JUMP);
            optm = 1;
          }
          break;
        }
        case OP_PUSHNIL: {
          if (GETARG_U(i) == 1) {
            fs->pc--;  /* erase previous instruction */
            luaK_deltastack(fs, -1);  /* correct stack */
            return NO_JUMP; 
          }
          break;
        }
        default: break;
      }
      break;
    }
    case OP_JMPF:
    case OP_JMPONF: {
      switch (GET_OPCODE(i)) {
        case OP_NOT: {
          i = CREATE_S(OP_JMPT, NO_JUMP);
          optm = 1;
          break;
        }
        case OP_PUSHINT: {  /* `while 1 do ...' */
          fs->pc--;  /* erase previous instruction */
          luaK_deltastack(fs, -1);  /* correct stack */
          return NO_JUMP; 
        }
        case OP_PUSHNIL: {  /* `repeat ... until nil' */
          if (GETARG_U(i) == 1) {
            i = CREATE_S(OP_JMP, NO_JUMP);
            optm = 1;
          }
          break;
        }
        default: break;
      }
      break;
    }
    case OP_GETDOTTED:
    case OP_GETINDEXED:
    case OP_TAILCALL:
    case OP_ADDI: {
      LUA_INTERNALERROR("instruction used only for optimizations");
      break;
    }
    default: {
      LUA_ASSERT(delta != VD, "invalid delta");
      break;
    }
  }
  luaK_deltastack(fs, delta);
  if (optm) {  /* optimize: put instruction in place of last one */
      fs->f->code[fs->pc-1] = i;  /* change previous instruction */
      return fs->pc-1;  /* do not generate new instruction */
  }
  /* else build new instruction */
  switch ((enum Mode)luaK_opproperties[o].mode) {
    case iO: i = CREATE_0(o); break;
    case iU: i = CREATE_U(o, arg1); break;
    case iS: i = CREATE_S(o, arg1); break;
    case iAB: i = CREATE_AB(o, arg1, arg2); break;
  }
  codelineinfo(fs);
  /* put new instruction in code array */
  luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction,
                  "code size overflow", MAX_INT);
  fs->f->code[fs->pc] = i;
  return fs->pc++;
}


const struct OpProperties luaK_opproperties[NUM_OPCODES] = {
  {iO, 0, 0},	/* OP_END */
  {iU, 0, 0},	/* OP_RETURN */
  {iAB, 0, 0},	/* OP_CALL */
  {iAB, 0, 0},	/* OP_TAILCALL */
  {iU, VD, 0},	/* OP_PUSHNIL */
  {iU, VD, 0},	/* OP_POP */
  {iS, 1, 0},	/* OP_PUSHINT */
  {iU, 1, 0},	/* OP_PUSHSTRING */
  {iU, 1, 0},	/* OP_PUSHNUM */
  {iU, 1, 0},	/* OP_PUSHNEGNUM */
  {iU, 1, 0},	/* OP_PUSHUPVALUE */
  {iU, 1, 0},	/* OP_GETLOCAL */
  {iU, 1, 0},	/* OP_GETGLOBAL */
  {iO, 1, 2},	/* OP_GETTABLE */
  {iU, 1, 1},	/* OP_GETDOTTED */
  {iU, 1, 1},	/* OP_GETINDEXED */
  {iU, 2, 1},	/* OP_PUSHSELF */
  {iU, 1, 0},	/* OP_CREATETABLE */
  {iU, 0, 1},	/* OP_SETLOCAL */
  {iU, 0, 1},	/* OP_SETGLOBAL */
  {iAB, VD, 0},	/* OP_SETTABLE */
  {iAB, VD, 0},	/* OP_SETLIST */
  {iU, VD, 0},	/* OP_SETMAP */
  {iO, 1, 2},	/* OP_ADD */
  {iS, 1, 1},	/* OP_ADDI */
  {iO, 1, 2},	/* OP_SUB */
  {iO, 1, 2},	/* OP_MULT */
  {iO, 1, 2},	/* OP_DIV */
  {iO, 1, 2},	/* OP_POW */
  {iU, VD, 0},	/* OP_CONCAT */
  {iO, 1, 1},	/* OP_MINUS */
  {iO, 1, 1},	/* OP_NOT */
  {iS, 0, 2},	/* OP_JMPNE */
  {iS, 0, 2},	/* OP_JMPEQ */
  {iS, 0, 2},	/* OP_JMPLT */
  {iS, 0, 2},	/* OP_JMPLE */
  {iS, 0, 2},	/* OP_JMPGT */
  {iS, 0, 2},	/* OP_JMPGE */
  {iS, 0, 1},	/* OP_JMPT */
  {iS, 0, 1},	/* OP_JMPF */
  {iS, 0, 1},	/* OP_JMPONT */
  {iS, 0, 1},	/* OP_JMPONF */
  {iS, 0, 0},	/* OP_JMP */
  {iO, 0, 0},	/* OP_PUSHNILJMP */
  {iS, 0, 0},	/* OP_FORPREP */
  {iS, 0, 3},	/* OP_FORLOOP */
  {iS, 2, 0},	/* OP_LFORPREP */
  {iS, 0, 3},	/* OP_LFORLOOP */
  {iAB, VD, 0}	/* OP_CLOSURE */
};

tome-235-src/src/lua/lcode.h0000644000076400017500000000364011012107763013500 0ustar  dgdg/*
** $Id: lcode.h,v 1.2 2001/11/26 23:00:23 darkgod Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/

#ifndef lcode_h
#define lcode_h

#include "llex.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"


/*
** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself).
*/
#define NO_JUMP (-1)


/*
** grep "ORDER OPR" if you change these enums
*/
typedef enum BinOpr {
  OPR_ADD, OPR_SUB, OPR_MULT, OPR_DIV, OPR_POW,
  OPR_CONCAT,
  OPR_NE, OPR_EQ, OPR_LT, OPR_LE, OPR_GT, OPR_GE,
  OPR_AND, OPR_OR,
  OPR_NOBINOPR
} BinOpr;

typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;


enum Mode {iO, iU, iS, iAB};  /* instruction format */

#define VD	100	/* flag for variable delta */

extern const struct OpProperties {
  char mode;
  unsigned char push;
  unsigned char pop;
} luaK_opproperties[NUM_OPCODES];


void luaK_error (LexState *ls, const char *msg);
int luaK_code0 (FuncState *fs, OpCode o);
int luaK_code1 (FuncState *fs, OpCode o, int arg1);
int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2);
int luaK_jump (FuncState *fs);
void luaK_patchlist (FuncState *fs, int list, int target);
void luaK_concat (FuncState *fs, int *l1, int l2);
void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue);
int luaK_getlabel (FuncState *fs);
void luaK_deltastack (FuncState *fs, int delta);
void luaK_kstr (LexState *ls, int c);
void luaK_number (FuncState *fs, Number f);
void luaK_adjuststack (FuncState *fs, int n);
int luaK_lastisopen (FuncState *fs);
void luaK_setcallreturns (FuncState *fs, int nresults);
void luaK_tostack (LexState *ls, expdesc *v, int onlyone);
void luaK_storevar (LexState *ls, const expdesc *var);
void luaK_prefix (LexState *ls, UnOpr op, expdesc *v);
void luaK_infix (LexState *ls, BinOpr op, expdesc *v);
void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2);


#endif
tome-235-src/src/lua/lfunc.c0000644000076400017500000000457011012107763013517 0ustar  dgdg/*
** $Id: lfunc.c,v 1.3 2001/11/26 23:00:23 darkgod Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/


#include 

#include "lua.h"

#include "lfunc.h"
#include "lmem.h"
#include "lstate.h"


#define sizeclosure(n)	((int)sizeof(Closure) + (int)sizeof(TObject)*((n)-1))


Closure *luaF_newclosure (lua_State *L, int nelems) {
  int size = sizeclosure(nelems);
  Closure *c = (Closure *)luaM_malloc(L, size);
  c->next = L->rootcl;
  L->rootcl = c;
  c->mark = c;
  c->nupvalues = nelems;
  L->nblocks += size;
  return c;
}


Proto *luaF_newproto (lua_State *L) {
  Proto *f = luaM_new(L, Proto);
  f->knum = NULL;
  f->nknum = 0;
  f->kstr = NULL;
  f->nkstr = 0;
  f->kproto = NULL;
  f->nkproto = 0;
  f->code = NULL;
  f->ncode = 0;
  f->numparams = 0;
  f->is_vararg = 0;
  f->maxstacksize = 0;
  f->marked = 0;
  f->lineinfo = NULL;
  f->nlineinfo = 0;
  f->nlocvars = 0;
  f->locvars = NULL;
  f->lineDefined = 0;
  f->source = NULL;
  f->next = L->rootproto;  /* chain in list of protos */
  L->rootproto = f;
  return f;
}


static size_t protosize (Proto *f) {
  return sizeof(Proto)
       + f->nknum*sizeof(Number)
       + f->nkstr*sizeof(TString *)
       + f->nkproto*sizeof(Proto *)
       + f->ncode*sizeof(Instruction)
       + f->nlocvars*sizeof(struct LocVar)
       + f->nlineinfo*sizeof(int);
}


void luaF_protook (lua_State *L, Proto *f, int pc) {
  f->ncode = pc;  /* signal that proto was properly created */
  L->nblocks += protosize(f);
}


void luaF_freeproto (lua_State *L, Proto *f) {
  if (f->ncode > 0)  /* function was properly created? */
    L->nblocks -= protosize(f);
  luaM_free(L, f->code);
  luaM_free(L, f->locvars);
  luaM_free(L, f->kstr);
  luaM_free(L, f->knum);
  luaM_free(L, f->kproto);
  luaM_free(L, f->lineinfo);
  luaM_free(L, f);
}


void luaF_freeclosure (lua_State *L, Closure *c) {
  L->nblocks -= sizeclosure(c->nupvalues);
  luaM_free(L, c);
}


/*
** Look for n-th local variable at line `line' in function `func'.
** Returns NULL if not found.
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
  int i;
  for (i = 0; inlocvars && f->locvars[i].startpc <= pc; i++) {
    if (pc < f->locvars[i].endpc) {  /* is variable active? */
      local_number--;
      if (local_number == 0)
        return f->locvars[i].varname->str;
    }
  }
  return NULL;  /* not found */
}

tome-235-src/src/lua/lfunc.h0000644000076400017500000000103411012107763013514 0ustar  dgdg/*
** $Id: lfunc.h,v 1.3 2001/11/26 23:00:23 darkgod Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/

#ifndef lfunc_h
#define lfunc_h


#include "lobject.h"



Proto *luaF_newproto (lua_State *L);
void luaF_protook (lua_State *L, Proto *f, int pc);
Closure *luaF_newclosure (lua_State *L, int nelems);
void luaF_freeproto (lua_State *L, Proto *f);
void luaF_freeclosure (lua_State *L, Closure *c);

const char *luaF_getlocalname (const Proto *func, int local_number, int pc);


#endif
tome-235-src/src/lua/lauxlib.c0000644000076400017500000001173011012107763014044 0ustar  dgdg/*
** $Id: lauxlib.c,v 1.3 2001/11/26 23:00:23 darkgod Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 

/* This file uses only the official API of Lua.
** Any function declared here could be written as an application function.
** With care, these functions can be used by other libraries.
*/

#include "lua.h"

#include "lauxlib.h"
#include "luadebug.h"



LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
  int i;
  for (i=0; list[i]; i++)
    if (strcmp(list[i], name) == 0)
      return i;
  return -1;  /* name not found */
}

LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
  lua_Debug ar;
  lua_getstack(L, 0, &ar);
  lua_getinfo(L, "n", &ar);
  if (ar.name == NULL)
    ar.name = "?";
  luaL_verror(L, "bad argument #%d to `%.50s' (%.100s)",
              narg, ar.name, extramsg);
}


static void type_error (lua_State *L, int narg, int t) {
  char buff[50];
  sprintf(buff, "%.8s expected, got %.8s", lua_typename(L, t),
                                           lua_typename(L, lua_type(L, narg)));
  luaL_argerror(L, narg, buff);
}


LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
  if (space > lua_stackspace(L))
    luaL_verror(L, "stack overflow (%.30s)", mes);
}


LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) {
  if (lua_type(L, narg) != t)
    type_error(L, narg, t);
}


LUALIB_API void luaL_checkany (lua_State *L, int narg) {
  if (lua_type(L, narg) == LUA_TNONE)
    luaL_argerror(L, narg, "value expected");
}


LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
  const char *s = lua_tostring(L, narg);
  if (!s) type_error(L, narg, LUA_TSTRING);
  if (len) *len = lua_strlen(L, narg);
  return s;
}


LUALIB_API const char *luaL_opt_lstr (lua_State *L, int narg, const char *def, size_t *len) {
  if (lua_isnull(L, narg)) {
    if (len)
      *len = (def ? strlen(def) : 0);
    return def;
  }
  else return luaL_check_lstr(L, narg, len);
}


LUALIB_API long luaL_check_number (lua_State *L, int narg) {
  long d = lua_tonumber(L, narg);
  if (d == 0 && !lua_isnumber(L, narg))  /* avoid extra test when d is not 0 */
    type_error(L, narg, LUA_TNUMBER);
  return d;
}


LUALIB_API long luaL_opt_number (lua_State *L, int narg, long def) {
  if (lua_isnull(L, narg)) return def;
  else return luaL_check_number(L, narg);
}


LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) {
  int i;
  for (i=0; ip == (B)->buffer)
#define bufflen(B)	((B)->p - (B)->buffer)
#define bufffree(B)	((size_t)(LUAL_BUFFERSIZE - bufflen(B)))

#define LIMIT	(LUA_MINSTACK/2)


static int emptybuffer (luaL_Buffer *B) {
  size_t l = bufflen(B);
  if (l == 0) return 0;  /* put nothing on stack */
  else {
    lua_pushlstring(B->L, B->buffer, l);
    B->p = B->buffer;
    B->level++;
    return 1;
  }
}


static void adjuststack (luaL_Buffer *B) {
  if (B->level > 1) {
    lua_State *L = B->L;
    int toget = 1;  /* number of levels to concat */
    size_t toplen = lua_strlen(L, -1);
    do {
      size_t l = lua_strlen(L, -(toget+1));
      if (B->level - toget + 1 >= LIMIT || toplen > l) {
        toplen += l;
        toget++;
      }
      else break;
    } while (toget < B->level);
    if (toget >= 2) {
      lua_concat(L, toget);
      B->level = B->level - toget + 1;
    }
  }
}


LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
  if (emptybuffer(B))
    adjuststack(B);
  return B->buffer;
}


LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
  while (l--)
    luaL_putchar(B, *s++);
}


LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
  luaL_addlstring(B, s, strlen(s));
}


LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
  emptybuffer(B);
  if (B->level == 0)
    lua_pushlstring(B->L, NULL, 0);
  else if (B->level > 1)
    lua_concat(B->L, B->level);
  B->level = 1;
}


LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
  lua_State *L = B->L;
  size_t vl = lua_strlen(L, -1);
  if (vl <= bufffree(B)) {  /* fit into buffer? */
    memcpy(B->p, lua_tostring(L, -1), vl);  /* put it there */
    B->p += vl;
    lua_pop(L, 1);  /* remove from stack */
  }
  else {
    if (emptybuffer(B))
      lua_insert(L, -2);  /* put buffer before new value */
    B->level++;  /* add new value into B stack */
    adjuststack(B);
  }
}


LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
  B->L = L;
  B->p = B->buffer;
  B->level = 0;
}

/* }====================================================== */
tome-235-src/src/lua/lauxlib.h0000644000076400017500000000552111012107763014052 0ustar  dgdg/*
** $Id: lauxlib.h,v 1.2 2001/11/26 23:00:23 darkgod Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/


#ifndef lauxlib_h
#define lauxlib_h


#include 
#include 

#include "lua.h"


#ifndef LUALIB_API
#define LUALIB_API	extern
#endif


struct luaL_reg {
  const char *name;
  lua_CFunction func;
};


LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n);
LUALIB_API void luaL_argerror (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *luaL_check_lstr (lua_State *L, int numArg, size_t *len);
LUALIB_API const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def, size_t *len);
LUALIB_API long luaL_check_number (lua_State *L, int numArg);
LUALIB_API long luaL_opt_number (lua_State *L, int numArg, long def);

LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg);
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
LUALIB_API void luaL_checkany (lua_State *L, int narg);

LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...);
LUALIB_API int luaL_findstring (const char *name, const char *const list[]);



/*
** ===============================================================
** some useful macros
** ===============================================================
*/

#define luaL_arg_check(L, cond,numarg,extramsg) if (!(cond)) \
                                               luaL_argerror(L, numarg,extramsg)
#define luaL_check_string(L,n)	(luaL_check_lstr(L, (n), NULL))
#define luaL_opt_string(L,n,d)	(luaL_opt_lstr(L, (n), (d), NULL))
#define luaL_check_int(L,n)	((int)luaL_check_number(L, n))
#define luaL_check_long(L,n)	((long)luaL_check_number(L, n))
#define luaL_opt_int(L,n,d)	((int)luaL_opt_number(L, n,d))
#define luaL_opt_long(L,n,d)	((long)luaL_opt_number(L, n,d))
#define luaL_openl(L,a)		luaL_openlib(L, a, (sizeof(a)/sizeof(a[0])))


/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/


#ifndef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE	  BUFSIZ
#endif


typedef struct luaL_Buffer {
  char *p;			/* current position in buffer */
  int level;
  lua_State *L;
  char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;

#define luaL_putchar(B,c) \
  ((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \
   (*(B)->p++ = (char)(c)))

#define luaL_addsize(B,n)	((B)->p += (n))

LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B);
LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B);
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s);
LUALIB_API void luaL_addvalue (luaL_Buffer *B);
LUALIB_API void luaL_pushresult (luaL_Buffer *B);


/* }====================================================== */


#endif


tome-235-src/src/lua/verbatim.lua0000644000076400017500000000262611012107763014560 0ustar  dgdg-- tolua: verbatim class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: verbatim.lua,v 1.2 2001/11/26 23:00:27 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 



-- Verbatim class
-- Represents a line translated directed to the binding file.
-- The following filds are stored:
--   line = line text
classVerbatim = {
 line = '',
 _base = classFeature,
}
settag(classVerbatim,tolua_tag)

-- preamble verbatim
function classVerbatim:preamble ()
 if not self.cond then
  write(self.line)
 end
end

-- support code
function classVerbatim:supcode ()
 if self.cond then
  write(self.line)
  write('\n')
 end
end

-- register code
function classVerbatim:register ()
 if self.cond then
  write(self.line)
 end
end
 

-- Print method
function classVerbatim:print (ident,close)
 print(ident.."Verbatim{")
 print(ident.." line = '"..self.line.."',")
 print(ident.."}"..close)
end


-- Internal constructor
function _Verbatim (t)
 t._base = classVerbatim
 settag(t,tolua_tag)
 append(t)
 return t
end

-- Constructor
-- Expects a string representing the text line
function Verbatim (l)
 local c
 if strsub(l,1,1) == '$' then
  c = 1
  l = strsub(l,2)
 end
 return _Verbatim {
  line = l,
  cond = c
 }
end


tome-235-src/src/lua/lparser.c0000644000076400017500000007216011012107763014060 0ustar  dgdg/*
** $Id: lparser.c,v 1.8 2004/06/04 13:42:10 neil Exp $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/


#include 
#include 

#include "lua.h"

#include "lcode.h"
#include "lfunc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"

#ifdef __MWERKS__
/* To avoid name conflict resulting from the use of prefix header */
#define stat lua_hack_stat
#endif /* __MWERKS__ */


/*
** Constructors descriptor:
** `n' indicates number of elements, and `k' signals whether
** it is a list constructor (k = 0) or a record constructor (k = 1)
** or empty (k = ';' or '}')
*/
typedef struct Constdesc {
  int n;
  int k;
} Constdesc;


typedef struct Breaklabel {
  struct Breaklabel *previous;  /* chain */
  int breaklist;
  int stacklevel;
} Breaklabel;




/*
** prototypes for recursive non-terminal functions
*/
static void body (LexState *ls, int needself, int line);
static void chunk (LexState *ls);
static void constructor (LexState *ls);
static void expr (LexState *ls, expdesc *v);
static void exp1 (LexState *ls);



static void next (LexState *ls) {
  ls->lastline = ls->linenumber;
  if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
    ls->t = ls->lookahead;  /* use this one */
    ls->lookahead.token = TK_EOS;  /* and discharge it */
  }
  else
    ls->t.token = luaX_lex(ls, &ls->t.seminfo);  /* read next token */
}


static void lookahead (LexState *ls) {
  LUA_ASSERT(ls->lookahead.token == TK_EOS, "two look-aheads");
  ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo);
}


static void error_expected (LexState *ls, int token) {
  char buff[100], t[TOKEN_LEN];
  luaX_token2str(token, t);
  sprintf(buff, "`%.20s' expected", t);
  luaK_error(ls, buff);
}


static void check (LexState *ls, int c) {
  if (ls->t.token != c)
    error_expected(ls, c);
  next(ls);
}


static void check_condition (LexState *ls, int c, const char *msg) {
  if (!c) luaK_error(ls, msg);
}


static int optional (LexState *ls, int c) {
  if (ls->t.token == c) {
    next(ls);
    return 1;
  }
  else return 0;
}


static void check_match (LexState *ls, int what, int who, int where) {
  if (ls->t.token != what) {
    if (where == ls->linenumber)
      error_expected(ls, what);
    else {
      char buff[100];
      char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
      luaX_token2str(what, t_what);
      luaX_token2str(who, t_who);
      sprintf(buff, "`%.20s' expected (to close `%.20s' at line %d)",
              t_what, t_who, where);
      luaK_error(ls, buff);
    }
  }
  next(ls);
}


static int string_constant (FuncState *fs, TString *s) {
  Proto *f = fs->f;
  int c = s->u.s.constindex;
  if (c >= f->nkstr || f->kstr[c] != s) {
    luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *,
                    "constant table overflow", MAXARG_U);
    c = f->nkstr++;
    f->kstr[c] = s;
    s->u.s.constindex = c;  /* hint for next time */
  }
  return c;
}


static void code_string (LexState *ls, TString *s) {
  luaK_kstr(ls, string_constant(ls->fs, s));
}


static TString *str_checkname (LexState *ls) {
  TString *ts;
  check_condition(ls, (ls->t.token == TK_NAME), " expected");
  ts = ls->t.seminfo.ts;
  next(ls);
  return ts;
}


static int checkname (LexState *ls) {
  return string_constant(ls->fs, str_checkname(ls));
}


static int luaI_registerlocalvar (LexState *ls, TString *varname) {
  Proto *f = ls->fs->f;
  luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT);
  f->locvars[f->nlocvars].varname = varname;
  return f->nlocvars++;
}


static void new_localvar (LexState *ls, TString *name, int n) {
  FuncState *fs = ls->fs;
  luaX_checklimit(ls, fs->nactloc+n+1, MAXLOCALS, "local variables");
  fs->actloc[fs->nactloc+n] = luaI_registerlocalvar(ls, name);
}


static void adjustlocalvars (LexState *ls, int nvars) {
  FuncState *fs = ls->fs;
  while (nvars--)
    fs->f->locvars[fs->actloc[fs->nactloc++]].startpc = fs->pc;
}


static void removelocalvars (LexState *ls, int nvars) {
  FuncState *fs = ls->fs;
  while (nvars--)
    fs->f->locvars[fs->actloc[--fs->nactloc]].endpc = fs->pc;
}


static void new_localvarstr (LexState *ls, const char *name, int n) {
  new_localvar(ls, luaS_newfixed(ls->L, name), n);
}


static int search_local (LexState *ls, TString *n, expdesc *var) {
  FuncState *fs;
  int level = 0;
  for (fs=ls->fs; fs; fs=fs->prev) {
    int i;
    for (i=fs->nactloc-1; i >= 0; i--) {
      if (n == fs->f->locvars[fs->actloc[i]].varname) {
        var->k = VLOCAL;
        var->u.index = i;
        return level;
      }
    }
    level++;  /* `var' not found; check outer level */
  }
  var->k = VGLOBAL;  /* not found in any level; must be global */
  return -1;
}


static void singlevar (LexState *ls, TString *n, expdesc *var) {
  int level = search_local(ls, n, var);
  if (level >= 1)  /* neither local (0) nor global (-1)? */
    luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str);
  else if (level == -1)  /* global? */
    var->u.index = string_constant(ls->fs, n);
}


static int indexupvalue (LexState *ls, expdesc *v) {
  FuncState *fs = ls->fs;
  int i;
  for (i=0; inupvalues; i++) {
    if (fs->upvalues[i].k == v->k && fs->upvalues[i].u.index == v->u.index)
      return i;
  }
  /* new one */
  luaX_checklimit(ls, fs->nupvalues+1, MAXUPVALUES, "upvalues");
  fs->upvalues[fs->nupvalues] = *v;
  return fs->nupvalues++;
}


static void pushupvalue (LexState *ls, TString *n) {
  FuncState *fs = ls->fs;
  expdesc v;
  int level = search_local(ls, n, &v);
  if (level == -1) {  /* global? */
    if (fs->prev == NULL)
      luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
    v.u.index = string_constant(fs->prev, n);
  }
  else if (level != 1)
    luaX_syntaxerror(ls,
         "upvalue must be global or local to immediately outer scope", n->str);
  luaK_code1(fs, OP_PUSHUPVALUE, indexupvalue(ls, &v));
}


static void adjust_mult_assign (LexState *ls, int nvars, int nexps) {
  FuncState *fs = ls->fs;
  int diff = nexps - nvars;
  if (nexps > 0 && luaK_lastisopen(fs)) { /* list ends in a function call */
    diff--;  /* do not count function call itself */
    if (diff <= 0) {  /* more variables than values? */
      luaK_setcallreturns(fs, -diff);  /* function call provide extra values */
      diff = 0;  /* no more difference */
    }
    else  /* more values than variables */
      luaK_setcallreturns(fs, 0);  /* call should provide no value */
  }
  /* push or pop eventual difference between list lengths */
  luaK_adjuststack(fs, diff);
}


static void code_params (LexState *ls, int nparams, int dots) {
  FuncState *fs = ls->fs;
  adjustlocalvars(ls, nparams);
  luaX_checklimit(ls, fs->nactloc, MAXPARAMS, "parameters");
  fs->f->numparams = fs->nactloc;  /* `self' could be there already */
  fs->f->is_vararg = dots;
  if (dots) {
    new_localvarstr(ls, "arg", 0);
    adjustlocalvars(ls, 1);
  }
  luaK_deltastack(fs, fs->nactloc);  /* count parameters in the stack */
}


static void enterbreak (FuncState *fs, Breaklabel *bl) {
  bl->stacklevel = fs->stacklevel;
  bl->breaklist = NO_JUMP;
  bl->previous = fs->bl;
  fs->bl = bl;
}


static void leavebreak (FuncState *fs, Breaklabel *bl) {
  fs->bl = bl->previous;
  LUA_ASSERT(bl->stacklevel == fs->stacklevel, "wrong levels");
  luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs));
}


static void pushclosure (LexState *ls, FuncState *func) {
  FuncState *fs = ls->fs;
  Proto *f = fs->f;
  int i;
  for (i=0; inupvalues; i++)
    luaK_tostack(ls, &func->upvalues[i], 1);
  luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *,
                  "constant table overflow", MAXARG_A);
  f->kproto[f->nkproto++] = func->f;
  luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues);
}


static void open_func (LexState *ls, FuncState *fs) {
  Proto *f = luaF_newproto(ls->L);
  fs->prev = ls->fs;  /* linked list of funcstates */
  fs->ls = ls;
  fs->L = ls->L;
  ls->fs = fs;
  fs->stacklevel = 0;
  fs->nactloc = 0;
  fs->nupvalues = 0;
  fs->bl = NULL;
  fs->f = f;
  f->source = ls->source;
  fs->pc = 0;
  fs->lasttarget = 0;
  fs->lastline = 0;
  fs->jlt = NO_JUMP;
  f->code = NULL;
  f->maxstacksize = 0;
  f->numparams = 0;  /* default for main chunk */
  f->is_vararg = 0;  /* default for main chunk */
}


static void close_func (LexState *ls) {
  lua_State *L = ls->L;
  FuncState *fs = ls->fs;
  Proto *f = fs->f;
  luaK_code0(fs, OP_END);
  luaK_getlabel(fs);  /* close eventual list of pending jumps */
  luaM_reallocvector(L, f->code, fs->pc, Instruction);
  luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
  luaM_reallocvector(L, f->knum, f->nknum, Number);
  luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
  removelocalvars(ls, fs->nactloc);
  luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar);
  luaM_reallocvector(L, f->lineinfo, f->nlineinfo+1, int);
  f->lineinfo[f->nlineinfo++] = MAX_INT;  /* end flag */
  luaF_protook(L, f, fs->pc);  /* proto is ok now */
  ls->fs = fs->prev;
  LUA_ASSERT(fs->bl == NULL, "wrong list end");
}


Proto *luaY_parser (lua_State *L, ZIO *z) {
  struct LexState lexstate;
  struct FuncState funcstate;
  luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z)));
  open_func(&lexstate, &funcstate);
  next(&lexstate);  /* read first token */
  chunk(&lexstate);
  check_condition(&lexstate, (lexstate.t.token == TK_EOS), " expected");
  close_func(&lexstate);
  LUA_ASSERT(funcstate.prev == NULL, "wrong list end");
  LUA_ASSERT(funcstate.nupvalues == 0, "no upvalues in main");
  return funcstate.f;
}



/*============================================================*/
/* GRAMMAR RULES */
/*============================================================*/


static int explist1 (LexState *ls) {
  /* explist1 -> expr { ',' expr } */
  int n = 1;  /* at least one expression */
  expdesc v;
  expr(ls, &v);
  while (ls->t.token == ',') {
    luaK_tostack(ls, &v, 1);  /* gets only 1 value from previous expression */
    next(ls);  /* skip comma */
    expr(ls, &v);
    n++;
  }
  luaK_tostack(ls, &v, 0);  /* keep open number of values of last expression */
  return n;
}


static void funcargs (LexState *ls, int slf) {
  FuncState *fs = ls->fs;
  int slevel = fs->stacklevel - slf - 1;  /* where is func in the stack */
  switch (ls->t.token) {
    case '(': {  /* funcargs -> '(' [ explist1 ] ')' */
      int line = ls->linenumber;
      int nargs = 0;
      next(ls);
      if (ls->t.token != ')')  /* arg list not empty? */
        nargs = explist1(ls);
      check_match(ls, ')', '(', line);
#ifdef LUA_COMPAT_ARGRET
      if (nargs > 0)  /* arg list is not empty? */
        luaK_setcallreturns(fs, 1);  /* last call returns only 1 value */
#else
      UNUSED(nargs);  /* to avoid warnings */
#endif
      break;
    }
    case '{': {  /* funcargs -> constructor */
      constructor(ls);
      break;
    }
    case TK_STRING: {  /* funcargs -> STRING */
      code_string(ls, ls->t.seminfo.ts);  /* must use `seminfo' before `next' */
      next(ls);
      break;
    }
    default: {
      luaK_error(ls, "function arguments expected");
      break;
    }
  }
  fs->stacklevel = slevel;  /* call will remove function and arguments */
  luaK_code2(fs, OP_CALL, slevel, MULT_RET);
}


static void var_or_func_tail (LexState *ls, expdesc *v) {
  for (;;) {
    switch (ls->t.token) {
      case '.': {  /* var_or_func_tail -> '.' NAME */
        next(ls);
        luaK_tostack(ls, v, 1);  /* `v' must be on stack */
        luaK_kstr(ls, checkname(ls));
        v->k = VINDEXED;
        break;
      }
      case '[': {  /* var_or_func_tail -> '[' exp1 ']' */
        next(ls);
        luaK_tostack(ls, v, 1);  /* `v' must be on stack */
        v->k = VINDEXED;
        exp1(ls);
        check(ls, ']');
        break;
      }
      case ':': {  /* var_or_func_tail -> ':' NAME funcargs */
        int name;
        next(ls);
        name = checkname(ls);
        luaK_tostack(ls, v, 1);  /* `v' must be on stack */
        luaK_code1(ls->fs, OP_PUSHSELF, name);
        funcargs(ls, 1);
        v->k = VEXP;
        v->u.l.t = v->u.l.f = NO_JUMP;
        break;
      }
      case '(': case TK_STRING: case '{': {  /* var_or_func_tail -> funcargs */
        luaK_tostack(ls, v, 1);  /* `v' must be on stack */
        funcargs(ls, 0);
        v->k = VEXP;
        v->u.l.t = v->u.l.f = NO_JUMP;
        break;
      }
      default: return;  /* should be follow... */
    }
  }
}


static void var_or_func (LexState *ls, expdesc *v) {
  /* var_or_func -> ['%'] NAME var_or_func_tail */
  if (optional(ls, '%')) {  /* upvalue? */
    pushupvalue(ls, str_checkname(ls));
    v->k = VEXP;
    v->u.l.t = v->u.l.f = NO_JUMP;
  }
  else  /* variable name */
    singlevar(ls, str_checkname(ls), v);
  var_or_func_tail(ls, v);
}



/*
** {======================================================================
** Rules for Constructors
** =======================================================================
*/


static void recfield (LexState *ls) {
  /* recfield -> (NAME | '['exp1']') = exp1 */
  switch (ls->t.token) {
    case TK_NAME: {
      luaK_kstr(ls, checkname(ls));
      break;
    }
    case '[': {
      next(ls);
      exp1(ls);
      check(ls, ']');
      break;
    }
    default: luaK_error(ls, " or `[' expected");
  }
  check(ls, '=');
  exp1(ls);
}


static int recfields (LexState *ls) {
  /* recfields -> recfield { ',' recfield } [','] */
  FuncState *fs = ls->fs;
  int n = 1;  /* at least one element */
  recfield(ls);
  while (ls->t.token == ',') {
    next(ls);
    if (ls->t.token == ';' || ls->t.token == '}')
      break;
    recfield(ls);
    n++;
    if (n%RFIELDS_PER_FLUSH == 0)
      luaK_code1(fs, OP_SETMAP, RFIELDS_PER_FLUSH);
  }
  luaK_code1(fs, OP_SETMAP, n%RFIELDS_PER_FLUSH);
  return n;
}


static int listfields (LexState *ls) {
  /* listfields -> exp1 { ',' exp1 } [','] */
  FuncState *fs = ls->fs;
  int n = 1;  /* at least one element */
  exp1(ls);
  while (ls->t.token == ',') {
    next(ls);
    if (ls->t.token == ';' || ls->t.token == '}')
      break;
    exp1(ls);
    n++;
    luaX_checklimit(ls, n/LFIELDS_PER_FLUSH, MAXARG_A,
               "`item groups' in a list initializer");
    if (n%LFIELDS_PER_FLUSH == 0)
      luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
  }
  luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
  return n;
}



static void constructor_part (LexState *ls, Constdesc *cd) {
  switch (ls->t.token) {
    case ';': case '}': {  /* constructor_part -> empty */
      cd->n = 0;
      cd->k = ls->t.token;
      break;
    }
    case TK_NAME: {  /* may be listfields or recfields */
      lookahead(ls);
      if (ls->lookahead.token != '=')  /* expression? */
        goto case_default;
      /* else go through to recfields */
    }
    case '[': {  /* constructor_part -> recfields */
      cd->n = recfields(ls);
      cd->k = 1;  /* record */
      break;
    }
    default: {  /* constructor_part -> listfields */
    case_default:
      cd->n = listfields(ls);
      cd->k = 0;  /* list */
      break;
    }
  }
}


static void constructor (LexState *ls) {
  /* constructor -> '{' constructor_part [';' constructor_part] '}' */
  FuncState *fs = ls->fs;
  int line = ls->linenumber;
  int pc = luaK_code1(fs, OP_CREATETABLE, 0);
  int nelems;
  Constdesc cd;
  check(ls, '{');
  constructor_part(ls, &cd);
  nelems = cd.n;
  if (optional(ls, ';')) {
    Constdesc other_cd;
    constructor_part(ls, &other_cd);
    check_condition(ls, (cd.k != other_cd.k), "invalid constructor syntax");
    nelems += other_cd.n;
  }
  check_match(ls, '}', '{', line);
  luaX_checklimit(ls, nelems, MAXARG_U, "elements in a table constructor");
  SETARG_U(fs->f->code[pc], nelems);  /* set initial table size */
}

/* }====================================================================== */




/*
** {======================================================================
** Expression parsing
** =======================================================================
*/


static void simpleexp (LexState *ls, expdesc *v) {
  FuncState *fs = ls->fs;
  switch (ls->t.token) {
    case TK_NUMBER: {  /* simpleexp -> NUMBER */
      Number r = ls->t.seminfo.r;
      next(ls);
      luaK_number(fs, r);
      break;
    }
    case TK_STRING: {  /* simpleexp -> STRING */
      code_string(ls, ls->t.seminfo.ts);  /* must use `seminfo' before `next' */
      next(ls);
      break;
    }
    case TK_NIL: {  /* simpleexp -> NIL */
      luaK_adjuststack(fs, -1);
      next(ls);
      break;
    }
    case '{': {  /* simpleexp -> constructor */
      constructor(ls);
      break;
    }
    case TK_FUNCTION: {  /* simpleexp -> FUNCTION body */
      next(ls);
      body(ls, 0, ls->linenumber);
      break;
    }
    case '(': {  /* simpleexp -> '(' expr ')' */
      next(ls);
      expr(ls, v);
      check(ls, ')');
      return;
    }
    case TK_NAME: case '%': {
      var_or_func(ls, v);
      return;
    }
    default: {
      luaK_error(ls, " expected");
      return;
    }
  }
  v->k = VEXP;
  v->u.l.t = v->u.l.f = NO_JUMP;
}


static void exp1 (LexState *ls) {
  expdesc v;
  expr(ls, &v);
  luaK_tostack(ls, &v, 1);
}


static UnOpr getunopr (int op) {
  switch (op) {
    case TK_NOT: return OPR_NOT;
    case '-': return OPR_MINUS;
    default: return OPR_NOUNOPR;
  }
}


static BinOpr getbinopr (int op) {
  switch (op) {
    case '+': return OPR_ADD;
    case '-': return OPR_SUB;
    case '*': return OPR_MULT;
    case '/': return OPR_DIV;
    case '^': return OPR_POW;
    case TK_CONCAT: return OPR_CONCAT;
    case TK_NE: return OPR_NE;
    case TK_EQ: return OPR_EQ;
    case '<': return OPR_LT;
    case TK_LE: return OPR_LE;
    case '>': return OPR_GT;
    case TK_GE: return OPR_GE;
    case TK_AND: return OPR_AND;
    case TK_OR: return OPR_OR;
    default: return OPR_NOBINOPR;
  }
}


static const struct {
  char left;  /* left priority for each binary operator */
  char right; /* right priority */
} priority[] = {  /* ORDER OPR */
   {5, 5}, {5, 5}, {6, 6}, {6, 6},  /* arithmetic */
   {9, 8}, {4, 3},                  /* power and concat (right associative) */
   {2, 2}, {2, 2},                  /* equality */
   {2, 2}, {2, 2}, {2, 2}, {2, 2},  /* order */
   {1, 1}, {1, 1}                   /* logical */
};

#define UNARY_PRIORITY	7  /* priority for unary operators */


/*
** subexpr -> (simplexep | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
*/
static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
  BinOpr op;
  UnOpr uop = getunopr(ls->t.token);
  if (uop != OPR_NOUNOPR) {
    next(ls);
    subexpr(ls, v, UNARY_PRIORITY);
    luaK_prefix(ls, uop, v);
  }
  else simpleexp(ls, v);
  /* expand while operators have priorities higher than `limit' */
  op = getbinopr(ls->t.token);
  while (op != OPR_NOBINOPR && priority[op].left > limit) {
    expdesc v2;
    BinOpr nextop;
    next(ls);
    luaK_infix(ls, op, v);
    /* read sub-expression with higher priority */
    nextop = subexpr(ls, &v2, priority[op].right);
    luaK_posfix(ls, op, v, &v2);
    op = nextop;
  }
  return op;  /* return first untreated operator */
}


static void expr (LexState *ls, expdesc *v) {
  subexpr(ls, v, -1);
}

/* }==================================================================== */


/*
** {======================================================================
** Rules for Statements
** =======================================================================
*/


static int block_follow (int token) {
  switch (token) {
    case TK_ELSE: case TK_ELSEIF: case TK_END:
    case TK_UNTIL: case TK_EOS:
      return 1;
    default: return 0;
  }
}


static void block (LexState *ls) {
  /* block -> chunk */
  FuncState *fs = ls->fs;
  int nactloc = fs->nactloc;
  chunk(ls);
  luaK_adjuststack(fs, fs->nactloc - nactloc);  /* remove local variables */
  removelocalvars(ls, fs->nactloc - nactloc);
}


static int assignment (LexState *ls, expdesc *v, int nvars) {
  int left = 0;  /* number of values left in the stack after assignment */
  luaX_checklimit(ls, nvars, MAXVARSLH, "variables in a multiple assignment");
  if (ls->t.token == ',') {  /* assignment -> ',' NAME assignment */
    expdesc nv;
    next(ls);
    var_or_func(ls, &nv);
    check_condition(ls, (nv.k != VEXP), "syntax error");
    left = assignment(ls, &nv, nvars+1);
  }
  else {  /* assignment -> '=' explist1 */
    int nexps;
    check(ls, '=');
    nexps = explist1(ls);
    adjust_mult_assign(ls, nvars, nexps);
  }
  if (v->k != VINDEXED)
    luaK_storevar(ls, v);
  else {  /* there may be garbage between table-index and value */
    luaK_code2(ls->fs, OP_SETTABLE, left+nvars+2, 1);
    left += 2;
  }
  return left;
}


static void cond (LexState *ls, expdesc *v) {
  /* cond -> exp */
  expr(ls, v);  /* read condition */
  luaK_goiftrue(ls->fs, v, 0);
}


static void whilestat (LexState *ls, int line) {
  /* whilestat -> WHILE cond DO block END */
  FuncState *fs = ls->fs;
  int while_init = luaK_getlabel(fs);
  expdesc v;
  Breaklabel bl;
  enterbreak(fs, &bl);
  next(ls);
  cond(ls, &v);
  check(ls, TK_DO);
  block(ls);
  luaK_patchlist(fs, luaK_jump(fs), while_init);
  luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
  check_match(ls, TK_END, TK_WHILE, line);
  leavebreak(fs, &bl);
}


static void repeatstat (LexState *ls, int line) {
  /* repeatstat -> REPEAT block UNTIL cond */
  FuncState *fs = ls->fs;
  int repeat_init = luaK_getlabel(fs);
  expdesc v;
  Breaklabel bl;
  enterbreak(fs, &bl);
  next(ls);
  block(ls);
  check_match(ls, TK_UNTIL, TK_REPEAT, line);
  cond(ls, &v);
  luaK_patchlist(fs, v.u.l.f, repeat_init);
  leavebreak(fs, &bl);
}


static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) {
  /* forbody -> DO block END */
  FuncState *fs = ls->fs;
  int prep = luaK_code1(fs, prepfor, NO_JUMP);
  int blockinit = luaK_getlabel(fs);
  check(ls, TK_DO);
  adjustlocalvars(ls, nvar);  /* scope for control variables */
  block(ls);
  luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit);
  luaK_patchlist(fs, prep, luaK_getlabel(fs));
  removelocalvars(ls, nvar);
}


static void fornum (LexState *ls, TString *varname) {
  /* fornum -> NAME = exp1,exp1[,exp1] forbody */
  FuncState *fs = ls->fs;
  check(ls, '=');
  exp1(ls);  /* initial value */
  check(ls, ',');
  exp1(ls);  /* limit */
  if (optional(ls, ','))
    exp1(ls);  /* optional step */
  else
    luaK_code1(fs, OP_PUSHINT, 1);  /* default step */
  new_localvar(ls, varname, 0);
  new_localvarstr(ls, "(limit)", 1);
  new_localvarstr(ls, "(step)", 2);
  forbody(ls, 3, OP_FORPREP, OP_FORLOOP);
}


static void forlist (LexState *ls, TString *indexname) {
  /* forlist -> NAME,NAME IN exp1 forbody */
  TString *valname;
  check(ls, ',');
  valname = str_checkname(ls);
  /* next test is dirty, but avoids `in' being a reserved word */
  check_condition(ls,
       (ls->t.token == TK_NAME && ls->t.seminfo.ts == luaS_new(ls->L, "in")),
       "`in' expected");
  next(ls);  /* skip `in' */
  exp1(ls);  /* table */
  new_localvarstr(ls, "(table)", 0);
  new_localvar(ls, indexname, 1);
  new_localvar(ls, valname, 2);
  forbody(ls, 3, OP_LFORPREP, OP_LFORLOOP);
}


static void forstat (LexState *ls, int line) {
  /* forstat -> fornum | forlist */
  FuncState *fs = ls->fs;
  TString *varname;
  Breaklabel bl;
  enterbreak(fs, &bl);
  next(ls);  /* skip `for' */
  varname = str_checkname(ls);  /* first variable name */
  switch (ls->t.token) {
    case '=': fornum(ls, varname); break;
    case ',': forlist(ls, varname); break;
    default: luaK_error(ls, "`=' or `,' expected");
  }
  check_match(ls, TK_END, TK_FOR, line);
  leavebreak(fs, &bl);
}


static void test_then_block (LexState *ls, expdesc *v) {
  /* test_then_block -> [IF | ELSEIF] cond THEN block */
  next(ls);  /* skip IF or ELSEIF */
  cond(ls, v);
  check(ls, TK_THEN);
  block(ls);  /* `then' part */
}


static void ifstat (LexState *ls, int line) {
  /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
  FuncState *fs = ls->fs;
  expdesc v;
  int escapelist = NO_JUMP;
  test_then_block(ls, &v);  /* IF cond THEN block */
  while (ls->t.token == TK_ELSEIF) {
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
    test_then_block(ls, &v);  /* ELSEIF cond THEN block */
  }
  if (ls->t.token == TK_ELSE) {
    luaK_concat(fs, &escapelist, luaK_jump(fs));
    luaK_patchlist(fs, v.u.l.f, luaK_getlabel(fs));
    next(ls);  /* skip ELSE */
    block(ls);  /* `else' part */
  }
  else
    luaK_concat(fs, &escapelist, v.u.l.f);
  luaK_patchlist(fs, escapelist, luaK_getlabel(fs));
  check_match(ls, TK_END, TK_IF, line);
}


static void localstat (LexState *ls) {
  /* stat -> LOCAL NAME {',' NAME} ['=' explist1] */
  int nvars = 0;
  int nexps;
  do {
    next(ls);  /* skip LOCAL or ',' */
    new_localvar(ls, str_checkname(ls), nvars++);
  } while (ls->t.token == ',');
  if (optional(ls, '='))
    nexps = explist1(ls);
  else
    nexps = 0;
  adjust_mult_assign(ls, nvars, nexps);
  adjustlocalvars(ls, nvars);
}


static int funcname (LexState *ls, expdesc *v) {
  /* funcname -> NAME [':' NAME | '.' NAME] */
  int needself = 0;
  singlevar(ls, str_checkname(ls), v);
  if (ls->t.token == ':' || ls->t.token == '.') {
    needself = (ls->t.token == ':');
    next(ls);
    luaK_tostack(ls, v, 1);
    luaK_kstr(ls, checkname(ls));
    v->k = VINDEXED;
  }
  return needself;
}


static void funcstat (LexState *ls, int line) {
  /* funcstat -> FUNCTION funcname body */
  int needself;
  expdesc v;
  next(ls);  /* skip FUNCTION */
  needself = funcname(ls, &v);
  body(ls, needself, line);
  luaK_storevar(ls, &v);
}


static void namestat (LexState *ls) {
  /* stat -> func | ['%'] NAME assignment */
  FuncState *fs = ls->fs;
  expdesc v;
  var_or_func(ls, &v);
  if (v.k == VEXP) {  /* stat -> func */
    check_condition(ls, luaK_lastisopen(fs), "syntax error");  /* an upvalue? */
    luaK_setcallreturns(fs, 0);  /* call statement uses no results */
  }
  else {  /* stat -> ['%'] NAME assignment */
    int left = assignment(ls, &v, 1);
    luaK_adjuststack(fs, left);  /* remove eventual garbage left on stack */
  }
}


static void retstat (LexState *ls) {
  /* stat -> RETURN explist */
  FuncState *fs = ls->fs;
  next(ls);  /* skip RETURN */
  if (!block_follow(ls->t.token))
    explist1(ls);  /* optional return values */
  luaK_code1(fs, OP_RETURN, ls->fs->nactloc);
  fs->stacklevel = fs->nactloc;  /* removes all temp values */
}


static void breakstat (LexState *ls) {
  /* stat -> BREAK [NAME] */
  FuncState *fs = ls->fs;
  int currentlevel = fs->stacklevel;
  Breaklabel *bl = fs->bl;
  if (!bl)
    luaK_error(ls, "no loop to break");
  next(ls);  /* skip BREAK */
  luaK_adjuststack(fs, currentlevel - bl->stacklevel);
  luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
  /* correct stack for compiler and symbolic execution */
  luaK_adjuststack(fs, bl->stacklevel - currentlevel);
}


static int stat (LexState *ls) {
  int line = ls->linenumber;  /* may be needed for error messages */
  switch (ls->t.token) {
    case TK_IF: {  /* stat -> ifstat */
      ifstat(ls, line);
      return 0;
    }
    case TK_WHILE: {  /* stat -> whilestat */
      whilestat(ls, line);
      return 0;
    }
    case TK_DO: {  /* stat -> DO block END */
      next(ls);  /* skip DO */
      block(ls);
      check_match(ls, TK_END, TK_DO, line);
      return 0;
    }
    case TK_FOR: {  /* stat -> forstat */
      forstat(ls, line);
      return 0;
    }
    case TK_REPEAT: {  /* stat -> repeatstat */
      repeatstat(ls, line);
      return 0;
    }
    case TK_FUNCTION: {  /* stat -> funcstat */
      funcstat(ls, line);
      return 0;
    }
    case TK_LOCAL: {  /* stat -> localstat */
      localstat(ls);
      return 0;
    }
    case TK_NAME: case '%': {  /* stat -> namestat */
      namestat(ls);
      return 0;
    }
    case TK_RETURN: {  /* stat -> retstat */
      retstat(ls);
      return 1;  /* must be last statement */
    }
    case TK_BREAK: {  /* stat -> breakstat */
      breakstat(ls);
      return 1;  /* must be last statement */
    }
    default: {
      luaK_error(ls, " expected");
      return 0;  /* to avoid warnings */
    }
  }
}


static void parlist (LexState *ls) {
  /* parlist -> [ param { ',' param } ] */
  int nparams = 0;
  int dots = 0;
  if (ls->t.token != ')') {  /* is `parlist' not empty? */
    do {
      switch (ls->t.token) {
        case TK_DOTS: next(ls); dots = 1; break;
        case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
        default: luaK_error(ls, " or `...' expected");
      }
    } while (!dots && optional(ls, ','));
  }
  code_params(ls, nparams, dots);
}


static void body (LexState *ls, int needself, int line) {
  /* body ->  '(' parlist ')' chunk END */
  FuncState new_fs;
  open_func(ls, &new_fs);
  new_fs.f->lineDefined = line;
  check(ls, '(');
  if (needself) {
    new_localvarstr(ls, "self", 0);
    adjustlocalvars(ls, 1);
  }
  parlist(ls);
  check(ls, ')');
  chunk(ls);
  check_match(ls, TK_END, TK_FUNCTION, line);
  close_func(ls);
  pushclosure(ls, &new_fs);
}


/* }====================================================================== */


static void chunk (LexState *ls) {
  /* chunk -> { stat [';'] } */
  int islast = 0;
  while (!islast && !block_follow(ls->t.token)) {
    islast = stat(ls);
    optional(ls, ';');
    LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc,
               "stack size != # local vars");
  }
}

tome-235-src/src/lua/lparser.h0000644000076400017500000000272011012107763014060 0ustar  dgdg/*
** $Id: lparser.h,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** LL(1) Parser and code generator for Lua
** See Copyright Notice in lua.h
*/

#ifndef lparser_h
#define lparser_h

#include "lobject.h"
#include "lzio.h"


/*
** Expression descriptor
*/

typedef enum {
  VGLOBAL,
  VLOCAL,
  VINDEXED,
  VEXP
} expkind;

typedef struct expdesc {
  expkind k;
  union {
    int index;  /* VGLOBAL: `kstr' index of global name; VLOCAL: stack index */
    struct {
      int t;  /* patch list of `exit when true' */
      int f;  /* patch list of `exit when false' */
    } l;
  } u;
} expdesc;



/* state needed to generate code for a given function */
typedef struct FuncState {
  Proto *f;  /* current function header */
  struct FuncState *prev;  /* enclosing function */
  struct LexState *ls;  /* lexical state */
  struct lua_State *L;  /* copy of the Lua state */
  int pc;  /* next position to code */
  int lasttarget;   /* `pc' of last `jump target' */
  int jlt;  /* list of jumps to `lasttarget' */
  short stacklevel;  /* number of values on activation register */
  short nactloc;  /* number of active local variables */
  short nupvalues;  /* number of upvalues */
  int lastline;  /* line where last `lineinfo' was generated */
  struct Breaklabel *bl;  /* chain of breakable blocks */
  expdesc upvalues[MAXUPVALUES];  /* upvalues */
  int actloc[MAXLOCALS];  /* local-variable stack (indices to locvars) */
} FuncState;


Proto *luaY_parser (lua_State *L, ZIO *z);


#endif
tome-235-src/src/lua/feature.lua0000644000076400017500000000305511012107763014377 0ustar  dgdg-- tolua: abstract feature class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: feature.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Feature class
-- Represents the base class of all mapped feature.
classFeature = {
}

-- write support code
function classFeature:supcode ()
end

-- output tag
function classFeature:decltag ()
end

-- register feature
function classFeature:register ()
end

-- unregister feature
function classFeature:unregister ()
end

-- translate verbatim
function classFeature:preamble ()
end

-- check if feature is inside a class definition
-- it returns the feature class name or nil.
function classFeature:inclass ()
 if self.parent and self.parent.type == 'class' then
  return self.parent.name
 else
  return nil
 end
end

-- check if feature is inside a module
-- it returns the feature module name or nil.
function classFeature:inmodule ()
 if self.parent and self.parent.type == 'module' then
  return self.parent.name
 else
  return nil
 end
end

-- return C binding function name based on name
-- the client specifies a prefix
-- return C binding function name
-- the client specifies a prefix
function classFeature:cfuncname (n)
 if self.parent then
  n = self.parent:cfuncname(n)
 end
 if self.lname then
  return n..'_'..self.lname
 else
  return n..'_'..self.name
 end
end

tome-235-src/src/lua/code.lua0000644000076400017500000000331311012107763013653 0ustar  dgdg-- tolua: code class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1999
-- $Id: code.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Code class
-- Represents Lua code to be compiled and included
-- in the initialization function.
-- The following fields are stored:
--   text = text code
classCode = {
 text = '',
 _base = classFeature,
}
settag(classCode,tolua_tag)

-- register code
function classCode:register ()
 -- clean Lua code
 local s = clean(self.text)
 if not s then
  error("parser error in embedded code")  
 end
 
 -- convert to C
 output('\n { /* begin embedded lua code */\n')
 output('  static unsigned char B[] = {\n   ')
 local t={n=0}
 local b = gsub(s,'(.)',function (c) 
                         local e = '' 
                         %t.n=%t.n+1 if %t.n==15 then %t.n=0 e='\n   ' end 
                         return format('%3u,%s',strbyte(c),e) 
                        end
               )
 output(b..strbyte(" "))
 output('\n  };\n')
 output('  lua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code");')
 output(' } /* end of embedded lua code */\n\n')
end
 

-- Print method
function classCode:print (ident,close)
 print(ident.."Code{")
 print(ident.." text = [["..self.text.."]],")
 print(ident.."}"..close)
end


-- Internal constructor
function _Code (t)
 t._base = classCode
 settag(t,tolua_tag)
 append(t)
 return t
end

-- Constructor
-- Expects a string representing the code text
function Code (l)
 return _Code {
  text = l
 }
end


tome-235-src/src/lua/declaration.lua0000644000076400017500000002246411012107763015236 0ustar  dgdg-- tolua: declaration class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: declaration.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Declaration class
-- Represents variable, function, or argument declaration.
-- Stores the following fields:
--  mod  = type modifiers
--  type = type
--  ptr  = "*" or "&", if representing a pointer or a reference
--  name = name
--  dim  = dimension, if a vector
--  def  = default value, if any (only for arguments)
--  ret  = "*" or "&", if value is to be returned (only for arguments)
classDeclaration = {
 _base = classFeature,
 mod = '',
 type = '',
 ptr = '',
 name = '',
 dim = '',
 ret = '',
 def = ''
}
settag(classDeclaration,tolua_tag)

-- Create an unique variable name
function create_varname ()
 if not _varnumber then _varnumber = 0 end
 _varnumber = _varnumber + 1
 return "tolua_var_".._varnumber
end

-- Check declaration name
-- It also identifies default values
function classDeclaration:checkname ()

 if strsub(self.name,1,1) == '[' and not istype(self.type) then
  self.name = self.type..self.name
  local m = split(self.mod,'%s%s*')
  self.type = m[m.n]
  self.mod = concat(m,1,m.n-1)
 end

 local t = split(self.name,'=')
 if t.n==2 then
  self.name = t[1]
  self.def = t[t.n]
 end

 local b,e,d = strfind(self.name,"%[(.-)%]")
 if b then
  self.name = strsub(self.name,1,b-1)
  self.dim = d
 end


 if self.type ~= '' and self.type ~= 'void' and self.name == '' then
  self.name = create_varname()
 elseif self.kind=='var' then
  if self.type=='' and self.name~='' then
   self.type = self.type..self.name
   self.name = create_varname()
  elseif istype(self.name) then
   if self.type=='' then self.type = self.name
   else self.type = self.type..' '..self.name end
   self.name = create_varname()
  end
 end

end

-- Check declaration type
-- Substitutes typedef's.
function classDeclaration:checktype ()

 -- check if there is a pointer to basic type
 if isbasic(self.type) and self.ptr~='' then
  self.ret = self.ptr
  self.ptr = nil
 end

 -- check if there is array to be returned
 if self.dim~='' and self.ret~='' then
   error('#invalid parameter: cannot return an array of values')
 end

 -- register type
 if self.type~='' then
  regtype(self.type)
 end

 -- restore 'void*' and 'string*'
 if self.type == '_userdata' then self.type = 'void*'
 elseif self.type == '_cstring' then self.type = 'char*'
 end

--
-- -- if returning value, automatically set default value
-- if self.ret ~= '' and self.def == '' then
--  self.def = '0'
-- end
--

end

-- Print method
function classDeclaration:print (ident,close)
 print(ident.."Declaration{")
 print(ident.." mod  = '"..self.mod.."',")
 print(ident.." type = '"..self.type.."',")
 print(ident.." ptr  = '"..self.ptr.."',")
 print(ident.." name = '"..self.name.."',")
 print(ident.." dim  = '"..self.dim.."',")
 print(ident.." def  = '"..self.def.."',")
 print(ident.." ret  = '"..self.ret.."',")
 print(ident.."}"..close)
end

-- declare tag
function classDeclaration:decltag ()
 self.itype, self.tag = tagvar(self.type,strfind(self.mod,'const'))
end


-- output type checking
function classDeclaration:outchecktype (narg)
 local tag, def
 if self.dim ~= '' then 
  tag = 'LUA_TTABLE'
  def = 0
 else
  tag = self.tag
  def = self.def~='' or 0
 end
 return 'tolua_istype(tolua_S,'..narg..','..tag..','..def..')'
end

-- Declare variable
function classDeclaration:declare (narg)
 local ptr = ''
 if self.ptr~='' then ptr = '*' end
 output(" ",self.mod,self.type,ptr)
 if self.dim ~= '' and tonumber(self.dim)==nil then
  output('*')
 end 
 output(self.name)
 if self.dim ~= '' then
  if tonumber(self.dim)~=nil then
   output('[',self.dim,'];')
  else
   output(' = (',self.mod,self.type,ptr,'*)',
          'malloc(',self.dim,'*sizeof(',self.type,ptr,'));')
  end
 else
  local t = isbasic(self.type)
  output(' = ')
  if not t and ptr=='' then output('*') end
  output('((',self.mod,self.type)
  if not t then
   output('*')
  end
  output(') ')
  local def = 0
  if self.def ~= '' then def = self.def end
  if t then
   output('tolua_get'..t,'(tolua_S,',narg,',',def,'));')
  else
   output('tolua_getusertype(tolua_S,',narg,',',def,'));')
  end
 end
end

-- Get parameter value
function classDeclaration:getarray (narg)
 if self.dim ~= '' then
  output('  {')
  local def = self.def~='' or 0
  output('   if (!tolua_arrayistype(tolua_S,',narg,',',self.tag,',',self.dim,',',def,'))')
  output('    goto tolua_lerror;')
  output('   else\n')
  output('   {')
  output('    int i;')
  output('    for(i=0; i<'..self.dim..';i++)')
  local t = isbasic(self.type)
  local ptr = ''
  if self.ptr~='' then ptr = '*' end
  output('   ',self.name..'[i] = ')
  if not t and ptr=='' then output('*') end
  output('((',self.mod,self.type)
  if not t then
   output('*')
  end
  output(') ')
  local def = 0
  if self.def ~= '' then def = self.def end
  if t then
   output('tolua_getfield'..t..'(tolua_S,',narg,',i+1,',def,'));')
  else 
   output('tolua_getfieldusertype(tolua_S,',narg,',i+1,',def,'));')
  end
  output('   }')
  output('  }')
 end
end

-- Get parameter value
function classDeclaration:setarray (narg)
 if self.dim ~= '' then
  output('  {')
  output('   int i;')
  output('   for(i=0; i<'..self.dim..';i++)')
  local t,ct = isbasic(self.type)
  if t then
   output('   tolua_pushfield'..t..'(tolua_S,',narg,',i+1,(',ct,')',self.name,'[i]);')
  else
   if self.ptr == '' then
     output('   {')
     output('#ifdef __cplusplus\n')
     output('    void* toluaI_clone = new',self.type,'(',self.name,'[i]);')
     output('#else\n')
     output('    void* toluaI_clone = tolua_copy(tolua_S,(void*)&',self.name,'[i],sizeof(',self.type,'));')
     output('#endif\n')
     output('    tolua_pushfieldusertype(tolua_S,',narg,',i+1,tolua_doclone(tolua_S,toluaI_clone,',self.tag,'),',self.tag,');')
     output('   }')

    --output('   tolua_pushfieldclone(tolua_S,',narg,',i+1,(void*)&',self.name,'[i],sizeof(',self.type,'),',self.tag,');')
   else
    output('   tolua_pushfieldusertype(tolua_S,',narg,',i+1,(void*)',self.name,'[i],',self.tag,');')
   end
  end
  output('  }')
 end
end

-- Free dynamically allocated array
function classDeclaration:freearray ()
 if self.dim ~= '' and tonumber(self.dim)==nil then
  output('  free(',self.name,');')
 end
end

-- Pass parameter
function classDeclaration:passpar ()
 if self.ptr=='&' then
  output('*'..self.name)
 elseif self.ret=='*' then
  output('&'..self.name)
 else
  output(self.name)
 end
end

-- Return parameter value
function classDeclaration:retvalue ()
 if self.ret ~= '' then
  local t,ct = isbasic(self.type)
  if t then
   output('   tolua_push'..t..'(tolua_S,(',ct,')'..self.name..');')
  else
   output('   tolua_pushusertype(tolua_S,(void*)'..self.name..',',self.tag,');')
  end
  return 1
 end
 return 0
end

-- Internal constructor
function _Declaration (t)
 if t.name and t.name~='' then
  local n = split(t.name,'@')
  t.name = n[1]
  t.lname = gsub(n[2] or n[1],"%[.-%]","")
 end
 t._base = classDeclaration
 settag(t,tolua_tag)
 t:checkname()
 t:checktype()
 return t
end

-- Constructor
-- Expects the string declaration.
-- The kind of declaration can be "var" or "func".
function Declaration (s,kind)
 -- eliminate spaces if default value is provided
 s = gsub(s,"%s*=%s*","=")

 if kind == "var" then
  -- check the form: void
  if s == '' or s == 'void' then
   return _Declaration{type = 'void', kind = kind}
  end
 end

 -- check the form: mod type*& name
 local t = split(s,'%*%s*&')
 if t.n == 2 then
  if kind == 'func' then
   error("#invalid function return type: "..s)
  end
  local m = split(t[1],'%s%s*')
  return _Declaration{
   name = t[2],
   ptr = '*',
   ret = '&',
   type = m[m.n],
   mod = concat(m,1,m.n-1),
   kind = kind
  }
 end

 -- check the form: mod type** name
 t = split(s,'%*%s*%*')
 if t.n == 2 then
  if kind == 'func' then
   error("#invalid function return type: "..s)
  end
  local m = split(t[1],'%s%s*')
  return _Declaration{
   name = t[2],
   ptr = '*',
   ret = '*',
   type = m[m.n],
   mod = concat(m,1,m.n-1),
   kind = kind
  }
 end
 
 -- check the form: mod type& name
 t = split(s,'&')
 if t.n == 2 then
  local m = split(t[1],'%s%s*')
  return _Declaration{
   name = t[2],
   ptr = '&',
   type = m[m.n],
   mod = concat(m,1,m.n-1)   ,
   kind = kind
  }
 end
  
 -- check the form: mod type* name
 local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end)
 t = split(s1,'%*')
 if t.n == 2 then
  t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression
  local m = split(t[1],'%s%s*')
  return _Declaration{
   name = t[2],
   ptr = '*',
   type = m[m.n],
   mod = concat(m,1,m.n-1)   ,
   kind = kind
  }
 end

 if kind == 'var' then
  -- check the form: mod type name
  t = split(s,'%s%s*')
  local v
  if istype(t[t.n]) then v = '' else v = t[t.n]; t.n = t.n-1 end
  return _Declaration{
   name = v,
   type = t[t.n],
   mod = concat(t,1,t.n-1),
   kind = kind
  }

 else -- kind == "func"
 
  -- check the form: mod type name
  t = split(s,'%s%s*')
  local v = t[t.n]  -- last word is the function name
  local tp,md
  if t.n>1 then
   tp = t[t.n-1]
   md = concat(t,1,t.n-2)
  end
  return _Declaration{
   name = v,
   type = tp,
   mod = md,
   kind = kind
  }
 end

end



tome-235-src/src/lua/lbaselib.c0000644000076400017500000004132411012107763014163 0ustar  dgdg/*
** $Id: lbaselib.c,v 1.2 2001/11/26 23:00:23 darkgod Exp $
** Basic library
** See Copyright Notice in lua.h
*/



#include 
#include 
#include 
#include 

#include "lua.h"

#include "lauxlib.h"
#include "luadebug.h"
#include "lualib.h"



/*
** If your system does not support `stderr', redefine this function, or
** redefine _ERRORMESSAGE so that it won't need _ALERT.
*/
static int luaB__ALERT (lua_State *L) {
  fputs(luaL_check_string(L, 1), stderr);
  return 0;
}


/*
** Basic implementation of _ERRORMESSAGE.
** The library `liolib' redefines _ERRORMESSAGE for better error information.
*/
static int luaB__ERRORMESSAGE (lua_State *L) {
  luaL_checktype(L, 1, LUA_TSTRING);
  lua_getglobal(L, LUA_ALERT);
  if (lua_isfunction(L, -1)) {  /* avoid error loop if _ALERT is not defined */
    lua_Debug ar;
    lua_pushstring(L, "error: ");
    lua_pushvalue(L, 1);
    if (lua_getstack(L, 1, &ar)) {
      lua_getinfo(L, "Sl", &ar);
      if (ar.source && ar.currentline > 0) {
        char buff[100];
        sprintf(buff, "\n  <%.70s: line %d>", ar.short_src, ar.currentline);
        lua_pushstring(L, buff);
        lua_concat(L, 2);
      }
    }
    lua_pushstring(L, "\n");
    lua_concat(L, 3);
    lua_rawcall(L, 1, 0);
  }
  return 0;
}


/*
** If your system does not support `stdout', you can just remove this function.
** If you need, you can define your own `print' function, following this
** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance).
*/
static int luaB_print (lua_State *L) {
  int n = lua_gettop(L);  /* number of arguments */
  int i;
  lua_getglobal(L, "tostring");
  for (i=1; i<=n; i++) {
    const char *s;
    lua_pushvalue(L, -1);  /* function to be called */
    lua_pushvalue(L, i);   /* value to print */
    lua_rawcall(L, 1, 1);
    s = lua_tostring(L, -1);  /* get result */
    if (s == NULL)
      lua_error(L, "`tostring' must return a string to `print'");
    if (i>1) fputs("\t", stdout);
    fputs(s, stdout);
    lua_pop(L, 1);  /* pop result */
  }
  fputs("\n", stdout);
  return 0;
}


static int luaB_tonumber (lua_State *L) {
  int base = luaL_opt_int(L, 2, 10);
  if (base == 10) {  /* standard conversion */
    luaL_checkany(L, 1);
    if (lua_isnumber(L, 1)) {
      lua_pushnumber(L, lua_tonumber(L, 1));
      return 1;
    }
  }
  else {
    const char *s1 = luaL_check_string(L, 1);
    char *s2;
    unsigned long n;
    luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range");
    n = strtoul(s1, &s2, base);
    if (s1 != s2) {  /* at least one valid digit? */
      while (isspace((unsigned char)*s2)) s2++;  /* skip trailing spaces */
      if (*s2 == '\0') {  /* no invalid trailing characters? */
        lua_pushnumber(L, n);
        return 1;
      }
    }
  }
  lua_pushnil(L);  /* else not a number */
  return 1;
}


static int luaB_error (lua_State *L) {
  lua_error(L, luaL_opt_string(L, 1, NULL));
  return 0;  /* to avoid warnings */
}

static int luaB_setglobal (lua_State *L) {
  luaL_checkany(L, 2);
  lua_setglobal(L, luaL_check_string(L, 1));
  return 0;
}

static int luaB_getglobal (lua_State *L) {
  lua_getglobal(L, luaL_check_string(L, 1));
  return 1;
}

static int luaB_tag (lua_State *L) {
  luaL_checkany(L, 1);
  lua_pushnumber(L, lua_tag(L, 1));
  return 1;
}

static int luaB_settag (lua_State *L) {
  luaL_checktype(L, 1, LUA_TTABLE);
  lua_pushvalue(L, 1);  /* push table */
  lua_settag(L, luaL_check_int(L, 2));
  return 1;  /* return table */
}

static int luaB_newtag (lua_State *L) {
  lua_pushnumber(L, lua_newtag(L));
  return 1;
}

static int luaB_copytagmethods (lua_State *L) {
  lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1),
                                          luaL_check_int(L, 2)));
  return 1;
}

static int luaB_globals (lua_State *L) {
  lua_getglobals(L);  /* value to be returned */
  if (!lua_isnull(L, 1)) {
    luaL_checktype(L, 1, LUA_TTABLE);
    lua_pushvalue(L, 1);  /* new table of globals */
    lua_setglobals(L);
  }
  return 1;
}

static int luaB_rawget (lua_State *L) {
  luaL_checktype(L, 1, LUA_TTABLE);
  luaL_checkany(L, 2);
  lua_rawget(L, -2);
  return 1;
}

static int luaB_rawset (lua_State *L) {
  luaL_checktype(L, 1, LUA_TTABLE);
  luaL_checkany(L, 2);
  luaL_checkany(L, 3);
  lua_rawset(L, -3);
  return 1;
}

static int luaB_settagmethod (lua_State *L) {
  int tag = luaL_check_int(L, 1);
  const char *event = luaL_check_string(L, 2);
  luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
                 "function or nil expected");
  if (strcmp(event, "gc") == 0)
    lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua");
  lua_gettagmethod(L, tag, event);
  lua_pushvalue(L, 3);
  lua_settagmethod(L, tag, event);
  return 1;
}


static int luaB_gettagmethod (lua_State *L) {
  int tag = luaL_check_int(L, 1);
  const char *event = luaL_check_string(L, 2);
  if (strcmp(event, "gc") == 0)
    lua_error(L, "deprecated use: cannot get the `gc' tag method from Lua");
  lua_gettagmethod(L, tag, event);
  return 1;
}


static int luaB_gcinfo (lua_State *L) {
  lua_pushnumber(L, lua_getgccount(L));
  lua_pushnumber(L, lua_getgcthreshold(L));
  return 2;
}


static int luaB_collectgarbage (lua_State *L) {
  lua_setgcthreshold(L, luaL_opt_int(L, 1, 0));
  return 0;
}


static int luaB_type (lua_State *L) {
  luaL_checkany(L, 1);
  lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
  return 1;
}


static int luaB_next (lua_State *L) {
  luaL_checktype(L, 1, LUA_TTABLE);
  lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
  if (lua_next(L, 1))
    return 2;
  else {
    lua_pushnil(L);
    return 1;
  }
}


static int passresults (lua_State *L, int status, int oldtop) {
  static const char *const errornames[] =
    {"ok", "run-time error", "file error", "syntax error",
     "memory error", "error in error handling"};
  if (status == 0) {
    int nresults = lua_gettop(L) - oldtop;
    if (nresults > 0)
      return nresults;  /* results are already on the stack */
    else {
      lua_pushuserdata(L, NULL);  /* at least one result to signal no errors */
      return 1;
    }
  }
  else {  /* error */
    lua_pushnil(L);
    lua_pushstring(L, errornames[status]);  /* error code */
    return 2;
  }
}

static int luaB_dostring (lua_State *L) {
  int oldtop = lua_gettop(L);
  size_t l;
  const char *s = luaL_check_lstr(L, 1, &l);
  if (*s == '\27')  /* binary files start with ESC... */
    lua_error(L, "`dostring' cannot run pre-compiled code");
  return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop);
}


static int luaB_dofile (lua_State *L) {
  int oldtop = lua_gettop(L);
  const char *fname = luaL_opt_string(L, 1, NULL);
  return passresults(L, lua_dofile(L, fname), oldtop);
}


static int luaB_call (lua_State *L) {
  int oldtop;
  const char *options = luaL_opt_string(L, 3, "");
  int err = 0;  /* index of old error method */
  int i, status;
  int n;
  luaL_checktype(L, 2, LUA_TTABLE);
  n = lua_getn(L, 2);
  if (!lua_isnull(L, 4)) {  /* set new error method */
    lua_getglobal(L, LUA_ERRORMESSAGE);
    err = lua_gettop(L);  /* get index */
    lua_pushvalue(L, 4);
    lua_setglobal(L, LUA_ERRORMESSAGE);
  }
  oldtop = lua_gettop(L);  /* top before function-call preparation */
  /* push function */
  lua_pushvalue(L, 1);
  luaL_checkstack(L, n, "too many arguments");
  for (i=0; i=pos; n--) {
    lua_rawgeti(L, 1, n);
    lua_rawseti(L, 1, n+1);  /* t[n+1] = t[n] */
  }
  lua_pushvalue(L, v);
  lua_rawseti(L, 1, pos);  /* t[pos] = v */
  return 0;
}


static int luaB_tremove (lua_State *L) {
  int pos, n;
  luaL_checktype(L, 1, LUA_TTABLE);
  n = lua_getn(L, 1);
  pos = luaL_opt_int(L, 2, n);
  if (n <= 0) return 0;  /* table is "empty" */
  lua_rawgeti(L, 1, pos);  /* result = t[pos] */
  for ( ;pos= P */
      while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
        if (i>u) lua_error(L, "invalid order function for sorting");
        lua_pop(L, 1);  /* remove a[i] */
      }
      /* repeat --j until a[j] <= P */
      while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
        if (ju.s.hash;
      break;
    case LUA_TUSERDATA:
      h = IntPoint(tsvalue(key));
      break;
    case LUA_TTABLE:
      h = IntPoint(hvalue(key));
      break;
    case LUA_TFUNCTION:
      h = IntPoint(clvalue(key));
      break;
    default:
      return NULL;  /* invalid key */
  }
  LUA_ASSERT(h%(unsigned int)t->size == (h&((unsigned int)t->size-1)),
            "a&(x-1) == a%x, for x power of 2");
  return &t->node[h&(t->size-1)];
}


static const TObject *luaH_getany (lua_State *L, const Hash *t,
                                   const TObject *key) {
  Node *n = luaH_mainposition(t, key);
  if (!n)
    lua_error(L, "table index is nil");
  else do {
    if (luaO_equalObj(key, &n->key))
      return &n->val;
    n = n->next;
  } while (n);
  return &luaO_nilobject;  /* key not found */
}


/* specialized version for numbers */
const TObject *luaH_getnum (const Hash *t, Number key) {
  Node *n = &t->node[(unsigned long)(long)key&(t->size-1)];
  do {
    if (ttype(&n->key) == LUA_TNUMBER && nvalue(&n->key) == key)
      return &n->val;
    n = n->next;
  } while (n);
  return &luaO_nilobject;  /* key not found */
}


/* specialized version for strings */
const TObject *luaH_getstr (const Hash *t, TString *key) {
  Node *n = &t->node[key->u.s.hash&(t->size-1)];
  do {
    if (ttype(&n->key) == LUA_TSTRING && tsvalue(&n->key) == key)
      return &n->val;
    n = n->next;
  } while (n);
  return &luaO_nilobject;  /* key not found */
}


const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key) {
  switch (ttype(key)) {
    case LUA_TNUMBER: return luaH_getnum(t, nvalue(key));
    case LUA_TSTRING: return luaH_getstr(t, tsvalue(key));
    default:         return luaH_getany(L, t, key);
  }
}


Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
  int i;
  if (ttype(key) == LUA_TNIL)
    i = 0;  /* first iteration */
  else {
    const TObject *v = luaH_get(L, t, key);
    if (v == &luaO_nilobject)
      lua_error(L, "invalid key for `next'");
    i = (int)(((const char *)v -
               (const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
  }
  for (; isize; i++) {
    Node *n = node(t, i);
    if (ttype(val(n)) != LUA_TNIL)
      return n;
  }
  return NULL;  /* no more elements */
}


/*
** try to remove a key without value from a table. To avoid problems with
** hash, change `key' for a number with the same hash.
*/
void luaH_remove (Hash *t, TObject *key) {
  if (ttype(key) == LUA_TNUMBER ||
       (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30))
  return;  /* do not remove numbers nor small strings */
  else {
    /* try to find a number `n' with the same hash as `key' */
    Node *mp = luaH_mainposition(t, key);
    int n = mp - &t->node[0];
    /* make sure `n' is not in `t' */
    while (luaH_getnum(t, n) != &luaO_nilobject) {
      if (n >= MAX_INT - t->size)
        return;  /* give up; (to avoid overflow) */
      n += t->size;
    }
    ttype(key) = LUA_TNUMBER;
    nvalue(key) = n;
    LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash");
  }
}


static void setnodevector (lua_State *L, Hash *t, lint32 size) {
  int i;
  if (size > MAX_INT)
    lua_error(L, "table overflow");
  t->node = luaM_newvector(L, size, Node);
  for (i=0; i<(int)size; i++) {
    ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL;
    t->node[i].next = NULL;
  }
  L->nblocks += gcsize(L, size) - gcsize(L, t->size);
  t->size = size;
  t->firstfree = &t->node[size-1];  /* first free position to be used */
}


Hash *luaH_new (lua_State *L, int size) {
  Hash *t = luaM_new(L, Hash);
  t->htag = TagDefault;
  t->next = L->roottable;
  L->roottable = t;
  t->mark = t;
  t->size = 0;
  L->nblocks += gcsize(L, 0);
  t->node = NULL;
  setnodevector(L, t, luaO_power2(size));
  return t;
}


void luaH_free (lua_State *L, Hash *t) {
  L->nblocks -= gcsize(L, t->size);
  luaM_free(L, t->node);
  luaM_free(L, t);
}


static int numuse (const Hash *t) {
  Node *v = t->node;
  int size = t->size;
  int realuse = 0;
  int i;
  for (i=0; isize;
  Node *nold = t->node;
  int nelems = numuse(t);
  int i;
  LUA_ASSERT(nelems<=oldsize, "wrong count");
  if (nelems >= oldsize-oldsize/4)  /* using more than 3/4? */
    setnodevector(L, t, (lint32)oldsize*2);
  else if (nelems <= oldsize/4 &&  /* less than 1/4? */
           oldsize > MINPOWER2)
    setnodevector(L, t, oldsize/2);
  else
    setnodevector(L, t, oldsize);
  for (i=0; ival) != LUA_TNIL)
      *luaH_set(L, t, &old->key) = old->val;
  }
  luaM_free(L, nold);  /* free old array */
}


/*
** inserts a key into a hash table; first, check whether key is
** already present; if not, check whether key's main position is free;
** if not, check whether colliding node is in its main position or not;
** if it is not, move colliding node to an empty place and put new key
** in its main position; otherwise (colliding node is in its main position),
** new key goes to an empty position.
*/
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key) {
  Node *mp = luaH_mainposition(t, key);
  Node *n = mp;
  if (!mp)
    lua_error(L, "table index is nil");
  do {  /* check whether `key' is somewhere in the chain */
    if (luaO_equalObj(key, &n->key))
      return &n->val;  /* that's all */
    else n = n->next;
  } while (n);
  /* `key' not found; must insert it */
  if (ttype(&mp->key) != LUA_TNIL) {  /* main position is not free? */
    Node *othern;  /* main position of colliding node */
    n = t->firstfree;  /* get a free place */
    /* is colliding node out of its main position? (can only happens if
       its position is after "firstfree") */
    if (mp > n && (othern=luaH_mainposition(t, &mp->key)) != mp) {
      /* yes; move colliding node into free position */
      while (othern->next != mp) othern = othern->next;  /* find previous */
      othern->next = n;  /* redo the chain with `n' in place of `mp' */
      *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
      mp->next = NULL;  /* now `mp' is free */
    }
    else {  /* colliding node is in its own main position */
      /* new node will go into free position */
      n->next = mp->next;  /* chain new position */
      mp->next = n;
      mp = n;
    }
  }
  mp->key = *key;
  for (;;) {  /* correct `firstfree' */
    if (ttype(&t->firstfree->key) == LUA_TNIL)
      return &mp->val;  /* OK; table still has a free place */
    else if (t->firstfree == t->node) break;  /* cannot decrement from here */
    else (t->firstfree)--;
  }
  rehash(L, t);  /* no more free places */
  return luaH_set(L, t, key);  /* `rehash' invalidates this insertion */
}


TObject *luaH_setint (lua_State *L, Hash *t, int key) {
  TObject index;
  ttype(&index) = LUA_TNUMBER;
  nvalue(&index) = key;
  return luaH_set(L, t, &index);
}


void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val) {
  TObject *value, index;
  ttype(&index) = LUA_TSTRING;
  tsvalue(&index) = key;
  value = luaH_set(L, t, &index);
  ttype(value) = LUA_TNUMBER;
  nvalue(value) = val;
}


const TObject *luaH_getglobal (lua_State *L, const char *name) {
  return luaH_getstr(L->gt, luaS_new(L, name));
}

tome-235-src/src/lua/ltable.h0000644000076400017500000000205011012107763013647 0ustar  dgdg/*
** $Id: ltable.h,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/

#ifndef ltable_h
#define ltable_h

#include "lobject.h"


#define node(t,i)	(&(t)->node[i])
#define key(n)		(&(n)->key)
#define val(n)		(&(n)->val)

Hash *luaH_new (lua_State *L, int nhash);
void luaH_free (lua_State *L, Hash *t);
const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key);
const TObject *luaH_getnum (const Hash *t, Number key);
const TObject *luaH_getstr (const Hash *t, TString *key);
void luaH_remove (Hash *t, TObject *key);
TObject *luaH_set (lua_State *L, Hash *t, const TObject *key);
Node * luaH_next (lua_State *L, const Hash *t, const TObject *r);
TObject *luaH_setint (lua_State *L, Hash *t, int key);
void luaH_setstrnum (lua_State *L, Hash *t, TString *key, Number val);
unsigned long luaH_hash (lua_State *L, const TObject *key);
const TObject *luaH_getglobal (lua_State *L, const char *name);

/* exported only for debugging */
Node *luaH_mainposition (const Hash *t, const TObject *key);


#endif
tome-235-src/src/lua/lua2c.lua0000644000076400017500000000142211012107763013746 0ustar  dgdg-- lua2c.lua
-- embed lua code into C source
-- celetecgraf.puc-rio.br
-- dez 2000

function embed (code)

 -- clean Lua code
 local s = clean(code)
 if not s then
  error("parser error in embedded code")  
 end
 
 -- convert to C
 output('\n { /* begin embedded lua code */\n')
 output('  static unsigned char B[] = {\n   ')
 local t={n=0}
 local b = gsub(s,'(.)',function (c) 
                         local e = '' 
                         %t.n=%t.n+1 if %t.n==15 then %t.n=0 e='\n   ' end 
                         return format('%3u,%s',strbyte(c),e) 
                        end
               )
 output(b..strbyte(" "))
 output('\n  };\n')
 output('  lua_dobuffer(tolua_S,(char*)B,sizeof(B),"'..fn..': embedded Lua code");')
 output(' } /* end of embedded lua code */\n\n')
end

tome-235-src/src/lua/ltests.c0000644000076400017500000003126111012107763013723 0ustar  dgdg/*
** $Id: ltests.c,v 1.2 2001/11/26 23:00:26 darkgod Exp $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 
#include 


#include "lua.h"

#include "lapi.h"
#include "lauxlib.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "luadebug.h"
#include "lualib.h"


void luaB_opentests (lua_State *L);


/*
** The whole module only makes sense with LUA_DEBUG on
*/
#ifdef LUA_DEBUG



static void setnameval (lua_State *L, const char *name, int val) {
  lua_pushstring(L, name);
  lua_pushnumber(L, val);
  lua_settable(L, -3);
}


/*
** {======================================================
** Disassembler
** =======================================================
*/


static const char *const instrname[NUM_OPCODES] = {
  "END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT", 
  "PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL", 
  "GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF", 
  "CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP", 
  "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", 
  "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", 
  "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", 
  "LFORLOOP", "CLOSURE"
};


static int pushop (lua_State *L, Proto *p, int pc) {
  char buff[100];
  Instruction i = p->code[pc];
  OpCode o = GET_OPCODE(i);
  const char *name = instrname[o];
  sprintf(buff, "%5d - ", luaG_getline(p->lineinfo, pc, 1, NULL));
  switch ((enum Mode)luaK_opproperties[o].mode) {  
    case iO:
      sprintf(buff+8, "%-12s", name);
      break;
    case iU:
      sprintf(buff+8, "%-12s%4u", name, GETARG_U(i));
      break;
    case iS:
      sprintf(buff+8, "%-12s%4d", name, GETARG_S(i));
      break;
    case iAB:
      sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
      break;
  }
  lua_pushstring(L, buff);
  return (o != OP_END);
}


static int listcode (lua_State *L) {
  int pc;
  Proto *p;
  int res;
  luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
                 1, "Lua function expected");
  p = clvalue(luaA_index(L, 1))->f.l;
  lua_newtable(L);
  setnameval(L, "maxstack", p->maxstacksize);
  setnameval(L, "numparams", p->numparams);
  pc = 0;
  do {
    lua_pushnumber(L, pc+1);
    res = pushop(L, p, pc++);
    lua_settable(L, -3);
  } while (res);
  return 1;
}


static int liststrings (lua_State *L) {
  Proto *p;
  int i;
  luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
                 1, "Lua function expected");
  p = clvalue(luaA_index(L, 1))->f.l;
  lua_newtable(L);
  for (i=0; inkstr; i++) {
    lua_pushnumber(L, i+1);
    lua_pushstring(L, p->kstr[i]->str);
    lua_settable(L, -3);
  }
  return 1;
}


static int listlocals (lua_State *L) {
  Proto *p;
  int pc = luaL_check_int(L, 2) - 1;
  int i = 0;
  const char *name;
  luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
                 1, "Lua function expected");
  p = clvalue(luaA_index(L, 1))->f.l;
  while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
    lua_pushstring(L, name);
  return i-1;
}

/* }====================================================== */



static int get_limits (lua_State *L) {
  lua_newtable(L);
  setnameval(L, "BITS_INT", BITS_INT);
  setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
  setnameval(L, "MAXARG_A", MAXARG_A);
  setnameval(L, "MAXARG_B", MAXARG_B);
  setnameval(L, "MAXARG_S", MAXARG_S);
  setnameval(L, "MAXARG_U", MAXARG_U);
  setnameval(L, "MAXLOCALS", MAXLOCALS);
  setnameval(L, "MAXPARAMS", MAXPARAMS);
  setnameval(L, "MAXSTACK", MAXSTACK);
  setnameval(L, "MAXUPVALUES", MAXUPVALUES);
  setnameval(L, "MAXVARSLH", MAXVARSLH);
  setnameval(L, "RFPF", RFIELDS_PER_FLUSH);
  setnameval(L, "SIZE_A", SIZE_A);
  setnameval(L, "SIZE_B", SIZE_B);
  setnameval(L, "SIZE_OP", SIZE_OP);
  setnameval(L, "SIZE_U", SIZE_U);
  return 1;
}


static int mem_query (lua_State *L) {
  if (lua_isnull(L, 1)) {
    lua_pushnumber(L, memdebug_total);
    lua_pushnumber(L, memdebug_numblocks);
    lua_pushnumber(L, memdebug_maxmem);
    return 3;
  }
  else {
    memdebug_memlimit = luaL_check_int(L, 1);
    return 0;
  }
}


static int hash_query (lua_State *L) {
  if (lua_isnull(L, 2)) {
    luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, "string expected");
    lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash);
  }
  else {
    Hash *t;
    luaL_checktype(L, 2, LUA_TTABLE);
    t = hvalue(luaA_index(L, 2));
    lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node);
  }
  return 1;
}


static int table_query (lua_State *L) {
  const Hash *t;
  int i = luaL_opt_int(L, 2, -1);
  luaL_checktype(L, 1, LUA_TTABLE);
  t = hvalue(luaA_index(L, 1));
  if (i == -1) {
    lua_pushnumber(L, t->size);
    lua_pushnumber(L, t->firstfree - t->node);
    return 2;
  }
  else if (i < t->size) {
    luaA_pushobject(L, &t->node[i].key);
    luaA_pushobject(L, &t->node[i].val);
    if (t->node[i].next) {
      lua_pushnumber(L, t->node[i].next - t->node);
      return 3;
    }
    else
      return 2;
  }
  return 0;
}


static int string_query (lua_State *L) {
  stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
  int s = luaL_opt_int(L, 2, 0) - 1;
  if (s==-1) {
    lua_pushnumber(L ,tb->nuse);
    lua_pushnumber(L ,tb->size);
    return 2;
  }
  else if (s < tb->size) {
    TString *ts;
    int n = 0;
    for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
      ttype(L->top) = LUA_TSTRING;
      tsvalue(L->top) = ts;
      incr_top;
      n++;
    }
    return n;
  }
  return 0;
}


static int tref (lua_State *L) {
  luaL_checkany(L, 1);
  lua_pushvalue(L, 1);
  lua_pushnumber(L, lua_ref(L, luaL_opt_int(L, 2, 1)));
  return 1;
}

static int getref (lua_State *L) {
  if (lua_getref(L, luaL_check_int(L, 1)))
    return 1;
  else
    return 0;
}

static int unref (lua_State *L) {
  lua_unref(L, luaL_check_int(L, 1));
  return 0;
}

static int newuserdata (lua_State *L) {
  if (lua_isnumber(L, 2))
    lua_pushusertag(L, (void *)luaL_check_int(L, 1), luaL_check_int(L, 2));
  else
    lua_newuserdata(L, luaL_check_int(L, 1));
  return 1;
}

static int udataval (lua_State *L) {
  luaL_checktype(L, 1, LUA_TUSERDATA);
  lua_pushnumber(L, (int)lua_touserdata(L, 1));
  return 1;
}

static int newstate (lua_State *L) {
  lua_State *L1 = lua_open(luaL_check_int(L, 1));
  if (L1)
    lua_pushuserdata(L, L1);
  else
    lua_pushnil(L);
  return 1;
}

static int loadlib (lua_State *L) {
  lua_State *L1 = (lua_State *)lua_touserdata(L, 1);
  switch (*luaL_check_string(L, 2)) {
    case 'm': lua_mathlibopen(L1); break;
    case 's': lua_strlibopen(L1); break;
    case 'i': lua_iolibopen(L1); break;
    case 'd': lua_dblibopen(L1); break;
    case 'b': lua_baselibopen(L1); break;
    default: luaL_argerror(L, 2, "invalid option");
  }
  return 0;
}

static int closestate (lua_State *L) {
  luaL_checktype(L, 1, LUA_TUSERDATA);
  lua_close((lua_State *)lua_touserdata(L, 1));
  return 0;
}

static int doremote (lua_State *L) {
  lua_State *L1;
  const char *code = luaL_check_string(L, 2);
  int status;
  luaL_checktype(L, 1, LUA_TUSERDATA);
  L1 = (lua_State *)lua_touserdata(L, 1);
  status = lua_dostring(L1, code);
  if (status != 0) {
    lua_pushnil(L);
    lua_pushnumber(L, status);
    return 2;
  }
  else {
    int i = 0;
    while (!lua_isnull(L1, ++i))
      lua_pushstring(L, lua_tostring(L1, i));
    return i-1;
  }
}

static int settagmethod (lua_State *L) {
  int tag = luaL_check_int(L, 1);
  const char *event = luaL_check_string(L, 2);
  luaL_checkany(L, 3);
  lua_gettagmethod(L, tag, event);
  lua_pushvalue(L, 3);
  lua_settagmethod(L, tag, event);
  return 1;
}

static int pushbool (lua_State *L, int b) {
  if (b) lua_pushnumber(L, 1);
  else lua_pushnil(L);
  return 1;
}

static int equal (lua_State *L) {
  return pushbool(L, lua_equal(L, 1, 2));
}

  

/*
** {======================================================
** function to test the API with C. It interprets a kind of "assembler"
** language with calls to the API, so the test can be driven by Lua code
** =======================================================
*/

static const char *const delimits = " \t\n,;";

static void skip (const char **pc) {
  while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
}

static int getnum (lua_State *L, const char **pc) {
  int res = 0;
  int sig = 1;
  skip(pc);
  if (**pc == '.') {
    res = (int)lua_tonumber(L, -1);
    lua_pop(L, 1);
    (*pc)++;
    return res;
  }
  else if (**pc == '-') {
    sig = -1;
    (*pc)++;
  }
  while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
  return sig*res;
}
  
static const char *getname (char *buff, const char **pc) {
  int i = 0;
  skip(pc);
  while (**pc != '\0' && !strchr(delimits, **pc))
    buff[i++] = *(*pc)++;
  buff[i] = '\0';
  return buff;
}


#define EQ(s1)	(strcmp(s1, inst) == 0)

#define getnum	((getnum)(L, &pc))
#define getname	((getname)(buff, &pc))


static int testC (lua_State *L) {
  char buff[30];
  const char *pc = luaL_check_string(L, 1);
  for (;;) {
    const char *inst = getname;
    if EQ("") return 0;
    else if EQ("isnumber") {
      lua_pushnumber(L, lua_isnumber(L, getnum));
    }
    else if EQ("isstring") {
      lua_pushnumber(L, lua_isstring(L, getnum));
    }
    else if EQ("istable") {
      lua_pushnumber(L, lua_istable(L, getnum));
    }
    else if EQ("iscfunction") {
      lua_pushnumber(L, lua_iscfunction(L, getnum));
    }
    else if EQ("isfunction") {
      lua_pushnumber(L, lua_isfunction(L, getnum));
    }
    else if EQ("isuserdata") {
      lua_pushnumber(L, lua_isuserdata(L, getnum));
    }
    else if EQ("isnil") {
      lua_pushnumber(L, lua_isnil(L, getnum));
    }
    else if EQ("isnull") {
      lua_pushnumber(L, lua_isnull(L, getnum));
    }
    else if EQ("tonumber") {
      lua_pushnumber(L, lua_tonumber(L, getnum));
    }
    else if EQ("tostring") {
      lua_pushstring(L, lua_tostring(L, getnum));
    }
    else if EQ("tonumber") {
      lua_pushnumber(L, lua_tonumber(L, getnum));
    }
    else if EQ("strlen") {
      lua_pushnumber(L, lua_strlen(L, getnum));
    }
    else if EQ("tocfunction") {
      lua_pushcfunction(L, lua_tocfunction(L, getnum));
    }
    else if EQ("return") {
      return getnum;
    }
    else if EQ("gettop") {
      lua_pushnumber(L, lua_gettop(L));
    }
    else if EQ("settop") {
      lua_settop(L, getnum);
    }
    else if EQ("pop") {
      lua_pop(L, getnum);
    }
    else if EQ("pushnum") {
      lua_pushnumber(L, getnum);
    }
    else if EQ("pushvalue") {
      lua_pushvalue(L, getnum);
    }
    else if EQ("remove") {
      lua_remove(L, getnum);
    }
    else if EQ("insert") {
      lua_insert(L, getnum);
    }
    else if EQ("gettable") {
      lua_gettable(L, getnum);
    }
    else if EQ("settable") {
      lua_settable(L, getnum);
    }
    else if EQ("next") {
      lua_next(L, -2);
    }
    else if EQ("concat") {
      lua_concat(L, getnum);
    }
    else if EQ("rawcall") {
      int narg = getnum;
      int nres = getnum;
      lua_rawcall(L, narg, nres);
    }
    else if EQ("call") {
      int narg = getnum;
      int nres = getnum;
      lua_call(L, narg, nres);
    }
    else if EQ("dostring") {
      lua_dostring(L, luaL_check_string(L, getnum));
    }
    else if EQ("settagmethod") {
      int tag = getnum;
      const char *event = getname;
      lua_settagmethod(L, tag, event);
    }
    else if EQ("gettagmethod") {
      int tag = getnum;
      const char *event = getname;
      lua_gettagmethod(L, tag, event);
    }
    else if EQ("type") {
      lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
    }
    else luaL_verror(L, "unknown instruction %.30s", buff);
  }
  return 0;
}

/* }====================================================== */



static const struct luaL_reg tests_funcs[] = {
  {"hash", hash_query},
  {"limits", get_limits},
  {"listcode", listcode},
  {"liststrings", liststrings},
  {"listlocals", listlocals},
  {"loadlib", loadlib},
  {"querystr", string_query},
  {"querytab", table_query},
  {"testC", testC},
  {"ref", tref},
  {"getref", getref},
  {"unref", unref},
  {"newuserdata", newuserdata},
  {"udataval", udataval},
  {"newstate", newstate},
  {"closestate", closestate},
  {"doremote", doremote},
  {"settagmethod", settagmethod},
  {"equal", equal},
  {"totalmem", mem_query}
};


void luaB_opentests (lua_State *L) {
  lua_newtable(L);
  lua_getglobals(L);
  lua_pushvalue(L, -2);
  lua_setglobals(L);
  luaL_openl(L, tests_funcs);  /* open functions inside new table */
  lua_setglobals(L);  /* restore old table of globals */
  lua_setglobal(L, "T");  /* set new table as global T */
}

#endif
tome-235-src/src/lua/typedef.lua0000644000076400017500000000261611012107763014406 0ustar  dgdg-- tolua: typedef class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: typedef.lua,v 1.2 2001/11/26 23:00:27 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 



-- Typedef class
-- Represents a type synonym.
-- The 'de facto' type replaces the typedef before the
-- remaining code is parsed.
-- The following fields are stored:
--   utype = typedef name
--   type = 'de facto' type
--   mod = modifiers to the 'de facto' type
classTypedef = {
 utype = '',
 mod = '',
 type = ''
}

-- Print method
function classTypedef:print (ident,close)
 print(ident.."Typedef{")
 print(ident.." utype = '"..self.utype.."',")
 print(ident.." mod = '"..self.mod.."',")
 print(ident.." type = '"..self.type.."',")
 print(ident.."}"..close)
end

-- Internal constructor
function _Typedef (t)
 t._base = classTypedef
 settag(t,tolua_tag)
 appendtypedef(t)
 return t
end

-- Constructor
-- Expects one string representing the type definition.
function Typedef (s)
 if strfind(s,'[%*&]') then
  tolua_error("#invalid typedef: pointers (and references) are not supported")
 end
 local t = split(gsub(s,"%s%s*"," ")," ")
 return _Typedef {
  utype = t[t.n],
  type = t[t.n-1],
  mod = concat(t,1,t.n-2)
 }
end


tome-235-src/src/lua/container.lua0000644000076400017500000001413611012107763014730 0ustar  dgdg-- tolua: container abstract class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: container.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Container class
-- Represents a container of features to be bound
-- to lua.
classContainer = 
{
 curr = nil,
 _base = classFeature,
}
settag(classContainer,tolua_tag)

-- output tags
function classContainer:decltag ()
 push(self)
 local i=1
 while self[i] do
  self[i]:decltag()
  i = i+1
 end
 pop()
end


-- write support code
function classContainer:supcode ()
 push(self)
 local i=1
 while self[i] do
  self[i]:supcode()
  i = i+1
 end
 pop()
end


-- Internal container constructor
function _Container (self)
 self._base = classContainer
 settag(self,tolua_tag)
 self.n = 0
 self.typedefs = {n=0}
 self.lnames = {}
 return self
end

-- push container
function push (t)
 classContainer.curr = t
end

-- pop container
function pop ()
 classContainer.curr = classContainer.curr.parent
end

-- append to current container
function append (t)
 return classContainer.curr:append(t)
end
 
-- append typedef to current container
function appendtypedef (t)
 return classContainer.curr:appendtypedef(t)
end
 
-- substitute typedef
function findtypedef (type)
 return classContainer.curr:findtypedef(type)
end

-- check if is typedef
function istypedef (type)
 return classContainer.curr:istypedef(type)
end

-- append feature to container
function classContainer:append (t)
 self.n = self.n + 1
 self[self.n] = t
 t.parent = self
end

-- append typedef 
function classContainer:appendtypedef (t)
 self.typedefs.n = self.typedefs.n + 1
 self.typedefs[self.typedefs.n] = t
end

-- determine lua function name overload
function classContainer:overload (lname)
 if not self.lnames[lname] then 
  self.lnames[lname] = 0
 else
  self.lnames[lname] = self.lnames[lname] + 1
 end
 return format("%02d",self.lnames[lname])
end

function classContainer:findtypedef (type)
 local env = self
 while env do
  if env.typedefs then
   local i=1
   while env.typedefs[i] do
    if env.typedefs[i].utype == type then
	 local mod1,type1 = env.typedefs[i].mod,env.typedefs[i].type
         local mod2,type2 = findtypedef(type1)
         return mod2..' '..mod1,type2
	end
	i = i+1
   end
  end
  env = env.parent
 end
 return '',type
end 

function classContainer:istypedef (type)
 local env = self
 while env do
  if env.typedefs then
   local i=1
   while env.typedefs[i] do
    if env.typedefs[i].utype == type then
         return 1
        end
        i = i+1
   end
  end
  env = env.parent
 end
 return nil 
end

-- parse chunk
function classContainer:doparse (s)

 -- try module
 do
  local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Module(name,body)
   return strsub(s,e+1)
  end
 end

 -- try define
 do
  local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Define(name)
   return strsub(s,e+1)
  end
 end

 -- try enumerates
 do
  local b,e,body = strfind(s,"^%s*enum[^{]*(%b{})%s*;?%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Enumerate(body)
   return strsub(s,e+1)
  end
 end

 do
  local b,e,body,name = strfind(s,"^%s*typedef%s%s*enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Enumerate(body)
   Typedef("int "..name)
   return strsub(s,e+1)
  end
 end

 -- try operator 
 do
  local b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&]*operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Operator(decl,kind,arg,const)
   return strsub(s,e+1)
  end
 end

 -- try function
 do
  local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")
  if not b then
   -- try a single letter function name
   b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
  end
  if b then
   _curr_code = strsub(s,b,e)
   Function(decl,arg,const)
   return strsub(s,e+1)
  end
 end

 -- try inline function
 do
  local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*%b{}%s*")
  if not b then
   -- try a single letter function name
   b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*%b{}%s*")
  end
  if b then
   _curr_code = strsub(s,b,e)
   Function(decl,arg,const)
   return strsub(s,e+1)
  end
 end

 -- try class
 do
  local b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w]*)%s*(.-)%s*(%b{})%s*;%s*")
  if not b then
   b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w]*)%s*(.-)%s*(%b{})%s*;%s*")
   if not b then
    base = ''
    b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w]*)%s*;%s*")
   end
  end
  if b then
   if base ~= '' then 
    local b,e
	b,e,base = strfind(base,".-([_%w][_%w]*)$") 
   end
   _curr_code = strsub(s,b,e)
   Class(name,base,body)
   return strsub(s,e+1)
  end
 end

 -- try typedef
 do
  local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Typedef(types)
   return strsub(s,e+1)
  end
 end

 -- try variable
 do
  local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&]*[_%w%d])%s*;%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Variable(decl)
   return strsub(s,e+1)
  end
 end

 -- try array
 do
  local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&%-%>]*[]_%w%d])%s*;%s*")
  if b then
   _curr_code = strsub(s,b,e)
   Array(decl)
   return strsub(s,e+1)
  end
 end

 -- try code
 do
  local b,e,code = strfind(s,"^%s*(%b\1\2)")
  if b then
   Code(strsub(code,2,-2))
   return strsub(s,e+1)
  end 
 end 

 -- try verbatim
 do
  local b,e,line = strfind(s,"^%s*%$(.-\n)")
  if b then
   Verbatim(line)
   return strsub(s,e+1)
  end 
 end 

 -- no matching
 if gsub(s,"%s%s*","") ~= "" then
  _curr_code = s
  error("#parse error")
 else
  return ""
 end
end

function classContainer:parse (s)
 while s ~= '' do
  s = self:doparse(s)
 end
end


tome-235-src/src/lua/array.lua0000644000076400017500000001330111012107763014055 0ustar  dgdg-- tolua: array class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1999
-- $Id: array.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Array class
-- Represents a extern array variable or a public member of a class.
-- Stores all fields present in a declaration.
classArray = {
 _base = classDeclaration,
}

settag(classArray,tolua_tag)

-- Print method
function classArray:print (ident,close)
 print(ident.."Array{")
 print(ident.." mod  = '"..self.mod.."',")
 print(ident.." type = '"..self.type.."',")
 print(ident.." ptr  = '"..self.ptr.."',")
 print(ident.." name = '"..self.name.."',")
 print(ident.." def  = '"..self.def.."',")
 print(ident.." dim  = '"..self.dim.."',")
 print(ident.." ret  = '"..self.ret.."',")
 print(ident.."}"..close)
end

-- get variable value
function classArray:getvalue (class,static)
 if class and static then
  return class..'::'..self.name..'[toluaI_index]'
 elseif class then
  return 'self->'..self.name..'[toluaI_index]'
 else
  return self.name..'[toluaI_index]'
 end
end

-- Write binding functions
function classArray:supcode ()
 local class = self:inclass()

 -- get function ------------------------------------------------
 if class then
  output("/* get function:",self.name," of class ",class," */")
 else
  output("/* get function:",self.name," */")
 end
 self.cgetname = self:cfuncname("toluaI_get")
 output("static int",self.cgetname,"(lua_State* tolua_S)") 
 output("{")

 -- declare index
 output(' int toluaI_index;')

 -- declare self, if the case
 local _,_,static = strfind(self.mod,'^%s*(static)')
 if class and static==nil then
  output(' ',class,'*','self;')
  output(' lua_pushstring(tolua_S,".self");')
  output(' lua_rawget(tolua_S,1);')
  output(' self = ')
  output('(',class,'*) ')
  output('lua_touserdata(tolua_S,-1);')
 elseif static then
  _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
 end

 -- check index
 output(' if (!tolua_istype(tolua_S,2,LUA_TNUMBER,0))')
 output('  tolua_error(tolua_S,"invalid type in array indexing.");')
 output(' toluaI_index = (int)tolua_getnumber(tolua_S,2,0)-1;')
 output(' if (toluaI_index<0 || toluaI_index>='..self.dim..')')
 output('  tolua_error(tolua_S,"array indexing out of range.");')

 -- return value
 local t,ct = isbasic(self.type)
 if t then
  output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
 else
  if self.ptr == '&' or self.ptr == '' then
   output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',',self.tag,');')
  else
   output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',',self.tag,');')
  end
 end
 output(' return 1;')
 output('}')
 output('\n')

 -- set function ------------------------------------------------
 if not strfind(self.mod,'const') then
  if class then
   output("/* set function:",self.name," of class ",class," */")
  else
   output("/* set function:",self.name," */")
  end
  self.csetname = self:cfuncname("toluaI_set")
  output("static int",self.csetname,"(lua_State* tolua_S)")
  output("{")

  -- declare index
  output(' int toluaI_index;')

  -- declare self, if the case
  local _,_,static = strfind(self.mod,'^%s*(static)')
  if class and static==nil then
   output(' ',class,'*','self;')
   output(' lua_pushstring(tolua_S,".self");')
   output(' lua_rawget(tolua_S,1);')
   output(' self = ')
   output('(',class,'*) ')
   output('lua_touserdata(tolua_S,-1);')
  elseif static then
   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
  end
 
  -- check index
  output(' if (!tolua_istype(tolua_S,2,LUA_TNUMBER,0))')
  output('  tolua_error(tolua_S,"invalid type in array indexing.");')
  output(' toluaI_index = (int)tolua_getnumber(tolua_S,2,0)-1;')
  output(' if (toluaI_index<0 || toluaI_index>='..self.dim..')')
  output('  tolua_error(tolua_S,"array indexing out of range.");')

  -- assign value
  local ptr = ''
  if self.ptr~='' then ptr = '*' end
  output(' ')
  if class and static then
   output(class..'::'..self.name..'[toluaI_index]')
  elseif class then
   output('self->'..self.name..'[toluaI_index]')
  else
   output(self.name..'[toluaI_index]')
  end
  local t = isbasic(self.type)
  output(' = ')
  if not t and ptr=='' then output('*') end
  output('((',self.mod,self.type)
  if not t then
   output('*')
  end
  output(') ')
  local def = 0
  if self.def ~= '' then def = self.def end
  if t then
   output('tolua_get'..t,'(tolua_S,3,',def,'));')
  else
   output('tolua_getusertype(tolua_S,3,',def,'));')
  end
  output(' return 0;')
  output('}')
  output('\n')
 end 

end

function classArray:register ()
 local parent = self:inclass() or self:inmodule()
 if parent then
  if self.csetname then
   output(' tolua_tablearray(tolua_S,"'..parent..'","'..self.lname..'",'..self.cgetname..','..self.csetname..');')
  else
   output(' tolua_tablearray(tolua_S,"'..parent..'","'..self.lname..'",'..self.cgetname..',NULL);')
  end
 else
  if self.csetname then
   output(' tolua_globalarray(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
  else
   output(' tolua_globalarray(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
  end
 end
end

function classArray:unregister ()
 if self:inclass()==nil and self:inmodule()==nil then
  output(' lua_pushnil(tolua_S); lua_setglobal(tolua_S,"'..self.lname..'");') 
 end
end 
 

-- Internal constructor
function _Array (t)
 t._base = classArray
 settag(t,tolua_tag)
 append(t)
 return t
end

-- Constructor
-- Expects a string representing the variable declaration.
function Array (s)
 return _Array (Declaration(s,'var'))
end


tome-235-src/src/lua/lstate.c0000644000076400017500000000621411012107763013701 0ustar  dgdg/*
** $Id: lstate.c,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** Global State
** See Copyright Notice in lua.h
*/


#include 

#include "lua.h"

#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"


#ifdef LUA_DEBUG
static lua_State *lua_state = NULL;
void luaB_opentests (lua_State *L);
#endif


/*
** built-in implementation for ERRORMESSAGE. In a "correct" environment
** ERRORMESSAGE should have an external definition, and so this function
** would not be used.
*/
static int errormessage (lua_State *L) {
  const char *s = lua_tostring(L, 1);
  if (s == NULL) s = "(no message)";
  fprintf(stderr, "error: %s\n", s);
  return 0;
}


/*
** open parts that may cause memory-allocation errors
*/
static void f_luaopen (lua_State *L, void *ud) {
  int stacksize = *(int *)ud;
  if (stacksize == 0)
    stacksize = DEFAULT_STACK_SIZE;
  else
    stacksize += LUA_MINSTACK;
  L->gt = luaH_new(L, 10);  /* table of globals */
  luaD_init(L, stacksize);
  luaS_init(L);
  luaX_init(L);
  luaT_init(L);
  lua_newtable(L);
  lua_ref(L, 1);  /* create registry */
  lua_register(L, LUA_ERRORMESSAGE, errormessage);
#ifdef LUA_DEBUG
  luaB_opentests(L);
  if (lua_state == NULL) lua_state = L;  /* keep first state to be opened */
#endif
  LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack");
}


LUA_API lua_State *lua_open (int stacksize) {
  lua_State *L = luaM_new(NULL, lua_State);
  if (L == NULL) return NULL;  /* memory allocation error */
  L->stack = NULL;
  L->strt.size = L->udt.size = 0;
  L->strt.nuse = L->udt.nuse = 0;
  L->strt.hash = NULL;
  L->udt.hash = NULL;
  L->Mbuffer = NULL;
  L->Mbuffsize = 0;
  L->rootproto = NULL;
  L->rootcl = NULL;
  L->roottable = NULL;
  L->TMtable = NULL;
  L->last_tag = -1;
  L->refArray = NULL;
  L->refSize = 0;
  L->refFree = NONEXT;
  L->nblocks = sizeof(lua_State);
  L->GCthreshold = MAX_INT;  /* to avoid GC during pre-definitions */
  L->callhook = NULL;
  L->linehook = NULL;
  L->allowhooks = 1;
  L->errorJmp = NULL;
  if (luaD_runprotected(L, f_luaopen, &stacksize) != 0) {
    /* memory allocation error: free partial state */
    lua_close(L);
    return NULL;
  }
  L->GCthreshold = 2*L->nblocks;
  return L;
}


LUA_API void lua_close (lua_State *L) {
  LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack");
  luaC_collect(L, 1);  /* collect all elements */
  LUA_ASSERT(L->rootproto == NULL, "list should be empty");
  LUA_ASSERT(L->rootcl == NULL, "list should be empty");
  LUA_ASSERT(L->roottable == NULL, "list should be empty");
  luaS_freeall(L);
  if (L->stack)
    L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject);
  luaM_free(L, L->stack);
  L->nblocks -= (L->last_tag+1)*sizeof(struct TM);
  luaM_free(L, L->TMtable);
  L->nblocks -= (L->refSize)*sizeof(struct Ref);
  luaM_free(L, L->refArray);
  L->nblocks -= (L->Mbuffsize)*sizeof(char);
  luaM_free(L, L->Mbuffer);
  LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks");
  luaM_free(L, L);
  LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
  LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!");
}

tome-235-src/src/lua/lstate.h0000644000076400017500000000350211012107763013703 0ustar  dgdg/*
** $Id: lstate.h,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** Global State
** See Copyright Notice in lua.h
*/

#ifndef lstate_h
#define lstate_h

#include "lobject.h"
#include "lua.h"
#include "luadebug.h"



typedef TObject *StkId;  /* index to stack elements */


/*
** marks for Reference array
*/
#define NONEXT          -1      /* to end the free list */
#define HOLD            -2
#define COLLECTED       -3
#define LOCK            -4


struct Ref {
  TObject o;
  int st;  /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
};


struct lua_longjmp;  /* defined in ldo.c */
struct TM;  /* defined in ltm.h */


typedef struct stringtable {
  int size;
  lint32 nuse;  /* number of elements */
  TString **hash;
} stringtable;



struct lua_State {
  /* thread-specific state */
  StkId top;  /* first free slot in the stack */
  StkId stack;  /* stack base */
  StkId stack_last;  /* last free slot in the stack */
  int stacksize;
  StkId Cbase;  /* base for current C function */
  struct lua_longjmp *errorJmp;  /* current error recover point */
  char *Mbuffer;  /* global buffer */
  size_t Mbuffsize;  /* size of Mbuffer */
  /* global state */
  Proto *rootproto;  /* list of all prototypes */
  Closure *rootcl;  /* list of all closures */
  Hash *roottable;  /* list of all tables */
  stringtable strt;  /* hash table for strings */
  stringtable udt;   /* hash table for udata */
  Hash *gt;  /* table for globals */
  struct TM *TMtable;  /* table for tag methods */
  int last_tag;  /* last used tag in TMtable */
  struct Ref *refArray;  /* locked objects */
  int refSize;  /* size of refArray */
  int refFree;  /* list of free positions in refArray */
  unsigned long GCthreshold;
  unsigned long nblocks;  /* number of `bytes' currently allocated */
  lua_Hook callhook;
  lua_Hook linehook;
  int allowhooks;
};


#endif

tome-235-src/src/lua/tolua.c0000644000076400017500000000655211012107763013536 0ustar  dgdg/* tolua
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua.c,v 1.4 2004/06/04 13:42:10 neil Exp $
*/

/* This code is free software; you can redistribute it and/or modify it. 
** The software provided hereunder is on an "as is" basis, and 
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications. 
*/

#include "tolua.h"
#include "lua.h"
#include "lualib.h"

#include 
#include 
#include 


static void help (void)
{
 fprintf(stderr,"\n"
         "usage: tolua [options] input_file\n"
         "\n"
         "Command line options are:\n"
         "  -v       : print version information.\n"
         "  -o  file : set output file; default is stdout.\n"
         "  -H  file : create include file.\n"
         "  -n  name : set package name; default is input file root name.\n"
         "  -p       : parse only.\n"
         "  -P       : parse and print structure information (for debug).\n"
         "  -h       : print this message.\n"
         "Should the input file be omitted, stdin is assumed;\n"
         "in that case, the package name must be explicitly set.\n\n" 
        );
}

static void version (void)
{
 fprintf(stderr, "%s (written by W. Celes)\n",TOLUA_VERSION);
}

static void setfield (lua_State* L, int table, char* f, char* v)
{
 lua_pushstring(L,f);
 lua_pushstring(L,v);
 lua_settable(L,table);
}

static void error (char* o)
{
 fprintf(stderr,"tolua: unknown option '%s'\n",o);
 help();
 exit(1);
}

int main (int argc, char* argv[])
{
 lua_State* L = lua_open(0);
 lua_baselibopen(L);
 lua_iolibopen(L);
 lua_strlibopen(L);
 lua_pushstring(L,TOLUA_VERSION); lua_setglobal(L,"TOLUA_VERSION");

 if (argc==1)
 {
  help();
  return 0;
 }
 else
 {
  int i, t;
  lua_newtable(L);
  lua_pushvalue(L,-1);
  lua_setglobal(L,"flags");
  t = lua_gettop(L);
  for (i=1; i		/* NULL, malloc, free */

#ifdef __cplusplus
extern "C" {
#endif

#include "lua.h"


/*************************************** Exported functions */

int   tolua_open (lua_State* L);
void  tolua_using (lua_State* L, int module);
void  tolua_class (lua_State* L, int derived, int base);
void  tolua_instance (lua_State* L, int instance, int classobj);
void  tolua_foreach (lua_State* L, int lo, int f);
int   tolua_tag (lua_State* L, char* type);
const char* tolua_type (lua_State* L, int lo);
int   tolua_base (lua_State* L, int lo);
int   tolua_cast (lua_State* L, int lo, char* type);
void  tolua_takeownership (lua_State* L, int lo);



/*************************************** Support functions for binding code */

#define LUA_VALUE int
#define LUA_NIL 0 /* TODO */
/*#define TOLUA_NIL	(lua_pushnil(),lua_pop())*/

/* Register functions */
void tolua_globalvar (lua_State* L, char* name, lua_CFunction get, lua_CFunction set);
void tolua_globalarray (lua_State* L, char* name, lua_CFunction get, lua_CFunction set);
void tolua_module (lua_State* L, char* name);
void tolua_cclass (lua_State* L, char* name, char* base);
void tolua_function (lua_State* L, char* parent, char* name, lua_CFunction func);
void tolua_constant (lua_State* L, char* parent, char* name, long value);
void tolua_tablevar
(lua_State* L, char* table, char* name, lua_CFunction get, lua_CFunction set);
void tolua_tablearray
(lua_State* L, char* table, char* name, lua_CFunction get, lua_CFunction set);


/* Get and push functions */
long tolua_getnumber (lua_State* L, int narg, long def);
const char* tolua_getstring (lua_State* L, int narg, const char* def);
void* tolua_getuserdata (lua_State* L, int narg, void* def);
void* tolua_getusertype (lua_State* L, int narg, void* def);
int   tolua_getvalue (lua_State* L, int narg, int def);
int   tolua_getbool (lua_State* L, int narg, int def);
long tolua_getfieldnumber (lua_State* L, int lo, int index, long def);
const char* tolua_getfieldstring (lua_State* L, int lo, int index, const char* def);
void* tolua_getfielduserdata (lua_State* L, int lo, int index, void* def);
void* tolua_getfieldusertype (lua_State* L, int lo, int index, void* def);
int tolua_getfieldvalue (lua_State* L, int lo, int index, int def);
int tolua_getfieldbool (lua_State* L, int lo, int index, int def);

void tolua_pushnumber (lua_State* L, long value);
void tolua_pushstring (lua_State* L, const char* value);
void tolua_pushuserdata (lua_State* L, void* value);
void tolua_pushusertype (lua_State* L, void* value, int tag);
void tolua_pushvalue (lua_State* L, int lo);
void tolua_pushbool (lua_State* L, int value);
void tolua_pushfieldnumber (lua_State* L, int lo, int index, long v);
void tolua_pushfieldstring (lua_State* L, int lo, int index, char* v);
void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v);
void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, int tag);
void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v);
void tolua_pushfieldbool (lua_State* L, int lo, int index, int v);


/* Type & tag manipulation */
void tolua_usertype (lua_State* L, char* type);
#if 0
void tolua_settag (lua_State* L, char* type, int* tag);
#endif
int  tolua_istype (lua_State* L, int narg, int tag, int dim);
int  tolua_arrayistype (lua_State* L, int narg, int tag, int dim, int def);

int  tolua_isnoobj (lua_State* L, int narg);

/* Tag method manipulation */
void* tolua_doclone (lua_State* L, void* value, int tag);
void* tolua_copy (lua_State* L, void* value, unsigned int size);

/* Error handling */
void tolua_error (lua_State* L, char* msg);

/* Exported variables */
extern int tolua_tag_nil;
extern int tolua_tag_number;
extern int tolua_tag_string;
extern int tolua_tag_userdata;
extern int tolua_tag_table;
extern int tolua_tag_function;

#ifdef __cplusplus
}
#endif

#endif 

tome-235-src/src/lua/lapi.c0000644000076400017500000002532211012107763013333 0ustar  dgdg/*
** $Id: lapi.c,v 1.3 2001/11/26 23:00:23 darkgod Exp $
** Lua API
** See Copyright Notice in lua.h
*/


#include 

#include "lua.h"

#include "lapi.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"


const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
                               "$Authors: " LUA_AUTHORS " $";



#define Index(L,i)	((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))

#define api_incr_top(L)	incr_top




TObject *luaA_index (lua_State *L, int index) {
  return Index(L, index);
}


static TObject *luaA_indexAcceptable (lua_State *L, int index) {
  if (index >= 0) {
    TObject *o = L->Cbase+(index-1);
    if (o >= L->top) return NULL;
    else return o;
  }
  else return L->top+index;
}


void luaA_pushobject (lua_State *L, const TObject *o) {
  *L->top = *o;
  incr_top;
}

LUA_API int lua_stackspace (lua_State *L) {
  return (L->stack_last - L->top);
}



/*
** basic stack manipulation
*/


LUA_API int lua_gettop (lua_State *L) {
  return (L->top - L->Cbase);
}


LUA_API void lua_settop (lua_State *L, int index) {
  if (index >= 0)
    luaD_adjusttop(L, L->Cbase, index);
  else
    L->top = L->top+index+1;  /* index is negative */
}


LUA_API void lua_remove (lua_State *L, int index) {
  StkId p = luaA_index(L, index);
  while (++p < L->top) *(p-1) = *p;
  L->top--;
}


LUA_API void lua_insert (lua_State *L, int index) {
  StkId p = luaA_index(L, index);
  StkId q;
  for (q = L->top; q>p; q--)
    *q = *(q-1);
  *p = *L->top;
}


LUA_API void lua_pushvalue (lua_State *L, int index) {
  *L->top = *luaA_index(L, index);
  api_incr_top(L);
}



/*
** access functions (stack -> C)
*/


LUA_API int lua_type (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL) ? LUA_TNONE : ttype(o);
}

LUA_API const char *lua_typename (lua_State *L, int t) {
  UNUSED(L);
  return (t == LUA_TNONE) ? "no value" : luaO_typenames[t];
}


LUA_API int lua_iscfunction (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL) ? 0 : iscfunction(o);
}

LUA_API int lua_isnumber (lua_State *L, int index) {
  TObject *o = luaA_indexAcceptable(L, index);
  return (o == NULL) ? 0 : (tonumber(o) == 0);
}

LUA_API int lua_isstring (lua_State *L, int index) {
  int t = lua_type(L, index);
  return (t == LUA_TSTRING || t == LUA_TNUMBER);
}


LUA_API int lua_tag (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL) ? LUA_NOTAG : luaT_tag(o);
}

LUA_API int lua_equal (lua_State *L, int index1, int index2) {
  StkId o1 = luaA_indexAcceptable(L, index1);
  StkId o2 = luaA_indexAcceptable(L, index2);
  if (o1 == NULL || o2 == NULL) return 0;  /* index out-of-range */
  else return luaO_equalObj(o1, o2);
}

LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
  StkId o1 = luaA_indexAcceptable(L, index1);
  StkId o2 = luaA_indexAcceptable(L, index2);
  if (o1 == NULL || o2 == NULL) return 0;  /* index out-of-range */
  else return luaV_lessthan(L, o1, o2, L->top);
}



LUA_API long lua_tonumber (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL || tonumber(o)) ? 0 : nvalue(o);
}

LUA_API const char *lua_tostring (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL || tostring(L, o)) ? NULL : svalue(o);
}

LUA_API size_t lua_strlen (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len;
}

LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c;
}

LUA_API void *lua_touserdata (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL :
                                                    tsvalue(o)->u.d.value;
}

LUA_API const void *lua_topointer (lua_State *L, int index) {
  StkId o = luaA_indexAcceptable(L, index);
  if (o == NULL) return NULL;
  switch (ttype(o)) {
    case LUA_TTABLE: 
      return hvalue(o);
    case LUA_TFUNCTION:
      return clvalue(o);
    default: return NULL;
  }
}



/*
** push functions (C -> stack)
*/


LUA_API void lua_pushnil (lua_State *L) {
  ttype(L->top) = LUA_TNIL;
  api_incr_top(L);
}


LUA_API void lua_pushnumber (lua_State *L, long n) {
  nvalue(L->top) = n;
  ttype(L->top) = LUA_TNUMBER;
  api_incr_top(L);
}


LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
  tsvalue(L->top) = luaS_newlstr(L, s, len);
  ttype(L->top) = LUA_TSTRING;
  api_incr_top(L);
}


LUA_API void lua_pushstring (lua_State *L, const char *s) {
  if (s == NULL)
    lua_pushnil(L);
  else
    lua_pushlstring(L, s, strlen(s));
}


LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
  luaV_Cclosure(L, fn, n);
}


LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
  /* ORDER LUA_T */
  if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(tag)))
    luaO_verror(L, "invalid tag for a userdata (%d)", tag);
  tsvalue(L->top) = luaS_createudata(L, u, tag);
  ttype(L->top) = LUA_TUSERDATA;
  api_incr_top(L);
}



/*
** get functions (Lua -> stack)
*/


LUA_API void lua_getglobal (lua_State *L, const char *name) {
  StkId top = L->top;
  *top = *luaV_getglobal(L, luaS_new(L, name));
  L->top = top;
  api_incr_top(L);
}


LUA_API void lua_gettable (lua_State *L, int index) {
  StkId t = Index(L, index);
  StkId top = L->top;
  *(top-1) = *luaV_gettable(L, t);
  L->top = top;  /* tag method may change top */
}


LUA_API void lua_rawget (lua_State *L, int index) {
  StkId t = Index(L, index);
  LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
  *(L->top - 1) = *luaH_get(L, hvalue(t), L->top - 1);
}


LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
  StkId o = Index(L, index);
  LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
  *L->top = *luaH_getnum(hvalue(o), n);
  api_incr_top(L);
}


LUA_API void lua_getglobals (lua_State *L) {
  hvalue(L->top) = L->gt;
  ttype(L->top) = LUA_TTABLE;
  api_incr_top(L);
}


LUA_API int lua_getref (lua_State *L, int ref) {
  if (ref == LUA_REFNIL)
    ttype(L->top) = LUA_TNIL;
  else if (0 <= ref && ref < L->refSize &&
          (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
    *L->top = L->refArray[ref].o;
  else
    return 0;
  api_incr_top(L);
  return 1;
}


LUA_API void lua_newtable (lua_State *L) {
  hvalue(L->top) = luaH_new(L, 0);
  ttype(L->top) = LUA_TTABLE;
  api_incr_top(L);
}



/*
** set functions (stack -> Lua)
*/


LUA_API void lua_setglobal (lua_State *L, const char *name) {
  StkId top = L->top;
  luaV_setglobal(L, luaS_new(L, name));
  L->top = top-1;  /* remove element from the top */
}


LUA_API void lua_settable (lua_State *L, int index) {
  StkId t = Index(L, index);
  StkId top = L->top;
  luaV_settable(L, t, top-2);
  L->top = top-2;  /* pop index and value */
}


LUA_API void lua_rawset (lua_State *L, int index) {
  StkId t = Index(L, index);
  LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
  *luaH_set(L, hvalue(t), L->top-2) = *(L->top-1);
  L->top -= 2;
}


LUA_API void lua_rawseti (lua_State *L, int index, int n) {
  StkId o = Index(L, index);
  LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
  *luaH_setint(L, hvalue(o), n) = *(L->top-1);
  L->top--;
}


LUA_API void lua_setglobals (lua_State *L) {
  StkId newtable = --L->top;
  LUA_ASSERT(ttype(newtable) == LUA_TTABLE, "table expected");
  L->gt = hvalue(newtable);
}


LUA_API int lua_ref (lua_State *L,  int lock) {
  int ref;
  if (ttype(L->top-1) == LUA_TNIL)
    ref = LUA_REFNIL;
  else {
    if (L->refFree != NONEXT) {  /* is there a free place? */
      ref = L->refFree;
      L->refFree = L->refArray[ref].st;
    }
    else {  /* no more free places */
      luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
                      "reference table overflow", MAX_INT);
      L->nblocks += sizeof(struct Ref);
      ref = L->refSize++;
    }
    L->refArray[ref].o = *(L->top-1);
    L->refArray[ref].st = lock ? LOCK : HOLD;
  }
  L->top--;
  return ref;
}


/*
** "do" functions (run Lua code)
** (most of them are in ldo.c)
*/

LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
  luaD_call(L, L->top-(nargs+1), nresults);
}


/*
** Garbage-collection functions
*/

/* GC values are expressed in Kbytes: #bytes/2^10 */
#define GCscale(x)		((int)((x)>>10))
#define GCunscale(x)		((unsigned long)(x)<<10)

LUA_API int lua_getgcthreshold (lua_State *L) {
  return GCscale(L->GCthreshold);
}

LUA_API int lua_getgccount (lua_State *L) {
  return GCscale(L->nblocks);
}

LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
  if (newthreshold > GCscale(ULONG_MAX))
    L->GCthreshold = ULONG_MAX;
  else
    L->GCthreshold = GCunscale(newthreshold);
  luaC_checkGC(L);
}


/*
** miscellaneous functions
*/

LUA_API void lua_settag (lua_State *L, int tag) {
  luaT_realtag(L, tag);
  switch (ttype(L->top-1)) {
    case LUA_TTABLE:
      hvalue(L->top-1)->htag = tag;
      break;
    case LUA_TUSERDATA:
      tsvalue(L->top-1)->u.d.tag = tag;
      break;
    default:
      luaO_verror(L, "cannot change the tag of a %.20s",
                  luaO_typename(L->top-1));
  }
}


LUA_API void lua_unref (lua_State *L, int ref) {
  if (ref >= 0) {
    LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref");
    L->refArray[ref].st = L->refFree;
    L->refFree = ref;
  }
}


LUA_API int lua_next (lua_State *L, int index) {
  StkId t = luaA_index(L, index);
  Node *n;
  LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
  n = luaH_next(L, hvalue(t), luaA_index(L, -1));
  if (n) {
    *(L->top-1) = *key(n);
    *L->top = *val(n);
    api_incr_top(L);
    return 1;
  }
  else {  /* no more elements */
    L->top -= 1;  /* remove key */
    return 0;
  }
}


LUA_API int lua_getn (lua_State *L, int index) {
  Hash *h = hvalue(luaA_index(L, index));
  const TObject *value = luaH_getstr(h, luaS_new(L, "n"));  /* value = h.n */
  if (ttype(value) == LUA_TNUMBER)
    return (int)nvalue(value);
  else {
    Number max = 0;
    int i = h->size;
    Node *n = h->node;
    while (i--) {
      if (ttype(key(n)) == LUA_TNUMBER &&
          ttype(val(n)) != LUA_TNIL &&
          nvalue(key(n)) > max)
        max = nvalue(key(n));
      n++;
    }
    return (int)max;
  }
}


LUA_API void lua_concat (lua_State *L, int n) {
  StkId top = L->top;
  luaV_strconc(L, n, top);
  L->top = top-(n-1);
  luaC_checkGC(L);
}


LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
  TString *ts = luaS_newudata(L, size, NULL);
  tsvalue(L->top) = ts;
  ttype(L->top) = LUA_TUSERDATA;
  api_incr_top(L);
  return ts->u.d.value;
}

tome-235-src/src/lua/lapi.h0000644000076400017500000000045011012107763013333 0ustar  dgdg/*
** $Id: lapi.h,v 1.3 2001/11/26 23:00:23 darkgod Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/

#ifndef lapi_h
#define lapi_h


#include "lobject.h"


TObject *luaA_index (lua_State *L, int index);
void luaA_pushobject (lua_State *L, const TObject *o);

#endif
tome-235-src/src/lua/lualib.h0000644000076400017500000000124311012107763013657 0ustar  dgdg/*
** $Id: lualib.h,v 1.2 2001/11/26 23:00:26 darkgod Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/


#ifndef lualib_h
#define lualib_h

#include "lua.h"


#ifndef LUALIB_API
#define LUALIB_API	extern
#endif


#define LUA_ALERT               "_ALERT"

LUALIB_API void lua_baselibopen (lua_State *L);
LUALIB_API void lua_iolibopen (lua_State *L);
LUALIB_API void lua_strlibopen (lua_State *L);
LUALIB_API void lua_mathlibopen (lua_State *L);
LUALIB_API void lua_dblibopen (lua_State *L);



/* Auxiliary functions (private) */

const char *luaI_classend (lua_State *L, const char *p);
int luaI_singlematch (int c, const char *p, const char *ep);

#endif
tome-235-src/src/lua/llex.c0000644000076400017500000002451111012107763013351 0ustar  dgdg/*
** $Id: llex.c,v 1.6 2004/06/04 13:42:10 neil Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 

#include "lua.h"

#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "luadebug.h"
#include "lzio.h"



#define next(LS) (LS->current = zgetc(LS->z))



/* ORDER RESERVED */
static const char *const token2string [] = {
    "and", "break", "do", "else", "elseif", "end", "for",
    "function", "if", "local", "nil", "not", "or", "repeat", "return", "then",
    "until", "while", "", "..", "...", "==", ">=", "<=", "~=", "", "", ""};


void luaX_init (lua_State *L) {
  int i;
  for (i=0; imarked = (unsigned char)(RESERVEDMARK+i);  /* reserved word */
  }
}


#define MAXSRC          80


void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
  if (val > limit) {
    char buff[100];
    sprintf(buff, "too many %.50s (limit=%d)", msg, limit);
    luaX_error(ls, buff, ls->t.token);
  }
}


void luaX_syntaxerror (LexState *ls, const char *s, const char *token) {
  char buff[MAXSRC];
  luaO_chunkid(buff, ls->source->str, sizeof(buff));
  luaO_verror(ls->L, "%.99s;\n  last token read: `%.30s' at line %d in %.80s",
              s, token, ls->linenumber, buff);
}


void luaX_error (LexState *ls, const char *s, int token) {
  char buff[TOKEN_LEN];
  luaX_token2str(token, buff);
  if (buff[0] == '\0')
    luaX_syntaxerror(ls, s, ls->L->Mbuffer);
  else
    luaX_syntaxerror(ls, s, buff);
}


void luaX_token2str (int token, char *s) {
  if (token < 256) {
    s[0] = (char)token;
    s[1] = '\0';
  }
  else
    strcpy(s, token2string[token-FIRST_RESERVED]);
}


static void luaX_invalidchar (LexState *ls, int c) {
  char buff[8];
  sprintf(buff, "0x%02X", c);
  luaX_syntaxerror(ls, "invalid control char", buff);
}


static void inclinenumber (LexState *LS) {
  next(LS);  /* skip '\n' */
  ++LS->linenumber;
  luaX_checklimit(LS, LS->linenumber, MAX_INT, "lines in a chunk");
}


void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
  LS->L = L;
  LS->lookahead.token = TK_EOS;  /* no look-ahead token */
  LS->z = z;
  LS->fs = NULL;
  LS->linenumber = 1;
  LS->lastline = 1;
  LS->source = source;
  next(LS);  /* read first char */
  if (LS->current == '#') {
    do {  /* skip first line */
      next(LS);
    } while (LS->current != '\n' && LS->current != '\r' && LS->current != EOZ);
  }
}



/*
** =======================================================
** LEXICAL ANALYZER
** =======================================================
*/


/* use Mbuffer to store names, literal strings and numbers */

#define EXTRABUFF	128
#define checkbuffer(L, n, len)	if ((len)+(n) > L->Mbuffsize) \
                                  luaO_openspace(L, (len)+(n)+EXTRABUFF)

#define save(L, c, l)	(L->Mbuffer[l++] = (char)c)
#define save_and_next(L, LS, l)  (save(L, LS->current, l), next(LS))


static const char *readname (LexState *LS) {
  lua_State *L = LS->L;
  size_t l = 0;
  checkbuffer(L, 10, l);
  do {
    checkbuffer(L, 10, l);
    save_and_next(L, LS, l);
  } while (isalnum(LS->current) || LS->current == '_');
  save(L, '\0', l);
  return L->Mbuffer;
}


/* LUA_NUMBER */
static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
  lua_State *L = LS->L;
  size_t l = 0;
  checkbuffer(L, 10, l);
  if (comma) save(L, '.', l);
  while (isdigit(LS->current)) {
    checkbuffer(L, 10, l);
    save_and_next(L, LS, l);
  }
  if (LS->current == '.') {
    save_and_next(L, LS, l);
    if (LS->current == '.') {
      save_and_next(L, LS, l);
      save(L, '\0', l);
      luaX_error(LS, "ambiguous syntax"
           " (decimal point x string concatenation)", TK_NUMBER);
    }
  }
  while (isdigit(LS->current)) {
    checkbuffer(L, 10, l);
    save_and_next(L, LS, l);
  }
  if (LS->current == 'e' || LS->current == 'E') {
    save_and_next(L, LS, l);  /* read 'E' */
    if (LS->current == '+' || LS->current == '-')
      save_and_next(L, LS, l);  /* optional exponent sign */
    while (isdigit(LS->current)) {
      checkbuffer(L, 10, l);
      save_and_next(L, LS, l);
    }
  }
  save(L, '\0', l);
  if (!luaO_str2d(L->Mbuffer, &seminfo->r))
    luaX_error(LS, "malformed number", TK_NUMBER);
}


static void read_long_string (LexState *LS, SemInfo *seminfo) {
  lua_State *L = LS->L;
  int cont = 0;
  size_t l = 0;
  checkbuffer(L, 10, l);
  save(L, '[', l);  /* save first '[' */
  save_and_next(L, LS, l);  /* pass the second '[' */
  for (;;) {
    checkbuffer(L, 10, l);
    switch (LS->current) {
      case EOZ:
        save(L, '\0', l);
        if (seminfo)
          luaX_error(LS, "unfinished long string", TK_STRING);
        else
          luaX_error(LS, "unfinished comment", TK_EOS);
        break;  /* to avoid warnings */
      case '[':
        save_and_next(L, LS, l);
        if (LS->current == '[') {
          cont++;
          save_and_next(L, LS, l);
        }
        continue;
      case ']':
        save_and_next(L, LS, l);
        if (LS->current == ']') {
          if (cont == 0) goto endloop;
          cont--;
          save_and_next(L, LS, l);
        }
        continue;
      case '\n':
        save(L, '\n', l);
        inclinenumber(LS);
        if (LS->current == '\r') next(LS);
        continue;
      case '\r':
        save(L, '\n', l);
        inclinenumber(LS);
        if (LS->current == '\n') next(LS);
        continue;
      default:
        if (seminfo)	/* no need to save complete comment */
          save(L, LS->current, l);
        next(LS);
    }
  } endloop:
  save_and_next(L, LS, l);  /* skip the second ']' */
  save(L, '\0', l);
  if (seminfo)
    seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
}


static void read_string (LexState *LS, int del, SemInfo *seminfo) {
  lua_State *L = LS->L;
  size_t l = 0;
  checkbuffer(L, 10, l);
  save_and_next(L, LS, l);
  while (LS->current != del) {
    checkbuffer(L, 10, l);
    switch (LS->current) {
      case EOZ:  case '\n':  case '\r':
        save(L, '\0', l);
        luaX_error(LS, "unfinished string", TK_STRING);
        break;  /* to avoid warnings */
      case '\\':
        next(LS);  /* do not save the '\' */
        switch (LS->current) {
          case 'a': save(L, '\a', l); next(LS); break;
          case 'b': save(L, '\b', l); next(LS); break;
          case 'f': save(L, '\f', l); next(LS); break;
          case 'n': save(L, '\n', l); next(LS); break;
          case 'r': save(L, '\r', l); next(LS); break;
          case 't': save(L, '\t', l); next(LS); break;
          case 'v': save(L, '\v', l); next(LS); break;
          case '\n':
            save(L, '\n', l);
            inclinenumber(LS);
            if (LS->current == '\r') next(LS);
            break;
          case '\r':
            save(L, '\n', l);
            inclinenumber(LS);
            if (LS->current == '\n') next(LS);
            break;
          case '0': case '1': case '2': case '3': case '4':
          case '5': case '6': case '7': case '8': case '9': {
            int c = 0;
            int i = 0;
            do {
              c = 10*c + (LS->current-'0');
              next(LS);
            } while (++i<3 && isdigit(LS->current));
            if (c != (unsigned char)c) {
              save(L, '\0', l);
              luaX_error(LS, "escape sequence too large", TK_STRING);
            }
            save(L, c, l);
            break;
          }
          default:  /* handles \\, \", \', and \? */
            save_and_next(L, LS, l);
        }
        break;
      default:
        save_and_next(L, LS, l);
    }
  }
  save_and_next(L, LS, l);  /* skip delimiter */
  save(L, '\0', l);
  seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
}


int luaX_lex (LexState *LS, SemInfo *seminfo) {
  for (;;) {
    switch (LS->current) {

      case ' ': case '\t':
        next(LS);
        continue;

      case '\n':
        inclinenumber(LS);
        if (LS->current == '\r') next(LS);
        continue;

      case '\r':
        inclinenumber(LS);
        if (LS->current == '\n') next(LS);
        continue;

      case '$':
        luaX_error(LS, "unexpected `$' (pragmas are no longer supported)", '$');
        break;

      case '-':
        next(LS);
        if (LS->current != '-') return '-';
        if (next(LS) == '[' && next(LS) == '[')
          read_long_string(LS, NULL);
        else
          while (LS->current != '\n' && LS->current != '\r' && LS->current != EOZ)
            next(LS);
        continue;

      case '[':
        next(LS);
        if (LS->current != '[') return '[';
        else {
          read_long_string(LS, seminfo);
          return TK_STRING;
        }

      case '=':
        next(LS);
        if (LS->current != '=') return '=';
        else { next(LS); return TK_EQ; }

      case '<':
        next(LS);
        if (LS->current != '=') return '<';
        else { next(LS); return TK_LE; }

      case '>':
        next(LS);
        if (LS->current != '=') return '>';
        else { next(LS); return TK_GE; }

      case '~':
        next(LS);
        if (LS->current != '=') return '~';
        else { next(LS); return TK_NE; }

      case '"':
      case '\'':
        read_string(LS, LS->current, seminfo);
        return TK_STRING;

      case '.':
        next(LS);
        if (LS->current == '.') {
          next(LS);
          if (LS->current == '.') {
            next(LS);
            return TK_DOTS;   /* ... */
          }
          else return TK_CONCAT;   /* .. */
        }
        else if (!isdigit(LS->current)) return '.';
        else {
          read_number(LS, 1, seminfo);
          return TK_NUMBER;
        }

      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        read_number(LS, 0, seminfo);
        return TK_NUMBER;

      case EOZ:
        return TK_EOS;

      case '_': goto tname;

      default:
        if (!isalpha(LS->current)) {
          int c = LS->current;
          if (iscntrl(c))
            luaX_invalidchar(LS, c);
          next(LS);
          return c;
        }
        tname: {  /* identifier or reserved word */
          TString *ts = luaS_new(LS->L, readname(LS));
          if (ts->marked >= RESERVEDMARK)  /* reserved word? */
            return ts->marked-RESERVEDMARK+FIRST_RESERVED;
          seminfo->ts = ts;
          return TK_NAME;
        }
    }
  }
}

tome-235-src/src/lua/llex.h0000644000076400017500000000345211012107763013357 0ustar  dgdg/*
** $Id: llex.h,v 1.3 2001/11/26 23:00:24 darkgod Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/

#ifndef llex_h
#define llex_h

#include "lobject.h"
#include "lzio.h"


#define FIRST_RESERVED	257

/* maximum length of a reserved word (+1 for final 0) */
#define TOKEN_LEN	15


/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER RESERVED"
*/
enum RESERVED {
  /* terminal symbols denoted by reserved words */
  TK_AND = FIRST_RESERVED, TK_BREAK,
  TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FOR, TK_FUNCTION, TK_IF, TK_LOCAL,
  TK_NIL, TK_NOT, TK_OR, TK_REPEAT, TK_RETURN, TK_THEN, TK_UNTIL, TK_WHILE,
  /* other terminal symbols */
  TK_NAME, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
  TK_STRING, TK_EOS
};

/* number of reserved words */
#define NUM_RESERVED	((int)(TK_WHILE-FIRST_RESERVED+1))


typedef union {
  Number r;
  TString *ts;
} SemInfo;  /* semantics information */


typedef struct Token {
  int token;
  SemInfo seminfo;
} Token;


typedef struct LexState {
  int current;  /* current character */
  Token t;  /* current token */
  Token lookahead;  /* look ahead token */
  struct FuncState *fs;  /* `FuncState' is private to the parser */
  struct lua_State *L;
  struct zio *z;  /* input stream */
  int linenumber;  /* input line counter */
  int lastline;  /* line of last token `consumed' */
  TString *source;  /* current source name */
} LexState;


void luaX_init (lua_State *L);
void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
int luaX_lex (LexState *LS, SemInfo *seminfo);
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
void luaX_syntaxerror (LexState *ls, const char *s, const char *token);
void luaX_error (LexState *ls, const char *s, int token);
void luaX_token2str (int token, char *s);


#endif
tome-235-src/src/lua/lmem.c0000644000076400017500000000745211012107763013344 0ustar  dgdg/*
** $Id: lmem.c,v 1.3 2001/11/26 23:00:24 darkgod Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/


#include 

#include "lua.h"

#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"




#ifdef LUA_DEBUG
/*
** {======================================================================
** Controlled version for realloc.
** =======================================================================
*/


#include 
#include 
#include 

#define realloc(b, s)	debug_realloc(b, s)
#define malloc(b)	debug_realloc(NULL, b)
#define free(b)		debug_realloc(b, 0)


/* ensures maximum alignment for HEADER */
#define HEADER	(sizeof(union L_Umaxalign))

#define MARKSIZE	16
#define MARK		0x55  /* 01010101 (a nice pattern) */


#define blocksize(b)	((unsigned long *)((char *)(b) - HEADER))

unsigned long memdebug_numblocks = 0;
unsigned long memdebug_total = 0;
unsigned long memdebug_maxmem = 0;
unsigned long memdebug_memlimit = LONG_MAX;


static void *checkblock (void *block) {
  unsigned long *b = blocksize(block);
  unsigned long size = *b;
  int i;
  for (i=0;i memdebug_memlimit)
    return NULL;  /* to test memory allocation errors */
  else {
    size_t realsize = HEADER+size+MARKSIZE;
    char *newblock = (char *)(malloc)(realsize);  /* alloc a new block */
    int i;
    if (realsize < size) return NULL;  /* overflow! */
    if (newblock == NULL) return NULL;
    if (block) {
      size_t oldsize = *blocksize(block);
      if (oldsize > size) oldsize = size;
      memcpy(newblock+HEADER, block, oldsize);
      freeblock(block);  /* erase (and check) old copy */
    }
    memdebug_total += size;
    if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total;
    memdebug_numblocks++;
    *(unsigned long *)newblock = size;
    for (i=0;i= limit-inc) lua_error(L, errormsg);
  if ((newn ^ nelems) <= nelems ||  /* still the same power-of-2 limit? */
       (nelems > 0 && newn < MINPOWER2))  /* or block already is MINPOWER2? */
      return block;  /* do not need to reallocate */
  else  /* it crossed a power-of-2 boundary; grow to next power */
    return luaM_realloc(L, block, luaO_power2(newn)*size);
}


/*
** generic allocation routine.
*/
void *luaM_realloc (lua_State *L, void *block, lint32 size) {
  if (size == 0) {
    free(block);  /* block may be NULL; that is OK for free */
    return NULL;
  }
  else if (size >= MAX_SIZET)
    lua_error(L, "memory allocation error: block too big");
  block = realloc(block, size);
  if (block == NULL) {
    if (L)
      luaD_breakrun(L, LUA_ERRMEM);  /* break run without error message */
    else return NULL;  /* error before creating state! */
  }
  return block;
}


tome-235-src/src/lua/lmem.h0000644000076400017500000000210011012107763013332 0ustar  dgdg/*
** $Id: lmem.h,v 1.3 2001/11/26 23:00:24 darkgod Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/

#ifndef lmem_h
#define lmem_h


#include 

#include "llimits.h"
#include "lua.h"

void *luaM_realloc (lua_State *L, void *oldblock, lint32 size);
void *luaM_growaux (lua_State *L, void *block, size_t nelems,
                    int inc, size_t size, const char *errormsg,
                    size_t limit);

#define luaM_free(L, b)		luaM_realloc(L, (b), 0)
#define luaM_malloc(L, t)	luaM_realloc(L, NULL, (t))
#define luaM_new(L, t)          ((t *)luaM_malloc(L, sizeof(t)))
#define luaM_newvector(L, n,t)  ((t *)luaM_malloc(L, (n)*(lint32)sizeof(t)))

#define luaM_growvector(L, v,nelems,inc,t,e,l) \
          ((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l))

#define luaM_reallocvector(L, v,n,t) \
	((v)=(t *)luaM_realloc(L, v,(n)*(lint32)sizeof(t)))


#ifdef LUA_DEBUG
extern unsigned long memdebug_numblocks;
extern unsigned long memdebug_total;
extern unsigned long memdebug_maxmem;
extern unsigned long memdebug_memlimit;
#endif


#endif

tome-235-src/src/lua/lzio.c0000644000076400017500000000335211012107763013362 0ustar  dgdg/*
** $Id: lzio.c,v 1.5 2004/06/04 13:42:10 neil Exp $
** a generic input stream interface
** See Copyright Notice in lua.h
*/



#include 
#include 

#include "lua.h"

#include "lzio.h"



/* ----------------------------------------------------- memory buffers --- */

static int zmfilbuf (ZIO* z) {
  (void)z;  /* to avoid warnings */
  return EOZ;
}


ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name) {
  if (b==NULL) return NULL;
  z->n = size;
  z->p = (const unsigned char *)b;
  z->filbuf = zmfilbuf;
  z->u = NULL;
  z->name = name;
  return z;
}

/* ------------------------------------------------------------ strings --- */

ZIO* zsopen (ZIO* z, const char* s, const char *name) {
  if (s==NULL) return NULL;
  return zmopen(z, s, strlen(s), name);
}

/* -------------------------------------------------------------- FILEs --- */

static int zffilbuf (ZIO* z) {
  size_t n;
  if (feof((FILE *)z->u)) return EOZ;
  n = fread(z->buffer, 1, ZBSIZE, (FILE *)z->u);
  if (n==0) return EOZ;
  z->n = n-1;
  z->p = z->buffer;
  return *(z->p++);
}


ZIO* zFopen (ZIO* z, FILE* f, const char *name) {
  if (f==NULL) return NULL;
  z->n = 0;
  z->p = z->buffer;
  z->filbuf = zffilbuf;
  z->u = f;
  z->name = name;
  return z;
}


/* --------------------------------------------------------------- read --- */
size_t zread (ZIO *z, void *b, size_t n) {
  while (n) {
    size_t m;
    if (z->n == 0) {
      if (z->filbuf(z) == EOZ)
        return n;  /* return number of missing bytes */
      zungetc(z);  /* put result from `filbuf' in the buffer */
    }
    m = (n <= z->n) ? n : z->n;  /* min. between n and z->n */
    memcpy(b, z->p, m);
    z->n -= m;
    z->p += m;
    b = (char *)b + m;
    n -= m;
  }
  return 0;
}
tome-235-src/src/lua/lzio.h0000644000076400017500000000216111012107763013364 0ustar  dgdg/*
** $Id: lzio.h,v 1.5 2004/06/04 13:42:10 neil Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/


#ifndef lzio_h
#define lzio_h

#include 



/* For Lua only */
#define zFopen	luaZ_Fopen
#define zsopen	luaZ_sopen
#define zmopen	luaZ_mopen
#define zread	luaZ_read

#define EOZ	(-1)			/* end of stream */

typedef struct zio ZIO;

ZIO* zFopen (ZIO* z, FILE* f, const char *name);	/* open FILEs */
ZIO* zsopen (ZIO* z, const char* s, const char *name);	/* string */
ZIO* zmopen (ZIO* z, const char* b, size_t size, const char *name); /* memory */

size_t zread (ZIO* z, void* b, size_t n);	/* read next n bytes */

#define zgetc(z)	(((z)->n--)>0 ? ((int)*(z)->p++): (z)->filbuf(z))
#define zungetc(z)	(++(z)->n,--(z)->p)
#define zname(z)	((z)->name)



/* --------- Private Part ------------------ */

#ifndef ZBSIZE
#define ZBSIZE	256			/* buffer size */
#endif

struct zio {
  size_t n;				/* bytes still unread */
  const unsigned char* p;		/* current position in buffer */
  int (*filbuf)(ZIO* z);
  void* u;				/* additional data */
  const char *name;
  unsigned char buffer[ZBSIZE];		/* buffer */
};


#endif
tome-235-src/src/lua/lopcodes.h0000644000076400017500000001232011012107763014215 0ustar  dgdg/*
** $Id: lopcodes.h,v 1.5 2004/06/04 13:42:10 neil Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/

#ifndef lopcodes_h
#define lopcodes_h

#include "llimits.h"


/*===========================================================================
  We assume that instructions are unsigned numbers.
  All instructions have an opcode in the first 6 bits. Moreover,
  an instruction can have 0, 1, or 2 arguments. Instructions can
  have the following types:
  type 0: no arguments
  type 1: 1 unsigned argument in the higher bits (called `U')
  type 2: 1 signed argument in the higher bits          (`S')
  type 3: 1st unsigned argument in the higher bits      (`A')
          2nd unsigned argument in the middle bits      (`B')

  A signed argument is represented in excess K; that is, the number
  value is the unsigned value minus K. K is exactly the maximum value
  for that argument (so that -max is represented by 0, and +max is
  represented by 2*max), which is half the maximum for the corresponding
  unsigned argument.

  The size of each argument is defined in `llimits.h'. The usual is an
  instruction with 32 bits, U arguments with 26 bits (32-6), B arguments
  with 9 bits, and A arguments with 17 bits (32-6-9). For small
  installations, the instruction size can be 16, so U has 10 bits,
  and A and B have 5 bits each.
===========================================================================*/




/* creates a mask with `n' 1 bits at position `p' */
#define MASK1(n,p)	((~((~(Instruction)0)<>POS_U))
#define SETARG_U(i,u)	((i) = (((i)&MASK0(SIZE_U,POS_U)) | \
                               ((Instruction)(u)<>POS_A))
#define SETARG_A(i,a)	((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
                               ((Instruction)(a)<>POS_B) & MASK1(SIZE_B,0)))
#define SETARG_B(i,b)	((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
                               ((Instruction)(b)<y)? PC+=s	*/
OP_JMPGE,/*	J	y x		-		(x>=y)? PC+=s	*/

OP_JMPT,/*	J	x		-		(x~=nil)? PC+=s	*/
OP_JMPF,/*	J	x		-		(x==nil)? PC+=s	*/
OP_JMPONT,/*	J	x		(x~=nil)? x : -	(x~=nil)? PC+=s	*/
OP_JMPONF,/*	J	x		(x==nil)? x : -	(x==nil)? PC+=s	*/
OP_JMP,/*	J	-		-		PC+=s		*/

OP_PUSHNILJMP,/* -	-		nil		PC++;		*/

OP_FORPREP,/*	J							*/
OP_FORLOOP,/*	J							*/

OP_LFORPREP,/*	J							*/
OP_LFORLOOP,/*	J							*/

OP_CLOSURE/*	A B	v_b-v_1		closure(KPROTO[a], v_1-v_b)	*/

} OpCode;

#define NUM_OPCODES	((int)OP_CLOSURE+1)


#define ISJUMP(o)	(OP_JMPNE <= (o) && (o) <= OP_JMP)



/* special code to fit a LUA_MULTRET inside an argB */
#define MULT_RET        255	/* (<=MAXARG_B) */
#if MULT_RET>MAXARG_B
#undef MULT_RET
#define MULT_RET	MAXARG_B
#endif


#endif
tome-235-src/src/lua/tolua_bd.c0000644000076400017500000001166311012107763014202 0ustar  dgdg/*
** Lua binding: tolua
** Generated automatically by tolua 4.0b on Tue Nov 14 14:18:50 2000.
*/

#include "tolua.h"

/* Exported function */
int  tolua_tolua_open (lua_State* tolua_S);
void tolua_tolua_close (lua_State* tolua_S);

#define tolua_using(module)       (tolua_using)(tolua_S,module)
#define tolua_type(lo)            (tolua_type)(tolua_S,lo)
#define tolua_foreach(lo,f)       (tolua_foreach)(tolua_S,lo,f)
#define tolua_class(derived,base) (tolua_class)(tolua_S,derived,base)
#define tolua_instance(inst,cobj) (tolua_instance)(tolua_S,inst,cobj)
#define tolua_base(lo)            (tolua_base)(tolua_S,lo)
#define tolua_cast(lo,type)       (tolua_cast)(tolua_S,lo,type)
#define tolua_takeownership(lo)   (tolua_takeownership)(tolua_S,lo)

/* function to register type */
static void toluaI_reg_types (lua_State* tolua_S)
{
}

/* function: tolua_using */
static int toluaI_tolua_tolua_using00(lua_State* tolua_S)
{
 if (
     !tolua_isnoobj(tolua_S,2)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE module = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  {
   tolua_using(module);
  }
 }
 return 0;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'using'.");
 return 0;
}

/* function: tolua_type */
static int toluaI_tolua_tolua_type00(lua_State* tolua_S)
{
 if (
     !tolua_isnoobj(tolua_S,2)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE lo = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  {
   char* toluaI_ret = (char*)  tolua_type(lo);
   tolua_pushstring(tolua_S,toluaI_ret);
  }
 }
 return 1;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'type'.");
 return 0;
}

/* function: tolua_foreach */
static int toluaI_tolua_tolua_foreach00(lua_State* tolua_S)
{
 if (
     !tolua_isnoobj(tolua_S,3)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE lo = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  LUA_VALUE f = ((LUA_VALUE)  tolua_getvalue(tolua_S,2,0));
  {
   tolua_foreach(lo,f);
  }
 }
 return 0;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'foreach'.");
 return 0;
}

/* function: tolua_class */
static int toluaI_tolua_tolua_class00(lua_State* tolua_S)
{
 if (
     !tolua_isnoobj(tolua_S,3)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE derived = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  LUA_VALUE base = ((LUA_VALUE)  tolua_getvalue(tolua_S,2,0));
  {
   tolua_class(derived,base);
  }
 }
 return 0;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'class'.");
 return 0;
}

/* function: tolua_instance */
static int toluaI_tolua_tolua_instance00(lua_State* tolua_S)
{
 if (
     !tolua_isnoobj(tolua_S,3)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE instance = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  LUA_VALUE classobj = ((LUA_VALUE)  tolua_getvalue(tolua_S,2,0));
  {
   tolua_instance(instance,classobj);
  }
 }
 return 0;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'instance'.");
 return 0;
}

/* function: tolua_base */
static int toluaI_tolua_tolua_base00(lua_State* tolua_S)
{
 if (
     !tolua_isnoobj(tolua_S,2)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE lo = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  {
   LUA_VALUE toluaI_ret = (LUA_VALUE)  tolua_base(lo);
   tolua_pushvalue(tolua_S,toluaI_ret);
  }
 }
 return 1;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'base'.");
 return 0;
}

/* function: tolua_cast */
static int toluaI_tolua_tolua_cast00(lua_State* tolua_S)
{
 if (
     !tolua_istype(tolua_S,2,LUA_TSTRING,0) ||
     !tolua_isnoobj(tolua_S,3)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE lo = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  char* type = ((char*)  tolua_getstring(tolua_S,2,0));
  {
   LUA_VALUE toluaI_ret = (LUA_VALUE)  tolua_cast(lo,type);
   tolua_pushvalue(tolua_S,toluaI_ret);
  }
 }
 return 1;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'cast'.");
 return 0;
}

/* function: tolua_takeownership */
static int toluaI_tolua_tolua_takeownership00(lua_State* tolua_S)
{
 if (
     !tolua_isnoobj(tolua_S,2)
 )
  goto tolua_lerror;
 else
 {
  LUA_VALUE lo = ((LUA_VALUE)  tolua_getvalue(tolua_S,1,0));
  {
   tolua_takeownership(lo);
  }
 }
 return 0;
tolua_lerror:
 tolua_error(tolua_S,"#ferror in function 'takeownership'.");
 return 0;
}

/* Open function */
int tolua_tolua_open (lua_State* tolua_S)
{
 tolua_open(tolua_S);
 toluaI_reg_types(tolua_S);
 tolua_module(tolua_S,"tolua");
 tolua_function(tolua_S,"tolua","using",toluaI_tolua_tolua_using00);
 tolua_function(tolua_S,"tolua","type",toluaI_tolua_tolua_type00);
 tolua_function(tolua_S,"tolua","foreach",toluaI_tolua_tolua_foreach00);
 tolua_function(tolua_S,"tolua","class",toluaI_tolua_tolua_class00);
 tolua_function(tolua_S,"tolua","instance",toluaI_tolua_tolua_instance00);
 tolua_function(tolua_S,"tolua","base",toluaI_tolua_tolua_base00);
 tolua_function(tolua_S,"tolua","cast",toluaI_tolua_tolua_cast00);
 tolua_function(tolua_S,"tolua","takeownership",toluaI_tolua_tolua_takeownership00);
 return 1;
}
/* Close function */
void tolua_tolua_close (lua_State* tolua_S)
{
 lua_pushnil(tolua_S); lua_setglobal(tolua_S,"tolua");
}
tome-235-src/src/lua/tolua_eh.c0000644000076400017500000000337611012107763014213 0ustar  dgdg/* tolua: error handling
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_eh.c,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it. 
** The software provided hereunder is on an "as is" basis, and 
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications. 
*/

#include "tolua.h"
#include "tolua_eh.h"
#include "tolua_rg.h"

#include 

/* registry fiels used to hold current error info 
   - tolua_err_narg: number of wrong argument
   - tolua_err_provided: provided type
   - tolua_err_expected: expected type
*/

void toluaI_eh_set 
(lua_State* L, int narg, const char* provided, const char* expected)
{
 lua_pushnumber(L,narg);
 toluaI_setregistry(L,"tolua_err_narg");
 lua_pushstring(L,provided);
 toluaI_setregistry(L,"tolua_err_provided");
 lua_pushstring(L,expected);
 toluaI_setregistry(L,"tolua_err_expected");
}

void tolua_error (lua_State* L, char* msg)
{
 if (msg[0]=='#')
 {
  static char buffer[BUFSIZ];
  const char* err_provided;
  const char* err_expected;
  toluaI_getregistry(L,"tolua_err_provided");
  err_provided = lua_tostring(L,-1);
  toluaI_getregistry(L,"tolua_err_expected");
  err_expected = lua_tostring(L,-1);
  lua_pop(L,2);
  if (msg[1]=='f')
  {
   int err_narg;
   toluaI_getregistry(L,"tolua_err_narg");
   err_narg = (int)lua_tonumber(L,-1);
   lua_pop(L,1);
   sprintf(buffer,"%s\n     argument #%d is '%s'; '%s' expected.\n",
           msg+2,err_narg,err_provided,err_expected);
  }
  else if (msg[1]=='v')
   sprintf(buffer,"%s\n     value is '%s'; '%s' expected.\n",
           msg+2,err_provided,err_expected);
  lua_error(L,buffer);
 }
 else
  lua_error(L,msg);
}
tome-235-src/src/lua/tolua_eh.h0000644000076400017500000000107311012107763014210 0ustar  dgdg/* tolua: error handling
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_eh.h,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it.
** The software provided hereunder is on an "as is" basis, and
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications.
*/



#ifndef tolua_eh_h
#define tolua_eh_h

void toluaI_eh_set 
(lua_State* L, int narg, const char* provided, const char* expected);


#endif
tome-235-src/src/lua/tolua_gp.c0000644000076400017500000001002711012107763014214 0ustar  dgdg/* tolua: get & push functions.
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_gp.c,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it. 
** The software provided hereunder is on an "as is" basis, and 
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications. 
*/

#include "tolua.h"
#include "tolua_tm.h"

#include 
#include 

long tolua_getnumber (lua_State* L, int narg, long def)
{
 return lua_gettop(L)

#include "tolua.h"
#include "tolua_rg.h"
#include "tolua_tm.h"
#include "tolua_tt.h"

void tolua_globalvar (lua_State* L, char* name, lua_CFunction get, lua_CFunction set)
{
 lua_newtable(L);
 lua_pushstring(L,".get");
 lua_pushcfunction(L,get);
 lua_settable(L,-3);
 if (set)
 {
  lua_pushstring(L,".set");
  lua_pushcfunction(L,set);
  lua_settable(L,-3);
 }
 lua_pushvalue(L,-1);  /* duplicate top */
 lua_setglobal(L,name);
 toluaI_tm_global(L,lua_gettop(L));
 lua_pop(L,1);
}

static int toluaI_const_global_array (lua_State* L)
{
 lua_error(L,"value of const array cannot be changed");
 return 0;
}


void tolua_globalarray (lua_State* L,char* name, lua_CFunction get, lua_CFunction set)
{
 int tag = lua_newtag(L);
 lua_newtable(L);
 lua_settag(L,tag);
 lua_setglobal(L,name);
 
 lua_pushcfunction(L,get);
 lua_settagmethod(L,tag,"gettable"); 
 if (set)
  lua_pushcfunction(L,set);
 else
  lua_pushcfunction(L,toluaI_const_global_array);
 lua_settagmethod(L,tag,"settable");
}

void tolua_tablevar 
(lua_State* L, char* table, char* name, lua_CFunction get, lua_CFunction set)
{
 lua_getglobal(L,table);

 lua_pushstring(L,".get");
 lua_gettable(L,-2);
 lua_pushstring(L,name);
 lua_pushcfunction(L,get);
 lua_settable(L,-3);
 lua_pop(L,1);
 if (set)
 {
  lua_pushstring(L,".set");
  lua_gettable(L,-2);
  lua_pushstring(L,name);
  lua_pushcfunction(L,set);
  lua_settable(L,-3);
  lua_pop(L,1);
 }

 lua_pop(L,1);
}

static int toluaI_get_array (lua_State* L)
{
 void* self = tolua_getuserdata(L,1,0);
 const char* field = tolua_getstring(L,2,0);

 if (!field)
  tolua_error(L,"invalid 'field' in accessing array");
 if (!self)
 {
  static char msg[BUFSIZ];
  sprintf(msg,"invalid 'self' in accessing array '%s'",field);
  tolua_error(L,msg);
 }
 toluaI_getregistry(L,"tolua_tbl_itype");
 lua_pushnumber(L,lua_tag(L,1));
 lua_gettable(L,-2);
 lua_getglobal(L,lua_tostring(L,-1));
 lua_pushstring(L,".array");
 lua_gettable(L,-2);             
 lua_pushvalue(L,2);    /* field */
 lua_gettable(L,-2);
 lua_pushstring(L,".self");
 lua_pushvalue(L,1);    /* self */
 lua_rawset(L,-3);
 return 1;
}

static int toluaI_const_array (lua_State* L)
{
 lua_error(L,"value of const field cannot be changed");
 return 0;
}

void tolua_tablearray
(lua_State* L, char* table, char* name, lua_CFunction get, lua_CFunction set)
{
 int tag = lua_newtag(L);
 lua_getglobal(L,table);
 lua_pushstring(L,".array");
 lua_rawget(L,-2);
 lua_pushstring(L,name);
 lua_newtable(L);
 lua_settag(L,tag);
 lua_settable(L,-3);
 lua_pop(L,2);

 lua_pushcfunction(L,get);
 lua_settagmethod(L,tag,"gettable");
 if (set)
  lua_pushcfunction(L,set);
 else
  lua_pushcfunction(L,toluaI_const_array);
 lua_settagmethod(L,tag,"settable");

 tolua_tablevar(L,table,name,toluaI_get_array,NULL);
}

void tolua_module (lua_State* L, char* name)
{
 lua_getglobal(L,name);
 if (!lua_istable(L,-1))
 {
  lua_newtable(L);
  lua_pushstring(L,".get");
  lua_newtable(L);
  lua_settable(L,-3);
  lua_pushstring(L,".set");
  lua_newtable(L);
  lua_settable(L,-3);
  lua_pushvalue(L,-1);  /* duplicate top */
  lua_setglobal(L,name);
  toluaI_tm_module(L,lua_gettop(L));
  lua_pop(L,1);
 }
 lua_pop(L,1);
}

void tolua_cclass (lua_State* L, char* name, char* base)
{
 int t;
 lua_newtable(L);
 lua_pushstring(L,".get");
 lua_newtable(L);
 lua_settable(L,-3);
 lua_pushstring(L,".set");
 lua_newtable(L);
 lua_settable(L,-3);
 lua_pushstring(L,".array");
 lua_newtable(L);
 lua_settable(L,-3);
 if (*base != 0)
 {
  lua_pushstring(L,".base");
  lua_getglobal(L,base);
  lua_rawset(L,-3);
 }
 lua_pushvalue(L,-1);  /* duplicate top */
 lua_setglobal(L,name);
 t = lua_gettop(L); 
 toluaI_tm_class(L,t,name);
 toluaI_tt_class(L,t,name,base);
 lua_pop(L,1);
}


void tolua_function (lua_State* L, char* parent, char* name, lua_CFunction func)
{
 if (parent==NULL)
 {
  lua_pushcfunction(L,func);
  lua_setglobal(L,name);
 }
 else
 {
  lua_getglobal(L,parent);
  lua_pushstring(L,name);
  lua_pushcfunction(L,func);
  lua_settable(L,-3);
  lua_pop(L,1);
 }
}

void tolua_constant (lua_State* L, char* parent, char* name, long value)
{
 if (parent==NULL)
 {
  lua_pushnumber(L,value);
  lua_setglobal(L,name);
 }
 else
 {
  lua_getglobal(L,parent);
  lua_pushstring(L,name);
  lua_pushnumber(L,value);
  lua_settable(L,-3);
  lua_pop(L,1);
 }
}

void toluaI_setregistry (lua_State* L, char* field)
{
 lua_getregistry(L);
 lua_insert(L,-2);
 lua_pushstring(L,field);
 lua_insert(L,-2);
 lua_settable(L,-3);
 lua_pop(L,1);
}

void toluaI_getregistry (lua_State* L, char* field)
{
 lua_getregistry(L);
 lua_pushstring(L,field);
 lua_gettable(L,-2);
 lua_insert(L,-2);
 lua_pop(L,1);
}
tome-235-src/src/lua/tolua_rg.h0000644000076400017500000000111411012107763014220 0ustar  dgdg/* tolua: register functions
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Nov 200
** $Id: tolua_rg.h,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it.
** The software provided hereunder is on an "as is" basis, and
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications.
*/


#ifndef tolua_rg_h
#define tolua_rg_h

void toluaI_setregistry (lua_State* L, char* field);
void toluaI_getregistry (lua_State* L, char* field);

#endif
tome-235-src/src/lua/tolua_tm.c0000644000076400017500000003370611012107763014237 0ustar  dgdg/* tolua: tag methods
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_tm.c,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it. 
** The software provided hereunder is on an "as is" basis, and 
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications. 
*/

#include "tolua.h"
#include "tolua_tm.h"
#include "tolua_tt.h"
#include "tolua_rg.h"

#include 



/* Global tables created in Lua registry:
    tolua_tbl_class: indexed by instance tags, stores the class tables.
    tolua_tbl_clone: indexed by memory address, stores the tag indicanting 
                     it is a clone.
    tolua_tbl_mate:  indexed by memory address, stores the associate instance
                     table.

   General tags stored in Lua registry:
    tolua_tag_global;
    tolua_tag_module;
    tolua_tag_class;
    tolua_tag_instance;
    tolua_tag_linstance;
    tolua_tag_indirect;
*/

/* internal function prototype */
static void setmethods (lua_State* L);

static void settag (lua_State* L, int lo, char* tag_registry_field)
{
 toluaI_getregistry(L,tag_registry_field);
 lua_pushvalue(L,lo);
 lua_settag(L,(int)lua_tonumber(L,-2));
 lua_pop(L,2);
}

void toluaI_tm_global (lua_State* L, int lo)
{
 settag(L,lo,"tolua_tag_global");
}

void toluaI_tm_module (lua_State* L, int lo)
{
 settag(L,lo,"tolua_tag_module");
}

void toluaI_tm_setclass (lua_State* L, int lo)
{
 settag(L,lo,"tolua_tag_class");
}

void toluaI_tm_class (lua_State* L, int lo, char* name)
{
 int tag_class;
 int tag = lua_newtag(L);
 char* type = toluaI_tt_concat("class ",name);
 toluaI_getregistry(L,"tolua_tag_class");
 tag_class = (int)lua_tonumber(L,-1);
 lua_copytagmethods(L,tag,tag_class);
 toluaI_tt_register(L,tag,type);
 toluaI_tt_sethierarchy(L,tag,tag_class);
 lua_pushvalue(L,lo);
 lua_settag(L,tag);
 lua_pop(L,2);  /* tag_class and lo */
}

void toluaI_tm_instance (lua_State* L, int tag, int lo)
{
 toluaI_getregistry(L,"tolua_tbl_class");
 lua_pushnumber(L,tag);
 lua_pushvalue(L,lo);
 lua_settable(L,-3);
 toluaI_getregistry(L,"tolua_tag_instance");
 lua_copytagmethods(L,tag,(int)lua_tonumber(L,-1));
 lua_pop(L,2); /* tbl_class and tag_instance */
}

void toluaI_tm_linstance (lua_State* L, int tag, int lo)
{
 toluaI_getregistry(L,"tolua_tbl_class");
 lua_pushnumber(L,tag);
 lua_pushvalue(L,lo);
 lua_settable(L,-3);
 toluaI_getregistry(L,"tolua_tag_linstance");
 lua_copytagmethods(L,tag,(int)lua_tonumber(L,-1));
 lua_pop(L,2); /* tbl_class and tag_linstance */
}

void* tolua_doclone (lua_State* L, void* value, int tag)
{
 toluaI_getregistry(L,"tolua_tbl_clone");
 lua_pushuserdata(L,value);
 lua_pushnumber(L,tag);
 lua_settable(L,-3);
 lua_pop(L,1);
 return value;
}

void* tolua_copy (lua_State* L, void* value, unsigned int size)
{
 void* clone = (void*)malloc(size);
 if (clone)
  memcpy(clone,value,size);
 else
  tolua_error(L,"insuficient memory");
 return clone;
}

static void toluaI_tm_undoclone (lua_State* L, int tag, void* clone)
{
 toluaI_getregistry(L,"tolua_tbl_clone");
 lua_pushuserdata(L,clone);
 lua_gettable(L,-2);
 if (lua_isnumber(L,-1) && lua_tonumber(L,-1)==tag)
 {
  lua_pushuserdata(L,clone);
  lua_pushnil(L);
  lua_settable(L,-4);

  /* get base class */
  toluaI_getregistry(L,"tolua_tbl_class");
  lua_pushnumber(L,tag);
  lua_rawget(L,-2);

  /* look for destructor */
  lua_pushstring(L,"delete");
  lua_gettable(L,-2);
  if (lua_iscfunction(L,-1))
  {
   lua_pushusertag(L,clone,tag);
   lua_call(L,1,0);
  }
  else
  {
   free(clone);    /* no destructor: use raw free */
   lua_pop(L,1);   /* the nil function value */
  }
  lua_pop(L,2); /* tbl_class and class method table */
 }
 lua_pop(L,2);  /* table and value */
}

void toluaI_tm_pushmate (lua_State* L, int lo)
{
 toluaI_getregistry(L,"tolua_tbl_mate");
 lua_pushvalue(L,lo);
 lua_rawget(L,-2);
 lua_insert(L,-2);
 lua_pop(L,1);
}

void toluaI_tm_pushclass (lua_State* L, int lo)
{
 toluaI_getregistry(L,"tolua_tbl_class");
 lua_pushnumber(L,lua_tag(L,lo));
 lua_rawget(L,-2);
 lua_insert(L,-2);
 lua_pop(L,1);
}

int toluaI_gettag (lua_State* L, char* tagname)
{
 int tag;
 toluaI_getregistry(L,tagname);
 tag = (int)lua_tonumber(L,-1);
 lua_pop(L,1);
 return tag;
}

void toluaI_tm_init (lua_State* L)
{
 lua_newtable(L); toluaI_setregistry(L,"tolua_tbl_class");
 lua_newtable(L); toluaI_setregistry(L,"tolua_tbl_clone");
 lua_newtable(L); toluaI_setregistry(L,"tolua_tbl_mate");

 lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_global");
 lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_module");
 lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_class");
 lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_instance");
 lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_linstance");
 lua_pushnumber(L,lua_newtag(L)); toluaI_setregistry(L,"tolua_tag_indirect");

 toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_global"),"generic variable");
 toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_module"),"generic module");
 toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_class"),"generic class");
 toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_indirect"),"generic indirect");
 toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_instance"),"generic instance");
 toluaI_tt_register(L,toluaI_gettag(L,"tolua_tag_linstance"),"generic lua instance");

 /* allows modules and classes to be used as ordinary tables */
 toluaI_tt_sethierarchy(L,toluaI_gettag(L,"tolua_tag_module"),tolua_tag_table);
 toluaI_tt_sethierarchy(L,toluaI_gettag(L,"tolua_tag_class"),tolua_tag_table);

 setmethods(L);
}

static int map (lua_State* L)
{
 int m = lua_gettop(L);
 /* do not pass string fields starting with a dot */
 if (!lua_isstring(L,1) || *lua_tostring(L,1)!='.')
 {
  lua_getglobals(L);
  lua_pushvalue(L,1);
  lua_pushvalue(L,m);
  lua_rawset(L,-3);
  lua_pop(L,1);
 }
 return 0;
}

void toluaI_tm_using (lua_State* L, int module)
{
 lua_newtable(L);
 lua_settag(L,toluaI_gettag(L,"tolua_tag_indirect"));
 lua_pushstring(L,".module");
 lua_pushvalue(L,module);
 lua_settable(L,-3);

 lua_getglobal(L,"foreach");
 lua_pushvalue(L,module);
 lua_pushvalue(L,-3);
 lua_pushcclosure(L,map,1);
 lua_call(L,2,0);

 lua_getglobal(L,"foreach");
 lua_pushvalue(L,module);
 lua_pushstring(L,".get");
 lua_gettable(L,-2);
 lua_insert(L,-2);
 lua_pop(L,1);   /* module table */
 lua_pushvalue(L,-3);
 lua_pushcclosure(L,map,1);
 lua_call(L,2,0);
 lua_pop(L,1);   /* indirect table */
}

/********************************************************** tag methods */

/* tag methods coded in C */

/* generic gettable */
static void oo_gettable (lua_State* L, int table, int base, int index)
{
 while (lua_istable(L,base))
 {
  lua_pushvalue(L,index); 
  lua_rawget(L,base);
  if (!lua_isnil(L,-1))
   return;            /* returned value already on the top */
  else if (lua_isnumber(L,index))
  {
   lua_pushstring(L,"operator_get");
   lua_rawget(L,base);
   if (!lua_isnil(L,-1))
   {
    lua_pushvalue(L,table);
    lua_pushvalue(L,index);
    lua_call(L,2,1);
    return;
   }
  }
  else
  {
   lua_pushstring(L,".get");
   lua_rawget(L,base);
   if (!lua_isnil(L,-1))
   {
    lua_pushvalue(L,index);
    lua_rawget(L,-2);
    if (!lua_isnil(L,-1))
    {
     lua_pushvalue(L,table);
     lua_pushvalue(L,index); /* need to access array field (?) */
     lua_call(L,2,1);
     return;
    }
   }
  }
  lua_pushstring(L,".base"); lua_rawget(L,base);
  base = lua_gettop(L);
 }
 lua_pushnil(L);
}

/* generic settable */
static int oo_settable (lua_State* L, int table, int base, int index, int value) 
{
 while (lua_istable(L,base))
 {
  lua_pushstring(L,".set");
  lua_rawget(L,base);
  if (!lua_isnil(L,-1))
  {
   lua_pushvalue(L,index);
   lua_rawget(L,-2);
   if (!lua_isnil(L,-1))
   {
    lua_pushvalue(L,table);
    lua_pushvalue(L,value);
    lua_call(L,2,0);
    return 1;
   }
  }
  lua_pushstring(L,".base"); lua_rawget(L,base);
  base = lua_gettop(L);
 }
 return 0;
}

/* class tag methods */
static int class_index (lua_State* L)
{
 int table = 1;
 int index = 2;
 oo_gettable(L,table,table,index);
 return 1;
}
static int class_settable (lua_State* L)
{
 int table = 1;
 int index = 2;
 int value = 3;
 if (oo_settable(L,table,table,index,value) == 0)
 {
  lua_pushvalue(L,table);
  lua_pushvalue(L,index);
  lua_pushvalue(L,value);
  lua_rawset(L,-3);
 }
 return 0;
}

/* instance tags */
static int instance_gettable (lua_State* L)
{
 int table = 1;
 int index = 2;
 toluaI_tm_pushmate(L,table);   /* pushes mate */
 if (!lua_isnil(L,-1))          /* if there's a mate table */
 {
  lua_pushvalue(L,index);
  lua_rawget(L,-2);
  if (!lua_isnil(L,-1))         /* if field in mate table exists */
   return 1;
 }
 toluaI_tm_pushclass(L,table);  /* pushes base */
 oo_gettable(L,table,lua_gettop(L),index);
 return 1;
}
static int instance_settable (lua_State* L)
{
 int table = 1;
 int index = 2;
 int value = 3;
 toluaI_tm_pushclass(L,table);  /* pushes base */
 if (lua_isnumber(L,index))
 {
  lua_pushstring(L,"operator_set");
  lua_rawget(L,-2);
  if (!lua_isnil(L,-1))
  {/* the stack here is: table,index,value,base,operator */
   /* call operator passing table, index, and value */
   lua_insert(L,1);
   lua_pop(L,1);       /* base */
   lua_call(L,3,0);
   return 0;
  }
 }
 if (oo_settable(L,table,4,index,value) == 0)
 {
  toluaI_tm_pushmate(L,table);    /* pushes mate */
  if (lua_isnil(L,-1))
  {
   /* creates mate table */
   lua_newtable(L);
   toluaI_getregistry(L,"tolua_tbl_mate");
   lua_pushvalue(L,table);        /* that is the userdata */
   lua_pushvalue(L,-3);
   lua_rawset(L,-3);
   lua_pop(L,1);     /* tbl_mate */
  }
  /* the mate table is on the top */
  lua_pushvalue(L,index);
  lua_pushvalue(L,value);
  lua_rawset(L,-3);
 }
 return 0;
}
static int instance_gc (lua_State* L)
{
 toluaI_tm_undoclone(L,lua_tag(L,1),lua_touserdata(L,1)); 
 return 0;
}
static int gen_operator (lua_State* L)
{
 int op1 = 1;
 int op2 = 2;
 int event = 3;
 char* name = toluaI_tt_concat("operator_",lua_tostring(L,event));
 lua_pushstring(L,name); 
 lua_gettable(L,op1);
 lua_pushvalue(L,op1);
 lua_pushvalue(L,op2);
 lua_call(L,2,1);
 return 1;
}
static int instance_operator (lua_State* L)
{
 return gen_operator(L);
}
static int instance_relational (lua_State* L)
{
 gen_operator(L);
 if ((int)lua_tonumber(L,-1)==0) lua_pushnil(L);
 return 1;
}

/* lua instance tags */
static int linstance_index (lua_State* L)
{
 toluaI_tm_pushclass(L,1);
 oo_gettable(L,1,3,2);  /* table,base,index */
 return 1;
}


/* module tag methods */
static int module_index (lua_State* L)
{
 int table = 1;
 int index = 2;
 lua_pushstring(L,".get");
 lua_rawget(L,table);
 if (!lua_isnil(L,-1))
 {
  lua_pushvalue(L,index);
  lua_rawget(L,-2);
  if (!lua_isnil(L,-1))
  {
   lua_call(L,0,1);
   return 1;
  }
 }
 lua_pushnil(L);
 return 1;
}
static int module_settable (lua_State* L)
{
 int table = 1;
 int index = 2;
 int value = 3;
 lua_pushstring(L,".set");
 lua_rawget(L,table);
 if (!lua_isnil(L,-1))
 {
  lua_pushvalue(L,index);
  lua_rawget(L,-2);
  if (!lua_isnil(L,-1))
  {
   lua_pushvalue(L,value);
   lua_call(L,1,0);
   return 0;
  }
 }
 lua_pushvalue(L,index);
 lua_pushvalue(L,value);
 lua_rawset(L,table);
 return 0;
}

/* global variable tag methods */
static int global_getglobal (lua_State* L)
{
 int value = 2;
 lua_pushstring(L,".get");
 lua_rawget(L,value);
 lua_call(L,0,1);
 return 1;
}
static int global_setglobal (lua_State* L)
{
 int value = 2;
 int newvalue = 3;
 lua_pushstring(L,".set");
 lua_rawget(L,value);
 if (lua_isnil(L,-1))
  lua_error(L,"value of const variable cannot be changed");
 else
 {
  lua_pushvalue(L,newvalue);
  lua_call(L,1,0);
 }
 return 0;
}

/* indirect tag methods */
static int indirect_getglobal (lua_State* L)
{
 int varname = 1;
 int value = 2;
 lua_pushstring(L,".module");
 lua_gettable(L,value);
 lua_pushvalue(L,varname);
 lua_gettable(L,-2);
 return 1;
}
static int indirect_setglobal (lua_State* L)
{
 int varname = 1;
 int value = 2;
 int newvalue = 3;
 lua_pushstring(L,".module");
 lua_gettable(L,value);
 lua_pushvalue(L,varname);
 lua_pushvalue(L,newvalue);
 lua_settable(L,-3);
 return 0;
}

static void setmethods (lua_State* L)
{
 /* global variable */
 lua_pushcfunction(L,global_getglobal);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_global"),"getglobal");
 lua_pushcfunction(L,global_setglobal);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_global"),"setglobal");

 /* module */
 lua_pushcfunction(L,module_index);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_module"),"index");
 lua_pushcfunction(L,module_settable);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_module"),"settable");

 /* class */
 lua_pushcfunction(L,class_index);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_class"),"index");
 lua_pushcfunction(L,class_settable);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_class"),"settable");

 /* instance */
 lua_pushcfunction(L,instance_gettable);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"gettable");
 lua_pushcfunction(L,instance_settable);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"settable");
 lua_pushcfunction(L,instance_operator);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"add");
 lua_pushcfunction(L,instance_operator);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"sub");
 lua_pushcfunction(L,instance_operator);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"mul");
 lua_pushcfunction(L,instance_operator);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"div");
 lua_pushcfunction(L,instance_relational);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"lt");
 lua_pushcfunction(L,instance_gc);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_instance"),"gc");

 /* lua instance */
 lua_pushcfunction(L,linstance_index);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_linstance"),"index");

 /* indirect */
 lua_pushcfunction(L,indirect_getglobal);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_indirect"),"getglobal");
 lua_pushcfunction(L,indirect_setglobal);
 lua_settagmethod(L,toluaI_gettag(L,"tolua_tag_indirect"),"setglobal");
}



tome-235-src/src/lua/tolua_tm.h0000644000076400017500000000171411012107763014236 0ustar  dgdg/* tolua: tag methods
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_tm.h,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it.
** The software provided hereunder is on an "as is" basis, and
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications.
*/



#ifndef tolua_tm_h
#define tolua_tm_h

void toluaI_tm_init (lua_State* L);
void toluaI_tm_global (lua_State* L, int lo);
void toluaI_tm_module (lua_State* L, int lo);
void toluaI_tm_class (lua_State* L, int lo, char* name);
void toluaI_tm_instance (lua_State* L, int tag, int lo);
void toluaI_tm_linstance (lua_State* L, int tag, int lo);
void toluaI_tm_using (lua_State* L, int module);
void toluaI_tm_setclass (lua_State* L, int lo);
void toluaI_tm_pushmate (lua_State* L, int lo);
void toluaI_tm_pushclass (lua_State* L, int lo);


#endif
tome-235-src/src/lua/tolua_tt.c0000644000076400017500000001745411012107763014250 0ustar  dgdg/* tolua: type & tag manipulation.
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_tt.c,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it. 
** The software provided hereunder is on an "as is" basis, and 
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications. 
*/

#include "tolua.h"
#include "tolua_tt.h"
#include "tolua_tm.h"
#include "tolua_eh.h"
#include "tolua_rg.h"

#include 
#include 
#include 

/* Global tables created in Lua registry:
   tolua_tbl_itype: indexed by instance tags, stores the instance types.
   tolua_tbl_itag: indexed by instance types, stores the instance tags.
   tolua_tbl_const: indexed by constant tags, stores the tags.
   tolua_tbl_hierarchy: indexed by instance tags, stores the base tags.
*/

/* exported basic type tags */
int tolua_tag_nil;
int tolua_tag_number;
int tolua_tag_string;
int tolua_tag_userdata;
int tolua_tag_table;
int tolua_tag_function;


static const char* gettype (lua_State* L, int tag)
{
 const char* type;
 toluaI_getregistry(L,"tolua_tbl_itype");
 lua_pushnumber(L,tag);
 lua_gettable(L,-2);
 type = lua_tostring(L,-1);
 if (type==NULL) type = "[undefined]";
 lua_pop(L,2);
 return type;
}

const char* toluaI_tt_getobjtype (lua_State* L, int lo)
{
 if (lua_gettop(L)=abs(narg))
 {
  toluaI_eh_set(L,narg,toluaI_tt_getobjtype(L,narg),
                toluaI_tt_getobjtype(L,lua_gettop(L)+1)); 
  return 0;
 }
 return 1;
}


tome-235-src/src/lua/tolua_tt.h0000644000076400017500000000166011012107763014245 0ustar  dgdg/* tolua: type & tag manipulation.
** Support code for Lua bindings.
** Written by Waldemar Celes
** TeCGraf/PUC-Rio
** Jul 1998
** $Id: tolua_tt.h,v 1.2 2001/11/26 23:00:27 darkgod Exp $
*/

/* This code is free software; you can redistribute it and/or modify it.
** The software provided hereunder is on an "as is" basis, and
** the author has no obligation to provide maintenance, support, updates,
** enhancements, or modifications.
*/


#ifndef tolua_tt_h
#define tolua_tt_h

void  toluaI_tt_init (lua_State* L);
void  toluaI_tt_register (lua_State* L, int tag, char* type);
void  toluaI_tt_class (lua_State* L, int lo, char* derived, char* base);
void  toluaI_tt_sethierarchy (lua_State* L, int tag, int btag);
int   toluaI_tt_isusertype (lua_State* L, int lo);
int   toluaI_tt_gettag (lua_State* L, char* type);
const char* toluaI_tt_getobjtype (lua_State* L, int lo);
char* toluaI_tt_concat (const char* s1, const char* s2);




#endif
tome-235-src/src/lua/tolualua.c0000644000076400017500000054516211012107763014245 0ustar  dgdg/*
** Lua binding: tolualua
** Generated automatically by tolua 4.0a - angband on Sun Nov 11 22:59:08 2001.
*/

#include "tolua.h"

/* Exported function */
int tolua_tolualua_open (lua_State* tolua_S);
void tolua_tolualua_close (lua_State* tolua_S);


/* function to register type */
static void toluaI_reg_types (lua_State* tolua_S)
{
}

/* error messages */
#define TOLUA_ERR_SELF tolua_error(tolua_S,"invalid 'self'")
#define TOLUA_ERR_ASSIGN tolua_error(tolua_S,"#vinvalid type in variable assignment.")

/* Open function */
int tolua_tolualua_open (lua_State* tolua_S)
{
 tolua_open(tolua_S);
 toluaI_reg_types(tolua_S);

 { /* begin embedded lua code */
 static unsigned char B[] = {
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 95, 98, 97,115,105, 99, 32, 61, 32,123, 10, 91, 39,118,
 111,105,100, 39, 93, 32, 61, 32, 39, 39, 44, 10, 91, 39, 99,
 104, 97,114, 39, 93, 32, 61, 32, 39,110,117,109, 98,101,114,
  39, 44, 10, 91, 39,105,110,116, 39, 93, 32, 61, 32, 39,110,
 117,109, 98,101,114, 39, 44, 10, 91, 39,115,104,111,114,116,
  39, 93, 32, 61, 32, 39,110,117,109, 98,101,114, 39, 44, 10,
  91, 39,108,111,110,103, 39, 93, 32, 61, 32, 39,110,117,109,
  98,101,114, 39, 44, 10, 91, 39, 95, 99,115,116,114,105,110,
 103, 39, 93, 32, 61, 32, 39,115,116,114,105,110,103, 39, 44,
  10, 91, 39, 95,117,115,101,114,100, 97,116, 97, 39, 93, 32,
  61, 32, 39,117,115,101,114,100, 97,116, 97, 39, 44, 10, 91,
  39, 99,104, 97,114, 42, 39, 93, 32, 61, 32, 39,115,116,114,
 105,110,103, 39, 44, 10, 91, 39,118,111,105,100, 42, 39, 93,
  32, 61, 32, 39,117,115,101,114,100, 97,116, 97, 39, 44, 10,
  91, 39, 98,111,111,108, 39, 93, 32, 61, 32, 39, 98,111,111,
 108, 39, 44, 10, 91, 39, 76, 85, 65, 95, 86, 65, 76, 85, 69,
  39, 93, 32, 61, 32, 39,118, 97,108,117,101, 39, 44, 10, 91,
  39, 98,121,116,101, 39, 93, 32, 61, 32, 39,110,117,109, 98,
 101,114, 39, 44, 10, 91, 39,115, 49, 54, 98, 39, 93, 32, 61,
  32, 39,110,117,109, 98,101,114, 39, 44, 10, 91, 39,117, 49,
  54, 98, 39, 93, 32, 61, 32, 39,110,117,109, 98,101,114, 39,
  44, 10, 91, 39,115, 51, 50, 98, 39, 93, 32, 61, 32, 39,110,
 117,109, 98,101,114, 39, 44, 10, 91, 39,117, 51, 50, 98, 39,
  93, 32, 61, 32, 39,110,117,109, 98,101,114, 39, 44, 10,125,
  10, 10, 95, 98, 97,115,105, 99, 95,116, 97,103, 32, 61, 32,
 123, 10, 91, 39,118,111,105,100, 39, 93, 32, 61, 32, 39, 39,
  44, 10, 91, 39, 99,104, 97,114, 39, 93, 32, 61, 32, 39, 76,
  85, 65, 95, 84, 78, 85, 77, 66, 69, 82, 39, 44, 10, 91, 39,
 105,110,116, 39, 93, 32, 61, 32, 39, 76, 85, 65, 95, 84, 78,
  85, 77, 66, 69, 82, 39, 44, 10, 91, 39,115,104,111,114,116,
  39, 93, 32, 61, 32, 39, 76, 85, 65, 95, 84, 78, 85, 77, 66,
  69, 82, 39, 44, 10, 91, 39,108,111,110,103, 39, 93, 32, 61,
  32, 39, 76, 85, 65, 95, 84, 78, 85, 77, 66, 69, 82, 39, 44,
  10, 91, 39, 95, 99,115,116,114,105,110,103, 39, 93, 32, 61,
  32, 39, 76, 85, 65, 95, 84, 83, 84, 82, 73, 78, 71, 39, 44,
  10, 91, 39, 95,117,115,101,114,100, 97,116, 97, 39, 93, 32,
  61, 32, 39, 76, 85, 65, 95, 84, 85, 83, 69, 82, 68, 65, 84,
  65, 39, 44, 10, 91, 39, 99,104, 97,114, 42, 39, 93, 32, 61,
  32, 39, 76, 85, 65, 95, 84, 83, 84, 82, 73, 78, 71, 39, 44,
  10, 91, 39,118,111,105,100, 42, 39, 93, 32, 61, 32, 39, 76,
  85, 65, 95, 84, 85, 83, 69, 82, 68, 65, 84, 65, 39, 44, 10,
  91, 39, 98,111,111,108, 39, 93, 32, 61, 32, 39,116,111,108,
 117, 97, 95,116, 97,103, 40,116,111,108,117, 97, 95, 83, 44,
  34, 98,111,111,108, 34, 41, 39, 44, 10, 91, 39, 98,121,116,
 101, 39, 93, 32, 61, 32, 39, 76, 85, 65, 95, 84, 78, 85, 77,
  66, 69, 82, 39, 44, 10, 91, 39,115, 49, 54, 98, 39, 93, 32,
  61, 32, 39, 76, 85, 65, 95, 84, 78, 85, 77, 66, 69, 82, 39,
  44, 10, 91, 39,117, 49, 54, 98, 39, 93, 32, 61, 32, 39, 76,
  85, 65, 95, 84, 78, 85, 77, 66, 69, 82, 39, 44, 10, 91, 39,
 115, 51, 50, 98, 39, 93, 32, 61, 32, 39, 76, 85, 65, 95, 84,
  78, 85, 77, 66, 69, 82, 39, 44, 10, 91, 39,117, 51, 50, 98,
  39, 93, 32, 61, 32, 39, 76, 85, 65, 95, 84, 78, 85, 77, 66,
  69, 82, 39, 44, 10,125, 10, 10, 95, 98, 97,115,105, 99, 95,
  99,116,121,112,101, 32, 61, 32,123, 10,110,117,109, 98,101,
 114, 32, 61, 32, 34,108,111,110,103, 34, 44, 10,115,116,114,
 105,110,103, 32, 61, 32, 34, 99,111,110,115,116, 32, 99,104,
  97,114, 42, 34, 44, 10,117,115,101,114,100, 97,116, 97, 32,
  61, 32, 34,118,111,105,100, 42, 34, 44, 10, 98,111,111,108,
  32, 61, 32, 34,105,110,116, 34, 44, 10,125, 10, 10, 10, 10,
  95,117,115,101,114,116,121,112,101, 32, 61, 32,123,125, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32,116,111,108,117,
  97, 95,105,110,100,101,120, 32, 40,116, 44,102, 41, 10,105,
 102, 32,102, 32, 61, 61, 32, 39, 95, 98, 97,115,101, 39, 32,
 116,104,101,110, 10,114,101,116,117,114,110, 32,116,111,108,
 117, 97, 95,111,108,100, 95,105,110,100,101,120, 40,116, 44,
 102, 41, 10,101,108,115,101, 10,114,101,116,117,114,110, 32,
 116, 46, 95, 98, 97,115,101, 91,102, 93, 10,101,110,100, 10,
 101,110,100, 10, 10,116,111,108,117, 97, 95,116, 97,103, 32,
  61, 32,110,101,119,116, 97,103, 40, 41, 10,116,111,108,117,
  97, 95,111,108,100, 95,105,110,100,101,120, 32, 61, 32,115,
 101,116,116, 97,103,109,101,116,104,111,100, 40,116,111,108,
 117, 97, 95,116, 97,103, 44, 34,105,110,100,101,120, 34, 44,
 116,111,108,117, 97, 95,105,110,100,101,120, 41, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32,116,111,108,117, 97, 95,
 101,114,114,111,114, 32, 40,115, 41, 10,108,111, 99, 97,108,
  32,111,117,116, 32, 61, 32, 95, 79, 85, 84, 80, 85, 84, 10,
  95, 79, 85, 84, 80, 85, 84, 32, 61, 32, 95, 83, 84, 68, 69,
  82, 82, 10,105,102, 32,115,116,114,115,117, 98, 40,115, 44,
  49, 44, 49, 41, 32, 61, 61, 32, 39, 35, 39, 32,116,104,101,
 110, 10,119,114,105,116,101, 40, 34, 92,110, 42, 42, 32,116,
 111,108,117, 97, 58, 32, 34, 46, 46,115,116,114,115,117, 98,
  40,115, 44, 50, 41, 46, 46, 34, 46, 92,110, 92,110, 34, 41,
  10,101,108,115,101, 10,119,114,105,116,101, 40, 34, 92,110,
  42, 42, 32,116,111,108,117, 97, 32,105,110,116,101,114,110,
  97,108, 32,101,114,114,111,114, 58, 32, 34, 46, 46,115, 46,
  46, 34, 46, 92,110, 92,110, 34, 41, 10,114,101,116,117,114,
 110, 10,101,110,100, 10, 10,105,102, 32, 95, 99,117,114,114,
  95, 99,111,100,101, 32,116,104,101,110, 10,108,111, 99, 97,
 108, 32, 95, 44, 95, 44,115, 32, 61, 32,115,116,114,102,105,
 110,100, 40, 95, 99,117,114,114, 95, 99,111,100,101, 44, 34,
  94, 37,115, 42, 40, 46, 45, 92,110, 41, 34, 41, 10,105,102,
  32,115, 61, 61,110,105,108, 32,116,104,101,110, 32,115, 32,
  61, 32, 95, 99,117,114,114, 95, 99,111,100,101, 32,101,110,
 100, 10,115, 32, 61, 32,103,115,117, 98, 40,115, 44, 34, 95,
 117,115,101,114,100, 97,116, 97, 34, 44, 34,118,111,105,100,
  42, 34, 41, 10,115, 32, 61, 32,103,115,117, 98, 40,115, 44,
  34, 95, 99,115,116,114,105,110,103, 34, 44, 34, 99,104, 97,
 114, 42, 34, 41, 10,119,114,105,116,101, 40, 34, 67,111,100,
 101, 32, 98,101,105,110,103, 32,112,114,111, 99,101,115,115,
 101,100, 58, 92,110, 34, 46, 46,115, 46, 46, 34, 92,110, 34,
  41, 10,101,110,100, 10, 95, 79, 85, 84, 80, 85, 84, 32, 61,
  32,111,117,116, 10,101,110,100, 10, 10, 10, 95, 69, 82, 82,
  79, 82, 77, 69, 83, 83, 65, 71, 69, 32, 61, 32,116,111,108,
 117, 97, 95,101,114,114,111,114, 10, 10, 10,102,117,110, 99,
 116,105,111,110, 32,114,101,103,116,121,112,101, 32, 40,116,
  41, 10,105,102, 32,110,111,116, 32,105,115,116,121,112,101,
  40,116, 41, 32,116,104,101,110, 10, 95,117,115,101,114,116,
 121,112,101, 91,116, 93, 32, 61, 32,116, 10,101,110,100, 10,
 114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32,116, 97,103,118, 97,114,
  40,116,121,112,101, 44, 99,111,110,115,116, 41, 10,105,102,
  32,116,121,112,101, 32, 61, 61, 32, 39, 39, 32,111,114, 32,
 116,121,112,101, 32, 61, 61, 32, 39,118,111,105,100, 39, 32,
 116,104,101,110, 10,114,101,116,117,114,110, 32,116,121,112,
 101, 44, 48, 10,101,108,115,101, 10,108,111, 99, 97,108, 32,
 109, 44,116, 32, 61, 32,102,105,110,100,116,121,112,101,100,
 101,102, 40,116,121,112,101, 41, 10,105,102, 32,105,115, 98,
  97,115,105, 99, 40,116, 41, 32,116,104,101,110, 10,114,101,
 116,117,114,110, 32,116, 44, 32, 95, 98, 97,115,105, 99, 95,
 116, 97,103, 91,116, 93, 10,101,110,100, 10,105,102, 32,115,
 116,114,102,105,110,100, 40,109, 44, 39, 99,111,110,115,116,
  39, 41, 32,116,104,101,110, 32, 99,111,110,115,116, 32, 61,
  32, 39, 99,111,110,115,116, 39, 32,101,110,100, 10,114,101,
 103,116,121,112,101, 40,116, 41, 10,105,102, 32, 99,111,110,
 115,116, 32, 97,110,100, 32, 99,111,110,115,116, 32,126, 61,
  32, 39, 39, 32,116,104,101,110, 10,116, 32, 61, 32, 39, 99,
 111,110,115,116, 32, 39, 46, 46,116, 10,101,110,100, 10,114,
 101,116,117,114,110, 32,116, 44, 39,116,111,108,117, 97, 95,
 116, 97,103, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46,
  46,116, 46, 46, 39, 34, 41, 39, 10,101,110,100, 10,101,110,
 100, 10, 10, 10,102,117,110, 99,116,105,111,110, 32,105,115,
  98, 97,115,105, 99, 32, 40,116,121,112,101, 41, 10,108,111,
  99, 97,108, 32,109, 44,116, 32, 61, 32,102,105,110,100,116,
 121,112,101,100,101,102, 40,116,121,112,101, 41, 10,108,111,
  99, 97,108, 32, 98, 32, 61, 32, 95, 98, 97,115,105, 99, 91,
 116, 93, 10,105,102, 32, 98, 32,116,104,101,110, 10,114,101,
 116,117,114,110, 32, 98, 44, 95, 98, 97,115,105, 99, 95, 99,
 116,121,112,101, 91, 98, 93, 10,101,110,100, 10,114,101,116,
 117,114,110, 32,110,105,108, 10,101,110,100, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32,105,115,116,121,112,101, 32,
  40,116, 41, 10,114,101,116,117,114,110, 32, 95, 98, 97,115,
 105, 99, 91,116, 93, 32,111,114, 32, 95,117,115,101,114,116,
 121,112,101, 91,116, 93, 32,111,114, 32,105,115,116,121,112,
 101,100,101,102, 40,116, 41, 10,101,110,100, 10, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32,115,112,108,105,116, 32,
  40,115, 44,116, 41, 10,108,111, 99, 97,108, 32,108, 32, 61,
  32,123,110, 61, 48,125, 10,108,111, 99, 97,108, 32,102, 32,
  61, 32,102,117,110, 99,116,105,111,110, 32, 40,115, 41, 10,
  37,108, 46,110, 32, 61, 32, 37,108, 46,110, 32, 43, 32, 49,
  10, 37,108, 91, 37,108, 46,110, 93, 32, 61, 32,115, 10,101,
 110,100, 10,108,111, 99, 97,108, 32,112, 32, 61, 32, 34, 37,
 115, 42, 40, 46, 45, 41, 37,115, 42, 34, 46, 46,116, 46, 46,
  34, 37,115, 42, 34, 10,115, 32, 61, 32,103,115,117, 98, 40,
 115, 44, 34, 94, 37,115, 43, 34, 44, 34, 34, 41, 10,115, 32,
  61, 32,103,115,117, 98, 40,115, 44, 34, 37,115, 43, 36, 34,
  44, 34, 34, 41, 10,115, 32, 61, 32,103,115,117, 98, 40,115,
  44,112, 44,102, 41, 10,108, 46,110, 32, 61, 32,108, 46,110,
  32, 43, 32, 49, 10,108, 91,108, 46,110, 93, 32, 61, 32,103,
 115,117, 98, 40,115, 44, 34, 40, 37,115, 37,115, 42, 41, 36,
  34, 44, 34, 34, 41, 10,114,101,116,117,114,110, 32,108, 10,
 101,110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 99,111,110, 99, 97,116, 32, 40,116, 44,102, 44,108, 41,
  10,108,111, 99, 97,108, 32,115, 32, 61, 32, 39, 39, 10,108,
 111, 99, 97,108, 32,105, 61,102, 10,119,104,105,108,101, 32,
 105, 60, 61,108, 32,100,111, 10,115, 32, 61, 32,115, 46, 46,
 116, 91,105, 93, 10,105, 32, 61, 32,105, 43, 49, 10,105,102,
  32,105, 32, 60, 61, 32,108, 32,116,104,101,110, 32,115, 32,
  61, 32,115, 46, 46, 39, 32, 39, 32,101,110,100, 10,101,110,
 100, 10,114,101,116,117,114,110, 32,115, 10,101,110,100, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32,111,117,116,112,
 117,116, 32, 40, 46, 46, 46, 41, 10,108,111, 99, 97,108, 32,
 105, 61, 49, 10,119,104,105,108,101, 32,105, 60, 61, 97,114,
 103, 46,110, 32,100,111, 10,105,102, 32, 95, 99,111,110,116,
  32, 97,110,100, 32,110,111,116, 32,115,116,114,102,105,110,
 100, 40, 95, 99,111,110,116, 44, 39, 91, 37, 40, 44, 34, 93,
  39, 41, 32, 97,110,100, 10,115,116,114,102,105,110,100, 40,
  97,114,103, 91,105, 93, 44, 34, 94, 91, 37, 97, 95,126, 93,
  34, 41, 32,116,104,101,110, 10,119,114,105,116,101, 40, 39,
  32, 39, 41, 10,101,110,100, 10,119,114,105,116,101, 40, 97,
 114,103, 91,105, 93, 41, 10,105,102, 32, 97,114,103, 91,105,
  93, 32,126, 61, 32, 39, 39, 32,116,104,101,110, 10, 95, 99,
 111,110,116, 32, 61, 32,115,116,114,115,117, 98, 40, 97,114,
 103, 91,105, 93, 44, 45, 49, 44, 45, 49, 41, 10,101,110,100,
  10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,105,102,
  32,115,116,114,102,105,110,100, 40, 97,114,103, 91, 97,114,
 103, 46,110, 93, 44, 34, 91, 37, 47, 37, 41, 37, 59, 37,123,
  37,125, 93, 36, 34, 41, 32,116,104,101,110, 10, 95, 99,111,
 110,116, 61,110,105,108, 32,119,114,105,116,101, 40, 39, 92,
 110, 39, 41, 10,101,110,100, 10,101,110,100, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,
 115, 70,101, 97,116,117,114,101, 32, 61, 32,123, 10,125, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,
 115, 70,101, 97,116,117,114,101, 58,115,117,112, 99,111,100,
 101, 32, 40, 41, 10,101,110,100, 10, 10, 10,102,117,110, 99,
 116,105,111,110, 32, 99,108, 97,115,115, 70,101, 97,116,117,
 114,101, 58,100,101, 99,108,116, 97,103, 32, 40, 41, 10,101,
 110,100, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,
 108, 97,115,115, 70,101, 97,116,117,114,101, 58,114,101,103,
 105,115,116,101,114, 32, 40, 41, 10,101,110,100, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 70,
 101, 97,116,117,114,101, 58,117,110,114,101,103,105,115,116,
 101,114, 32, 40, 41, 10,101,110,100, 10, 10, 10,102,117,110,
  99,116,105,111,110, 32, 99,108, 97,115,115, 70,101, 97,116,
 117,114,101, 58,112,114,101, 97,109, 98,108,101, 32, 40, 41,
  10,101,110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,
 110, 32, 99,108, 97,115,115, 70,101, 97,116,117,114,101, 58,
 105,110, 99,108, 97,115,115, 32, 40, 41, 10,105,102, 32,115,
 101,108,102, 46,112, 97,114,101,110,116, 32, 97,110,100, 32,
 115,101,108,102, 46,112, 97,114,101,110,116, 46,116,121,112,
 101, 32, 61, 61, 32, 39, 99,108, 97,115,115, 39, 32,116,104,
 101,110, 10,114,101,116,117,114,110, 32,115,101,108,102, 46,
 112, 97,114,101,110,116, 46,110, 97,109,101, 10,101,108,115,
 101, 10,114,101,116,117,114,110, 32,110,105,108, 10,101,110,
 100, 10,101,110,100, 10, 10, 10, 10,102,117,110, 99,116,105,
 111,110, 32, 99,108, 97,115,115, 70,101, 97,116,117,114,101,
  58,105,110,109,111,100,117,108,101, 32, 40, 41, 10,105,102,
  32,115,101,108,102, 46,112, 97,114,101,110,116, 32, 97,110,
 100, 32,115,101,108,102, 46,112, 97,114,101,110,116, 46,116,
 121,112,101, 32, 61, 61, 32, 39,109,111,100,117,108,101, 39,
  32,116,104,101,110, 10,114,101,116,117,114,110, 32,115,101,
 108,102, 46,112, 97,114,101,110,116, 46,110, 97,109,101, 10,
 101,108,115,101, 10,114,101,116,117,114,110, 32,110,105,108,
  10,101,110,100, 10,101,110,100, 10, 10, 10, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 70,101,
  97,116,117,114,101, 58, 99,102,117,110, 99,110, 97,109,101,
  32, 40,110, 41, 10,105,102, 32,115,101,108,102, 46,112, 97,
 114,101,110,116, 32,116,104,101,110, 10,110, 32, 61, 32,115,
 101,108,102, 46,112, 97,114,101,110,116, 58, 99,102,117,110,
  99,110, 97,109,101, 40,110, 41, 10,101,110,100, 10,105,102,
  32,115,101,108,102, 46,108,110, 97,109,101, 32,116,104,101,
 110, 10,114,101,116,117,114,110, 32,110, 46, 46, 39, 95, 39,
  46, 46,115,101,108,102, 46,108,110, 97,109,101, 10,101,108,
 115,101, 10,114,101,116,117,114,110, 32,110, 46, 46, 39, 95,
  39, 46, 46,115,101,108,102, 46,110, 97,109,101, 10,101,110,
 100, 10,101,110,100, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,115, 86,
 101,114, 98, 97,116,105,109, 32, 61, 32,123, 10,108,105,110,
 101, 32, 61, 32, 39, 39, 44, 10, 95, 98, 97,115,101, 32, 61,
  32, 99,108, 97,115,115, 70,101, 97,116,117,114,101, 44, 10,
 125, 10,115,101,116,116, 97,103, 40, 99,108, 97,115,115, 86,
 101,114, 98, 97,116,105,109, 44,116,111,108,117, 97, 95,116,
  97,103, 41, 10, 10, 10,102,117,110, 99,116,105,111,110, 32,
  99,108, 97,115,115, 86,101,114, 98, 97,116,105,109, 58,112,
 114,101, 97,109, 98,108,101, 32, 40, 41, 10,105,102, 32,110,
 111,116, 32,115,101,108,102, 46, 99,111,110,100, 32,116,104,
 101,110, 10,119,114,105,116,101, 40,115,101,108,102, 46,108,
 105,110,101, 41, 10,101,110,100, 10,101,110,100, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 86,
 101,114, 98, 97,116,105,109, 58,115,117,112, 99,111,100,101,
  32, 40, 41, 10,105,102, 32,115,101,108,102, 46, 99,111,110,
 100, 32,116,104,101,110, 10,119,114,105,116,101, 40,115,101,
 108,102, 46,108,105,110,101, 41, 10,119,114,105,116,101, 40,
  39, 92,110, 39, 41, 10,101,110,100, 10,101,110,100, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115,
  86,101,114, 98, 97,116,105,109, 58,114,101,103,105,115,116,
 101,114, 32, 40, 41, 10,105,102, 32,115,101,108,102, 46, 99,
 111,110,100, 32,116,104,101,110, 10,119,114,105,116,101, 40,
 115,101,108,102, 46,108,105,110,101, 41, 10,101,110,100, 10,
 101,110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 99,108, 97,115,115, 86,101,114, 98, 97,116,105,109, 58,
 112,114,105,110,116, 32, 40,105,100,101,110,116, 44, 99,108,
 111,115,101, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34, 86,101,114, 98, 97,116,105,109,123, 34, 41,
  10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34,
  32,108,105,110,101, 32, 61, 32, 39, 34, 46, 46,115,101,108,
 102, 46,108,105,110,101, 46, 46, 34, 39, 44, 34, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34,125, 34,
  46, 46, 99,108,111,115,101, 41, 10,101,110,100, 10, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 95, 86,101,114, 98,
  97,116,105,109, 32, 40,116, 41, 10,116, 46, 95, 98, 97,115,
 101, 32, 61, 32, 99,108, 97,115,115, 86,101,114, 98, 97,116,
 105,109, 10,115,101,116,116, 97,103, 40,116, 44,116,111,108,
 117, 97, 95,116, 97,103, 41, 10, 97,112,112,101,110,100, 40,
 116, 41, 10,114,101,116,117,114,110, 32,116, 10,101,110,100,
  10, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 86,101,
 114, 98, 97,116,105,109, 32, 40,108, 41, 10,108,111, 99, 97,
 108, 32, 99, 10,105,102, 32,115,116,114,115,117, 98, 40,108,
  44, 49, 44, 49, 41, 32, 61, 61, 32, 39, 36, 39, 32,116,104,
 101,110, 10, 99, 32, 61, 32, 49, 10,108, 32, 61, 32,115,116,
 114,115,117, 98, 40,108, 44, 50, 41, 10,101,110,100, 10,114,
 101,116,117,114,110, 32, 95, 86,101,114, 98, 97,116,105,109,
  32,123, 10,108,105,110,101, 32, 61, 32,108, 44, 10, 99,111,
 110,100, 32, 61, 32, 99, 10,125, 10,101,110,100, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  99,108, 97,115,115, 67,111,100,101, 32, 61, 32,123, 10,116,
 101,120,116, 32, 61, 32, 39, 39, 44, 10, 95, 98, 97,115,101,
  32, 61, 32, 99,108, 97,115,115, 70,101, 97,116,117,114,101,
  44, 10,125, 10,115,101,116,116, 97,103, 40, 99,108, 97,115,
 115, 67,111,100,101, 44,116,111,108,117, 97, 95,116, 97,103,
  41, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108,
  97,115,115, 67,111,100,101, 58,114,101,103,105,115,116,101,
 114, 32, 40, 41, 10, 10,108,111, 99, 97,108, 32,115, 32, 61,
  32, 99,108,101, 97,110, 40,115,101,108,102, 46,116,101,120,
 116, 41, 10,105,102, 32,110,111,116, 32,115, 32,116,104,101,
 110, 10,101,114,114,111,114, 40, 34,112, 97,114,115,101,114,
  32,101,114,114,111,114, 32,105,110, 32,101,109, 98,101,100,
 100,101,100, 32, 99,111,100,101, 34, 41, 10,101,110,100, 10,
  10, 10,111,117,116,112,117,116, 40, 39, 92,110, 32,123, 32,
  47, 42, 32, 98,101,103,105,110, 32,101,109, 98,101,100,100,
 101,100, 32,108,117, 97, 32, 99,111,100,101, 32, 42, 47, 92,
 110, 39, 41, 10,111,117,116,112,117,116, 40, 39, 32,115,116,
  97,116,105, 99, 32,117,110,115,105,103,110,101,100, 32, 99,
 104, 97,114, 32, 66, 91, 93, 32, 61, 32,123, 92,110, 32, 39,
  41, 10,108,111, 99, 97,108, 32,116, 61,123,110, 61, 48,125,
  10,108,111, 99, 97,108, 32, 98, 32, 61, 32,103,115,117, 98,
  40,115, 44, 39, 40, 46, 41, 39, 44,102,117,110, 99,116,105,
 111,110, 32, 40, 99, 41, 10,108,111, 99, 97,108, 32,101, 32,
  61, 32, 39, 39, 10, 37,116, 46,110, 61, 37,116, 46,110, 43,
  49, 32,105,102, 32, 37,116, 46,110, 61, 61, 49, 53, 32,116,
 104,101,110, 32, 37,116, 46,110, 61, 48, 32,101, 61, 39, 92,
 110, 32, 39, 32,101,110,100, 10,114,101,116,117,114,110, 32,
 102,111,114,109, 97,116, 40, 39, 37, 51,117, 44, 37,115, 39,
  44,115,116,114, 98,121,116,101, 40, 99, 41, 44,101, 41, 10,
 101,110,100, 10, 41, 10,111,117,116,112,117,116, 40, 98, 46,
  46,115,116,114, 98,121,116,101, 40, 34, 32, 34, 41, 41, 10,
 111,117,116,112,117,116, 40, 39, 92,110, 32,125, 59, 92,110,
  39, 41, 10,111,117,116,112,117,116, 40, 39, 32,108,117, 97,
  95,100,111, 98,117,102,102,101,114, 40,116,111,108,117, 97,
  95, 83, 44, 40, 99,104, 97,114, 42, 41, 66, 44,115,105,122,
 101,111,102, 40, 66, 41, 44, 34,116,111,108,117, 97, 58, 32,
 101,109, 98,101,100,100,101,100, 32, 76,117, 97, 32, 99,111,
 100,101, 34, 41, 59, 39, 41, 10,111,117,116,112,117,116, 40,
  39, 32,125, 32, 47, 42, 32,101,110,100, 32,111,102, 32,101,
 109, 98,101,100,100,101,100, 32,108,117, 97, 32, 99,111,100,
 101, 32, 42, 47, 92,110, 92,110, 39, 41, 10,101,110,100, 10,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,
 115,115, 67,111,100,101, 58,112,114,105,110,116, 32, 40,105,
 100,101,110,116, 44, 99,108,111,115,101, 41, 10,112,114,105,
 110,116, 40,105,100,101,110,116, 46, 46, 34, 67,111,100,101,
 123, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116,
  46, 46, 34, 32,116,101,120,116, 32, 61, 32, 91, 91, 34, 46,
  46,115,101,108,102, 46,116,101,120,116, 46, 46, 34, 93, 93,
  44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116,
  46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,101,
 110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110, 32,
  95, 67,111,100,101, 32, 40,116, 41, 10,116, 46, 95, 98, 97,
 115,101, 32, 61, 32, 99,108, 97,115,115, 67,111,100,101, 10,
 115,101,116,116, 97,103, 40,116, 44,116,111,108,117, 97, 95,
 116, 97,103, 41, 10, 97,112,112,101,110,100, 40,116, 41, 10,
 114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 67,111,100,101, 32,
  40,108, 41, 10,114,101,116,117,114,110, 32, 95, 67,111,100,
 101, 32,123, 10,116,101,120,116, 32, 61, 32,108, 10,125, 10,
 101,110,100, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,
 115,115, 84,121,112,101,100,101,102, 32, 61, 32,123, 10,117,
 116,121,112,101, 32, 61, 32, 39, 39, 44, 10,109,111,100, 32,
  61, 32, 39, 39, 44, 10,116,121,112,101, 32, 61, 32, 39, 39,
  10,125, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,
 108, 97,115,115, 84,121,112,101,100,101,102, 58,112,114,105,
 110,116, 32, 40,105,100,101,110,116, 44, 99,108,111,115,101,
  41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46,
  34, 84,121,112,101,100,101,102,123, 34, 41, 10,112,114,105,
 110,116, 40,105,100,101,110,116, 46, 46, 34, 32,117,116,121,
 112,101, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,117,
 116,121,112,101, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,
 110,116, 40,105,100,101,110,116, 46, 46, 34, 32,109,111,100,
  32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,109,111,100,
  46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,
 100,101,110,116, 46, 46, 34, 32,116,121,112,101, 32, 61, 32,
  39, 34, 46, 46,115,101,108,102, 46,116,121,112,101, 46, 46,
  34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,
 110,116, 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41,
  10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 95, 84,121,112,101,100,101,102, 32, 40,116, 41, 10,116,
  46, 95, 98, 97,115,101, 32, 61, 32, 99,108, 97,115,115, 84,
 121,112,101,100,101,102, 10,115,101,116,116, 97,103, 40,116,
  44,116,111,108,117, 97, 95,116, 97,103, 41, 10, 97,112,112,
 101,110,100,116,121,112,101,100,101,102, 40,116, 41, 10,114,
 101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32, 84,121,112,101,100,101,
 102, 32, 40,115, 41, 10,105,102, 32,115,116,114,102,105,110,
 100, 40,115, 44, 39, 91, 37, 42, 38, 93, 39, 41, 32,116,104,
 101,110, 10,116,111,108,117, 97, 95,101,114,114,111,114, 40,
  34, 35,105,110,118, 97,108,105,100, 32,116,121,112,101,100,
 101,102, 58, 32,112,111,105,110,116,101,114,115, 32, 40, 97,
 110,100, 32,114,101,102,101,114,101,110, 99,101,115, 41, 32,
  97,114,101, 32,110,111,116, 32,115,117,112,112,111,114,116,
 101,100, 34, 41, 10,101,110,100, 10,108,111, 99, 97,108, 32,
 116, 32, 61, 32,115,112,108,105,116, 40,103,115,117, 98, 40,
 115, 44, 34, 37,115, 37,115, 42, 34, 44, 34, 32, 34, 41, 44,
  34, 32, 34, 41, 10,114,101,116,117,114,110, 32, 95, 84,121,
 112,101,100,101,102, 32,123, 10,117,116,121,112,101, 32, 61,
  32,116, 91,116, 46,110, 93, 44, 10,116,121,112,101, 32, 61,
  32,116, 91,116, 46,110, 45, 49, 93, 44, 10,109,111,100, 32,
  61, 32, 99,111,110, 99, 97,116, 40,116, 44, 49, 44,116, 46,
 110, 45, 50, 41, 10,125, 10,101,110,100, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,
 115, 67,111,110,116, 97,105,110,101,114, 32, 61, 10,123, 10,
  99,117,114,114, 32, 61, 32,110,105,108, 44, 10, 95, 98, 97,
 115,101, 32, 61, 32, 99,108, 97,115,115, 70,101, 97,116,117,
 114,101, 44, 10,125, 10,115,101,116,116, 97,103, 40, 99,108,
  97,115,115, 67,111,110,116, 97,105,110,101,114, 44,116,111,
 108,117, 97, 95,116, 97,103, 41, 10, 10, 10,102,117,110, 99,
 116,105,111,110, 32, 99,108, 97,115,115, 67,111,110,116, 97,
 105,110,101,114, 58,100,101, 99,108,116, 97,103, 32, 40, 41,
  10,112,117,115,104, 40,115,101,108,102, 41, 10,108,111, 99,
  97,108, 32,105, 61, 49, 10,119,104,105,108,101, 32,115,101,
 108,102, 91,105, 93, 32,100,111, 10,115,101,108,102, 91,105,
  93, 58,100,101, 99,108,116, 97,103, 40, 41, 10,105, 32, 61,
  32,105, 43, 49, 10,101,110,100, 10,112,111,112, 40, 41, 10,
 101,110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114,
  58,115,117,112, 99,111,100,101, 32, 40, 41, 10,112,117,115,
 104, 40,115,101,108,102, 41, 10,108,111, 99, 97,108, 32,105,
  61, 49, 10,119,104,105,108,101, 32,115,101,108,102, 91,105,
  93, 32,100,111, 10,115,101,108,102, 91,105, 93, 58,115,117,
 112, 99,111,100,101, 40, 41, 10,105, 32, 61, 32,105, 43, 49,
  10,101,110,100, 10,112,111,112, 40, 41, 10,101,110,100, 10,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 67,111,
 110,116, 97,105,110,101,114, 32, 40,115,101,108,102, 41, 10,
 115,101,108,102, 46, 95, 98, 97,115,101, 32, 61, 32, 99,108,
  97,115,115, 67,111,110,116, 97,105,110,101,114, 10,115,101,
 116,116, 97,103, 40,115,101,108,102, 44,116,111,108,117, 97,
  95,116, 97,103, 41, 10,115,101,108,102, 46,110, 32, 61, 32,
  48, 10,115,101,108,102, 46,116,121,112,101,100,101,102,115,
  32, 61, 32,123,110, 61, 48,125, 10,115,101,108,102, 46,108,
 110, 97,109,101,115, 32, 61, 32,123,125, 10,114,101,116,117,
 114,110, 32,115,101,108,102, 10,101,110,100, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32,112,117,115,104, 32, 40,116,
  41, 10, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,
 114, 46, 99,117,114,114, 32, 61, 32,116, 10,101,110,100, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32,112,111,112, 32,
  40, 41, 10, 99,108, 97,115,115, 67,111,110,116, 97,105,110,
 101,114, 46, 99,117,114,114, 32, 61, 32, 99,108, 97,115,115,
  67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 46,
 112, 97,114,101,110,116, 10,101,110,100, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 97,112,112,101,110,100, 32, 40,
 116, 41, 10,114,101,116,117,114,110, 32, 99,108, 97,115,115,
  67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 58,
  97,112,112,101,110,100, 40,116, 41, 10,101,110,100, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 97,112,112,101,110,
 100,116,121,112,101,100,101,102, 32, 40,116, 41, 10,114,101,
 116,117,114,110, 32, 99,108, 97,115,115, 67,111,110,116, 97,
 105,110,101,114, 46, 99,117,114,114, 58, 97,112,112,101,110,
 100,116,121,112,101,100,101,102, 40,116, 41, 10,101,110,100,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32,102,105,110,
 100,116,121,112,101,100,101,102, 32, 40,116,121,112,101, 41,
  10,114,101,116,117,114,110, 32, 99,108, 97,115,115, 67,111,
 110,116, 97,105,110,101,114, 46, 99,117,114,114, 58,102,105,
 110,100,116,121,112,101,100,101,102, 40,116,121,112,101, 41,
  10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32,105,115,116,121,112,101,100,101,102, 32, 40,116,121,112,
 101, 41, 10,114,101,116,117,114,110, 32, 99,108, 97,115,115,
  67,111,110,116, 97,105,110,101,114, 46, 99,117,114,114, 58,
 105,115,116,121,112,101,100,101,102, 40,116,121,112,101, 41,
  10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114,
  58, 97,112,112,101,110,100, 32, 40,116, 41, 10,115,101,108,
 102, 46,110, 32, 61, 32,115,101,108,102, 46,110, 32, 43, 32,
  49, 10,115,101,108,102, 91,115,101,108,102, 46,110, 93, 32,
  61, 32,116, 10,116, 46,112, 97,114,101,110,116, 32, 61, 32,
 115,101,108,102, 10,101,110,100, 10, 10, 10,102,117,110, 99,
 116,105,111,110, 32, 99,108, 97,115,115, 67,111,110,116, 97,
 105,110,101,114, 58, 97,112,112,101,110,100,116,121,112,101,
 100,101,102, 32, 40,116, 41, 10,115,101,108,102, 46,116,121,
 112,101,100,101,102,115, 46,110, 32, 61, 32,115,101,108,102,
  46,116,121,112,101,100,101,102,115, 46,110, 32, 43, 32, 49,
  10,115,101,108,102, 46,116,121,112,101,100,101,102,115, 91,
 115,101,108,102, 46,116,121,112,101,100,101,102,115, 46,110,
  93, 32, 61, 32,116, 10,101,110,100, 10, 10, 10,102,117,110,
  99,116,105,111,110, 32, 99,108, 97,115,115, 67,111,110,116,
  97,105,110,101,114, 58,111,118,101,114,108,111, 97,100, 32,
  40,108,110, 97,109,101, 41, 10,105,102, 32,110,111,116, 32,
 115,101,108,102, 46,108,110, 97,109,101,115, 91,108,110, 97,
 109,101, 93, 32,116,104,101,110, 10,115,101,108,102, 46,108,
 110, 97,109,101,115, 91,108,110, 97,109,101, 93, 32, 61, 32,
  48, 10,101,108,115,101, 10,115,101,108,102, 46,108,110, 97,
 109,101,115, 91,108,110, 97,109,101, 93, 32, 61, 32,115,101,
 108,102, 46,108,110, 97,109,101,115, 91,108,110, 97,109,101,
  93, 32, 43, 32, 49, 10,101,110,100, 10,114,101,116,117,114,
 110, 32,102,111,114,109, 97,116, 40, 34, 37, 48, 50,100, 34,
  44,115,101,108,102, 46,108,110, 97,109,101,115, 91,108,110,
  97,109,101, 93, 41, 10,101,110,100, 10, 10,102,117,110, 99,
 116,105,111,110, 32, 99,108, 97,115,115, 67,111,110,116, 97,
 105,110,101,114, 58,102,105,110,100,116,121,112,101,100,101,
 102, 32, 40,116,121,112,101, 41, 10,108,111, 99, 97,108, 32,
 101,110,118, 32, 61, 32,115,101,108,102, 10,119,104,105,108,
 101, 32,101,110,118, 32,100,111, 10,105,102, 32,101,110,118,
  46,116,121,112,101,100,101,102,115, 32,116,104,101,110, 10,
 108,111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,108,101,
  32,101,110,118, 46,116,121,112,101,100,101,102,115, 91,105,
  93, 32,100,111, 10,105,102, 32,101,110,118, 46,116,121,112,
 101,100,101,102,115, 91,105, 93, 46,117,116,121,112,101, 32,
  61, 61, 32,116,121,112,101, 32,116,104,101,110, 10,108,111,
  99, 97,108, 32,109,111,100, 49, 44,116,121,112,101, 49, 32,
  61, 32,101,110,118, 46,116,121,112,101,100,101,102,115, 91,
 105, 93, 46,109,111,100, 44,101,110,118, 46,116,121,112,101,
 100,101,102,115, 91,105, 93, 46,116,121,112,101, 10,108,111,
  99, 97,108, 32,109,111,100, 50, 44,116,121,112,101, 50, 32,
  61, 32,102,105,110,100,116,121,112,101,100,101,102, 40,116,
 121,112,101, 49, 41, 10,114,101,116,117,114,110, 32,109,111,
 100, 50, 46, 46, 39, 32, 39, 46, 46,109,111,100, 49, 44,116,
 121,112,101, 50, 10,101,110,100, 10,105, 32, 61, 32,105, 43,
  49, 10,101,110,100, 10,101,110,100, 10,101,110,118, 32, 61,
  32,101,110,118, 46,112, 97,114,101,110,116, 10,101,110,100,
  10,114,101,116,117,114,110, 32, 39, 39, 44,116,121,112,101,
  10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,
  99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, 58,
 105,115,116,121,112,101,100,101,102, 32, 40,116,121,112,101,
  41, 10,108,111, 99, 97,108, 32,101,110,118, 32, 61, 32,115,
 101,108,102, 10,119,104,105,108,101, 32,101,110,118, 32,100,
 111, 10,105,102, 32,101,110,118, 46,116,121,112,101,100,101,
 102,115, 32,116,104,101,110, 10,108,111, 99, 97,108, 32,105,
  61, 49, 10,119,104,105,108,101, 32,101,110,118, 46,116,121,
 112,101,100,101,102,115, 91,105, 93, 32,100,111, 10,105,102,
  32,101,110,118, 46,116,121,112,101,100,101,102,115, 91,105,
  93, 46,117,116,121,112,101, 32, 61, 61, 32,116,121,112,101,
  32,116,104,101,110, 10,114,101,116,117,114,110, 32, 49, 10,
 101,110,100, 10,105, 32, 61, 32,105, 43, 49, 10,101,110,100,
  10,101,110,100, 10,101,110,118, 32, 61, 32,101,110,118, 46,
 112, 97,114,101,110,116, 10,101,110,100, 10,114,101,116,117,
 114,110, 32,110,105,108, 10,101,110,100, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 67,111,110,
 116, 97,105,110,101,114, 58,100,111,112, 97,114,115,101, 32,
  40,115, 41, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32,
  98, 44,101, 44,110, 97,109,101, 44, 98,111,100,121, 32, 61,
  32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115,
  42,109,111,100,117,108,101, 37,115, 37,115, 42, 40, 91, 95,
  37,119, 93, 91, 95, 37,119, 93, 42, 41, 37,115, 42, 40, 37,
  98,123,125, 41, 37,115, 42, 34, 41, 10,105,102, 32, 98, 32,
 116,104,101,110, 10, 95, 99,117,114,114, 95, 99,111,100,101,
  32, 61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,101,
  41, 10, 77,111,100,117,108,101, 40,110, 97,109,101, 44, 98,
 111,100,121, 41, 10,114,101,116,117,114,110, 32,115,116,114,
 115,117, 98, 40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,
 101,110,100, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32,
  98, 44,101, 44,110, 97,109,101, 32, 61, 32,115,116,114,102,
 105,110,100, 40,115, 44, 34, 94, 37,115, 42, 35,100,101,102,
 105,110,101, 37,115, 37,115, 42, 40, 91, 94, 37,115, 93, 42,
  41, 91, 94, 92,110, 93, 42, 92,110, 37,115, 42, 34, 41, 10,
 105,102, 32, 98, 32,116,104,101,110, 10, 95, 99,117,114,114,
  95, 99,111,100,101, 32, 61, 32,115,116,114,115,117, 98, 40,
 115, 44, 98, 44,101, 41, 10, 68,101,102,105,110,101, 40,110,
  97,109,101, 41, 10,114,101,116,117,114,110, 32,115,116,114,
 115,117, 98, 40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,
 101,110,100, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32,
  98, 44,101, 44, 98,111,100,121, 32, 61, 32,115,116,114,102,
 105,110,100, 40,115, 44, 34, 94, 37,115, 42,101,110,117,109,
  91, 94,123, 93, 42, 40, 37, 98,123,125, 41, 37,115, 42, 59,
  63, 37,115, 42, 34, 41, 10,105,102, 32, 98, 32,116,104,101,
 110, 10, 95, 99,117,114,114, 95, 99,111,100,101, 32, 61, 32,
 115,116,114,115,117, 98, 40,115, 44, 98, 44,101, 41, 10, 69,
 110,117,109,101,114, 97,116,101, 40, 98,111,100,121, 41, 10,
 114,101,116,117,114,110, 32,115,116,114,115,117, 98, 40,115,
  44,101, 43, 49, 41, 10,101,110,100, 10,101,110,100, 10, 10,
 100,111, 10,108,111, 99, 97,108, 32, 98, 44,101, 44, 98,111,
 100,121, 44,110, 97,109,101, 32, 61, 32,115,116,114,102,105,
 110,100, 40,115, 44, 34, 94, 37,115, 42,116,121,112,101,100,
 101,102, 37,115, 37,115, 42,101,110,117,109, 91, 94,123, 93,
  42, 40, 37, 98,123,125, 41, 37,115, 42, 40, 91, 37,119, 95,
  93, 91, 94, 37,115, 93, 42, 41, 37,115, 42, 59, 37,115, 42,
  34, 41, 10,105,102, 32, 98, 32,116,104,101,110, 10, 95, 99,
 117,114,114, 95, 99,111,100,101, 32, 61, 32,115,116,114,115,
 117, 98, 40,115, 44, 98, 44,101, 41, 10, 69,110,117,109,101,
 114, 97,116,101, 40, 98,111,100,121, 41, 10, 84,121,112,101,
 100,101,102, 40, 34,105,110,116, 32, 34, 46, 46,110, 97,109,
 101, 41, 10,114,101,116,117,114,110, 32,115,116,114,115,117,
  98, 40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,101,110,
 100, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32, 98, 44,
 101, 44,100,101, 99,108, 44,107,105,110,100, 44, 97,114,103,
  44, 99,111,110,115,116, 32, 61, 32,115,116,114,102,105,110,
 100, 40,115, 44, 34, 94, 37,115, 42, 40, 91, 95, 37,119, 93,
  91, 95, 37,119, 37,115, 37, 42, 38, 93, 42,111,112,101,114,
  97,116,111,114, 41, 37,115, 42, 40, 91, 94, 37,115, 93, 91,
  94, 37,115, 93, 42, 41, 37,115, 42, 40, 37, 98, 40, 41, 41,
  37,115, 42, 40, 99, 63,111, 63,110, 63,115, 63,116, 63, 41,
  37,115, 42, 59, 37,115, 42, 34, 41, 10,105,102, 32, 98, 32,
 116,104,101,110, 10, 95, 99,117,114,114, 95, 99,111,100,101,
  32, 61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,101,
  41, 10, 79,112,101,114, 97,116,111,114, 40,100,101, 99,108,
  44,107,105,110,100, 44, 97,114,103, 44, 99,111,110,115,116,
  41, 10,114,101,116,117,114,110, 32,115,116,114,115,117, 98,
  40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,101,110,100,
  10, 10, 10,100,111, 10,108,111, 99, 97,108, 32, 98, 44,101,
  44,100,101, 99,108, 44, 97,114,103, 44, 99,111,110,115,116,
  32, 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94,
  37,115, 42, 40, 91,126, 95, 37,119, 93, 91, 95, 64, 37,119,
  37,115, 37, 42, 38, 93, 42, 91, 95, 37,119, 93, 41, 37,115,
  42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,
 110, 63,115, 63,116, 63, 41, 37,115, 42, 61, 63, 37,115, 42,
  48, 63, 37,115, 42, 59, 37,115, 42, 34, 41, 10,105,102, 32,
 110,111,116, 32, 98, 32,116,104,101,110, 10, 10, 98, 44,101,
  44,100,101, 99,108, 44, 97,114,103, 44, 99,111,110,115,116,
  32, 61, 32,115,116,114,102,105,110,100, 40,115, 44, 34, 94,
  37,115, 42, 40, 91, 95, 37,119, 93, 41, 37,115, 42, 40, 37,
  98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, 63,115,
  63,116, 63, 41, 37,115, 42, 59, 37,115, 42, 34, 41, 10,101,
 110,100, 10,105,102, 32, 98, 32,116,104,101,110, 10, 95, 99,
 117,114,114, 95, 99,111,100,101, 32, 61, 32,115,116,114,115,
 117, 98, 40,115, 44, 98, 44,101, 41, 10, 70,117,110, 99,116,
 105,111,110, 40,100,101, 99,108, 44, 97,114,103, 44, 99,111,
 110,115,116, 41, 10,114,101,116,117,114,110, 32,115,116,114,
 115,117, 98, 40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,
 101,110,100, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32,
  98, 44,101, 44,100,101, 99,108, 44, 97,114,103, 44, 99,111,
 110,115,116, 32, 61, 32,115,116,114,102,105,110,100, 40,115,
  44, 34, 94, 37,115, 42, 40, 91,126, 95, 37,119, 93, 91, 95,
  64, 37,119, 37,115, 37, 42, 38, 93, 42, 91, 95, 37,119, 93,
  41, 37,115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99,
  63,111, 63,110, 63,115, 63,116, 63, 41, 37,115, 42, 37, 98,
 123,125, 37,115, 42, 34, 41, 10,105,102, 32,110,111,116, 32,
  98, 32,116,104,101,110, 10, 10, 98, 44,101, 44,100,101, 99,
 108, 44, 97,114,103, 44, 99,111,110,115,116, 32, 61, 32,115,
 116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42, 40,
  91, 95, 37,119, 93, 41, 37,115, 42, 40, 37, 98, 40, 41, 41,
  37,115, 42, 40, 99, 63,111, 63,110, 63,115, 63,116, 63, 41,
  37,115, 42, 37, 98,123,125, 37,115, 42, 34, 41, 10,101,110,
 100, 10,105,102, 32, 98, 32,116,104,101,110, 10, 95, 99,117,
 114,114, 95, 99,111,100,101, 32, 61, 32,115,116,114,115,117,
  98, 40,115, 44, 98, 44,101, 41, 10, 70,117,110, 99,116,105,
 111,110, 40,100,101, 99,108, 44, 97,114,103, 44, 99,111,110,
 115,116, 41, 10,114,101,116,117,114,110, 32,115,116,114,115,
 117, 98, 40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,101,
 110,100, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32, 98,
  44,101, 44,110, 97,109,101, 44, 98, 97,115,101, 44, 98,111,
 100,121, 32, 61, 32,115,116,114,102,105,110,100, 40,115, 44,
  34, 94, 37,115, 42, 99,108, 97,115,115, 37,115, 42, 40, 91,
  95, 37,119, 93, 91, 95, 37,119, 93, 42, 41, 37,115, 42, 40,
  46, 45, 41, 37,115, 42, 40, 37, 98,123,125, 41, 37,115, 42,
  59, 37,115, 42, 34, 41, 10,105,102, 32,110,111,116, 32, 98,
  32,116,104,101,110, 10, 98, 44,101, 44,110, 97,109,101, 44,
  98, 97,115,101, 44, 98,111,100,121, 32, 61, 32,115,116,114,
 102,105,110,100, 40,115, 44, 34, 94, 37,115, 42,115,116,114,
 117, 99,116, 37,115, 42, 40, 91, 95, 37,119, 93, 91, 95, 37,
 119, 93, 42, 41, 37,115, 42, 40, 46, 45, 41, 37,115, 42, 40,
  37, 98,123,125, 41, 37,115, 42, 59, 37,115, 42, 34, 41, 10,
 105,102, 32,110,111,116, 32, 98, 32,116,104,101,110, 10, 98,
  97,115,101, 32, 61, 32, 39, 39, 10, 98, 44,101, 44, 98,111,
 100,121, 44,110, 97,109,101, 32, 61, 32,115,116,114,102,105,
 110,100, 40,115, 44, 34, 94, 37,115, 42,116,121,112,101,100,
 101,102, 37,115, 37,115, 42,115,116,114,117, 99,116, 37,115,
  37,115, 42, 91, 95, 37,119, 93, 42, 37,115, 42, 40, 37, 98,
 123,125, 41, 37,115, 42, 40, 91, 95, 37,119, 93, 91, 95, 37,
 119, 93, 42, 41, 37,115, 42, 59, 37,115, 42, 34, 41, 10,101,
 110,100, 10,101,110,100, 10,105,102, 32, 98, 32,116,104,101,
 110, 10,105,102, 32, 98, 97,115,101, 32,126, 61, 32, 39, 39,
  32,116,104,101,110, 10,108,111, 99, 97,108, 32, 98, 44,101,
  10, 98, 44,101, 44, 98, 97,115,101, 32, 61, 32,115,116,114,
 102,105,110,100, 40, 98, 97,115,101, 44, 34, 46, 45, 40, 91,
  95, 37,119, 93, 91, 95, 37,119, 93, 42, 41, 36, 34, 41, 10,
 101,110,100, 10, 95, 99,117,114,114, 95, 99,111,100,101, 32,
  61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,101, 41,
  10, 67,108, 97,115,115, 40,110, 97,109,101, 44, 98, 97,115,
 101, 44, 98,111,100,121, 41, 10,114,101,116,117,114,110, 32,
 115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10,101,
 110,100, 10,101,110,100, 10, 10, 10,100,111, 10,108,111, 99,
  97,108, 32, 98, 44,101, 44,116,121,112,101,115, 32, 61, 32,
 115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42,
 116,121,112,101,100,101,102, 37,115, 37,115, 42, 40, 46, 45,
  41, 37,115, 42, 59, 37,115, 42, 34, 41, 10,105,102, 32, 98,
  32,116,104,101,110, 10, 95, 99,117,114,114, 95, 99,111,100,
 101, 32, 61, 32,115,116,114,115,117, 98, 40,115, 44, 98, 44,
 101, 41, 10, 84,121,112,101,100,101,102, 40,116,121,112,101,
 115, 41, 10,114,101,116,117,114,110, 32,115,116,114,115,117,
  98, 40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,101,110,
 100, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32, 98, 44,
 101, 44,100,101, 99,108, 32, 61, 32,115,116,114,102,105,110,
 100, 40,115, 44, 34, 94, 37,115, 42, 40, 91, 95, 37,119, 93,
  91, 95, 64, 37,115, 37,119, 37,100, 37, 42, 38, 93, 42, 91,
  95, 37,119, 37,100, 93, 41, 37,115, 42, 59, 37,115, 42, 34,
  41, 10,105,102, 32, 98, 32,116,104,101,110, 10, 95, 99,117,
 114,114, 95, 99,111,100,101, 32, 61, 32,115,116,114,115,117,
  98, 40,115, 44, 98, 44,101, 41, 10, 86, 97,114,105, 97, 98,
 108,101, 40,100,101, 99,108, 41, 10,114,101,116,117,114,110,
  32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10,
 101,110,100, 10,101,110,100, 10, 10, 10,100,111, 10,108,111,
  99, 97,108, 32, 98, 44,101, 44,100,101, 99,108, 32, 61, 32,
 115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115, 42,
  40, 91, 95, 37,119, 93, 91, 93, 91, 95, 64, 37,115, 37,119,
  37,100, 37, 42, 38, 37, 45, 37, 62, 93, 42, 91, 93, 95, 37,
 119, 37,100, 93, 41, 37,115, 42, 59, 37,115, 42, 34, 41, 10,
 105,102, 32, 98, 32,116,104,101,110, 10, 95, 99,117,114,114,
  95, 99,111,100,101, 32, 61, 32,115,116,114,115,117, 98, 40,
 115, 44, 98, 44,101, 41, 10, 65,114,114, 97,121, 40,100,101,
  99,108, 41, 10,114,101,116,117,114,110, 32,115,116,114,115,
 117, 98, 40,115, 44,101, 43, 49, 41, 10,101,110,100, 10,101,
 110,100, 10, 10, 10,100,111, 10,108,111, 99, 97,108, 32, 98,
  44,101, 44, 99,111,100,101, 32, 61, 32,115,116,114,102,105,
 110,100, 40,115, 44, 34, 94, 37,115, 42, 40, 37, 98, 92, 49,
  92, 50, 41, 34, 41, 10,105,102, 32, 98, 32,116,104,101,110,
  10, 67,111,100,101, 40,115,116,114,115,117, 98, 40, 99,111,
 100,101, 44, 50, 44, 45, 50, 41, 41, 10,114,101,116,117,114,
 110, 32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41,
  10,101,110,100, 10,101,110,100, 10, 10, 10,100,111, 10,108,
 111, 99, 97,108, 32, 98, 44,101, 44,108,105,110,101, 32, 61,
  32,115,116,114,102,105,110,100, 40,115, 44, 34, 94, 37,115,
  42, 37, 36, 40, 46, 45, 92,110, 41, 34, 41, 10,105,102, 32,
  98, 32,116,104,101,110, 10, 86,101,114, 98, 97,116,105,109,
  40,108,105,110,101, 41, 10,114,101,116,117,114,110, 32,115,
 116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10,101,110,
 100, 10,101,110,100, 10, 10, 10,105,102, 32,103,115,117, 98,
  40,115, 44, 34, 37,115, 37,115, 42, 34, 44, 34, 34, 41, 32,
 126, 61, 32, 34, 34, 32,116,104,101,110, 10, 95, 99,117,114,
 114, 95, 99,111,100,101, 32, 61, 32,115, 10,101,114,114,111,
 114, 40, 34, 35,112, 97,114,115,101, 32,101,114,114,111,114,
  34, 41, 10,101,108,115,101, 10,114,101,116,117,114,110, 32,
  34, 34, 10,101,110,100, 10,101,110,100, 10, 10,102,117,110,
  99,116,105,111,110, 32, 99,108, 97,115,115, 67,111,110,116,
  97,105,110,101,114, 58,112, 97,114,115,101, 32, 40,115, 41,
  10,119,104,105,108,101, 32,115, 32,126, 61, 32, 39, 39, 32,
 100,111, 10,115, 32, 61, 32,115,101,108,102, 58,100,111,112,
  97,114,115,101, 40,115, 41, 10,101,110,100, 10,101,110,100,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 99,108, 97,115,115, 80, 97, 99,107, 97,
 103,101, 32, 61, 32,123, 10, 95, 98, 97,115,101, 32, 61, 32,
  99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114, 44,
  10,116,121,112,101, 32, 61, 32, 39,112, 97, 99,107, 97,103,
 101, 39, 10,125, 10,115,101,116,116, 97,103, 40, 99,108, 97,
 115,115, 80, 97, 99,107, 97,103,101, 44,116,111,108,117, 97,
  95,116, 97,103, 41, 10, 10, 10,102,117,110, 99,116,105,111,
 110, 32, 99,108, 97,115,115, 80, 97, 99,107, 97,103,101, 58,
 112,114,105,110,116, 32, 40, 41, 10,112,114,105,110,116, 40,
  34, 80, 97, 99,107, 97,103,101, 58, 32, 34, 46, 46,115,101,
 108,102, 46,110, 97,109,101, 41, 10,108,111, 99, 97,108, 32,
 105, 61, 49, 10,119,104,105,108,101, 32,115,101,108,102, 91,
 105, 93, 32,100,111, 10,115,101,108,102, 91,105, 93, 58,112,
 114,105,110,116, 40, 34, 34, 44, 34, 34, 41, 10,105, 32, 61,
  32,105, 43, 49, 10,101,110,100, 10,101,110,100, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 80, 97,
  99,107, 97,103,101, 58,112,114,101,112,114,111, 99,101,115,
 115, 32, 40, 41, 10,115,101,108,102, 46, 99,111,100,101, 32,
  61, 32, 34, 92,110, 34, 46, 46,115,101,108,102, 46, 99,111,
 100,101, 10, 10,108,111, 99, 97,108, 32, 86, 32, 61, 32,123,
 125, 10,115,101,108,102, 46, 99,111,100,101, 32, 61, 32,103,
 115,117, 98, 40,115,101,108,102, 46, 99,111,100,101, 44, 34,
  92,110, 40, 37,115, 42, 37, 36, 91, 94, 37, 91, 37, 93, 93,
  91, 94, 92,110, 93, 42, 41, 34, 44,102,117,110, 99,116,105,
 111,110, 32, 40,118, 41, 10,116,105,110,115,101,114,116, 40,
  37, 86, 44,118, 41, 10,114,101,116,117,114,110, 32, 34, 92,
 110, 36, 34, 46, 46,103,101,116,110, 40, 37, 86, 41, 46, 46,
  34, 36, 34, 10,101,110,100, 41, 10, 10,108,111, 99, 97,108,
  32, 67, 32, 61, 32,123,125, 10,115,101,108,102, 46, 99,111,
 100,101, 32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46,
  99,111,100,101, 44, 34, 92,110, 37,115, 42, 37, 36, 37, 91,
  34, 44, 34, 92, 49, 34, 41, 10,115,101,108,102, 46, 99,111,
 100,101, 32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46,
  99,111,100,101, 44, 34, 92,110, 37,115, 42, 37, 36, 37, 93,
  34, 44, 34, 92, 50, 34, 41, 10,115,101,108,102, 46, 99,111,
 100,101, 32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46,
  99,111,100,101, 44, 34, 40, 37, 98, 92, 49, 92, 50, 41, 34,
  44, 32,102,117,110, 99,116,105,111,110, 32, 40, 99, 41, 10,
 116,105,110,115,101,114,116, 40, 37, 67, 44, 99, 41, 10,114,
 101,116,117,114,110, 32, 34, 92,110, 36, 91, 34, 46, 46,103,
 101,116,110, 40, 37, 67, 41, 46, 46, 34, 93, 36, 34, 10,101,
 110,100, 41, 10, 10, 10,115,101,108,102, 46, 99,111,100,101,
  32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46, 99,111,
 100,101, 44, 34, 40, 47, 47, 91, 94, 92,110, 93, 42, 41, 34,
  44, 34, 34, 41, 10,115,101,108,102, 46, 99,111,100,101, 32,
  61, 32,103,115,117, 98, 40,115,101,108,102, 46, 99,111,100,
 101, 44, 34, 47, 37, 42, 34, 44, 34, 92, 49, 34, 41, 10,115,
 101,108,102, 46, 99,111,100,101, 32, 61, 32,103,115,117, 98,
  40,115,101,108,102, 46, 99,111,100,101, 44, 34, 37, 42, 47,
  34, 44, 34, 92, 50, 34, 41, 10,115,101,108,102, 46, 99,111,
 100,101, 32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46,
  99,111,100,101, 44, 34, 37, 98, 92, 49, 92, 50, 34, 44, 34,
  34, 41, 10,115,101,108,102, 46, 99,111,100,101, 32, 61, 32,
 103,115,117, 98, 40,115,101,108,102, 46, 99,111,100,101, 44,
  34, 92, 49, 34, 44, 34, 47, 37, 42, 34, 41, 10,115,101,108,
 102, 46, 99,111,100,101, 32, 61, 32,103,115,117, 98, 40,115,
 101,108,102, 46, 99,111,100,101, 44, 34, 92, 50, 34, 44, 34,
  37, 42, 47, 34, 41, 10,115,101,108,102, 46, 99,111,100,101,
  32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46, 99,111,
 100,101, 44, 34, 37,115, 42, 64, 37,115, 42, 34, 44, 34, 64,
  34, 41, 10,115,101,108,102, 46, 99,111,100,101, 32, 61, 32,
 103,115,117, 98, 40,115,101,108,102, 46, 99,111,100,101, 44,
  34, 37,115, 63,105,110,108,105,110,101, 40, 37,115, 41, 34,
  44, 34, 37, 49, 34, 41, 10,115,101,108,102, 46, 99,111,100,
 101, 32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46, 99,
 111,100,101, 44, 34, 37,115, 63,101,120,116,101,114,110, 40,
  37,115, 41, 34, 44, 34, 37, 49, 34, 41, 10,115,101,108,102,
  46, 99,111,100,101, 32, 61, 32,103,115,117, 98, 40,115,101,
 108,102, 46, 99,111,100,101, 44, 34, 37,115, 63,118,105,114,
 116,117, 97,108, 40, 37,115, 41, 34, 44, 34, 37, 49, 34, 41,
  10,115,101,108,102, 46, 99,111,100,101, 32, 61, 32,103,115,
 117, 98, 40,115,101,108,102, 46, 99,111,100,101, 44, 34,112,
 117, 98,108,105, 99, 58, 34, 44, 34, 34, 41, 10,115,101,108,
 102, 46, 99,111,100,101, 32, 61, 32,103,115,117, 98, 40,115,
 101,108,102, 46, 99,111,100,101, 44, 34, 40, 91, 94, 37,119,
  95, 93, 41,118,111,105,100, 37,115, 42, 37, 42, 34, 44, 34,
  37, 49, 95,117,115,101,114,100, 97,116, 97, 32, 34, 41, 10,
 115,101,108,102, 46, 99,111,100,101, 32, 61, 32,103,115,117,
  98, 40,115,101,108,102, 46, 99,111,100,101, 44, 34, 40, 91,
  94, 37,119, 95, 93, 41,118,111,105,100, 37,115, 42, 37, 42,
  34, 44, 34, 37, 49, 95,117,115,101,114,100, 97,116, 97, 32,
  34, 41, 10,115,101,108,102, 46, 99,111,100,101, 32, 61, 32,
 103,115,117, 98, 40,115,101,108,102, 46, 99,111,100,101, 44,
  34, 40, 91, 94, 37,119, 95, 93, 41, 99,104, 97,114, 37,115,
  42, 37, 42, 34, 44, 34, 37, 49, 95, 99,115,116,114,105,110,
 103, 32, 34, 41, 10, 10, 10,115,101,108,102, 46, 99,111,100,
 101, 32, 61, 32,103,115,117, 98, 40,115,101,108,102, 46, 99,
 111,100,101, 44, 34, 37, 36, 37, 91, 40, 37,100, 43, 41, 37,
  93, 37, 36, 34, 44,102,117,110, 99,116,105,111,110, 32, 40,
 110, 41, 10,114,101,116,117,114,110, 32, 37, 67, 91,116,111,
 110,117,109, 98,101,114, 40,110, 41, 93, 10,101,110,100, 41,
  10, 10,115,101,108,102, 46, 99,111,100,101, 32, 61, 32,103,
 115,117, 98, 40,115,101,108,102, 46, 99,111,100,101, 44, 34,
  37, 36, 40, 37,100, 43, 41, 37, 36, 34, 44,102,117,110, 99,
 116,105,111,110, 32, 40,110, 41, 10,114,101,116,117,114,110,
  32, 37, 86, 91,116,111,110,117,109, 98,101,114, 40,110, 41,
  93, 10,101,110,100, 41, 10,101,110,100, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 80, 97, 99,
 107, 97,103,101, 58,112,114,101, 97,109, 98,108,101, 32, 40,
  41, 10,111,117,116,112,117,116, 40, 39, 47, 42, 92,110, 39,
  41, 10,111,117,116,112,117,116, 40, 39, 42, 42, 32, 76,117,
  97, 32, 98,105,110,100,105,110,103, 58, 32, 39, 46, 46,115,
 101,108,102, 46,110, 97,109,101, 46, 46, 39, 92,110, 39, 41,
  10,111,117,116,112,117,116, 40, 39, 42, 42, 32, 71,101,110,
 101,114, 97,116,101,100, 32, 97,117,116,111,109, 97,116,105,
  99, 97,108,108,121, 32, 98,121, 32, 39, 46, 46, 84, 79, 76,
  85, 65, 95, 86, 69, 82, 83, 73, 79, 78, 46, 46, 39, 32,111,
 110, 32, 39, 46, 46,100, 97,116,101, 40, 41, 46, 46, 39, 46,
  92,110, 39, 41, 10,111,117,116,112,117,116, 40, 39, 42, 47,
  92,110, 92,110, 39, 41, 10, 10,111,117,116,112,117,116, 40,
  39, 35,105,110, 99,108,117,100,101, 32, 34,108,117, 97, 47,
 116,111,108,117, 97, 46,104, 34, 92,110, 92,110, 39, 41, 10,
  10,105,102, 32,110,111,116, 32,102,108, 97,103,115, 46,104,
  32,116,104,101,110, 10,111,117,116,112,117,116, 40, 39, 47,
  42, 32, 69,120,112,111,114,116,101,100, 32,102,117,110, 99,
 116,105,111,110, 32, 42, 47, 39, 41, 10,111,117,116,112,117,
 116, 40, 39,105,110,116, 32,116,111,108,117, 97, 95, 39, 46,
  46,115,101,108,102, 46,110, 97,109,101, 46, 46, 39, 95,111,
 112,101,110, 32, 40,108,117, 97, 95, 83,116, 97,116,101, 42,
  32,116,111,108,117, 97, 95, 83, 41, 59, 39, 41, 10,111,117,
 116,112,117,116, 40, 39,118,111,105,100, 32,116,111,108,117,
  97, 95, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, 46,
  46, 39, 95, 99,108,111,115,101, 32, 40,108,117, 97, 95, 83,
 116, 97,116,101, 42, 32,116,111,108,117, 97, 95, 83, 41, 59,
  39, 41, 10,111,117,116,112,117,116, 40, 39, 92,110, 39, 41,
  10,101,110,100, 10, 10,108,111, 99, 97,108, 32,105, 61, 49,
  10,119,104,105,108,101, 32,115,101,108,102, 91,105, 93, 32,
 100,111, 10,115,101,108,102, 91,105, 93, 58,112,114,101, 97,
 109, 98,108,101, 40, 41, 10,105, 32, 61, 32,105, 43, 49, 10,
 101,110,100, 10,111,117,116,112,117,116, 40, 39, 92,110, 39,
  41, 10,111,117,116,112,117,116, 40, 39, 47, 42, 32,102,117,
 110, 99,116,105,111,110, 32,116,111, 32,114,101,103,105,115,
 116,101,114, 32,116,121,112,101, 32, 42, 47, 39, 41, 10,111,
 117,116,112,117,116, 40, 39,115,116, 97,116,105, 99, 32,118,
 111,105,100, 32,116,111,108,117, 97, 73, 95,114,101,103, 95,
 116,121,112,101,115, 32, 40,108,117, 97, 95, 83,116, 97,116,
 101, 42, 32,116,111,108,117, 97, 95, 83, 41, 39, 41, 10,111,
 117,116,112,117,116, 40, 39,123, 39, 41, 10,102,111,114,101,
  97, 99,104, 40, 95,117,115,101,114,116,121,112,101, 44,102,
 117,110, 99,116,105,111,110, 40,110, 44,118, 41, 32,111,117,
 116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95,117,115,
 101,114,116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44,
  34, 39, 44,118, 44, 39, 34, 41, 59, 39, 41, 32,101,110,100,
  41, 10,111,117,116,112,117,116, 40, 39,125, 39, 41, 10,111,
 117,116,112,117,116, 40, 39, 92,110, 39, 41, 10, 10,111,117,
 116,112,117,116, 40, 39, 47, 42, 32,101,114,114,111,114, 32,
 109,101,115,115, 97,103,101,115, 32, 42, 47, 39, 41, 10,111,
 117,116,112,117,116, 40, 39, 35,100,101,102,105,110,101, 32,
  84, 79, 76, 85, 65, 95, 69, 82, 82, 95, 83, 69, 76, 70, 32,
 116,111,108,117, 97, 95,101,114,114,111,114, 40,116,111,108,
 117, 97, 95, 83, 44, 92, 34,105,110,118, 97,108,105,100, 32,
  92, 39,115,101,108,102, 92, 39, 92, 34, 41, 39, 41, 10,111,
 117,116,112,117,116, 40, 39, 35,100,101,102,105,110,101, 32,
  84, 79, 76, 85, 65, 95, 69, 82, 82, 95, 65, 83, 83, 73, 71,
  78, 32,116,111,108,117, 97, 95,101,114,114,111,114, 40,116,
 111,108,117, 97, 95, 83, 44, 92, 34, 35,118,105,110,118, 97,
 108,105,100, 32,116,121,112,101, 32,105,110, 32,118, 97,114,
 105, 97, 98,108,101, 32, 97,115,115,105,103,110,109,101,110,
 116, 46, 92, 34, 41, 39, 41, 10,111,117,116,112,117,116, 40,
  39, 92,110, 39, 41, 10,101,110,100, 10, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 80, 97, 99,
 107, 97,103,101, 58,114,101,103,105,115,116,101,114, 32, 40,
  41, 10,111,117,116,112,117,116, 40, 34, 47, 42, 32, 79,112,
 101,110, 32,102,117,110, 99,116,105,111,110, 32, 42, 47, 34,
  41, 10,111,117,116,112,117,116, 40, 34,105,110,116, 32,116,
 111,108,117, 97, 95, 34, 46, 46,115,101,108,102, 46,110, 97,
 109,101, 46, 46, 34, 95,111,112,101,110, 32, 40,108,117, 97,
  95, 83,116, 97,116,101, 42, 32,116,111,108,117, 97, 95, 83,
  41, 34, 41, 10,111,117,116,112,117,116, 40, 34,123, 34, 41,
  10,111,117,116,112,117,116, 40, 34, 32,116,111,108,117, 97,
  95,111,112,101,110, 40,116,111,108,117, 97, 95, 83, 41, 59,
  34, 41, 10,111,117,116,112,117,116, 40, 34, 32,116,111,108,
 117, 97, 73, 95,114,101,103, 95,116,121,112,101,115, 40,116,
 111,108,117, 97, 95, 83, 41, 59, 34, 41, 10,108,111, 99, 97,
 108, 32,105, 61, 49, 10,119,104,105,108,101, 32,115,101,108,
 102, 91,105, 93, 32,100,111, 10,115,101,108,102, 91,105, 93,
  58,114,101,103,105,115,116,101,114, 40, 41, 10,105, 32, 61,
  32,105, 43, 49, 10,101,110,100, 10,111,117,116,112,117,116,
  40, 34, 32,114,101,116,117,114,110, 32, 49, 59, 34, 41, 10,
 111,117,116,112,117,116, 40, 34,125, 34, 41, 10,101,110,100,
  10, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108,
  97,115,115, 80, 97, 99,107, 97,103,101, 58,117,110,114,101,
 103,105,115,116,101,114, 32, 40, 41, 10,111,117,116,112,117,
 116, 40, 34, 47, 42, 32, 67,108,111,115,101, 32,102,117,110,
  99,116,105,111,110, 32, 42, 47, 34, 41, 10,111,117,116,112,
 117,116, 40, 34,118,111,105,100, 32,116,111,108,117, 97, 95,
  34, 46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46, 34,
  95, 99,108,111,115,101, 32, 40,108,117, 97, 95, 83,116, 97,
 116,101, 42, 32,116,111,108,117, 97, 95, 83, 41, 34, 41, 10,
 111,117,116,112,117,116, 40, 34,123, 34, 41, 10,108,111, 99,
  97,108, 32,105, 61, 49, 10,119,104,105,108,101, 32,115,101,
 108,102, 91,105, 93, 32,100,111, 10,115,101,108,102, 91,105,
  93, 58,117,110,114,101,103,105,115,116,101,114, 40, 41, 10,
 105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,111,117,116,
 112,117,116, 40, 34,125, 34, 41, 10,101,110,100, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 80,
  97, 99,107, 97,103,101, 58,104,101, 97,100,101,114, 32, 40,
  41, 10,111,117,116,112,117,116, 40, 39, 47, 42, 92,110, 39,
  41, 32,111,117,116,112,117,116, 40, 39, 42, 42, 32, 76,117,
  97, 32, 98,105,110,100,105,110,103, 58, 32, 39, 46, 46,115,
 101,108,102, 46,110, 97,109,101, 46, 46, 39, 92,110, 39, 41,
  10,111,117,116,112,117,116, 40, 39, 42, 42, 32, 71,101,110,
 101,114, 97,116,101,100, 32, 97,117,116,111,109, 97,116,105,
  99, 97,108,108,121, 32, 98,121, 32, 39, 46, 46, 84, 79, 76,
  85, 65, 95, 86, 69, 82, 83, 73, 79, 78, 46, 46, 39, 32,111,
 110, 32, 39, 46, 46,100, 97,116,101, 40, 41, 46, 46, 39, 46,
  92,110, 39, 41, 10,111,117,116,112,117,116, 40, 39, 42, 47,
  92,110, 92,110, 39, 41, 10, 10,105,102, 32,110,111,116, 32,
 102,108, 97,103,115, 46,104, 32,116,104,101,110, 10,111,117,
 116,112,117,116, 40, 39, 47, 42, 32, 69,120,112,111,114,116,
 101,100, 32,102,117,110, 99,116,105,111,110, 32, 42, 47, 39,
  41, 10,111,117,116,112,117,116, 40, 39,105,110,116, 32,116,
 111,108,117, 97, 95, 39, 46, 46,115,101,108,102, 46,110, 97,
 109,101, 46, 46, 39, 95,111,112,101,110, 32, 40,108,117, 97,
  95, 83,116, 97,116,101, 42, 32,116,111,108,117, 97, 95, 83,
  41, 59, 39, 41, 10,111,117,116,112,117,116, 40, 39,118,111,
 105,100, 32,116,111,108,117, 97, 95, 39, 46, 46,115,101,108,
 102, 46,110, 97,109,101, 46, 46, 39, 95, 99,108,111,115,101,
  32, 40,108,117, 97, 95, 83,116, 97,116,101, 42, 32,116,111,
 108,117, 97, 95, 83, 41, 59, 39, 41, 10,111,117,116,112,117,
 116, 40, 39, 92,110, 39, 41, 10,101,110,100, 10,101,110,100,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 80, 97,
  99,107, 97,103,101, 32, 40,116, 41, 10,116, 46, 95, 98, 97,
 115,101, 32, 61, 32, 99,108, 97,115,115, 80, 97, 99,107, 97,
 103,101, 10,115,101,116,116, 97,103, 40,116, 44,116,111,108,
 117, 97, 95,116, 97,103, 41, 10,114,101,116,117,114,110, 32,
 116, 10,101,110,100, 10, 10, 10, 10, 10,102,117,110, 99,116,
 105,111,110, 32, 80, 97, 99,107, 97,103,101, 32, 40,110, 97,
 109,101, 41, 10, 10,108,111, 99, 97,108, 32, 99,111,100,101,
  32, 61, 32,114,101, 97,100, 40, 34, 42, 97, 34, 41, 10, 99,
 111,100,101, 32, 61, 32, 34, 92,110, 34, 32, 46, 46, 32, 99,
 111,100,101, 10, 10,108,111, 99, 97,108, 32,110,115,117, 98,
 115,116, 10,114,101,112,101, 97,116, 10, 99,111,100,101, 44,
 110,115,117, 98,115,116, 32, 61, 32,103,115,117, 98, 40, 99,
 111,100,101, 44, 34, 92,110, 37,115, 42, 37, 36, 60, 40, 46,
  45, 41, 62, 37,115, 42, 92,110, 34, 44,102,117,110, 99,116,
 105,111,110, 32, 40,102,110, 41, 10,108,111, 99, 97,108, 32,
 102,112, 44,109,115,103, 32, 61, 32,111,112,101,110,102,105,
 108,101, 40,102,110, 44, 39,114, 39, 41, 10,105,102, 32,110,
 111,116, 32,102,112, 32,116,104,101,110, 10,101,114,114,111,
 114, 40, 39, 35, 39, 46, 46,109,115,103, 46, 46, 39, 58, 32,
  39, 46, 46,102,110, 41, 10,101,110,100, 10,108,111, 99, 97,
 108, 32,115, 32, 61, 32,114,101, 97,100, 40,102,112, 44, 39,
  42, 97, 39, 41, 10, 99,108,111,115,101,102,105,108,101, 40,
 102,112, 41, 10,114,101,116,117,114,110, 32, 34, 92,110, 34,
  32, 46, 46, 32,115, 10,101,110,100, 41, 10,117,110,116,105,
 108, 32,110,115,117, 98,115,116, 61, 61, 48, 10, 10, 10,108,
 111, 99, 97,108, 32,110,115,117, 98,115,116, 10,114,101,112,
 101, 97,116, 10, 99,111,100,101, 44,110,115,117, 98,115,116,
  32, 61, 10,103,115,117, 98, 40, 99,111,100,101, 44, 34, 92,
 110, 37,115, 42, 37, 36,123, 40, 46, 45, 41,125, 37,115, 42,
  92,110, 34, 44, 10,102,117,110, 99,116,105,111,110, 32, 40,
 102,110, 41, 10,108,111, 99, 97,108, 32,102,112, 44,109,115,
 103, 32, 61, 32,111,112,101,110,102,105,108,101, 40,102,110,
  44, 39,114, 39, 41, 10,105,102, 32,110,111,116, 32,102,112,
  32,116,104,101,110, 10,101,114,114,111,114, 40, 39, 35, 39,
  46, 46,109,115,103, 46, 46, 39, 58, 32, 39, 46, 46,102,110,
  41, 10,101,110,100, 10,108,111, 99, 97,108, 32,115, 32, 61,
  32,114,101, 97,100, 40,102,112, 44, 39, 42, 97, 39, 41, 10,
  99,108,111,115,101,102,105,108,101, 40,102,112, 41, 10, 10,
 108,111, 99, 97,108, 32, 84, 32, 61, 32,123, 99,111,100,101,
  61, 34, 92,110, 34,125, 10,115, 61, 32, 34, 92,110, 34, 32,
  46, 46, 32,115, 32, 46, 46, 32, 34, 92,110, 34, 10, 10,103,
 115,117, 98, 40,115, 44, 34, 92,110, 40, 46, 45, 41, 91, 84,
 116, 93, 91, 79,111, 93, 91, 76,108, 93, 91, 85,117, 93, 91,
  65, 97, 93, 95, 91, 69,101, 93, 91, 88,120, 93, 91, 80,112,
  93, 91, 79,111, 93, 91, 82,114, 93, 91, 84,116, 93, 91, 94,
  92,110, 93, 42, 92,110, 34, 44, 10,102,117,110, 99,116,105,
 111,110, 32, 40, 99, 41, 32, 37, 84, 46, 99,111,100,101, 32,
  61, 32, 37, 84, 46, 99,111,100,101, 32, 46, 46, 32, 99, 32,
  46, 46, 32, 34, 92,110, 34, 32,101,110,100, 10, 41, 10, 10,
 103,115,117, 98, 40,115, 44, 34, 92,110, 91, 94, 92,110, 93,
  42, 91, 84,116, 93, 91, 79,111, 93, 91, 76,108, 93, 91, 85,
 117, 93, 91, 65, 97, 93, 95, 91, 66, 98, 93, 91, 69,101, 93,
  91, 71,103, 93, 91, 73,105, 93, 91, 78,110, 93, 91, 94, 92,
 110, 93, 42, 34, 46, 46, 10, 34, 40, 46, 45, 41, 34, 32, 46,
  46, 10, 34, 92,110, 91, 94, 92,110, 93, 42, 91, 84,116, 93,
  91, 79,111, 93, 91, 76,108, 93, 91, 85,117, 93, 91, 65, 97,
  93, 95, 91, 69,101, 93, 91, 78,110, 93, 91, 68,100, 93, 91,
  94, 92,110, 93, 42, 92,110, 34, 44, 10,102,117,110, 99,116,
 105,111,110, 32, 40, 99, 41, 32, 37, 84, 46, 99,111,100,101,
  32, 61, 32, 37, 84, 46, 99,111,100,101, 32, 46, 46, 32, 99,
  32, 46, 46, 32, 34, 92,110, 34, 32,101,110,100, 10, 41, 10,
 114,101,116,117,114,110, 32, 84, 46, 99,111,100,101, 10,101,
 110,100, 41, 10,117,110,116,105,108, 32,110,115,117, 98,115,
 116, 61, 61, 48, 10, 10,108,111, 99, 97,108, 32,116, 32, 61,
  32, 95, 80, 97, 99,107, 97,103,101, 40, 95, 67,111,110,116,
  97,105,110,101,114,123,110, 97,109,101, 61,110, 97,109,101,
  44, 32, 99,111,100,101, 61, 99,111,100,101,125, 41, 10,112,
 117,115,104, 40,116, 41, 10,116, 58,112,114,101,112,114,111,
  99,101,115,115, 40, 41, 10,116, 58,112, 97,114,115,101, 40,
 116, 46, 99,111,100,101, 41, 10,112,111,112, 40, 41, 10,114,
 101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 99,
 108, 97,115,115, 77,111,100,117,108,101, 32, 61, 32,123, 10,
  95, 98, 97,115,101, 32, 61, 32, 99,108, 97,115,115, 67,111,
 110,116, 97,105,110,101,114, 44, 10,116,121,112,101, 32, 61,
  32, 39,109,111,100,117,108,101, 39, 10,125, 10,115,101,116,
 116, 97,103, 40, 99,108, 97,115,115, 77,111,100,117,108,101,
  44,116,111,108,117, 97, 95,116, 97,103, 41, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 77,111,
 100,117,108,101, 58,114,101,103,105,115,116,101,114, 32, 40,
  41, 10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117,
  97, 95,109,111,100,117,108,101, 40,116,111,108,117, 97, 95,
  83, 44, 34, 39, 46, 46,115,101,108,102, 46,110, 97,109,101,
  46, 46, 39, 34, 41, 59, 39, 41, 10,108,111, 99, 97,108, 32,
 105, 61, 49, 10,119,104,105,108,101, 32,115,101,108,102, 91,
 105, 93, 32,100,111, 10,115,101,108,102, 91,105, 93, 58,114,
 101,103,105,115,116,101,114, 40, 41, 10,105, 32, 61, 32,105,
  43, 49, 10,101,110,100, 10,101,110,100, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 77,111,100,
 117,108,101, 58,117,110,114,101,103,105,115,116,101,114, 32,
  40, 41, 10,111,117,116,112,117,116, 40, 39, 32,108,117, 97,
  95,112,117,115,104,110,105,108, 40,116,111,108,117, 97, 95,
  83, 41, 59, 32,108,117, 97, 95,115,101,116,103,108,111, 98,
  97,108, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46, 46,
 115,101,108,102, 46,110, 97,109,101, 46, 46, 39, 34, 41, 59,
  39, 41, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,
 111,110, 32, 99,108, 97,115,115, 77,111,100,117,108,101, 58,
 112,114,105,110,116, 32, 40,105,100,101,110,116, 44, 99,108,
 111,115,101, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34, 77,111,100,117,108,101,123, 34, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,110,
  97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,
 110, 97,109,101, 46, 46, 34, 39, 59, 34, 41, 10,108,111, 99,
  97,108, 32,105, 61, 49, 10,119,104,105,108,101, 32,115,101,
 108,102, 91,105, 93, 32,100,111, 10,115,101,108,102, 91,105,
  93, 58,112,114,105,110,116, 40,105,100,101,110,116, 46, 46,
  34, 32, 34, 44, 34, 44, 34, 41, 10,105, 32, 61, 32,105, 43,
  49, 10,101,110,100, 10,112,114,105,110,116, 40,105,100,101,
 110,116, 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41,
  10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 95, 77,111,100,117,108,101, 32, 40,116, 41, 10,116, 46,
  95, 98, 97,115,101, 32, 61, 32, 99,108, 97,115,115, 77,111,
 100,117,108,101, 10,115,101,116,116, 97,103, 40,116, 44,116,
 111,108,117, 97, 95,116, 97,103, 41, 10, 97,112,112,101,110,
 100, 40,116, 41, 10,114,101,116,117,114,110, 32,116, 10,101,
 110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110, 32,
  77,111,100,117,108,101, 32, 40,110, 44, 98, 41, 10,108,111,
  99, 97,108, 32,116, 32, 61, 32, 95, 77,111,100,117,108,101,
  40, 95, 67,111,110,116, 97,105,110,101,114,123,110, 97,109,
 101, 61,110,125, 41, 10,112,117,115,104, 40,116, 41, 10,116,
  58,112, 97,114,115,101, 40,115,116,114,115,117, 98, 40, 98,
  44, 50, 44,115,116,114,108,101,110, 40, 98, 41, 45, 49, 41,
  41, 10,112,111,112, 40, 41, 10,114,101,116,117,114,110, 32,
 116, 10,101,110,100, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,115, 68,
 101,102,105,110,101, 32, 61, 32,123, 10,110, 97,109,101, 32,
  61, 32, 39, 39, 44, 10, 95, 98, 97,115,101, 32, 61, 32, 99,
 108, 97,115,115, 70,101, 97,116,117,114,101, 44, 10,125, 10,
 115,101,116,116, 97,103, 40, 99,108, 97,115,115, 68,101,102,
 105,110,101, 44,116,111,108,117, 97, 95,116, 97,103, 41, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,
 115, 68,101,102,105,110,101, 58,114,101,103,105,115,116,101,
 114, 32, 40, 41, 10,108,111, 99, 97,108, 32,112, 32, 61, 32,
 115,101,108,102, 58,105,110,109,111,100,117,108,101, 40, 41,
  10,105,102, 32,112, 32,116,104,101,110, 10,111,117,116,112,
 117,116, 40, 39, 32,116,111,108,117, 97, 95, 99,111,110,115,
 116, 97,110,116, 40,116,111,108,117, 97, 95, 83, 44, 34, 39,
  46, 46,112, 46, 46, 39, 34, 44, 34, 39, 46, 46,115,101,108,
 102, 46,108,110, 97,109,101, 46, 46, 39, 34, 44, 39, 46, 46,
 115,101,108,102, 46,110, 97,109,101, 46, 46, 39, 41, 59, 39,
  41, 10,101,108,115,101, 10,111,117,116,112,117,116, 40, 39,
  32,116,111,108,117, 97, 95, 99,111,110,115,116, 97,110,116,
  40,116,111,108,117, 97, 95, 83, 44, 78, 85, 76, 76, 44, 34,
  39, 46, 46,115,101,108,102, 46,108,110, 97,109,101, 46, 46,
  39, 34, 44, 39, 46, 46,115,101,108,102, 46,110, 97,109,101,
  46, 46, 39, 41, 59, 39, 41, 10,101,110,100, 10,101,110,100,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,
 115,115, 68,101,102,105,110,101, 58,117,110,114,101,103,105,
 115,116,101,114, 32, 40, 41, 10,105,102, 32,110,111,116, 32,
 115,101,108,102, 58,105,110,109,111,100,117,108,101, 40, 41,
  32,116,104,101,110, 10,111,117,116,112,117,116, 40, 39, 32,
 108,117, 97, 95,112,117,115,104,110,105,108, 40,116,111,108,
 117, 97, 95, 83, 41, 59, 32,108,117, 97, 95,115,101,116,103,
 108,111, 98, 97,108, 40,116,111,108,117, 97, 95, 83, 44, 34,
  39, 46, 46,115,101,108,102, 46,108,110, 97,109,101, 46, 46,
  39, 34, 41, 59, 39, 41, 10,101,110,100, 10,101,110,100, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,
 115, 68,101,102,105,110,101, 58,112,114,105,110,116, 32, 40,
 105,100,101,110,116, 44, 99,108,111,115,101, 41, 10,112,114,
 105,110,116, 40,105,100,101,110,116, 46, 46, 34, 68,101,102,
 105,110,101,123, 34, 41, 10,112,114,105,110,116, 40,105,100,
 101,110,116, 46, 46, 34, 32,110, 97,109,101, 32, 61, 32, 39,
  34, 46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46, 34,
  39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34, 32,108,110, 97,109,101, 32, 61, 32, 39, 34,
  46, 46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 34,
  39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,
 101,110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 95, 68,101,102,105,110,101, 32, 40,116, 41, 10,116, 46,
  95, 98, 97,115,101, 32, 61, 32, 99,108, 97,115,115, 68,101,
 102,105,110,101, 10,115,101,116,116, 97,103, 40,116, 44,116,
 111,108,117, 97, 95,116, 97,103, 41, 10, 10,105,102, 32,116,
  46,110, 97,109,101, 32, 61, 61, 32, 39, 39, 32,116,104,101,
 110, 10,101,114,114,111,114, 40, 34, 35,105,110,118, 97,108,
 105,100, 32,100,101,102,105,110,101, 34, 41, 10,101,110,100,
  10, 10, 97,112,112,101,110,100, 40,116, 41, 10,114,101,116,
 117,114,110, 32,116, 10,101,110,100, 10, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 68,101,102,105,110,101, 32, 40,
 110, 41, 10,108,111, 99, 97,108, 32,116, 32, 61, 32,115,112,
 108,105,116, 40,110, 44, 39, 64, 39, 41, 10,114,101,116,117,
 114,110, 32, 95, 68,101,102,105,110,101, 32,123, 10,110, 97,
 109,101, 32, 61, 32,116, 91, 49, 93, 44, 10,108,110, 97,109,
 101, 32, 61, 32,116, 91, 50, 93, 32,111,114, 32,116, 91, 49,
  93, 10,125, 10,101,110,100, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,115, 69,
 110,117,109,101,114, 97,116,101, 32, 61, 32,123, 10, 95, 98,
  97,115,101, 32, 61, 32, 99,108, 97,115,115, 70,101, 97,116,
 117,114,101, 44, 10,125, 10,115,101,116,116, 97,103, 40, 99,
 108, 97,115,115, 69,110,117,109,101,114, 97,116,101, 44,116,
 111,108,117, 97, 95,116, 97,103, 41, 10, 10, 10,102,117,110,
  99,116,105,111,110, 32, 99,108, 97,115,115, 69,110,117,109,
 101,114, 97,116,101, 58,114,101,103,105,115,116,101,114, 32,
  40, 41, 10,108,111, 99, 97,108, 32,112, 32, 61, 32,115,101,
 108,102, 58,105,110, 99,108, 97,115,115, 40, 41, 32,111,114,
  32,115,101,108,102, 58,105,110,109,111,100,117,108,101, 40,
  41, 10,108,111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,
 108,101, 32,115,101,108,102, 91,105, 93, 32,100,111, 10,105,
 102, 32,112, 32,116,104,101,110, 10,105,102, 32,115,101,108,
 102, 58,105,110, 99,108, 97,115,115, 40, 41, 32,116,104,101,
 110, 10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117,
  97, 95, 99,111,110,115,116, 97,110,116, 40,116,111,108,117,
  97, 95, 83, 44, 34, 39, 46, 46,112, 46, 46, 39, 34, 44, 34,
  39, 46, 46,115,101,108,102, 46,108,110, 97,109,101,115, 91,
 105, 93, 46, 46, 39, 34, 44, 39, 46, 46,112, 46, 46, 39, 58,
  58, 39, 46, 46,115,101,108,102, 91,105, 93, 46, 46, 39, 41,
  59, 39, 41, 10,101,108,115,101, 10,111,117,116,112,117,116,
  40, 39, 32,116,111,108,117, 97, 95, 99,111,110,115,116, 97,
 110,116, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46, 46,
 112, 46, 46, 39, 34, 44, 34, 39, 46, 46,115,101,108,102, 46,
 108,110, 97,109,101,115, 91,105, 93, 46, 46, 39, 34, 44, 39,
  46, 46,115,101,108,102, 91,105, 93, 46, 46, 39, 41, 59, 39,
  41, 10,101,110,100, 10,101,108,115,101, 10,111,117,116,112,
 117,116, 40, 39, 32,116,111,108,117, 97, 95, 99,111,110,115,
 116, 97,110,116, 40,116,111,108,117, 97, 95, 83, 44, 78, 85,
  76, 76, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110, 97,
 109,101,115, 91,105, 93, 46, 46, 39, 34, 44, 39, 46, 46,115,
 101,108,102, 91,105, 93, 46, 46, 39, 41, 59, 39, 41, 10,101,
 110,100, 10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,
 101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,
 108, 97,115,115, 69,110,117,109,101,114, 97,116,101, 58,117,
 110,114,101,103,105,115,116,101,114, 32, 40, 41, 10,105,102,
  32,115,101,108,102, 58,105,110, 99,108, 97,115,115, 40, 41,
  61, 61,110,105,108, 32, 97,110,100, 32,115,101,108,102, 58,
 105,110,109,111,100,117,108,101, 40, 41, 61, 61,110,105,108,
  32,116,104,101,110, 10,108,111, 99, 97,108, 32,105, 61, 49,
  10,119,104,105,108,101, 32,115,101,108,102, 91,105, 93, 32,
 100,111, 10,111,117,116,112,117,116, 40, 39, 32,108,117, 97,
  95,112,117,115,104,110,105,108, 40,116,111,108,117, 97, 95,
  83, 41, 59, 32,108,117, 97, 95,115,101,116,103,108,111, 98,
  97,108, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46, 46,
 115,101,108,102, 46,108,110, 97,109,101,115, 91,105, 93, 46,
  46, 39, 34, 41, 59, 39, 41, 10,105, 32, 61, 32,105, 43, 49,
  10,101,110,100, 10,101,110,100, 10,101,110,100, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 69,
 110,117,109,101,114, 97,116,101, 58,112,114,105,110,116, 32,
  40,105,100,101,110,116, 44, 99,108,111,115,101, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 69,110,
 117,109,101,114, 97,116,101,123, 34, 41, 10,108,111, 99, 97,
 108, 32,105, 61, 49, 10,119,104,105,108,101, 32,115,101,108,
 102, 91,105, 93, 32,100,111, 10,112,114,105,110,116, 40,105,
 100,101,110,116, 46, 46, 34, 32, 39, 34, 46, 46,115,101,108,
 102, 91,105, 93, 46, 46, 34, 39, 40, 34, 46, 46,115,101,108,
 102, 46,108,110, 97,109,101,115, 91,105, 93, 46, 46, 34, 41,
  44, 34, 41, 10,105, 32, 61, 32,105, 43, 49, 10,101,110,100,
  10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34,
 125, 34, 46, 46, 99,108,111,115,101, 41, 10,101,110,100, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32, 95, 69,110,117,
 109,101,114, 97,116,101, 32, 40,116, 41, 10,116, 46, 95, 98,
  97,115,101, 32, 61, 32, 99,108, 97,115,115, 69,110,117,109,
 101,114, 97,116,101, 10,115,101,116,116, 97,103, 40,116, 44,
 116,111,108,117, 97, 95,116, 97,103, 41, 10, 97,112,112,101,
 110,100, 40,116, 41, 10,114,101,116,117,114,110, 32,116, 10,
 101,110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 69,110,117,109,101,114, 97,116,101, 32, 40, 98, 41, 10,
 108,111, 99, 97,108, 32,116, 32, 61, 32,115,112,108,105,116,
  40,115,116,114,115,117, 98, 40, 98, 44, 50, 44, 45, 50, 41,
  44, 39, 44, 39, 41, 10,108,111, 99, 97,108, 32,105, 32, 61,
  32, 49, 10,108,111, 99, 97,108, 32,101, 32, 61, 32,123,110,
  61, 48,125, 10,119,104,105,108,101, 32,116, 91,105, 93, 32,
 100,111, 10,108,111, 99, 97,108, 32,116,116, 32, 61, 32,115,
 112,108,105,116, 40,116, 91,105, 93, 44, 39, 61, 39, 41, 10,
 101, 46,110, 32, 61, 32,101, 46,110, 32, 43, 32, 49, 10,101,
  91,101, 46,110, 93, 32, 61, 32,116,116, 91, 49, 93, 10,105,
  32, 61, 32,105, 43, 49, 10,101,110,100, 10, 10,105, 32, 61,
  32, 49, 10,101, 46,108,110, 97,109,101,115, 32, 61, 32,123,
 125, 10,119,104,105,108,101, 32,101, 91,105, 93, 32,100,111,
  10,108,111, 99, 97,108, 32,116, 32, 61, 32,115,112,108,105,
 116, 40,101, 91,105, 93, 44, 39, 64, 39, 41, 10,101, 91,105,
  93, 32, 61, 32,116, 91, 49, 93, 10,101, 46,108,110, 97,109,
 101,115, 91,105, 93, 32, 61, 32,116, 91, 50, 93, 32,111,114,
  32,116, 91, 49, 93, 10,105, 32, 61, 32,105, 43, 49, 10,101,
 110,100, 10,114,101,116,117,114,110, 32, 95, 69,110,117,109,
 101,114, 97,116,101, 40,101, 41, 10,101,110,100, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,115, 68,101, 99,
 108, 97,114, 97,116,105,111,110, 32, 61, 32,123, 10, 95, 98,
  97,115,101, 32, 61, 32, 99,108, 97,115,115, 70,101, 97,116,
 117,114,101, 44, 10,109,111,100, 32, 61, 32, 39, 39, 44, 10,
 116,121,112,101, 32, 61, 32, 39, 39, 44, 10,112,116,114, 32,
  61, 32, 39, 39, 44, 10,110, 97,109,101, 32, 61, 32, 39, 39,
  44, 10,100,105,109, 32, 61, 32, 39, 39, 44, 10,114,101,116,
  32, 61, 32, 39, 39, 44, 10,100,101,102, 32, 61, 32, 39, 39,
  10,125, 10,115,101,116,116, 97,103, 40, 99,108, 97,115,115,
  68,101, 99,108, 97,114, 97,116,105,111,110, 44,116,111,108,
 117, 97, 95,116, 97,103, 41, 10, 10, 10,102,117,110, 99,116,
 105,111,110, 32, 99,114,101, 97,116,101, 95,118, 97,114,110,
  97,109,101, 32, 40, 41, 10,105,102, 32,110,111,116, 32, 95,
 118, 97,114,110,117,109, 98,101,114, 32,116,104,101,110, 32,
  95,118, 97,114,110,117,109, 98,101,114, 32, 61, 32, 48, 32,
 101,110,100, 10, 95,118, 97,114,110,117,109, 98,101,114, 32,
  61, 32, 95,118, 97,114,110,117,109, 98,101,114, 32, 43, 32,
  49, 10,114,101,116,117,114,110, 32, 34,116,111,108,117, 97,
  95,118, 97,114, 95, 34, 46, 46, 95,118, 97,114,110,117,109,
  98,101,114, 10,101,110,100, 10, 10, 10, 10,102,117,110, 99,
 116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,
 114, 97,116,105,111,110, 58, 99,104,101, 99,107,110, 97,109,
 101, 32, 40, 41, 10, 10,105,102, 32,115,116,114,115,117, 98,
  40,115,101,108,102, 46,110, 97,109,101, 44, 49, 44, 49, 41,
  32, 61, 61, 32, 39, 91, 39, 32, 97,110,100, 32,110,111,116,
  32,105,115,116,121,112,101, 40,115,101,108,102, 46,116,121,
 112,101, 41, 32,116,104,101,110, 10,115,101,108,102, 46,110,
  97,109,101, 32, 61, 32,115,101,108,102, 46,116,121,112,101,
  46, 46,115,101,108,102, 46,110, 97,109,101, 10,108,111, 99,
  97,108, 32,109, 32, 61, 32,115,112,108,105,116, 40,115,101,
 108,102, 46,109,111,100, 44, 39, 37,115, 37,115, 42, 39, 41,
  10,115,101,108,102, 46,116,121,112,101, 32, 61, 32,109, 91,
 109, 46,110, 93, 10,115,101,108,102, 46,109,111,100, 32, 61,
  32, 99,111,110, 99, 97,116, 40,109, 44, 49, 44,109, 46,110,
  45, 49, 41, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,
 116, 32, 61, 32,115,112,108,105,116, 40,115,101,108,102, 46,
 110, 97,109,101, 44, 39, 61, 39, 41, 10,105,102, 32,116, 46,
 110, 61, 61, 50, 32,116,104,101,110, 10,115,101,108,102, 46,
 110, 97,109,101, 32, 61, 32,116, 91, 49, 93, 10,115,101,108,
 102, 46,100,101,102, 32, 61, 32,116, 91,116, 46,110, 93, 10,
 101,110,100, 10, 10,108,111, 99, 97,108, 32, 98, 44,101, 44,
 100, 32, 61, 32,115,116,114,102,105,110,100, 40,115,101,108,
 102, 46,110, 97,109,101, 44, 34, 37, 91, 40, 46, 45, 41, 37,
  93, 34, 41, 10,105,102, 32, 98, 32,116,104,101,110, 10,115,
 101,108,102, 46,110, 97,109,101, 32, 61, 32,115,116,114,115,
 117, 98, 40,115,101,108,102, 46,110, 97,109,101, 44, 49, 44,
  98, 45, 49, 41, 10,115,101,108,102, 46,100,105,109, 32, 61,
  32,100, 10,101,110,100, 10, 10, 10,105,102, 32,115,101,108,
 102, 46,116,121,112,101, 32,126, 61, 32, 39, 39, 32, 97,110,
 100, 32,115,101,108,102, 46,116,121,112,101, 32,126, 61, 32,
  39,118,111,105,100, 39, 32, 97,110,100, 32,115,101,108,102,
  46,110, 97,109,101, 32, 61, 61, 32, 39, 39, 32,116,104,101,
 110, 10,115,101,108,102, 46,110, 97,109,101, 32, 61, 32, 99,
 114,101, 97,116,101, 95,118, 97,114,110, 97,109,101, 40, 41,
  10,101,108,115,101,105,102, 32,115,101,108,102, 46,107,105,
 110,100, 61, 61, 39,118, 97,114, 39, 32,116,104,101,110, 10,
 105,102, 32,115,101,108,102, 46,116,121,112,101, 61, 61, 39,
  39, 32, 97,110,100, 32,115,101,108,102, 46,110, 97,109,101,
 126, 61, 39, 39, 32,116,104,101,110, 10,115,101,108,102, 46,
 116,121,112,101, 32, 61, 32,115,101,108,102, 46,116,121,112,
 101, 46, 46,115,101,108,102, 46,110, 97,109,101, 10,115,101,
 108,102, 46,110, 97,109,101, 32, 61, 32, 99,114,101, 97,116,
 101, 95,118, 97,114,110, 97,109,101, 40, 41, 10,101,108,115,
 101,105,102, 32,105,115,116,121,112,101, 40,115,101,108,102,
  46,110, 97,109,101, 41, 32,116,104,101,110, 10,105,102, 32,
 115,101,108,102, 46,116,121,112,101, 61, 61, 39, 39, 32,116,
 104,101,110, 32,115,101,108,102, 46,116,121,112,101, 32, 61,
  32,115,101,108,102, 46,110, 97,109,101, 10,101,108,115,101,
  32,115,101,108,102, 46,116,121,112,101, 32, 61, 32,115,101,
 108,102, 46,116,121,112,101, 46, 46, 39, 32, 39, 46, 46,115,
 101,108,102, 46,110, 97,109,101, 32,101,110,100, 10,115,101,
 108,102, 46,110, 97,109,101, 32, 61, 32, 99,114,101, 97,116,
 101, 95,118, 97,114,110, 97,109,101, 40, 41, 10,101,110,100,
  10,101,110,100, 10, 10,101,110,100, 10, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99,
 108, 97,114, 97,116,105,111,110, 58, 99,104,101, 99,107,116,
 121,112,101, 32, 40, 41, 10, 10, 10,105,102, 32,105,115, 98,
  97,115,105, 99, 40,115,101,108,102, 46,116,121,112,101, 41,
  32, 97,110,100, 32,115,101,108,102, 46,112,116,114,126, 61,
  39, 39, 32,116,104,101,110, 10,115,101,108,102, 46,114,101,
 116, 32, 61, 32,115,101,108,102, 46,112,116,114, 10,115,101,
 108,102, 46,112,116,114, 32, 61, 32,110,105,108, 10,101,110,
 100, 10, 10, 10,105,102, 32,115,101,108,102, 46,100,105,109,
 126, 61, 39, 39, 32, 97,110,100, 32,115,101,108,102, 46,114,
 101,116,126, 61, 39, 39, 32,116,104,101,110, 10,101,114,114,
 111,114, 40, 39, 35,105,110,118, 97,108,105,100, 32,112, 97,
 114, 97,109,101,116,101,114, 58, 32, 99, 97,110,110,111,116,
  32,114,101,116,117,114,110, 32, 97,110, 32, 97,114,114, 97,
 121, 32,111,102, 32,118, 97,108,117,101,115, 39, 41, 10,101,
 110,100, 10, 10, 10,105,102, 32,115,101,108,102, 46,116,121,
 112,101,126, 61, 39, 39, 32,116,104,101,110, 10,114,101,103,
 116,121,112,101, 40,115,101,108,102, 46,116,121,112,101, 41,
  10,101,110,100, 10, 10, 10,105,102, 32,115,101,108,102, 46,
 116,121,112,101, 32, 61, 61, 32, 39, 95,117,115,101,114,100,
  97,116, 97, 39, 32,116,104,101,110, 32,115,101,108,102, 46,
 116,121,112,101, 32, 61, 32, 39,118,111,105,100, 42, 39, 10,
 101,108,115,101,105,102, 32,115,101,108,102, 46,116,121,112,
 101, 32, 61, 61, 32, 39, 95, 99,115,116,114,105,110,103, 39,
  32,116,104,101,110, 32,115,101,108,102, 46,116,121,112,101,
  32, 61, 32, 39, 99,104, 97,114, 42, 39, 10,101,110,100, 10,
  10, 10, 10, 10, 10, 10, 10, 10,101,110,100, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101,
  99,108, 97,114, 97,116,105,111,110, 58,112,114,105,110,116,
  32, 40,105,100,101,110,116, 44, 99,108,111,115,101, 41, 10,
 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 68,
 101, 99,108, 97,114, 97,116,105,111,110,123, 34, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,109,
 111,100, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,109,
 111,100, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,116,
  40,105,100,101,110,116, 46, 46, 34, 32,116,121,112,101, 32,
  61, 32, 39, 34, 46, 46,115,101,108,102, 46,116,121,112,101,
  46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,
 100,101,110,116, 46, 46, 34, 32,112,116,114, 32, 61, 32, 39,
  34, 46, 46,115,101,108,102, 46,112,116,114, 46, 46, 34, 39,
  44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116,
  46, 46, 34, 32,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,
 115,101,108,102, 46,110, 97,109,101, 46, 46, 34, 39, 44, 34,
  41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46,
  34, 32,100,105,109, 32, 61, 32, 39, 34, 46, 46,115,101,108,
 102, 46,100,105,109, 46, 46, 34, 39, 44, 34, 41, 10,112,114,
 105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,100,101,
 102, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,100,101,
 102, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,
 105,100,101,110,116, 46, 46, 34, 32,114,101,116, 32, 61, 32,
  39, 34, 46, 46,115,101,108,102, 46,114,101,116, 46, 46, 34,
  39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,
 101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,110, 32,
  99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,
 110, 58,100,101, 99,108,116, 97,103, 32, 40, 41, 10,115,101,
 108,102, 46,105,116,121,112,101, 44, 32,115,101,108,102, 46,
 116, 97,103, 32, 61, 32,116, 97,103,118, 97,114, 40,115,101,
 108,102, 46,116,121,112,101, 44,115,116,114,102,105,110,100,
  40,115,101,108,102, 46,109,111,100, 44, 39, 99,111,110,115,
 116, 39, 41, 41, 10,101,110,100, 10, 10, 10, 10,102,117,110,
  99,116,105,111,110, 32, 99,108, 97,115,115, 68,101, 99,108,
  97,114, 97,116,105,111,110, 58,111,117,116, 99,104,101, 99,
 107,116,121,112,101, 32, 40,110, 97,114,103, 41, 10,108,111,
  99, 97,108, 32,116, 97,103, 44, 32,100,101,102, 10,105,102,
  32,115,101,108,102, 46,100,105,109, 32,126, 61, 32, 39, 39,
  32,116,104,101,110, 10,116, 97,103, 32, 61, 32, 39, 76, 85,
  65, 95, 84, 84, 65, 66, 76, 69, 39, 10,100,101,102, 32, 61,
  32, 48, 10,101,108,115,101, 10,116, 97,103, 32, 61, 32,115,
 101,108,102, 46,116, 97,103, 10,100,101,102, 32, 61, 32,115,
 101,108,102, 46,100,101,102,126, 61, 39, 39, 32,111,114, 32,
  48, 10,101,110,100, 10,114,101,116,117,114,110, 32, 39,116,
 111,108,117, 97, 95,105,115,116,121,112,101, 40,116,111,108,
 117, 97, 95, 83, 44, 39, 46, 46,110, 97,114,103, 46, 46, 39,
  44, 39, 46, 46,116, 97,103, 46, 46, 39, 44, 39, 46, 46,100,
 101,102, 46, 46, 39, 41, 39, 10,101,110,100, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101,
  99,108, 97,114, 97,116,105,111,110, 58,100,101, 99,108, 97,
 114,101, 32, 40,110, 97,114,103, 41, 10,108,111, 99, 97,108,
  32,112,116,114, 32, 61, 32, 39, 39, 10,105,102, 32,115,101,
 108,102, 46,112,116,114,126, 61, 39, 39, 32,116,104,101,110,
  32,112,116,114, 32, 61, 32, 39, 42, 39, 32,101,110,100, 10,
 111,117,116,112,117,116, 40, 34, 32, 34, 44,115,101,108,102,
  46,109,111,100, 44,115,101,108,102, 46,116,121,112,101, 44,
 112,116,114, 41, 10,105,102, 32,115,101,108,102, 46,100,105,
 109, 32,126, 61, 32, 39, 39, 32, 97,110,100, 32,116,111,110,
 117,109, 98,101,114, 40,115,101,108,102, 46,100,105,109, 41,
  61, 61,110,105,108, 32,116,104,101,110, 10,111,117,116,112,
 117,116, 40, 39, 42, 39, 41, 10,101,110,100, 10,111,117,116,
 112,117,116, 40,115,101,108,102, 46,110, 97,109,101, 41, 10,
 105,102, 32,115,101,108,102, 46,100,105,109, 32,126, 61, 32,
  39, 39, 32,116,104,101,110, 10,105,102, 32,116,111,110,117,
 109, 98,101,114, 40,115,101,108,102, 46,100,105,109, 41,126,
  61,110,105,108, 32,116,104,101,110, 10,111,117,116,112,117,
 116, 40, 39, 91, 39, 44,115,101,108,102, 46,100,105,109, 44,
  39, 93, 59, 39, 41, 10,101,108,115,101, 10,111,117,116,112,
 117,116, 40, 39, 32, 61, 32, 40, 39, 44,115,101,108,102, 46,
 109,111,100, 44,115,101,108,102, 46,116,121,112,101, 44,112,
 116,114, 44, 39, 42, 41, 39, 44, 10, 39,109, 97,108,108,111,
  99, 40, 39, 44,115,101,108,102, 46,100,105,109, 44, 39, 42,
 115,105,122,101,111,102, 40, 39, 44,115,101,108,102, 46,116,
 121,112,101, 44,112,116,114, 44, 39, 41, 41, 59, 39, 41, 10,
 101,110,100, 10,101,108,115,101, 10,108,111, 99, 97,108, 32,
 116, 32, 61, 32,105,115, 98, 97,115,105, 99, 40,115,101,108,
 102, 46,116,121,112,101, 41, 10,111,117,116,112,117,116, 40,
  39, 32, 61, 32, 39, 41, 10,105,102, 32,110,111,116, 32,116,
  32, 97,110,100, 32,112,116,114, 61, 61, 39, 39, 32,116,104,
 101,110, 32,111,117,116,112,117,116, 40, 39, 42, 39, 41, 32,
 101,110,100, 10,111,117,116,112,117,116, 40, 39, 40, 40, 39,
  44,115,101,108,102, 46,109,111,100, 44,115,101,108,102, 46,
 116,121,112,101, 41, 10,105,102, 32,110,111,116, 32,116, 32,
 116,104,101,110, 10,111,117,116,112,117,116, 40, 39, 42, 39,
  41, 10,101,110,100, 10,111,117,116,112,117,116, 40, 39, 41,
  32, 39, 41, 10,108,111, 99, 97,108, 32,100,101,102, 32, 61,
  32, 48, 10,105,102, 32,115,101,108,102, 46,100,101,102, 32,
 126, 61, 32, 39, 39, 32,116,104,101,110, 32,100,101,102, 32,
  61, 32,115,101,108,102, 46,100,101,102, 32,101,110,100, 10,
 105,102, 32,116, 32,116,104,101,110, 10,111,117,116,112,117,
 116, 40, 39,116,111,108,117, 97, 95,103,101,116, 39, 46, 46,
 116, 44, 39, 40,116,111,108,117, 97, 95, 83, 44, 39, 44,110,
  97,114,103, 44, 39, 44, 39, 44,100,101,102, 44, 39, 41, 41,
  59, 39, 41, 10,101,108,115,101, 10,111,117,116,112,117,116,
  40, 39,116,111,108,117, 97, 95,103,101,116,117,115,101,114,
 116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 39, 44,
 110, 97,114,103, 44, 39, 44, 39, 44,100,101,102, 44, 39, 41,
  41, 59, 39, 41, 10,101,110,100, 10,101,110,100, 10,101,110,
 100, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108,
  97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58,
 103,101,116, 97,114,114, 97,121, 32, 40,110, 97,114,103, 41,
  10,105,102, 32,115,101,108,102, 46,100,105,109, 32,126, 61,
  32, 39, 39, 32,116,104,101,110, 10,111,117,116,112,117,116,
  40, 39, 32,123, 39, 41, 10,108,111, 99, 97,108, 32,100,101,
 102, 32, 61, 32,115,101,108,102, 46,100,101,102,126, 61, 39,
  39, 32,111,114, 32, 48, 10,111,117,116,112,117,116, 40, 39,
  32,105,102, 32, 40, 33,116,111,108,117, 97, 95, 97,114,114,
  97,121,105,115,116,121,112,101, 40,116,111,108,117, 97, 95,
  83, 44, 39, 44,110, 97,114,103, 44, 39, 44, 39, 44,115,101,
 108,102, 46,116, 97,103, 44, 39, 44, 39, 44,115,101,108,102,
  46,100,105,109, 44, 39, 44, 39, 44,100,101,102, 44, 39, 41,
  41, 39, 41, 10,111,117,116,112,117,116, 40, 39, 32,103,111,
 116,111, 32,116,111,108,117, 97, 95,108,101,114,114,111,114,
  59, 39, 41, 10,111,117,116,112,117,116, 40, 39, 32,101,108,
 115,101, 92,110, 39, 41, 10,111,117,116,112,117,116, 40, 39,
  32,123, 39, 41, 10,111,117,116,112,117,116, 40, 39, 32,105,
 110,116, 32,105, 59, 39, 41, 10,111,117,116,112,117,116, 40,
  39, 32,102,111,114, 40,105, 61, 48, 59, 32,105, 60, 39, 46,
  46,115,101,108,102, 46,100,105,109, 46, 46, 39, 59,105, 43,
  43, 41, 39, 41, 10,108,111, 99, 97,108, 32,116, 32, 61, 32,
 105,115, 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,
 112,101, 41, 10,108,111, 99, 97,108, 32,112,116,114, 32, 61,
  32, 39, 39, 10,105,102, 32,115,101,108,102, 46,112,116,114,
 126, 61, 39, 39, 32,116,104,101,110, 32,112,116,114, 32, 61,
  32, 39, 42, 39, 32,101,110,100, 10,111,117,116,112,117,116,
  40, 39, 32, 39, 44,115,101,108,102, 46,110, 97,109,101, 46,
  46, 39, 91,105, 93, 32, 61, 32, 39, 41, 10,105,102, 32,110,
 111,116, 32,116, 32, 97,110,100, 32,112,116,114, 61, 61, 39,
  39, 32,116,104,101,110, 32,111,117,116,112,117,116, 40, 39,
  42, 39, 41, 32,101,110,100, 10,111,117,116,112,117,116, 40,
  39, 40, 40, 39, 44,115,101,108,102, 46,109,111,100, 44,115,
 101,108,102, 46,116,121,112,101, 41, 10,105,102, 32,110,111,
 116, 32,116, 32,116,104,101,110, 10,111,117,116,112,117,116,
  40, 39, 42, 39, 41, 10,101,110,100, 10,111,117,116,112,117,
 116, 40, 39, 41, 32, 39, 41, 10,108,111, 99, 97,108, 32,100,
 101,102, 32, 61, 32, 48, 10,105,102, 32,115,101,108,102, 46,
 100,101,102, 32,126, 61, 32, 39, 39, 32,116,104,101,110, 32,
 100,101,102, 32, 61, 32,115,101,108,102, 46,100,101,102, 32,
 101,110,100, 10,105,102, 32,116, 32,116,104,101,110, 10,111,
 117,116,112,117,116, 40, 39,116,111,108,117, 97, 95,103,101,
 116,102,105,101,108,100, 39, 46, 46,116, 46, 46, 39, 40,116,
 111,108,117, 97, 95, 83, 44, 39, 44,110, 97,114,103, 44, 39,
  44,105, 43, 49, 44, 39, 44,100,101,102, 44, 39, 41, 41, 59,
  39, 41, 10,101,108,115,101, 10,111,117,116,112,117,116, 40,
  39,116,111,108,117, 97, 95,103,101,116,102,105,101,108,100,
 117,115,101,114,116,121,112,101, 40,116,111,108,117, 97, 95,
  83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49, 44,
  39, 44,100,101,102, 44, 39, 41, 41, 59, 39, 41, 10,101,110,
 100, 10,111,117,116,112,117,116, 40, 39, 32,125, 39, 41, 10,
 111,117,116,112,117,116, 40, 39, 32,125, 39, 41, 10,101,110,
 100, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,
 110, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,
 105,111,110, 58,115,101,116, 97,114,114, 97,121, 32, 40,110,
  97,114,103, 41, 10,105,102, 32,115,101,108,102, 46,100,105,
 109, 32,126, 61, 32, 39, 39, 32,116,104,101,110, 10,111,117,
 116,112,117,116, 40, 39, 32,123, 39, 41, 10,111,117,116,112,
 117,116, 40, 39, 32,105,110,116, 32,105, 59, 39, 41, 10,111,
 117,116,112,117,116, 40, 39, 32,102,111,114, 40,105, 61, 48,
  59, 32,105, 60, 39, 46, 46,115,101,108,102, 46,100,105,109,
  46, 46, 39, 59,105, 43, 43, 41, 39, 41, 10,108,111, 99, 97,
 108, 32,116, 44, 99,116, 32, 61, 32,105,115, 98, 97,115,105,
  99, 40,115,101,108,102, 46,116,121,112,101, 41, 10,105,102,
  32,116, 32,116,104,101,110, 10,111,117,116,112,117,116, 40,
  39, 32,116,111,108,117, 97, 95,112,117,115,104,102,105,101,
 108,100, 39, 46, 46,116, 46, 46, 39, 40,116,111,108,117, 97,
  95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49,
  44, 40, 39, 44, 99,116, 44, 39, 41, 39, 44,115,101,108,102,
  46,110, 97,109,101, 44, 39, 91,105, 93, 41, 59, 39, 41, 10,
 101,108,115,101, 10,105,102, 32,115,101,108,102, 46,112,116,
 114, 32, 61, 61, 32, 39, 39, 32,116,104,101,110, 10,111,117,
 116,112,117,116, 40, 39, 32,123, 39, 41, 10,111,117,116,112,
 117,116, 40, 39, 35,105,102,100,101,102, 32, 95, 95, 99,112,
 108,117,115,112,108,117,115, 92,110, 39, 41, 10,111,117,116,
 112,117,116, 40, 39, 32,118,111,105,100, 42, 32,116,111,108,
 117, 97, 73, 95, 99,108,111,110,101, 32, 61, 32,110,101,119,
  39, 44,115,101,108,102, 46,116,121,112,101, 44, 39, 40, 39,
  44,115,101,108,102, 46,110, 97,109,101, 44, 39, 91,105, 93,
  41, 59, 39, 41, 10,111,117,116,112,117,116, 40, 39, 35,101,
 108,115,101, 92,110, 39, 41, 10,111,117,116,112,117,116, 40,
  39, 32,118,111,105,100, 42, 32,116,111,108,117, 97, 73, 95,
  99,108,111,110,101, 32, 61, 32,116,111,108,117, 97, 95, 99,
 111,112,121, 40,116,111,108,117, 97, 95, 83, 44, 40,118,111,
 105,100, 42, 41, 38, 39, 44,115,101,108,102, 46,110, 97,109,
 101, 44, 39, 91,105, 93, 44,115,105,122,101,111,102, 40, 39,
  44,115,101,108,102, 46,116,121,112,101, 44, 39, 41, 41, 59,
  39, 41, 10,111,117,116,112,117,116, 40, 39, 35,101,110,100,
 105,102, 92,110, 39, 41, 10,111,117,116,112,117,116, 40, 39,
  32,116,111,108,117, 97, 95,112,117,115,104,102,105,101,108,
 100,117,115,101,114,116,121,112,101, 40,116,111,108,117, 97,
  95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,105, 43, 49,
  44,116,111,108,117, 97, 95,100,111, 99,108,111,110,101, 40,
 116,111,108,117, 97, 95, 83, 44,116,111,108,117, 97, 73, 95,
  99,108,111,110,101, 44, 39, 44,115,101,108,102, 46,116, 97,
 103, 44, 39, 41, 44, 39, 44,115,101,108,102, 46,116, 97,103,
  44, 39, 41, 59, 39, 41, 10,111,117,116,112,117,116, 40, 39,
  32,125, 39, 41, 10, 10, 10,101,108,115,101, 10,111,117,116,
 112,117,116, 40, 39, 32,116,111,108,117, 97, 95,112,117,115,
 104,102,105,101,108,100,117,115,101,114,116,121,112,101, 40,
 116,111,108,117, 97, 95, 83, 44, 39, 44,110, 97,114,103, 44,
  39, 44,105, 43, 49, 44, 40,118,111,105,100, 42, 41, 39, 44,
 115,101,108,102, 46,110, 97,109,101, 44, 39, 91,105, 93, 44,
  39, 44,115,101,108,102, 46,116, 97,103, 44, 39, 41, 59, 39,
  41, 10,101,110,100, 10,101,110,100, 10,111,117,116,112,117,
 116, 40, 39, 32,125, 39, 41, 10,101,110,100, 10,101,110,100,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,
 115,115, 68,101, 99,108, 97,114, 97,116,105,111,110, 58,102,
 114,101,101, 97,114,114, 97,121, 32, 40, 41, 10,105,102, 32,
 115,101,108,102, 46,100,105,109, 32,126, 61, 32, 39, 39, 32,
  97,110,100, 32,116,111,110,117,109, 98,101,114, 40,115,101,
 108,102, 46,100,105,109, 41, 61, 61,110,105,108, 32,116,104,
 101,110, 10,111,117,116,112,117,116, 40, 39, 32,102,114,101,
 101, 40, 39, 44,115,101,108,102, 46,110, 97,109,101, 44, 39,
  41, 59, 39, 41, 10,101,110,100, 10,101,110,100, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,
 101, 99,108, 97,114, 97,116,105,111,110, 58,112, 97,115,115,
 112, 97,114, 32, 40, 41, 10,105,102, 32,115,101,108,102, 46,
 112,116,114, 61, 61, 39, 38, 39, 32,116,104,101,110, 10,111,
 117,116,112,117,116, 40, 39, 42, 39, 46, 46,115,101,108,102,
  46,110, 97,109,101, 41, 10,101,108,115,101,105,102, 32,115,
 101,108,102, 46,114,101,116, 61, 61, 39, 42, 39, 32,116,104,
 101,110, 10,111,117,116,112,117,116, 40, 39, 38, 39, 46, 46,
 115,101,108,102, 46,110, 97,109,101, 41, 10,101,108,115,101,
  10,111,117,116,112,117,116, 40,115,101,108,102, 46,110, 97,
 109,101, 41, 10,101,110,100, 10,101,110,100, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 68,101,
  99,108, 97,114, 97,116,105,111,110, 58,114,101,116,118, 97,
 108,117,101, 32, 40, 41, 10,105,102, 32,115,101,108,102, 46,
 114,101,116, 32,126, 61, 32, 39, 39, 32,116,104,101,110, 10,
 108,111, 99, 97,108, 32,116, 44, 99,116, 32, 61, 32,105,115,
  98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,112,101,
  41, 10,105,102, 32,116, 32,116,104,101,110, 10,111,117,116,
 112,117,116, 40, 39, 32,116,111,108,117, 97, 95,112,117,115,
 104, 39, 46, 46,116, 46, 46, 39, 40,116,111,108,117, 97, 95,
  83, 44, 40, 39, 44, 99,116, 44, 39, 41, 39, 46, 46,115,101,
 108,102, 46,110, 97,109,101, 46, 46, 39, 41, 59, 39, 41, 10,
 101,108,115,101, 10,111,117,116,112,117,116, 40, 39, 32,116,
 111,108,117, 97, 95,112,117,115,104,117,115,101,114,116,121,
 112,101, 40,116,111,108,117, 97, 95, 83, 44, 40,118,111,105,
 100, 42, 41, 39, 46, 46,115,101,108,102, 46,110, 97,109,101,
  46, 46, 39, 44, 39, 44,115,101,108,102, 46,116, 97,103, 44,
  39, 41, 59, 39, 41, 10,101,110,100, 10,114,101,116,117,114,
 110, 32, 49, 10,101,110,100, 10,114,101,116,117,114,110, 32,
  48, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,
 110, 32, 95, 68,101, 99,108, 97,114, 97,116,105,111,110, 32,
  40,116, 41, 10,105,102, 32,116, 46,110, 97,109,101, 32, 97,
 110,100, 32,116, 46,110, 97,109,101,126, 61, 39, 39, 32,116,
 104,101,110, 10,108,111, 99, 97,108, 32,110, 32, 61, 32,115,
 112,108,105,116, 40,116, 46,110, 97,109,101, 44, 39, 64, 39,
  41, 10,116, 46,110, 97,109,101, 32, 61, 32,110, 91, 49, 93,
  10,116, 46,108,110, 97,109,101, 32, 61, 32,103,115,117, 98,
  40,110, 91, 50, 93, 32,111,114, 32,110, 91, 49, 93, 44, 34,
  37, 91, 46, 45, 37, 93, 34, 44, 34, 34, 41, 10,101,110,100,
  10,116, 46, 95, 98, 97,115,101, 32, 61, 32, 99,108, 97,115,
 115, 68,101, 99,108, 97,114, 97,116,105,111,110, 10,115,101,
 116,116, 97,103, 40,116, 44,116,111,108,117, 97, 95,116, 97,
 103, 41, 10,116, 58, 99,104,101, 99,107,110, 97,109,101, 40,
  41, 10,116, 58, 99,104,101, 99,107,116,121,112,101, 40, 41,
  10,114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 68,101, 99,
 108, 97,114, 97,116,105,111,110, 32, 40,115, 44,107,105,110,
 100, 41, 10, 10,115, 32, 61, 32,103,115,117, 98, 40,115, 44,
  34, 37,115, 42, 61, 37,115, 42, 34, 44, 34, 61, 34, 41, 10,
  10,105,102, 32,107,105,110,100, 32, 61, 61, 32, 34,118, 97,
 114, 34, 32,116,104,101,110, 10, 10,105,102, 32,115, 32, 61,
  61, 32, 39, 39, 32,111,114, 32,115, 32, 61, 61, 32, 39,118,
 111,105,100, 39, 32,116,104,101,110, 10,114,101,116,117,114,
 110, 32, 95, 68,101, 99,108, 97,114, 97,116,105,111,110,123,
 116,121,112,101, 32, 61, 32, 39,118,111,105,100, 39, 44, 32,
 107,105,110,100, 32, 61, 32,107,105,110,100,125, 10,101,110,
 100, 10,101,110,100, 10, 10, 10,108,111, 99, 97,108, 32,116,
  32, 61, 32,115,112,108,105,116, 40,115, 44, 39, 37, 42, 37,
 115, 42, 38, 39, 41, 10,105,102, 32,116, 46,110, 32, 61, 61,
  32, 50, 32,116,104,101,110, 10,105,102, 32,107,105,110,100,
  32, 61, 61, 32, 39,102,117,110, 99, 39, 32,116,104,101,110,
  10,101,114,114,111,114, 40, 34, 35,105,110,118, 97,108,105,
 100, 32,102,117,110, 99,116,105,111,110, 32,114,101,116,117,
 114,110, 32,116,121,112,101, 58, 32, 34, 46, 46,115, 41, 10,
 101,110,100, 10,108,111, 99, 97,108, 32,109, 32, 61, 32,115,
 112,108,105,116, 40,116, 91, 49, 93, 44, 39, 37,115, 37,115,
  42, 39, 41, 10,114,101,116,117,114,110, 32, 95, 68,101, 99,
 108, 97,114, 97,116,105,111,110,123, 10,110, 97,109,101, 32,
  61, 32,116, 91, 50, 93, 44, 10,112,116,114, 32, 61, 32, 39,
  42, 39, 44, 10,114,101,116, 32, 61, 32, 39, 38, 39, 44, 10,
 116,121,112,101, 32, 61, 32,109, 91,109, 46,110, 93, 44, 10,
 109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, 40,109, 44,
  49, 44,109, 46,110, 45, 49, 41, 44, 10,107,105,110,100, 32,
  61, 32,107,105,110,100, 10,125, 10,101,110,100, 10, 10, 10,
 116, 32, 61, 32,115,112,108,105,116, 40,115, 44, 39, 37, 42,
  37,115, 42, 37, 42, 39, 41, 10,105,102, 32,116, 46,110, 32,
  61, 61, 32, 50, 32,116,104,101,110, 10,105,102, 32,107,105,
 110,100, 32, 61, 61, 32, 39,102,117,110, 99, 39, 32,116,104,
 101,110, 10,101,114,114,111,114, 40, 34, 35,105,110,118, 97,
 108,105,100, 32,102,117,110, 99,116,105,111,110, 32,114,101,
 116,117,114,110, 32,116,121,112,101, 58, 32, 34, 46, 46,115,
  41, 10,101,110,100, 10,108,111, 99, 97,108, 32,109, 32, 61,
  32,115,112,108,105,116, 40,116, 91, 49, 93, 44, 39, 37,115,
  37,115, 42, 39, 41, 10,114,101,116,117,114,110, 32, 95, 68,
 101, 99,108, 97,114, 97,116,105,111,110,123, 10,110, 97,109,
 101, 32, 61, 32,116, 91, 50, 93, 44, 10,112,116,114, 32, 61,
  32, 39, 42, 39, 44, 10,114,101,116, 32, 61, 32, 39, 42, 39,
  44, 10,116,121,112,101, 32, 61, 32,109, 91,109, 46,110, 93,
  44, 10,109,111,100, 32, 61, 32, 99,111,110, 99, 97,116, 40,
 109, 44, 49, 44,109, 46,110, 45, 49, 41, 44, 10,107,105,110,
 100, 32, 61, 32,107,105,110,100, 10,125, 10,101,110,100, 10,
  10, 10,116, 32, 61, 32,115,112,108,105,116, 40,115, 44, 39,
  38, 39, 41, 10,105,102, 32,116, 46,110, 32, 61, 61, 32, 50,
  32,116,104,101,110, 10,108,111, 99, 97,108, 32,109, 32, 61,
  32,115,112,108,105,116, 40,116, 91, 49, 93, 44, 39, 37,115,
  37,115, 42, 39, 41, 10,114,101,116,117,114,110, 32, 95, 68,
 101, 99,108, 97,114, 97,116,105,111,110,123, 10,110, 97,109,
 101, 32, 61, 32,116, 91, 50, 93, 44, 10,112,116,114, 32, 61,
  32, 39, 38, 39, 44, 10,116,121,112,101, 32, 61, 32,109, 91,
 109, 46,110, 93, 44, 10,109,111,100, 32, 61, 32, 99,111,110,
  99, 97,116, 40,109, 44, 49, 44,109, 46,110, 45, 49, 41, 32,
  44, 10,107,105,110,100, 32, 61, 32,107,105,110,100, 10,125,
  10,101,110,100, 10, 10, 10,108,111, 99, 97,108, 32,115, 49,
  32, 61, 32,103,115,117, 98, 40,115, 44, 34, 40, 37, 98, 92,
  91, 92, 93, 41, 34, 44,102,117,110, 99,116,105,111,110, 32,
  40,110, 41, 32,114,101,116,117,114,110, 32,103,115,117, 98,
  40,110, 44, 39, 37, 42, 39, 44, 39, 92, 49, 39, 41, 32,101,
 110,100, 41, 10,116, 32, 61, 32,115,112,108,105,116, 40,115,
  49, 44, 39, 37, 42, 39, 41, 10,105,102, 32,116, 46,110, 32,
  61, 61, 32, 50, 32,116,104,101,110, 10,116, 91, 50, 93, 32,
  61, 32,103,115,117, 98, 40,116, 91, 50, 93, 44, 39, 92, 49,
  39, 44, 39, 37, 42, 39, 41, 10,108,111, 99, 97,108, 32,109,
  32, 61, 32,115,112,108,105,116, 40,116, 91, 49, 93, 44, 39,
  37,115, 37,115, 42, 39, 41, 10,114,101,116,117,114,110, 32,
  95, 68,101, 99,108, 97,114, 97,116,105,111,110,123, 10,110,
  97,109,101, 32, 61, 32,116, 91, 50, 93, 44, 10,112,116,114,
  32, 61, 32, 39, 42, 39, 44, 10,116,121,112,101, 32, 61, 32,
 109, 91,109, 46,110, 93, 44, 10,109,111,100, 32, 61, 32, 99,
 111,110, 99, 97,116, 40,109, 44, 49, 44,109, 46,110, 45, 49,
  41, 32, 44, 10,107,105,110,100, 32, 61, 32,107,105,110,100,
  10,125, 10,101,110,100, 10, 10,105,102, 32,107,105,110,100,
  32, 61, 61, 32, 39,118, 97,114, 39, 32,116,104,101,110, 10,
  10,116, 32, 61, 32,115,112,108,105,116, 40,115, 44, 39, 37,
 115, 37,115, 42, 39, 41, 10,108,111, 99, 97,108, 32,118, 10,
 105,102, 32,105,115,116,121,112,101, 40,116, 91,116, 46,110,
  93, 41, 32,116,104,101,110, 32,118, 32, 61, 32, 39, 39, 32,
 101,108,115,101, 32,118, 32, 61, 32,116, 91,116, 46,110, 93,
  59, 32,116, 46,110, 32, 61, 32,116, 46,110, 45, 49, 32,101,
 110,100, 10,114,101,116,117,114,110, 32, 95, 68,101, 99,108,
  97,114, 97,116,105,111,110,123, 10,110, 97,109,101, 32, 61,
  32,118, 44, 10,116,121,112,101, 32, 61, 32,116, 91,116, 46,
 110, 93, 44, 10,109,111,100, 32, 61, 32, 99,111,110, 99, 97,
 116, 40,116, 44, 49, 44,116, 46,110, 45, 49, 41, 44, 10,107,
 105,110,100, 32, 61, 32,107,105,110,100, 10,125, 10, 10,101,
 108,115,101, 10, 10, 10,116, 32, 61, 32,115,112,108,105,116,
  40,115, 44, 39, 37,115, 37,115, 42, 39, 41, 10,108,111, 99,
  97,108, 32,118, 32, 61, 32,116, 91,116, 46,110, 93, 10,108,
 111, 99, 97,108, 32,116,112, 44,109,100, 10,105,102, 32,116,
  46,110, 62, 49, 32,116,104,101,110, 10,116,112, 32, 61, 32,
 116, 91,116, 46,110, 45, 49, 93, 10,109,100, 32, 61, 32, 99,
 111,110, 99, 97,116, 40,116, 44, 49, 44,116, 46,110, 45, 50,
  41, 10,101,110,100, 10,114,101,116,117,114,110, 32, 95, 68,
 101, 99,108, 97,114, 97,116,105,111,110,123, 10,110, 97,109,
 101, 32, 61, 32,118, 44, 10,116,121,112,101, 32, 61, 32,116,
 112, 44, 10,109,111,100, 32, 61, 32,109,100, 44, 10,107,105,
 110,100, 32, 61, 32,107,105,110,100, 10,125, 10,101,110,100,
  10, 10,101,110,100, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 99,108, 97,115,115, 86, 97,114,105,
  97, 98,108,101, 32, 61, 32,123, 10, 95, 98, 97,115,101, 32,
  61, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,
 105,111,110, 44, 10,125, 10, 10,115,101,116,116, 97,103, 40,
  99,108, 97,115,115, 86, 97,114,105, 97, 98,108,101, 44,116,
 111,108,117, 97, 95,116, 97,103, 41, 10, 10, 10,102,117,110,
  99,116,105,111,110, 32, 99,108, 97,115,115, 86, 97,114,105,
  97, 98,108,101, 58,112,114,105,110,116, 32, 40,105,100,101,
 110,116, 44, 99,108,111,115,101, 41, 10,112,114,105,110,116,
  40,105,100,101,110,116, 46, 46, 34, 86, 97,114,105, 97, 98,
 108,101,123, 34, 41, 10,112,114,105,110,116, 40,105,100,101,
 110,116, 46, 46, 34, 32,109,111,100, 32, 61, 32, 39, 34, 46,
  46,115,101,108,102, 46,109,111,100, 46, 46, 34, 39, 44, 34,
  41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46,
  34, 32,116,121,112,101, 32, 61, 32, 39, 34, 46, 46,115,101,
 108,102, 46,116,121,112,101, 46, 46, 34, 39, 44, 34, 41, 10,
 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,
 112,116,114, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,
 112,116,114, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,
 116, 40,105,100,101,110,116, 46, 46, 34, 32,110, 97,109,101,
  32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,110, 97,109,
 101, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,
 105,100,101,110,116, 46, 46, 34, 32,100,101,102, 32, 61, 32,
  39, 34, 46, 46,115,101,108,102, 46,100,101,102, 46, 46, 34,
  39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34, 32,114,101,116, 32, 61, 32, 39, 34, 46, 46,
 115,101,108,102, 46,114,101,116, 46, 46, 34, 39, 44, 34, 41,
  10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34,
 125, 34, 46, 46, 99,108,111,115,101, 41, 10,101,110,100, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,
 115, 86, 97,114,105, 97, 98,108,101, 58,103,101,116,118, 97,
 108,117,101, 32, 40, 99,108, 97,115,115, 44,115,116, 97,116,
 105, 99, 41, 10,105,102, 32, 99,108, 97,115,115, 32, 97,110,
 100, 32,115,116, 97,116,105, 99, 32,116,104,101,110, 10,114,
 101,116,117,114,110, 32, 99,108, 97,115,115, 46, 46, 39, 58,
  58, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, 10,101,
 108,115,101,105,102, 32, 99,108, 97,115,115, 32,116,104,101,
 110, 10,114,101,116,117,114,110, 32, 39,115,101,108,102, 45,
  62, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, 10,101,
 108,115,101, 10,114,101,116,117,114,110, 32,115,101,108,102,
  46,110, 97,109,101, 10,101,110,100, 10,101,110,100, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115,
  86, 97,114,105, 97, 98,108,101, 58,115,117,112, 99,111,100,
 101, 32, 40, 41, 10,108,111, 99, 97,108, 32, 99,108, 97,115,
 115, 32, 61, 32,115,101,108,102, 58,105,110, 99,108, 97,115,
 115, 40, 41, 10, 10, 10,105,102, 32, 99,108, 97,115,115, 32,
 116,104,101,110, 10,111,117,116,112,117,116, 40, 34, 47, 42,
  32,103,101,116, 32,102,117,110, 99,116,105,111,110, 58, 34,
  44,115,101,108,102, 46,110, 97,109,101, 44, 34, 32,111,102,
  32, 99,108, 97,115,115, 32, 34, 44, 99,108, 97,115,115, 44,
  34, 32, 42, 47, 34, 41, 10,101,108,115,101, 10,111,117,116,
 112,117,116, 40, 34, 47, 42, 32,103,101,116, 32,102,117,110,
  99,116,105,111,110, 58, 34, 44,115,101,108,102, 46,110, 97,
 109,101, 44, 34, 32, 42, 47, 34, 41, 10,101,110,100, 10,115,
 101,108,102, 46, 99,103,101,116,110, 97,109,101, 32, 61, 32,
 115,101,108,102, 58, 99,102,117,110, 99,110, 97,109,101, 40,
  34,116,111,108,117, 97, 73, 95,103,101,116, 34, 41, 10,111,
 117,116,112,117,116, 40, 34,115,116, 97,116,105, 99, 32,105,
 110,116, 34, 44,115,101,108,102, 46, 99,103,101,116,110, 97,
 109,101, 44, 34, 40,108,117, 97, 95, 83,116, 97,116,101, 42,
  32,116,111,108,117, 97, 95, 83, 41, 34, 41, 10,111,117,116,
 112,117,116, 40, 34,123, 34, 41, 10, 10, 10,108,111, 99, 97,
 108, 32, 95, 44, 95, 44,115,116, 97,116,105, 99, 32, 61, 32,
 115,116,114,102,105,110,100, 40,115,101,108,102, 46,109,111,
 100, 44, 39, 94, 37,115, 42, 40,115,116, 97,116,105, 99, 41,
  39, 41, 10,105,102, 32, 99,108, 97,115,115, 32, 97,110,100,
  32,115,116, 97,116,105, 99, 61, 61,110,105,108, 32,116,104,
 101,110, 10,111,117,116,112,117,116, 40, 39, 32, 39, 44, 99,
 108, 97,115,115, 44, 39, 42, 39, 44, 39,115,101,108,102, 32,
  61, 32, 39, 41, 10,111,117,116,112,117,116, 40, 39, 40, 39,
  44, 99,108, 97,115,115, 44, 39, 42, 41, 32, 39, 41, 10,111,
 117,116,112,117,116, 40, 39,116,111,108,117, 97, 95,103,101,
 116,117,115,101,114,116,121,112,101, 40,116,111,108,117, 97,
  95, 83, 44, 49, 44, 48, 41, 59, 39, 41, 10,101,108,115,101,
 105,102, 32,115,116, 97,116,105, 99, 32,116,104,101,110, 10,
  95, 44, 95, 44,115,101,108,102, 46,109,111,100, 32, 61, 32,
 115,116,114,102,105,110,100, 40,115,101,108,102, 46,109,111,
 100, 44, 39, 94, 37,115, 42,115,116, 97,116,105, 99, 37,115,
  37,115, 42, 40, 46, 42, 41, 39, 41, 10,101,110,100, 10, 10,
  10, 10,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, 32,
 115,116, 97,116,105, 99, 61, 61,110,105,108, 32,116,104,101,
 110, 10,111,117,116,112,117,116, 40, 39, 32,105,102, 32, 40,
  33,115,101,108,102, 41, 32, 84, 79, 76, 85, 65, 95, 69, 82,
  82, 95, 83, 69, 76, 70, 59, 39, 41, 59, 10,101,110,100, 10,
  10, 10,108,111, 99, 97,108, 32,116, 44, 99,116, 32, 61, 32,
 105,115, 98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,
 112,101, 41, 10,105,102, 32,116, 32,116,104,101,110, 10,111,
 117,116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95,112,
 117,115,104, 39, 46, 46,116, 46, 46, 39, 40,116,111,108,117,
  97, 95, 83, 44, 40, 39, 44, 99,116, 44, 39, 41, 39, 46, 46,
 115,101,108,102, 58,103,101,116,118, 97,108,117,101, 40, 99,
 108, 97,115,115, 44,115,116, 97,116,105, 99, 41, 46, 46, 39,
  41, 59, 39, 41, 10,101,108,115,101, 10,105,102, 32,115,101,
 108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, 32,111,
 114, 32,115,101,108,102, 46,112,116,114, 32, 61, 61, 32, 39,
  39, 32,116,104,101,110, 10,111,117,116,112,117,116, 40, 39,
  32,116,111,108,117, 97, 95,112,117,115,104,117,115,101,114,
 116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 40,118,
 111,105,100, 42, 41, 38, 39, 46, 46,115,101,108,102, 58,103,
 101,116,118, 97,108,117,101, 40, 99,108, 97,115,115, 44,115,
 116, 97,116,105, 99, 41, 46, 46, 39, 44, 39, 44,115,101,108,
 102, 46,116, 97,103, 44, 39, 41, 59, 39, 41, 10,101,108,115,
 101, 10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117,
  97, 95,112,117,115,104,117,115,101,114,116,121,112,101, 40,
 116,111,108,117, 97, 95, 83, 44, 40,118,111,105,100, 42, 41,
  39, 46, 46,115,101,108,102, 58,103,101,116,118, 97,108,117,
 101, 40, 99,108, 97,115,115, 44,115,116, 97,116,105, 99, 41,
  46, 46, 39, 44, 39, 44,115,101,108,102, 46,116, 97,103, 44,
  39, 41, 59, 39, 41, 10,101,110,100, 10,101,110,100, 10,111,
 117,116,112,117,116, 40, 39, 32,114,101,116,117,114,110, 32,
  49, 59, 39, 41, 10,111,117,116,112,117,116, 40, 39,125, 39,
  41, 10,111,117,116,112,117,116, 40, 39, 92,110, 39, 41, 10,
  10, 10,105,102, 32,110,111,116, 32,115,116,114,102,105,110,
 100, 40,115,101,108,102, 46,109,111,100, 44, 39, 99,111,110,
 115,116, 39, 41, 32,116,104,101,110, 10,105,102, 32, 99,108,
  97,115,115, 32,116,104,101,110, 10,111,117,116,112,117,116,
  40, 34, 47, 42, 32,115,101,116, 32,102,117,110, 99,116,105,
 111,110, 58, 34, 44,115,101,108,102, 46,110, 97,109,101, 44,
  34, 32,111,102, 32, 99,108, 97,115,115, 32, 34, 44, 99,108,
  97,115,115, 44, 34, 32, 42, 47, 34, 41, 10,101,108,115,101,
  10,111,117,116,112,117,116, 40, 34, 47, 42, 32,115,101,116,
  32,102,117,110, 99,116,105,111,110, 58, 34, 44,115,101,108,
 102, 46,110, 97,109,101, 44, 34, 32, 42, 47, 34, 41, 10,101,
 110,100, 10,115,101,108,102, 46, 99,115,101,116,110, 97,109,
 101, 32, 61, 32,115,101,108,102, 58, 99,102,117,110, 99,110,
  97,109,101, 40, 34,116,111,108,117, 97, 73, 95,115,101,116,
  34, 41, 10,111,117,116,112,117,116, 40, 34,115,116, 97,116,
 105, 99, 32,105,110,116, 34, 44,115,101,108,102, 46, 99,115,
 101,116,110, 97,109,101, 44, 34, 40,108,117, 97, 95, 83,116,
  97,116,101, 42, 32,116,111,108,117, 97, 95, 83, 41, 34, 41,
  10,111,117,116,112,117,116, 40, 34,123, 34, 41, 10, 10, 10,
 108,111, 99, 97,108, 32,110, 97,114,103, 61, 49, 10,105,102,
  32, 99,108, 97,115,115, 32, 97,110,100, 32,115,116, 97,116,
 105, 99, 61, 61,110,105,108, 32,116,104,101,110, 10,111,117,
 116,112,117,116, 40, 39, 32, 39, 44, 99,108, 97,115,115, 44,
  39, 42, 39, 44, 39,115,101,108,102, 32, 61, 32, 39, 41, 10,
 111,117,116,112,117,116, 40, 39, 40, 39, 44, 99,108, 97,115,
 115, 44, 39, 42, 41, 32, 39, 41, 10,111,117,116,112,117,116,
  40, 39,116,111,108,117, 97, 95,103,101,116,117,115,101,114,
 116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 49, 44,
  48, 41, 59, 39, 41, 10, 10,111,117,116,112,117,116, 40, 39,
  32,105,102, 32, 40, 33,115,101,108,102, 41, 32, 84, 79, 76,
  85, 65, 95, 69, 82, 82, 95, 83, 69, 76, 70, 59, 39, 41, 59,
  10,110, 97,114,103, 32, 61, 32,110, 97,114,103, 43, 49, 10,
 101,108,115,101,105,102, 32,115,116, 97,116,105, 99, 32,116,
 104,101,110, 10, 95, 44, 95, 44,115,101,108,102, 46,109,111,
 100, 32, 61, 32,115,116,114,102,105,110,100, 40,115,101,108,
 102, 46,109,111,100, 44, 39, 94, 37,115, 42,115,116, 97,116,
 105, 99, 37,115, 37,115, 42, 40, 46, 42, 41, 39, 41, 10,110,
  97,114,103, 32, 61, 32,110, 97,114,103, 43, 49, 10,101,110,
 100, 10, 10, 10,111,117,116,112,117,116, 40, 39, 32,105,102,
  32, 40, 33, 39, 46, 46,115,101,108,102, 58,111,117,116, 99,
 104,101, 99,107,116,121,112,101, 40,110, 97,114,103, 41, 46,
  46, 39, 41, 39, 41, 10,111,117,116,112,117,116, 40, 39, 32,
  84, 79, 76, 85, 65, 95, 69, 82, 82, 95, 65, 83, 83, 73, 71,
  78, 59, 39, 41, 10, 10, 10,108,111, 99, 97,108, 32,112,116,
 114, 32, 61, 32, 39, 39, 10,105,102, 32,115,101,108,102, 46,
 112,116,114,126, 61, 39, 39, 32,116,104,101,110, 32,112,116,
 114, 32, 61, 32, 39, 42, 39, 32,101,110,100, 10,111,117,116,
 112,117,116, 40, 39, 32, 39, 41, 10,105,102, 32, 99,108, 97,
 115,115, 32, 97,110,100, 32,115,116, 97,116,105, 99, 32,116,
 104,101,110, 10,111,117,116,112,117,116, 40, 99,108, 97,115,
 115, 46, 46, 39, 58, 58, 39, 46, 46,115,101,108,102, 46,110,
  97,109,101, 41, 10,101,108,115,101,105,102, 32, 99,108, 97,
 115,115, 32,116,104,101,110, 10,111,117,116,112,117,116, 40,
  39,115,101,108,102, 45, 62, 39, 46, 46,115,101,108,102, 46,
 110, 97,109,101, 41, 10,101,108,115,101, 10,111,117,116,112,
 117,116, 40,115,101,108,102, 46,110, 97,109,101, 41, 10,101,
 110,100, 10,108,111, 99, 97,108, 32,116, 32, 61, 32,105,115,
  98, 97,115,105, 99, 40,115,101,108,102, 46,116,121,112,101,
  41, 10,111,117,116,112,117,116, 40, 39, 32, 61, 32, 39, 41,
  10,105,102, 32,110,111,116, 32,116, 32, 97,110,100, 32,112,
 116,114, 61, 61, 39, 39, 32,116,104,101,110, 32,111,117,116,
 112,117,116, 40, 39, 42, 39, 41, 32,101,110,100, 10,111,117,
 116,112,117,116, 40, 39, 40, 40, 39, 44,115,101,108,102, 46,
 109,111,100, 44,115,101,108,102, 46,116,121,112,101, 41, 10,
 105,102, 32,110,111,116, 32,116, 32,116,104,101,110, 10,111,
 117,116,112,117,116, 40, 39, 42, 39, 41, 10,101,110,100, 10,
 111,117,116,112,117,116, 40, 39, 41, 32, 39, 41, 10,108,111,
  99, 97,108, 32,100,101,102, 32, 61, 32, 48, 10,105,102, 32,
 115,101,108,102, 46,100,101,102, 32,126, 61, 32, 39, 39, 32,
 116,104,101,110, 32,100,101,102, 32, 61, 32,115,101,108,102,
  46,100,101,102, 32,101,110,100, 10,105,102, 32,116, 32,116,
 104,101,110, 10,111,117,116,112,117,116, 40, 39,116,111,108,
 117, 97, 95,103,101,116, 39, 46, 46,116, 44, 39, 40,116,111,
 108,117, 97, 95, 83, 44, 39, 44,110, 97,114,103, 44, 39, 44,
  39, 44,100,101,102, 44, 39, 41, 41, 59, 39, 41, 10,101,108,
 115,101, 10,111,117,116,112,117,116, 40, 39,116,111,108,117,
  97, 95,103,101,116,117,115,101,114,116,121,112,101, 40,116,
 111,108,117, 97, 95, 83, 44, 39, 44,110, 97,114,103, 44, 39,
  44, 39, 44,100,101,102, 44, 39, 41, 41, 59, 39, 41, 10,101,
 110,100, 10,111,117,116,112,117,116, 40, 39, 32,114,101,116,
 117,114,110, 32, 48, 59, 39, 41, 10,111,117,116,112,117,116,
  40, 39,125, 39, 41, 10,111,117,116,112,117,116, 40, 39, 92,
 110, 39, 41, 10,101,110,100, 10, 10,101,110,100, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 99,108, 97,115,115, 86, 97,
 114,105, 97, 98,108,101, 58,114,101,103,105,115,116,101,114,
  32, 40, 41, 10,108,111, 99, 97,108, 32,112, 97,114,101,110,
 116, 32, 61, 32,115,101,108,102, 58,105,110, 99,108, 97,115,
 115, 40, 41, 32,111,114, 32,115,101,108,102, 58,105,110,109,
 111,100,117,108,101, 40, 41, 10,105,102, 32,112, 97,114,101,
 110,116, 32,116,104,101,110, 10,105,102, 32,115,101,108,102,
  46, 99,115,101,116,110, 97,109,101, 32,116,104,101,110, 10,
 111,117,116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95,
 116, 97, 98,108,101,118, 97,114, 40,116,111,108,117, 97, 95,
  83, 44, 34, 39, 46, 46,112, 97,114,101,110,116, 46, 46, 39,
  34, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110, 97,109,
 101, 46, 46, 39, 34, 44, 39, 46, 46,115,101,108,102, 46, 99,
 103,101,116,110, 97,109,101, 46, 46, 39, 44, 39, 46, 46,115,
 101,108,102, 46, 99,115,101,116,110, 97,109,101, 46, 46, 39,
  41, 59, 39, 41, 10,101,108,115,101, 10,111,117,116,112,117,
 116, 40, 39, 32,116,111,108,117, 97, 95,116, 97, 98,108,101,
 118, 97,114, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46,
  46,112, 97,114,101,110,116, 46, 46, 39, 34, 44, 34, 39, 46,
  46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 39, 34,
  44, 39, 46, 46,115,101,108,102, 46, 99,103,101,116,110, 97,
 109,101, 46, 46, 39, 44, 78, 85, 76, 76, 41, 59, 39, 41, 10,
 101,110,100, 10,101,108,115,101, 10,105,102, 32,115,101,108,
 102, 46, 99,115,101,116,110, 97,109,101, 32,116,104,101,110,
  10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117, 97,
  95,103,108,111, 98, 97,108,118, 97,114, 40,116,111,108,117,
  97, 95, 83, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110,
  97,109,101, 46, 46, 39, 34, 44, 39, 46, 46,115,101,108,102,
  46, 99,103,101,116,110, 97,109,101, 46, 46, 39, 44, 39, 46,
  46,115,101,108,102, 46, 99,115,101,116,110, 97,109,101, 46,
  46, 39, 41, 59, 39, 41, 10,101,108,115,101, 10,111,117,116,
 112,117,116, 40, 39, 32,116,111,108,117, 97, 95,103,108,111,
  98, 97,108,118, 97,114, 40,116,111,108,117, 97, 95, 83, 44,
  34, 39, 46, 46,115,101,108,102, 46,108,110, 97,109,101, 46,
  46, 39, 34, 44, 39, 46, 46,115,101,108,102, 46, 99,103,101,
 116,110, 97,109,101, 46, 46, 39, 44, 78, 85, 76, 76, 41, 59,
  39, 41, 10,101,110,100, 10,101,110,100, 10,101,110,100, 10,
  10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115,
  86, 97,114,105, 97, 98,108,101, 58,117,110,114,101,103,105,
 115,116,101,114, 32, 40, 41, 10,105,102, 32,115,101,108,102,
  58,105,110, 99,108, 97,115,115, 40, 41, 61, 61,110,105,108,
  32, 97,110,100, 32,115,101,108,102, 58,105,110,109,111,100,
 117,108,101, 40, 41, 61, 61,110,105,108, 32,116,104,101,110,
  10,111,117,116,112,117,116, 40, 39, 32,108,117, 97, 95,103,
 101,116,103,108,111, 98, 97,108,115, 40,116,111,108,117, 97,
  95, 83, 41, 59, 39, 41, 10,111,117,116,112,117,116, 40, 39,
  32,108,117, 97, 95,112,117,115,104,115,116,114,105,110,103,
  40,116,111,108,117, 97, 95, 83, 44, 34, 39, 44,115,101,108,
 102, 46,108,110, 97,109,101, 44, 39, 34, 41, 59, 32,108,117,
  97, 95,112,117,115,104,110,105,108, 40,116,111,108,117, 97,
  95, 83, 41, 59, 32,108,117, 97, 95,114, 97,119,115,101,116,
  40,116,111,108,117, 97, 95, 83, 44, 45, 51, 41, 59, 39, 41,
  10,111,117,116,112,117,116, 40, 39, 32,108,117, 97, 95,112,
 111,112, 40,116,111,108,117, 97, 95, 83, 44, 49, 41, 59, 39,
  41, 10,101,110,100, 10,101,110,100, 10, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 95, 86, 97,114,105, 97, 98,108,
 101, 32, 40,116, 41, 10,116, 46, 95, 98, 97,115,101, 32, 61,
  32, 99,108, 97,115,115, 86, 97,114,105, 97, 98,108,101, 10,
 115,101,116,116, 97,103, 40,116, 44,116,111,108,117, 97, 95,
 116, 97,103, 41, 10, 97,112,112,101,110,100, 40,116, 41, 10,
 114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 86, 97,114,105, 97,
  98,108,101, 32, 40,115, 41, 10,114,101,116,117,114,110, 32,
  95, 86, 97,114,105, 97, 98,108,101, 32, 40, 68,101, 99,108,
  97,114, 97,116,105,111,110, 40,115, 44, 39,118, 97,114, 39,
  41, 41, 10,101,110,100, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,115, 65,
 114,114, 97,121, 32, 61, 32,123, 10, 95, 98, 97,115,101, 32,
  61, 32, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,
 105,111,110, 44, 10,125, 10, 10,115,101,116,116, 97,103, 40,
  99,108, 97,115,115, 65,114,114, 97,121, 44,116,111,108,117,
  97, 95,116, 97,103, 41, 10, 10, 10,102,117,110, 99,116,105,
 111,110, 32, 99,108, 97,115,115, 65,114,114, 97,121, 58,112,
 114,105,110,116, 32, 40,105,100,101,110,116, 44, 99,108,111,
 115,101, 41, 10,112,114,105,110,116, 40,105,100,101,110,116,
  46, 46, 34, 65,114,114, 97,121,123, 34, 41, 10,112,114,105,
 110,116, 40,105,100,101,110,116, 46, 46, 34, 32,109,111,100,
  32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,109,111,100,
  46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,
 100,101,110,116, 46, 46, 34, 32,116,121,112,101, 32, 61, 32,
  39, 34, 46, 46,115,101,108,102, 46,116,121,112,101, 46, 46,
  34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,
 110,116, 46, 46, 34, 32,112,116,114, 32, 61, 32, 39, 34, 46,
  46,115,101,108,102, 46,112,116,114, 46, 46, 34, 39, 44, 34,
  41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46,
  34, 32,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101,
 108,102, 46,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, 10,
 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,
 100,101,102, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,
 100,101,102, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,
 116, 40,105,100,101,110,116, 46, 46, 34, 32,100,105,109, 32,
  61, 32, 39, 34, 46, 46,115,101,108,102, 46,100,105,109, 46,
  46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,
 101,110,116, 46, 46, 34, 32,114,101,116, 32, 61, 32, 39, 34,
  46, 46,115,101,108,102, 46,114,101,116, 46, 46, 34, 39, 44,
  34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46,
  46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,101,110,
 100, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108,
  97,115,115, 65,114,114, 97,121, 58,103,101,116,118, 97,108,
 117,101, 32, 40, 99,108, 97,115,115, 44,115,116, 97,116,105,
  99, 41, 10,105,102, 32, 99,108, 97,115,115, 32, 97,110,100,
  32,115,116, 97,116,105, 99, 32,116,104,101,110, 10,114,101,
 116,117,114,110, 32, 99,108, 97,115,115, 46, 46, 39, 58, 58,
  39, 46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46, 39,
  91,116,111,108,117, 97, 73, 95,105,110,100,101,120, 93, 39,
  10,101,108,115,101,105,102, 32, 99,108, 97,115,115, 32,116,
 104,101,110, 10,114,101,116,117,114,110, 32, 39,115,101,108,
 102, 45, 62, 39, 46, 46,115,101,108,102, 46,110, 97,109,101,
  46, 46, 39, 91,116,111,108,117, 97, 73, 95,105,110,100,101,
 120, 93, 39, 10,101,108,115,101, 10,114,101,116,117,114,110,
  32,115,101,108,102, 46,110, 97,109,101, 46, 46, 39, 91,116,
 111,108,117, 97, 73, 95,105,110,100,101,120, 93, 39, 10,101,
 110,100, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,
 111,110, 32, 99,108, 97,115,115, 65,114,114, 97,121, 58,115,
 117,112, 99,111,100,101, 32, 40, 41, 10,108,111, 99, 97,108,
  32, 99,108, 97,115,115, 32, 61, 32,115,101,108,102, 58,105,
 110, 99,108, 97,115,115, 40, 41, 10, 10, 10,105,102, 32, 99,
 108, 97,115,115, 32,116,104,101,110, 10,111,117,116,112,117,
 116, 40, 34, 47, 42, 32,103,101,116, 32,102,117,110, 99,116,
 105,111,110, 58, 34, 44,115,101,108,102, 46,110, 97,109,101,
  44, 34, 32,111,102, 32, 99,108, 97,115,115, 32, 34, 44, 99,
 108, 97,115,115, 44, 34, 32, 42, 47, 34, 41, 10,101,108,115,
 101, 10,111,117,116,112,117,116, 40, 34, 47, 42, 32,103,101,
 116, 32,102,117,110, 99,116,105,111,110, 58, 34, 44,115,101,
 108,102, 46,110, 97,109,101, 44, 34, 32, 42, 47, 34, 41, 10,
 101,110,100, 10,115,101,108,102, 46, 99,103,101,116,110, 97,
 109,101, 32, 61, 32,115,101,108,102, 58, 99,102,117,110, 99,
 110, 97,109,101, 40, 34,116,111,108,117, 97, 73, 95,103,101,
 116, 34, 41, 10,111,117,116,112,117,116, 40, 34,115,116, 97,
 116,105, 99, 32,105,110,116, 34, 44,115,101,108,102, 46, 99,
 103,101,116,110, 97,109,101, 44, 34, 40,108,117, 97, 95, 83,
 116, 97,116,101, 42, 32,116,111,108,117, 97, 95, 83, 41, 34,
  41, 10,111,117,116,112,117,116, 40, 34,123, 34, 41, 10, 10,
  10,111,117,116,112,117,116, 40, 39, 32,105,110,116, 32,116,
 111,108,117, 97, 73, 95,105,110,100,101,120, 59, 39, 41, 10,
  10, 10,108,111, 99, 97,108, 32, 95, 44, 95, 44,115,116, 97,
 116,105, 99, 32, 61, 32,115,116,114,102,105,110,100, 40,115,
 101,108,102, 46,109,111,100, 44, 39, 94, 37,115, 42, 40,115,
 116, 97,116,105, 99, 41, 39, 41, 10,105,102, 32, 99,108, 97,
 115,115, 32, 97,110,100, 32,115,116, 97,116,105, 99, 61, 61,
 110,105,108, 32,116,104,101,110, 10,111,117,116,112,117,116,
  40, 39, 32, 39, 44, 99,108, 97,115,115, 44, 39, 42, 39, 44,
  39,115,101,108,102, 59, 39, 41, 10,111,117,116,112,117,116,
  40, 39, 32,108,117, 97, 95,112,117,115,104,115,116,114,105,
 110,103, 40,116,111,108,117, 97, 95, 83, 44, 34, 46,115,101,
 108,102, 34, 41, 59, 39, 41, 10,111,117,116,112,117,116, 40,
  39, 32,108,117, 97, 95,114, 97,119,103,101,116, 40,116,111,
 108,117, 97, 95, 83, 44, 49, 41, 59, 39, 41, 10,111,117,116,
 112,117,116, 40, 39, 32,115,101,108,102, 32, 61, 32, 39, 41,
  10,111,117,116,112,117,116, 40, 39, 40, 39, 44, 99,108, 97,
 115,115, 44, 39, 42, 41, 32, 39, 41, 10,111,117,116,112,117,
 116, 40, 39,108,117, 97, 95,116,111,117,115,101,114,100, 97,
 116, 97, 40,116,111,108,117, 97, 95, 83, 44, 45, 49, 41, 59,
  39, 41, 10,101,108,115,101,105,102, 32,115,116, 97,116,105,
  99, 32,116,104,101,110, 10, 95, 44, 95, 44,115,101,108,102,
  46,109,111,100, 32, 61, 32,115,116,114,102,105,110,100, 40,
 115,101,108,102, 46,109,111,100, 44, 39, 94, 37,115, 42,115,
 116, 97,116,105, 99, 37,115, 37,115, 42, 40, 46, 42, 41, 39,
  41, 10,101,110,100, 10, 10, 10,111,117,116,112,117,116, 40,
  39, 32,105,102, 32, 40, 33,116,111,108,117, 97, 95,105,115,
 116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 50, 44,
  76, 85, 65, 95, 84, 78, 85, 77, 66, 69, 82, 44, 48, 41, 41,
  39, 41, 10,111,117,116,112,117,116, 40, 39, 32,116,111,108,
 117, 97, 95,101,114,114,111,114, 40,116,111,108,117, 97, 95,
  83, 44, 34,105,110,118, 97,108,105,100, 32,116,121,112,101,
  32,105,110, 32, 97,114,114, 97,121, 32,105,110,100,101,120,
 105,110,103, 46, 34, 41, 59, 39, 41, 10,111,117,116,112,117,
 116, 40, 39, 32,116,111,108,117, 97, 73, 95,105,110,100,101,
 120, 32, 61, 32, 40,105,110,116, 41,116,111,108,117, 97, 95,
 103,101,116,110,117,109, 98,101,114, 40,116,111,108,117, 97,
  95, 83, 44, 50, 44, 48, 41, 45, 49, 59, 39, 41, 10,111,117,
 116,112,117,116, 40, 39, 32,105,102, 32, 40,116,111,108,117,
  97, 73, 95,105,110,100,101,120, 60, 48, 32,124,124, 32,116,
 111,108,117, 97, 73, 95,105,110,100,101,120, 62, 61, 39, 46,
  46,115,101,108,102, 46,100,105,109, 46, 46, 39, 41, 39, 41,
  10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117, 97,
  95,101,114,114,111,114, 40,116,111,108,117, 97, 95, 83, 44,
  34, 97,114,114, 97,121, 32,105,110,100,101,120,105,110,103,
  32,111,117,116, 32,111,102, 32,114, 97,110,103,101, 46, 34,
  41, 59, 39, 41, 10, 10, 10,108,111, 99, 97,108, 32,116, 44,
  99,116, 32, 61, 32,105,115, 98, 97,115,105, 99, 40,115,101,
 108,102, 46,116,121,112,101, 41, 10,105,102, 32,116, 32,116,
 104,101,110, 10,111,117,116,112,117,116, 40, 39, 32,116,111,
 108,117, 97, 95,112,117,115,104, 39, 46, 46,116, 46, 46, 39,
  40,116,111,108,117, 97, 95, 83, 44, 40, 39, 44, 99,116, 44,
  39, 41, 39, 46, 46,115,101,108,102, 58,103,101,116,118, 97,
 108,117,101, 40, 99,108, 97,115,115, 44,115,116, 97,116,105,
  99, 41, 46, 46, 39, 41, 59, 39, 41, 10,101,108,115,101, 10,
 105,102, 32,115,101,108,102, 46,112,116,114, 32, 61, 61, 32,
  39, 38, 39, 32,111,114, 32,115,101,108,102, 46,112,116,114,
  32, 61, 61, 32, 39, 39, 32,116,104,101,110, 10,111,117,116,
 112,117,116, 40, 39, 32,116,111,108,117, 97, 95,112,117,115,
 104,117,115,101,114,116,121,112,101, 40,116,111,108,117, 97,
  95, 83, 44, 40,118,111,105,100, 42, 41, 38, 39, 46, 46,115,
 101,108,102, 58,103,101,116,118, 97,108,117,101, 40, 99,108,
  97,115,115, 44,115,116, 97,116,105, 99, 41, 46, 46, 39, 44,
  39, 44,115,101,108,102, 46,116, 97,103, 44, 39, 41, 59, 39,
  41, 10,101,108,115,101, 10,111,117,116,112,117,116, 40, 39,
  32,116,111,108,117, 97, 95,112,117,115,104,117,115,101,114,
 116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 40,118,
 111,105,100, 42, 41, 39, 46, 46,115,101,108,102, 58,103,101,
 116,118, 97,108,117,101, 40, 99,108, 97,115,115, 44,115,116,
  97,116,105, 99, 41, 46, 46, 39, 44, 39, 44,115,101,108,102,
  46,116, 97,103, 44, 39, 41, 59, 39, 41, 10,101,110,100, 10,
 101,110,100, 10,111,117,116,112,117,116, 40, 39, 32,114,101,
 116,117,114,110, 32, 49, 59, 39, 41, 10,111,117,116,112,117,
 116, 40, 39,125, 39, 41, 10,111,117,116,112,117,116, 40, 39,
  92,110, 39, 41, 10, 10, 10,105,102, 32,110,111,116, 32,115,
 116,114,102,105,110,100, 40,115,101,108,102, 46,109,111,100,
  44, 39, 99,111,110,115,116, 39, 41, 32,116,104,101,110, 10,
 105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, 10,111,
 117,116,112,117,116, 40, 34, 47, 42, 32,115,101,116, 32,102,
 117,110, 99,116,105,111,110, 58, 34, 44,115,101,108,102, 46,
 110, 97,109,101, 44, 34, 32,111,102, 32, 99,108, 97,115,115,
  32, 34, 44, 99,108, 97,115,115, 44, 34, 32, 42, 47, 34, 41,
  10,101,108,115,101, 10,111,117,116,112,117,116, 40, 34, 47,
  42, 32,115,101,116, 32,102,117,110, 99,116,105,111,110, 58,
  34, 44,115,101,108,102, 46,110, 97,109,101, 44, 34, 32, 42,
  47, 34, 41, 10,101,110,100, 10,115,101,108,102, 46, 99,115,
 101,116,110, 97,109,101, 32, 61, 32,115,101,108,102, 58, 99,
 102,117,110, 99,110, 97,109,101, 40, 34,116,111,108,117, 97,
  73, 95,115,101,116, 34, 41, 10,111,117,116,112,117,116, 40,
  34,115,116, 97,116,105, 99, 32,105,110,116, 34, 44,115,101,
 108,102, 46, 99,115,101,116,110, 97,109,101, 44, 34, 40,108,
 117, 97, 95, 83,116, 97,116,101, 42, 32,116,111,108,117, 97,
  95, 83, 41, 34, 41, 10,111,117,116,112,117,116, 40, 34,123,
  34, 41, 10, 10, 10,111,117,116,112,117,116, 40, 39, 32,105,
 110,116, 32,116,111,108,117, 97, 73, 95,105,110,100,101,120,
  59, 39, 41, 10, 10, 10,108,111, 99, 97,108, 32, 95, 44, 95,
  44,115,116, 97,116,105, 99, 32, 61, 32,115,116,114,102,105,
 110,100, 40,115,101,108,102, 46,109,111,100, 44, 39, 94, 37,
 115, 42, 40,115,116, 97,116,105, 99, 41, 39, 41, 10,105,102,
  32, 99,108, 97,115,115, 32, 97,110,100, 32,115,116, 97,116,
 105, 99, 61, 61,110,105,108, 32,116,104,101,110, 10,111,117,
 116,112,117,116, 40, 39, 32, 39, 44, 99,108, 97,115,115, 44,
  39, 42, 39, 44, 39,115,101,108,102, 59, 39, 41, 10,111,117,
 116,112,117,116, 40, 39, 32,108,117, 97, 95,112,117,115,104,
 115,116,114,105,110,103, 40,116,111,108,117, 97, 95, 83, 44,
  34, 46,115,101,108,102, 34, 41, 59, 39, 41, 10,111,117,116,
 112,117,116, 40, 39, 32,108,117, 97, 95,114, 97,119,103,101,
 116, 40,116,111,108,117, 97, 95, 83, 44, 49, 41, 59, 39, 41,
  10,111,117,116,112,117,116, 40, 39, 32,115,101,108,102, 32,
  61, 32, 39, 41, 10,111,117,116,112,117,116, 40, 39, 40, 39,
  44, 99,108, 97,115,115, 44, 39, 42, 41, 32, 39, 41, 10,111,
 117,116,112,117,116, 40, 39,108,117, 97, 95,116,111,117,115,
 101,114,100, 97,116, 97, 40,116,111,108,117, 97, 95, 83, 44,
  45, 49, 41, 59, 39, 41, 10,101,108,115,101,105,102, 32,115,
 116, 97,116,105, 99, 32,116,104,101,110, 10, 95, 44, 95, 44,
 115,101,108,102, 46,109,111,100, 32, 61, 32,115,116,114,102,
 105,110,100, 40,115,101,108,102, 46,109,111,100, 44, 39, 94,
  37,115, 42,115,116, 97,116,105, 99, 37,115, 37,115, 42, 40,
  46, 42, 41, 39, 41, 10,101,110,100, 10, 10, 10,111,117,116,
 112,117,116, 40, 39, 32,105,102, 32, 40, 33,116,111,108,117,
  97, 95,105,115,116,121,112,101, 40,116,111,108,117, 97, 95,
  83, 44, 50, 44, 76, 85, 65, 95, 84, 78, 85, 77, 66, 69, 82,
  44, 48, 41, 41, 39, 41, 10,111,117,116,112,117,116, 40, 39,
  32,116,111,108,117, 97, 95,101,114,114,111,114, 40,116,111,
 108,117, 97, 95, 83, 44, 34,105,110,118, 97,108,105,100, 32,
 116,121,112,101, 32,105,110, 32, 97,114,114, 97,121, 32,105,
 110,100,101,120,105,110,103, 46, 34, 41, 59, 39, 41, 10,111,
 117,116,112,117,116, 40, 39, 32,116,111,108,117, 97, 73, 95,
 105,110,100,101,120, 32, 61, 32, 40,105,110,116, 41,116,111,
 108,117, 97, 95,103,101,116,110,117,109, 98,101,114, 40,116,
 111,108,117, 97, 95, 83, 44, 50, 44, 48, 41, 45, 49, 59, 39,
  41, 10,111,117,116,112,117,116, 40, 39, 32,105,102, 32, 40,
 116,111,108,117, 97, 73, 95,105,110,100,101,120, 60, 48, 32,
 124,124, 32,116,111,108,117, 97, 73, 95,105,110,100,101,120,
  62, 61, 39, 46, 46,115,101,108,102, 46,100,105,109, 46, 46,
  39, 41, 39, 41, 10,111,117,116,112,117,116, 40, 39, 32,116,
 111,108,117, 97, 95,101,114,114,111,114, 40,116,111,108,117,
  97, 95, 83, 44, 34, 97,114,114, 97,121, 32,105,110,100,101,
 120,105,110,103, 32,111,117,116, 32,111,102, 32,114, 97,110,
 103,101, 46, 34, 41, 59, 39, 41, 10, 10, 10,108,111, 99, 97,
 108, 32,112,116,114, 32, 61, 32, 39, 39, 10,105,102, 32,115,
 101,108,102, 46,112,116,114,126, 61, 39, 39, 32,116,104,101,
 110, 32,112,116,114, 32, 61, 32, 39, 42, 39, 32,101,110,100,
  10,111,117,116,112,117,116, 40, 39, 32, 39, 41, 10,105,102,
  32, 99,108, 97,115,115, 32, 97,110,100, 32,115,116, 97,116,
 105, 99, 32,116,104,101,110, 10,111,117,116,112,117,116, 40,
  99,108, 97,115,115, 46, 46, 39, 58, 58, 39, 46, 46,115,101,
 108,102, 46,110, 97,109,101, 46, 46, 39, 91,116,111,108,117,
  97, 73, 95,105,110,100,101,120, 93, 39, 41, 10,101,108,115,
 101,105,102, 32, 99,108, 97,115,115, 32,116,104,101,110, 10,
 111,117,116,112,117,116, 40, 39,115,101,108,102, 45, 62, 39,
  46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46, 39, 91,
 116,111,108,117, 97, 73, 95,105,110,100,101,120, 93, 39, 41,
  10,101,108,115,101, 10,111,117,116,112,117,116, 40,115,101,
 108,102, 46,110, 97,109,101, 46, 46, 39, 91,116,111,108,117,
  97, 73, 95,105,110,100,101,120, 93, 39, 41, 10,101,110,100,
  10,108,111, 99, 97,108, 32,116, 32, 61, 32,105,115, 98, 97,
 115,105, 99, 40,115,101,108,102, 46,116,121,112,101, 41, 10,
 111,117,116,112,117,116, 40, 39, 32, 61, 32, 39, 41, 10,105,
 102, 32,110,111,116, 32,116, 32, 97,110,100, 32,112,116,114,
  61, 61, 39, 39, 32,116,104,101,110, 32,111,117,116,112,117,
 116, 40, 39, 42, 39, 41, 32,101,110,100, 10,111,117,116,112,
 117,116, 40, 39, 40, 40, 39, 44,115,101,108,102, 46,109,111,
 100, 44,115,101,108,102, 46,116,121,112,101, 41, 10,105,102,
  32,110,111,116, 32,116, 32,116,104,101,110, 10,111,117,116,
 112,117,116, 40, 39, 42, 39, 41, 10,101,110,100, 10,111,117,
 116,112,117,116, 40, 39, 41, 32, 39, 41, 10,108,111, 99, 97,
 108, 32,100,101,102, 32, 61, 32, 48, 10,105,102, 32,115,101,
 108,102, 46,100,101,102, 32,126, 61, 32, 39, 39, 32,116,104,
 101,110, 32,100,101,102, 32, 61, 32,115,101,108,102, 46,100,
 101,102, 32,101,110,100, 10,105,102, 32,116, 32,116,104,101,
 110, 10,111,117,116,112,117,116, 40, 39,116,111,108,117, 97,
  95,103,101,116, 39, 46, 46,116, 44, 39, 40,116,111,108,117,
  97, 95, 83, 44, 51, 44, 39, 44,100,101,102, 44, 39, 41, 41,
  59, 39, 41, 10,101,108,115,101, 10,111,117,116,112,117,116,
  40, 39,116,111,108,117, 97, 95,103,101,116,117,115,101,114,
 116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 51, 44,
  39, 44,100,101,102, 44, 39, 41, 41, 59, 39, 41, 10,101,110,
 100, 10,111,117,116,112,117,116, 40, 39, 32,114,101,116,117,
 114,110, 32, 48, 59, 39, 41, 10,111,117,116,112,117,116, 40,
  39,125, 39, 41, 10,111,117,116,112,117,116, 40, 39, 92,110,
  39, 41, 10,101,110,100, 10, 10,101,110,100, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 65,114,114,
  97,121, 58,114,101,103,105,115,116,101,114, 32, 40, 41, 10,
 108,111, 99, 97,108, 32,112, 97,114,101,110,116, 32, 61, 32,
 115,101,108,102, 58,105,110, 99,108, 97,115,115, 40, 41, 32,
 111,114, 32,115,101,108,102, 58,105,110,109,111,100,117,108,
 101, 40, 41, 10,105,102, 32,112, 97,114,101,110,116, 32,116,
 104,101,110, 10,105,102, 32,115,101,108,102, 46, 99,115,101,
 116,110, 97,109,101, 32,116,104,101,110, 10,111,117,116,112,
 117,116, 40, 39, 32,116,111,108,117, 97, 95,116, 97, 98,108,
 101, 97,114,114, 97,121, 40,116,111,108,117, 97, 95, 83, 44,
  34, 39, 46, 46,112, 97,114,101,110,116, 46, 46, 39, 34, 44,
  34, 39, 46, 46,115,101,108,102, 46,108,110, 97,109,101, 46,
  46, 39, 34, 44, 39, 46, 46,115,101,108,102, 46, 99,103,101,
 116,110, 97,109,101, 46, 46, 39, 44, 39, 46, 46,115,101,108,
 102, 46, 99,115,101,116,110, 97,109,101, 46, 46, 39, 41, 59,
  39, 41, 10,101,108,115,101, 10,111,117,116,112,117,116, 40,
  39, 32,116,111,108,117, 97, 95,116, 97, 98,108,101, 97,114,
 114, 97,121, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46,
  46,112, 97,114,101,110,116, 46, 46, 39, 34, 44, 34, 39, 46,
  46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 39, 34,
  44, 39, 46, 46,115,101,108,102, 46, 99,103,101,116,110, 97,
 109,101, 46, 46, 39, 44, 78, 85, 76, 76, 41, 59, 39, 41, 10,
 101,110,100, 10,101,108,115,101, 10,105,102, 32,115,101,108,
 102, 46, 99,115,101,116,110, 97,109,101, 32,116,104,101,110,
  10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117, 97,
  95,103,108,111, 98, 97,108, 97,114,114, 97,121, 40,116,111,
 108,117, 97, 95, 83, 44, 34, 39, 46, 46,115,101,108,102, 46,
 108,110, 97,109,101, 46, 46, 39, 34, 44, 39, 46, 46,115,101,
 108,102, 46, 99,103,101,116,110, 97,109,101, 46, 46, 39, 44,
  39, 46, 46,115,101,108,102, 46, 99,115,101,116,110, 97,109,
 101, 46, 46, 39, 41, 59, 39, 41, 10,101,108,115,101, 10,111,
 117,116,112,117,116, 40, 39, 32,116,111,108,117, 97, 95,103,
 108,111, 98, 97,108, 97,114,114, 97,121, 40,116,111,108,117,
  97, 95, 83, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110,
  97,109,101, 46, 46, 39, 34, 44, 39, 46, 46,115,101,108,102,
  46, 99,103,101,116,110, 97,109,101, 46, 46, 39, 44, 78, 85,
  76, 76, 41, 59, 39, 41, 10,101,110,100, 10,101,110,100, 10,
 101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,
 108, 97,115,115, 65,114,114, 97,121, 58,117,110,114,101,103,
 105,115,116,101,114, 32, 40, 41, 10,105,102, 32,115,101,108,
 102, 58,105,110, 99,108, 97,115,115, 40, 41, 61, 61,110,105,
 108, 32, 97,110,100, 32,115,101,108,102, 58,105,110,109,111,
 100,117,108,101, 40, 41, 61, 61,110,105,108, 32,116,104,101,
 110, 10,111,117,116,112,117,116, 40, 39, 32,108,117, 97, 95,
 112,117,115,104,110,105,108, 40,116,111,108,117, 97, 95, 83,
  41, 59, 32,108,117, 97, 95,115,101,116,103,108,111, 98, 97,
 108, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46, 46,115,
 101,108,102, 46,108,110, 97,109,101, 46, 46, 39, 34, 41, 59,
  39, 41, 10,101,110,100, 10,101,110,100, 10, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 95, 65,114,114, 97,121, 32,
  40,116, 41, 10,116, 46, 95, 98, 97,115,101, 32, 61, 32, 99,
 108, 97,115,115, 65,114,114, 97,121, 10,115,101,116,116, 97,
 103, 40,116, 44,116,111,108,117, 97, 95,116, 97,103, 41, 10,
  97,112,112,101,110,100, 40,116, 41, 10,114,101,116,117,114,
 110, 32,116, 10,101,110,100, 10, 10, 10, 10,102,117,110, 99,
 116,105,111,110, 32, 65,114,114, 97,121, 32, 40,115, 41, 10,
 114,101,116,117,114,110, 32, 95, 65,114,114, 97,121, 32, 40,
  68,101, 99,108, 97,114, 97,116,105,111,110, 40,115, 44, 39,
 118, 97,114, 39, 41, 41, 10,101,110,100, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 99,108, 97,115,115, 70,117,110, 99,116,105,111,
 110, 32, 61, 32,123, 10,109,111,100, 32, 61, 32, 39, 39, 44,
  10,116,121,112,101, 32, 61, 32, 39, 39, 44, 10,112,116,114,
  32, 61, 32, 39, 39, 44, 10,110, 97,109,101, 32, 61, 32, 39,
  39, 44, 10, 97,114,103,115, 32, 61, 32,123,110, 61, 48,125,
  44, 10, 99,111,110,115,116, 32, 61, 32, 39, 39, 44, 10, 95,
  98, 97,115,101, 32, 61, 32, 99,108, 97,115,115, 70,101, 97,
 116,117,114,101, 44, 10,125, 10,115,101,116,116, 97,103, 40,
  99,108, 97,115,115, 70,117,110, 99,116,105,111,110, 44,116,
 111,108,117, 97, 95,116, 97,103, 41, 10, 10, 10,102,117,110,
  99,116,105,111,110, 32, 99,108, 97,115,115, 70,117,110, 99,
 116,105,111,110, 58,100,101, 99,108,116, 97,103, 32, 40, 41,
  10,115,101,108,102, 46,105,116,121,112,101, 44,115,101,108,
 102, 46,116, 97,103, 32, 61, 32,116, 97,103,118, 97,114, 40,
 115,101,108,102, 46,116,121,112,101, 44,115,116,114,102,105,
 110,100, 40,115,101,108,102, 46,109,111,100, 44, 39, 99,111,
 110,115,116, 39, 41, 41, 10,108,111, 99, 97,108, 32,105, 61,
  49, 10,119,104,105,108,101, 32,115,101,108,102, 46, 97,114,
 103,115, 91,105, 93, 32,100,111, 10,115,101,108,102, 46, 97,
 114,103,115, 91,105, 93, 58,100,101, 99,108,116, 97,103, 40,
  41, 10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,101,
 110,100, 10, 10, 10, 10, 10,102,117,110, 99,116,105,111,110,
  32, 99,108, 97,115,115, 70,117,110, 99,116,105,111,110, 58,
 115,117,112, 99,111,100,101, 32, 40, 41, 10,108,111, 99, 97,
 108, 32,110,114,101,116, 32, 61, 32, 48, 10,108,111, 99, 97,
 108, 32, 99,108, 97,115,115, 32, 61, 32,115,101,108,102, 58,
 105,110, 99,108, 97,115,115, 40, 41, 10,108,111, 99, 97,108,
  32, 95, 44, 95, 44,115,116, 97,116,105, 99, 32, 61, 32,115,
 116,114,102,105,110,100, 40,115,101,108,102, 46,109,111,100,
  44, 39, 94, 37,115, 42, 40,115,116, 97,116,105, 99, 41, 39,
  41, 10, 10,105,102, 32, 99,108, 97,115,115, 32,116,104,101,
 110, 10,111,117,116,112,117,116, 40, 34, 47, 42, 32,109,101,
 116,104,111,100, 58, 34, 44,115,101,108,102, 46,110, 97,109,
 101, 44, 34, 32,111,102, 32, 99,108, 97,115,115, 32, 34, 44,
  99,108, 97,115,115, 44, 34, 32, 42, 47, 34, 41, 10,101,108,
 115,101, 10,111,117,116,112,117,116, 40, 34, 47, 42, 32,102,
 117,110, 99,116,105,111,110, 58, 34, 44,115,101,108,102, 46,
 110, 97,109,101, 44, 34, 32, 42, 47, 34, 41, 10,101,110,100,
  10,111,117,116,112,117,116, 40, 34,115,116, 97,116,105, 99,
  32,105,110,116, 34, 44,115,101,108,102, 46, 99,110, 97,109,
 101, 44, 34, 40,108,117, 97, 95, 83,116, 97,116,101, 42, 32,
 116,111,108,117, 97, 95, 83, 41, 34, 41, 10,111,117,116,112,
 117,116, 40, 34,123, 34, 41, 10, 10, 10,111,117,116,112,117,
 116, 40, 39, 32,105,102, 32, 40, 92,110, 39, 41, 10, 10,108,
 111, 99, 97,108, 32,110, 97,114,103, 10,105,102, 32, 99,108,
  97,115,115, 32,116,104,101,110, 32,110, 97,114,103, 61, 50,
  32,101,108,115,101, 32,110, 97,114,103, 61, 49, 32,101,110,
 100, 10,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, 32,
 115,101,108,102, 46,110, 97,109,101,126, 61, 39,110,101,119,
  39, 32, 97,110,100, 32,115,116, 97,116,105, 99, 61, 61,110,
 105,108, 32,116,104,101,110, 10,105,102, 32,115,101,108,102,
  46, 99,111,110,115,116, 32, 61, 61, 32, 39, 99,111,110,115,
 116, 39, 32,116,104,101,110, 10,111,117,116,112,117,116, 40,
  39, 32, 33,116,111,108,117, 97, 95,105,115,116,121,112,101,
  40,116,111,108,117, 97, 95, 83, 44, 49, 44, 39, 44,115,101,
 108,102, 46,112, 97,114,101,110,116, 46, 99,116, 97,103, 44,
  39, 44, 48, 41, 32,124,124, 92,110, 39, 41, 10,101,108,115,
 101, 10,111,117,116,112,117,116, 40, 39, 32, 33,116,111,108,
 117, 97, 95,105,115,116,121,112,101, 40,116,111,108,117, 97,
  95, 83, 44, 49, 44, 39, 44,115,101,108,102, 46,112, 97,114,
 101,110,116, 46,116, 97,103, 44, 39, 44, 48, 41, 32,124,124,
  92,110, 39, 41, 10,101,110,100, 10,101,110,100, 10, 10,105,
 102, 32,115,101,108,102, 46, 97,114,103,115, 91, 49, 93, 46,
 116,121,112,101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,
 116,104,101,110, 10,108,111, 99, 97,108, 32,105, 61, 49, 10,
 119,104,105,108,101, 32,115,101,108,102, 46, 97,114,103,115,
  91,105, 93, 32,100,111, 10,105,102, 32,105,115, 98, 97,115,
 105, 99, 40,115,101,108,102, 46, 97,114,103,115, 91,105, 93,
  46,116,121,112,101, 41, 32,126, 61, 32, 39,118, 97,108,117,
 101, 39, 32,116,104,101,110, 10,111,117,116,112,117,116, 40,
  39, 32, 33, 39, 46, 46,115,101,108,102, 46, 97,114,103,115,
  91,105, 93, 58,111,117,116, 99,104,101, 99,107,116,121,112,
 101, 40,110, 97,114,103, 41, 46, 46, 39, 32,124,124, 92,110,
  39, 41, 10,101,110,100, 10,110, 97,114,103, 32, 61, 32,110,
  97,114,103, 43, 49, 10,105, 32, 61, 32,105, 43, 49, 10,101,
 110,100, 10,101,110,100, 10, 10,111,117,116,112,117,116, 40,
  39, 32, 33,116,111,108,117, 97, 95,105,115,110,111,111, 98,
 106, 40,116,111,108,117, 97, 95, 83, 44, 39, 46, 46,110, 97,
 114,103, 46, 46, 39, 41, 92,110, 32, 41, 92,110, 32,103,111,
 116,111, 32,116,111,108,117, 97, 95,108,101,114,114,111,114,
  59, 39, 41, 10, 10,111,117,116,112,117,116, 40, 39, 32,101,
 108,115,101, 92,110, 32,123, 39, 41, 10, 10, 10,108,111, 99,
  97,108, 32,110, 97,114,103, 10,105,102, 32, 99,108, 97,115,
 115, 32,116,104,101,110, 32,110, 97,114,103, 61, 50, 32,101,
 108,115,101, 32,110, 97,114,103, 61, 49, 32,101,110,100, 10,
 105,102, 32, 99,108, 97,115,115, 32, 97,110,100, 32,115,101,
 108,102, 46,110, 97,109,101,126, 61, 39,110,101,119, 39, 32,
  97,110,100, 32,115,116, 97,116,105, 99, 61, 61,110,105,108,
  32,116,104,101,110, 10,111,117,116,112,117,116, 40, 39, 32,
  39, 44,115,101,108,102, 46, 99,111,110,115,116, 44, 99,108,
  97,115,115, 44, 39, 42, 39, 44, 39,115,101,108,102, 32, 61,
  32, 39, 41, 10,111,117,116,112,117,116, 40, 39, 40, 39, 44,
 115,101,108,102, 46, 99,111,110,115,116, 44, 99,108, 97,115,
 115, 44, 39, 42, 41, 32, 39, 41, 10,111,117,116,112,117,116,
  40, 39,116,111,108,117, 97, 95,103,101,116,117,115,101,114,
 116,121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 49, 44,
  48, 41, 59, 39, 41, 10,101,108,115,101,105,102, 32,115,116,
  97,116,105, 99, 32,116,104,101,110, 10, 95, 44, 95, 44,115,
 101,108,102, 46,109,111,100, 32, 61, 32,115,116,114,102,105,
 110,100, 40,115,101,108,102, 46,109,111,100, 44, 39, 94, 37,
 115, 42,115,116, 97,116,105, 99, 37,115, 37,115, 42, 40, 46,
  42, 41, 39, 41, 10,101,110,100, 10, 10,105,102, 32,115,101,
 108,102, 46, 97,114,103,115, 91, 49, 93, 46,116,121,112,101,
  32,126, 61, 32, 39,118,111,105,100, 39, 32,116,104,101,110,
  10,108,111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,108,
 101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 32,
 100,111, 10,115,101,108,102, 46, 97,114,103,115, 91,105, 93,
  58,100,101, 99,108, 97,114,101, 40,110, 97,114,103, 41, 10,
 110, 97,114,103, 32, 61, 32,110, 97,114,103, 43, 49, 10,105,
  32, 61, 32,105, 43, 49, 10,101,110,100, 10,101,110,100, 10,
  10, 10,105,102, 32, 99,108, 97,115,115, 32, 97,110,100, 32,
 115,101,108,102, 46,110, 97,109,101,126, 61, 39,110,101,119,
  39, 32, 97,110,100, 32,115,116, 97,116,105, 99, 61, 61,110,
 105,108, 32,116,104,101,110, 10,111,117,116,112,117,116, 40,
  39, 32,105,102, 32, 40, 33,115,101,108,102, 41, 32,116,111,
 108,117, 97, 95,101,114,114,111,114, 40,116,111,108,117, 97,
  95, 83, 44, 34,105,110,118, 97,108,105,100, 32, 92, 39,115,
 101,108,102, 92, 39, 32,105,110, 32,102,117,110, 99,116,105,
 111,110, 32, 92, 39, 39, 46, 46,115,101,108,102, 46,110, 97,
 109,101, 46, 46, 39, 92, 39, 34, 41, 59, 39, 41, 59, 10,101,
 110,100, 10, 10, 10,105,102, 32, 99,108, 97,115,115, 32,116,
 104,101,110, 32,110, 97,114,103, 61, 50, 32,101,108,115,101,
  32,110, 97,114,103, 61, 49, 32,101,110,100, 10,105,102, 32,
 115,101,108,102, 46, 97,114,103,115, 91, 49, 93, 46,116,121,
 112,101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,104,
 101,110, 10,108,111, 99, 97,108, 32,105, 61, 49, 10,119,104,
 105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,105,
  93, 32,100,111, 10,115,101,108,102, 46, 97,114,103,115, 91,
 105, 93, 58,103,101,116, 97,114,114, 97,121, 40,110, 97,114,
 103, 41, 10,110, 97,114,103, 32, 61, 32,110, 97,114,103, 43,
  49, 10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,101,
 110,100, 10, 10, 10,105,102, 32, 99,108, 97,115,115, 32, 97,
 110,100, 32,115,101,108,102, 46,110, 97,109,101, 61, 61, 39,
 100,101,108,101,116,101, 39, 32,116,104,101,110, 10,111,117,
 116,112,117,116, 40, 39, 32,100,101,108,101,116,101, 32,115,
 101,108,102, 59, 39, 41, 10,101,108,115,101,105,102, 32, 99,
 108, 97,115,115, 32, 97,110,100, 32,115,101,108,102, 46,110,
  97,109,101, 32, 61, 61, 32, 39,111,112,101,114, 97,116,111,
 114, 38, 91, 93, 39, 32,116,104,101,110, 10,111,117,116,112,
 117,116, 40, 39, 32,115,101,108,102, 45, 62,111,112,101,114,
  97,116,111,114, 91, 93, 40, 39, 44,115,101,108,102, 46, 97,
 114,103,115, 91, 49, 93, 46,110, 97,109,101, 44, 39, 41, 32,
  61, 32, 39, 44,115,101,108,102, 46, 97,114,103,115, 91, 50,
  93, 46,110, 97,109,101, 44, 39, 59, 39, 41, 10,101,108,115,
 101, 10,111,117,116,112,117,116, 40, 39, 32,123, 39, 41, 10,
 105,102, 32,115,101,108,102, 46,116,121,112,101, 32,126, 61,
  32, 39, 39, 32, 97,110,100, 32,115,101,108,102, 46,116,121,
 112,101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,104,
 101,110, 10,111,117,116,112,117,116, 40, 39, 32, 39, 44,115,
 101,108,102, 46,109,111,100, 44,115,101,108,102, 46,116,121,
 112,101, 44,115,101,108,102, 46,112,116,114, 44, 39,116,111,
 108,117, 97, 73, 95,114,101,116, 32, 61, 32, 39, 41, 10,111,
 117,116,112,117,116, 40, 39, 40, 39, 44,115,101,108,102, 46,
 109,111,100, 44,115,101,108,102, 46,116,121,112,101, 44,115,
 101,108,102, 46,112,116,114, 44, 39, 41, 32, 39, 41, 10,101,
 108,115,101, 10,111,117,116,112,117,116, 40, 39, 32, 39, 41,
  10,101,110,100, 10,105,102, 32, 99,108, 97,115,115, 32, 97,
 110,100, 32,115,101,108,102, 46,110, 97,109,101, 61, 61, 39,
 110,101,119, 39, 32,116,104,101,110, 10,111,117,116,112,117,
 116, 40, 39,110,101,119, 39, 44, 99,108, 97,115,115, 44, 39,
  40, 39, 41, 10,101,108,115,101,105,102, 32, 99,108, 97,115,
 115, 32, 97,110,100, 32,115,116, 97,116,105, 99, 32,116,104,
 101,110, 10,111,117,116,112,117,116, 40, 99,108, 97,115,115,
  46, 46, 39, 58, 58, 39, 46, 46,115,101,108,102, 46,110, 97,
 109,101, 44, 39, 40, 39, 41, 10,101,108,115,101,105,102, 32,
  99,108, 97,115,115, 32,116,104,101,110, 10,111,117,116,112,
 117,116, 40, 39,115,101,108,102, 45, 62, 39, 46, 46,115,101,
 108,102, 46,110, 97,109,101, 44, 39, 40, 39, 41, 10,101,108,
 115,101, 10,111,117,116,112,117,116, 40,115,101,108,102, 46,
 110, 97,109,101, 44, 39, 40, 39, 41, 10,101,110,100, 10, 10,
  10,108,111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,108,
 101, 32,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 32,
 100,111, 10,115,101,108,102, 46, 97,114,103,115, 91,105, 93,
  58,112, 97,115,115,112, 97,114, 40, 41, 10,105, 32, 61, 32,
 105, 43, 49, 10,105,102, 32,115,101,108,102, 46, 97,114,103,
 115, 91,105, 93, 32,116,104,101,110, 10,111,117,116,112,117,
 116, 40, 39, 44, 39, 41, 10,101,110,100, 10,101,110,100, 10,
  10,111,117,116,112,117,116, 40, 39, 41, 59, 39, 41, 10, 10,
  10,105,102, 32,115,101,108,102, 46,116,121,112,101, 32,126,
  61, 32, 39, 39, 32, 97,110,100, 32,115,101,108,102, 46,116,
 121,112,101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,
 104,101,110, 10,110,114,101,116, 32, 61, 32,110,114,101,116,
  32, 43, 32, 49, 10,108,111, 99, 97,108, 32,116, 44, 99,116,
  32, 61, 32,105,115, 98, 97,115,105, 99, 40,115,101,108,102,
  46,116,121,112,101, 41, 10,105,102, 32,116, 32,116,104,101,
 110, 10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117,
  97, 95,112,117,115,104, 39, 46, 46,116, 46, 46, 39, 40,116,
 111,108,117, 97, 95, 83, 44, 40, 39, 44, 99,116, 44, 39, 41,
 116,111,108,117, 97, 73, 95,114,101,116, 41, 59, 39, 41, 10,
 101,108,115,101, 10,105,102, 32,115,101,108,102, 46,112,116,
 114, 32, 61, 61, 32, 39, 39, 32,116,104,101,110, 10,111,117,
 116,112,117,116, 40, 39, 32,123, 39, 41, 10,111,117,116,112,
 117,116, 40, 39, 35,105,102,100,101,102, 32, 95, 95, 99,112,
 108,117,115,112,108,117,115, 92,110, 39, 41, 10,111,117,116,
 112,117,116, 40, 39, 32,118,111,105,100, 42, 32,116,111,108,
 117, 97, 73, 95, 99,108,111,110,101, 32, 61, 32,110,101,119,
  39, 44,115,101,108,102, 46,116,121,112,101, 44, 39, 40,116,
 111,108,117, 97, 73, 95,114,101,116, 41, 59, 39, 41, 10,111,
 117,116,112,117,116, 40, 39, 35,101,108,115,101, 92,110, 39,
  41, 10,111,117,116,112,117,116, 40, 39, 32,118,111,105,100,
  42, 32,116,111,108,117, 97, 73, 95, 99,108,111,110,101, 32,
  61, 32,116,111,108,117, 97, 95, 99,111,112,121, 40,116,111,
 108,117, 97, 95, 83, 44, 40,118,111,105,100, 42, 41, 38,116,
 111,108,117, 97, 73, 95,114,101,116, 44,115,105,122,101,111,
 102, 40, 39, 44,115,101,108,102, 46,116,121,112,101, 44, 39,
  41, 41, 59, 39, 41, 10,111,117,116,112,117,116, 40, 39, 35,
 101,110,100,105,102, 92,110, 39, 41, 10,111,117,116,112,117,
 116, 40, 39, 32,116,111,108,117, 97, 95,112,117,115,104,117,
 115,101,114,116,121,112,101, 40,116,111,108,117, 97, 95, 83,
  44,116,111,108,117, 97, 95,100,111, 99,108,111,110,101, 40,
 116,111,108,117, 97, 95, 83, 44,116,111,108,117, 97, 73, 95,
  99,108,111,110,101, 44, 39, 44,115,101,108,102, 46,116, 97,
 103, 44, 39, 41, 44, 39, 44,115,101,108,102, 46,116, 97,103,
  44, 39, 41, 59, 39, 41, 10,111,117,116,112,117,116, 40, 39,
  32,125, 39, 41, 10, 10,101,108,115,101,105,102, 32,115,101,
 108,102, 46,112,116,114, 32, 61, 61, 32, 39, 38, 39, 32,116,
 104,101,110, 10,111,117,116,112,117,116, 40, 39, 32,116,111,
 108,117, 97, 95,112,117,115,104,117,115,101,114,116,121,112,
 101, 40,116,111,108,117, 97, 95, 83, 44, 40,118,111,105,100,
  42, 41, 38,116,111,108,117, 97, 73, 95,114,101,116, 44, 39,
  44,115,101,108,102, 46,116, 97,103, 44, 39, 41, 59, 39, 41,
  10,101,108,115,101, 10,111,117,116,112,117,116, 40, 39, 32,
 116,111,108,117, 97, 95,112,117,115,104,117,115,101,114,116,
 121,112,101, 40,116,111,108,117, 97, 95, 83, 44, 40,118,111,
 105,100, 42, 41,116,111,108,117, 97, 73, 95,114,101,116, 44,
  39, 44,115,101,108,102, 46,116, 97,103, 44, 39, 41, 59, 39,
  41, 10,101,110,100, 10,101,110,100, 10,101,110,100, 10,108,
 111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,108,101, 32,
 115,101,108,102, 46, 97,114,103,115, 91,105, 93, 32,100,111,
  10,110,114,101,116, 32, 61, 32,110,114,101,116, 32, 43, 32,
 115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58,114,101,
 116,118, 97,108,117,101, 40, 41, 10,105, 32, 61, 32,105, 43,
  49, 10,101,110,100, 10,111,117,116,112,117,116, 40, 39, 32,
 125, 39, 41, 10, 10, 10,105,102, 32, 99,108, 97,115,115, 32,
 116,104,101,110, 32,110, 97,114,103, 61, 50, 32,101,108,115,
 101, 32,110, 97,114,103, 61, 49, 32,101,110,100, 10,105,102,
  32,115,101,108,102, 46, 97,114,103,115, 91, 49, 93, 46,116,
 121,112,101, 32,126, 61, 32, 39,118,111,105,100, 39, 32,116,
 104,101,110, 10,108,111, 99, 97,108, 32,105, 61, 49, 10,119,
 104,105,108,101, 32,115,101,108,102, 46, 97,114,103,115, 91,
 105, 93, 32,100,111, 10,115,101,108,102, 46, 97,114,103,115,
  91,105, 93, 58,115,101,116, 97,114,114, 97,121, 40,110, 97,
 114,103, 41, 10,110, 97,114,103, 32, 61, 32,110, 97,114,103,
  43, 49, 10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,
 101,110,100, 10, 10, 10,105,102, 32,115,101,108,102, 46, 97,
 114,103,115, 91, 49, 93, 46,116,121,112,101, 32,126, 61, 32,
  39,118,111,105,100, 39, 32,116,104,101,110, 10,108,111, 99,
  97,108, 32,105, 61, 49, 10,119,104,105,108,101, 32,115,101,
 108,102, 46, 97,114,103,115, 91,105, 93, 32,100,111, 10,115,
 101,108,102, 46, 97,114,103,115, 91,105, 93, 58,102,114,101,
 101, 97,114,114, 97,121, 40, 41, 10,105, 32, 61, 32,105, 43,
  49, 10,101,110,100, 10,101,110,100, 10,101,110,100, 10, 10,
 111,117,116,112,117,116, 40, 39, 32,125, 39, 41, 10,111,117,
 116,112,117,116, 40, 39, 32,114,101,116,117,114,110, 32, 39,
  46, 46,110,114,101,116, 46, 46, 39, 59, 39, 41, 10, 10, 10,
 111,117,116,112,117,116, 40, 39,116,111,108,117, 97, 95,108,
 101,114,114,111,114, 58, 92,110, 39, 41, 10,108,111, 99, 97,
 108, 32,111,118,101,114,108,111, 97,100, 32, 61, 32,115,116,
 114,115,117, 98, 40,115,101,108,102, 46, 99,110, 97,109,101,
  44, 45, 50, 44, 45, 49, 41, 32, 45, 32, 49, 10,105,102, 32,
 111,118,101,114,108,111, 97,100, 32, 62, 61, 32, 48, 32,116,
 104,101,110, 10,111,117,116,112,117,116, 40, 39, 32,114,101,
 116,117,114,110, 32, 39, 46, 46,115,116,114,115,117, 98, 40,
 115,101,108,102, 46, 99,110, 97,109,101, 44, 49, 44, 45, 51,
  41, 46, 46,102,111,114,109, 97,116, 40, 34, 37, 48, 50,100,
  34, 44,111,118,101,114,108,111, 97,100, 41, 46, 46, 39, 40,
 116,111,108,117, 97, 95, 83, 41, 59, 39, 41, 10,101,108,115,
 101, 10,111,117,116,112,117,116, 40, 39, 32,116,111,108,117,
  97, 95,101,114,114,111,114, 40,116,111,108,117, 97, 95, 83,
  44, 34, 35,102,101,114,114,111,114, 32,105,110, 32,102,117,
 110, 99,116,105,111,110, 32, 92, 39, 39, 46, 46,115,101,108,
 102, 46,108,110, 97,109,101, 46, 46, 39, 92, 39, 46, 34, 41,
  59, 39, 41, 10,111,117,116,112,117,116, 40, 39, 32,114,101,
 116,117,114,110, 32, 48, 59, 39, 41, 10,101,110,100, 10, 10,
 111,117,116,112,117,116, 40, 39,125, 39, 41, 10,111,117,116,
 112,117,116, 40, 39, 92,110, 39, 41, 10,101,110,100, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,115,
  70,117,110, 99,116,105,111,110, 58,114,101,103,105,115,116,
 101,114, 32, 40, 41, 10,108,111, 99, 97,108, 32,112, 97,114,
 101,110,116, 32, 61, 32,115,101,108,102, 58,105,110, 99,108,
  97,115,115, 40, 41, 32,111,114, 32,115,101,108,102, 58,105,
 110,109,111,100,117,108,101, 40, 41, 10,105,102, 32,112, 97,
 114,101,110,116, 32,116,104,101,110, 10,111,117,116,112,117,
 116, 40, 39, 32,116,111,108,117, 97, 95,102,117,110, 99,116,
 105,111,110, 40,116,111,108,117, 97, 95, 83, 44, 34, 39, 46,
  46,112, 97,114,101,110,116, 46, 46, 39, 34, 44, 34, 39, 46,
  46,115,101,108,102, 46,108,110, 97,109,101, 46, 46, 39, 34,
  44, 39, 46, 46,115,101,108,102, 46, 99,110, 97,109,101, 46,
  46, 39, 41, 59, 39, 41, 10,101,108,115,101, 10,111,117,116,
 112,117,116, 40, 39, 32,116,111,108,117, 97, 95,102,117,110,
  99,116,105,111,110, 40,116,111,108,117, 97, 95, 83, 44, 78,
  85, 76, 76, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110,
  97,109,101, 46, 46, 39, 34, 44, 39, 46, 46,115,101,108,102,
  46, 99,110, 97,109,101, 46, 46, 39, 41, 59, 39, 41, 10,101,
 110,100, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,
 111,110, 32, 99,108, 97,115,115, 70,117,110, 99,116,105,111,
 110, 58,117,110,114,101,103,105,115,116,101,114, 32, 40, 41,
  10,105,102, 32,115,101,108,102, 58,105,110, 99,108, 97,115,
 115, 40, 41, 61, 61,110,105,108, 32, 97,110,100, 32,115,101,
 108,102, 58,105,110,109,111,100,117,108,101, 40, 41, 61, 61,
 110,105,108, 32,116,104,101,110, 10,111,117,116,112,117,116,
  40, 39, 32,108,117, 97, 95,112,117,115,104,110,105,108, 40,
 116,111,108,117, 97, 95, 83, 41, 59, 32,108,117, 97, 95,115,
 101,116,103,108,111, 98, 97,108, 40,116,111,108,117, 97, 95,
  83, 44, 34, 39, 46, 46,115,101,108,102, 46,108,110, 97,109,
 101, 46, 46, 39, 34, 41, 59, 39, 41, 10,101,110,100, 10,101,
 110,100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110, 32,
  99,108, 97,115,115, 70,117,110, 99,116,105,111,110, 58,112,
 114,105,110,116, 32, 40,105,100,101,110,116, 44, 99,108,111,
 115,101, 41, 10,112,114,105,110,116, 40,105,100,101,110,116,
  46, 46, 34, 70,117,110, 99,116,105,111,110,123, 34, 41, 10,
 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,
 109,111,100, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,
 109,111,100, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,
 116, 40,105,100,101,110,116, 46, 46, 34, 32,116,121,112,101,
  32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,116,121,112,
 101, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,
 105,100,101,110,116, 46, 46, 34, 32,112,116,114, 32, 61, 32,
  39, 34, 46, 46,115,101,108,102, 46,112,116,114, 46, 46, 34,
  39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34, 32,110, 97,109,101, 32, 61, 32, 39, 34, 46,
  46,115,101,108,102, 46,110, 97,109,101, 46, 46, 34, 39, 44,
  34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46,
  46, 34, 32, 99,111,110,115,116, 32, 61, 32, 39, 34, 46, 46,
 115,101,108,102, 46, 99,111,110,115,116, 46, 46, 34, 39, 44,
  34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46,
  46, 34, 32, 99,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,
 115,101,108,102, 46, 99,110, 97,109,101, 46, 46, 34, 39, 44,
  34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46,
  46, 34, 32,108,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,
 115,101,108,102, 46,108,110, 97,109,101, 46, 46, 34, 39, 44,
  34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46,
  46, 34, 32, 97,114,103,115, 32, 61, 32,123, 34, 41, 10,108,
 111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,108,101, 32,
 115,101,108,102, 46, 97,114,103,115, 91,105, 93, 32,100,111,
  10,115,101,108,102, 46, 97,114,103,115, 91,105, 93, 58,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32, 34,
  44, 34, 44, 34, 41, 10,105, 32, 61, 32,105, 43, 49, 10,101,
 110,100, 10,112,114,105,110,116, 40,105,100,101,110,116, 46,
  46, 34, 32,125, 34, 41, 10,112,114,105,110,116, 40,105,100,
 101,110,116, 46, 46, 34,125, 34, 46, 46, 99,108,111,115,101,
  41, 10,101,110,100, 10, 10, 10,102,117,110, 99,116,105,111,
 110, 32, 99,108, 97,115,115, 70,117,110, 99,116,105,111,110,
  58,111,118,101,114,108,111, 97,100, 32, 40, 41, 10,114,101,
 116,117,114,110, 32,115,101,108,102, 46,112, 97,114,101,110,
 116, 58,111,118,101,114,108,111, 97,100, 40,115,101,108,102,
  46,108,110, 97,109,101, 41, 10,101,110,100, 10, 10, 10, 10,
  10,102,117,110, 99,116,105,111,110, 32, 95, 70,117,110, 99,
 116,105,111,110, 32, 40,116, 41, 10,116, 46, 95, 98, 97,115,
 101, 32, 61, 32, 99,108, 97,115,115, 70,117,110, 99,116,105,
 111,110, 10,115,101,116,116, 97,103, 40,116, 44,116,111,108,
 117, 97, 95,116, 97,103, 41, 10, 10,105,102, 32,116, 46, 99,
 111,110,115,116, 32,126, 61, 32, 39, 99,111,110,115,116, 39,
  32, 97,110,100, 32,116, 46, 99,111,110,115,116, 32,126, 61,
  32, 39, 39, 32,116,104,101,110, 10,101,114,114,111,114, 40,
  34, 35,105,110,118, 97,108,105,100, 32, 39, 99,111,110,115,
 116, 39, 32,115,112,101, 99,105,102,105, 99, 97,116,105,111,
 110, 34, 41, 10,101,110,100, 10, 10, 97,112,112,101,110,100,
  40,116, 41, 10,105,102, 32,116, 58,105,110, 99,108, 97,115,
 115, 40, 41, 32,116,104,101,110, 10,105,102, 32,116, 46,110,
  97,109,101, 32, 61, 61, 32,116, 46,112, 97,114,101,110,116,
  46,110, 97,109,101, 32,116,104,101,110, 10,116, 46,110, 97,
 109,101, 32, 61, 32, 39,110,101,119, 39, 10,116, 46,108,110,
  97,109,101, 32, 61, 32, 39,110,101,119, 39, 10,116, 46,116,
 121,112,101, 32, 61, 32,116, 46,112, 97,114,101,110,116, 46,
 110, 97,109,101, 10,116, 46,112,116,114, 32, 61, 32, 39, 42,
  39, 10,101,108,115,101,105,102, 32,116, 46,110, 97,109,101,
  32, 61, 61, 32, 39,126, 39, 46, 46,116, 46,112, 97,114,101,
 110,116, 46,110, 97,109,101, 32,116,104,101,110, 10,116, 46,
 110, 97,109,101, 32, 61, 32, 39,100,101,108,101,116,101, 39,
  10,116, 46,108,110, 97,109,101, 32, 61, 32, 39,100,101,108,
 101,116,101, 39, 10,101,110,100, 10,101,110,100, 10,116, 46,
  99,110, 97,109,101, 32, 61, 32,116, 58, 99,102,117,110, 99,
 110, 97,109,101, 40, 34,116,111,108,117, 97, 73, 34, 41, 46,
  46,116, 58,111,118,101,114,108,111, 97,100, 40,116, 41, 10,
 114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10, 10,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 70,117,110,
  99,116,105,111,110, 32, 40,100, 44, 97, 44, 99, 41, 10,108,
 111, 99, 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 40,
 115,116,114,115,117, 98, 40, 97, 44, 50, 44, 45, 50, 41, 44,
  39, 44, 39, 41, 10,108,111, 99, 97,108, 32,105, 61, 49, 10,
 108,111, 99, 97,108, 32,108, 32, 61, 32,123,110, 61, 48,125,
  10,119,104,105,108,101, 32,116, 91,105, 93, 32,100,111, 10,
 108, 46,110, 32, 61, 32,108, 46,110, 43, 49, 10,108, 91,108,
  46,110, 93, 32, 61, 32, 68,101, 99,108, 97,114, 97,116,105,
 111,110, 40,116, 91,105, 93, 44, 39,118, 97,114, 39, 41, 10,
 105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,108,111, 99,
  97,108, 32,102, 32, 61, 32, 68,101, 99,108, 97,114, 97,116,
 105,111,110, 40,100, 44, 39,102,117,110, 99, 39, 41, 10,102,
  46, 97,114,103,115, 32, 61, 32,108, 10,102, 46, 99,111,110,
 115,116, 32, 61, 32, 99, 10,114,101,116,117,114,110, 32, 95,
  70,117,110, 99,116,105,111,110, 40,102, 41, 10,101,110,100,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 99,108, 97,115,115, 79,112,101,114, 97,116,
 111,114, 32, 61, 32,123, 10,107,105,110,100, 32, 61, 32, 39,
  39, 44, 10, 95, 98, 97,115,101, 32, 61, 32, 99,108, 97,115,
 115, 70,117,110, 99,116,105,111,110, 44, 10,125, 10,115,101,
 116,116, 97,103, 40, 99,108, 97,115,115, 79,112,101,114, 97,
 116,111,114, 44,116,111,108,117, 97, 95,116, 97,103, 41, 10,
  10, 10, 95, 84, 77, 32, 61, 32,123, 91, 39, 43, 39, 93, 32,
  61, 32, 39,111,112,101,114, 97,116,111,114, 95, 97,100,100,
  39, 44, 10, 91, 39, 45, 39, 93, 32, 61, 32, 39,111,112,101,
 114, 97,116,111,114, 95,115,117, 98, 39, 44, 10, 91, 39, 42,
  39, 93, 32, 61, 32, 39,111,112,101,114, 97,116,111,114, 95,
 109,117,108, 39, 44, 10, 91, 39, 47, 39, 93, 32, 61, 32, 39,
 111,112,101,114, 97,116,111,114, 95,100,105,118, 39, 44, 10,
  91, 39, 60, 39, 93, 32, 61, 32, 39,111,112,101,114, 97,116,
 111,114, 95,108,116, 39, 44, 10, 91, 39, 91, 93, 39, 93, 32,
  61, 32, 39,111,112,101,114, 97,116,111,114, 95,103,101,116,
  39, 44, 10, 91, 39, 38, 91, 93, 39, 93, 32, 61, 32, 39,111,
 112,101,114, 97,116,111,114, 95,115,101,116, 39, 44, 10,125,
  10, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108,
  97,115,115, 79,112,101,114, 97,116,111,114, 58,112,114,105,
 110,116, 32, 40,105,100,101,110,116, 44, 99,108,111,115,101,
  41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46,
  34, 79,112,101,114, 97,116,111,114,123, 34, 41, 10,112,114,
 105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,107,105,
 110,100, 32, 61, 32, 39, 34, 46, 46,115,101,108,102, 46,107,
 105,110,100, 46, 46, 34, 39, 44, 34, 41, 10,112,114,105,110,
 116, 40,105,100,101,110,116, 46, 46, 34, 32,109,111,100, 32,
  61, 32, 39, 34, 46, 46,115,101,108,102, 46,109,111,100, 46,
  46, 34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,
 101,110,116, 46, 46, 34, 32,116,121,112,101, 32, 61, 32, 39,
  34, 46, 46,115,101,108,102, 46,116,121,112,101, 46, 46, 34,
  39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,110,
 116, 46, 46, 34, 32,112,116,114, 32, 61, 32, 39, 34, 46, 46,
 115,101,108,102, 46,112,116,114, 46, 46, 34, 39, 44, 34, 41,
  10,112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34,
  32,110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101,108,
 102, 46,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32, 99,
 111,110,115,116, 32, 61, 32, 39, 34, 46, 46,115,101,108,102,
  46, 99,111,110,115,116, 46, 46, 34, 39, 44, 34, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32, 99,
 110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101,108,102,
  46, 99,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,108,
 110, 97,109,101, 32, 61, 32, 39, 34, 46, 46,115,101,108,102,
  46,108,110, 97,109,101, 46, 46, 34, 39, 44, 34, 41, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32, 97,
 114,103,115, 32, 61, 32,123, 34, 41, 10,108,111, 99, 97,108,
  32,105, 61, 49, 10,119,104,105,108,101, 32,115,101,108,102,
  46, 97,114,103,115, 91,105, 93, 32,100,111, 10,115,101,108,
 102, 46, 97,114,103,115, 91,105, 93, 58,112,114,105,110,116,
  40,105,100,101,110,116, 46, 46, 34, 32, 34, 44, 34, 44, 34,
  41, 10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,112,
 114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 32,125,
  34, 41, 10,112,114,105,110,116, 40,105,100,101,110,116, 46,
  46, 34,125, 34, 46, 46, 99,108,111,115,101, 41, 10,101,110,
 100, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 95, 79,
 112,101,114, 97,116,111,114, 32, 40,116, 41, 10,116, 46, 95,
  98, 97,115,101, 32, 61, 32, 99,108, 97,115,115, 79,112,101,
 114, 97,116,111,114, 10,115,101,116,116, 97,103, 40,116, 44,
 116,111,108,117, 97, 95,116, 97,103, 41, 10, 10,105,102, 32,
 116, 46, 99,111,110,115,116, 32,126, 61, 32, 39, 99,111,110,
 115,116, 39, 32, 97,110,100, 32,116, 46, 99,111,110,115,116,
  32,126, 61, 32, 39, 39, 32,116,104,101,110, 10,101,114,114,
 111,114, 40, 34, 35,105,110,118, 97,108,105,100, 32, 39, 99,
 111,110,115,116, 39, 32,115,112,101, 99,105,102,105, 99, 97,
 116,105,111,110, 34, 41, 10,101,110,100, 10, 10, 97,112,112,
 101,110,100, 40,116, 41, 10,105,102, 32,110,111,116, 32,116,
  58,105,110, 99,108, 97,115,115, 40, 41, 32,116,104,101,110,
  10,101,114,114,111,114, 40, 34, 35,111,112,101,114, 97,116,
 111,114, 32, 99, 97,110, 32,111,110,108,121, 32, 98,101, 32,
 100,101,102,105,110,101,100, 32, 97,115, 32, 99,108, 97,115,
 115, 32,109,101,109, 98,101,114, 34, 41, 10,101,110,100, 10,
  10,116, 46, 99,110, 97,109,101, 32, 61, 32,116, 58, 99,102,
 117,110, 99,110, 97,109,101, 40, 34,116,111,108,117, 97, 73,
  34, 41, 46, 46,116, 58,111,118,101,114,108,111, 97,100, 40,
 116, 41, 10,116, 46,110, 97,109,101, 32, 61, 32,116, 46,110,
  97,109,101, 46, 46,116, 46,107,105,110,100, 10,114,101,116,
 117,114,110, 32,116, 10,101,110,100, 10, 10, 10, 10, 10, 10,
 102,117,110, 99,116,105,111,110, 32, 79,112,101,114, 97,116,
 111,114, 32, 40,100, 44,107, 44, 97, 44, 99, 41, 10,108,111,
  99, 97,108, 32,116, 32, 61, 32,115,112,108,105,116, 40,115,
 116,114,115,117, 98, 40, 97, 44, 50, 44,115,116,114,108,101,
 110, 40, 97, 41, 45, 49, 41, 44, 39, 44, 39, 41, 10,108,111,
  99, 97,108, 32,105, 61, 49, 10,108,111, 99, 97,108, 32,108,
  32, 61, 32,123,110, 61, 48,125, 10,119,104,105,108,101, 32,
 116, 91,105, 93, 32,100,111, 10,108, 46,110, 32, 61, 32,108,
  46,110, 43, 49, 10,108, 91,108, 46,110, 93, 32, 61, 32, 68,
 101, 99,108, 97,114, 97,116,105,111,110, 40,116, 91,105, 93,
  44, 39,118, 97,114, 39, 41, 10,105, 32, 61, 32,105, 43, 49,
  10,101,110,100, 10,105,102, 32,107, 32, 61, 61, 32, 39, 91,
  93, 39, 32,116,104,101,110, 10,100, 32, 61, 32,103,115,117,
  98, 40,100, 44, 39, 38, 39, 44, 39, 39, 41, 10,101,108,115,
 101,105,102, 32,107, 61, 61, 39, 38, 91, 93, 39, 32,116,104,
 101,110, 10,108, 46,110, 32, 61, 32,108, 46,110, 43, 49, 10,
 108, 91,108, 46,110, 93, 32, 61, 32, 68,101, 99,108, 97,114,
  97,116,105,111,110, 40,100, 44, 39,118, 97,114, 39, 41, 10,
 108, 91,108, 46,110, 93, 46,110, 97,109,101, 32, 61, 32, 39,
 116,111,108,117, 97, 73, 95,118, 97,108,117,101, 39, 10,101,
 110,100, 10,108,111, 99, 97,108, 32,102, 32, 61, 32, 68,101,
  99,108, 97,114, 97,116,105,111,110, 40,100, 44, 39,102,117,
 110, 99, 39, 41, 10,105,102, 32,107, 32, 61, 61, 32, 39, 91,
  93, 39, 32, 97,110,100, 32, 40,108, 91, 49, 93, 61, 61,110,
 105,108, 32,111,114, 32,105,115, 98, 97,115,105, 99, 40,108,
  91, 49, 93, 46,116,121,112,101, 41,126, 61, 39,110,117,109,
  98,101,114, 39, 41, 32,116,104,101,110, 10,101,114,114,111,
 114, 40, 39,111,112,101,114, 97,116,111,114, 91, 93, 32, 99,
  97,110, 32,111,110,108,121, 32, 98,101, 32,100,101,102,105,
 110,101,100, 32,102,111,114, 32,110,117,109,101,114,105, 99,
  32,105,110,100,101,120, 46, 39, 41, 10,101,110,100, 10,102,
  46, 97,114,103,115, 32, 61, 32,108, 10,102, 46, 99,111,110,
 115,116, 32, 61, 32, 99, 10,102, 46,107,105,110,100, 32, 61,
  32,103,115,117, 98, 40,107, 44, 34, 37,115, 34, 44, 34, 34,
  41, 10,102, 46,108,110, 97,109,101, 32, 61, 32, 95, 84, 77,
  91,102, 46,107,105,110,100, 93, 10,105,102, 32,110,111,116,
  32,102, 46,108,110, 97,109,101, 32,116,104,101,110, 10,101,
 114,114,111,114, 40, 34,116,111,108,117, 97, 58, 32,110,111,
  32,115,117,112,112,111,114,116, 32,102,111,114, 32,111,112,
 101,114, 97,116,111,114, 34, 32, 46, 46, 32,102, 46,107,105,
 110,100, 41, 10,101,110,100, 10,105,102, 32,102, 46,107,105,
 110,100, 32, 61, 61, 32, 39, 91, 93, 39, 32, 97,110,100, 32,
 110,111,116, 32,115,116,114,102,105,110,100, 40,102, 46,109,
 111,100, 44, 39, 99,111,110,115,116, 39, 41, 32,116,104,101,
 110, 10, 79,112,101,114, 97,116,111,114, 40,100, 44, 39, 38,
  39, 46, 46,107, 44, 97, 44, 99, 41, 10,101,110,100, 10,114,
 101,116,117,114,110, 32, 95, 79,112,101,114, 97,116,111,114,
  40,102, 41, 10,101,110,100, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 99,108, 97,115,
 115, 67,108, 97,115,115, 32, 61, 32,123, 10, 95, 98, 97,115,
 101, 32, 61, 32, 99,108, 97,115,115, 67,111,110,116, 97,105,
 110,101,114, 44, 10,116,121,112,101, 32, 61, 32, 39, 99,108,
  97,115,115, 39, 44, 10,110, 97,109,101, 32, 61, 32, 39, 39,
  44, 10, 98, 97,115,101, 32, 61, 32, 39, 39, 44, 10,125, 10,
 115,101,116,116, 97,103, 40, 99,108, 97,115,115, 67,108, 97,
 115,115, 44,116,111,108,117, 97, 95,116, 97,103, 41, 10, 10,
  10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,115,
 115, 67,108, 97,115,115, 58,114,101,103,105,115,116,101,114,
  32, 40, 41, 10,111,117,116,112,117,116, 40, 39, 32,116,111,
 108,117, 97, 95, 99, 99,108, 97,115,115, 40,116,111,108,117,
  97, 95, 83, 44, 34, 39, 46, 46,115,101,108,102, 46,110, 97,
 109,101, 46, 46, 39, 34, 44, 34, 39, 46, 46,115,101,108,102,
  46, 98, 97,115,101, 46, 46, 39, 34, 41, 59, 39, 41, 10,108,
 111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,108,101, 32,
 115,101,108,102, 91,105, 93, 32,100,111, 10,115,101,108,102,
  91,105, 93, 58,114,101,103,105,115,116,101,114, 40, 41, 10,
 105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,101,110,100,
  10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108, 97,
 115,115, 67,108, 97,115,115, 58,117,110,114,101,103,105,115,
 116,101,114, 32, 40, 41, 10,111,117,116,112,117,116, 40, 39,
  32,108,117, 97, 95,112,117,115,104,110,105,108, 40,116,111,
 108,117, 97, 95, 83, 41, 59, 32,108,117, 97, 95,115,101,116,
 103,108,111, 98, 97,108, 40,116,111,108,117, 97, 95, 83, 44,
  34, 39, 46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46,
  39, 34, 41, 59, 39, 41, 10,101,110,100, 10, 10, 10,102,117,
 110, 99,116,105,111,110, 32, 99,108, 97,115,115, 67,108, 97,
 115,115, 58,100,101, 99,108,116, 97,103, 32, 40, 41, 10,115,
 101,108,102, 46,105,116,121,112,101, 44,115,101,108,102, 46,
 116, 97,103, 32, 61, 32,116, 97,103,118, 97,114, 40,115,101,
 108,102, 46,110, 97,109,101, 41, 59, 10,115,101,108,102, 46,
  99,105,116,121,112,101, 44,115,101,108,102, 46, 99,116, 97,
 103, 32, 61, 32,116, 97,103,118, 97,114, 40,115,101,108,102,
  46,110, 97,109,101, 44, 39, 99,111,110,115,116, 39, 41, 59,
  10,108,111, 99, 97,108, 32,105, 61, 49, 10,119,104,105,108,
 101, 32,115,101,108,102, 91,105, 93, 32,100,111, 10,115,101,
 108,102, 91,105, 93, 58,100,101, 99,108,116, 97,103, 40, 41,
  10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,101,110,
 100, 10, 10, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,
 108, 97,115,115, 67,108, 97,115,115, 58,112,114,105,110,116,
  32, 40,105,100,101,110,116, 44, 99,108,111,115,101, 41, 10,
 112,114,105,110,116, 40,105,100,101,110,116, 46, 46, 34, 67,
 108, 97,115,115,123, 34, 41, 10,112,114,105,110,116, 40,105,
 100,101,110,116, 46, 46, 34, 32,110, 97,109,101, 32, 61, 32,
  39, 34, 46, 46,115,101,108,102, 46,110, 97,109,101, 46, 46,
  34, 39, 44, 34, 41, 10,112,114,105,110,116, 40,105,100,101,
 110,116, 46, 46, 34, 32, 98, 97,115,101, 32, 61, 32, 39, 34,
  46, 46,115,101,108,102, 46, 98, 97,115,101, 46, 46, 34, 39,
  59, 34, 41, 10,108,111, 99, 97,108, 32,105, 61, 49, 10,119,
 104,105,108,101, 32,115,101,108,102, 91,105, 93, 32,100,111,
  10,115,101,108,102, 91,105, 93, 58,112,114,105,110,116, 40,
 105,100,101,110,116, 46, 46, 34, 32, 34, 44, 34, 44, 34, 41,
  10,105, 32, 61, 32,105, 43, 49, 10,101,110,100, 10,112,114,
 105,110,116, 40,105,100,101,110,116, 46, 46, 34,125, 34, 46,
  46, 99,108,111,115,101, 41, 10,101,110,100, 10, 10, 10,102,
 117,110, 99,116,105,111,110, 32, 95, 67,108, 97,115,115, 32,
  40,116, 41, 10,116, 46, 95, 98, 97,115,101, 32, 61, 32, 99,
 108, 97,115,115, 67,108, 97,115,115, 10,115,101,116,116, 97,
 103, 40,116, 44,116,111,108,117, 97, 95,116, 97,103, 41, 10,
  97,112,112,101,110,100, 40,116, 41, 10,114,101,116,117,114,
 110, 32,116, 10,101,110,100, 10, 10, 10, 10,102,117,110, 99,
 116,105,111,110, 32, 67,108, 97,115,115, 32, 40,110, 44,112,
  44, 98, 41, 10,108,111, 99, 97,108, 32, 99, 32, 61, 32, 95,
  67,108, 97,115,115, 40, 95, 67,111,110,116, 97,105,110,101,
 114,123,110, 97,109,101, 61,110, 44, 32, 98, 97,115,101, 61,
 112,125, 41, 10,112,117,115,104, 40, 99, 41, 10, 99, 58,112,
  97,114,115,101, 40,115,116,114,115,117, 98, 40, 98, 44, 50,
  44,115,116,114,108,101,110, 40, 98, 41, 45, 49, 41, 41, 10,
 112,111,112, 40, 41, 10,101,110,100, 10, 10, 10, 10, 83, 84,
  82, 49, 32, 61, 32, 34, 92, 48, 48, 49, 34, 10, 83, 84, 82,
  50, 32, 61, 32, 34, 92, 48, 48, 50, 34, 10, 83, 84, 82, 51,
  32, 61, 32, 34, 92, 48, 48, 51, 34, 10, 83, 84, 82, 52, 32,
  61, 32, 34, 92, 48, 48, 52, 34, 10, 82, 69, 77, 32, 61, 32,
  34, 92, 48, 48, 53, 34, 10, 65, 78, 89, 32, 61, 32, 34, 40,
  91, 92, 48, 48, 49, 45, 92, 48, 48, 53, 93, 41, 34, 10, 69,
  83, 67, 49, 32, 61, 32, 34, 92, 48, 48, 54, 34, 10, 69, 83,
  67, 50, 32, 61, 32, 34, 92, 48, 48, 55, 34, 10, 10, 77, 65,
  83, 75, 32, 61, 32,123, 10,123, 69, 83, 67, 49, 44, 32, 34,
  92, 92, 39, 34,125, 44, 10,123, 69, 83, 67, 50, 44, 32, 39,
  92, 92, 34, 39,125, 44, 10,123, 83, 84, 82, 49, 44, 32, 34,
  39, 34,125, 44, 10,123, 83, 84, 82, 50, 44, 32, 39, 34, 39,
 125, 44, 10,123, 83, 84, 82, 51, 44, 32, 34, 37, 91, 37, 91,
  34,125, 44, 10,123, 83, 84, 82, 52, 44, 32, 34, 37, 93, 37,
  93, 34,125, 44, 10,123, 82, 69, 77, 32, 44, 32, 34, 37, 45,
  37, 45, 34,125, 44, 10,125, 10, 10,102,117,110, 99,116,105,
 111,110, 32,109, 97,115,107, 32, 40,115, 41, 10,102,111,114,
  32,105, 32, 61, 32, 49, 44,103,101,116,110, 40, 77, 65, 83,
  75, 41, 32,100,111, 10,115, 32, 61, 32,103,115,117, 98, 40,
 115, 44, 77, 65, 83, 75, 91,105, 93, 91, 50, 93, 44, 77, 65,
  83, 75, 91,105, 93, 91, 49, 93, 41, 10,101,110,100, 10,114,
 101,116,117,114,110, 32,115, 10,101,110,100, 10, 10,102,117,
 110, 99,116,105,111,110, 32,117,110,109, 97,115,107, 32, 40,
 115, 41, 10,102,111,114, 32,105, 32, 61, 32, 49, 44,103,101,
 116,110, 40, 77, 65, 83, 75, 41, 32,100,111, 10,115, 32, 61,
  32,103,115,117, 98, 40,115, 44, 77, 65, 83, 75, 91,105, 93,
  91, 49, 93, 44, 77, 65, 83, 75, 91,105, 93, 91, 50, 93, 41,
  10,101,110,100, 10,114,101,116,117,114,110, 32,115, 10,101,
 110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, 99,108,
 101, 97,110, 32, 40,115, 41, 10, 10,108,111, 99, 97,108, 32,
  99,111,100,101, 32, 61, 32, 34,114,101,116,117,114,110, 32,
 102,117,110, 99,116,105,111,110, 32, 40, 41, 32, 34, 32, 46,
  46, 32,115, 32, 46, 46, 32, 34, 32,101,110,100, 34, 10,105,
 102, 32,110,111,116, 32,100,111,115,116,114,105,110,103, 40,
  99,111,100,101, 41, 32,116,104,101,110, 10,114,101,116,117,
 114,110, 32,110,105,108, 10,101,110,100, 10, 10,108,111, 99,
  97,108, 32, 83, 32, 61, 32, 34, 34, 10, 10,115, 32, 61, 32,
 109, 97,115,107, 40,115, 41, 10, 10, 10,119,104,105,108,101,
  32, 49, 32,100,111, 10,108,111, 99, 97,108, 32, 98, 44,101,
  44,100, 32, 61, 32,115,116,114,102,105,110,100, 40,115, 44,
  65, 78, 89, 41, 10,105,102, 32, 98, 32,116,104,101,110, 10,
  83, 32, 61, 32, 83, 46, 46,115,116,114,115,117, 98, 40,115,
  44, 49, 44, 98, 45, 49, 41, 10,115, 32, 61, 32,115,116,114,
 115,117, 98, 40,115, 44, 98, 43, 49, 41, 10,105,102, 32,100,
  61, 61, 83, 84, 82, 49, 32,111,114, 32,100, 61, 61, 83, 84,
  82, 50, 32,116,104,101,110, 10,101, 32, 61, 32,115,116,114,
 102,105,110,100, 40,115, 44,100, 41, 10, 83, 32, 61, 32, 83,
  32, 46, 46,100, 46, 46,115,116,114,115,117, 98, 40,115, 44,
  49, 44,101, 41, 10,115, 32, 61, 32,115,116,114,115,117, 98,
  40,115, 44,101, 43, 49, 41, 10,101,108,115,101,105,102, 32,
 100, 61, 61, 83, 84, 82, 51, 32,116,104,101,110, 10,101, 32,
  61, 32,115,116,114,102,105,110,100, 40,115, 44, 83, 84, 82,
  52, 41, 10, 83, 32, 61, 32, 83, 46, 46,100, 46, 46,115,116,
 114,115,117, 98, 40,115, 44, 49, 44,101, 41, 10,115, 32, 61,
  32,115,116,114,115,117, 98, 40,115, 44,101, 43, 49, 41, 10,
 101,108,115,101,105,102, 32,100, 61, 61, 82, 69, 77, 32,116,
 104,101,110, 10,115, 32, 61, 32,103,115,117, 98, 40,115, 44,
  34, 91, 94, 92,110, 93, 42, 40, 92,110, 63, 41, 34, 44, 34,
  37, 49, 34, 44, 49, 41, 10,101,110,100, 10,101,108,115,101,
  10, 83, 32, 61, 32, 83, 46, 46,115, 10, 98,114,101, 97,107,
  10,101,110,100, 10,101,110,100, 10, 10, 83, 32, 61, 32,103,
 115,117, 98, 40, 83, 44, 34, 91, 32, 92,116, 93, 43, 34, 44,
  34, 32, 34, 41, 10, 83, 32, 61, 32,103,115,117, 98, 40, 83,
  44, 34, 91, 32, 92,116, 93, 42, 92,110, 91, 32, 92,116, 93,
  42, 34, 44, 34, 92,110, 34, 41, 10, 83, 32, 61, 32,117,110,
 109, 97,115,107, 40, 83, 41, 10,114,101,116,117,114,110, 32,
  83, 10,101,110,100, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
  10, 10, 10, 10, 10,105,102, 32,102,108, 97,103,115, 46,102,
  32,116,104,101,110, 10,108,111, 99, 97,108, 32,115,116, 44,
  32,109,115,103, 32, 61, 32,114,101, 97,100,102,114,111,109,
  40,102,108, 97,103,115, 46,102, 41, 10,105,102, 32,110,111,
 116, 32,115,116, 32,116,104,101,110, 10,101,114,114,111,114,
  40, 39, 35, 39, 46, 46,109,115,103, 41, 10,101,110,100, 10,
 101,110,100, 10, 10, 10,105,102, 32,110,111,116, 32,102,108,
  97,103,115, 46,110, 32,116,104,101,110, 10,105,102, 32,102,
 108, 97,103,115, 46,102, 32,116,104,101,110, 10,102,108, 97,
 103,115, 46,110, 32, 61, 32,103,115,117, 98, 40,102,108, 97,
 103,115, 46,102, 44, 34, 37, 46, 46, 42, 34, 44, 34, 34, 41,
  10,101,108,115,101, 10,101,114,114,111,114, 40, 34, 35,110,
 111, 32,112, 97, 99,107, 97,103,101, 32,110, 97,109,101, 32,
 110,111,114, 32,105,110,112,117,116, 32,102,105,108,101, 32,
 112,114,111,118,105,100,101,100, 34, 41, 10,101,110,100, 10,
 101,110,100, 10, 10,108,111, 99, 97,108, 32,112, 32, 61, 32,
  80, 97, 99,107, 97,103,101, 40,102,108, 97,103,115, 46,110,
  41, 10, 10,105,102, 32,102,108, 97,103,115, 46,102, 32,116,
 104,101,110, 10,114,101, 97,100,102,114,111,109, 40, 41, 10,
 101,110,100, 10, 10,105,102, 32,102,108, 97,103,115, 46,112,
  32,116,104,101,110, 10,114,101,116,117,114,110, 10,101,110,
 100, 10, 10,105,102, 32,102,108, 97,103,115, 46,111, 32,116,
 104,101,110, 10,108,111, 99, 97,108, 32,115,116, 44,109,115,
 103, 32, 61, 32,119,114,105,116,101,116,111, 40,102,108, 97,
 103,115, 46,111, 41, 10,105,102, 32,110,111,116, 32,115,116,
  32,116,104,101,110, 10,101,114,114,111,114, 40, 39, 35, 39,
  46, 46,109,115,103, 41, 10,101,110,100, 10,101,110,100, 10,
  10,105,102, 32,102,108, 97,103,115, 46, 80, 32,116,104,101,
 110, 10,112, 58,112,114,105,110,116, 40, 41, 10,101,108,115,
 101, 10,112, 58,100,101, 99,108,116, 97,103, 40, 41, 10,112,
  58,112,114,101, 97,109, 98,108,101, 40, 41, 10,112, 58,115,
 117,112, 99,111,100,101, 40, 41, 10,112, 58,114,101,103,105,
 115,116,101,114, 40, 41, 10,112, 58,117,110,114,101,103,105,
 115,116,101,114, 40, 41, 10,101,110,100, 10, 10,105,102, 32,
 102,108, 97,103,115, 46,111, 32,116,104,101,110, 10,119,114,
 105,116,101,116,111, 40, 41, 10,101,110,100, 10, 10, 10,105,
 102, 32,110,111,116, 32,102,108, 97,103,115, 46, 80, 32,116,
 104,101,110, 10,105,102, 32,102,108, 97,103,115, 46, 72, 32,
 116,104,101,110, 10,108,111, 99, 97,108, 32,115,116, 44,109,
 115,103, 32, 61, 32,119,114,105,116,101,116,111, 40,102,108,
  97,103,115, 46, 72, 41, 10,105,102, 32,110,111,116, 32,115,
 116, 32,116,104,101,110, 10,101,114,114,111,114, 40, 39, 35,
  39, 46, 46,109,115,103, 41, 10,101,110,100, 10,112, 58,104,
 101, 97,100,101,114, 40, 41, 10,119,114,105,116,101,116,111,
  40, 41, 10,101,110,100, 10,101,110,100,32
 };
 lua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code");
 } /* end of embedded lua code */

 return 1;
}
/* Close function */
void tolua_tolualua_close (lua_State* tolua_S)
{
}
tome-235-src/src/lua/tolualua.h0000644000076400017500000063655711012107763014263 0ustar  dgdg/* code automatically generated by bin2c -- DO NOT EDIT */
{
/* #include'ing this file in a C program is equivalent to calling
  lua_dofile("basic.lo");
  lua_dofile("feature.lo");
  lua_dofile("declaration.lo");
  lua_dofile("container.lo");
  lua_dofile("package.lo");
  lua_dofile("module.lo");
  lua_dofile("class.lo");
  lua_dofile("typedef.lo");
  lua_dofile("define.lo");
  lua_dofile("enumerate.lo");
  lua_dofile("variable.lo");
  lua_dofile("array.lo");
  lua_dofile("function.lo");
  lua_dofile("operator.lo");
  lua_dofile("verbatim.lo");
  lua_dofile("code.lo");
  lua_dofile("doit.lo");
*/
/* basic.lo */
static char B1[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 11, 64, 98, 97,115,105, 99,
 46,108,117, 97,  0,  0,  0,  0,190, 25,  0, 60, 17, 22, 12, 60, 18, 11,  1, 11,
  2, 60, 19, 11,  3, 11,  4, 60, 20, 11,  5, 11,  4, 60, 21, 11,  6, 11,  4, 60,
 22, 11,  7, 11,  4, 60, 23, 11,  8, 11,  4, 60, 24, 11,  9, 11,  4, 60, 25, 11,
 10, 11, 11, 60, 26, 11, 12, 11, 13, 60, 27, 11, 14, 11, 11, 60, 28, 11, 15, 11,
 13, 60, 29, 11, 16, 11, 17, 30, 11, 60, 30, 25,  0, 60, 34, 22,  0, 25, 18, 60,
 37, 11, 20, 25, 19, 60, 45, 15, 22,  2,  1,  0, 25, 21, 60, 46, 15, 24, 15, 21,
 11, 25, 15, 19,  2,  1,  3, 25, 23, 60, 49, 11, 27, 25, 26, 60, 69, 15, 28, 15,
 26,  2,  0,  1, 60, 72, 11, 30, 25, 29, 60, 80, 22,  0, 25, 31, 60, 81, 11, 33,
 25, 32, 60, 89, 11, 35, 25, 34, 60,109, 11, 37, 25, 36, 60,115, 11, 39, 25, 38,
 60,121, 11, 41, 25, 40, 60,138, 11, 43, 25, 42, 60,150, 11, 45, 25, 44,  0,  0,
  0,  0,  0,  0,  0,  0, 46,  2,  0,  0,  0,  7, 95, 98, 97,115,105, 99,  0,  2,
  0,  0,  0,  5,118,111,105,100,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  5,
 99,104, 97,114,  0,  2,  0,  0,  0,  7,110,117,109, 98,101,114,  0,  2,  0,  0,
  0,  4,105,110,116,  0,  2,  0,  0,  0,  6,115,104,111,114,116,  0,  2,  0,  0,
  0,  5,108,111,110,103,  0,  2,  0,  0,  0,  6,102,108,111, 97,116,  0,  2,  0,
  0,  0,  7,100,111,117, 98,108,101,  0,  2,  0,  0,  0,  9, 95, 99,115,116,114,
105,110,103,  0,  2,  0,  0,  0,  7,115,116,114,105,110,103,  0,  2,  0,  0,  0,
 10, 95,117,115,101,114,100, 97,116, 97,  0,  2,  0,  0,  0,  9,117,115,101,114,
100, 97,116, 97,  0,  2,  0,  0,  0,  6, 99,104, 97,114, 42,  0,  2,  0,  0,  0,
  6,118,111,105,100, 42,  0,  2,  0,  0,  0, 11,108,117, 97, 95, 79, 98,106,101,
 99,116,  0,  2,  0,  0,  0,  7,111, 98,106,101, 99,116,  0,  2,  0,  0,  0, 10,
 95,117,115,101,114,116,121,112,101,  0,  2,  0,  0,  0, 12,116,111,108,117, 97,
 95,105,110,100,101,120,  0,  4,  0,  0,  0, 37,  0,  0,  0, 11, 64, 98, 97,115,
105, 99, 46,108,117, 97,  0,  0,  0,  0, 40,  5,  2, 60, 38, 13,  1, 11,  2, 32,
 52, 13, 60, 39, 15,  3, 13,  0, 13,  1,  3,  2,  2, 50, 13, 60, 41, 13,  0, 18,
  2, 13,  1, 16,  1,  2, 60, 42, 60, 43,  0,  0,  0,  0,  2,  0,  0,  0, 37,  0,
  0,  0,  2,116,  0,  0,  0,  0, 37,  0,  0,  0,  2,102,  0,  0,  0,  0,  4,  2,
  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  2,102,  0,  2,  0,  0,  0,  6, 95, 98,
 97,115,101,  0,  2,  0,  0,  0, 16,116,111,108,117, 97, 95,111,108,100, 95,105,
110,100,101,120,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,
  2,  0,  0,  0,  7,110,101,119,116, 97,103,  0,  2,  0,  0,  0, 16,116,111,108,
117, 97, 95,111,108,100, 95,105,110,100,101,120,  0,  2,  0,  0,  0, 13,115,101,
116,116, 97,103,109,101,116,104,111,100,  0,  2,  0,  0,  0,  6,105,110,100,101,
120,  0,  2,  0,  0,  0, 12,116,111,108,117, 97, 95,101,114,114,111,114,  0,  4,
  0,  0,  0, 49,  0,  0,  0, 11, 64, 98, 97,115,105, 99, 46,108,117, 97,  0,  0,
  0,  0,163,  9,  1, 60, 50, 15,  2, 60, 51, 15,  3, 25,  2, 60, 52, 15,  4, 13,
  0,  7,  1,  7,  1,  2,  1,  3, 11,  5, 32, 52, 24, 60, 53, 15,  6, 11,  7, 15,
  4, 13,  0,  7,  2,  2,  1,  2, 42, 11,  8, 42,  2,  0,  1, 50, 19, 60, 55, 15,
  6, 11,  9, 13,  0, 42, 11,  8, 42,  2,  0,  1, 60, 57,  1,  2, 60, 59, 15, 10,
 52, 73, 60, 60, 15, 12, 15, 10, 11, 13,  2,  3,  2, 60, 61, 13,  4,  4,  0, 32,
 52,  4, 15, 10, 23,  4, 60, 62, 15, 14, 13,  4, 11, 15, 11, 16,  2,  1,  3, 23,
  4, 60, 63, 15, 14, 13,  4, 11, 17, 11, 18,  2,  1,  3, 23,  4, 60, 64, 15,  6,
 11, 19, 13,  4, 42, 11, 20, 42,  2,  0,  1,  5,  3, 50,  2, 60, 65, 60, 66, 13,
  1, 25,  2, 60, 67,  0,  0,  0,  0,  8,  0,  0,  0, 49,  0,  0,  0,  2,115,  0,
  0,  0,  0, 50,  0,  0,  0,  4,111,117,116,  0,  0,  0,  0, 60,  0,  0,  0,  2,
 95,  0,  0,  0,  0, 60,  0,  0,  0,  2, 95,  0,  0,  0,  0, 60,  0,  0,  0,  2,
115,  0,  0,  0,  0, 64,  0,  0,  0,  0,  0,  0,  0, 64,  0,  0,  0,  0,  0,  0,
  0, 64,  0,  0,  0,  0,  0,  0,  0, 21,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,
  0,  4,111,117,116,  0,  2,  0,  0,  0,  8, 95, 79, 85, 84, 80, 85, 84,  0,  2,
  0,  0,  0,  8, 95, 83, 84, 68, 69, 82, 82,  0,  2,  0,  0,  0,  7,115,116,114,
115,117, 98,  0,  2,  0,  0,  0,  2, 35,  0,  2,  0,  0,  0,  6,119,114,105,116,
101,  0,  2,  0,  0,  0, 12, 10, 42, 42, 32,116,111,108,117, 97, 58, 32,  0,  2,
  0,  0,  0,  4, 46, 10, 10,  0,  2,  0,  0,  0, 27, 10, 42, 42, 32,116,111,108,
117, 97, 32,105,110,116,101,114,110, 97,108, 32,101,114,114,111,114, 58, 32,  0,
  2,  0,  0,  0, 11, 95, 99,117,114,114, 95, 99,111,100,101,  0,  2,  0,  0,  0,
  2, 95,  0,  2,  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,  0,  0,  0,
 10, 94, 37,115, 42, 40, 46, 45, 10, 41,  0,  2,  0,  0,  0,  5,103,115,117, 98,
  0,  2,  0,  0,  0, 10, 95,117,115,101,114,100, 97,116, 97,  0,  2,  0,  0,  0,
  6,118,111,105,100, 42,  0,  2,  0,  0,  0,  9, 95, 99,115,116,114,105,110,103,
  0,  2,  0,  0,  0,  6, 99,104, 97,114, 42,  0,  2,  0,  0,  0, 23, 67,111,100,
101, 32, 98,101,105,110,103, 32,112,114,111, 99,101,115,115,101,100, 58, 10,  0,
  2,  0,  0,  0,  2, 10,  0,  2,  0,  0,  0, 15,115,101,116,101,114,114,111,114,
109,101,116,104,111,100,  0,  2,  0,  0,  0,  8,114,101,103,116,121,112,101,  0,
  4,  0,  0,  0, 72,  0,  0,  0, 11, 64, 98, 97,115,105, 99, 46,108,117, 97,  0,
  0,  0,  0, 36,  4,  1, 60, 73, 15,  1, 13,  0,  2,  1,  1, 44, 52, 11, 60, 74,
 15,  2, 13,  0, 13,  0, 26, 50,  2, 60, 75, 60, 76, 13,  0,  1,  1, 60, 77,  0,
  0,  0,  0,  1,  0,  0,  0, 72,  0,  0,  0,  2,116,  0,  0,  0,  0,  3,  2,  0,
  0,  0,  2,116,  0,  2,  0,  0,  0,  7,105,115,116,121,112,101,  0,  2,  0,  0,
  0, 10, 95,117,115,101,114,116,121,112,101,  0,  2,  0,  0,  0, 10, 95,116, 97,
103,110, 97,109,101,115,  0,  2,  0,  0,  0,  8,100,101, 99,108,116, 97,103,  0,
  4,  0,  0,  0, 81,  0,  0,  0, 11, 64, 98, 97,115,105, 99, 46,108,117, 97,  0,
  0,  0,  0, 67,  5,  2, 60, 82, 13,  0, 11,  2, 31, 48,  5, 13,  1,  7,  0, 31,
 48,  8, 15,  3, 13,  0,  2,  1,  1, 44, 48,  6, 15,  4, 13,  1, 16, 44, 52, 26,
 60, 83, 15,  4, 13,  1, 13,  0, 26, 60, 84, 15,  5, 11,  6, 13,  1, 42, 11,  7,
 42,  2,  0,  1, 50,  2, 60, 85, 60, 86,  0,  0,  0,  0,  2,  0,  0,  0, 81,  0,
  0,  0,  6,105,116,121,112,101,  0,  0,  0,  0, 81,  0,  0,  0,  4,116, 97,103,
  0,  0,  0,  0,  8,  2,  0,  0,  0,  6,105,116,121,112,101,  0,  2,  0,  0,  0,
  4,116, 97,103,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  8,105,115, 98, 97,
115,105, 99,  0,  2,  0,  0,  0, 10, 95,116, 97,103,110, 97,109,101,115,  0,  2,
  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 12,115,116, 97,116,
105, 99, 32,105,110,116, 32,  0,  2,  0,  0,  0,  2, 59,  0,  2,  0,  0,  0,  7,
116, 97,103,118, 97,114,  0,  4,  0,  0,  0, 89,  0,  0,  0, 11, 64, 98, 97,115,
105, 99, 46,108,117, 97,  0,  0,  0,  0,155,  8,  2, 60, 90, 13,  0, 11,  2, 32,
 46,  5, 13,  0, 11,  3, 32, 52, 10, 60, 91, 13,  0,  7,  0,  1,  2, 50,124, 60,
 92, 15,  4, 13,  0,  2,  1,  1, 52, 18, 60, 93, 13,  0, 11,  5, 15,  4, 13,  0,
  2,  1,  1, 42,  1,  2, 50, 95, 60, 95, 15,  8, 13,  0,  2,  2,  1, 60, 96, 15,
  9, 13,  2, 11,  1,  2,  1,  2, 52,  4, 11,  1, 23,  1, 60, 97, 13,  3, 23,  0,
 60, 98, 15, 10, 13,  3,  2,  0,  1, 60, 99, 11,  5, 60,100, 13,  1, 48,  5, 13,
  1, 11,  2, 31, 52, 20, 60,101, 11, 12, 13,  3, 42, 23,  3, 60,102, 13,  4, 11,
 13, 42, 23,  4, 50,  2, 60,103, 60,104, 13,  3, 13,  4, 13,  0, 42,  1,  5,  5,
  3, 60,105, 60,106,  0,  0,  0,  0,  8,  0,  0,  0, 89,  0,  0,  0,  5,116,121,
112,101,  0,  0,  0,  0, 89,  0,  0,  0,  6, 99,111,110,115,116,  0,  0,  0,  0,
 95,  0,  0,  0,  2,109,  0,  0,  0,  0, 95,  0,  0,  0,  2,116,  0,  0,  0,  0,
 99,  0,  0,  0,  2,118,  0,  0,  0,  0,104,  0,  0,  0,  0,  0,  0,  0,104,  0,
  0,  0,  0,  0,  0,  0,104,  0,  0,  0,  0,  0,  0,  0, 14,  2,  0,  0,  0,  5,
116,121,112,101,  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,  0,  0,  0,
  1,  0,  2,  0,  0,  0,  5,118,111,105,100,  0,  2,  0,  0,  0,  8,105,115, 98,
 97,115,105, 99,  0,  2,  0,  0,  0, 11,116,111,108,117, 97, 95,116, 97,103, 95,
  0,  2,  0,  0,  0,  2,109,  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0, 12,
102,105,110,100,116,121,112,101,100,101,102,  0,  2,  0,  0,  0,  8,115,116,114,
102,105,110,100,  0,  2,  0,  0,  0,  8,114,101,103,116,121,112,101,  0,  2,  0,
  0,  0,  2,118,  0,  2,  0,  0,  0,  7, 99,111,110,115,116, 32,  0,  2,  0,  0,
  0,  7, 99,111,110,115,116, 95,  0,  2,  0,  0,  0,  8,105,115, 98, 97,115,105,
 99,  0,  4,  0,  0,  0,109,  0,  0,  0, 11, 64, 98, 97,115,105, 99, 46,108,117,
 97,  0,  0,  0,  0, 23,  5,  1, 60,110, 15,  3, 13,  0,  2,  2,  1, 60,111, 15,
  4, 13,  2, 16,  1,  3, 60,112,  0,  0,  0,  0,  3,  0,  0,  0,109,  0,  0,  0,
  5,116,121,112,101,  0,  0,  0,  0,110,  0,  0,  0,  2,109,  0,  0,  0,  0,110,
  0,  0,  0,  2,116,  0,  0,  0,  0,  5,  2,  0,  0,  0,  5,116,121,112,101,  0,
  2,  0,  0,  0,  2,109,  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0, 12,102,
105,110,100,116,121,112,101,100,101,102,  0,  2,  0,  0,  0,  7, 95, 98, 97,115,
105, 99,  0,  2,  0,  0,  0,  7,105,115,116,121,112,101,  0,  4,  0,  0,  0,115,
  0,  0,  0, 11, 64, 98, 97,115,105, 99, 46,108,117, 97,  0,  0,  0,  0, 30,  3,
  1, 60,116, 15,  1, 13,  0, 16, 46,  5, 15,  2, 13,  0, 16, 46,  7, 15,  3, 13,
  0,  2,  1,  1,  1,  1, 60,117,  0,  0,  0,  0,  1,  0,  0,  0,115,  0,  0,  0,
  2,116,  0,  0,  0,  0,  4,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  7, 95,
 98, 97,115,105, 99,  0,  2,  0,  0,  0, 10, 95,117,115,101,114,116,121,112,101,
  0,  2,  0,  0,  0, 10,105,115,116,121,112,101,100,101,102,  0,  2,  0,  0,  0,
  6,115,112,108,105,116,  0,  4,  0,  0,  0,121,  0,  0,  0, 11, 64, 98, 97,115,
105, 99, 46,108,117, 97,  0,  0,  0,  0,117, 11,  2, 60,122, 22,  1, 11,  3,  7,
  0, 30,  0, 60,123, 13,  2, 58,  5,  1, 60,127, 11,  7, 13,  1, 42, 11,  8, 42,
 60,128, 15,  9, 13,  0, 11, 10, 11, 11,  2,  1,  3, 23,  0, 60,129, 15,  9, 13,
  0, 11, 12, 11, 11,  2,  1,  3, 23,  0, 60,130, 15,  9, 13,  0, 13,  4, 13,  3,
  2,  1,  3, 23,  0, 60,131, 13,  2, 11, 14, 13,  2, 18, 14,  7,  1, 37, 26, 60,
132, 13,  2, 13,  2, 18, 14, 15,  9, 13,  0, 11, 15, 11, 11,  2,  1,  3, 26, 60,
133, 13,  2,  1,  5, 60,134,  0,  0,  0,  0,  5,  0,  0,  0,121,  0,  0,  0,  2,
115,  0,  0,  0,  0,121,  0,  0,  0,  2,116,  0,  0,  0,  0,122,  0,  0,  0,  2,
108,  0,  0,  0,  0,123,  0,  0,  0,  2,102,  0,  0,  0,  0,127,  0,  0,  0,  2,
112,  0,  0,  0,  0, 16,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0,  2,116,  0,
  2,  0,  0,  0,  2,108,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  2,102,
  0,  4,  0,  0,  0,123,  0,  0,  0, 11, 64, 98, 97,115,105, 99, 46,108,117, 97,
  0,  0,  0,  0, 30,  5,  1, 60,124, 12,  0, 11,  2, 12,  0, 18,  2,  7,  1, 37,
 26, 60,125, 12,  0, 12,  0, 18,  2, 13,  0, 26, 60,126,  0,  0,  0,  0,  1,  0,
  0,  0,123,  0,  0,  0,  2,115,  0,  0,  0,  0,  3,  2,  0,  0,  0,  2,115,  0,
  2,  0,  0,  0,  2,108,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  2,112,
  0,  2,  0,  0,  0, 11, 37,115, 42, 40, 46, 45, 41, 37,115, 42,  0,  2,  0,  0,
  0,  4, 37,115, 42,  0,  2,  0,  0,  0,  5,103,115,117, 98,  0,  2,  0,  0,  0,
  5, 94, 37,115, 43,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  5, 37,115, 43,
 36,  0,  2,  0,  0,  0,  2,108,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,
  9, 40, 37,115, 37,115, 42, 41, 36,  0,  2,  0,  0,  0,  7, 99,111,110, 99, 97,
116,  0,  4,  0,  0,  0,138,  0,  0,  0, 11, 64, 98, 97,115,105, 99, 46,108,117,
 97,  0,  0,  0,  0, 69,  8,  3, 60,139, 11,  4, 60,140, 13,  1, 50, 39, 60,142,
 13,  3, 13,  0, 13,  4, 16, 42, 23,  3, 60,143, 13,  4,  7,  1, 37, 23,  4, 60,
144, 13,  4, 13,  2, 34, 52,  7, 13,  3, 11,  6, 42, 23,  3, 60,145, 60,141, 13,
  4, 13,  2, 34, 54, 48, 60,146, 13,  3,  1,  5, 60,147,  0,  0,  0,  0,  5,  0,
  0,  0,138,  0,  0,  0,  2,116,  0,  0,  0,  0,138,  0,  0,  0,  2,102,  0,  0,
  0,  0,138,  0,  0,  0,  2,108,  0,  0,  0,  0,139,  0,  0,  0,  2,115,  0,  0,
  0,  0,140,  0,  0,  0,  2,105,  0,  0,  0,  0,  7,  2,  0,  0,  0,  2,116,  0,
  2,  0,  0,  0,  2,102,  0,  2,  0,  0,  0,  2,108,  0,  2,  0,  0,  0,  2,115,
  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  2, 32,
  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  4,  0,  0,  0,150,  0,  0,
  0, 11, 64, 98, 97,115,105, 99, 46,108,117, 97,  0,  0,  0,  0,161,  6,128, 60,
151,  7,  1, 50,104, 60,153, 15,  3, 48, 10, 15,  4, 15,  3, 11,  5,  2,  1,  2,
 44, 48, 14, 60,154, 15,  4, 13,  0, 13,  1, 16, 11,  6,  2,  1,  2, 52, 11, 60,
155, 15,  7, 11,  8,  2,  0,  1, 50,  2, 60,156, 60,157, 15,  7, 13,  0, 13,  1,
 16,  2,  0,  1, 60,158, 13,  0, 13,  1, 16, 11,  9, 31, 52, 20, 60,159, 15, 10,
 13,  0, 13,  1, 16,  9,  1,  9,  1,  2,  1,  3, 25,  3, 50,  2, 60,160, 60,161,
 13,  1,  7,  1, 37, 23,  1, 60,162, 60,152, 13,  1, 13,  0, 18,  2, 34, 54,115,
 60,163, 15,  4, 13,  0, 13,  0, 18,  2, 16, 11, 11,  2,  1,  2, 52, 15, 60,164,
  4,  0, 25,  3, 15,  7, 11, 12,  2,  0,  1, 50,  2, 60,165, 60,166,  0,  0,  0,
  0,  2,  0,  0,  0,150,  0,  0,  0,  4, 97,114,103,  0,  0,  0,  0,151,  0,  0,
  0,  2,105,  0,  0,  0,  0, 13,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  4,
 97,114,103,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  6, 95, 99,111,110,
116,  0,  2,  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,  0,  0,  0,  7,
 91, 37, 40, 44, 34, 93,  0,  2,  0,  0,  0,  8, 94, 91, 37, 97, 95,126, 93,  0,
  2,  0,  0,  0,  6,119,114,105,116,101,  0,  2,  0,  0,  0,  2, 32,  0,  2,  0,
  0,  0,  1,  0,  2,  0,  0,  0,  7,115,116,114,115,117, 98,  0,  2,  0,  0,  0,
 14, 91, 37, 47, 37, 41, 37, 59, 37,123, 37,125, 93, 36,  0,  2,  0,  0,  0,  2,
 10,  0,
};

/* feature.lo */
static char B2[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 13, 64,102,101, 97,116,117,
114,101, 46,108,117, 97,  0,  0,  0,  0, 83,  3,  0, 60, 16, 22,  0, 60, 17, 25,
  0, 60, 20, 15,  0, 11,  1, 11,  2, 26, 60, 24, 15,  0, 11,  3, 11,  4, 26, 60,
 28, 15,  0, 11,  5, 11,  6, 26, 60, 32, 15,  0, 11,  7, 11,  8, 26, 60, 36, 15,
  0, 11,  9, 11, 10, 26, 60, 40, 15,  0, 11, 11, 11, 12, 26, 60, 49, 15,  0, 11,
 13, 11, 14, 26, 60, 59, 15,  0, 11, 15, 11, 16, 26,  0,  0,  0,  0,  0,  0,  0,
  0, 17,  2,  0,  0,  0, 13, 99,108, 97,115,115, 70,101, 97,116,117,114,101,  0,
  2,  0,  0,  0,  8,115,117,112, 99,111,100,101,  0,  4,  0,  0,  0, 20,  0,  0,
  0, 13, 64,102,101, 97,116,117,114,101, 46,108,117, 97,  0,  0,  0,  0,  5,  1,
  1, 60, 21,  0,  0,  0,  0,  1,  0,  0,  0, 20,  0,  0,  0,  5,115,101,108,102,
  0,  0,  0,  0,  0,  2,  0,  0,  0,  8,100,101, 99,108,116, 97,103,  0,  4,  0,
  0,  0, 24,  0,  0,  0, 13, 64,102,101, 97,116,117,114,101, 46,108,117, 97,  0,
  0,  0,  0,  5,  1,  1, 60, 25,  0,  0,  0,  0,  1,  0,  0,  0, 24,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0,  0,  2,  0,  0,  0,  9,114,101,103,105,115,
116,101,114,  0,  4,  0,  0,  0, 28,  0,  0,  0, 13, 64,102,101, 97,116,117,114,
101, 46,108,117, 97,  0,  0,  0,  0,  5,  1,  1, 60, 29,  0,  0,  0,  0,  1,  0,
  0,  0, 28,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  0,  2,  0,  0,  0,
 11,117,110,114,101,103,105,115,116,101,114,  0,  4,  0,  0,  0, 32,  0,  0,  0,
 13, 64,102,101, 97,116,117,114,101, 46,108,117, 97,  0,  0,  0,  0,  5,  1,  1,
 60, 33,  0,  0,  0,  0,  1,  0,  0,  0, 32,  0,  0,  0,  5,115,101,108,102,  0,
  0,  0,  0,  0,  2,  0,  0,  0,  9,112,114,101, 97,109, 98,108,101,  0,  4,  0,
  0,  0, 36,  0,  0,  0, 13, 64,102,101, 97,116,117,114,101, 46,108,117, 97,  0,
  0,  0,  0,  5,  1,  1, 60, 37,  0,  0,  0,  0,  1,  0,  0,  0, 36,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0,  0,  2,  0,  0,  0,  8,105,110, 99,108, 97,
115,115,  0,  4,  0,  0,  0, 40,  0,  0,  0, 13, 64,102,101, 97,116,117,114,101,
 46,108,117, 97,  0,  0,  0,  0, 44,  3,  1, 60, 41, 13,  0, 18,  1, 48,  9, 13,
  0, 18,  1, 18,  2, 11,  3, 32, 52, 12, 60, 42, 13,  0, 18,  1, 18,  4,  1,  1,
 50,  8, 60, 44,  4,  0,  1,  1, 60, 45, 60, 46,  0,  0,  0,  0,  1,  0,  0,  0,
 40,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  5,  2,  0,  0,  0,  5,115,
101,108,102,  0,  2,  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,  0,  0,  0,
  5,116,121,112,101,  0,  2,  0,  0,  0,  6, 99,108, 97,115,115,  0,  2,  0,  0,
  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,108,101,
  0,  4,  0,  0,  0, 49,  0,  0,  0, 13, 64,102,101, 97,116,117,114,101, 46,108,
117, 97,  0,  0,  0,  0, 44,  3,  1, 60, 50, 13,  0, 18,  1, 48,  9, 13,  0, 18,
  1, 18,  2, 11,  3, 32, 52, 12, 60, 51, 13,  0, 18,  1, 18,  4,  1,  1, 50,  8,
 60, 53,  4,  0,  1,  1, 60, 54, 60, 55,  0,  0,  0,  0,  1,  0,  0,  0, 49,  0,
  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  5,  2,  0,  0,  0,  5,115,101,108,
102,  0,  2,  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,  0,  0,  0,  5,116,
121,112,101,  0,  2,  0,  0,  0,  7,109,111,100,117,108,101,  0,  2,  0,  0,  0,
  5,110, 97,109,101,  0,  2,  0,  0,  0, 10, 99,102,117,110, 99,110, 97,109,101,
  0,  4,  0,  0,  0, 59,  0,  0,  0, 13, 64,102,101, 97,116,117,114,101, 46,108,
117, 97,  0,  0,  0,  0, 72,  5,  2, 60, 60, 13,  0, 18,  2, 52, 17, 60, 61, 13,
  0, 18,  2, 20,  3, 13,  1,  2,  1,  2, 23,  1, 50,  2, 60, 62, 60, 63, 13,  0,
 18,  4, 52, 16, 60, 64, 13,  1, 11,  5, 42, 13,  0, 18,  4, 42,  1,  2, 50, 16,
 60, 66, 13,  1, 11,  5, 42, 13,  0, 18,  6, 42,  1,  2, 60, 67, 60, 68,  0,  0,
  0,  0,  2,  0,  0,  0, 59,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 59,
  0,  0,  0,  2,110,  0,  0,  0,  0,  7,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,
  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,
  0,  0,  0, 10, 99,102,117,110, 99,110, 97,109,101,  0,  2,  0,  0,  0,  6,108,
110, 97,109,101,  0,  2,  0,  0,  0,  2, 95,  0,  2,  0,  0,  0,  5,110, 97,109,
101,  0,
};

/* declaration.lo */
static char B3[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 17, 64,100,101, 99,108, 97,
114, 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0,193, 17,  0, 60, 24, 22,
  8, 60, 25, 11,  1, 15,  2, 11,  3, 60, 26, 11,  4, 11,  5, 60, 27, 11,  4, 11,
  6, 60, 28, 11,  4, 11,  7, 60, 29, 11,  4, 11,  8, 60, 30, 11,  4, 11,  9, 60,
 31, 11,  4, 11, 10, 60, 32, 11,  4, 30,  7, 60, 33, 25,  0, 60, 34, 15, 11, 15,
  0, 15, 12,  2,  0,  2, 60, 37, 11, 14, 25, 13, 60, 45, 15,  0, 11, 15, 11, 16,
 26, 60, 84, 15,  0, 11, 17, 11, 18, 26, 60,117, 15,  0, 11, 19, 11, 20, 26, 60,
130, 15,  0, 11, 21, 11, 22, 26, 60,136, 15,  0, 11, 23, 11, 24, 26, 60,149, 15,
  0, 11, 25, 11, 26, 26, 60,184, 15,  0, 11, 27, 11, 28, 26, 60,218, 15,  0, 11,
 29, 11, 30, 26, 60,250, 15,  0, 11, 31, 11, 32, 26, 59,  1,  1, 15,  0, 11, 33,
 11, 34, 26, 59,  1, 12, 15,  0, 11, 35, 11, 36, 26, 59,  1, 26, 11, 38, 25, 37,
 59,  1, 42, 11, 40, 25, 39,  0,  0,  0,  0,  0,  0,  0,  0, 41,  2,  0,  0,  0,
 17, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110,  0,  2,  0,
  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 13, 99,108, 97,115,115, 70,
101, 97,116,117,114,101,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,
  1,  0,  2,  0,  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0,  4,112,116,114,
  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  4,100,105,109,  0,
  2,  0,  0,  0,  4,114,101,116,  0,  2,  0,  0,  0,  4,100,101,102,  0,  2,  0,
  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97,
 95,116, 97,103,  0,  2,  0,  0,  0, 15, 99,114,101, 97,116,101, 95,118, 97,114,
110, 97,109,101,  0,  4,  0,  0,  0, 37,  0,  0,  0, 17, 64,100,101, 99,108, 97,
114, 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0, 34,  2,  0, 60, 38, 15,
  0, 44, 52,  4,  7,  0, 25,  0, 60, 39, 15,  0,  7,  1, 37, 25,  0, 60, 40, 11,
  1, 15,  0, 42,  1,  0, 60, 41,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,
  0, 11, 95,118, 97,114,110,117,109, 98,101,114,  0,  2,  0,  0,  0, 11,116,111,
108,117, 97, 95,118, 97,114, 95,  0,  2,  0,  0,  0, 10, 99,104,101, 99,107,110,
 97,109,101,  0,  4,  0,  0,  0, 45,  0,  0,  0, 17, 64,100,101, 99,108, 97,114,
 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  1,140, 12,  1, 60, 47, 15,  0,
 13,  0, 18,  2,  7,  1,  7,  1,  2,  1,  3, 11,  3, 32, 48, 10, 15,  4, 13,  0,
 18,  5,  2,  1,  1, 44, 52, 70, 60, 48, 13,  0, 11,  2, 13,  0, 18,  5, 13,  0,
 18,  2, 42, 26, 60, 49, 15,  7, 13,  0, 18,  8, 11,  9,  2,  1,  2, 60, 50, 13,
  0, 11,  5, 13,  1, 13,  1, 18, 10, 16, 26, 60, 51, 13,  0, 11,  8, 15, 11, 13,
  1,  7,  1, 13,  1, 18, 10,  7,  1, 38,  2,  1,  3, 26,  5,  1, 50,  2, 60, 52,
 60, 54, 15,  7, 13,  0, 18,  2, 11, 13,  2,  1,  2, 60, 55, 13,  1, 18, 10,  7,
  2, 32, 52, 28, 60, 56, 13,  0, 11,  2, 13,  1,  7,  1, 16, 26, 60, 57, 13,  0,
 11, 14, 13,  1, 13,  1, 18, 10, 16, 26, 50,  2, 60, 58, 60, 60, 15, 18, 13,  0,
 18,  2, 11, 19,  2,  3,  2, 60, 61, 13,  2, 52, 34, 60, 62, 13,  0, 11,  2, 15,
  0, 13,  0, 18,  2,  7,  1, 13,  2,  7,  1, 38,  2,  1,  3, 26, 60, 63, 13,  0,
 11, 20, 13,  4, 26, 50,  2, 60, 64, 60, 67, 13,  0, 18,  5, 11, 21, 31, 48,  7,
 13,  0, 18,  5, 11, 22, 31, 48,  7, 13,  0, 18,  2, 11, 21, 32, 52, 14, 60, 68,
 13,  0, 11,  2, 15, 23,  2,  1,  0, 26, 50,135, 60, 69, 13,  0, 18, 24, 11, 25,
 32, 52,122, 60, 70, 13,  0, 18,  5, 11, 21, 32, 48,  7, 13,  0, 18,  2, 11, 21,
 31, 52, 30, 60, 71, 13,  0, 11,  5, 13,  0, 18,  5, 13,  0, 18,  2, 42, 26, 60,
 72, 13,  0, 11,  2, 15, 23,  2,  1,  0, 26, 50, 70, 60, 73, 15,  4, 13,  0, 18,
  2,  2,  1,  1, 52, 55, 60, 74, 13,  0, 18,  5, 11, 21, 32, 52, 11, 13,  0, 11,
  5, 13,  0, 18,  2, 26, 50, 19, 60, 75, 13,  0, 11,  5, 13,  0, 18,  5, 11, 26,
 42, 13,  0, 18,  2, 42, 26, 60, 76, 13,  0, 11,  2, 15, 23,  2,  1,  0, 26, 50,
  2, 60, 77, 50,  2, 60, 78, 60, 80,  0,  0,  0,  0,  7,  0,  0,  0, 45,  0,  0,
  0,  5,115,101,108,102,  0,  0,  0,  0, 49,  0,  0,  0,  2,109,  0,  0,  0,  0,
 51,  0,  0,  0,  0,  0,  0,  0, 54,  0,  0,  0,  2,116,  0,  0,  0,  0, 60,  0,
  0,  0,  2, 98,  0,  0,  0,  0, 60,  0,  0,  0,  2,101,  0,  0,  0,  0, 60,  0,
  0,  0,  2,100,  0,  0,  0,  0, 27,  2,  0,  0,  0,  7,115,116,114,115,117, 98,
  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,
  0,  2,  0,  0,  0,  2, 91,  0,  2,  0,  0,  0,  7,105,115,116,121,112,101,  0,
  2,  0,  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0,  2,109,  0,  2,  0,  0,
  0,  6,115,112,108,105,116,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,
  0,  6, 37,115, 37,115, 42,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  7,
 99,111,110, 99, 97,116,  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  2, 61,
  0,  2,  0,  0,  0,  4,100,101,102,  0,  2,  0,  0,  0,  2, 98,  0,  2,  0,  0,
  0,  2,101,  0,  2,  0,  0,  0,  2,100,  0,  2,  0,  0,  0,  8,115,116,114,102,
105,110,100,  0,  2,  0,  0,  0,  9, 37, 91, 40, 46, 45, 41, 37, 93,  0,  2,  0,
  0,  0,  4,100,105,109,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  5,118,111,
105,100,  0,  2,  0,  0,  0, 15, 99,114,101, 97,116,101, 95,118, 97,114,110, 97,
109,101,  0,  2,  0,  0,  0,  5,107,105,110,100,  0,  2,  0,  0,  0,  4,118, 97,
114,  0,  2,  0,  0,  0,  2, 32,  0,  2,  0,  0,  0, 10, 99,104,101, 99,107,116,
121,112,101,  0,  4,  0,  0,  0, 84,  0,  0,  0, 17, 64,100,101, 99,108, 97,114,
 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0,152,  4,  1, 60, 87, 15,  0,
 13,  0, 18,  2,  2,  1,  1, 48,  7, 13,  0, 18,  3, 11,  4, 31, 52, 22, 60, 88,
 13,  0, 11,  5, 13,  0, 18,  3, 26, 60, 89, 13,  0, 11,  3,  4,  0, 26, 50,  2,
 60, 90, 60, 93, 13,  0, 18,  6, 11,  4, 31, 48,  7, 13,  0, 18,  5, 11,  4, 31,
 52, 11, 60, 94, 15,  7, 11,  8,  2,  0,  1, 50,  2, 60, 95, 60, 98, 13,  0, 18,
  2, 11,  4, 31, 52, 13, 60, 99, 15,  9, 13,  0, 18,  2,  2,  0,  1, 50,  2, 60,
100, 60,103, 13,  0, 18,  2, 11, 10, 32, 52,  9, 13,  0, 11,  2, 11, 11, 26, 50,
 22, 60,104, 13,  0, 18,  2, 11, 12, 32, 52,  9, 13,  0, 11,  2, 11, 13, 26, 50,
  2, 60,105, 60,114,  0,  0,  0,  0,  1,  0,  0,  0, 84,  0,  0,  0,  5,115,101,
108,102,  0,  0,  0,  0, 14,  2,  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,
  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,116,121,112,101,  0,
  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  4,
114,101,116,  0,  2,  0,  0,  0,  4,100,105,109,  0,  2,  0,  0,  0,  6,101,114,
114,111,114,  0,  2,  0,  0,  0, 53, 35,105,110,118, 97,108,105,100, 32,112, 97,
114, 97,109,101,116,101,114, 58, 32, 99, 97,110,110,111,116, 32,114,101,116,117,
114,110, 32, 97,110, 32, 97,114,114, 97,121, 32,111,102, 32,118, 97,108,117,101,
115,  0,  2,  0,  0,  0,  8,114,101,103,116,121,112,101,  0,  2,  0,  0,  0, 10,
 95,117,115,101,114,100, 97,116, 97,  0,  2,  0,  0,  0,  6,118,111,105,100, 42,
  0,  2,  0,  0,  0,  9, 95, 99,115,116,114,105,110,103,  0,  2,  0,  0,  0,  6,
 99,104, 97,114, 42,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,
  0,117,  0,  0,  0, 17, 64,100,101, 99,108, 97,114, 97,116,105,111,110, 46,108,
117, 97,  0,  0,  0,  0,172,  6,  3, 60,118, 15,  2, 13,  1, 11,  3, 42,  2,  0,
  1, 60,119, 15,  2, 13,  1, 11,  4, 42, 13,  0, 18,  6, 42, 11,  7, 42,  2,  0,
  1, 60,120, 15,  2, 13,  1, 11,  8, 42, 13,  0, 18,  9, 42, 11,  7, 42,  2,  0,
  1, 60,121, 15,  2, 13,  1, 11, 10, 42, 13,  0, 18, 11, 42, 11,  7, 42,  2,  0,
  1, 60,122, 15,  2, 13,  1, 11, 12, 42, 13,  0, 18, 13, 42, 11,  7, 42,  2,  0,
  1, 60,123, 15,  2, 13,  1, 11, 14, 42, 13,  0, 18, 15, 42, 11,  7, 42,  2,  0,
  1, 60,124, 15,  2, 13,  1, 11, 16, 42, 13,  0, 18, 17, 42, 11,  7, 42,  2,  0,
  1, 60,125, 15,  2, 13,  1, 11, 18, 42, 13,  0, 18, 19, 42, 11,  7, 42,  2,  0,
  1, 60,126, 15,  2, 13,  1, 11, 20, 42, 13,  2, 42,  2,  0,  1, 60,127,  0,  0,
  0,  0,  3,  0,  0,  0,117,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,117,
  0,  0,  0,  6,105,100,101,110,116,  0,  0,  0,  0,117,  0,  0,  0,  6, 99,108,
111,115,101,  0,  0,  0,  0, 21,  2,  0,  0,  0,  6,105,100,101,110,116,  0,  2,
  0,  0,  0,  6, 99,108,111,115,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,
  0,  2,  0,  0,  0, 13, 68,101, 99,108, 97,114, 97,116,105,111,110,123,  0,  2,
  0,  0,  0, 10, 32,109,111,100, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,115,
101,108,102,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  3, 39, 44,
  0,  2,  0,  0,  0, 10, 32,116,121,112,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,
  5,116,121,112,101,  0,  2,  0,  0,  0, 10, 32,112,116,114, 32, 32, 61, 32, 39,
  0,  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0, 10, 32,110, 97,109,101,
 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 10,
 32,100,105,109, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,100,105,109,  0,  2,
  0,  0,  0, 10, 32,100,101,102, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,100,
101,102,  0,  2,  0,  0,  0, 10, 32,114,101,116, 32, 32, 61, 32, 39,  0,  2,  0,
  0,  0,  4,114,101,116,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0,  8,100,
101, 99,108,116, 97,103,  0,  4,  0,  0,  0,130,  0,  0,  0, 17, 64,100,101, 99,
108, 97,114, 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0, 56, 10,  1, 60,
131, 13,  0, 11,  1, 13,  0, 11,  2, 15,  3, 13,  0, 18,  4, 15,  5, 13,  0, 18,
  6, 11,  7,  2,  1,  2,  2,  2,  2, 27,  1, 27,  2,  5,  4, 60,132, 15,  8, 13,
  0, 18,  1, 13,  0, 18,  2,  2,  0,  2, 60,133,  0,  0,  0,  0,  1,  0,  0,  0,
130,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  9,  2,  0,  0,  0,  5,115,
101,108,102,  0,  2,  0,  0,  0,  6,105,116,121,112,101,  0,  2,  0,  0,  0,  4,
116, 97,103,  0,  2,  0,  0,  0,  7,116, 97,103,118, 97,114,  0,  2,  0,  0,  0,
  5,116,121,112,101,  0,  2,  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,
  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,
  0,  0,  0,  8,100,101, 99,108,116, 97,103,  0,  2,  0,  0,  0, 13,111,117,116,
 99,104,101, 99,107,116,121,112,101,  0,  4,  0,  0,  0,136,  0,  0,  0, 17, 64,
100,101, 99,108, 97,114, 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0, 83,
  6,  2, 60,137,  4,  1, 60,138, 13,  0, 18,  4, 11,  5, 31, 52, 14, 60,139, 11,
  6, 23,  2, 60,140,  7,  0, 23,  3, 50, 25, 60,142, 13,  0, 18,  1, 23,  2, 60,
143, 13,  0, 18,  2, 11,  5, 31, 46,  2,  7,  0, 23,  3, 60,144, 60,145, 11,  7,
 13,  1, 42, 11,  8, 42, 13,  2, 42, 11,  8, 42, 13,  3, 42, 11,  9, 42,  1,  4,
 60,146,  0,  0,  0,  0,  4,  0,  0,  0,136,  0,  0,  0,  5,115,101,108,102,  0,
  0,  0,  0,136,  0,  0,  0,  5,110, 97,114,103,  0,  0,  0,  0,137,  0,  0,  0,
  4,116, 97,103,  0,  0,  0,  0,137,  0,  0,  0,  4,100,101,102,  0,  0,  0,  0,
 10,  2,  0,  0,  0,  5,110, 97,114,103,  0,  2,  0,  0,  0,  4,116, 97,103,  0,
  2,  0,  0,  0,  4,100,101,102,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,
  0,  0,  0,  4,100,105,109,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0, 16,116,
111,108,117, 97, 95,116, 97,103, 95,116, 97, 98,108,101,  0,  2,  0,  0,  0, 14,
116,111,108,117, 97, 95,105,115,116,121,112,101, 40,  0,  2,  0,  0,  0,  2, 44,
  0,  2,  0,  0,  0,  2, 41,  0,  2,  0,  0,  0,  8,100,101, 99,108, 97,114,101,
  0,  4,  0,  0,  0,149,  0,  0,  0, 17, 64,100,101, 99,108, 97,114, 97,116,105,
111,110, 46,108,117, 97,  0,  0,  0,  1, 84, 15,  2, 60,150, 11,  2, 60,151, 13,
  0, 18,  1, 11,  2, 31, 52,  4, 11,  4, 23,  2, 60,152, 15,  5, 11,  6, 13,  0,
 18,  7, 13,  0, 18,  8, 13,  2,  2,  0,  4, 60,153, 13,  0, 18,  9, 11,  2, 31,
 48, 12, 15, 10, 13,  0, 18,  9,  2,  1,  1,  4,  0, 32, 52, 11, 60,154, 15,  5,
 11,  4,  2,  0,  1, 50,  2, 60,155, 60,156, 15,  5, 13,  0, 18, 11,  2,  0,  1,
 60,157, 13,  0, 18,  9, 11,  2, 31, 52, 76, 60,158, 15, 10, 13,  0, 18,  9,  2,
  1,  1,  4,  0, 31, 52, 17, 60,159, 15,  5, 11, 12, 13,  0, 18,  9, 11, 13,  2,
  0,  3, 50, 41, 60,161, 15,  5, 11, 14, 13,  0, 18,  7, 13,  0, 18,  8, 13,  2,
 11, 15, 60,162, 11, 16, 13,  0, 18,  9, 11, 17, 13,  0, 18,  8, 13,  2, 11, 18,
  2,  0, 11, 60,163, 50,161, 60,165, 15, 20, 13,  0, 18,  8,  2,  1,  1, 60,166,
 15,  5, 11, 21,  2,  0,  1, 60,167, 13,  3, 44, 48,  5, 13,  2, 11,  2, 32, 52,
  7, 15,  5, 11,  4,  2,  0,  1, 60,168, 15,  5, 11, 22, 13,  0, 18,  7, 13,  0,
 18,  8,  2,  0,  3, 60,169, 13,  3, 44, 52, 11, 60,170, 15,  5, 11,  4,  2,  0,
  1, 50,  2, 60,171, 60,172, 15,  5, 11, 23,  2,  0,  1, 60,173,  7,  0, 60,174,
 13,  0, 18, 24, 11,  2, 31, 52,  6, 13,  0, 18, 24, 23,  4, 60,175, 13,  3, 52,
 24, 60,176, 15,  5, 11, 25, 13,  3, 42, 11, 26, 13,  1, 11, 27, 13,  4, 11, 18,
  2,  0,  6, 50, 19, 60,178, 15,  5, 11, 28, 13,  1, 11, 27, 13,  4, 11, 18,  2,
  0,  5, 60,179,  5,  2, 60,180, 60,181,  0,  0,  0,  0,  7,  0,  0,  0,149,  0,
  0,  0,  5,115,101,108,102,  0,  0,  0,  0,149,  0,  0,  0,  5,110, 97,114,103,
  0,  0,  0,  0,150,  0,  0,  0,  4,112,116,114,  0,  0,  0,  0,165,  0,  0,  0,
  2,116,  0,  0,  0,  0,173,  0,  0,  0,  4,100,101,102,  0,  0,  0,  0,179,  0,
  0,  0,  0,  0,  0,  0,179,  0,  0,  0,  0,  0,  0,  0, 29,  2,  0,  0,  0,  5,
110, 97,114,103,  0,  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0,  1,  0,
  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  2, 42,  0,  2,  0,  0,
  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0,  2, 32,  0,  2,  0,  0,  0,
  4,109,111,100,  0,  2,  0,  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0,  4,
100,105,109,  0,  2,  0,  0,  0,  9,116,111,110,117,109, 98,101,114,  0,  2,  0,
  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  2, 91,  0,  2,  0,  0,  0,  3,
 93, 59,  0,  2,  0,  0,  0,  5, 32, 61, 32, 40,  0,  2,  0,  0,  0,  3, 42, 41,
  0,  2,  0,  0,  0,  8,109, 97,108,108,111, 99, 40,  0,  2,  0,  0,  0,  9, 42,
115,105,122,101,111,102, 40,  0,  2,  0,  0,  0,  4, 41, 41, 59,  0,  2,  0,  0,
  0,  2,116,  0,  2,  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,
  0,  4, 32, 61, 32,  0,  2,  0,  0,  0,  3, 40, 40,  0,  2,  0,  0,  0,  3, 41,
 32,  0,  2,  0,  0,  0,  4,100,101,102,  0,  2,  0,  0,  0, 10,116,111,108,117,
 97, 95,103,101,116,  0,  2,  0,  0,  0,  2, 40,  0,  2,  0,  0,  0,  2, 44,  0,
  2,  0,  0,  0, 19,116,111,108,117, 97, 95,103,101,116,117,115,101,114,116,121,
112,101, 40,  0,  2,  0,  0,  0,  9,103,101,116, 97,114,114, 97,121,  0,  4,  0,
  0,  0,184,  0,  0,  0, 17, 64,100,101, 99,108, 97,114, 97,116,105,111,110, 46,
108,117, 97,  0,  0,  0,  1, 78, 13,  2, 60,185, 13,  0, 18,  2, 11,  3, 31, 51,
  1, 59, 60,186, 15,  4, 11,  5,  2,  0,  1, 60,187, 13,  0, 18,  6, 11,  3, 31,
 46,  2,  7,  0, 60,188, 15,  4, 11,  7, 13,  1, 11,  8, 13,  0, 18,  9, 11,  8,
 13,  0, 18,  2, 11,  8, 13,  2, 11, 10,  2,  0,  9, 60,189, 15,  4, 11, 11,  2,
  0,  1, 60,190, 15,  4, 11, 12,  2,  0,  1, 60,191, 15,  4, 11, 13,  2,  0,  1,
 60,192, 15,  4, 11, 14,  2,  0,  1, 60,193, 15,  4, 11, 15, 13,  1, 11, 16,  2,
  0,  3, 60,194, 15,  4, 11, 17, 13,  0, 18,  2, 42, 11, 18, 42,  2,  0,  1, 60,
195, 15, 20, 13,  0, 18, 21,  2,  1,  1, 60,196, 11,  3, 60,197, 13,  0, 18, 22,
 11,  3, 31, 52,  4, 11, 23, 23,  4, 60,198, 15,  4, 11, 24, 13,  0, 18, 25, 11,
 26, 42,  2,  0,  2, 60,199, 13,  3, 44, 48,  5, 13,  4, 11,  3, 32, 52,  7, 15,
  4, 11, 23,  2,  0,  1, 60,200, 15,  4, 11, 27, 13,  0, 18, 28, 13,  0, 18, 21,
  2,  0,  3, 60,201, 13,  3, 44, 52, 11, 60,202, 15,  4, 11, 23,  2,  0,  1, 50,
  2, 60,203, 60,204, 15,  4, 11, 29,  2,  0,  1, 60,205,  7,  0, 60,206, 13,  0,
 18,  6, 11,  3, 31, 52,  6, 13,  0, 18,  6, 23,  5, 60,207, 13,  3, 52, 21, 60,
208, 15,  4, 11, 30, 13,  3, 42, 11, 31, 42, 13,  5, 11, 32,  2,  0,  3, 50, 15,
 60,210, 15,  4, 11, 33, 13,  5, 11, 32,  2,  0,  3, 60,211, 60,212, 15,  4, 11,
 34,  2,  0,  1, 60,213, 15,  4, 11, 35,  2,  0,  1,  5,  4, 50,  2, 60,214, 60,
215,  0,  0,  0,  0, 10,  0,  0,  0,184,  0,  0,  0,  5,115,101,108,102,  0,  0,
  0,  0,184,  0,  0,  0,  5,110, 97,114,103,  0,  0,  0,  0,187,  0,  0,  0,  4,
100,101,102,  0,  0,  0,  0,195,  0,  0,  0,  2,116,  0,  0,  0,  0,196,  0,  0,
  0,  4,112,116,114,  0,  0,  0,  0,205,  0,  0,  0,  4,100,101,102,  0,  0,  0,
  0,213,  0,  0,  0,  0,  0,  0,  0,213,  0,  0,  0,  0,  0,  0,  0,213,  0,  0,
  0,  0,  0,  0,  0,213,  0,  0,  0,  0,  0,  0,  0, 36,  2,  0,  0,  0,  5,110,
 97,114,103,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  4,100,
105,109,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,
  0,  2,  0,  0,  0,  4, 32, 32,123,  0,  2,  0,  0,  0,  4,100,101,102,  0,  2,
  0,  0,  0, 27, 32, 32, 32,105,102, 32, 40, 33,116,111,108,117, 97, 95, 97,114,
114, 97,121,105,115,116,121,112,101, 40,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,
  0,  0,  4,116, 97,103,  0,  2,  0,  0,  0,  3, 41, 41,  0,  2,  0,  0,  0, 16,
 32, 32, 32, 32,103,111,116,111, 32,101,114,114,111,114, 59,  0,  2,  0,  0,  0,
  9, 32, 32, 32,101,108,115,101, 10,  0,  2,  0,  0,  0,  5, 32, 32, 32,123,  0,
  2,  0,  0,  0, 11, 32, 32, 32, 32,105,110,116, 32,105, 59,  0,  2,  0,  0,  0,
 34, 32, 32, 32, 32,108,117, 97, 95, 79, 98,106,101, 99,116, 32,108,111, 32, 61,
 32,108,117, 97, 95,103,101,116,112, 97,114, 97,109, 40,  0,  2,  0,  0,  0,  3,
 41, 59,  0,  2,  0,  0,  0, 16, 32, 32, 32, 32,102,111,114, 40,105, 61, 48, 59,
 32,105, 60,  0,  2,  0,  0,  0,  6, 59,105, 43, 43, 41,  0,  2,  0,  0,  0,  2,
116,  0,  2,  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,  0,  5,
116,121,112,101,  0,  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0,  2, 42,
  0,  2,  0,  0,  0,  4, 32, 32, 32,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,
  2,  0,  0,  0,  7, 91,105, 93, 32, 61, 32,  0,  2,  0,  0,  0,  3, 40, 40,  0,
  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  3, 41, 32,  0,  2,  0,  0,
  0, 15,116,111,108,117, 97, 95,103,101,116,102,105,101,108,100,  0,  2,  0,  0,
  0,  9, 40,108,111, 44,105, 43, 49, 44,  0,  2,  0,  0,  0,  4, 41, 41, 59,  0,
  2,  0,  0,  0, 31,116,111,108,117, 97, 95,103,101,116,102,105,101,108,100,117,
115,101,114,116,121,112,101, 40,108,111, 44,105, 43, 49, 44,  0,  2,  0,  0,  0,
  5, 32, 32, 32,125,  0,  2,  0,  0,  0,  4, 32, 32,125,  0,  2,  0,  0,  0,  9,
115,101,116, 97,114,114, 97,121,  0,  4,  0,  0,  0,218,  0,  0,  0, 17, 64,100,
101, 99,108, 97,114, 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  1, 42,  9,
  2, 60,219, 13,  0, 18,  2, 11,  3, 31, 51,  1, 23, 60,220, 15,  4, 11,  5,  2,
  0,  1, 60,221, 15,  4, 11,  6,  2,  0,  1, 60,222, 15,  4, 11,  7, 13,  1, 11,
  8,  2,  0,  3, 60,223, 15,  4, 11,  9, 13,  0, 18,  2, 42, 11, 10, 42,  2,  0,
  1, 60,224, 15, 12, 13,  0, 18, 13,  2,  1,  1, 60,225, 13,  2, 11, 14, 32, 52,
 23, 60,226, 15,  4, 11, 15, 13,  2, 42, 11, 16, 42, 13,  0, 18, 17, 11, 18,  2,
  0,  3, 50,175, 60,227, 13,  2, 52, 23, 60,228, 15,  4, 11, 15, 13,  2, 42, 11,
 19, 42, 13,  0, 18, 17, 11, 18,  2,  0,  3, 50,146, 60,230, 13,  0, 18, 20, 11,
  3, 32, 52,110, 60,231, 15,  4, 11, 21,  2,  0,  1, 60,232, 15,  4, 11, 22,  2,
  0,  1, 60,233, 15,  4, 11, 23, 13,  0, 18, 13, 11, 24, 13,  0, 18, 17, 11, 18,
  2,  0,  5, 60,234, 15,  4, 11, 25,  2,  0,  1, 60,235, 15,  4, 11, 26, 13,  0,
 18, 17, 11, 27, 13,  0, 18, 13, 11, 28,  2,  0,  5, 60,236, 15,  4, 11, 29,  2,
  0,  1, 60,237, 15,  4, 11, 30, 13,  0, 18, 31, 11, 32, 13,  0, 18, 31, 11,  8,
  2,  0,  5, 60,238, 15,  4, 11, 33,  2,  0,  1, 50, 23, 60,242, 15,  4, 11, 34,
 13,  0, 18, 17, 11, 35, 13,  0, 18, 31, 11,  8,  2,  0,  5, 60,243, 60,244, 60,
245, 15,  4, 11, 36,  2,  0,  1,  5,  1, 50,  2, 60,246, 60,247,  0,  0,  0,  0,
  4,  0,  0,  0,218,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,218,  0,  0,
  0,  5,110, 97,114,103,  0,  0,  0,  0,224,  0,  0,  0,  2,116,  0,  0,  0,  0,
245,  0,  0,  0,  0,  0,  0,  0, 37,  2,  0,  0,  0,  5,110, 97,114,103,  0,  2,
  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  4,100,105,109,  0,  2,  0,
  0,  0,  1,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0,
  4, 32, 32,123,  0,  2,  0,  0,  0, 10, 32, 32, 32,105,110,116, 32,105, 59,  0,
  2,  0,  0,  0, 33, 32, 32, 32,108,117, 97, 95, 79, 98,106,101, 99,116, 32,108,
111, 32, 61, 32,108,117, 97, 95,103,101,116,112, 97,114, 97,109, 40,  0,  2,  0,
  0,  0,  3, 41, 59,  0,  2,  0,  0,  0, 15, 32, 32, 32,102,111,114, 40,105, 61,
 48, 59, 32,105, 60,  0,  2,  0,  0,  0,  6, 59,105, 43, 43, 41,  0,  2,  0,  0,
  0,  2,116,  0,  2,  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,
  0,  5,116,121,112,101,  0,  2,  0,  0,  0,  7,110,117,109, 98,101,114,  0,  2,
  0,  0,  0, 19, 32, 32, 32,116,111,108,117, 97, 95,112,117,115,104,102,105,101,
108,100,  0,  2,  0,  0,  0, 17, 40,108,111, 44,105, 43, 49, 44, 40,100,111,117,
 98,108,101, 41,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  6,
 91,105, 93, 41, 59,  0,  2,  0,  0,  0,  9, 40,108,111, 44,105, 43, 49, 44,  0,
  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0,  5, 32, 32, 32,123,  0,  2,
  0,  0,  0, 20, 35,105,102,100,101,102, 32, 95, 95, 99,112,108,117,115,112,108,
117,115, 10,  0,  2,  0,  0,  0, 29, 32, 32, 32, 32,118,111,105,100, 42, 32,116,
111,108,117, 97, 73, 95, 99,108,111,110,101, 32, 61, 32,110,101,119,  0,  2,  0,
  0,  0,  2, 40,  0,  2,  0,  0,  0,  7, 35,101,108,115,101, 10,  0,  2,  0,  0,
  0, 45, 32, 32, 32, 32,118,111,105,100, 42, 32,116,111,108,117, 97, 73, 95, 99,
108,111,110,101, 32, 61, 32,116,111,108,117, 97, 95, 99,111,112,121, 40, 40,118,
111,105,100, 42, 41, 38,  0,  2,  0,  0,  0, 12, 91,105, 93, 44,115,105,122,101,
111,102, 40,  0,  2,  0,  0,  0,  4, 41, 41, 59,  0,  2,  0,  0,  0,  8, 35,101,
110,100,105,102, 10,  0,  2,  0,  0,  0, 63, 32, 32, 32, 32,116,111,108,117, 97,
 95,112,117,115,104,102,105,101,108,100,117,115,101,114,116,121,112,101, 40,108,
111, 44,105, 43, 49, 44,116,111,108,117, 97, 95,100,111, 99,108,111,110,101, 40,
116,111,108,117, 97, 73, 95, 99,108,111,110,101, 44,  0,  2,  0,  0,  0,  4,116,
 97,103,  0,  2,  0,  0,  0,  3, 41, 44,  0,  2,  0,  0,  0,  5, 32, 32, 32,125,
  0,  2,  0,  0,  0, 42, 32, 32, 32,116,111,108,117, 97, 95,112,117,115,104,102,
105,101,108,100,117,115,101,114,116,121,112,101, 40,108,111, 44,105, 43, 49, 44,
 40,118,111,105,100, 42, 41,  0,  2,  0,  0,  0,  5, 91,105, 93, 44,  0,  2,  0,
  0,  0,  4, 32, 32,125,  0,  2,  0,  0,  0, 10,102,114,101,101, 97,114,114, 97,
121,  0,  4,  0,  0,  0,250,  0,  0,  0, 17, 64,100,101, 99,108, 97,114, 97,116,
105,111,110, 46,108,117, 97,  0,  0,  0,  0, 49,  5,  1, 60,251, 13,  0, 18,  1,
 11,  2, 31, 48, 12, 15,  3, 13,  0, 18,  1,  2,  1,  1,  4,  0, 32, 52, 17, 60,
252, 15,  4, 11,  5, 13,  0, 18,  6, 11,  7,  2,  0,  3, 50,  2, 60,253, 60,254,
  0,  0,  0,  0,  1,  0,  0,  0,250,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,
  0,  8,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  4,100,105,109,
  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  9,116,111,110,117,109, 98,101,114,
  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0,  8, 32, 32,
102,114,101,101, 40,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,
  3, 41, 59,  0,  2,  0,  0,  0,  8,112, 97,115,115,112, 97,114,  0,  4,  0,  0,
  1,  1,  0,  0,  0, 17, 64,100,101, 99,108, 97,114, 97,116,105,111,110, 46,108,
117, 97,  0,  0,  0,  0, 79,  4,  1, 59,  1,  2, 13,  0, 18,  1, 11,  2, 32, 52,
 17, 59,  1,  3, 15,  3, 11,  4, 13,  0, 18,  5, 42,  2,  0,  1, 50, 44, 59,  1,
  4, 13,  0, 18,  6, 11,  4, 32, 52, 17, 59,  1,  5, 15,  3, 11,  2, 13,  0, 18,
  5, 42,  2,  0,  1, 50, 15, 59,  1,  7, 15,  3, 13,  0, 18,  5,  2,  0,  1, 59,
  1,  8, 59,  1,  9,  0,  0,  0,  0,  1,  0,  0,  1,  1,  0,  0,  0,  5,115,101,
108,102,  0,  0,  0,  0,  7,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,
  0,  4,112,116,114,  0,  2,  0,  0,  0,  2, 38,  0,  2,  0,  0,  0,  7,111,117,
116,112,117,116,  0,  2,  0,  0,  0,  2, 42,  0,  2,  0,  0,  0,  5,110, 97,109,
101,  0,  2,  0,  0,  0,  4,114,101,116,  0,  2,  0,  0,  0,  9,114,101,116,118,
 97,108,117,101,  0,  4,  0,  0,  1, 12,  0,  0,  0, 17, 64,100,101, 99,108, 97,
114, 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0,133,  6,  1, 59,  1, 13,
 13,  0, 18,  1, 11,  2, 31, 52,112, 59,  1, 14, 15,  4, 13,  0, 18,  5,  2,  1,
  1, 59,  1, 15, 13,  1, 11,  6, 32, 52, 26, 59,  1, 16, 15,  7, 11,  8, 13,  1,
 42, 11,  9, 42, 13,  0, 18, 10, 42, 11, 11, 42,  2,  0,  1, 50, 60, 59,  1, 17,
 13,  1, 52, 26, 59,  1, 18, 15,  7, 11,  8, 13,  1, 42, 11, 12, 42, 13,  0, 18,
 10, 42, 11, 11, 42,  2,  0,  1, 50, 27, 59,  1, 20, 15,  7, 11, 13, 13,  0, 18,
 10, 42, 11, 14, 42, 13,  0, 18, 15, 11, 11,  2,  0,  3, 59,  1, 21,  5,  1, 50,
  3, 59,  1, 22, 59,  1, 23,  0,  0,  0,  0,  3,  0,  0,  1, 12,  0,  0,  0,  5,
115,101,108,102,  0,  0,  0,  1, 14,  0,  0,  0,  2,116,  0,  0,  0,  1, 21,  0,
  0,  0,  0,  0,  0,  0, 16,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,
  0,  4,114,101,116,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  2,116,  0,  2,
  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,  0,  5,116,121,112,
101,  0,  2,  0,  0,  0,  7,110,117,109, 98,101,114,  0,  2,  0,  0,  0,  7,111,
117,116,112,117,116,  0,  2,  0,  0,  0, 14, 32, 32, 32,116,111,108,117, 97, 95,
112,117,115,104,  0,  2,  0,  0,  0, 10, 40, 40,100,111,117, 98,108,101, 41,  0,
  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  3, 41, 59,  0,  2,  0,
  0,  0,  2, 40,  0,  2,  0,  0,  0, 30, 32, 32, 32,116,111,108,117, 97, 95,112,
117,115,104,117,115,101,114,116,121,112,101, 40, 40,118,111,105,100, 42, 41,  0,
  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  4,116, 97,103,  0,  2,  0,  0,  0,
 13, 95, 68,101, 99,108, 97,114, 97,116,105,111,110,  0,  4,  0,  0,  1, 26,  0,
  0,  0, 17, 64,100,101, 99,108, 97,114, 97,116,105,111,110, 46,108,117, 97,  0,
  0,  0,  0,136,  8,  1, 59,  1, 27, 13,  0, 18,  1, 48,  7, 13,  0, 18,  1, 11,
  2, 31, 52, 60, 59,  1, 28, 15,  4, 13,  0, 18,  1, 11,  5,  2,  1,  2, 59,  1,
 29, 13,  0, 11,  1, 13,  1,  7,  1, 16, 26, 59,  1, 30, 13,  0, 11,  6, 15,  7,
 13,  1,  7,  2, 16, 46,  5, 13,  1,  7,  1, 16, 11,  8, 11,  2,  2,  1,  3, 26,
  5,  1, 50,  3, 59,  1, 31, 59,  1, 32, 13,  0, 11,  9, 15, 10, 26, 59,  1, 33,
 15, 11, 13,  0, 15, 12,  2,  0,  2, 59,  1, 34, 13,  0, 20, 13,  2,  0,  1, 59,
  1, 35, 13,  0, 20, 14,  2,  0,  1, 59,  1, 36, 13,  0,  1,  1, 59,  1, 37,  0,
  0,  0,  0,  3,  0,  0,  1, 26,  0,  0,  0,  2,116,  0,  0,  0,  1, 28,  0,  0,
  0,  2,110,  0,  0,  0,  1, 30,  0,  0,  0,  0,  0,  0,  0, 15,  2,  0,  0,  0,
  2,116,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  1,  0,  2,
  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  6,115,112,108,105,116,  0,  2,  0,  0,
  0,  2, 64,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,  5,
103,115,117, 98,  0,  2,  0,  0,  0,  7, 37, 91, 46, 45, 37, 93,  0,  2,  0,  0,
  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 17, 99,108, 97,115,115, 68,101,
 99,108, 97,114, 97,116,105,111,110,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,
103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,
  0, 10, 99,104,101, 99,107,110, 97,109,101,  0,  2,  0,  0,  0, 10, 99,104,101,
 99,107,116,121,112,101,  0,  2,  0,  0,  0, 12, 68,101, 99,108, 97,114, 97,116,
105,111,110,  0,  4,  0,  0,  1, 42,  0,  0,  0, 17, 64,100,101, 99,108, 97,114,
 97,116,105,111,110, 46,108,117, 97,  0,  0,  0,  3,164, 20,  2, 59,  1, 44, 15,
  2, 13,  0, 11,  3, 11,  4,  2,  1,  3, 23,  0, 59,  1, 46, 13,  1, 11,  5, 32,
 52, 44, 59,  1, 48, 13,  0, 11,  6, 32, 46,  5, 13,  0, 11,  7, 32, 52, 22, 59,
  1, 49, 15,  8, 22,  2, 11,  9, 11,  7, 11,  1, 13,  1, 30,  1,  3,  2,  1, 50,
  3, 59,  1, 50, 50,  3, 59,  1, 51, 59,  1, 54, 15, 11, 13,  0, 11, 12,  2,  1,
  2, 59,  1, 55, 13,  2, 18, 13,  7,  2, 32, 52,126, 59,  1, 56, 13,  1, 11, 14,
 32, 52, 15, 59,  1, 57, 15, 15, 11, 16, 13,  0, 42,  2,  0,  1, 50,  3, 59,  1,
 58, 59,  1, 59, 15, 11, 13,  2,  7,  1, 16, 11, 18,  2,  1,  2, 59,  1, 60, 15,
  8, 22,  6, 59,  1, 61, 11, 19, 13,  2,  7,  2, 16, 11, 20, 59,  1, 62, 11, 21,
 11, 22, 59,  1, 63, 11, 23, 11,  9, 59,  1, 64, 13,  3, 13,  3, 18, 13, 16, 11,
 24, 59,  1, 65, 15, 25, 13,  3,  7,  1, 13,  3, 18, 13,  7,  1, 38,  2,  1,  3,
 11,  1, 59,  1, 66, 13,  1, 30,  5, 59,  1, 67,  3,  4,  1,  5,  1, 50,  3, 59,
  1, 68, 59,  1, 71, 15, 11, 13,  0, 11, 26,  2,  1,  2, 23,  2, 59,  1, 72, 13,
  2, 18, 13,  7,  2, 32, 52,126, 59,  1, 73, 13,  1, 11, 14, 32, 52, 15, 59,  1,
 74, 15, 15, 11, 16, 13,  0, 42,  2,  0,  1, 50,  3, 59,  1, 75, 59,  1, 76, 15,
 11, 13,  2,  7,  1, 16, 11, 18,  2,  1,  2, 59,  1, 77, 15,  8, 22,  6, 59,  1,
 78, 11, 19, 13,  2,  7,  2, 16, 11, 20, 59,  1, 79, 11, 21, 11, 22, 59,  1, 80,
 11, 21, 11,  9, 59,  1, 81, 13,  3, 13,  3, 18, 13, 16, 11, 24, 59,  1, 82, 15,
 25, 13,  3,  7,  1, 13,  3, 18, 13,  7,  1, 38,  2,  1,  3, 11,  1, 59,  1, 83,
 13,  1, 30,  5, 59,  1, 84,  3,  4,  1,  5,  1, 50,  3, 59,  1, 85, 59,  1, 88,
 15, 11, 13,  0, 11, 23,  2,  1,  2, 23,  2, 59,  1, 89, 13,  2, 18, 13,  7,  2,
 32, 52, 91, 59,  1, 90, 15, 11, 13,  2,  7,  1, 16, 11, 18,  2,  1,  2, 59,  1,
 91, 15,  8, 22,  5, 59,  1, 92, 11, 19, 13,  2,  7,  2, 16, 11, 20, 59,  1, 93,
 11, 23, 11,  9, 59,  1, 94, 13,  3, 13,  3, 18, 13, 16, 11, 24, 59,  1, 95, 15,
 25, 13,  3,  7,  1, 13,  3, 18, 13,  7,  1, 38,  2,  1,  3, 11,  1, 59,  1, 96,
 13,  1, 30,  4, 59,  1, 97,  3,  4,  1,  5,  1, 50,  3, 59,  1, 98, 59,  1,101,
 15,  2, 13,  0, 11, 28, 11, 29,  2,  1,  3, 59,  1,102, 15, 11, 13,  3, 11, 30,
  2,  1,  2, 23,  2, 59,  1,103, 13,  2, 18, 31,  7,  2, 32, 52,113, 59,  1,104,
 13,  2,  7,  2, 15, 32, 13,  2,  7,  2, 16, 11, 33, 11, 30,  2,  1,  3, 26, 59,
  1,105, 15, 11, 13,  2,  7,  1, 16, 11, 18,  2,  1,  2, 59,  1,106, 15,  8, 22,
  5, 59,  1,107, 11, 19, 13,  2,  7,  2, 16, 11, 20, 59,  1,108, 11, 21, 11,  9,
 59,  1,109, 13,  4, 13,  4, 18, 31, 16, 11, 24, 59,  1,110, 15, 25, 13,  4,  7,
  1, 13,  4, 18, 31,  7,  1, 38,  2,  1,  3, 11,  1, 59,  1,111, 13,  1, 30,  4,
 59,  1,112,  3,  5,  1,  5,  1, 50,  3, 59,  1,113, 59,  1,115, 13,  1, 11,  5,
 32, 52,129, 59,  1,117, 15, 11, 13,  0, 11, 18,  2,  1,  2, 23,  2, 59,  1,118,
  4,  0, 59,  1,119, 15, 35, 13,  2, 13,  2, 18, 31, 16,  2,  1,  1, 52,  6, 11,
  6, 23,  4, 50, 21, 13,  2, 13,  2, 18, 31, 16, 23,  4, 13,  2, 11, 31, 13,  2,
 18, 31,  7,  1, 38, 26, 59,  1,120, 15,  8, 22,  4, 59,  1,121, 11, 19, 13,  4,
 11,  9, 59,  1,122, 13,  2, 13,  2, 18, 31, 16, 11, 24, 59,  1,123, 15, 25, 13,
  2,  7,  1, 13,  2, 18, 31,  7,  1, 38,  2,  1,  3, 11,  1, 59,  1,124, 13,  1,
 30,  3, 59,  1,125,  3,  5,  1,  5,  1, 50,130, 59,  1,130, 15, 11, 13,  0, 11,
 18,  2,  1,  2, 23,  2, 59,  1,131, 13,  2, 13,  2, 18, 31, 16, 59,  1,132,  4,
  1, 59,  1,133, 13,  2, 18, 31,  7,  1, 35, 52, 38, 59,  1,134, 13,  2, 13,  2,
 18, 31,  7,  1, 38, 16, 23,  5, 59,  1,135, 15, 25, 13,  2,  7,  1, 13,  2, 18,
 31,  7,  2, 38,  2,  1,  3, 23,  6, 50,  3, 59,  1,136, 59,  1,137, 15,  8, 22,
  4, 59,  1,138, 11, 19, 13,  4, 11,  9, 59,  1,139, 13,  5, 11, 24, 59,  1,140,
 13,  6, 11,  1, 59,  1,141, 13,  1, 30,  3, 59,  1,142,  3,  7,  1,  5,  3, 59,
  1,143, 59,  1,145,  0,  0,  0,  0, 20,  0,  0,  1, 42,  0,  0,  0,  2,115,  0,
  0,  0,  1, 42,  0,  0,  0,  5,107,105,110,100,  0,  0,  0,  1, 54,  0,  0,  0,
  2,116,  0,  0,  0,  1, 59,  0,  0,  0,  2,109,  0,  0,  0,  1, 67,  0,  0,  0,
  0,  0,  0,  1, 76,  0,  0,  0,  2,109,  0,  0,  0,  1, 84,  0,  0,  0,  0,  0,
  0,  1, 90,  0,  0,  0,  2,109,  0,  0,  0,  1, 97,  0,  0,  0,  0,  0,  0,  1,
101,  0,  0,  0,  3,115, 49,  0,  0,  0,  1,105,  0,  0,  0,  2,109,  0,  0,  0,
  1,112,  0,  0,  0,  0,  0,  0,  1,118,  0,  0,  0,  2,118,  0,  0,  0,  1,125,
  0,  0,  0,  0,  0,  0,  1,131,  0,  0,  0,  2,118,  0,  0,  0,  1,132,  0,  0,
  0,  3,116,112,  0,  0,  0,  1,132,  0,  0,  0,  3,109,100,  0,  0,  0,  1,142,
  0,  0,  0,  0,  0,  0,  1,142,  0,  0,  0,  0,  0,  0,  1,142,  0,  0,  0,  0,
  0,  0,  0, 38,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0,  5,107,105,110,100,
  0,  2,  0,  0,  0,  5,103,115,117, 98,  0,  2,  0,  0,  0,  8, 37,115, 42, 61,
 37,115, 42,  0,  2,  0,  0,  0,  2, 61,  0,  2,  0,  0,  0,  4,118, 97,114,  0,
  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  5,118,111,105,100,  0,  2,  0,  0,  0,
 13, 95, 68,101, 99,108, 97,114, 97,116,105,111,110,  0,  2,  0,  0,  0,  5,116,
121,112,101,  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6,115,112,108,105,
116,  0,  2,  0,  0,  0,  7, 37, 42, 37,115, 42, 38,  0,  2,  0,  0,  0,  2,110,
  0,  2,  0,  0,  0,  5,102,117,110, 99,  0,  2,  0,  0,  0,  6,101,114,114,111,
114,  0,  2,  0,  0,  0, 32, 35,105,110,118, 97,108,105,100, 32,102,117,110, 99,
116,105,111,110, 32,114,101,116,117,114,110, 32,116,121,112,101, 58, 32,  0,  2,
  0,  0,  0,  2,109,  0,  2,  0,  0,  0,  6, 37,115, 37,115, 42,  0,  2,  0,  0,
  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0,
  2, 42,  0,  2,  0,  0,  0,  4,114,101,116,  0,  2,  0,  0,  0,  2, 38,  0,  2,
  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  7, 99,111,110, 99, 97,116,  0,
  2,  0,  0,  0,  8, 37, 42, 37,115, 42, 37, 42,  0,  2,  0,  0,  0,  3,115, 49,
  0,  2,  0,  0,  0,  7, 40, 37, 98, 91, 93, 41,  0,  4,  0,  0,  1,101,  0,  0,
  0, 17, 64,100,101, 99,108, 97,114, 97,116,105,111,110, 46,108,117, 97,  0,  0,
  0,  0, 17,  5,  1, 59,  1,101, 15,  1, 13,  0, 11,  2, 11,  3,  3,  1,  3,  0,
  0,  0,  0,  1,  0,  0,  1,101,  0,  0,  0,  2,110,  0,  0,  0,  0,  4,  2,  0,
  0,  0,  2,110,  0,  2,  0,  0,  0,  5,103,115,117, 98,  0,  2,  0,  0,  0,  3,
 37, 42,  0,  2,  0,  0,  0,  2,  1,  0,  2,  0,  0,  0,  3, 37, 42,  0,  2,  0,
  0,  0,  2,110,  0,  2,  0,  0,  0,  5,103,115,117, 98,  0,  2,  0,  0,  0,  2,
  1,  0,  2,  0,  0,  0,  2,118,  0,  2,  0,  0,  0,  7,105,115,116,121,112,101,
  0,  2,  0,  0,  0,  3,116,112,  0,  2,  0,  0,  0,  3,109,100,  0,
};

/* container.lo */
static char B4[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 15, 64, 99,111,110,116, 97,
105,110,101,114, 46,108,117, 97,  0,  0,  0,  0,162,  5,  0, 60, 17, 60, 18, 22,
  2, 60, 19, 11,  1,  4,  0, 11,  2, 60, 20, 15,  3, 30,  1, 60, 21, 25,  0, 60,
 22, 15,  4, 15,  0, 15,  5,  2,  0,  2, 60, 25, 15,  0, 11,  6, 11,  7, 26, 60,
 36, 15,  0, 11,  8, 11,  9, 26, 60, 48, 11, 11, 25, 10, 60, 58, 11, 13, 25, 12,
 60, 63, 11, 15, 25, 14, 60, 68, 11, 17, 25, 16, 60, 73, 11, 19, 25, 18, 60, 78,
 11, 21, 25, 20, 60, 83, 11, 23, 25, 22, 60, 88, 15, 24, 11, 25, 11, 26, 26, 60,
 95, 15, 24, 11, 27, 11, 28, 26, 60,101, 15, 24, 11, 29, 11, 30, 26, 60,110, 15,
 24, 11, 31, 11, 32, 26, 60,129, 15, 24, 11, 33, 11, 34, 26, 60,147, 15, 24, 11,
 35, 11, 36, 26, 59,  1, 49, 15, 24, 11, 37, 11, 38, 26,  0,  0,  0,  0,  0,  0,
  0,  0, 39,  2,  0,  0,  0, 15, 99,108, 97,115,115, 67,111,110,116, 97,105,110,
101,114,  0,  2,  0,  0,  0,  5, 99,117,114,114,  0,  2,  0,  0,  0,  6, 95, 98,
 97,115,101,  0,  2,  0,  0,  0, 13, 99,108, 97,115,115, 70,101, 97,116,117,114,
101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,
111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  8,100,101, 99,108,116, 97,
103,  0,  4,  0,  0,  0, 25,  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,101,
114, 46,108,117, 97,  0,  0,  0,  0, 59,  4,  1, 60, 26, 15,  0, 13,  0,  2,  0,
  1, 60, 27,  7,  1, 50, 23, 60, 29, 13,  0, 13,  1, 16, 20,  3,  2,  0,  1, 60,
 30, 13,  1,  7,  1, 37, 23,  1, 60, 31, 60, 28, 13,  0, 13,  1, 16, 54, 32, 60,
 32, 15,  4,  2,  0,  0, 60, 33,  0,  0,  0,  0,  2,  0,  0,  0, 25,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0, 27,  0,  0,  0,  2,105,  0,  0,  0,  0,  5,
  2,  0,  0,  0,  5,112,117,115,104,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,
  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  8,100,101, 99,108,116, 97,103,  0,
  2,  0,  0,  0,  4,112,111,112,  0,  2,  0,  0,  0,  8,115,117,112, 99,111,100,
101,  0,  4,  0,  0,  0, 36,  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,101,
114, 46,108,117, 97,  0,  0,  0,  0, 59,  4,  1, 60, 37, 15,  0, 13,  0,  2,  0,
  1, 60, 38,  7,  1, 50, 23, 60, 40, 13,  0, 13,  1, 16, 20,  3,  2,  0,  1, 60,
 41, 13,  1,  7,  1, 37, 23,  1, 60, 42, 60, 39, 13,  0, 13,  1, 16, 54, 32, 60,
 43, 15,  4,  2,  0,  0, 60, 44,  0,  0,  0,  0,  2,  0,  0,  0, 36,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0, 38,  0,  0,  0,  2,105,  0,  0,  0,  0,  5,
  2,  0,  0,  0,  5,112,117,115,104,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,
  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  8,115,117,112, 99,111,100,101,  0,
  2,  0,  0,  0,  4,112,111,112,  0,  2,  0,  0,  0, 11, 95, 67,111,110,116, 97,
105,110,101,114,  0,  4,  0,  0,  0, 48,  0,  0,  0, 15, 64, 99,111,110,116, 97,
105,110,101,114, 46,108,117, 97,  0,  0,  0,  0, 64,  6,  1, 60, 49, 13,  0, 11,
  1, 15,  2, 26, 60, 50, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60, 51, 13,  0, 11,
  5,  7,  0, 26, 60, 52, 13,  0, 11,  6, 22,  1, 11,  5,  7,  0, 30,  0, 26, 60,
 53, 13,  0, 11,  7, 22,  0, 26, 60, 54, 13,  0,  1,  1, 60, 55,  0,  0,  0,  0,
  1,  0,  0,  0, 48,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  8,  2,  0,
  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,
  0,  0,  0, 15, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114,  0,  2,
  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117,
 97, 95,116, 97,103,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  9,116,121,
112,101,100,101,102,115,  0,  2,  0,  0,  0,  7,108,110, 97,109,101,115,  0,  2,
  0,  0,  0,  5,112,117,115,104,  0,  4,  0,  0,  0, 58,  0,  0,  0, 15, 64, 99,
111,110,116, 97,105,110,101,114, 46,108,117, 97,  0,  0,  0,  0, 14,  4,  1, 60,
 59, 15,  1, 11,  2, 13,  0, 26, 60, 60,  0,  0,  0,  0,  1,  0,  0,  0, 58,  0,
  0,  0,  2,116,  0,  0,  0,  0,  3,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,
 15, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,
  5, 99,117,114,114,  0,  2,  0,  0,  0,  4,112,111,112,  0,  4,  0,  0,  0, 63,
  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,101,114, 46,108,117, 97,  0,  0,
  0,  0, 18,  3,  0, 60, 64, 15,  0, 11,  1, 15,  0, 18,  1, 18,  2, 26, 60, 65,
  0,  0,  0,  0,  0,  0,  0,  0,  3,  2,  0,  0,  0, 15, 99,108, 97,115,115, 67,
111,110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,  5, 99,117,114,114,  0,  2,
  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,  0,  0,  0,  7, 97,112,112,101,
110,100,  0,  4,  0,  0,  0, 68,  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,
101,114, 46,108,117, 97,  0,  0,  0,  0, 18,  4,  1, 60, 69, 15,  1, 18,  2, 20,
  3, 13,  0,  3,  1,  2, 60, 70,  0,  0,  0,  0,  1,  0,  0,  0, 68,  0,  0,  0,
  2,116,  0,  0,  0,  0,  4,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0, 15, 99,
108, 97,115,115, 67,111,110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,  5, 99,
117,114,114,  0,  2,  0,  0,  0,  7, 97,112,112,101,110,100,  0,  2,  0,  0,  0,
 14, 97,112,112,101,110,100,116,121,112,101,100,101,102,  0,  4,  0,  0,  0, 73,
  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,101,114, 46,108,117, 97,  0,  0,
  0,  0, 18,  4,  1, 60, 74, 15,  1, 18,  2, 20,  3, 13,  0,  3,  1,  2, 60, 75,
  0,  0,  0,  0,  1,  0,  0,  0, 73,  0,  0,  0,  2,116,  0,  0,  0,  0,  4,  2,
  0,  0,  0,  2,116,  0,  2,  0,  0,  0, 15, 99,108, 97,115,115, 67,111,110,116,
 97,105,110,101,114,  0,  2,  0,  0,  0,  5, 99,117,114,114,  0,  2,  0,  0,  0,
 14, 97,112,112,101,110,100,116,121,112,101,100,101,102,  0,  2,  0,  0,  0, 12,
102,105,110,100,116,121,112,101,100,101,102,  0,  4,  0,  0,  0, 78,  0,  0,  0,
 15, 64, 99,111,110,116, 97,105,110,101,114, 46,108,117, 97,  0,  0,  0,  0, 18,
  4,  1, 60, 79, 15,  1, 18,  2, 20,  3, 13,  0,  3,  1,  2, 60, 80,  0,  0,  0,
  0,  1,  0,  0,  0, 78,  0,  0,  0,  5,116,121,112,101,  0,  0,  0,  0,  4,  2,
  0,  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0, 15, 99,108, 97,115,115, 67,
111,110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,  5, 99,117,114,114,  0,  2,
  0,  0,  0, 12,102,105,110,100,116,121,112,101,100,101,102,  0,  2,  0,  0,  0,
 10,105,115,116,121,112,101,100,101,102,  0,  4,  0,  0,  0, 83,  0,  0,  0, 15,
 64, 99,111,110,116, 97,105,110,101,114, 46,108,117, 97,  0,  0,  0,  0, 18,  4,
  1, 60, 84, 15,  1, 18,  2, 20,  3, 13,  0,  3,  1,  2, 60, 85,  0,  0,  0,  0,
  1,  0,  0,  0, 83,  0,  0,  0,  5,116,121,112,101,  0,  0,  0,  0,  4,  2,  0,
  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0, 15, 99,108, 97,115,115, 67,111,
110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,  5, 99,117,114,114,  0,  2,  0,
  0,  0, 10,105,115,116,121,112,101,100,101,102,  0,  2,  0,  0,  0, 15, 99,108,
 97,115,115, 67,111,110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,  7, 97,112,
112,101,110,100,  0,  4,  0,  0,  0, 88,  0,  0,  0, 15, 64, 99,111,110,116, 97,
105,110,101,114, 46,108,117, 97,  0,  0,  0,  0, 39,  6,  2, 60, 89, 13,  0, 11,
  2, 13,  0, 18,  2,  7,  1, 37, 26, 60, 90, 13,  0, 13,  0, 18,  2, 13,  1, 26,
 60, 91, 13,  1, 11,  3, 13,  0, 26, 60, 92,  0,  0,  0,  0,  2,  0,  0,  0, 88,
  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 88,  0,  0,  0,  2,116,  0,  0,
  0,  0,  4,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,
  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,
  0,  0,  0, 14, 97,112,112,101,110,100,116,121,112,101,100,101,102,  0,  4,  0,
  0,  0, 95,  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,101,114, 46,108,117,
 97,  0,  0,  0,  0, 38,  6,  2, 60, 96, 13,  0, 18,  2, 11,  3, 13,  0, 18,  2,
 18,  3,  7,  1, 37, 26, 60, 97, 13,  0, 18,  2, 13,  0, 18,  2, 18,  3, 13,  1,
 26, 60, 98,  0,  0,  0,  0,  2,  0,  0,  0, 95,  0,  0,  0,  5,115,101,108,102,
  0,  0,  0,  0, 95,  0,  0,  0,  2,116,  0,  0,  0,  0,  4,  2,  0,  0,  0,  2,
116,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  9,116,121,112,
101,100,101,102,115,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  9,111,118,
101,114,108,111, 97,100,  0,  4,  0,  0,  0,101,  0,  0,  0, 15, 64, 99,111,110,
116, 97,105,110,101,114, 46,108,117, 97,  0,  0,  0,  0, 67,  6,  2, 60,102, 13,
  0, 18,  2, 13,  1, 16, 44, 52, 13, 60,103, 13,  0, 18,  2, 13,  1,  7,  0, 26,
 50, 21, 60,105, 13,  0, 18,  2, 13,  1, 13,  0, 18,  2, 13,  1, 16,  7,  1, 37,
 26, 60,106, 60,107, 15,  3, 11,  4, 13,  0, 18,  2, 13,  1, 16,  3,  2,  2, 60,
108,  0,  0,  0,  0,  2,  0,  0,  0,101,  0,  0,  0,  5,115,101,108,102,  0,  0,
  0,  0,101,  0,  0,  0,  6,108,110, 97,109,101,  0,  0,  0,  0,  5,  2,  0,  0,
  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,
  0,  0,  7,108,110, 97,109,101,115,  0,  2,  0,  0,  0,  7,102,111,114,109, 97,
116,  0,  2,  0,  0,  0,  5, 37, 48, 50,100,  0,  2,  0,  0,  0, 12,102,105,110,
100,116,121,112,101,100,101,102,  0,  4,  0,  0,  0,110,  0,  0,  0, 15, 64, 99,
111,110,116, 97,105,110,101,114, 46,108,117, 97,  0,  0,  0,  0,142, 10,  2, 60,
111, 13,  0, 50,117, 60,113, 13,  2, 18,  3, 52, 97, 60,114,  7,  1, 50, 76, 60,
116, 13,  2, 18,  3, 13,  3, 16, 18,  5, 13,  1, 32, 52, 47, 60,117, 13,  2, 18,
  3, 13,  3, 16, 18,  8, 13,  2, 18,  3, 13,  3, 16, 18,  0, 60,118, 15, 11, 13,
  5,  2,  2,  1, 60,119, 13,  6, 11, 12, 42, 13,  4, 42, 13,  7,  1,  8,  5,  4,
 50,  2, 60,120, 60,121, 13,  3,  7,  1, 37, 23,  3, 60,122, 60,115, 13,  2, 18,
  3, 13,  3, 16, 54, 87,  5,  1, 50,  2, 60,123, 60,124, 13,  2, 18, 13, 23,  2,
 60,125, 60,112, 13,  2, 54,123, 60,126, 11, 14, 13,  1,  1,  3, 60,127,  0,  0,
  0,  0, 13,  0,  0,  0,110,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,110,
  0,  0,  0,  5,116,121,112,101,  0,  0,  0,  0,111,  0,  0,  0,  4,101,110,118,
  0,  0,  0,  0,114,  0,  0,  0,  2,105,  0,  0,  0,  0,117,  0,  0,  0,  5,109,
111,100, 49,  0,  0,  0,  0,117,  0,  0,  0,  6,116,121,112,101, 49,  0,  0,  0,
  0,118,  0,  0,  0,  5,109,111,100, 50,  0,  0,  0,  0,118,  0,  0,  0,  6,116,
121,112,101, 50,  0,  0,  0,  0,119,  0,  0,  0,  0,  0,  0,  0,119,  0,  0,  0,
  0,  0,  0,  0,119,  0,  0,  0,  0,  0,  0,  0,119,  0,  0,  0,  0,  0,  0,  0,
122,  0,  0,  0,  0,  0,  0,  0, 15,  2,  0,  0,  0,  5,116,121,112,101,  0,  2,
  0,  0,  0,  4,101,110,118,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,
  0,  0,  9,116,121,112,101,100,101,102,115,  0,  2,  0,  0,  0,  2,105,  0,  2,
  0,  0,  0,  6,117,116,121,112,101,  0,  2,  0,  0,  0,  5,109,111,100, 49,  0,
  2,  0,  0,  0,  6,116,121,112,101, 49,  0,  2,  0,  0,  0,  4,109,111,100,  0,
  2,  0,  0,  0,  5,109,111,100, 50,  0,  2,  0,  0,  0,  6,116,121,112,101, 50,
  0,  2,  0,  0,  0, 12,102,105,110,100,116,121,112,101,100,101,102,  0,  2,  0,
  0,  0,  2, 32,  0,  2,  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,  0,  0,
  0,  1,  0,  2,  0,  0,  0, 10,105,115,116,121,112,101,100,101,102,  0,  4,  0,
  0,  0,129,  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,101,114, 46,108,117,
 97,  0,  0,  0,  0,101,  6,  2, 60,130, 13,  0, 50, 78, 60,132, 13,  2, 18,  3,
 52, 58, 60,133,  7,  1, 50, 37, 60,135, 13,  2, 18,  3, 13,  3, 16, 18,  5, 13,
  1, 32, 52,  8, 60,136,  7,  1,  1,  4, 50,  2, 60,137, 60,138, 13,  3,  7,  1,
 37, 23,  3, 60,139, 60,134, 13,  2, 18,  3, 13,  3, 16, 54, 48,  5,  1, 50,  2,
 60,140, 60,141, 13,  2, 18,  6, 23,  2, 60,142, 60,131, 13,  2, 54, 84, 60,143,
  4,  0,  1,  3, 60,144,  0,  0,  0,  0,  5,  0,  0,  0,129,  0,  0,  0,  5,115,
101,108,102,  0,  0,  0,  0,129,  0,  0,  0,  5,116,121,112,101,  0,  0,  0,  0,
130,  0,  0,  0,  4,101,110,118,  0,  0,  0,  0,133,  0,  0,  0,  2,105,  0,  0,
  0,  0,139,  0,  0,  0,  0,  0,  0,  0,  7,  2,  0,  0,  0,  5,116,121,112,101,
  0,  2,  0,  0,  0,  4,101,110,118,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,
  2,  0,  0,  0,  9,116,121,112,101,100,101,102,115,  0,  2,  0,  0,  0,  2,105,
  0,  2,  0,  0,  0,  6,117,116,121,112,101,  0,  2,  0,  0,  0,  7,112, 97,114,
101,110,116,  0,  2,  0,  0,  0,  8,100,111,112, 97,114,115,101,  0,  4,  0,  0,
  0,147,  0,  0,  0, 15, 64, 99,111,110,116, 97,105,110,101,114, 46,108,117, 97,
  0,  0,  0,  4, 55, 13,  2, 60,151, 15,  5, 13,  1, 11,  6,  2,  4,  2, 60,152,
 13,  2, 52, 42, 60,153, 15,  8, 13,  1, 13,  2, 13,  3,  2,  1,  3, 25,  7, 60,
154, 15,  9, 13,  4, 13,  5,  2,  0,  2, 60,155, 15,  8, 13,  1, 13,  3,  7,  1,
 37,  3,  6,  2, 50,  2, 60,156,  5,  4, 60,157, 60,161, 15,  5, 13,  1, 11, 10,
  2,  3,  2, 60,162, 13,  2, 52, 40, 60,163, 15,  8, 13,  1, 13,  2, 13,  3,  2,
  1,  3, 25,  7, 60,164, 15, 11, 13,  4,  2,  0,  1, 60,165, 15,  8, 13,  1, 13,
  3,  7,  1, 37,  3,  5,  2, 50,  2, 60,166,  5,  3, 60,167, 60,171, 15,  5, 13,
  1, 11, 12,  2,  3,  2, 60,172, 13,  2, 52, 40, 60,173, 15,  8, 13,  1, 13,  2,
 13,  3,  2,  1,  3, 25,  7, 60,174, 15, 13, 13,  4,  2,  0,  1, 60,175, 15,  8,
 13,  1, 13,  3,  7,  1, 37,  3,  5,  2, 50,  2, 60,176,  5,  3, 60,177, 60,180,
 15,  5, 13,  1, 11, 14,  2,  4,  2, 60,181, 13,  2, 52, 52, 60,182, 15,  8, 13,
  1, 13,  2, 13,  3,  2,  1,  3, 25,  7, 60,183, 15, 13, 13,  4,  2,  0,  1, 60,
184, 15, 15, 11, 16, 13,  5, 42,  2,  0,  1, 60,185, 15,  8, 13,  1, 13,  3,  7,
  1, 37,  3,  6,  2, 50,  2, 60,186,  5,  4, 60,187, 60,191, 15,  5, 13,  1, 11,
 21,  2,  6,  2, 60,192, 13,  2, 52, 46, 60,193, 15,  8, 13,  1, 13,  2, 13,  3,
  2,  1,  3, 25,  7, 60,194, 15, 22, 13,  4, 13,  5, 13,  6, 13,  7,  2,  0,  4,
 60,195, 15,  8, 13,  1, 13,  3,  7,  1, 37,  3,  8,  2, 50,  2, 60,196,  5,  6,
 60,197, 60,201, 15,  5, 13,  1, 11, 23,  2,  5,  2, 60,202, 13,  2, 44, 52, 23,
 60,204, 15,  5, 13,  1, 11, 24,  2,  5,  2, 23,  6, 23,  5, 23,  4, 23,  3, 23,
  2, 50,  2, 60,205, 60,206, 13,  2, 52, 44, 60,207, 15,  8, 13,  1, 13,  2, 13,
  3,  2,  1,  3, 25,  7, 60,208, 15, 25, 13,  4, 13,  5, 13,  6,  2,  0,  3, 60,
209, 15,  8, 13,  1, 13,  3,  7,  1, 37,  3,  7,  2, 50,  2, 60,210,  5,  5, 60,
211, 60,215, 15,  5, 13,  1, 11, 26,  2,  5,  2, 60,216, 13,  2, 44, 52, 23, 60,
218, 15,  5, 13,  1, 11, 27,  2,  5,  2, 23,  6, 23,  5, 23,  4, 23,  3, 23,  2,
 50,  2, 60,219, 60,220, 13,  2, 52, 44, 60,221, 15,  8, 13,  1, 13,  2, 13,  3,
  2,  1,  3, 25,  7, 60,222, 15, 25, 13,  4, 13,  5, 13,  6,  2,  0,  3, 60,223,
 15,  8, 13,  1, 13,  3,  7,  1, 37,  3,  7,  2, 50,  2, 60,224,  5,  5, 60,225,
 60,229, 15,  5, 13,  1, 11, 29,  2,  5,  2, 60,230, 13,  2, 44, 52, 59, 60,231,
 15,  5, 13,  1, 11, 30,  2,  5,  2, 23,  6, 23,  5, 23,  4, 23,  3, 23,  2, 60,
232, 13,  2, 44, 52, 27, 60,233, 11, 31, 23,  5, 60,234, 15,  5, 13,  1, 11, 32,
  2,  4,  2, 23,  4, 23,  6, 23,  3, 23,  2, 50,  2, 60,235, 50,  2, 60,236, 60,
237, 13,  2, 52, 80, 60,238, 13,  5, 11, 31, 31, 52, 25, 60,239,  4,  1, 60,240,
 15,  5, 13,  5, 11, 33,  2,  3,  2, 23,  5, 23,  8, 23,  7,  5,  2, 50,  2, 60,
241, 60,242, 15,  8, 13,  1, 13,  2, 13,  3,  2,  1,  3, 25,  7, 60,243, 15, 34,
 13,  4, 13,  5, 13,  6,  2,  0,  3, 60,244, 15,  8, 13,  1, 13,  3,  7,  1, 37,
  3,  7,  2, 50,  2, 60,245,  5,  5, 60,246, 60,250, 15,  5, 13,  1, 11, 36,  2,
  3,  2, 60,251, 13,  2, 52, 40, 60,252, 15,  8, 13,  1, 13,  2, 13,  3,  2,  1,
  3, 25,  7, 60,253, 15, 15, 13,  4,  2,  0,  1, 60,254, 15,  8, 13,  1, 13,  3,
  7,  1, 37,  3,  5,  2, 50,  2, 60,255,  5,  3, 59,  1,  0, 59,  1,  4, 15,  5,
 13,  1, 11, 37,  2,  3,  2, 59,  1,  5, 13,  2, 52, 43, 59,  1,  6, 15,  8, 13,
  1, 13,  2, 13,  3,  2,  1,  3, 25,  7, 59,  1,  7, 15, 38, 13,  4,  2,  0,  1,
 59,  1,  8, 15,  8, 13,  1, 13,  3,  7,  1, 37,  3,  5,  2, 50,  3, 59,  1,  9,
  5,  3, 59,  1, 10, 59,  1, 14, 15,  5, 13,  1, 11, 39,  2,  3,  2, 59,  1, 15,
 13,  2, 52, 43, 59,  1, 16, 15,  8, 13,  1, 13,  2, 13,  3,  2,  1,  3, 25,  7,
 59,  1, 17, 15, 40, 13,  4,  2,  0,  1, 59,  1, 18, 15,  8, 13,  1, 13,  3,  7,
  1, 37,  3,  5,  2, 50,  3, 59,  1, 19,  5,  3, 59,  1, 20, 59,  1, 24, 15,  5,
 13,  1, 11, 42,  2,  3,  2, 59,  1, 25, 13,  2, 52, 36, 59,  1, 26, 15, 43, 15,
  8, 13,  4,  7,  2,  9,  2,  2,  1,  3,  2,  0,  1, 59,  1, 27, 15,  8, 13,  1,
 13,  3,  7,  1, 37,  3,  5,  2, 50,  3, 59,  1, 28,  5,  3, 59,  1, 29, 59,  1,
 33, 15,  5, 13,  1, 11, 45,  2,  3,  2, 59,  1, 34, 13,  2, 52, 27, 59,  1, 35,
 15, 46, 13,  4,  2,  0,  1, 59,  1, 36, 15,  8, 13,  1, 13,  3,  7,  1, 37,  3,
  5,  2, 50,  3, 59,  1, 37,  5,  3, 59,  1, 38, 59,  1, 41, 15, 47, 13,  1, 11,
 48, 11, 31,  2,  1,  3, 11, 31, 31, 52, 19, 59,  1, 42, 13,  1, 25,  7, 59,  1,
 43, 15, 49, 11, 50,  2,  0,  1, 50, 10, 59,  1, 45, 11, 31,  1,  2, 59,  1, 46,
 59,  1, 47,  0,  0,  0,  0,106,  0,  0,  0,147,  0,  0,  0,  5,115,101,108,102,
  0,  0,  0,  0,147,  0,  0,  0,  2,115,  0,  0,  0,  0,151,  0,  0,  0,  2, 98,
  0,  0,  0,  0,151,  0,  0,  0,  2,101,  0,  0,  0,  0,151,  0,  0,  0,  5,110,
 97,109,101,  0,  0,  0,  0,151,  0,  0,  0,  5, 98,111,100,121,  0,  0,  0,  0,
156,  0,  0,  0,  0,  0,  0,  0,156,  0,  0,  0,  0,  0,  0,  0,156,  0,  0,  0,
  0,  0,  0,  0,156,  0,  0,  0,  0,  0,  0,  0,161,  0,  0,  0,  2, 98,  0,  0,
  0,  0,161,  0,  0,  0,  2,101,  0,  0,  0,  0,161,  0,  0,  0,  5,110, 97,109,
101,  0,  0,  0,  0,166,  0,  0,  0,  0,  0,  0,  0,166,  0,  0,  0,  0,  0,  0,
  0,166,  0,  0,  0,  0,  0,  0,  0,171,  0,  0,  0,  2, 98,  0,  0,  0,  0,171,
  0,  0,  0,  2,101,  0,  0,  0,  0,171,  0,  0,  0,  5, 98,111,100,121,  0,  0,
  0,  0,176,  0,  0,  0,  0,  0,  0,  0,176,  0,  0,  0,  0,  0,  0,  0,176,  0,
  0,  0,  0,  0,  0,  0,180,  0,  0,  0,  2, 98,  0,  0,  0,  0,180,  0,  0,  0,
  2,101,  0,  0,  0,  0,180,  0,  0,  0,  5, 98,111,100,121,  0,  0,  0,  0,180,
  0,  0,  0,  5,110, 97,109,101,  0,  0,  0,  0,186,  0,  0,  0,  0,  0,  0,  0,
186,  0,  0,  0,  0,  0,  0,  0,186,  0,  0,  0,  0,  0,  0,  0,186,  0,  0,  0,
  0,  0,  0,  0,191,  0,  0,  0,  2, 98,  0,  0,  0,  0,191,  0,  0,  0,  2,101,
  0,  0,  0,  0,191,  0,  0,  0,  5,100,101, 99,108,  0,  0,  0,  0,191,  0,  0,
  0,  5,107,105,110,100,  0,  0,  0,  0,191,  0,  0,  0,  4, 97,114,103,  0,  0,
  0,  0,191,  0,  0,  0,  6, 99,111,110,115,116,  0,  0,  0,  0,196,  0,  0,  0,
  0,  0,  0,  0,196,  0,  0,  0,  0,  0,  0,  0,196,  0,  0,  0,  0,  0,  0,  0,
196,  0,  0,  0,  0,  0,  0,  0,196,  0,  0,  0,  0,  0,  0,  0,196,  0,  0,  0,
  0,  0,  0,  0,201,  0,  0,  0,  2, 98,  0,  0,  0,  0,201,  0,  0,  0,  2,101,
  0,  0,  0,  0,201,  0,  0,  0,  5,100,101, 99,108,  0,  0,  0,  0,201,  0,  0,
  0,  4, 97,114,103,  0,  0,  0,  0,201,  0,  0,  0,  6, 99,111,110,115,116,  0,
  0,  0,  0,210,  0,  0,  0,  0,  0,  0,  0,210,  0,  0,  0,  0,  0,  0,  0,210,
  0,  0,  0,  0,  0,  0,  0,210,  0,  0,  0,  0,  0,  0,  0,210,  0,  0,  0,  0,
  0,  0,  0,215,  0,  0,  0,  2, 98,  0,  0,  0,  0,215,  0,  0,  0,  2,101,  0,
  0,  0,  0,215,  0,  0,  0,  5,100,101, 99,108,  0,  0,  0,  0,215,  0,  0,  0,
  4, 97,114,103,  0,  0,  0,  0,215,  0,  0,  0,  6, 99,111,110,115,116,  0,  0,
  0,  0,224,  0,  0,  0,  0,  0,  0,  0,224,  0,  0,  0,  0,  0,  0,  0,224,  0,
  0,  0,  0,  0,  0,  0,224,  0,  0,  0,  0,  0,  0,  0,224,  0,  0,  0,  0,  0,
  0,  0,229,  0,  0,  0,  2, 98,  0,  0,  0,  0,229,  0,  0,  0,  2,101,  0,  0,
  0,  0,229,  0,  0,  0,  5,110, 97,109,101,  0,  0,  0,  0,229,  0,  0,  0,  5,
 98, 97,115,101,  0,  0,  0,  0,229,  0,  0,  0,  5, 98,111,100,121,  0,  0,  0,
  0,239,  0,  0,  0,  2, 98,  0,  0,  0,  0,239,  0,  0,  0,  2,101,  0,  0,  0,
  0,240,  0,  0,  0,  0,  0,  0,  0,240,  0,  0,  0,  0,  0,  0,  0,245,  0,  0,
  0,  0,  0,  0,  0,245,  0,  0,  0,  0,  0,  0,  0,245,  0,  0,  0,  0,  0,  0,
  0,245,  0,  0,  0,  0,  0,  0,  0,245,  0,  0,  0,  0,  0,  0,  0,250,  0,  0,
  0,  2, 98,  0,  0,  0,  0,250,  0,  0,  0,  2,101,  0,  0,  0,  0,250,  0,  0,
  0,  6,116,121,112,101,115,  0,  0,  0,  0,255,  0,  0,  0,  0,  0,  0,  0,255,
  0,  0,  0,  0,  0,  0,  0,255,  0,  0,  0,  0,  0,  0,  1,  4,  0,  0,  0,  2,
 98,  0,  0,  0,  1,  4,  0,  0,  0,  2,101,  0,  0,  0,  1,  4,  0,  0,  0,  5,
100,101, 99,108,  0,  0,  0,  1,  9,  0,  0,  0,  0,  0,  0,  1,  9,  0,  0,  0,
  0,  0,  0,  1,  9,  0,  0,  0,  0,  0,  0,  1, 14,  0,  0,  0,  2, 98,  0,  0,
  0,  1, 14,  0,  0,  0,  2,101,  0,  0,  0,  1, 14,  0,  0,  0,  5,100,101, 99,
108,  0,  0,  0,  1, 19,  0,  0,  0,  0,  0,  0,  1, 19,  0,  0,  0,  0,  0,  0,
  1, 19,  0,  0,  0,  0,  0,  0,  1, 24,  0,  0,  0,  2, 98,  0,  0,  0,  1, 24,
  0,  0,  0,  2,101,  0,  0,  0,  1, 24,  0,  0,  0,  5, 99,111,100,101,  0,  0,
  0,  1, 28,  0,  0,  0,  0,  0,  0,  1, 28,  0,  0,  0,  0,  0,  0,  1, 28,  0,
  0,  0,  0,  0,  0,  1, 33,  0,  0,  0,  2, 98,  0,  0,  0,  1, 33,  0,  0,  0,
  2,101,  0,  0,  0,  1, 33,  0,  0,  0,  5,108,105,110,101,  0,  0,  0,  1, 37,
  0,  0,  0,  0,  0,  0,  1, 37,  0,  0,  0,  0,  0,  0,  1, 37,  0,  0,  0,  0,
  0,  0,  0, 51,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0,  2, 98,  0,  2,  0,
  0,  0,  2,101,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  5,
 98,111,100,121,  0,  2,  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,  0,
  0,  0, 41, 94, 37,115, 42,109,111,100,117,108,101, 37,115, 37,115, 42, 40, 91,
 95, 37,119, 93, 91, 95, 37,119, 93, 42, 41, 37,115, 42, 40, 37, 98,123,125, 41,
 37,115, 42,  0,  2,  0,  0,  0, 11, 95, 99,117,114,114, 95, 99,111,100,101,  0,
  2,  0,  0,  0,  7,115,116,114,115,117, 98,  0,  2,  0,  0,  0,  7, 77,111,100,
117,108,101,  0,  2,  0,  0,  0, 34, 94, 37,115, 42, 35,100,101,102,105,110,101,
 37,115, 37,115, 42, 40, 91, 94, 37,115, 93, 42, 41, 91, 94, 10, 93, 42, 10, 37,
115, 42,  0,  2,  0,  0,  0,  7, 68,101,102,105,110,101,  0,  2,  0,  0,  0, 28,
 94, 37,115, 42,101,110,117,109, 91, 94,123, 93, 42, 40, 37, 98,123,125, 41, 37,
115, 42, 59, 63, 37,115, 42,  0,  2,  0,  0,  0, 10, 69,110,117,109,101,114, 97,
116,101,  0,  2,  0,  0,  0, 55, 94, 37,115, 42,116,121,112,101,100,101,102, 37,
115, 37,115, 42,101,110,117,109, 91, 94,123, 93, 42, 40, 37, 98,123,125, 41, 37,
115, 42, 40, 91, 37,119, 95, 93, 91, 94, 37,115, 93, 42, 41, 37,115, 42, 59, 37,
115, 42,  0,  2,  0,  0,  0,  8, 84,121,112,101,100,101,102,  0,  2,  0,  0,  0,
  5,105,110,116, 32,  0,  2,  0,  0,  0,  5,100,101, 99,108,  0,  2,  0,  0,  0,
  5,107,105,110,100,  0,  2,  0,  0,  0,  4, 97,114,103,  0,  2,  0,  0,  0,  6,
 99,111,110,115,116,  0,  2,  0,  0,  0, 78, 94, 37,115, 42, 40, 91, 95, 37,119,
 93, 91, 95, 37,119, 37,115, 37, 42, 38, 93, 42,111,112,101,114, 97,116,111,114,
 41, 37,115, 42, 40, 91, 94, 37,115, 93, 91, 94, 37,115, 93, 42, 41, 37,115, 42,
 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, 63,115, 63,116, 63,
 41, 37,115, 42, 59, 37,115, 42,  0,  2,  0,  0,  0,  9, 79,112,101,114, 97,116,
111,114,  0,  2,  0,  0,  0, 71, 94, 37,115, 42, 40, 91,126, 95, 37,119, 93, 91,
 95, 64, 37,119, 37,115, 37, 42, 38, 93, 42, 91, 95, 37,119, 93, 41, 37,115, 42,
 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, 63,115, 63,116, 63,
 41, 37,115, 42, 61, 63, 37,115, 42, 48, 63, 37,115, 42, 59, 37,115, 42,  0,  2,
  0,  0,  0, 43, 94, 37,115, 42, 40, 91, 95, 37,119, 93, 41, 37,115, 42, 40, 37,
 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, 63,115, 63,116, 63, 41, 37,
115, 42, 59, 37,115, 42,  0,  2,  0,  0,  0,  9, 70,117,110, 99,116,105,111,110,
  0,  2,  0,  0,  0, 64, 94, 37,115, 42, 40, 91,126, 95, 37,119, 93, 91, 95, 64,
 37,119, 37,115, 37, 42, 38, 93, 42, 91, 95, 37,119, 93, 41, 37,115, 42, 40, 37,
 98, 40, 41, 41, 37,115, 42, 40, 99, 63,111, 63,110, 63,115, 63,116, 63, 41, 37,
115, 42, 37, 98,123,125, 37,115, 42,  0,  2,  0,  0,  0, 46, 94, 37,115, 42, 40,
 91, 95, 37,119, 93, 41, 37,115, 42, 40, 37, 98, 40, 41, 41, 37,115, 42, 40, 99,
 63,111, 63,110, 63,115, 63,116, 63, 41, 37,115, 42, 37, 98,123,125, 37,115, 42,
  0,  2,  0,  0,  0,  5, 98, 97,115,101,  0,  2,  0,  0,  0, 49, 94, 37,115, 42,
 99,108, 97,115,115, 37,115, 42, 40, 91, 95, 37,119, 93, 91, 95, 37,119, 93, 42,
 41, 37,115, 42, 40, 46, 45, 41, 37,115, 42, 40, 37, 98,123,125, 41, 37,115, 42,
 59, 37,115, 42,  0,  2,  0,  0,  0, 50, 94, 37,115, 42,115,116,114,117, 99,116,
 37,115, 42, 40, 91, 95, 37,119, 93, 91, 95, 37,119, 93, 42, 41, 37,115, 42, 40,
 46, 45, 41, 37,115, 42, 40, 37, 98,123,125, 41, 37,115, 42, 59, 37,115, 42,  0,
  2,  0,  0,  0,  1,  0,  2,  0,  0,  0, 66, 94, 37,115, 42,116,121,112,101,100,
101,102, 37,115, 37,115, 42,115,116,114,117, 99,116, 37,115, 37,115, 42, 91, 95,
 37,119, 93, 42, 37,115, 42, 40, 37, 98,123,125, 41, 37,115, 42, 40, 91, 95, 37,
119, 93, 91, 95, 37,119, 93, 42, 41, 37,115, 42, 59, 37,115, 42,  0,  2,  0,  0,
  0, 17, 46, 45, 40, 91, 95, 37,119, 93, 91, 95, 37,119, 93, 42, 41, 36,  0,  2,
  0,  0,  0,  6, 67,108, 97,115,115,  0,  2,  0,  0,  0,  6,116,121,112,101,115,
  0,  2,  0,  0,  0, 28, 94, 37,115, 42,116,121,112,101,100,101,102, 37,115, 37,
115, 42, 40, 46, 45, 41, 37,115, 42, 59, 37,115, 42,  0,  2,  0,  0,  0, 40, 94,
 37,115, 42, 40, 91, 95, 37,119, 93, 91, 95, 64, 37,115, 37,119, 37,100, 37, 42,
 38, 93, 42, 91, 95, 37,119, 37,100, 93, 41, 37,115, 42, 59, 37,115, 42,  0,  2,
  0,  0,  0,  9, 86, 97,114,105, 97, 98,108,101,  0,  2,  0,  0,  0, 43, 94, 37,
115, 42, 40, 91, 95, 37,119, 93, 91, 93, 91, 95, 64, 37,115, 37,119, 37,100, 37,
 42, 38, 93, 42, 91, 93, 95, 37,119, 37,100, 93, 41, 37,115, 42, 59, 37,115, 42,
  0,  2,  0,  0,  0,  6, 65,114,114, 97,121,  0,  2,  0,  0,  0,  5, 99,111,100,
101,  0,  2,  0,  0,  0, 11, 94, 37,115, 42, 40, 37, 98,  1,  2, 41,  0,  2,  0,
  0,  0,  5, 67,111,100,101,  0,  2,  0,  0,  0,  5,108,105,110,101,  0,  2,  0,
  0,  0, 12, 94, 37,115, 42, 37, 36, 40, 46, 45, 10, 41,  0,  2,  0,  0,  0,  9,
 86,101,114, 98, 97,116,105,109,  0,  2,  0,  0,  0,  5,103,115,117, 98,  0,  2,
  0,  0,  0,  6, 37,115, 37,115, 42,  0,  2,  0,  0,  0,  6,101,114,114,111,114,
  0,  2,  0,  0,  0, 13, 35,112, 97,114,115,101, 32,101,114,114,111,114,  0,  2,
  0,  0,  0,  6,112, 97,114,115,101,  0,  4,  0,  0,  1, 49,  0,  0,  0, 15, 64,
 99,111,110,116, 97,105,110,101,114, 46,108,117, 97,  0,  0,  0,  0, 35,  5,  2,
 50, 17, 59,  1, 51, 13,  0, 20,  3, 13,  1,  2,  1,  2, 23,  1, 59,  1, 52, 59,
  1, 50, 13,  1, 11,  1, 31, 54, 27, 59,  1, 53,  0,  0,  0,  0,  2,  0,  0,  1,
 49,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  1, 49,  0,  0,  0,  2,115,  0,
  0,  0,  0,  4,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,
  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,100,111,112, 97,114,115,101,  0,

};

/* package.lo */
static char B5[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 13, 64,112, 97, 99,107, 97,
103,101, 46,108,117, 97,  0,  0,  0,  0,102,  5,  0, 60, 20, 22,  2, 60, 21, 11,
  1, 15,  2, 11,  3, 60, 22, 11,  4, 30,  1, 60, 23, 25,  0, 60, 24, 15,  5, 15,
  0, 15,  6,  2,  0,  2, 60, 27, 15,  0, 11,  7, 11,  8, 26, 60, 36, 15,  0, 11,
  9, 11, 10, 26, 60, 60, 15,  0, 11, 11, 11, 12, 26, 60,100, 15,  0, 11, 13, 11,
 14, 26, 60,119, 15,  0, 11, 15, 11, 16, 26, 60,132, 15,  0, 11, 17, 11, 18, 26,
 60,146, 11, 20, 25, 19, 60,155, 11, 22, 25, 21,  0,  0,  0,  0,  0,  0,  0,  0,
 23,  2,  0,  0,  0, 13, 99,108, 97,115,115, 80, 97, 99,107, 97,103,101,  0,  2,
  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 15, 99,108, 97,115,115,
 67,111,110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,  5,116,121,112,101,  0,
  2,  0,  0,  0,  8,112, 97, 99,107, 97,103,101,  0,  2,  0,  0,  0,  7,115,101,
116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,
  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0, 27,  0,  0,  0, 13,
 64,112, 97, 99,107, 97,103,101, 46,108,117, 97,  0,  0,  0,  0, 61,  6,  1, 60,
 28, 15,  0, 11,  1, 13,  0, 18,  3, 42,  2,  0,  1, 60, 29,  7,  1, 50, 27, 60,
 31, 13,  0, 13,  1, 16, 20,  0, 11,  5, 11,  5,  2,  0,  3, 60, 32, 13,  1,  7,
  1, 37, 23,  1, 60, 33, 60, 30, 13,  0, 13,  1, 16, 54, 36, 60, 34,  0,  0,  0,
  0,  2,  0,  0,  0, 27,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 29,  0,
  0,  0,  2,105,  0,  0,  0,  0,  6,  2,  0,  0,  0,  6,112,114,105,110,116,  0,
  2,  0,  0,  0, 10, 80, 97, 99,107, 97,103,101, 58, 32,  0,  2,  0,  0,  0,  5,
115,101,108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  2,
105,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0, 11,112,114,101,112,114,111, 99,
101,115,115,  0,  4,  0,  0,  0, 36,  0,  0,  0, 13, 64,112, 97, 99,107, 97,103,
101, 46,108,117, 97,  0,  0,  0,  1, 83,  7,  1, 60, 38, 13,  0, 11,  1, 11,  2,
 13,  0, 18,  1, 42, 26, 60, 40, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11,  4,
 11,  5,  2,  1,  3, 26, 60, 41, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11,  6,
 11,  7,  2,  1,  3, 26, 60, 42, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11,  8,
 11,  9,  2,  1,  3, 26, 60, 43, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 10,
 11,  5,  2,  1,  3, 26, 60, 44, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11,  7,
 11,  6,  2,  1,  3, 26, 60, 45, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11,  9,
 11,  8,  2,  1,  3, 26, 60, 46, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 11,
 11, 12,  2,  1,  3, 26, 60, 47, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 13,
 11, 14,  2,  1,  3, 26, 60, 48, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 15,
 11, 14,  2,  1,  3, 26, 60, 49, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 16,
 11, 14,  2,  1,  3, 26, 60, 50, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 17,
 11,  5,  2,  1,  3, 26, 60, 51, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 18,
 11, 19,  2,  1,  3, 26, 60, 52, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 18,
 11, 19,  2,  1,  3, 26, 60, 53, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 20,
 11, 21,  2,  1,  3, 26, 60, 55, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 22,
 11,  7,  2,  1,  3, 26, 60, 56, 13,  0, 11,  1, 15,  3, 13,  0, 18,  1, 11, 23,
 11,  9,  2,  1,  3, 26, 60, 57,  0,  0,  0,  0,  1,  0,  0,  0, 36,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0, 24,  2,  0,  0,  0,  5,115,101,108,102,  0,
  2,  0,  0,  0,  5, 99,111,100,101,  0,  2,  0,  0,  0,  2, 32,  0,  2,  0,  0,
  0,  5,103,115,117, 98,  0,  2,  0,  0,  0, 10, 40, 47, 47, 91, 94, 10, 93, 42,
 41,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  4, 47, 37, 42,  0,  2,  0,  0,
  0,  2,  1,  0,  2,  0,  0,  0,  4, 37, 42, 47,  0,  2,  0,  0,  0,  2,  2,  0,
  2,  0,  0,  0,  5, 37, 98,  1,  2,  0,  2,  0,  0,  0,  8, 37,115, 42, 64, 37,
115, 42,  0,  2,  0,  0,  0,  2, 64,  0,  2,  0,  0,  0, 14, 37,115, 63,105,110,
108,105,110,101, 40, 37,115, 41,  0,  2,  0,  0,  0,  3, 37, 49,  0,  2,  0,  0,
  0, 14, 37,115, 63,101,120,116,101,114,110, 40, 37,115, 41,  0,  2,  0,  0,  0,
 15, 37,115, 63,118,105,114,116,117, 97,108, 40, 37,115, 41,  0,  2,  0,  0,  0,
  8,112,117, 98,108,105, 99, 58,  0,  2,  0,  0,  0, 18, 40, 91, 94, 37,119, 95,
 93, 41,118,111,105,100, 37,115, 42, 37, 42,  0,  2,  0,  0,  0, 13, 37, 49, 95,
117,115,101,114,100, 97,116, 97, 32,  0,  2,  0,  0,  0, 18, 40, 91, 94, 37,119,
 95, 93, 41, 99,104, 97,114, 37,115, 42, 37, 42,  0,  2,  0,  0,  0, 12, 37, 49,
 95, 99,115,116,114,105,110,103, 32,  0,  2,  0,  0,  0,  5, 37, 36, 37, 91,  0,
  2,  0,  0,  0,  5, 37, 36, 37, 93,  0,  2,  0,  0,  0,  9,112,114,101, 97,109,
 98,108,101,  0,  4,  0,  0,  0, 60,  0,  0,  0, 13, 64,112, 97, 99,107, 97,103,
101, 46,108,117, 97,  0,  0,  0,  1, 79,  5,  1, 60, 61, 15,  0, 11,  1,  2,  0,
  1, 60, 62, 15,  0, 11,  2, 13,  0, 18,  4, 42, 11,  5, 42,  2,  0,  1, 60, 63,
 15,  0, 11,  6, 15,  7, 42, 11,  8, 42, 15,  9,  2,  1,  0, 42, 11, 10, 42,  2,
  0,  1, 60, 64, 15,  0, 11, 11,  2,  0,  1, 60, 66, 15, 12, 18, 13, 44, 52, 54,
 60, 67, 15,  0, 11, 14,  2,  0,  1, 60, 68, 15,  0, 11, 15, 13,  0, 18,  4, 42,
 11, 16, 42,  2,  0,  1, 60, 69, 15,  0, 11, 17, 13,  0, 18,  4, 42, 11, 18, 42,
  2,  0,  1, 60, 70, 15,  0, 11,  5,  2,  0,  1, 50,  2, 60, 71, 60, 73, 15, 12,
 18, 19, 52, 46, 60, 74, 15,  0, 11, 20,  2,  0,  1, 60, 75, 15,  0, 11, 21,  2,
  0,  1, 60, 76, 15,  0, 11, 22, 13,  0, 18,  4, 42, 11, 23, 42,  2,  0,  1, 60,
 77, 15,  0, 11, 24,  2,  0,  1, 50,  2, 60, 78, 60, 79, 15,  0, 11, 25,  2,  0,
  1, 60, 80,  7,  1, 50, 23, 60, 82, 13,  0, 13,  1, 16, 20, 27,  2,  0,  1, 60,
 83, 13,  1,  7,  1, 37, 23,  1, 60, 84, 60, 81, 13,  0, 13,  1, 16, 54, 32, 60,
 85, 15,  0, 11,  5,  2,  0,  1, 60, 86, 15,  0, 11, 28,  2,  0,  1, 60, 87, 13,
  0, 20, 29,  2,  0,  1, 60, 88, 15,  0, 11,  5,  2,  0,  1, 60, 89, 15,  0, 11,
 30,  2,  0,  1, 60, 90, 15,  0, 11, 31,  2,  0,  1, 60, 91, 15,  0, 11, 32,  2,
  0,  1, 60, 92, 15, 33, 15, 34, 11, 35,  2,  0,  2, 60, 93, 15, 33, 15, 36, 11,
 37,  2,  0,  2, 60, 94, 15, 38, 11, 39,  2,  0,  1, 60, 95, 15, 38, 11,  5,  2,
  0,  1, 60, 96,  0,  0,  0,  0,  2,  0,  0,  0, 60,  0,  0,  0,  5,115,101,108,
102,  0,  0,  0,  0, 80,  0,  0,  0,  2,105,  0,  0,  0,  0, 40,  2,  0,  0,  0,
  7,111,117,116,112,117,116,  0,  2,  0,  0,  0,  4, 47, 42, 10,  0,  2,  0,  0,
  0, 17, 42, 42, 32, 76,117, 97, 32, 98,105,110,100,105,110,103, 58, 32,  0,  2,
  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,
  0,  0,  0,  2, 10,  0,  2,  0,  0,  0, 31, 42, 42, 32, 71,101,110,101,114, 97,
116,101,100, 32, 97,117,116,111,109, 97,116,105, 99, 97,108,108,121, 32, 98,121,
 32,  0,  2,  0,  0,  0, 14, 84, 79, 76, 85, 65, 95, 86, 69, 82, 83, 73, 79, 78,
  0,  2,  0,  0,  0,  5, 32,111,110, 32,  0,  2,  0,  0,  0,  5,100, 97,116,101,
  0,  2,  0,  0,  0,  3, 46, 10,  0,  2,  0,  0,  0,  5, 42, 47, 10, 10,  0,  2,
  0,  0,  0,  6,102,108, 97,103,115,  0,  2,  0,  0,  0,  2,104,  0,  2,  0,  0,
  0, 24, 47, 42, 32, 69,120,112,111,114,116,101,100, 32,102,117,110, 99,116,105,
111,110, 32, 42, 47,  0,  2,  0,  0,  0, 12,105,110,116, 32, 32,116,111,108,117,
 97, 95,  0,  2,  0,  0,  0, 14, 95,111,112,101,110, 32, 40,118,111,105,100, 41,
 59,  0,  2,  0,  0,  0, 12,118,111,105,100, 32,116,111,108,117, 97, 95,  0,  2,
  0,  0,  0, 15, 95, 99,108,111,115,101, 32, 40,118,111,105,100, 41, 59,  0,  2,
  0,  0,  0,  2, 97,  0,  2,  0,  0,  0, 45, 47, 42, 32, 65,117,116,111,109, 97,
116,105, 99, 32,105,110,105,116,105, 97,108,105,122, 97,116,105,111,110, 32,102,
111,114, 32, 67, 43, 43, 32, 99,111,100,101, 32, 42, 47, 10,  0,  2,  0,  0,  0,
 20, 35,105,102,100,101,102, 32, 95, 95, 99,112,108,117,115,112,108,117,115, 10,
  0,  2,  0,  0,  0, 26,115,116, 97,116,105, 99, 32,105,110,116, 32,100,117,109,
109,121, 32, 61, 32,116,111,108,117, 97, 95,  0,  2,  0,  0,  0, 10, 95,111,112,
101,110, 32, 40, 41, 59,  0,  2,  0,  0,  0,  9, 35,101,110,100,105,102, 10, 10,
  0,  2,  0,  0,  0, 21, 35,105,110, 99,108,117,100,101, 32, 34,116,111,108,117,
 97, 46,104, 34, 10, 10,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  9,112,
114,101, 97,109, 98,108,101,  0,  2,  0,  0,  0, 20, 47, 42, 32,116, 97,103, 32,
118, 97,114,105, 97, 98,108,101,115, 32, 42, 47,  0,  2,  0,  0,  0,  8,100,101,
 99,108,116, 97,103,  0,  2,  0,  0,  0, 51, 47, 42, 32,102,117,110, 99,116,105,
111,110, 32,116,111, 32,114,101,103,105,115,116,101,114, 32,116,121,112,101, 32,
 97,110,100, 32,105,110,105,116,105, 97,108,105,122,101, 32,116, 97,103, 32, 42,
 47,  0,  2,  0,  0,  0, 35,115,116, 97,116,105, 99, 32,118,111,105,100, 32,116,
111,108,117, 97, 73, 95,105,110,105,116, 95,116, 97,103, 32, 40,118,111,105,100,
 41,  0,  2,  0,  0,  0,  2,123,  0,  2,  0,  0,  0,  8,102,111,114,101, 97, 99,
104,  0,  2,  0,  0,  0, 10, 95,117,115,101,114,116,121,112,101,  0,  4,  0,  0,
  0, 92,  0,  0,  0, 13, 64,112, 97, 99,107, 97,103,101, 46,108,117, 97,  0,  0,
  0,  0, 16,  6,  2, 60, 92, 15,  2, 11,  3, 13,  1, 11,  4,  2,  0,  3,  0,  0,
  0,  0,  2,  0,  0,  0, 92,  0,  0,  0,  2,110,  0,  0,  0,  0, 92,  0,  0,  0,
  2,118,  0,  0,  0,  0,  5,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  2,118,
  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 18, 32,116,
111,108,117, 97, 95,117,115,101,114,116,121,112,101, 40, 34,  0,  2,  0,  0,  0,
  4, 34, 41, 59,  0,  2,  0,  0,  0, 10, 95,116, 97,103,110, 97,109,101,115,  0,
  4,  0,  0,  0, 93,  0,  0,  0, 13, 64,112, 97, 99,107, 97,103,101, 46,108,117,
 97,  0,  0,  0,  0, 21,  7,  2, 60, 93, 15,  2, 11,  3, 13,  1, 11,  4, 13,  0,
 42, 11,  5,  2,  0,  4,  0,  0,  0,  0,  2,  0,  0,  0, 93,  0,  0,  0,  2,110,
  0,  0,  0,  0, 93,  0,  0,  0,  2,118,  0,  0,  0,  0,  6,  2,  0,  0,  0,  2,
110,  0,  2,  0,  0,  0,  2,118,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,
  0,  2,  0,  0,  0, 16, 32,116,111,108,117, 97, 95,115,101,116,116, 97,103, 40,
 34,  0,  2,  0,  0,  0,  4, 34, 44, 38,  0,  2,  0,  0,  0,  3, 41, 59,  0,  2,
  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,
  0,  0,  9,114,101,103,105,115,116,101,114,  0,  4,  0,  0,  0,100,  0,  0,  0,
 13, 64,112, 97, 99,107, 97,103,101, 46,108,117, 97,  0,  0,  0,  0,132,  4,  1,
 60,101, 15,  0, 11,  1,  2,  0,  1, 60,102, 15,  0, 11,  2, 13,  0, 18,  4, 42,
 11,  5, 42,  2,  0,  1, 60,103, 15,  0, 11,  6,  2,  0,  1, 60,104, 15,  0, 11,
  7,  2,  0,  1, 60,105, 15,  0, 11,  8,  2,  0,  1, 60,106, 15,  0, 11,  9,  2,
  0,  1, 60,107,  7,  1, 50, 23, 60,109, 13,  0, 13,  1, 16, 20, 11,  2,  0,  1,
 60,110, 13,  1,  7,  1, 37, 23,  1, 60,111, 60,108, 13,  0, 13,  1, 16, 54, 32,
 60,112, 15,  0, 11, 12,  2,  0,  1, 60,113, 15,  0, 11, 13,  2,  0,  1, 60,114,
 15,  0, 11, 14,  2,  0,  1, 60,115,  0,  0,  0,  0,  2,  0,  0,  0,100,  0,  0,
  0,  5,115,101,108,102,  0,  0,  0,  0,107,  0,  0,  0,  2,105,  0,  0,  0,  0,
 15,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 20, 47, 42,
 32, 79,112,101,110, 32,102,117,110, 99,116,105,111,110, 32, 42, 47,  0,  2,  0,
  0,  0, 11,105,110,116, 32,116,111,108,117, 97, 95,  0,  2,  0,  0,  0,  5,115,
101,108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 13, 95,
111,112,101,110, 32, 40,118,111,105,100, 41,  0,  2,  0,  0,  0,  2,123,  0,  2,
  0,  0,  0, 15, 32,116,111,108,117, 97, 95,111,112,101,110, 40, 41, 59,  0,  2,
  0,  0,  0, 19, 32,108,117, 97, 95, 98,101,103,105,110, 98,108,111, 99,107, 40,
 41, 59,  0,  2,  0,  0,  0, 20, 32,116,111,108,117, 97, 73, 95,105,110,105,116,
 95,116, 97,103, 40, 41, 59,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  9,
114,101,103,105,115,116,101,114,  0,  2,  0,  0,  0, 17, 32,108,117, 97, 95,101,
110,100, 98,108,111, 99,107, 40, 41, 59,  0,  2,  0,  0,  0, 11, 32,114,101,116,
117,114,110, 32, 49, 59,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0, 11,117,
110,114,101,103,105,115,116,101,114,  0,  4,  0,  0,  0,119,  0,  0,  0, 13, 64,
112, 97, 99,107, 97,103,101, 46,108,117, 97,  0,  0,  0,  0, 87,  4,  1, 60,120,
 15,  0, 11,  1,  2,  0,  1, 60,121, 15,  0, 11,  2, 13,  0, 18,  4, 42, 11,  5,
 42,  2,  0,  1, 60,122, 15,  0, 11,  6,  2,  0,  1, 60,123,  7,  1, 50, 23, 60,
125, 13,  0, 13,  1, 16, 20,  8,  2,  0,  1, 60,126, 13,  1,  7,  1, 37, 23,  1,
 60,127, 60,124, 13,  0, 13,  1, 16, 54, 32, 60,128, 15,  0, 11,  9,  2,  0,  1,
 60,129,  0,  0,  0,  0,  2,  0,  0,  0,119,  0,  0,  0,  5,115,101,108,102,  0,
  0,  0,  0,123,  0,  0,  0,  2,105,  0,  0,  0,  0, 10,  2,  0,  0,  0,  7,111,
117,116,112,117,116,  0,  2,  0,  0,  0, 21, 47, 42, 32, 67,108,111,115,101, 32,
102,117,110, 99,116,105,111,110, 32, 42, 47,  0,  2,  0,  0,  0, 12,118,111,105,
100, 32,116,111,108,117, 97, 95,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,
  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 14, 95, 99,108,111,115,101,
 32, 40,118,111,105,100, 41,  0,  2,  0,  0,  0,  2,123,  0,  2,  0,  0,  0,  2,
105,  0,  2,  0,  0,  0, 11,117,110,114,101,103,105,115,116,101,114,  0,  2,  0,
  0,  0,  2,125,  0,  2,  0,  0,  0,  7,104,101, 97,100,101,114,  0,  4,  0,  0,
  0,132,  0,  0,  0, 13, 64,112, 97, 99,107, 97,103,101, 46,108,117, 97,  0,  0,
  0,  0,127,  4,  1, 60,133, 15,  0, 11,  1,  2,  0,  1, 15,  0, 11,  2, 13,  0,
 18,  4, 42, 11,  5, 42,  2,  0,  1, 60,134, 15,  0, 11,  6, 15,  7, 42, 11,  8,
 42, 15,  9,  2,  1,  0, 42, 11, 10, 42,  2,  0,  1, 60,135, 15,  0, 11, 11,  2,
  0,  1, 60,137, 15, 12, 18, 13, 44, 52, 54, 60,138, 15,  0, 11, 14,  2,  0,  1,
 60,139, 15,  0, 11, 15, 13,  0, 18,  4, 42, 11, 16, 42,  2,  0,  1, 60,140, 15,
  0, 11, 17, 13,  0, 18,  4, 42, 11, 18, 42,  2,  0,  1, 60,141, 15,  0, 11,  5,
  2,  0,  1, 50,  2, 60,142, 60,143,  0,  0,  0,  0,  1,  0,  0,  0,132,  0,  0,
  0,  5,115,101,108,102,  0,  0,  0,  0, 19,  2,  0,  0,  0,  7,111,117,116,112,
117,116,  0,  2,  0,  0,  0,  4, 47, 42, 10,  0,  2,  0,  0,  0, 17, 42, 42, 32,
 76,117, 97, 32, 98,105,110,100,105,110,103, 58, 32,  0,  2,  0,  0,  0,  5,115,
101,108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  2, 10,
  0,  2,  0,  0,  0, 31, 42, 42, 32, 71,101,110,101,114, 97,116,101,100, 32, 97,
117,116,111,109, 97,116,105, 99, 97,108,108,121, 32, 98,121, 32,  0,  2,  0,  0,
  0, 14, 84, 79, 76, 85, 65, 95, 86, 69, 82, 83, 73, 79, 78,  0,  2,  0,  0,  0,
  5, 32,111,110, 32,  0,  2,  0,  0,  0,  5,100, 97,116,101,  0,  2,  0,  0,  0,
  3, 46, 10,  0,  2,  0,  0,  0,  5, 42, 47, 10, 10,  0,  2,  0,  0,  0,  6,102,
108, 97,103,115,  0,  2,  0,  0,  0,  2,104,  0,  2,  0,  0,  0, 24, 47, 42, 32,
 69,120,112,111,114,116,101,100, 32,102,117,110, 99,116,105,111,110, 32, 42, 47,
  0,  2,  0,  0,  0, 12,105,110,116, 32, 32,116,111,108,117, 97, 95,  0,  2,  0,
  0,  0, 14, 95,111,112,101,110, 32, 40,118,111,105,100, 41, 59,  0,  2,  0,  0,
  0, 12,118,111,105,100, 32,116,111,108,117, 97, 95,  0,  2,  0,  0,  0, 15, 95,
 99,108,111,115,101, 32, 40,118,111,105,100, 41, 59,  0,  2,  0,  0,  0,  9, 95,
 80, 97, 99,107, 97,103,101,  0,  4,  0,  0,  0,146,  0,  0,  0, 13, 64,112, 97,
 99,107, 97,103,101, 46,108,117, 97,  0,  0,  0,  0, 31,  4,  1, 60,147, 13,  0,
 11,  1, 15,  2, 26, 60,148, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60,149, 13,  0,
  1,  1, 60,150,  0,  0,  0,  0,  1,  0,  0,  0,146,  0,  0,  0,  2,116,  0,  0,
  0,  0,  5,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,
  0,  2,  0,  0,  0, 13, 99,108, 97,115,115, 80, 97, 99,107, 97,103,101,  0,  2,
  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117,
 97, 95,116, 97,103,  0,  2,  0,  0,  0,  8, 80, 97, 99,107, 97,103,101,  0,  4,
  0,  0,  0,155,  0,  0,  0, 13, 64,112, 97, 99,107, 97,103,101, 46,108,117, 97,
  0,  0,  0,  0,114, 10,  1, 60,157, 15,  2, 11,  3,  2,  1,  1, 60,159,  4,  0,
 60,161, 15,  5, 13,  1, 11,  6, 11,  7, 60,169,  2,  2,  3, 23,  2, 23,  1, 60,
170, 13,  2,  7,  0, 32, 56, 28, 60,172, 15,  9, 15, 10, 22,  2, 11,  0, 13,  0,
 11,  1, 13,  1, 30,  1,  2,  1,  1,  2,  1,  1, 60,173, 15, 11, 13,  3,  2,  0,
  1, 60,174, 13,  3, 20, 12,  2,  0,  1, 60,175, 13,  3, 20, 13, 13,  3, 18,  1,
  2,  0,  2, 60,176, 15, 14,  2,  0,  0, 60,177, 13,  3,  1,  4, 60,178,  0,  0,
  0,  0,  4,  0,  0,  0,155,  0,  0,  0,  5,110, 97,109,101,  0,  0,  0,  0,157,
  0,  0,  0,  5, 99,111,100,101,  0,  0,  0,  0,159,  0,  0,  0,  7,110,115,117,
 98,115,116,  0,  0,  0,  0,172,  0,  0,  0,  2,116,  0,  0,  0,  0, 15,  2,  0,
  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  5, 99,111,100,101,  0,  2,  0,
  0,  0,  5,114,101, 97,100,  0,  2,  0,  0,  0,  3, 46, 42,  0,  2,  0,  0,  0,
  7,110,115,117, 98,115,116,  0,  2,  0,  0,  0,  5,103,115,117, 98,  0,  2,  0,
  0,  0, 13, 37, 36, 60, 40, 46, 45, 41, 62, 37,115, 42, 10,  0,  4,  0,  0,  0,
161,  0,  0,  0, 13, 64,112, 97, 99,107, 97,103,101, 46,108,117, 97,  0,  0,  0,
  0, 71,  6,  1, 60,162, 15,  3, 13,  0, 11,  4,  2,  2,  2, 60,163, 13,  1, 44,
 52, 20, 60,164, 15,  5, 11,  6, 13,  2, 42, 11,  7, 42, 13,  0, 42,  2,  0,  1,
 50,  2, 60,165, 60,166, 15,  9, 13,  1, 11, 10,  2,  1,  2, 60,167, 15, 11, 13,
  1,  2,  0,  1, 60,168, 13,  3,  1,  4, 60,169,  0,  0,  0,  0,  4,  0,  0,  0,
161,  0,  0,  0,  3,102,110,  0,  0,  0,  0,162,  0,  0,  0,  3,102,112,  0,  0,
  0,  0,162,  0,  0,  0,  4,109,115,103,  0,  0,  0,  0,166,  0,  0,  0,  2,115,
  0,  0,  0,  0, 12,  2,  0,  0,  0,  3,102,110,  0,  2,  0,  0,  0,  3,102,112,
  0,  2,  0,  0,  0,  4,109,115,103,  0,  2,  0,  0,  0,  9,111,112,101,110,102,
105,108,101,  0,  2,  0,  0,  0,  2,114,  0,  2,  0,  0,  0,  6,101,114,114,111,
114,  0,  2,  0,  0,  0,  2, 35,  0,  2,  0,  0,  0,  3, 58, 32,  0,  2,  0,  0,
  0,  2,115,  0,  2,  0,  0,  0,  5,114,101, 97,100,  0,  2,  0,  0,  0,  3, 46,
 42,  0,  2,  0,  0,  0, 10, 99,108,111,115,101,102,105,108,101,  0,  2,  0,  0,
  0,  2,116,  0,  2,  0,  0,  0,  9, 95, 80, 97, 99,107, 97,103,101,  0,  2,  0,
  0,  0, 11, 95, 67,111,110,116, 97,105,110,101,114,  0,  2,  0,  0,  0,  5,112,
117,115,104,  0,  2,  0,  0,  0, 11,112,114,101,112,114,111, 99,101,115,115,  0,
  2,  0,  0,  0,  6,112, 97,114,115,101,  0,  2,  0,  0,  0,  4,112,111,112,  0,

};

/* module.lo */
static char B6[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 12, 64,109,111,100,117,108,
101, 46,108,117, 97,  0,  0,  0,  0, 75,  5,  0, 60, 19, 22,  2, 60, 20, 11,  1,
 15,  2, 11,  3, 60, 21, 11,  4, 30,  1, 60, 22, 25,  0, 60, 23, 15,  5, 15,  0,
 15,  6,  2,  0,  2, 60, 26, 15,  0, 11,  7, 11,  8, 26, 60, 36, 15,  0, 11,  9,
 11, 10, 26, 60, 41, 15,  0, 11, 11, 11, 12, 26, 60, 53, 11, 14, 25, 13, 60, 62,
 11, 16, 25, 15,  0,  0,  0,  0,  0,  0,  0,  0, 17,  2,  0,  0,  0, 12, 99,108,
 97,115,115, 77,111,100,117,108,101,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,
  0,  2,  0,  0,  0, 15, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114,
  0,  2,  0,  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0,  7,109,111,100,117,
108,101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,
116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  9,114,101,103,105,115,
116,101,114,  0,  4,  0,  0,  0, 26,  0,  0,  0, 12, 64,109,111,100,117,108,101,
 46,108,117, 97,  0,  0,  0,  0, 60,  4,  1, 60, 27, 15,  0, 11,  1, 13,  0, 18,
  3, 42, 11,  4, 42,  2,  0,  1, 60, 28,  7,  1, 50, 23, 60, 30, 13,  0, 13,  1,
 16, 20,  6,  2,  0,  1, 60, 31, 13,  1,  7,  1, 37, 23,  1, 60, 32, 60, 29, 13,
  0, 13,  1, 16, 54, 32, 60, 33,  0,  0,  0,  0,  2,  0,  0,  0, 26,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0, 28,  0,  0,  0,  2,105,  0,  0,  0,  0,  7,
  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 16, 32,116,111,
108,117, 97, 95,109,111,100,117,108,101, 40, 34,  0,  2,  0,  0,  0,  5,115,101,
108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  4, 34, 41,
 59,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  9,114,101,103,105,115,116,
101,114,  0,  2,  0,  0,  0, 11,117,110,114,101,103,105,115,116,101,114,  0,  4,
  0,  0,  0, 36,  0,  0,  0, 12, 64,109,111,100,117,108,101, 46,108,117, 97,  0,
  0,  0,  0, 22,  4,  1, 60, 37, 15,  0, 11,  1, 13,  0, 18,  3, 42, 11,  4, 42,
  2,  0,  1, 60, 38,  0,  0,  0,  0,  1,  0,  0,  0, 36,  0,  0,  0,  5,115,101,
108,102,  0,  0,  0,  0,  5,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,
  0,  0,  0, 32, 32,108,117, 97, 95,112,117,115,104,110,105,108, 40, 41, 59, 32,
108,117, 97, 95,115,101,116,103,108,111, 98, 97,108, 40, 34,  0,  2,  0,  0,  0,
  5,115,101,108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,
  4, 34, 41, 59,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0,
 41,  0,  0,  0, 12, 64,109,111,100,117,108,101, 46,108,117, 97,  0,  0,  0,  0,
 97,  8,  3, 60, 42, 15,  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 43, 15,  2, 13,
  1, 11,  4, 42, 13,  0, 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 44,  7,  1, 50,
 30, 60, 46, 13,  0, 13,  3, 16, 20,  2, 13,  1, 11,  9, 42, 11, 10,  2,  0,  3,
 60, 47, 13,  3,  7,  1, 37, 23,  3, 60, 48, 60, 45, 13,  0, 13,  3, 16, 54, 39,
 60, 49, 15,  2, 13,  1, 11, 11, 42, 13,  2, 42,  2,  0,  1, 60, 50,  0,  0,  0,
  0,  4,  0,  0,  0, 41,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 41,  0,
  0,  0,  6,105,100,101,110,116,  0,  0,  0,  0, 41,  0,  0,  0,  6, 99,108,111,
115,101,  0,  0,  0,  0, 44,  0,  0,  0,  2,105,  0,  0,  0,  0, 12,  2,  0,  0,
  0,  6,105,100,101,110,116,  0,  2,  0,  0,  0,  6, 99,108,111,115,101,  0,  2,
  0,  0,  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0,  8, 77,111,100,117,108,
101,123,  0,  2,  0,  0,  0, 10, 32,110, 97,109,101, 32, 61, 32, 39,  0,  2,  0,
  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,
  0,  0,  3, 39, 59,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  2, 32,  0,
  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0,  8, 95,
 77,111,100,117,108,101,  0,  4,  0,  0,  0, 53,  0,  0,  0, 12, 64,109,111,100,
117,108,101, 46,108,117, 97,  0,  0,  0,  0, 40,  4,  1, 60, 54, 13,  0, 11,  1,
 15,  2, 26, 60, 55, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60, 56, 15,  5, 13,  0,
  2,  0,  1, 60, 57, 13,  0,  1,  1, 60, 58,  0,  0,  0,  0,  1,  0,  0,  0, 53,
  0,  0,  0,  2,116,  0,  0,  0,  0,  6,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,
  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 12, 99,108, 97,115,115, 77,111,
100,117,108,101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,
  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  7, 97,112,112,
101,110,100,  0,  2,  0,  0,  0,  7, 77,111,100,117,108,101,  0,  4,  0,  0,  0,
 62,  0,  0,  0, 12, 64,109,111,100,117,108,101, 46,108,117, 97,  0,  0,  0,  0,
 75, 10,  2, 60, 63, 15,  3, 15,  4, 22,  1, 11,  5, 13,  0, 30,  0,  2,  1,  1,
  2,  1,  1, 60, 64, 15,  6, 13,  2,  2,  0,  1, 60, 65, 13,  2, 20,  7, 15,  8,
 13,  1,  7,  2, 15,  9, 13,  1,  2,  1,  1,  7,  1, 38,  2,  1,  3,  2,  0,  2,
 60, 66, 15, 10,  2,  0,  0, 60, 67, 13,  2,  1,  3, 60, 68,  0,  0,  0,  0,  3,
  0,  0,  0, 62,  0,  0,  0,  2,110,  0,  0,  0,  0, 62,  0,  0,  0,  2, 98,  0,
  0,  0,  0, 63,  0,  0,  0,  2,116,  0,  0,  0,  0, 11,  2,  0,  0,  0,  2,110,
  0,  2,  0,  0,  0,  2, 98,  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  8,
 95, 77,111,100,117,108,101,  0,  2,  0,  0,  0, 11, 95, 67,111,110,116, 97,105,
110,101,114,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  5,112,
117,115,104,  0,  2,  0,  0,  0,  6,112, 97,114,115,101,  0,  2,  0,  0,  0,  7,
115,116,114,115,117, 98,  0,  2,  0,  0,  0,  7,115,116,114,108,101,110,  0,  2,
  0,  0,  0,  4,112,111,112,  0,
};

/* class.lo */
static char B7[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 11, 64, 99,108, 97,115,115,
 46,108,117, 97,  0,  0,  0,  0, 96,  9,  0, 60, 20, 22,  4, 60, 21, 11,  1, 15,
  2, 11,  3, 60, 22, 11,  4, 11,  5, 60, 23, 11,  6, 11,  7, 60, 24, 11,  6, 30,
  3, 60, 25, 25,  0, 60, 26, 15,  8, 15,  0, 15,  9,  2,  0,  2, 60, 30, 15,  0,
 11, 10, 11, 11, 26, 60, 40, 15,  0, 11, 12, 11, 13, 26, 60, 45, 15,  0, 11, 14,
 11, 15, 26, 60, 57, 15,  0, 11, 16, 11, 17, 26, 60, 70, 11, 19, 25, 18, 60, 79,
 11, 21, 25, 20,  0,  0,  0,  0,  0,  0,  0,  0, 22,  2,  0,  0,  0, 11, 99,108,
 97,115,115, 67,108, 97,115,115,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,
  2,  0,  0,  0, 15, 99,108, 97,115,115, 67,111,110,116, 97,105,110,101,114,  0,
  2,  0,  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0,  6, 99,108, 97,115,115,
  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,
  0,  5, 98, 97,115,101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,
  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  9,114,
101,103,105,115,116,101,114,  0,  4,  0,  0,  0, 30,  0,  0,  0, 11, 64, 99,108,
 97,115,115, 46,108,117, 97,  0,  0,  0,  0, 68,  4,  1, 60, 31, 15,  0, 11,  1,
 13,  0, 18,  3, 42, 11,  4, 42, 13,  0, 18,  5, 42, 11,  6, 42,  2,  0,  1, 60,
 32,  7,  1, 50, 23, 60, 34, 13,  0, 13,  1, 16, 20,  8,  2,  0,  1, 60, 35, 13,
  1,  7,  1, 37, 23,  1, 60, 36, 60, 33, 13,  0, 13,  1, 16, 54, 32, 60, 37,  0,
  0,  0,  0,  2,  0,  0,  0, 30,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,
 32,  0,  0,  0,  2,105,  0,  0,  0,  0,  9,  2,  0,  0,  0,  7,111,117,116,112,
117,116,  0,  2,  0,  0,  0, 16, 32,116,111,108,117, 97, 95, 99, 99,108, 97,115,
115, 40, 34,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,110,
 97,109,101,  0,  2,  0,  0,  0,  4, 34, 44, 34,  0,  2,  0,  0,  0,  5, 98, 97,
115,101,  0,  2,  0,  0,  0,  4, 34, 41, 59,  0,  2,  0,  0,  0,  2,105,  0,  2,
  0,  0,  0,  9,114,101,103,105,115,116,101,114,  0,  2,  0,  0,  0, 11,117,110,
114,101,103,105,115,116,101,114,  0,  4,  0,  0,  0, 40,  0,  0,  0, 11, 64, 99,
108, 97,115,115, 46,108,117, 97,  0,  0,  0,  0, 22,  4,  1, 60, 41, 15,  0, 11,
  1, 13,  0, 18,  3, 42, 11,  4, 42,  2,  0,  1, 60, 42,  0,  0,  0,  0,  1,  0,
  0,  0, 40,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  5,  2,  0,  0,  0,
  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 32, 32,108,117, 97, 95,112,117,
115,104,110,105,108, 40, 41, 59, 32,108,117, 97, 95,115,101,116,103,108,111, 98,
 97,108, 40, 34,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,
110, 97,109,101,  0,  2,  0,  0,  0,  4, 34, 41, 59,  0,  2,  0,  0,  0,  8,100,
101, 99,108,116, 97,103,  0,  4,  0,  0,  0, 45,  0,  0,  0, 11, 64, 99,108, 97,
115,115, 46,108,117, 97,  0,  0,  0,  0,128,  8,  1, 60, 46, 13,  0, 11,  1, 13,
  0, 11,  2, 15,  3, 13,  0, 18,  4,  2,  2,  1, 27,  1, 27,  2,  5,  4, 15,  5,
 13,  0, 18,  1, 13,  0, 18,  2,  2,  0,  2, 60, 47, 13,  0, 11,  6, 13,  0, 11,
  7, 15,  3, 13,  0, 18,  4, 11,  8,  2,  2,  2, 27,  1, 27,  2,  5,  4, 60, 48,
 15,  3, 13,  0, 18, 10,  2,  2,  1, 15,  5, 13,  1, 13,  2,  2,  0,  2, 60, 49,
  7,  1, 50, 23, 60, 51, 13,  0, 13,  3, 16, 20,  5,  2,  0,  1, 60, 52, 13,  3,
  7,  1, 37, 23,  3, 60, 53, 60, 50, 13,  0, 13,  3, 16, 54, 32, 60, 54,  0,  0,
  0,  0,  4,  0,  0,  0, 45,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 48,
  0,  0,  0,  5,116,121,112,101,  0,  0,  0,  0, 48,  0,  0,  0,  4,116, 97,103,
  0,  0,  0,  0, 49,  0,  0,  0,  2,105,  0,  0,  0,  0, 12,  2,  0,  0,  0,  5,
115,101,108,102,  0,  2,  0,  0,  0,  6,105,116,121,112,101,  0,  2,  0,  0,  0,
  4,116, 97,103,  0,  2,  0,  0,  0,  7,116, 97,103,118, 97,114,  0,  2,  0,  0,
  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  8,100,101, 99,108,116, 97,103,  0,
  2,  0,  0,  0,  7, 99,105,116,121,112,101,  0,  2,  0,  0,  0,  5, 99,116, 97,
103,  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,  0,  0,  0,  5,116,121,
112,101,  0,  2,  0,  0,  0,  5, 98, 97,115,101,  0,  2,  0,  0,  0,  2,105,  0,
  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0, 57,  0,  0,  0, 11,
 64, 99,108, 97,115,115, 46,108,117, 97,  0,  0,  0,  0,117,  8,  3, 60, 58, 15,
  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 59, 15,  2, 13,  1, 11,  4, 42, 13,  0,
 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 60, 15,  2, 13,  1, 11,  8, 42, 13,  0,
 18,  9, 42, 11, 10, 42,  2,  0,  1, 60, 61,  7,  1, 50, 30, 60, 63, 13,  0, 13,
  3, 16, 20,  2, 13,  1, 11, 12, 42, 11, 13,  2,  0,  3, 60, 64, 13,  3,  7,  1,
 37, 23,  3, 60, 65, 60, 62, 13,  0, 13,  3, 16, 54, 39, 60, 66, 15,  2, 13,  1,
 11, 14, 42, 13,  2, 42,  2,  0,  1, 60, 67,  0,  0,  0,  0,  4,  0,  0,  0, 57,
  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 57,  0,  0,  0,  6,105,100,101,
110,116,  0,  0,  0,  0, 57,  0,  0,  0,  6, 99,108,111,115,101,  0,  0,  0,  0,
 61,  0,  0,  0,  2,105,  0,  0,  0,  0, 15,  2,  0,  0,  0,  6,105,100,101,110,
116,  0,  2,  0,  0,  0,  6, 99,108,111,115,101,  0,  2,  0,  0,  0,  6,112,114,
105,110,116,  0,  2,  0,  0,  0,  7, 67,108, 97,115,115,123,  0,  2,  0,  0,  0,
 10, 32,110, 97,109,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,115,101,108,102,
  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  3, 39, 44,  0,  2,
  0,  0,  0, 10, 32, 98, 97,115,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5, 98,
 97,115,101,  0,  2,  0,  0,  0,  3, 39, 59,  0,  2,  0,  0,  0,  2,105,  0,  2,
  0,  0,  0,  2, 32,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  2,125,  0,
  2,  0,  0,  0,  7, 95, 67,108, 97,115,115,  0,  4,  0,  0,  0, 70,  0,  0,  0,
 11, 64, 99,108, 97,115,115, 46,108,117, 97,  0,  0,  0,  0, 40,  4,  1, 60, 71,
 13,  0, 11,  1, 15,  2, 26, 60, 72, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60, 73,
 15,  5, 13,  0,  2,  0,  1, 60, 74, 13,  0,  1,  1, 60, 75,  0,  0,  0,  0,  1,
  0,  0,  0, 70,  0,  0,  0,  2,116,  0,  0,  0,  0,  6,  2,  0,  0,  0,  2,116,
  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 11, 99,108, 97,
115,115, 67,108, 97,115,115,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,
  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  7,
 97,112,112,101,110,100,  0,  2,  0,  0,  0,  6, 67,108, 97,115,115,  0,  4,  0,
  0,  0, 79,  0,  0,  0, 11, 64, 99,108, 97,115,115, 46,108,117, 97,  0,  0,  0,
  0, 73, 11,  3, 60, 80, 15,  4, 15,  5, 22,  2, 11,  6, 13,  0, 11,  7, 13,  1,
 30,  1,  2,  1,  1,  2,  1,  1, 60, 81, 15,  8, 13,  3,  2,  0,  1, 60, 82, 13,
  3, 20,  9, 15, 10, 13,  2,  7,  2, 15, 11, 13,  2,  2,  1,  1,  7,  1, 38,  2,
  1,  3,  2,  0,  2, 60, 83, 15, 12,  2,  0,  0, 60, 84,  0,  0,  0,  0,  4,  0,
  0,  0, 79,  0,  0,  0,  2,110,  0,  0,  0,  0, 79,  0,  0,  0,  2,112,  0,  0,
  0,  0, 79,  0,  0,  0,  2, 98,  0,  0,  0,  0, 80,  0,  0,  0,  2, 99,  0,  0,
  0,  0, 13,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  2,112,  0,  2,  0,  0,
  0,  2, 98,  0,  2,  0,  0,  0,  2, 99,  0,  2,  0,  0,  0,  7, 95, 67,108, 97,
115,115,  0,  2,  0,  0,  0, 11, 95, 67,111,110,116, 97,105,110,101,114,  0,  2,
  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,  5, 98, 97,115,101,  0,  2,
  0,  0,  0,  5,112,117,115,104,  0,  2,  0,  0,  0,  6,112, 97,114,115,101,  0,
  2,  0,  0,  0,  7,115,116,114,115,117, 98,  0,  2,  0,  0,  0,  7,115,116,114,
108,101,110,  0,  2,  0,  0,  0,  4,112,111,112,  0,
};

/* typedef.lo */
static char B8[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 13, 64,116,121,112,101,100,
101,102, 46,108,117, 97,  0,  0,  0,  0, 52,  7,  0, 60, 24, 22,  3, 60, 25, 11,
  1, 11,  2, 11,  3, 60, 26, 11,  2, 11,  4, 60, 27, 11,  2, 30,  2, 60, 28, 25,
  0, 60, 31, 15,  0, 11,  5, 11,  6, 26, 60, 40, 11,  8, 25,  7, 60, 49, 11, 10,
 25,  9,  0,  0,  0,  0,  0,  0,  0,  0, 11,  2,  0,  0,  0, 13, 99,108, 97,115,
115, 84,121,112,101,100,101,102,  0,  2,  0,  0,  0,  6,117,116,121,112,101,  0,
  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  5,
116,121,112,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0,
 31,  0,  0,  0, 13, 64,116,121,112,101,100,101,102, 46,108,117, 97,  0,  0,  0,
  0, 92,  6,  3, 60, 32, 15,  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 33, 15,  2,
 13,  1, 11,  4, 42, 13,  0, 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 34, 15,  2,
 13,  1, 11,  8, 42, 13,  0, 18,  9, 42, 11,  7, 42,  2,  0,  1, 60, 35, 15,  2,
 13,  1, 11, 10, 42, 13,  0, 18, 11, 42, 11,  7, 42,  2,  0,  1, 60, 36, 15,  2,
 13,  1, 11, 12, 42, 13,  2, 42,  2,  0,  1, 60, 37,  0,  0,  0,  0,  3,  0,  0,
  0, 31,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 31,  0,  0,  0,  6,105,
100,101,110,116,  0,  0,  0,  0, 31,  0,  0,  0,  6, 99,108,111,115,101,  0,  0,
  0,  0, 13,  2,  0,  0,  0,  6,105,100,101,110,116,  0,  2,  0,  0,  0,  6, 99,
108,111,115,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0,
  9, 84,121,112,101,100,101,102,123,  0,  2,  0,  0,  0, 11, 32,117,116,121,112,
101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,
  6,117,116,121,112,101,  0,  2,  0,  0,  0,  3, 39, 44,  0,  2,  0,  0,  0,  9,
 32,109,111,100, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,
  0,  0, 10, 32,116,121,112,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,116,121,
112,101,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0,  9, 95, 84,121,112,101,
100,101,102,  0,  4,  0,  0,  0, 40,  0,  0,  0, 13, 64,116,121,112,101,100,101,
102, 46,108,117, 97,  0,  0,  0,  0, 40,  4,  1, 60, 41, 13,  0, 11,  1, 15,  2,
 26, 60, 42, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60, 43, 15,  5, 13,  0,  2,  0,
  1, 60, 44, 13,  0,  1,  1, 60, 45,  0,  0,  0,  0,  1,  0,  0,  0, 40,  0,  0,
  0,  2,116,  0,  0,  0,  0,  6,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6,
 95, 98, 97,115,101,  0,  2,  0,  0,  0, 13, 99,108, 97,115,115, 84,121,112,101,
100,101,102,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0,
 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0, 14, 97,112,112,101,
110,100,116,121,112,101,100,101,102,  0,  2,  0,  0,  0,  8, 84,121,112,101,100,
101,102,  0,  4,  0,  0,  0, 49,  0,  0,  0, 13, 64,116,121,112,101,100,101,102,
 46,108,117, 97,  0,  0,  0,  0,109, 14,  1, 60, 50, 15,  1, 13,  0, 11,  2,  2,
  1,  2, 52, 11, 60, 51, 15,  3, 11,  4,  2,  0,  1, 50,  2, 60, 52, 60, 53, 15,
  6, 15,  7, 13,  0, 11,  8, 11,  9,  2,  1,  3, 11,  9,  2,  1,  2, 60, 54, 15,
 10, 22,  3, 60, 55, 11, 11, 13,  1, 13,  1, 18, 12, 16, 11, 13, 60, 56, 13,  1,
 13,  1, 18, 12,  7,  1, 38, 16, 11, 14, 60, 57, 15, 15, 13,  1,  7,  1, 13,  1,
 18, 12,  7,  2, 38,  2,  1,  3, 30,  2, 60, 58,  3,  2,  1, 60, 59,  0,  0,  0,
  0,  2,  0,  0,  0, 49,  0,  0,  0,  2,115,  0,  0,  0,  0, 53,  0,  0,  0,  2,
116,  0,  0,  0,  0, 16,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0,  8,115,116,
114,102,105,110,100,  0,  2,  0,  0,  0,  6, 91, 37, 42, 38, 93,  0,  2,  0,  0,
  0, 12,116,111,108,117, 97, 95,101,114,114,111,114,  0,  2,  0,  0,  0, 62, 35,
105,110,118, 97,108,105,100, 32,116,121,112,101,100,101,102, 58, 32,112,111,105,
110,116,101,114,115, 32, 40, 97,110,100, 32,114,101,102,101,114,101,110, 99,101,
115, 41, 32, 97,114,101, 32,110,111,116, 32,115,117,112,112,111,114,116,101,100,
  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6,115,112,108,105,116,  0,  2,
  0,  0,  0,  5,103,115,117, 98,  0,  2,  0,  0,  0,  6, 37,115, 37,115, 42,  0,
  2,  0,  0,  0,  2, 32,  0,  2,  0,  0,  0,  9, 95, 84,121,112,101,100,101,102,
  0,  2,  0,  0,  0,  6,117,116,121,112,101,  0,  2,  0,  0,  0,  2,110,  0,  2,
  0,  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,
  0,  0,  7, 99,111,110, 99, 97,116,  0,
};

/* define.lo */
static char B9[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 12, 64,100,101,102,105,110,
101, 46,108,117, 97,  0,  0,  0,  0, 75,  5,  0, 60, 18, 22,  2, 60, 19, 11,  1,
 11,  2, 11,  3, 60, 20, 15,  4, 30,  1, 60, 21, 25,  0, 60, 22, 15,  5, 15,  0,
 15,  6,  2,  0,  2, 60, 25, 15,  0, 11,  7, 11,  8, 26, 60, 35, 15,  0, 11,  9,
 11, 10, 26, 60, 42, 15,  0, 11, 11, 11, 12, 26, 60, 51, 11, 14, 25, 13, 60, 65,
 11, 16, 25, 15,  0,  0,  0,  0,  0,  0,  0,  0, 17,  2,  0,  0,  0, 12, 99,108,
 97,115,115, 68,101,102,105,110,101,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,
  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,
  0, 13, 99,108, 97,115,115, 70,101, 97,116,117,114,101,  0,  2,  0,  0,  0,  7,
115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,
103,  0,  2,  0,  0,  0,  9,114,101,103,105,115,116,101,114,  0,  4,  0,  0,  0,
 25,  0,  0,  0, 12, 64,100,101,102,105,110,101, 46,108,117, 97,  0,  0,  0,  0,
 80,  5,  1, 60, 26, 13,  0, 20,  2,  2,  1,  1, 60, 27, 13,  1, 52, 33, 60, 28,
 15,  3, 11,  4, 13,  1, 42, 11,  5, 42, 13,  0, 18,  6, 42, 11,  7, 42, 13,  0,
 18,  8, 42, 11,  9, 42,  2,  0,  1, 50, 27, 60, 30, 15,  3, 11, 10, 13,  0, 18,
  6, 42, 11,  7, 42, 13,  0, 18,  8, 42, 11,  9, 42,  2,  0,  1, 60, 31, 60, 32,
  0,  0,  0,  0,  2,  0,  0,  0, 25,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,
  0, 26,  0,  0,  0,  2,112,  0,  0,  0,  0, 11,  2,  0,  0,  0,  2,112,  0,  2,
  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,
108,101,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 18,
 32,116,111,108,117, 97, 95, 99,111,110,115,116, 97,110,116, 40, 34,  0,  2,  0,
  0,  0,  4, 34, 44, 34,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,
  0,  0,  3, 34, 44,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0,
  3, 41, 59,  0,  2,  0,  0,  0, 23, 32,116,111,108,117, 97, 95, 99,111,110,115,
116, 97,110,116, 40, 78, 85, 76, 76, 44, 34,  0,  2,  0,  0,  0, 11,117,110,114,
101,103,105,115,116,101,114,  0,  4,  0,  0,  0, 35,  0,  0,  0, 12, 64,100,101,
102,105,110,101, 46,108,117, 97,  0,  0,  0,  0, 38,  4,  1, 60, 36, 13,  0, 20,
  1,  2,  1,  1, 44, 52, 19, 60, 37, 15,  2, 11,  3, 13,  0, 18,  4, 42, 11,  5,
 42,  2,  0,  1, 50,  2, 60, 38, 60, 39,  0,  0,  0,  0,  1,  0,  0,  0, 35,  0,
  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  6,  2,  0,  0,  0,  5,115,101,108,
102,  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,108,101,  0,  2,  0,  0,  0,
  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 32, 32,108,117, 97, 95,112,117,
115,104,110,105,108, 40, 41, 59, 32,108,117, 97, 95,115,101,116,103,108,111, 98,
 97,108, 40, 34,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,
  4, 34, 41, 59,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0,
 42,  0,  0,  0, 12, 64,100,101,102,105,110,101, 46,108,117, 97,  0,  0,  0,  0,
 72,  6,  3, 60, 43, 15,  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 44, 15,  2, 13,
  1, 11,  4, 42, 13,  0, 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 45, 15,  2, 13,
  1, 11,  8, 42, 13,  0, 18,  9, 42, 11,  7, 42,  2,  0,  1, 60, 46, 15,  2, 13,
  1, 11, 10, 42, 13,  2, 42,  2,  0,  1, 60, 47,  0,  0,  0,  0,  3,  0,  0,  0,
 42,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 42,  0,  0,  0,  6,105,100,
101,110,116,  0,  0,  0,  0, 42,  0,  0,  0,  6, 99,108,111,115,101,  0,  0,  0,
  0, 11,  2,  0,  0,  0,  6,105,100,101,110,116,  0,  2,  0,  0,  0,  6, 99,108,
111,115,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0,  8,
 68,101,102,105,110,101,123,  0,  2,  0,  0,  0, 10, 32,110, 97,109,101, 32, 61,
 32, 39,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,110, 97,
109,101,  0,  2,  0,  0,  0,  3, 39, 44,  0,  2,  0,  0,  0, 11, 32,108,110, 97,
109,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,
  0,  0,  2,125,  0,  2,  0,  0,  0,  8, 95, 68,101,102,105,110,101,  0,  4,  0,
  0,  0, 51,  0,  0,  0, 12, 64,100,101,102,105,110,101, 46,108,117, 97,  0,  0,
  0,  0, 64,  4,  1, 60, 52, 13,  0, 11,  1, 15,  2, 26, 60, 53, 15,  3, 13,  0,
 15,  4,  2,  0,  2, 60, 55, 13,  0, 18,  5, 11,  6, 32, 52, 11, 60, 56, 15,  7,
 11,  8,  2,  0,  1, 50,  2, 60, 57, 60, 59, 15,  9, 13,  0,  2,  0,  1, 60, 60,
 13,  0,  1,  1, 60, 61,  0,  0,  0,  0,  1,  0,  0,  0, 51,  0,  0,  0,  2,116,
  0,  0,  0,  0, 10,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6, 95, 98, 97,
115,101,  0,  2,  0,  0,  0, 12, 99,108, 97,115,115, 68,101,102,105,110,101,  0,
  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,
117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,
  0,  1,  0,  2,  0,  0,  0,  6,101,114,114,111,114,  0,  2,  0,  0,  0, 16, 35,
105,110,118, 97,108,105,100, 32,100,101,102,105,110,101,  0,  2,  0,  0,  0,  7,
 97,112,112,101,110,100,  0,  2,  0,  0,  0,  7, 68,101,102,105,110,101,  0,  4,
  0,  0,  0, 65,  0,  0,  0, 12, 64,100,101,102,105,110,101, 46,108,117, 97,  0,
  0,  0,  0, 54,  9,  1, 60, 66, 15,  2, 13,  0, 11,  3,  2,  1,  2, 60, 67, 15,
  4, 22,  2, 60, 68, 11,  5, 13,  1,  7,  1, 16, 11,  6, 60, 69, 13,  1,  7,  2,
 16, 46,  5, 13,  1,  7,  1, 16, 30,  1, 60, 70,  3,  2,  1, 60, 71,  0,  0,  0,
  0,  2,  0,  0,  0, 65,  0,  0,  0,  2,110,  0,  0,  0,  0, 66,  0,  0,  0,  2,
116,  0,  0,  0,  0,  7,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  2,116,  0,
  2,  0,  0,  0,  6,115,112,108,105,116,  0,  2,  0,  0,  0,  2, 64,  0,  2,  0,
  0,  0,  8, 95, 68,101,102,105,110,101,  0,  2,  0,  0,  0,  5,110, 97,109,101,
  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,
};

/* enumerate.lo */
static char B10[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 15, 64,101,110,117,109,101,
114, 97,116,101, 46,108,117, 97,  0,  0,  0,  0, 69,  3,  0, 60, 19, 22,  1, 60,
 20, 11,  1, 15,  2, 30,  0, 60, 21, 25,  0, 60, 22, 15,  3, 15,  0, 15,  4,  2,
  0,  2, 60, 25, 15,  0, 11,  5, 11,  6, 26, 60, 42, 15,  0, 11,  7, 11,  8, 26,
 60, 53, 15,  0, 11,  9, 11, 10, 26, 60, 64, 11, 12, 25, 11, 60, 73, 11, 14, 25,
 13,  0,  0,  0,  0,  0,  0,  0,  0, 15,  2,  0,  0,  0, 15, 99,108, 97,115,115,
 69,110,117,109,101,114, 97,116,101,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,
  0,  2,  0,  0,  0, 13, 99,108, 97,115,115, 70,101, 97,116,117,114,101,  0,  2,
  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117,
 97, 95,116, 97,103,  0,  2,  0,  0,  0,  9,114,101,103,105,115,116,101,114,  0,
  4,  0,  0,  0, 25,  0,  0,  0, 15, 64,101,110,117,109,101,114, 97,116,101, 46,
108,117, 97,  0,  0,  0,  0,179,  7,  1, 60, 26, 13,  0, 20,  2,  2,  1,  1, 46,
  7, 13,  0, 20,  3,  2,  1,  1, 60, 27,  7,  1, 50,141, 60, 29, 13,  1, 52, 93,
 60, 30, 13,  0, 20,  2,  2,  1,  1, 52, 43, 60, 31, 15,  5, 11,  6, 13,  1, 42,
 11,  7, 42, 13,  0, 18,  8, 13,  2, 16, 42, 11,  9, 42, 13,  1, 42, 11, 10, 42,
 13,  0, 13,  2, 16, 42, 11, 11, 42,  2,  0,  1, 50, 37, 60, 33, 15,  5, 11,  6,
 13,  1, 42, 11,  7, 42, 13,  0, 18,  8, 13,  2, 16, 42, 11,  9, 42, 13,  0, 13,
  2, 16, 42, 11, 11, 42,  2,  0,  1, 60, 34, 50, 31, 60, 36, 15,  5, 11, 12, 13,
  0, 18,  8, 13,  2, 16, 42, 11,  9, 42, 13,  0, 13,  2, 16, 42, 11, 11, 42,  2,
  0,  1, 60, 37, 60, 38, 13,  2,  7,  1, 37, 23,  2, 60, 39, 60, 28, 13,  0, 13,
  2, 16, 54,150, 60, 40,  0,  0,  0,  0,  3,  0,  0,  0, 25,  0,  0,  0,  5,115,
101,108,102,  0,  0,  0,  0, 26,  0,  0,  0,  2,112,  0,  0,  0,  0, 27,  0,  0,
  0,  2,105,  0,  0,  0,  0, 13,  2,  0,  0,  0,  2,112,  0,  2,  0,  0,  0,  5,
115,101,108,102,  0,  2,  0,  0,  0,  8,105,110, 99,108, 97,115,115,  0,  2,  0,
  0,  0,  9,105,110,109,111,100,117,108,101,  0,  2,  0,  0,  0,  2,105,  0,  2,
  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 18, 32,116,111,108,
117, 97, 95, 99,111,110,115,116, 97,110,116, 40, 34,  0,  2,  0,  0,  0,  4, 34,
 44, 34,  0,  2,  0,  0,  0,  7,108,110, 97,109,101,115,  0,  2,  0,  0,  0,  3,
 34, 44,  0,  2,  0,  0,  0,  3, 58, 58,  0,  2,  0,  0,  0,  3, 41, 59,  0,  2,
  0,  0,  0, 23, 32,116,111,108,117, 97, 95, 99,111,110,115,116, 97,110,116, 40,
 78, 85, 76, 76, 44, 34,  0,  2,  0,  0,  0, 11,117,110,114,101,103,105,115,116,
101,114,  0,  4,  0,  0,  0, 42,  0,  0,  0, 15, 64,101,110,117,109,101,114, 97,
116,101, 46,108,117, 97,  0,  0,  0,  0, 83,  6,  1, 60, 43, 13,  0, 20,  1,  2,
  1,  1,  4,  0, 32, 48, 10, 13,  0, 20,  2,  2,  1,  1,  4,  0, 32, 52, 50, 60,
 44,  7,  1, 50, 31, 60, 46, 15,  4, 11,  5, 13,  0, 18,  6, 13,  1, 16, 42, 11,
  7, 42,  2,  0,  1, 60, 47, 13,  1,  7,  1, 37, 23,  1, 60, 48, 60, 45, 13,  0,
 13,  1, 16, 54, 40,  5,  1, 50,  2, 60, 49, 60, 50,  0,  0,  0,  0,  3,  0,  0,
  0, 42,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 44,  0,  0,  0,  2,105,
  0,  0,  0,  0, 48,  0,  0,  0,  0,  0,  0,  0,  8,  2,  0,  0,  0,  5,115,101,
108,102,  0,  2,  0,  0,  0,  8,105,110, 99,108, 97,115,115,  0,  2,  0,  0,  0,
  9,105,110,109,111,100,117,108,101,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,
  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 32, 32,108,117, 97, 95,112,
117,115,104,110,105,108, 40, 41, 59, 32,108,117, 97, 95,115,101,116,103,108,111,
 98, 97,108, 40, 34,  0,  2,  0,  0,  0,  7,108,110, 97,109,101,115,  0,  2,  0,
  0,  0,  4, 34, 41, 59,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,
  0,  0, 53,  0,  0,  0, 15, 64,101,110,117,109,101,114, 97,116,101, 46,108,117,
 97,  0,  0,  0,  0, 90,  8,  3, 60, 54, 15,  2, 13,  1, 11,  3, 42,  2,  0,  1,
 60, 55,  7,  1, 50, 43, 60, 57, 15,  2, 13,  1, 11,  6, 42, 13,  0, 13,  3, 16,
 42, 11,  7, 42, 13,  0, 18,  8, 13,  3, 16, 42, 11,  9, 42,  2,  0,  1, 60, 58,
 13,  3,  7,  1, 37, 23,  3, 60, 59, 60, 56, 13,  0, 13,  3, 16, 54, 52, 60, 60,
 15,  2, 13,  1, 11, 10, 42, 13,  2, 42,  2,  0,  1, 60, 61,  0,  0,  0,  0,  4,
  0,  0,  0, 53,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 53,  0,  0,  0,
  6,105,100,101,110,116,  0,  0,  0,  0, 53,  0,  0,  0,  6, 99,108,111,115,101,
  0,  0,  0,  0, 55,  0,  0,  0,  2,105,  0,  0,  0,  0, 11,  2,  0,  0,  0,  6,
105,100,101,110,116,  0,  2,  0,  0,  0,  6, 99,108,111,115,101,  0,  2,  0,  0,
  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0, 11, 69,110,117,109,101,114, 97,
116,101,123,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  5,115,101,108,102,
  0,  2,  0,  0,  0,  3, 32, 39,  0,  2,  0,  0,  0,  3, 39, 40,  0,  2,  0,  0,
  0,  7,108,110, 97,109,101,115,  0,  2,  0,  0,  0,  3, 41, 44,  0,  2,  0,  0,
  0,  2,125,  0,  2,  0,  0,  0, 11, 95, 69,110,117,109,101,114, 97,116,101,  0,
  4,  0,  0,  0, 64,  0,  0,  0, 15, 64,101,110,117,109,101,114, 97,116,101, 46,
108,117, 97,  0,  0,  0,  0, 40,  4,  1, 60, 65, 13,  0, 11,  1, 15,  2, 26, 60,
 66, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60, 67, 15,  5, 13,  0,  2,  0,  1, 60,
 68, 13,  0,  1,  1, 60, 69,  0,  0,  0,  0,  1,  0,  0,  0, 64,  0,  0,  0,  2,
116,  0,  0,  0,  0,  6,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6, 95, 98,
 97,115,101,  0,  2,  0,  0,  0, 15, 99,108, 97,115,115, 69,110,117,109,101,114,
 97,116,101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0,
 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  7, 97,112,112,101,
110,100,  0,  2,  0,  0,  0, 10, 69,110,117,109,101,114, 97,116,101,  0,  4,  0,
  0,  0, 73,  0,  0,  0, 15, 64,101,110,117,109,101,114, 97,116,101, 46,108,117,
 97,  0,  0,  0,  0,200,  9,  1, 60, 74, 15,  2, 15,  3, 13,  0,  7,  2,  9,  2,
  2,  1,  3, 11,  4,  2,  1,  2, 60, 75,  7,  1, 60, 76, 22,  1, 11,  7,  7,  0,
 30,  0, 50, 55, 60, 78, 15,  2, 13,  1, 13,  2, 16, 11,  9,  2,  1,  2, 60, 79,
 13,  3, 11,  7, 13,  3, 18,  7,  7,  1, 37, 26, 60, 80, 13,  3, 13,  3, 18,  7,
 13,  4,  7,  1, 16, 26, 60, 81, 13,  2,  7,  1, 37, 23,  2,  5,  1, 60, 82, 60,
 77, 13,  1, 13,  2, 16, 54, 64, 60, 84,  7,  1, 23,  2, 60, 85, 13,  3, 11, 10,
 22,  0, 26, 50, 60, 60, 87, 15,  2, 13,  3, 13,  2, 16, 11, 11,  2,  1,  2, 60,
 88, 13,  3, 13,  2, 13,  4,  7,  1, 16, 26, 60, 89, 13,  3, 18, 10, 13,  2, 13,
  4,  7,  2, 16, 46,  5, 13,  4,  7,  1, 16, 26, 60, 90, 13,  2,  7,  1, 37, 23,
  2,  5,  1, 60, 91, 60, 86, 13,  3, 13,  2, 16, 54, 69, 60, 92, 15, 12, 13,  3,
  3,  4,  1, 60, 93,  0,  0,  0,  0,  8,  0,  0,  0, 73,  0,  0,  0,  2, 98,  0,
  0,  0,  0, 74,  0,  0,  0,  2,116,  0,  0,  0,  0, 75,  0,  0,  0,  2,105,  0,
  0,  0,  0, 76,  0,  0,  0,  2,101,  0,  0,  0,  0, 78,  0,  0,  0,  3,116,116,
  0,  0,  0,  0, 81,  0,  0,  0,  0,  0,  0,  0, 87,  0,  0,  0,  2,116,  0,  0,
  0,  0, 90,  0,  0,  0,  0,  0,  0,  0, 13,  2,  0,  0,  0,  2, 98,  0,  2,  0,
  0,  0,  2,116,  0,  2,  0,  0,  0,  6,115,112,108,105,116,  0,  2,  0,  0,  0,
  7,115,116,114,115,117, 98,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  2,
105,  0,  2,  0,  0,  0,  2,101,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,
  3,116,116,  0,  2,  0,  0,  0,  2, 61,  0,  2,  0,  0,  0,  7,108,110, 97,109,
101,115,  0,  2,  0,  0,  0,  2, 64,  0,  2,  0,  0,  0, 11, 95, 69,110,117,109,
101,114, 97,116,101,  0,
};

/* variable.lo */
static char B11[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 14, 64,118, 97,114,105, 97,
 98,108,101, 46,108,117, 97,  0,  0,  0,  0, 87,  3,  0, 60, 18, 22,  1, 60, 19,
 11,  1, 15,  2, 30,  0, 60, 20, 25,  0, 60, 22, 15,  3, 15,  0, 15,  4,  2,  0,
  2, 60, 25, 15,  0, 11,  5, 11,  6, 26, 60, 37, 15,  0, 11,  7, 11,  8, 26, 60,
 48, 15,  0, 11,  9, 11, 10, 26, 60,154, 15,  0, 11, 11, 11, 12, 26, 60,171, 15,
  0, 11, 13, 11, 14, 26, 60,179, 11, 16, 25, 15, 60,188, 11, 18, 25, 17,  0,  0,
  0,  0,  0,  0,  0,  0, 19,  2,  0,  0,  0, 14, 99,108, 97,115,115, 86, 97,114,
105, 97, 98,108,101,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,
  0, 17, 99,108, 97,115,115, 68,101, 99,108, 97,114, 97,116,105,111,110,  0,  2,
  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117,
 97, 95,116, 97,103,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,
  0, 25,  0,  0,  0, 14, 64,118, 97,114,105, 97, 98,108,101, 46,108,117, 97,  0,
  0,  0,  0,152,  6,  3, 60, 26, 15,  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 27,
 15,  2, 13,  1, 11,  4, 42, 13,  0, 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 28,
 15,  2, 13,  1, 11,  8, 42, 13,  0, 18,  9, 42, 11,  7, 42,  2,  0,  1, 60, 29,
 15,  2, 13,  1, 11, 10, 42, 13,  0, 18, 11, 42, 11,  7, 42,  2,  0,  1, 60, 30,
 15,  2, 13,  1, 11, 12, 42, 13,  0, 18, 13, 42, 11,  7, 42,  2,  0,  1, 60, 31,
 15,  2, 13,  1, 11, 14, 42, 13,  0, 18, 15, 42, 11,  7, 42,  2,  0,  1, 60, 32,
 15,  2, 13,  1, 11, 16, 42, 13,  0, 18, 17, 42, 11,  7, 42,  2,  0,  1, 60, 33,
 15,  2, 13,  1, 11, 18, 42, 13,  2, 42,  2,  0,  1, 60, 34,  0,  0,  0,  0,  3,
  0,  0,  0, 25,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 25,  0,  0,  0,
  6,105,100,101,110,116,  0,  0,  0,  0, 25,  0,  0,  0,  6, 99,108,111,115,101,
  0,  0,  0,  0, 19,  2,  0,  0,  0,  6,105,100,101,110,116,  0,  2,  0,  0,  0,
  6, 99,108,111,115,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  2,  0,
  0,  0, 10, 86, 97,114,105, 97, 98,108,101,123,  0,  2,  0,  0,  0, 10, 32,109,
111,100, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,
  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  3, 39, 44,  0,  2,  0,  0,  0, 10,
 32,116,121,112,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,116,121,112,101,  0,
  2,  0,  0,  0, 10, 32,112,116,114, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,
112,116,114,  0,  2,  0,  0,  0, 10, 32,110, 97,109,101, 32, 61, 32, 39,  0,  2,
  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 10, 32,100,101,102, 32, 32,
 61, 32, 39,  0,  2,  0,  0,  0,  4,100,101,102,  0,  2,  0,  0,  0, 10, 32,114,
101,116, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,114,101,116,  0,  2,  0,  0,
  0,  2,125,  0,  2,  0,  0,  0,  9,103,101,116,118, 97,108,117,101,  0,  4,  0,
  0,  0, 37,  0,  0,  0, 14, 64,118, 97,114,105, 97, 98,108,101, 46,108,117, 97,
  0,  0,  0,  0, 60,  5,  3, 60, 38, 13,  1, 48,  2, 13,  2, 52, 16, 60, 39, 13,
  1, 11,  2, 42, 13,  0, 18,  4, 42,  1,  3, 50, 29, 60, 40, 13,  1, 52, 13, 60,
 41, 11,  5, 13,  0, 18,  4, 42,  1,  3, 50, 10, 60, 43, 13,  0, 18,  4,  1,  3,
 60, 44, 60, 45,  0,  0,  0,  0,  3,  0,  0,  0, 37,  0,  0,  0,  5,115,101,108,
102,  0,  0,  0,  0, 37,  0,  0,  0,  6, 99,108, 97,115,115,  0,  0,  0,  0, 37,
  0,  0,  0,  7,115,116, 97,116,105, 99,  0,  0,  0,  0,  6,  2,  0,  0,  0,  6,
 99,108, 97,115,115,  0,  2,  0,  0,  0,  7,115,116, 97,116,105, 99,  0,  2,  0,
  0,  0,  3, 58, 58,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,
  5,110, 97,109,101,  0,  2,  0,  0,  0,  7,115,101,108,102, 45, 62,  0,  2,  0,
  0,  0,  8,115,117,112, 99,111,100,101,  0,  4,  0,  0,  0, 48,  0,  0,  0, 14,
 64,118, 97,114,105, 97, 98,108,101, 46,108,117, 97,  0,  0,  0,  3,189, 17,  1,
 60, 49, 13,  0, 20,  2,  2,  1,  1, 60, 52, 13,  1, 52, 21, 60, 53, 15,  3, 11,
  4, 13,  0, 18,  5, 11,  6, 13,  1, 11,  7,  2,  0,  5, 50, 17, 60, 55, 15,  3,
 11,  4, 13,  0, 18,  5, 11,  7,  2,  0,  3, 60, 56, 60, 57, 13,  0, 11,  8, 13,
  0, 20,  9, 11, 10,  2,  1,  2, 26, 60, 58, 15,  3, 11, 11, 13,  0, 18,  8, 11,
 12,  2,  0,  3, 60, 59, 15,  3, 11, 13,  2,  0,  1, 60, 62, 15, 16, 13,  0, 18,
 17, 11, 18,  2,  3,  2, 60, 63, 13,  1, 48,  5, 13,  4,  4,  0, 32, 52, 39, 60,
 64, 15,  3, 11, 19, 13,  1, 11, 20, 11, 21,  2,  0,  4, 60, 65, 15,  3, 11, 22,
 13,  1, 11, 23,  2,  0,  3, 60, 66, 15,  3, 11, 24,  2,  0,  1, 50, 35, 60, 67,
 13,  4, 52, 27, 60, 68, 13,  0, 11, 17, 15, 16, 13,  0, 18, 17, 11, 25,  2,  3,
  2, 27,  2, 23,  3, 23,  3,  5,  2, 50,  2, 60, 69, 60, 73, 13,  1, 48,  5, 13,
  4,  4,  0, 32, 52, 19, 60, 74, 15,  3, 11, 26, 13,  0, 18,  5, 42, 11, 27, 42,
  2,  0,  1, 50,  2, 60, 75, 60, 78, 15, 29, 13,  0, 18, 30,  2,  1,  1, 60, 79,
 13,  5, 11, 31, 32, 52, 32, 60, 80, 15,  3, 11, 32, 13,  5, 42, 11, 33, 42, 13,
  0, 20, 34, 13,  1, 13,  4,  2,  1,  3, 42, 11, 35, 42,  2,  0,  1, 50,124, 60,
 81, 13,  5, 52, 32, 60, 82, 15,  3, 11, 32, 13,  5, 42, 11, 22, 42, 13,  0, 20,
 34, 13,  1, 13,  4,  2,  1,  3, 42, 11, 35, 42,  2,  0,  1, 50, 86, 60, 84, 13,
  0, 18, 36, 11, 37, 32, 46,  7, 13,  0, 18, 36, 11, 38, 32, 52, 32, 60, 85, 15,
  3, 11, 39, 13,  0, 20, 34, 13,  1, 13,  4,  2,  1,  3, 42, 11, 40, 42, 13,  0,
 18, 41, 11, 35,  2,  0,  3, 50, 32, 60, 87, 15,  3, 11, 42, 13,  0, 20, 34, 13,
  1, 13,  4,  2,  1,  3, 42, 11, 40, 42, 13,  0, 18, 41, 11, 35,  2,  0,  3, 60,
 88, 60, 89, 60, 90, 15,  3, 11, 43,  2,  0,  1, 60, 91, 15,  3, 11, 44,  2,  0,
  1, 60, 94, 15, 16, 13,  0, 18, 17, 11, 45,  2,  1,  2, 44, 51,  2,  0, 60, 95,
 13,  1, 52, 21, 60, 96, 15,  3, 11, 46, 13,  0, 18,  5, 11,  6, 13,  1, 11,  7,
  2,  0,  5, 50, 17, 60, 98, 15,  3, 11, 46, 13,  0, 18,  5, 11,  7,  2,  0,  3,
 60, 99, 60,100, 13,  0, 11, 47, 13,  0, 20,  9, 11, 48,  2,  1,  2, 26, 60,101,
 15,  3, 11, 11, 13,  0, 18, 47, 11, 12,  2,  0,  3, 60,102, 15,  3, 11, 13,  2,
  0,  1, 60,105,  7,  1, 60,106, 13,  1, 48,  5, 13,  4,  4,  0, 32, 52, 65, 60,
107, 15,  3, 11, 19, 13,  1, 11, 20, 11, 21,  2,  0,  4, 60,108, 15,  3, 11, 22,
 13,  1, 11, 23,  2,  0,  3, 60,109, 15,  3, 11, 24,  2,  0,  1, 60,111, 15,  3,
 11, 26, 13,  0, 18,  5, 42, 11, 27, 42,  2,  0,  1, 60,112, 13,  6,  7,  1, 37,
 23,  6, 50, 44, 60,113, 13,  4, 52, 36, 60,114, 13,  0, 11, 17, 15, 16, 13,  0,
 18, 17, 11, 25,  2,  3,  2, 27,  2, 23,  3, 23,  3,  5,  2, 60,115, 13,  6,  7,
  1, 37, 23,  6, 50,  2, 60,116, 60,119, 15,  3, 11, 50, 13,  0, 20, 51, 13,  6,
  2,  1,  2, 42, 11, 52, 42,  2,  0,  1, 60,120, 15,  3, 11, 53,  2,  0,  1, 60,
123, 11, 38, 60,124, 13,  0, 18, 36, 11, 38, 31, 52,  4, 11, 20, 23,  7, 60,125,
 15,  3, 11, 19,  2,  0,  1, 60,126, 13,  1, 48,  2, 13,  4, 52, 19, 60,127, 15,
  3, 13,  1, 11, 54, 42, 13,  0, 18,  5, 42,  2,  0,  1, 50, 35, 60,128, 13,  1,
 52, 16, 60,129, 15,  3, 11, 55, 13,  0, 18,  5, 42,  2,  0,  1, 50, 13, 60,131,
 15,  3, 13,  0, 18,  5,  2,  0,  1, 60,132, 60,133, 15, 29, 13,  0, 18, 30,  2,
  1,  1, 60,134, 15,  3, 11, 56,  2,  0,  1, 60,135, 13,  8, 44, 48,  5, 13,  7,
 11, 38, 32, 52,  7, 15,  3, 11, 20,  2,  0,  1, 60,136, 15,  3, 11, 57, 13,  0,
 18, 17, 13,  0, 18, 30,  2,  0,  3, 60,137, 13,  8, 44, 52, 11, 60,138, 15,  3,
 11, 20,  2,  0,  1, 50,  2, 60,139, 60,140, 15,  3, 11, 58,  2,  0,  1, 60,141,
  7,  0, 60,142, 13,  0, 18, 59, 11, 38, 31, 52,  6, 13,  0, 18, 59, 23,  9, 60,
143, 13,  8, 52, 24, 60,144, 15,  3, 11, 60, 13,  8, 42, 11, 22, 13,  6, 11, 40,
 13,  9, 11, 61,  2,  0,  6, 50, 19, 60,146, 15,  3, 11, 62, 13,  6, 11, 40, 13,
  9, 11, 61,  2,  0,  5, 60,147, 60,148, 15,  3, 11, 43,  2,  0,  1, 60,149, 15,
  3, 11, 44,  2,  0,  1,  5,  4, 50,  2, 60,150, 60,152,  0,  0,  0,  0, 14,  0,
  0,  0, 48,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 49,  0,  0,  0,  6,
 99,108, 97,115,115,  0,  0,  0,  0, 62,  0,  0,  0,  2, 95,  0,  0,  0,  0, 62,
  0,  0,  0,  2, 95,  0,  0,  0,  0, 62,  0,  0,  0,  7,115,116, 97,116,105, 99,
  0,  0,  0,  0, 78,  0,  0,  0,  2,116,  0,  0,  0,  0,105,  0,  0,  0,  5,110,
 97,114,103,  0,  0,  0,  0,123,  0,  0,  0,  4,112,116,114,  0,  0,  0,  0,133,
  0,  0,  0,  2,116,  0,  0,  0,  0,141,  0,  0,  0,  4,100,101,102,  0,  0,  0,
  0,149,  0,  0,  0,  0,  0,  0,  0,149,  0,  0,  0,  0,  0,  0,  0,149,  0,  0,
  0,  0,  0,  0,  0,149,  0,  0,  0,  0,  0,  0,  0, 63,  2,  0,  0,  0,  6, 99,
108, 97,115,115,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,
105,110, 99,108, 97,115,115,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,
  2,  0,  0,  0, 17, 47, 42, 32,103,101,116, 32,102,117,110, 99,116,105,111,110,
 58,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 11, 32,111,102,
 32, 99,108, 97,115,115, 32,  0,  2,  0,  0,  0,  4, 32, 42, 47,  0,  2,  0,  0,
  0,  9, 99,103,101,116,110, 97,109,101,  0,  2,  0,  0,  0, 10, 99,102,117,110,
 99,110, 97,109,101,  0,  2,  0,  0,  0, 11,116,111,108,117, 97, 73, 95,103,101,
116,  0,  2,  0,  0,  0, 12,115,116, 97,116,105, 99, 32,118,111,105,100,  0,  2,
  0,  0,  0,  7, 40,118,111,105,100, 41,  0,  2,  0,  0,  0,  2,123,  0,  2,  0,
  0,  0,  2, 95,  0,  2,  0,  0,  0,  7,115,116, 97,116,105, 99,  0,  2,  0,  0,
  0,  8,115,116,114,102,105,110,100,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,
  0,  0,  0, 13, 94, 37,115, 42, 40,115,116, 97,116,105, 99, 41,  0,  2,  0,  0,
  0,  2, 32,  0,  2,  0,  0,  0,  2, 42,  0,  2,  0,  0,  0,  8,115,101,108,102,
 32, 61, 32,  0,  2,  0,  0,  0,  2, 40,  0,  2,  0,  0,  0,  4, 42, 41, 32,  0,
  2,  0,  0,  0, 24,116,111,108,117, 97, 95,103,101,116,117,115,101,114,116,121,
112,101, 40, 49, 44, 48, 41, 59,  0,  2,  0,  0,  0, 20, 94, 37,115, 42,115,116,
 97,116,105, 99, 37,115, 37,115, 42, 40, 46, 42, 41,  0,  2,  0,  0,  0, 65, 32,
 32,105,102, 32, 40, 33,115,101,108,102, 41, 32,116,111,108,117, 97, 95,101,114,
114,111,114, 40, 34,105,110,118, 97,108,105,100, 32, 39,115,101,108,102, 39, 32,
105,110, 32, 97, 99, 99,101,115,115,105,110,103, 32,118, 97,114,105, 97, 98,108,
101, 32, 39,  0,  2,  0,  0,  0,  5, 39, 34, 41, 59,  0,  2,  0,  0,  0,  2,116,
  0,  2,  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,  0,  5,116,
121,112,101,  0,  2,  0,  0,  0,  7,110,117,109, 98,101,114,  0,  2,  0,  0,  0,
 13, 32, 32,116,111,108,117, 97, 95,112,117,115,104,  0,  2,  0,  0,  0, 10, 40,
 40,100,111,117, 98,108,101, 41,  0,  2,  0,  0,  0,  9,103,101,116,118, 97,108,
117,101,  0,  2,  0,  0,  0,  3, 41, 59,  0,  2,  0,  0,  0,  4,112,116,114,  0,
  2,  0,  0,  0,  2, 38,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0, 30, 32, 32,
116,111,108,117, 97, 95,112,117,115,104,117,115,101,114,116,121,112,101, 40, 40,
118,111,105,100, 42, 41, 38,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  4,
116, 97,103,  0,  2,  0,  0,  0, 29, 32, 32,116,111,108,117, 97, 95,112,117,115,
104,117,115,101,114,116,121,112,101, 40, 40,118,111,105,100, 42, 41,  0,  2,  0,
  0,  0,  2,125,  0,  2,  0,  0,  0,  2, 10,  0,  2,  0,  0,  0,  6, 99,111,110,
115,116,  0,  2,  0,  0,  0, 17, 47, 42, 32,115,101,116, 32,102,117,110, 99,116,
105,111,110, 58,  0,  2,  0,  0,  0,  9, 99,115,101,116,110, 97,109,101,  0,  2,
  0,  0,  0, 11,116,111,108,117, 97, 73, 95,115,101,116,  0,  2,  0,  0,  0,  5,
110, 97,114,103,  0,  2,  0,  0,  0,  8, 32, 32,105,102, 32, 40, 33,  0,  2,  0,
  0,  0, 13,111,117,116, 99,104,101, 99,107,116,121,112,101,  0,  2,  0,  0,  0,
  2, 41,  0,  2,  0,  0,  0, 58, 32, 32, 32,116,111,108,117, 97, 95,101,114,114,
111,114, 40, 34, 35,118,105,110,118, 97,108,105,100, 32,116,121,112,101, 32,105,
110, 32,118, 97,114,105, 97, 98,108,101, 32, 97,115,115,105,103,110,109,101,110,
116, 46, 34, 41, 59,  0,  2,  0,  0,  0,  3, 58, 58,  0,  2,  0,  0,  0,  7,115,
101,108,102, 45, 62,  0,  2,  0,  0,  0,  4, 32, 61, 32,  0,  2,  0,  0,  0,  3,
 40, 40,  0,  2,  0,  0,  0,  3, 41, 32,  0,  2,  0,  0,  0,  4,100,101,102,  0,
  2,  0,  0,  0, 10,116,111,108,117, 97, 95,103,101,116,  0,  2,  0,  0,  0,  4,
 41, 41, 59,  0,  2,  0,  0,  0, 19,116,111,108,117, 97, 95,103,101,116,117,115,
101,114,116,121,112,101, 40,  0,  2,  0,  0,  0,  9,114,101,103,105,115,116,101,
114,  0,  4,  0,  0,  0,154,  0,  0,  0, 14, 64,118, 97,114,105, 97, 98,108,101,
 46,108,117, 97,  0,  0,  0,  0,185,  5,  1, 60,155, 13,  0, 20,  2,  2,  1,  1,
 46,  7, 13,  0, 20,  3,  2,  1,  1, 60,156, 13,  1, 52, 84, 60,157, 13,  0, 18,
  4, 52, 41, 60,158, 15,  5, 11,  6, 13,  1, 42, 11,  7, 42, 13,  0, 18,  8, 42,
 11,  9, 42, 13,  0, 18, 10, 42, 11, 11, 42, 13,  0, 18,  4, 42, 11, 12, 42,  2,
  0,  1, 50, 33, 60,160, 15,  5, 11,  6, 13,  1, 42, 11,  7, 42, 13,  0, 18,  8,
 42, 11,  9, 42, 13,  0, 18, 10, 42, 11, 13, 42,  2,  0,  1, 60,161, 50, 72, 60,
163, 13,  0, 18,  4, 52, 35, 60,164, 15,  5, 11, 14, 13,  0, 18,  8, 42, 11,  9,
 42, 13,  0, 18, 10, 42, 11, 11, 42, 13,  0, 18,  4, 42, 11, 12, 42,  2,  0,  1,
 50, 27, 60,166, 15,  5, 11, 14, 13,  0, 18,  8, 42, 11,  9, 42, 13,  0, 18, 10,
 42, 11, 13, 42,  2,  0,  1, 60,167, 60,168, 60,169,  0,  0,  0,  0,  2,  0,  0,
  0,154,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,155,  0,  0,  0,  7,112,
 97,114,101,110,116,  0,  0,  0,  0, 15,  2,  0,  0,  0,  7,112, 97,114,101,110,
116,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,105,110, 99,
108, 97,115,115,  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,108,101,  0,  2,
  0,  0,  0,  9, 99,115,101,116,110, 97,109,101,  0,  2,  0,  0,  0,  7,111,117,
116,112,117,116,  0,  2,  0,  0,  0, 18, 32,116,111,108,117, 97, 95,116, 97, 98,
108,101,118, 97,114, 40, 34,  0,  2,  0,  0,  0,  4, 34, 44, 34,  0,  2,  0,  0,
  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,  3, 34, 44,  0,  2,  0,  0,  0,
  9, 99,103,101,116,110, 97,109,101,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,
  0,  3, 41, 59,  0,  2,  0,  0,  0,  8, 44, 78, 85, 76, 76, 41, 59,  0,  2,  0,
  0,  0, 19, 32,116,111,108,117, 97, 95,103,108,111, 98, 97,108,118, 97,114, 40,
 34,  0,  2,  0,  0,  0, 11,117,110,114,101,103,105,115,116,101,114,  0,  4,  0,
  0,  0,171,  0,  0,  0, 14, 64,118, 97,114,105, 97, 98,108,101, 46,108,117, 97,
  0,  0,  0,  0, 52,  4,  1, 60,172, 13,  0, 20,  1,  2,  1,  1,  4,  0, 32, 48,
 10, 13,  0, 20,  2,  2,  1,  1,  4,  0, 32, 52, 19, 60,173, 15,  3, 11,  4, 13,
  0, 18,  5, 42, 11,  6, 42,  2,  0,  1, 50,  2, 60,174, 60,175,  0,  0,  0,  0,
  1,  0,  0,  0,171,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  7,  2,  0,
  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,105,110, 99,108, 97,115,115,
  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,108,101,  0,  2,  0,  0,  0,  7,
111,117,116,112,117,116,  0,  2,  0,  0,  0, 35, 32,108,117, 97, 95,112,117,115,
104,110,105,108, 40, 41, 59, 32,108,117, 97, 95,114, 97,119,115,101,116,103,108,
111, 98, 97,108, 40, 34,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,
  0,  0,  4, 34, 41, 59,  0,  2,  0,  0,  0, 10, 95, 86, 97,114,105, 97, 98,108,
101,  0,  4,  0,  0,  0,179,  0,  0,  0, 14, 64,118, 97,114,105, 97, 98,108,101,
 46,108,117, 97,  0,  0,  0,  0, 40,  4,  1, 60,180, 13,  0, 11,  1, 15,  2, 26,
 60,181, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60,182, 15,  5, 13,  0,  2,  0,  1,
 60,183, 13,  0,  1,  1, 60,184,  0,  0,  0,  0,  1,  0,  0,  0,179,  0,  0,  0,
  2,116,  0,  0,  0,  0,  6,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6, 95,
 98, 97,115,101,  0,  2,  0,  0,  0, 14, 99,108, 97,115,115, 86, 97,114,105, 97,
 98,108,101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0,
 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  7, 97,112,112,101,
110,100,  0,  2,  0,  0,  0,  9, 86, 97,114,105, 97, 98,108,101,  0,  4,  0,  0,
  0,188,  0,  0,  0, 14, 64,118, 97,114,105, 97, 98,108,101, 46,108,117, 97,  0,
  0,  0,  0, 21,  5,  1, 60,189, 15,  1, 15,  2, 13,  0, 11,  3,  2,  1,  2,  3,
  1,  1, 60,190,  0,  0,  0,  0,  1,  0,  0,  0,188,  0,  0,  0,  2,115,  0,  0,
  0,  0,  4,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0, 10, 95, 86, 97,114,105,
 97, 98,108,101,  0,  2,  0,  0,  0, 12, 68,101, 99,108, 97,114, 97,116,105,111,
110,  0,  2,  0,  0,  0,  4,118, 97,114,  0,
};

/* array.lo */
static char B12[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 11, 64, 97,114,114, 97,121,
 46,108,117, 97,  0,  0,  0,  0, 87,  3,  0, 60, 18, 22,  1, 60, 19, 11,  1, 15,
  2, 30,  0, 60, 20, 25,  0, 60, 22, 15,  3, 15,  0, 15,  4,  2,  0,  2, 60, 25,
 15,  0, 11,  5, 11,  6, 26, 60, 38, 15,  0, 11,  7, 11,  8, 26, 60, 49, 15,  0,
 11,  9, 11, 10, 26, 60,167, 15,  0, 11, 11, 11, 12, 26, 60,184, 15,  0, 11, 13,
 11, 14, 26, 60,192, 11, 16, 25, 15, 60,201, 11, 18, 25, 17,  0,  0,  0,  0,  0,
  0,  0,  0, 19,  2,  0,  0,  0, 11, 99,108, 97,115,115, 65,114,114, 97,121,  0,
  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 17, 99,108, 97,115,
115, 68,101, 99,108, 97,114, 97,116,105,111,110,  0,  2,  0,  0,  0,  7,115,101,
116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,
  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0, 25,  0,  0,  0, 11,
 64, 97,114,114, 97,121, 46,108,117, 97,  0,  0,  0,  0,172,  6,  3, 60, 26, 15,
  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 27, 15,  2, 13,  1, 11,  4, 42, 13,  0,
 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 28, 15,  2, 13,  1, 11,  8, 42, 13,  0,
 18,  9, 42, 11,  7, 42,  2,  0,  1, 60, 29, 15,  2, 13,  1, 11, 10, 42, 13,  0,
 18, 11, 42, 11,  7, 42,  2,  0,  1, 60, 30, 15,  2, 13,  1, 11, 12, 42, 13,  0,
 18, 13, 42, 11,  7, 42,  2,  0,  1, 60, 31, 15,  2, 13,  1, 11, 14, 42, 13,  0,
 18, 15, 42, 11,  7, 42,  2,  0,  1, 60, 32, 15,  2, 13,  1, 11, 16, 42, 13,  0,
 18, 17, 42, 11,  7, 42,  2,  0,  1, 60, 33, 15,  2, 13,  1, 11, 18, 42, 13,  0,
 18, 19, 42, 11,  7, 42,  2,  0,  1, 60, 34, 15,  2, 13,  1, 11, 20, 42, 13,  2,
 42,  2,  0,  1, 60, 35,  0,  0,  0,  0,  3,  0,  0,  0, 25,  0,  0,  0,  5,115,
101,108,102,  0,  0,  0,  0, 25,  0,  0,  0,  6,105,100,101,110,116,  0,  0,  0,
  0, 25,  0,  0,  0,  6, 99,108,111,115,101,  0,  0,  0,  0, 21,  2,  0,  0,  0,
  6,105,100,101,110,116,  0,  2,  0,  0,  0,  6, 99,108,111,115,101,  0,  2,  0,
  0,  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0,  7, 65,114,114, 97,121,123,
  0,  2,  0,  0,  0, 10, 32,109,111,100, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,
  5,115,101,108,102,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  3,
 39, 44,  0,  2,  0,  0,  0, 10, 32,116,121,112,101, 32, 61, 32, 39,  0,  2,  0,
  0,  0,  5,116,121,112,101,  0,  2,  0,  0,  0, 10, 32,112,116,114, 32, 32, 61,
 32, 39,  0,  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0, 10, 32,110, 97,
109,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,
  0, 10, 32,100,101,102, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,100,101,102,
  0,  2,  0,  0,  0, 10, 32,100,105,109, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,
  4,100,105,109,  0,  2,  0,  0,  0, 10, 32,114,101,116, 32, 32, 61, 32, 39,  0,
  2,  0,  0,  0,  4,114,101,116,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0,
  9,103,101,116,118, 97,108,117,101,  0,  4,  0,  0,  0, 38,  0,  0,  0, 11, 64,
 97,114,114, 97,121, 46,108,117, 97,  0,  0,  0,  0, 69,  5,  3, 60, 39, 13,  1,
 48,  2, 13,  2, 52, 19, 60, 40, 13,  1, 11,  2, 42, 13,  0, 18,  4, 42, 11,  5,
 42,  1,  3, 50, 35, 60, 41, 13,  1, 52, 16, 60, 42, 11,  6, 13,  0, 18,  4, 42,
 11,  5, 42,  1,  3, 50, 13, 60, 44, 13,  0, 18,  4, 11,  5, 42,  1,  3, 60, 45,
 60, 46,  0,  0,  0,  0,  3,  0,  0,  0, 38,  0,  0,  0,  5,115,101,108,102,  0,
  0,  0,  0, 38,  0,  0,  0,  6, 99,108, 97,115,115,  0,  0,  0,  0, 38,  0,  0,
  0,  7,115,116, 97,116,105, 99,  0,  0,  0,  0,  7,  2,  0,  0,  0,  6, 99,108,
 97,115,115,  0,  2,  0,  0,  0,  7,115,116, 97,116,105, 99,  0,  2,  0,  0,  0,
  3, 58, 58,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,110,
 97,109,101,  0,  2,  0,  0,  0, 15, 91,116,111,108,117, 97, 73, 95,105,110,100,
101,120, 93,  0,  2,  0,  0,  0,  7,115,101,108,102, 45, 62,  0,  2,  0,  0,  0,
  8,115,117,112, 99,111,100,101,  0,  4,  0,  0,  0, 49,  0,  0,  0, 11, 64, 97,
114,114, 97,121, 46,108,117, 97,  0,  0,  0,  4, 21, 17,  1, 60, 50, 13,  0, 20,
  2,  2,  1,  1, 60, 53, 13,  1, 52, 21, 60, 54, 15,  3, 11,  4, 13,  0, 18,  5,
 11,  6, 13,  1, 11,  7,  2,  0,  5, 50, 17, 60, 56, 15,  3, 11,  4, 13,  0, 18,
  5, 11,  7,  2,  0,  3, 60, 57, 60, 58, 13,  0, 11,  8, 13,  0, 20,  9, 11, 10,
  2,  1,  2, 26, 60, 59, 15,  3, 11, 11, 13,  0, 18,  8, 11, 12,  2,  0,  3, 60,
 60, 15,  3, 11, 13,  2,  0,  1, 60, 63, 15,  3, 11, 14,  2,  0,  1, 60, 66, 15,
 17, 13,  0, 18, 18, 11, 19,  2,  3,  2, 60, 67, 13,  1, 48,  5, 13,  4,  4,  0,
 32, 52, 66, 60, 68, 15,  3, 11, 20, 13,  1, 11, 21, 11, 22,  2,  0,  4, 60, 69,
 15,  3, 11, 23,  2,  0,  1, 60, 70, 15,  3, 11, 24,  2,  0,  1, 60, 71, 15,  3,
 11, 25,  2,  0,  1, 60, 72, 15,  3, 11, 26, 13,  1, 11, 27,  2,  0,  3, 60, 73,
 15,  3, 11, 28,  2,  0,  1, 50, 35, 60, 74, 13,  4, 52, 27, 60, 75, 13,  0, 11,
 18, 15, 17, 13,  0, 18, 18, 11, 29,  2,  3,  2, 27,  2, 23,  3, 23,  3,  5,  2,
 50,  2, 60, 76, 60, 79, 15,  3, 11, 30,  2,  0,  1, 60, 80, 15,  3, 11, 31,  2,
  0,  1, 60, 81, 15,  3, 11, 32,  2,  0,  1, 60, 82, 15,  3, 11, 33, 13,  0, 18,
 34, 42, 11, 35, 42,  2,  0,  1, 60, 83, 15,  3, 11, 36,  2,  0,  1, 60, 86, 15,
 38, 13,  0, 18, 39,  2,  1,  1, 60, 87, 13,  5, 11, 40, 32, 52, 32, 60, 88, 15,
  3, 11, 41, 13,  5, 42, 11, 42, 42, 13,  0, 20, 43, 13,  1, 13,  4,  2,  1,  3,
 42, 11, 44, 42,  2,  0,  1, 50,124, 60, 89, 13,  5, 52, 32, 60, 90, 15,  3, 11,
 41, 13,  5, 42, 11, 26, 42, 13,  0, 20, 43, 13,  1, 13,  4,  2,  1,  3, 42, 11,
 44, 42,  2,  0,  1, 50, 86, 60, 92, 13,  0, 18, 45, 11, 46, 32, 46,  7, 13,  0,
 18, 45, 11, 47, 32, 52, 32, 60, 93, 15,  3, 11, 48, 13,  0, 20, 43, 13,  1, 13,
  4,  2,  1,  3, 42, 11, 49, 42, 13,  0, 18, 50, 11, 44,  2,  0,  3, 50, 32, 60,
 95, 15,  3, 11, 51, 13,  0, 20, 43, 13,  1, 13,  4,  2,  1,  3, 42, 11, 49, 42,
 13,  0, 18, 50, 11, 44,  2,  0,  3, 60, 96, 60, 97, 60, 98, 15,  3, 11, 52,  2,
  0,  1, 60, 99, 15,  3, 11, 53,  2,  0,  1, 60,102, 15, 17, 13,  0, 18, 18, 11,
 54,  2,  1,  2, 44, 51,  2, 33, 60,103, 13,  1, 52, 21, 60,104, 15,  3, 11, 55,
 13,  0, 18,  5, 11,  6, 13,  1, 11,  7,  2,  0,  5, 50, 17, 60,106, 15,  3, 11,
 55, 13,  0, 18,  5, 11,  7,  2,  0,  3, 60,107, 60,108, 13,  0, 11, 56, 13,  0,
 20,  9, 11, 57,  2,  1,  2, 26, 60,109, 15,  3, 11, 11, 13,  0, 18, 56, 11, 12,
  2,  0,  3, 60,110, 15,  3, 11, 13,  2,  0,  1, 60,113, 15,  3, 11, 14,  2,  0,
  1, 60,116, 15, 17, 13,  0, 18, 18, 11, 19,  2,  3,  2, 60,117, 13,  1, 48,  5,
 13,  8,  4,  0, 32, 52, 66, 60,118, 15,  3, 11, 20, 13,  1, 11, 21, 11, 22,  2,
  0,  4, 60,119, 15,  3, 11, 23,  2,  0,  1, 60,120, 15,  3, 11, 24,  2,  0,  1,
 60,121, 15,  3, 11, 25,  2,  0,  1, 60,122, 15,  3, 11, 26, 13,  1, 11, 27,  2,
  0,  3, 60,123, 15,  3, 11, 28,  2,  0,  1, 50, 35, 60,124, 13,  8, 52, 27, 60,
125, 13,  0, 11, 18, 15, 17, 13,  0, 18, 18, 11, 29,  2,  3,  2, 27,  2, 23,  7,
 23,  7,  5,  2, 50,  2, 60,126, 60,129, 15,  3, 11, 30,  2,  0,  1, 60,130, 15,
  3, 11, 31,  2,  0,  1, 60,131, 15,  3, 11, 32,  2,  0,  1, 60,132, 15,  3, 11,
 33, 13,  0, 18, 34, 42, 11, 35, 42,  2,  0,  1, 60,133, 15,  3, 11, 36,  2,  0,
  1, 60,136, 11, 47, 60,137, 13,  0, 18, 45, 11, 47, 31, 52,  4, 11, 21, 23,  9,
 60,138, 15,  3, 11, 20,  2,  0,  1, 60,139, 13,  1, 48,  2, 13,  8, 52, 22, 60,
140, 15,  3, 13,  1, 11, 58, 42, 13,  0, 18,  5, 42, 11, 59, 42,  2,  0,  1, 50,
 41, 60,141, 13,  1, 52, 19, 60,142, 15,  3, 11, 60, 13,  0, 18,  5, 42, 11, 59,
 42,  2,  0,  1, 50, 16, 60,144, 15,  3, 13,  0, 18,  5, 11, 59, 42,  2,  0,  1,
 60,145, 60,146, 15, 38, 13,  0, 18, 39,  2,  1,  1, 60,147, 15,  3, 11, 61,  2,
  0,  1, 60,148, 13, 10, 44, 48,  5, 13,  9, 11, 47, 32, 52,  7, 15,  3, 11, 21,
  2,  0,  1, 60,149, 15,  3, 11, 62, 13,  0, 18, 18, 13,  0, 18, 39,  2,  0,  3,
 60,150, 13, 10, 44, 52, 11, 60,151, 15,  3, 11, 21,  2,  0,  1, 50,  2, 60,152,
 60,153, 15,  3, 11, 63,  2,  0,  1, 60,154,  7,  0, 60,155, 13,  0, 18, 64, 11,
 47, 31, 52,  6, 13,  0, 18, 64, 23, 11, 60,156, 13, 10, 52, 20, 60,157, 15,  3,
 11, 65, 13, 10, 42, 11, 66, 13, 11, 11, 67,  2,  0,  4, 50, 15, 60,159, 15,  3,
 11, 68, 13, 11, 11, 67,  2,  0,  3, 60,160, 60,161, 15,  3, 11, 52,  2,  0,  1,
 60,162, 15,  3, 11, 53,  2,  0,  1,  5,  6, 50,  2, 60,163, 60,165,  0,  0,  0,
  0, 18,  0,  0,  0, 49,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 50,  0,
  0,  0,  6, 99,108, 97,115,115,  0,  0,  0,  0, 66,  0,  0,  0,  2, 95,  0,  0,
  0,  0, 66,  0,  0,  0,  2, 95,  0,  0,  0,  0, 66,  0,  0,  0,  7,115,116, 97,
116,105, 99,  0,  0,  0,  0, 86,  0,  0,  0,  2,116,  0,  0,  0,  0,116,  0,  0,
  0,  2, 95,  0,  0,  0,  0,116,  0,  0,  0,  2, 95,  0,  0,  0,  0,116,  0,  0,
  0,  7,115,116, 97,116,105, 99,  0,  0,  0,  0,136,  0,  0,  0,  4,112,116,114,
  0,  0,  0,  0,146,  0,  0,  0,  2,116,  0,  0,  0,  0,154,  0,  0,  0,  4,100,
101,102,  0,  0,  0,  0,162,  0,  0,  0,  0,  0,  0,  0,162,  0,  0,  0,  0,  0,
  0,  0,162,  0,  0,  0,  0,  0,  0,  0,162,  0,  0,  0,  0,  0,  0,  0,162,  0,
  0,  0,  0,  0,  0,  0,162,  0,  0,  0,  0,  0,  0,  0, 69,  2,  0,  0,  0,  6,
 99,108, 97,115,115,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,
  8,105,110, 99,108, 97,115,115,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,
  0,  2,  0,  0,  0, 17, 47, 42, 32,103,101,116, 32,102,117,110, 99,116,105,111,
110, 58,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 11, 32,111,
102, 32, 99,108, 97,115,115, 32,  0,  2,  0,  0,  0,  4, 32, 42, 47,  0,  2,  0,
  0,  0,  9, 99,103,101,116,110, 97,109,101,  0,  2,  0,  0,  0, 10, 99,102,117,
110, 99,110, 97,109,101,  0,  2,  0,  0,  0, 11,116,111,108,117, 97, 73, 95,103,
101,116,  0,  2,  0,  0,  0, 12,115,116, 97,116,105, 99, 32,118,111,105,100,  0,
  2,  0,  0,  0,  7, 40,118,111,105,100, 41,  0,  2,  0,  0,  0,  2,123,  0,  2,
  0,  0,  0, 19, 32,105,110,116, 32,116,111,108,117, 97, 73, 95,105,110,100,101,
120, 59,  0,  2,  0,  0,  0,  2, 95,  0,  2,  0,  0,  0,  7,115,116, 97,116,105,
 99,  0,  2,  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,  0,  0,  0,  4,
109,111,100,  0,  2,  0,  0,  0, 13, 94, 37,115, 42, 40,115,116, 97,116,105, 99,
 41,  0,  2,  0,  0,  0,  2, 32,  0,  2,  0,  0,  0,  2, 42,  0,  2,  0,  0,  0,
  6,115,101,108,102, 59,  0,  2,  0,  0,  0, 34, 32,108,117, 97, 95,112,117,115,
104,111, 98,106,101, 99,116, 40,108,117, 97, 95,103,101,116,112, 97,114, 97,109,
 40, 49, 41, 41, 59,  0,  2,  0,  0,  0, 26, 32,108,117, 97, 95,112,117,115,104,
115,116,114,105,110,103, 40, 34, 46,115,101,108,102, 34, 41, 59,  0,  2,  0,  0,
  0,  9, 32,115,101,108,102, 32, 61, 32,  0,  2,  0,  0,  0,  2, 40,  0,  2,  0,
  0,  0,  4, 42, 41, 32,  0,  2,  0,  0,  0, 36,108,117, 97, 95,103,101,116,117,
115,101,114,100, 97,116, 97, 40,108,117, 97, 95,114, 97,119,103,101,116,116, 97,
 98,108,101, 40, 41, 41, 59,  0,  2,  0,  0,  0, 20, 94, 37,115, 42,115,116, 97,
116,105, 99, 37,115, 37,115, 42, 40, 46, 42, 41,  0,  2,  0,  0,  0, 42, 32,105,
102, 32, 40, 33,116,111,108,117, 97, 95,105,115,116,121,112,101, 40, 50, 44,116,
111,108,117, 97, 95,116, 97,103, 95,110,117,109, 98,101,114, 44, 48, 41, 41,  0,
  2,  0,  0,  0, 50, 32, 32,116,111,108,117, 97, 95,101,114,114,111,114, 40, 34,
105,110,118, 97,108,105,100, 32,116,121,112,101, 32,105,110, 32, 97,114,114, 97,
121, 32,105,110,100,101,120,105,110,103, 46, 34, 41, 59,  0,  2,  0,  0,  0, 45,
 32,116,111,108,117, 97, 73, 95,105,110,100,101,120, 32, 61, 32, 40,105,110,116,
 41,116,111,108,117, 97, 95,103,101,116,110,117,109, 98,101,114, 40, 50, 44, 48,
 41, 45, 49, 59,  0,  2,  0,  0,  0, 38, 32,105,102, 32, 40,116,111,108,117, 97,
 73, 95,105,110,100,101,120, 60, 48, 32,124,124, 32,116,111,108,117, 97, 73, 95,
105,110,100,101,120, 62, 61,  0,  2,  0,  0,  0,  4,100,105,109,  0,  2,  0,  0,
  0,  2, 41,  0,  2,  0,  0,  0, 47, 32, 32,116,111,108,117, 97, 95,101,114,114,
111,114, 40, 34, 97,114,114, 97,121, 32,105,110,100,101,120,105,110,103, 32,111,
117,116, 32,111,102, 32,114, 97,110,103,101, 46, 34, 41, 59,  0,  2,  0,  0,  0,
  2,116,  0,  2,  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,  0,
  5,116,121,112,101,  0,  2,  0,  0,  0,  7,110,117,109, 98,101,114,  0,  2,  0,
  0,  0, 13, 32, 32,116,111,108,117, 97, 95,112,117,115,104,  0,  2,  0,  0,  0,
 10, 40, 40,100,111,117, 98,108,101, 41,  0,  2,  0,  0,  0,  9,103,101,116,118,
 97,108,117,101,  0,  2,  0,  0,  0,  3, 41, 59,  0,  2,  0,  0,  0,  4,112,116,
114,  0,  2,  0,  0,  0,  2, 38,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0, 30,
 32, 32,116,111,108,117, 97, 95,112,117,115,104,117,115,101,114,116,121,112,101,
 40, 40,118,111,105,100, 42, 41, 38,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,
  0,  4,116, 97,103,  0,  2,  0,  0,  0, 29, 32, 32,116,111,108,117, 97, 95,112,
117,115,104,117,115,101,114,116,121,112,101, 40, 40,118,111,105,100, 42, 41,  0,
  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0,  2, 10,  0,  2,  0,  0,  0,  6, 99,
111,110,115,116,  0,  2,  0,  0,  0, 17, 47, 42, 32,115,101,116, 32,102,117,110,
 99,116,105,111,110, 58,  0,  2,  0,  0,  0,  9, 99,115,101,116,110, 97,109,101,
  0,  2,  0,  0,  0, 11,116,111,108,117, 97, 73, 95,115,101,116,  0,  2,  0,  0,
  0,  3, 58, 58,  0,  2,  0,  0,  0, 15, 91,116,111,108,117, 97, 73, 95,105,110,
100,101,120, 93,  0,  2,  0,  0,  0,  7,115,101,108,102, 45, 62,  0,  2,  0,  0,
  0,  4, 32, 61, 32,  0,  2,  0,  0,  0,  3, 40, 40,  0,  2,  0,  0,  0,  3, 41,
 32,  0,  2,  0,  0,  0,  4,100,101,102,  0,  2,  0,  0,  0, 10,116,111,108,117,
 97, 95,103,101,116,  0,  2,  0,  0,  0,  4, 40, 51, 44,  0,  2,  0,  0,  0,  4,
 41, 41, 59,  0,  2,  0,  0,  0, 21,116,111,108,117, 97, 95,103,101,116,117,115,
101,114,116,121,112,101, 40, 51, 44,  0,  2,  0,  0,  0,  9,114,101,103,105,115,
116,101,114,  0,  4,  0,  0,  0,167,  0,  0,  0, 11, 64, 97,114,114, 97,121, 46,
108,117, 97,  0,  0,  0,  0,185,  5,  1, 60,168, 13,  0, 20,  2,  2,  1,  1, 46,
  7, 13,  0, 20,  3,  2,  1,  1, 60,169, 13,  1, 52, 84, 60,170, 13,  0, 18,  4,
 52, 41, 60,171, 15,  5, 11,  6, 13,  1, 42, 11,  7, 42, 13,  0, 18,  8, 42, 11,
  9, 42, 13,  0, 18, 10, 42, 11, 11, 42, 13,  0, 18,  4, 42, 11, 12, 42,  2,  0,
  1, 50, 33, 60,173, 15,  5, 11,  6, 13,  1, 42, 11,  7, 42, 13,  0, 18,  8, 42,
 11,  9, 42, 13,  0, 18, 10, 42, 11, 13, 42,  2,  0,  1, 60,174, 50, 72, 60,176,
 13,  0, 18,  4, 52, 35, 60,177, 15,  5, 11, 14, 13,  0, 18,  8, 42, 11,  9, 42,
 13,  0, 18, 10, 42, 11, 11, 42, 13,  0, 18,  4, 42, 11, 12, 42,  2,  0,  1, 50,
 27, 60,179, 15,  5, 11, 14, 13,  0, 18,  8, 42, 11,  9, 42, 13,  0, 18, 10, 42,
 11, 13, 42,  2,  0,  1, 60,180, 60,181, 60,182,  0,  0,  0,  0,  2,  0,  0,  0,
167,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,168,  0,  0,  0,  7,112, 97,
114,101,110,116,  0,  0,  0,  0, 15,  2,  0,  0,  0,  7,112, 97,114,101,110,116,
  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,105,110, 99,108,
 97,115,115,  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,108,101,  0,  2,  0,
  0,  0,  9, 99,115,101,116,110, 97,109,101,  0,  2,  0,  0,  0,  7,111,117,116,
112,117,116,  0,  2,  0,  0,  0, 20, 32,116,111,108,117, 97, 95,116, 97, 98,108,
101, 97,114,114, 97,121, 40, 34,  0,  2,  0,  0,  0,  4, 34, 44, 34,  0,  2,  0,
  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,  3, 34, 44,  0,  2,  0,  0,
  0,  9, 99,103,101,116,110, 97,109,101,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,
  0,  0,  3, 41, 59,  0,  2,  0,  0,  0,  8, 44, 78, 85, 76, 76, 41, 59,  0,  2,
  0,  0,  0, 21, 32,116,111,108,117, 97, 95,103,108,111, 98, 97,108, 97,114,114,
 97,121, 40, 34,  0,  2,  0,  0,  0, 11,117,110,114,101,103,105,115,116,101,114,
  0,  4,  0,  0,  0,184,  0,  0,  0, 11, 64, 97,114,114, 97,121, 46,108,117, 97,
  0,  0,  0,  0, 52,  4,  1, 60,185, 13,  0, 20,  1,  2,  1,  1,  4,  0, 32, 48,
 10, 13,  0, 20,  2,  2,  1,  1,  4,  0, 32, 52, 19, 60,186, 15,  3, 11,  4, 13,
  0, 18,  5, 42, 11,  6, 42,  2,  0,  1, 50,  2, 60,187, 60,188,  0,  0,  0,  0,
  1,  0,  0,  0,184,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  7,  2,  0,
  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,105,110, 99,108, 97,115,115,
  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,108,101,  0,  2,  0,  0,  0,  7,
111,117,116,112,117,116,  0,  2,  0,  0,  0, 32, 32,108,117, 97, 95,112,117,115,
104,110,105,108, 40, 41, 59, 32,108,117, 97, 95,115,101,116,103,108,111, 98, 97,
108, 40, 34,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,  4,
 34, 41, 59,  0,  2,  0,  0,  0,  7, 95, 65,114,114, 97,121,  0,  4,  0,  0,  0,
192,  0,  0,  0, 11, 64, 97,114,114, 97,121, 46,108,117, 97,  0,  0,  0,  0, 40,
  4,  1, 60,193, 13,  0, 11,  1, 15,  2, 26, 60,194, 15,  3, 13,  0, 15,  4,  2,
  0,  2, 60,195, 15,  5, 13,  0,  2,  0,  1, 60,196, 13,  0,  1,  1, 60,197,  0,
  0,  0,  0,  1,  0,  0,  0,192,  0,  0,  0,  2,116,  0,  0,  0,  0,  6,  2,  0,
  0,  0,  2,116,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0,
 11, 99,108, 97,115,115, 65,114,114, 97,121,  0,  2,  0,  0,  0,  7,115,101,116,
116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,
  0,  0,  0,  7, 97,112,112,101,110,100,  0,  2,  0,  0,  0,  6, 65,114,114, 97,
121,  0,  4,  0,  0,  0,201,  0,  0,  0, 11, 64, 97,114,114, 97,121, 46,108,117,
 97,  0,  0,  0,  0, 21,  5,  1, 60,202, 15,  1, 15,  2, 13,  0, 11,  3,  2,  1,
  2,  3,  1,  1, 60,203,  0,  0,  0,  0,  1,  0,  0,  0,201,  0,  0,  0,  2,115,
  0,  0,  0,  0,  4,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0,  7, 95, 65,114,
114, 97,121,  0,  2,  0,  0,  0, 12, 68,101, 99,108, 97,114, 97,116,105,111,110,
  0,  2,  0,  0,  0,  4,118, 97,114,  0,
};

/* function.lo */
static char B13[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 14, 64,102,117,110, 99,116,
105,111,110, 46,108,117, 97,  0,  0,  0,  0,141, 15,  0, 60, 24, 22,  7, 60, 25,
 11,  1, 11,  2, 11,  3, 60, 26, 11,  2, 11,  4, 60, 27, 11,  2, 11,  5, 60, 28,
 11,  2, 11,  6, 60, 29, 22,  1, 11,  7,  7,  0, 30,  0, 11,  8, 60, 30, 11,  2,
 11,  9, 60, 31, 15, 10, 30,  6, 60, 32, 25,  0, 60, 33, 15, 11, 15,  0, 15, 12,
  2,  0,  2, 60, 36, 15,  0, 11, 13, 11, 14, 26, 60, 51, 15,  0, 11, 15, 11, 16,
 26, 60,232, 15,  0, 11, 17, 11, 18, 26, 60,242, 15,  0, 11, 19, 11, 20, 26, 60,
250, 15,  0, 11, 21, 11, 22, 26, 59,  1, 14, 15,  0, 11, 23, 11, 24, 26, 59,  1,
 21, 11, 26, 25, 25, 59,  1, 49, 11, 28, 25, 27,  0,  0,  0,  0,  0,  0,  0,  0,
 29,  2,  0,  0,  0, 14, 99,108, 97,115,115, 70,117,110, 99,116,105,111,110,  0,
  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  5,
116,121,112,101,  0,  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0,  5,110,
 97,109,101,  0,  2,  0,  0,  0,  5, 97,114,103,115,  0,  2,  0,  0,  0,  2,110,
  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,  0,  0,  0,  6, 95, 98, 97,
115,101,  0,  2,  0,  0,  0, 13, 99,108, 97,115,115, 70,101, 97,116,117,114,101,
  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,
108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  8,100,101, 99,108,116, 97,103,
  0,  4,  0,  0,  0, 36,  0,  0,  0, 14, 64,102,117,110, 99,116,105,111,110, 46,
108,117, 97,  0,  0,  0,  0,141, 10,  1, 60, 37, 13,  0, 20,  1,  2,  1,  1, 48,
  7, 13,  0, 18,  2, 11,  2, 32, 52, 21, 60, 38, 15,  3, 13,  0, 18,  4, 18,  5,
 13,  0, 18,  4, 18,  6,  2,  0,  2, 50,  2, 60, 39, 60, 40, 13,  0, 11,  7, 13,
  0, 11,  8, 15,  9, 13,  0, 18, 10, 15, 11, 13,  0, 18, 12, 11,  2,  2,  1,  2,
  2,  2,  2, 27,  1, 27,  2,  5,  4, 60, 41, 15,  3, 13,  0, 18,  7, 13,  0, 18,
  8,  2,  0,  2, 60, 42,  7,  1, 50, 25, 60, 44, 13,  0, 18, 14, 13,  1, 16, 20,
  3,  2,  0,  1, 60, 45, 13,  1,  7,  1, 37, 23,  1, 60, 46, 60, 43, 13,  0, 18,
 14, 13,  1, 16, 54, 36, 60, 47,  0,  0,  0,  0,  2,  0,  0,  0, 36,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0, 42,  0,  0,  0,  2,105,  0,  0,  0,  0, 15,
  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,105,110, 99,108, 97,
115,115,  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,  0,  0,  0,  8,100,
101, 99,108,116, 97,103,  0,  2,  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,
  0,  0,  0,  7, 99,105,116,121,112,101,  0,  2,  0,  0,  0,  5, 99,116, 97,103,
  0,  2,  0,  0,  0,  6,105,116,121,112,101,  0,  2,  0,  0,  0,  4,116, 97,103,
  0,  2,  0,  0,  0,  7,116, 97,103,118, 97,114,  0,  2,  0,  0,  0,  5,116,121,
112,101,  0,  2,  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,  0,  0,  0,
  4,109,111,100,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  5, 97,114,103,
115,  0,  2,  0,  0,  0,  8,115,117,112, 99,111,100,101,  0,  4,  0,  0,  0, 51,
  0,  0,  0, 14, 64,102,117,110, 99,116,105,111,110, 46,108,117, 97,  0,  0,  0,
  6, 51, 15,  1, 60, 52, 13,  0, 20,  2,  2,  1,  1, 60, 53, 15,  5, 13,  0, 18,
  6, 11,  7,  2,  3,  2, 60, 55, 13,  1, 52, 21, 60, 56, 15,  8, 11,  9, 13,  0,
 18, 10, 11, 11, 13,  1, 11, 12,  2,  0,  5, 50, 17, 60, 58, 15,  8, 11, 13, 13,
  0, 18, 10, 11, 12,  2,  0,  3, 60, 59, 60, 60, 15,  8, 11, 14, 13,  0, 18, 15,
 11, 16,  2,  0,  3, 60, 61, 15,  8, 11, 17,  2,  0,  1, 60, 64, 15,  8, 11, 18,
  2,  0,  1, 60, 66,  4,  0, 60, 67, 13,  1, 52,  6,  7,  2, 23,  5, 50,  4,  7,
  1, 23,  5, 60, 68, 13,  1, 48,  7, 13,  0, 18, 10, 11, 20, 31, 48,  5, 13,  4,
  4,  0, 32, 52, 51, 60, 69, 13,  0, 18, 21, 11, 21, 32, 52, 19, 60, 70, 15,  8,
 11, 22, 13,  0, 18, 23, 18, 24, 11, 25,  2,  0,  3, 50, 19, 60, 72, 15,  8, 11,
 22, 13,  0, 18, 23, 18, 26, 11, 25,  2,  0,  3, 60, 73, 50,  2, 60, 74, 60, 76,
 13,  0, 18, 27,  7,  1, 16, 18, 28, 11, 29, 31, 52, 93, 60, 77,  7,  1, 50, 72,
 60, 79, 15, 31, 13,  0, 18, 27, 13,  6, 16, 18, 28,  2,  1,  1, 11, 32, 31, 52,
 29, 60, 80, 15,  8, 11, 33, 13,  0, 18, 27, 13,  6, 16, 20, 34, 13,  5,  2,  1,
  2, 42, 11, 35, 42,  2,  0,  1, 50,  2, 60, 81, 60, 82, 13,  5,  7,  1, 37, 23,
  5, 60, 83, 13,  6,  7,  1, 37, 23,  6, 60, 84, 60, 78, 13,  0, 18, 27, 13,  6,
 16, 54, 83,  5,  1, 50,  2, 60, 85, 60, 87, 15,  8, 11, 36, 13,  5, 42, 11, 37,
 42,  2,  0,  1, 60, 89, 15,  8, 11, 38,  2,  0,  1, 60, 92,  4,  0, 60, 93, 13,
  1, 52,  6,  7,  2, 23,  6, 50,  4,  7,  1, 23,  6, 60, 94, 13,  1, 48,  7, 13,
  0, 18, 10, 11, 20, 31, 48,  5, 13,  4,  4,  0, 32, 52, 47, 60, 95, 15,  8, 11,
 39, 13,  0, 18, 21, 13,  1, 11, 40, 11, 41,  2,  0,  5, 60, 96, 15,  8, 11, 42,
 13,  0, 18, 21, 13,  1, 11, 43,  2,  0,  4, 60, 97, 15,  8, 11, 44,  2,  0,  1,
 50, 35, 60, 98, 13,  4, 52, 27, 60, 99, 13,  0, 11,  6, 15,  5, 13,  0, 18,  6,
 11, 45,  2,  3,  2, 27,  2, 23,  3, 23,  3,  5,  2, 50,  2, 60,100, 60,102, 13,
  0, 18, 27,  7,  1, 16, 18, 28, 11, 29, 31, 52, 57, 60,103,  7,  1, 50, 36, 60,
105, 13,  0, 18, 27, 13,  7, 16, 20, 46, 13,  6,  2,  0,  2, 60,106, 13,  6,  7,
  1, 37, 23,  6, 60,107, 13,  7,  7,  1, 37, 23,  7, 60,108, 60,104, 13,  0, 18,
 27, 13,  7, 16, 54, 47,  5,  1, 50,  2, 60,109, 60,112, 13,  1, 48,  7, 13,  0,
 18, 10, 11, 20, 31, 48,  5, 13,  4,  4,  0, 32, 52, 19, 60,113, 15,  8, 11, 47,
 13,  0, 18, 10, 42, 11, 48, 42,  2,  0,  1, 50,  2, 60,114, 60,117, 13,  1, 52,
  6,  7,  2, 23,  6, 50,  4,  7,  1, 23,  6, 60,118, 13,  0, 18, 27,  7,  1, 16,
 18, 28, 11, 29, 31, 52, 57, 60,119,  7,  1, 50, 36, 60,121, 13,  0, 18, 27, 13,
  7, 16, 20, 49, 13,  6,  2,  0,  2, 60,122, 13,  6,  7,  1, 37, 23,  6, 60,123,
 13,  7,  7,  1, 37, 23,  7, 60,124, 60,120, 13,  0, 18, 27, 13,  7, 16, 54, 47,
  5,  1, 50,  2, 60,125, 60,128, 13,  1, 48,  7, 13,  0, 18, 10, 11, 50, 32, 52,
 12, 60,129, 15,  8, 11, 51,  2,  0,  1, 49,  2,252, 60,130, 13,  1, 48,  7, 13,
  0, 18, 10, 11, 52, 32, 52, 34, 60,131, 15,  8, 11, 53, 13,  0, 18, 27,  7,  1,
 16, 18, 10, 11, 54, 13,  0, 18, 27,  7,  2, 16, 18, 10, 11, 55,  2,  0,  5, 49,
  2,203, 60,133, 15,  8, 11, 56,  2,  0,  1, 60,134, 13,  0, 18, 28, 11, 57, 31,
 48,  7, 13,  0, 18, 28, 11, 29, 31, 52, 48, 60,135, 15,  8, 11, 58, 13,  0, 18,
  6, 13,  0, 18, 28, 13,  0, 18, 59, 11, 60,  2,  0,  5, 60,136, 15,  8, 11, 42,
 13,  0, 18,  6, 13,  0, 18, 28, 13,  0, 18, 59, 11, 61,  2,  0,  5, 50, 11, 60,
138, 15,  8, 11, 58,  2,  0,  1, 60,139, 60,140, 13,  1, 48,  7, 13,  0, 18, 10,
 11, 20, 32, 52, 15, 60,141, 15,  8, 11, 20, 13,  1, 11, 42,  2,  0,  3, 50, 70,
 60,142, 13,  1, 48,  2, 13,  4, 52, 21, 60,143, 15,  8, 13,  1, 11, 62, 42, 13,
  0, 18, 10, 42, 11, 42,  2,  0,  2, 50, 39, 60,144, 13,  1, 52, 18, 60,145, 15,
  8, 11, 63, 13,  0, 18, 10, 42, 11, 42,  2,  0,  2, 50, 15, 60,147, 15,  8, 13,
  0, 18, 10, 11, 42,  2,  0,  2, 60,148, 60,151,  7,  1, 50, 49, 60,153, 13,  0,
 18, 27, 13,  7, 16, 20, 64,  2,  0,  1, 60,154, 13,  7,  7,  1, 37, 23,  7, 60,
155, 13,  0, 18, 27, 13,  7, 16, 52, 11, 60,156, 15,  8, 11, 65,  2,  0,  1, 50,
  2, 60,157, 60,158, 60,152, 13,  0, 18, 27, 13,  7, 16, 54, 60, 60,160, 15,  8,
 11, 66,  2,  0,  1, 60,163, 13,  0, 18, 28, 11, 57, 31, 48,  7, 13,  0, 18, 28,
 11, 29, 31, 52,220, 60,164, 15, 31, 13,  0, 18, 28,  2,  1,  1, 60,165, 13,  8,
 11, 68, 32, 52, 17, 60,166, 15,  8, 11, 69, 13,  8, 42, 11, 70, 42,  2,  0,  1,
 50,179, 60,167, 13,  8, 52, 17, 60,168, 15,  8, 11, 69, 13,  8, 42, 11, 71, 42,
  2,  0,  1, 50,156, 60,170, 13,  0, 18, 59, 11, 57, 32, 52, 98, 60,171, 15,  8,
 11, 72,  2,  0,  1, 60,172, 15,  8, 11, 73,  2,  0,  1, 60,173, 15,  8, 11, 74,
 13,  0, 18, 28, 11, 71,  2,  0,  3, 60,174, 15,  8, 11, 75,  2,  0,  1, 60,175,
 15,  8, 11, 76, 13,  0, 18, 28, 11, 77,  2,  0,  3, 60,176, 15,  8, 11, 78,  2,
  0,  1, 60,177, 15,  8, 11, 79, 13,  0, 18, 26, 11, 80, 13,  0, 18, 26, 11, 66,
  2,  0,  5, 60,178, 15,  8, 11, 81,  2,  0,  1, 50, 45, 60,180, 13,  0, 18, 59,
 11, 82, 32, 52, 17, 60,181, 15,  8, 11, 83, 13,  0, 18, 26, 11, 66,  2,  0,  3,
 50, 17, 60,183, 15,  8, 11, 84, 13,  0, 18, 26, 11, 66,  2,  0,  3, 60,184, 60,
185,  5,  1, 50,  2, 60,186, 60,187,  7,  1, 50, 25, 60,189, 13,  0, 18, 27, 13,
  8, 16, 20, 85,  2,  0,  1, 60,190, 13,  8,  7,  1, 37, 23,  8, 60,191, 60,188,
 13,  0, 18, 27, 13,  8, 16, 54, 36, 60,192, 15,  8, 11, 86,  2,  0,  1, 60,195,
 13,  1, 52,  6,  7,  2, 23,  6, 50,  4,  7,  1, 23,  6, 60,196, 13,  0, 18, 27,
  7,  1, 16, 18, 28, 11, 29, 31, 52, 57, 60,197,  7,  1, 50, 36, 60,199, 13,  0,
 18, 27, 13,  9, 16, 20, 87, 13,  6,  2,  0,  2, 60,200, 13,  6,  7,  1, 37, 23,
  6, 60,201, 13,  9,  7,  1, 37, 23,  9, 60,202, 60,198, 13,  0, 18, 27, 13,  9,
 16, 54, 47,  5,  1, 50,  2, 60,203, 60,206, 13,  0, 18, 27,  7,  1, 16, 18, 28,
 11, 29, 31, 52, 46, 60,207,  7,  1, 50, 25, 60,209, 13,  0, 18, 27, 13,  9, 16,
 20, 88,  2,  0,  1, 60,210, 13,  9,  7,  1, 37, 23,  9, 60,211, 60,208, 13,  0,
 18, 27, 13,  9, 16, 54, 36,  5,  1, 50,  2, 60,212,  5,  2, 60,213, 60,215, 15,
  8, 11, 89,  2,  0,  1, 60,216, 15,  8, 11, 90,  2,  0,  1, 60,219, 15,  8, 11,
 91,  2,  0,  1, 60,220, 15, 93, 13,  0, 18, 15,  9,  2,  9,  1,  2,  1,  3,  7,
  1, 38, 60,221, 13,  7,  7,  0, 36, 52, 38, 60,222, 15,  8, 11, 39, 15, 93, 13,
  0, 18, 15,  7,  1,  9,  3,  2,  1,  3, 42, 15, 94, 11, 95, 13,  7,  2,  1,  2,
 42, 11, 96, 42,  2,  0,  1, 50, 19, 60,224, 15,  8, 11, 97, 13,  0, 18, 98, 42,
 11, 99, 42,  2,  0,  1, 60,225, 60,227, 15,  8, 11,100,  2,  0,  1, 60,228, 15,
  8, 11,101,  2,  0,  1, 60,229,  0,  0,  0,  0, 24,  0,  0,  0, 51,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0, 52,  0,  0,  0,  6, 99,108, 97,115,115,  0,
  0,  0,  0, 53,  0,  0,  0,  2, 95,  0,  0,  0,  0, 53,  0,  0,  0,  2, 95,  0,
  0,  0,  0, 53,  0,  0,  0,  7,115,116, 97,116,105, 99,  0,  0,  0,  0, 66,  0,
  0,  0,  5,110, 97,114,103,  0,  0,  0,  0, 77,  0,  0,  0,  2,105,  0,  0,  0,
  0, 84,  0,  0,  0,  0,  0,  0,  0, 92,  0,  0,  0,  5,110, 97,114,103,  0,  0,
  0,  0,103,  0,  0,  0,  2,105,  0,  0,  0,  0,108,  0,  0,  0,  0,  0,  0,  0,
119,  0,  0,  0,  2,105,  0,  0,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,151,  0,
  0,  0,  2,105,  0,  0,  0,  0,164,  0,  0,  0,  2,116,  0,  0,  0,  0,185,  0,
  0,  0,  0,  0,  0,  0,187,  0,  0,  0,  2,105,  0,  0,  0,  0,197,  0,  0,  0,
  2,105,  0,  0,  0,  0,202,  0,  0,  0,  0,  0,  0,  0,207,  0,  0,  0,  2,105,
  0,  0,  0,  0,211,  0,  0,  0,  0,  0,  0,  0,212,  0,  0,  0,  0,  0,  0,  0,
212,  0,  0,  0,  0,  0,  0,  0,220,  0,  0,  0,  9,111,118,101,114,108,111, 97,
100,  0,  0,  0,  0,102,  2,  0,  0,  0,  6, 99,108, 97,115,115,  0,  2,  0,  0,
  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,105,110, 99,108, 97,115,115,  0,
  2,  0,  0,  0,  2, 95,  0,  2,  0,  0,  0,  7,115,116, 97,116,105, 99,  0,  2,
  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,  0,  0,  0,  4,109,111,100,
  0,  2,  0,  0,  0, 13, 94, 37,115, 42, 40,115,116, 97,116,105, 99, 41,  0,  2,
  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 11, 47, 42, 32,109,
101,116,104,111,100, 58,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,
  0, 11, 32,111,102, 32, 99,108, 97,115,115, 32,  0,  2,  0,  0,  0,  4, 32, 42,
 47,  0,  2,  0,  0,  0, 13, 47, 42, 32,102,117,110, 99,116,105,111,110, 58,  0,
  2,  0,  0,  0, 12,115,116, 97,116,105, 99, 32,118,111,105,100,  0,  2,  0,  0,
  0,  6, 99,110, 97,109,101,  0,  2,  0,  0,  0,  7, 40,118,111,105,100, 41,  0,
  2,  0,  0,  0,  2,123,  0,  2,  0,  0,  0,  7, 32,105,102, 32, 40, 10,  0,  2,
  0,  0,  0,  5,110, 97,114,103,  0,  2,  0,  0,  0,  4,110,101,119,  0,  2,  0,
  0,  0,  6, 99,111,110,115,116,  0,  2,  0,  0,  0, 22, 32, 32, 32, 32, 32, 33,
116,111,108,117, 97, 95,105,115,116,121,112,101, 40, 49, 44,  0,  2,  0,  0,  0,
  7,112, 97,114,101,110,116,  0,  2,  0,  0,  0,  5, 99,116, 97,103,  0,  2,  0,
  0,  0,  8, 44, 48, 41, 32,124,124, 10,  0,  2,  0,  0,  0,  4,116, 97,103,  0,
  2,  0,  0,  0,  5, 97,114,103,115,  0,  2,  0,  0,  0,  5,116,121,112,101,  0,
  2,  0,  0,  0,  5,118,111,105,100,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,
  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,  0,  7,111, 98,106,101, 99,
116,  0,  2,  0,  0,  0,  7, 32, 32, 32, 32, 32, 33,  0,  2,  0,  0,  0, 13,111,
117,116, 99,104,101, 99,107,116,121,112,101,  0,  2,  0,  0,  0,  5, 32,124,124,
 10,  0,  2,  0,  0,  0, 21, 32, 32, 32, 32, 32, 33,116,111,108,117, 97, 95,105,
115,110,111,111, 98,106, 40,  0,  2,  0,  0,  0, 19, 41, 10, 32, 41, 10, 32, 32,
103,111,116,111, 32,101,114,114,111,114, 59,  0,  2,  0,  0,  0,  9, 32,101,108,
115,101, 10, 32,123,  0,  2,  0,  0,  0,  2, 32,  0,  2,  0,  0,  0,  2, 42,  0,
  2,  0,  0,  0,  8,115,101,108,102, 32, 61, 32,  0,  2,  0,  0,  0,  2, 40,  0,
  2,  0,  0,  0,  3, 42, 41,  0,  2,  0,  0,  0, 24,116,111,108,117, 97, 95,103,
101,116,117,115,101,114,116,121,112,101, 40, 49, 44, 48, 41, 59,  0,  2,  0,  0,
  0, 20, 94, 37,115, 42,115,116, 97,116,105, 99, 37,115, 37,115, 42, 40, 46, 42,
 41,  0,  2,  0,  0,  0,  8,100,101, 99,108, 97,114,101,  0,  2,  0,  0,  0, 55,
 32, 32,105,102, 32, 40, 33,115,101,108,102, 41, 32,116,111,108,117, 97, 95,101,
114,114,111,114, 40, 34,105,110,118, 97,108,105,100, 32, 39,115,101,108,102, 39,
 32,105,110, 32,102,117,110, 99,116,105,111,110, 32, 39,  0,  2,  0,  0,  0,  5,
 39, 34, 41, 59,  0,  2,  0,  0,  0,  9,103,101,116, 97,114,114, 97,121,  0,  2,
  0,  0,  0,  7,100,101,108,101,116,101,  0,  2,  0,  0,  0, 15, 32, 32,100,101,
108,101,116,101, 32,115,101,108,102, 59,  0,  2,  0,  0,  0, 12,111,112,101,114,
 97,116,111,114, 38, 91, 93,  0,  2,  0,  0,  0, 20, 32, 32,115,101,108,102, 45,
 62,111,112,101,114, 97,116,111,114, 91, 93, 40,  0,  2,  0,  0,  0,  5, 41, 32,
 61, 32,  0,  2,  0,  0,  0,  2, 59,  0,  2,  0,  0,  0,  4, 32, 32,123,  0,  2,
  0,  0,  0,  1,  0,  2,  0,  0,  0,  3, 32, 32,  0,  2,  0,  0,  0,  4,112,116,
114,  0,  2,  0,  0,  0, 14,116,111,108,117, 97, 73, 95,114,101,116, 32, 61, 32,
  0,  2,  0,  0,  0,  3, 41, 32,  0,  2,  0,  0,  0,  3, 58, 58,  0,  2,  0,  0,
  0,  7,115,101,108,102, 45, 62,  0,  2,  0,  0,  0,  8,112, 97,115,115,112, 97,
114,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  3, 41, 59,  0,  2,  0,  0,
  0,  2,116,  0,  2,  0,  0,  0,  7,110,117,109, 98,101,114,  0,  2,  0,  0,  0,
 14, 32, 32, 32,116,111,108,117, 97, 95,112,117,115,104,  0,  2,  0,  0,  0, 22,
 40, 40,100,111,117, 98,108,101, 41,116,111,108,117, 97, 73, 95,114,101,116, 41,
 59,  0,  2,  0,  0,  0, 14, 40,116,111,108,117, 97, 73, 95,114,101,116, 41, 59,
  0,  2,  0,  0,  0,  5, 32, 32, 32,123,  0,  2,  0,  0,  0, 20, 35,105,102,100,
101,102, 32, 95, 95, 99,112,108,117,115,112,108,117,115, 10,  0,  2,  0,  0,  0,
 29, 32, 32, 32, 32,118,111,105,100, 42, 32,116,111,108,117, 97, 73, 95, 99,108,
111,110,101, 32, 61, 32,110,101,119,  0,  2,  0,  0,  0,  7, 35,101,108,115,101,
 10,  0,  2,  0,  0,  0, 63, 32, 32, 32, 32,118,111,105,100, 42, 32,116,111,108,
117, 97, 73, 95, 99,108,111,110,101, 32, 61, 32,116,111,108,117, 97, 95, 99,111,
112,121, 40, 40,118,111,105,100, 42, 41, 38,116,111,108,117, 97, 73, 95,114,101,
116, 44,115,105,122,101,111,102, 40,  0,  2,  0,  0,  0,  4, 41, 41, 59,  0,  2,
  0,  0,  0,  8, 35,101,110,100,105,102, 10,  0,  2,  0,  0,  0, 51, 32, 32, 32,
 32,116,111,108,117, 97, 95,112,117,115,104,117,115,101,114,116,121,112,101, 40,
116,111,108,117, 97, 95,100,111, 99,108,111,110,101, 40,116,111,108,117, 97, 73,
 95, 99,108,111,110,101, 44,  0,  2,  0,  0,  0,  3, 41, 44,  0,  2,  0,  0,  0,
  5, 32, 32, 32,125,  0,  2,  0,  0,  0,  2, 38,  0,  2,  0,  0,  0, 42, 32, 32,
 32,116,111,108,117, 97, 95,112,117,115,104,117,115,101,114,116,121,112,101, 40,
 40,118,111,105,100, 42, 41, 38,116,111,108,117, 97, 73, 95,114,101,116, 44,  0,
  2,  0,  0,  0, 41, 32, 32, 32,116,111,108,117, 97, 95,112,117,115,104,117,115,
101,114,116,121,112,101, 40, 40,118,111,105,100, 42, 41,116,111,108,117, 97, 73,
 95,114,101,116, 44,  0,  2,  0,  0,  0,  9,114,101,116,118, 97,108,117,101,  0,
  2,  0,  0,  0,  4, 32, 32,125,  0,  2,  0,  0,  0,  9,115,101,116, 97,114,114,
 97,121,  0,  2,  0,  0,  0, 10,102,114,101,101, 97,114,114, 97,121,  0,  2,  0,
  0,  0,  3, 32,125,  0,  2,  0,  0,  0,  9, 32,114,101,116,117,114,110, 59,  0,
  2,  0,  0,  0,  8,101,114,114,111,114, 58, 10,  0,  2,  0,  0,  0,  9,111,118,
101,114,108,111, 97,100,  0,  2,  0,  0,  0,  7,115,116,114,115,117, 98,  0,  2,
  0,  0,  0,  7,102,111,114,109, 97,116,  0,  2,  0,  0,  0,  5, 37, 48, 50,100,
  0,  2,  0,  0,  0,  4, 40, 41, 59,  0,  2,  0,  0,  0, 36, 32,116,111,108,117,
 97, 95,101,114,114,111,114, 40, 34, 35,102,101,114,114,111,114, 32,105,110, 32,
102,117,110, 99,116,105,111,110, 32, 39,  0,  2,  0,  0,  0,  6,108,110, 97,109,
101,  0,  2,  0,  0,  0,  6, 39, 46, 34, 41, 59,  0,  2,  0,  0,  0,  2,125,  0,
  2,  0,  0,  0,  2, 10,  0,  2,  0,  0,  0,  9,114,101,103,105,115,116,101,114,
  0,  4,  0,  0,  0,232,  0,  0,  0, 14, 64,102,117,110, 99,116,105,111,110, 46,
108,117, 97,  0,  0,  0,  0, 89,  5,  1, 60,233, 13,  0, 20,  2,  2,  1,  1, 46,
  7, 13,  0, 20,  3,  2,  1,  1, 60,234, 13,  1, 52, 33, 60,235, 15,  4, 11,  5,
 13,  1, 42, 11,  6, 42, 13,  0, 18,  7, 42, 11,  8, 42, 13,  0, 18,  9, 42, 11,
 10, 42,  2,  0,  1, 50, 27, 60,237, 15,  4, 11, 11, 13,  0, 18,  7, 42, 11,  8,
 42, 13,  0, 18,  9, 42, 11, 10, 42,  2,  0,  1, 60,238, 60,239,  0,  0,  0,  0,
  2,  0,  0,  0,232,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,233,  0,  0,
  0,  7,112, 97,114,101,110,116,  0,  0,  0,  0, 12,  2,  0,  0,  0,  7,112, 97,
114,101,110,116,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  8,
105,110, 99,108, 97,115,115,  0,  2,  0,  0,  0,  9,105,110,109,111,100,117,108,
101,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,  0, 18, 32,
116,111,108,117, 97, 95,102,117,110, 99,116,105,111,110, 40, 34,  0,  2,  0,  0,
  0,  4, 34, 44, 34,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,
  0,  3, 34, 44,  0,  2,  0,  0,  0,  6, 99,110, 97,109,101,  0,  2,  0,  0,  0,
  3, 41, 59,  0,  2,  0,  0,  0, 23, 32,116,111,108,117, 97, 95,102,117,110, 99,
116,105,111,110, 40, 78, 85, 76, 76, 44, 34,  0,  2,  0,  0,  0, 11,117,110,114,
101,103,105,115,116,101,114,  0,  4,  0,  0,  0,242,  0,  0,  0, 14, 64,102,117,
110, 99,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0, 52,  4,  1, 60,243, 13,
  0, 20,  1,  2,  1,  1,  4,  0, 32, 48, 10, 13,  0, 20,  2,  2,  1,  1,  4,  0,
 32, 52, 19, 60,244, 15,  3, 11,  4, 13,  0, 18,  5, 42, 11,  6, 42,  2,  0,  1,
 50,  2, 60,245, 60,246,  0,  0,  0,  0,  1,  0,  0,  0,242,  0,  0,  0,  5,115,
101,108,102,  0,  0,  0,  0,  7,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,
  0,  0,  8,105,110, 99,108, 97,115,115,  0,  2,  0,  0,  0,  9,105,110,109,111,
100,117,108,101,  0,  2,  0,  0,  0,  7,111,117,116,112,117,116,  0,  2,  0,  0,
  0, 32, 32,108,117, 97, 95,112,117,115,104,110,105,108, 40, 41, 59, 32,108,117,
 97, 95,115,101,116,103,108,111, 98, 97,108, 40, 34,  0,  2,  0,  0,  0,  6,108,
110, 97,109,101,  0,  2,  0,  0,  0,  4, 34, 41, 59,  0,  2,  0,  0,  0,  6,112,
114,105,110,116,  0,  4,  0,  0,  0,250,  0,  0,  0, 14, 64,102,117,110, 99,116,
105,111,110, 46,108,117, 97,  0,  0,  0,  1,  1,  8,  3, 60,251, 15,  2, 13,  1,
 11,  3, 42,  2,  0,  1, 60,252, 15,  2, 13,  1, 11,  4, 42, 13,  0, 18,  6, 42,
 11,  7, 42,  2,  0,  1, 60,253, 15,  2, 13,  1, 11,  8, 42, 13,  0, 18,  9, 42,
 11,  7, 42,  2,  0,  1, 60,254, 15,  2, 13,  1, 11, 10, 42, 13,  0, 18, 11, 42,
 11,  7, 42,  2,  0,  1, 60,255, 15,  2, 13,  1, 11, 12, 42, 13,  0, 18, 13, 42,
 11,  7, 42,  2,  0,  1, 59,  1,  0, 15,  2, 13,  1, 11, 14, 42, 13,  0, 18, 15,
 42, 11,  7, 42,  2,  0,  1, 59,  1,  1, 15,  2, 13,  1, 11, 16, 42, 13,  0, 18,
 17, 42, 11,  7, 42,  2,  0,  1, 59,  1,  2, 15,  2, 13,  1, 11, 18, 42, 13,  0,
 18, 19, 42, 11,  7, 42,  2,  0,  1, 59,  1,  3, 15,  2, 13,  1, 11, 20, 42,  2,
  0,  1, 59,  1,  4,  7,  1, 50, 35, 59,  1,  6, 13,  0, 18, 22, 13,  3, 16, 20,
  2, 13,  1, 11, 23, 42, 11, 24,  2,  0,  3, 59,  1,  7, 13,  3,  7,  1, 37, 23,
  3, 59,  1,  8, 59,  1,  5, 13,  0, 18, 22, 13,  3, 16, 54, 47, 59,  1,  9, 15,
  2, 13,  1, 11, 25, 42,  2,  0,  1, 59,  1, 10, 15,  2, 13,  1, 11, 26, 42, 13,
  2, 42,  2,  0,  1, 59,  1, 11,  0,  0,  0,  0,  4,  0,  0,  0,250,  0,  0,  0,
  5,115,101,108,102,  0,  0,  0,  0,250,  0,  0,  0,  6,105,100,101,110,116,  0,
  0,  0,  0,250,  0,  0,  0,  6, 99,108,111,115,101,  0,  0,  0,  1,  4,  0,  0,
  0,  2,105,  0,  0,  0,  0, 27,  2,  0,  0,  0,  6,105,100,101,110,116,  0,  2,
  0,  0,  0,  6, 99,108,111,115,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,
  0,  2,  0,  0,  0, 10, 70,117,110, 99,116,105,111,110,123,  0,  2,  0,  0,  0,
 10, 32,109,111,100, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,115,101,108,102,
  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0,  3, 39, 44,  0,  2,  0,
  0,  0, 10, 32,116,121,112,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,116,121,
112,101,  0,  2,  0,  0,  0, 10, 32,112,116,114, 32, 32, 61, 32, 39,  0,  2,  0,
  0,  0,  4,112,116,114,  0,  2,  0,  0,  0, 10, 32,110, 97,109,101, 32, 61, 32,
 39,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 11, 32, 99,111,
110,115,116, 32, 61, 32, 39,  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,
  0,  0,  0, 11, 32, 99,110, 97,109,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  6,
 99,110, 97,109,101,  0,  2,  0,  0,  0, 11, 32,108,110, 97,109,101, 32, 61, 32,
 39,  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0, 10, 32, 97,
114,103,115, 32, 61, 32,123,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  5,
 97,114,103,115,  0,  2,  0,  0,  0,  3, 32, 32,  0,  2,  0,  0,  0,  2, 44,  0,
  2,  0,  0,  0,  3, 32,125,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0,  9,
111,118,101,114,108,111, 97,100,  0,  4,  0,  0,  1, 14,  0,  0,  0, 14, 64,102,
117,110, 99,116,105,111,110, 46,108,117, 97,  0,  0,  0,  0, 22,  4,  1, 59,  1,
 15, 13,  0, 18,  1, 20,  2, 13,  0, 18,  3,  3,  1,  2, 59,  1, 16,  0,  0,  0,
  0,  1,  0,  0,  1, 14,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,  4,  2,
  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  7,112, 97,114,101,110,116,
  0,  2,  0,  0,  0,  9,111,118,101,114,108,111, 97,100,  0,  2,  0,  0,  0,  6,
108,110, 97,109,101,  0,  2,  0,  0,  0, 10, 95, 70,117,110, 99,116,105,111,110,
  0,  4,  0,  0,  1, 21,  0,  0,  0, 14, 64,102,117,110, 99,116,105,111,110, 46,
108,117, 97,  0,  0,  0,  0,231,  7,  1, 59,  1, 22, 13,  0, 11,  1, 15,  2, 26,
 59,  1, 23, 15,  3, 13,  0, 15,  4,  2,  0,  2, 59,  1, 25, 13,  0, 18,  5, 11,
  5, 31, 48,  7, 13,  0, 18,  5, 11,  6, 31, 52, 12, 59,  1, 26, 15,  7, 11,  8,
  2,  0,  1, 50,  3, 59,  1, 27, 59,  1, 29, 15,  9, 13,  0,  2,  0,  1, 59,  1,
 30, 13,  0, 20, 10,  2,  1,  1, 52,108, 59,  1, 31, 13,  0, 18, 11, 13,  0, 18,
 12, 18, 11, 32, 52, 46, 59,  1, 32, 13,  0, 11, 11, 11, 13, 26, 59,  1, 33, 13,
  0, 11, 14, 11, 13, 26, 59,  1, 34, 13,  0, 11, 15, 13,  0, 18, 12, 18, 11, 26,
 59,  1, 35, 13,  0, 11, 16, 11, 17, 26, 50, 44, 59,  1, 36, 13,  0, 18, 11, 11,
 18, 13,  0, 18, 12, 18, 11, 42, 32, 52, 22, 59,  1, 37, 13,  0, 11, 11, 11, 19,
 26, 59,  1, 38, 13,  0, 11, 14, 11, 19, 26, 50,  3, 59,  1, 39, 50,  3, 59,  1,
 40, 59,  1, 41, 13,  0, 11, 20, 13,  0, 20, 21, 11, 22,  2,  1,  2, 13,  0, 20,
 23, 13,  0,  2,  1,  2, 42, 26, 59,  1, 42, 13,  0,  1,  1, 59,  1, 43,  0,  0,
  0,  0,  1,  0,  0,  1, 21,  0,  0,  0,  2,116,  0,  0,  0,  0, 24,  2,  0,  0,
  0,  2,116,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 14,
 99,108, 97,115,115, 70,117,110, 99,116,105,111,110,  0,  2,  0,  0,  0,  7,115,
101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,
  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,  0,  0,  0,  1,  0,  2,  0,
  0,  0,  6,101,114,114,111,114,  0,  2,  0,  0,  0, 31, 35,105,110,118, 97,108,
105,100, 32, 39, 99,111,110,115,116, 39, 32,115,112,101, 99,105,102,105, 99, 97,
116,105,111,110,  0,  2,  0,  0,  0,  7, 97,112,112,101,110,100,  0,  2,  0,  0,
  0,  8,105,110, 99,108, 97,115,115,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,
  2,  0,  0,  0,  7,112, 97,114,101,110,116,  0,  2,  0,  0,  0,  4,110,101,119,
  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,  5,116,121,112,
101,  0,  2,  0,  0,  0,  4,112,116,114,  0,  2,  0,  0,  0,  2, 42,  0,  2,  0,
  0,  0,  2,126,  0,  2,  0,  0,  0,  7,100,101,108,101,116,101,  0,  2,  0,  0,
  0,  6, 99,110, 97,109,101,  0,  2,  0,  0,  0, 10, 99,102,117,110, 99,110, 97,
109,101,  0,  2,  0,  0,  0,  7,116,111,108,117, 97, 73,  0,  2,  0,  0,  0,  9,
111,118,101,114,108,111, 97,100,  0,  2,  0,  0,  0,  9, 70,117,110, 99,116,105,
111,110,  0,  4,  0,  0,  1, 49,  0,  0,  0, 14, 64,102,117,110, 99,116,105,111,
110, 46,108,117, 97,  0,  0,  0,  0,147, 11,  3, 59,  1, 50, 15,  4, 15,  5, 13,
  1,  7,  2,  9,  2,  2,  1,  3, 11,  6,  2,  1,  2, 59,  1, 51,  7,  1, 59,  1,
 52, 22,  1, 11,  9,  7,  0, 30,  0, 50, 50, 59,  1, 54, 13,  5, 11,  9, 13,  5,
 18,  9,  7,  1, 37, 26, 59,  1, 55, 13,  5, 13,  5, 18,  9, 15, 10, 13,  3, 13,
  4, 16, 11, 11,  2,  1,  2, 26, 59,  1, 56, 13,  4,  7,  1, 37, 23,  4, 59,  1,
 57, 59,  1, 53, 13,  3, 13,  4, 16, 54, 60, 59,  1, 58, 15, 10, 13,  0, 11, 13,
  2,  1,  2, 59,  1, 59, 13,  6, 11, 14, 13,  5, 26, 59,  1, 60, 13,  6, 11, 15,
 13,  2, 26, 59,  1, 61, 15, 16, 13,  6,  3,  7,  1, 59,  1, 62,  0,  0,  0,  0,
  7,  0,  0,  1, 49,  0,  0,  0,  2,100,  0,  0,  0,  1, 49,  0,  0,  0,  2, 97,
  0,  0,  0,  1, 49,  0,  0,  0,  2, 99,  0,  0,  0,  1, 50,  0,  0,  0,  2,116,
  0,  0,  0,  1, 51,  0,  0,  0,  2,105,  0,  0,  0,  1, 52,  0,  0,  0,  2,108,
  0,  0,  0,  1, 58,  0,  0,  0,  2,102,  0,  0,  0,  0, 17,  2,  0,  0,  0,  2,
100,  0,  2,  0,  0,  0,  2, 97,  0,  2,  0,  0,  0,  2, 99,  0,  2,  0,  0,  0,
  2,116,  0,  2,  0,  0,  0,  6,115,112,108,105,116,  0,  2,  0,  0,  0,  7,115,
116,114,115,117, 98,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  2,105,  0,
  2,  0,  0,  0,  2,108,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0, 12, 68,
101, 99,108, 97,114, 97,116,105,111,110,  0,  2,  0,  0,  0,  4,118, 97,114,  0,
  2,  0,  0,  0,  2,102,  0,  2,  0,  0,  0,  5,102,117,110, 99,  0,  2,  0,  0,
  0,  5, 97,114,103,115,  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,  0,
  0,  0, 10, 95, 70,117,110, 99,116,105,111,110,  0,
};

/* operator.lo */
static char B14[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 14, 64,111,112,101,114, 97,
116,111,114, 46,108,117, 97,  0,  0,  0,  0,125, 21,  0, 60, 18, 22,  2, 60, 19,
 11,  1, 11,  2, 11,  3, 60, 20, 15,  4, 30,  1, 60, 21, 25,  0, 60, 22, 15,  5,
 15,  0, 15,  6,  2,  0,  2, 60, 25, 22, 10, 11,  8, 11,  9, 60, 26, 11, 10, 11,
 11, 60, 27, 11, 12, 11, 13, 60, 28, 11, 14, 11, 15, 60, 29, 11, 16, 11, 17, 60,
 30, 11, 18, 11, 19, 60, 31, 11, 20, 11, 21, 60, 32, 11, 22, 11, 23, 60, 33, 11,
 24, 11, 25, 60, 34, 11, 26, 11, 27, 30,  9, 60, 35, 25,  7, 60, 39, 15,  0, 11,
 28, 11, 29, 26, 60, 60, 11, 31, 25, 30, 60, 82, 11, 33, 25, 32,  0,  0,  0,  0,
  0,  0,  0,  0, 34,  2,  0,  0,  0, 14, 99,108, 97,115,115, 79,112,101,114, 97,
116,111,114,  0,  2,  0,  0,  0,  5,107,105,110,100,  0,  2,  0,  0,  0,  1,  0,
  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 14, 99,108, 97,115,
115, 70,117,110, 99,116,105,111,110,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,
103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,
  0,  4, 95, 84, 77,  0,  2,  0,  0,  0,  2, 43,  0,  2,  0,  0,  0, 13,111,112,
101,114, 97,116,111,114, 95, 97,100,100,  0,  2,  0,  0,  0,  2, 45,  0,  2,  0,
  0,  0, 13,111,112,101,114, 97,116,111,114, 95,115,117, 98,  0,  2,  0,  0,  0,
  2, 42,  0,  2,  0,  0,  0, 13,111,112,101,114, 97,116,111,114, 95,109,117,108,
  0,  2,  0,  0,  0,  2, 47,  0,  2,  0,  0,  0, 13,111,112,101,114, 97,116,111,
114, 95,100,105,118,  0,  2,  0,  0,  0,  2, 60,  0,  2,  0,  0,  0, 12,111,112,
101,114, 97,116,111,114, 95,108,116,  0,  2,  0,  0,  0,  2, 62,  0,  2,  0,  0,
  0, 12,111,112,101,114, 97,116,111,114, 95,103,116,  0,  2,  0,  0,  0,  3, 60,
 61,  0,  2,  0,  0,  0, 12,111,112,101,114, 97,116,111,114, 95,108,101,  0,  2,
  0,  0,  0,  3, 62, 61,  0,  2,  0,  0,  0, 12,111,112,101,114, 97,116,111,114,
 95,103,101,  0,  2,  0,  0,  0,  3, 91, 93,  0,  2,  0,  0,  0, 13,111,112,101,
114, 97,116,111,114, 95,103,101,116,  0,  2,  0,  0,  0,  4, 38, 91, 93,  0,  2,
  0,  0,  0, 13,111,112,101,114, 97,116,111,114, 95,115,101,116,  0,  2,  0,  0,
  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0, 39,  0,  0,  0, 14, 64,111,112,
101,114, 97,116,111,114, 46,108,117, 97,  0,  0,  0,  1,  9,  8,  3, 60, 40, 15,
  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 41, 15,  2, 13,  1, 11,  4, 42, 13,  0,
 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 42, 15,  2, 13,  1, 11,  8, 42, 13,  0,
 18,  9, 42, 11,  7, 42,  2,  0,  1, 60, 43, 15,  2, 13,  1, 11, 10, 42, 13,  0,
 18, 11, 42, 11,  7, 42,  2,  0,  1, 60, 44, 15,  2, 13,  1, 11, 12, 42, 13,  0,
 18, 13, 42, 11,  7, 42,  2,  0,  1, 60, 45, 15,  2, 13,  1, 11, 14, 42, 13,  0,
 18, 15, 42, 11,  7, 42,  2,  0,  1, 60, 46, 15,  2, 13,  1, 11, 16, 42, 13,  0,
 18, 17, 42, 11,  7, 42,  2,  0,  1, 60, 47, 15,  2, 13,  1, 11, 18, 42, 13,  0,
 18, 19, 42, 11,  7, 42,  2,  0,  1, 60, 48, 15,  2, 13,  1, 11, 20, 42, 13,  0,
 18, 21, 42, 11,  7, 42,  2,  0,  1, 60, 49, 15,  2, 13,  1, 11, 22, 42,  2,  0,
  1, 60, 50,  7,  1, 50, 32, 60, 52, 13,  0, 18, 24, 13,  3, 16, 20,  2, 13,  1,
 11, 25, 42, 11, 26,  2,  0,  3, 60, 53, 13,  3,  7,  1, 37, 23,  3, 60, 54, 60,
 51, 13,  0, 18, 24, 13,  3, 16, 54, 43, 60, 55, 15,  2, 13,  1, 11, 27, 42,  2,
  0,  1, 60, 56, 15,  2, 13,  1, 11, 28, 42, 13,  2, 42,  2,  0,  1, 60, 57,  0,
  0,  0,  0,  4,  0,  0,  0, 39,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0,
 39,  0,  0,  0,  6,105,100,101,110,116,  0,  0,  0,  0, 39,  0,  0,  0,  6, 99,
108,111,115,101,  0,  0,  0,  0, 50,  0,  0,  0,  2,105,  0,  0,  0,  0, 29,  2,
  0,  0,  0,  6,105,100,101,110,116,  0,  2,  0,  0,  0,  6, 99,108,111,115,101,
  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0, 10, 79,112,101,
114, 97,116,111,114,123,  0,  2,  0,  0,  0, 11, 32,107,105,110,100, 32, 32, 61,
 32, 39,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,107,105,
110,100,  0,  2,  0,  0,  0,  3, 39, 44,  0,  2,  0,  0,  0, 10, 32,109,111,100,
 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,109,111,100,  0,  2,  0,  0,  0, 10,
 32,116,121,112,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,116,121,112,101,  0,
  2,  0,  0,  0, 10, 32,112,116,114, 32, 32, 61, 32, 39,  0,  2,  0,  0,  0,  4,
112,116,114,  0,  2,  0,  0,  0, 10, 32,110, 97,109,101, 32, 61, 32, 39,  0,  2,
  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,  0,  0, 11, 32, 99,111,110,115,116,
 32, 61, 32, 39,  0,  2,  0,  0,  0,  6, 99,111,110,115,116,  0,  2,  0,  0,  0,
 11, 32, 99,110, 97,109,101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  6, 99,110, 97,
109,101,  0,  2,  0,  0,  0, 11, 32,108,110, 97,109,101, 32, 61, 32, 39,  0,  2,
  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0, 10, 32, 97,114,103,115,
 32, 61, 32,123,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,  5, 97,114,103,
115,  0,  2,  0,  0,  0,  3, 32, 32,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,
  0,  3, 32,125,  0,  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0, 10, 95, 79,112,
101,114, 97,116,111,114,  0,  4,  0,  0,  0, 60,  0,  0,  0, 14, 64,111,112,101,
114, 97,116,111,114, 46,108,117, 97,  0,  0,  0,  0,140,  7,  1, 60, 61, 13,  0,
 11,  1, 15,  2, 26, 60, 62, 15,  3, 13,  0, 15,  4,  2,  0,  2, 60, 64, 13,  0,
 18,  5, 11,  5, 31, 48,  7, 13,  0, 18,  5, 11,  6, 31, 52, 11, 60, 65, 15,  7,
 11,  8,  2,  0,  1, 50,  2, 60, 66, 60, 68, 15,  9, 13,  0,  2,  0,  1, 60, 69,
 13,  0, 20, 10,  2,  1,  1, 44, 52, 11, 60, 70, 15,  7, 11, 11,  2,  0,  1, 50,
  2, 60, 71, 60, 73, 13,  0, 11, 12, 13,  0, 20, 13, 11, 14,  2,  1,  2, 13,  0,
 20, 15, 13,  0,  2,  1,  2, 42, 26, 60, 74, 13,  0, 11, 16, 13,  0, 18, 16, 13,
  0, 18, 17, 42, 26, 60, 75, 13,  0,  1,  1, 60, 76,  0,  0,  0,  0,  1,  0,  0,
  0, 60,  0,  0,  0,  2,116,  0,  0,  0,  0, 18,  2,  0,  0,  0,  2,116,  0,  2,
  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 14, 99,108, 97,115,115,
 79,112,101,114, 97,116,111,114,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,
  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,
  6, 99,111,110,115,116,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  6,101,114,
114,111,114,  0,  2,  0,  0,  0, 31, 35,105,110,118, 97,108,105,100, 32, 39, 99,
111,110,115,116, 39, 32,115,112,101, 99,105,102,105, 99, 97,116,105,111,110,  0,
  2,  0,  0,  0,  7, 97,112,112,101,110,100,  0,  2,  0,  0,  0,  8,105,110, 99,
108, 97,115,115,  0,  2,  0,  0,  0, 46, 35,111,112,101,114, 97,116,111,114, 32,
 99, 97,110, 32,111,110,108,121, 32, 98,101, 32,100,101,102,105,110,101,100, 32,
 97,115, 32, 99,108, 97,115,115, 32,109,101,109, 98,101,114,  0,  2,  0,  0,  0,
  6, 99,110, 97,109,101,  0,  2,  0,  0,  0, 10, 99,102,117,110, 99,110, 97,109,
101,  0,  2,  0,  0,  0,  7,116,111,108,117, 97, 73,  0,  2,  0,  0,  0,  9,111,
118,101,114,108,111, 97,100,  0,  2,  0,  0,  0,  5,110, 97,109,101,  0,  2,  0,
  0,  0,  5,107,105,110,100,  0,  2,  0,  0,  0,  9, 79,112,101,114, 97,116,111,
114,  0,  4,  0,  0,  0, 82,  0,  0,  0, 14, 64,111,112,101,114, 97,116,111,114,
 46,108,117, 97,  0,  0,  0,  1, 99, 14,  4, 60, 83, 15,  5, 15,  6, 13,  2,  7,
  2, 15,  7, 13,  2,  2,  1,  1,  7,  1, 38,  2,  1,  3, 11,  8,  2,  1,  2, 60,
 84,  7,  1, 60, 85, 22,  1, 11, 11,  7,  0, 30,  0, 50, 46, 60, 87, 13,  6, 11,
 11, 13,  6, 18, 11,  7,  1, 37, 26, 60, 88, 13,  6, 13,  6, 18, 11, 15, 12, 13,
  4, 13,  5, 16, 11, 13,  2,  1,  2, 26, 60, 89, 13,  5,  7,  1, 37, 23,  5, 60,
 90, 60, 86, 13,  4, 13,  5, 16, 54, 55, 60, 91, 13,  1, 11, 14, 32, 52, 17, 60,
 92, 15, 15, 13,  0, 11, 16, 11, 17,  2,  1,  3, 23,  0, 50, 59, 60, 93, 13,  1,
 11, 18, 32, 52, 48, 60, 94, 13,  6, 11, 11, 13,  6, 18, 11,  7,  1, 37, 26, 60,
 95, 13,  6, 13,  6, 18, 11, 15, 12, 13,  0, 11, 13,  2,  1,  2, 26, 60, 96, 13,
  6, 13,  6, 18, 11, 16, 11, 19, 11, 20, 26, 50,  2, 60, 97, 60, 98, 15, 12, 13,
  0, 11, 22,  2,  1,  2, 60, 99, 13,  1, 11, 14, 32, 48, 25, 13,  6,  7,  1, 16,
  4,  0, 32, 46, 15, 15, 23, 13,  6,  7,  1, 16, 18, 24,  2,  1,  1, 11, 25, 31,
 52, 11, 60,100, 15, 26, 11, 27,  2,  0,  1, 50,  2, 60,101, 60,102, 13,  7, 11,
 28, 13,  6, 26, 60,103, 13,  7, 11, 29, 13,  3, 26, 60,104, 13,  7, 11, 30, 15,
 15, 13,  1, 11, 31, 11, 17,  2,  1,  3, 26, 60,105, 13,  7, 11, 32, 15, 33, 13,
  7, 18, 30, 16, 26, 60,106, 13,  7, 18, 30, 11, 14, 32, 48, 12, 15, 34, 13,  7,
 18, 35, 11, 29,  2,  1,  2, 44, 52, 20, 60,107, 15, 36, 13,  0, 11, 16, 13,  1,
 42, 13,  2, 13,  3,  2,  0,  4, 50,  2, 60,108, 60,109, 15, 37, 13,  7,  3,  8,
  1, 60,110,  0,  0,  0,  0,  8,  0,  0,  0, 82,  0,  0,  0,  2,100,  0,  0,  0,
  0, 82,  0,  0,  0,  2,107,  0,  0,  0,  0, 82,  0,  0,  0,  2, 97,  0,  0,  0,
  0, 82,  0,  0,  0,  2, 99,  0,  0,  0,  0, 83,  0,  0,  0,  2,116,  0,  0,  0,
  0, 84,  0,  0,  0,  2,105,  0,  0,  0,  0, 85,  0,  0,  0,  2,108,  0,  0,  0,
  0, 98,  0,  0,  0,  2,102,  0,  0,  0,  0, 38,  2,  0,  0,  0,  2,100,  0,  2,
  0,  0,  0,  2,107,  0,  2,  0,  0,  0,  2, 97,  0,  2,  0,  0,  0,  2, 99,  0,
  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6,115,112,108,105,116,  0,  2,  0,
  0,  0,  7,115,116,114,115,117, 98,  0,  2,  0,  0,  0,  7,115,116,114,108,101,
110,  0,  2,  0,  0,  0,  2, 44,  0,  2,  0,  0,  0,  2,105,  0,  2,  0,  0,  0,
  2,108,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0, 12, 68,101, 99,108, 97,
114, 97,116,105,111,110,  0,  2,  0,  0,  0,  4,118, 97,114,  0,  2,  0,  0,  0,
  3, 91, 93,  0,  2,  0,  0,  0,  5,103,115,117, 98,  0,  2,  0,  0,  0,  2, 38,
  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  4, 38, 91, 93,  0,  2,  0,  0,  0,
  5,110, 97,109,101,  0,  2,  0,  0,  0, 13,116,111,108,117, 97, 73, 95,118, 97,
108,117,101,  0,  2,  0,  0,  0,  2,102,  0,  2,  0,  0,  0,  5,102,117,110, 99,
  0,  2,  0,  0,  0,  8,105,115, 98, 97,115,105, 99,  0,  2,  0,  0,  0,  5,116,
121,112,101,  0,  2,  0,  0,  0,  7,110,117,109, 98,101,114,  0,  2,  0,  0,  0,
  6,101,114,114,111,114,  0,  2,  0,  0,  0, 50,111,112,101,114, 97,116,111,114,
 91, 93, 32, 99, 97,110, 32,111,110,108,121, 32, 98,101, 32,100,101,102,105,110,
101,100, 32,102,111,114, 32,110,117,109,101,114,105, 99, 32,105,110,100,101,120,
 46,  0,  2,  0,  0,  0,  5, 97,114,103,115,  0,  2,  0,  0,  0,  6, 99,111,110,
115,116,  0,  2,  0,  0,  0,  5,107,105,110,100,  0,  2,  0,  0,  0,  3, 37,115,
  0,  2,  0,  0,  0,  6,108,110, 97,109,101,  0,  2,  0,  0,  0,  4, 95, 84, 77,
  0,  2,  0,  0,  0,  8,115,116,114,102,105,110,100,  0,  2,  0,  0,  0,  4,109,
111,100,  0,  2,  0,  0,  0,  9, 79,112,101,114, 97,116,111,114,  0,  2,  0,  0,
  0, 10, 95, 79,112,101,114, 97,116,111,114,  0,
};

/* verbatim.lo */
static char B15[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 14, 64,118,101,114, 98, 97,
116,105,109, 46,108,117, 97,  0,  0,  0,  0, 84,  5,  0, 60, 20, 22,  2, 60, 21,
 11,  1, 11,  2, 11,  3, 60, 22, 15,  4, 30,  1, 60, 23, 25,  0, 60, 24, 15,  5,
 15,  0, 15,  6,  2,  0,  2, 60, 27, 15,  0, 11,  7, 11,  8, 26, 60, 34, 15,  0,
 11,  9, 11, 10, 26, 60, 42, 15,  0, 11, 11, 11, 12, 26, 60, 50, 15,  0, 11, 13,
 11, 14, 26, 60, 58, 11, 16, 25, 15, 60, 67, 11, 18, 25, 17,  0,  0,  0,  0,  0,
  0,  0,  0, 19,  2,  0,  0,  0, 14, 99,108, 97,115,115, 86,101,114, 98, 97,116,
105,109,  0,  2,  0,  0,  0,  5,108,105,110,101,  0,  2,  0,  0,  0,  1,  0,  2,
  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,  0, 13, 99,108, 97,115,115,
 70,101, 97,116,117,114,101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,
  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  9,
112,114,101, 97,109, 98,108,101,  0,  4,  0,  0,  0, 27,  0,  0,  0, 14, 64,118,
101,114, 98, 97,116,105,109, 46,108,117, 97,  0,  0,  0,  0, 29,  3,  1, 60, 28,
 13,  0, 18,  1, 44, 52, 13, 60, 29, 15,  2, 13,  0, 18,  3,  2,  0,  1, 50,  2,
 60, 30, 60, 31,  0,  0,  0,  0,  1,  0,  0,  0, 27,  0,  0,  0,  5,115,101,108,
102,  0,  0,  0,  0,  4,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,
  5, 99,111,110,100,  0,  2,  0,  0,  0,  6,119,114,105,116,101,  0,  2,  0,  0,
  0,  5,108,105,110,101,  0,  2,  0,  0,  0,  8,115,117,112, 99,111,100,101,  0,
  4,  0,  0,  0, 34,  0,  0,  0, 14, 64,118,101,114, 98, 97,116,105,109, 46,108,
117, 97,  0,  0,  0,  0, 37,  3,  1, 60, 35, 13,  0, 18,  1, 52, 22, 60, 36, 15,
  2, 13,  0, 18,  3,  2,  0,  1, 60, 37, 15,  2, 11,  4,  2,  0,  1, 50,  2, 60,
 38, 60, 39,  0,  0,  0,  0,  1,  0,  0,  0, 34,  0,  0,  0,  5,115,101,108,102,
  0,  0,  0,  0,  5,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5,
 99,111,110,100,  0,  2,  0,  0,  0,  6,119,114,105,116,101,  0,  2,  0,  0,  0,
  5,108,105,110,101,  0,  2,  0,  0,  0,  2, 10,  0,  2,  0,  0,  0,  9,114,101,
103,105,115,116,101,114,  0,  4,  0,  0,  0, 42,  0,  0,  0, 14, 64,118,101,114,
 98, 97,116,105,109, 46,108,117, 97,  0,  0,  0,  0, 28,  3,  1, 60, 43, 13,  0,
 18,  1, 52, 13, 60, 44, 15,  2, 13,  0, 18,  3,  2,  0,  1, 50,  2, 60, 45, 60,
 46,  0,  0,  0,  0,  1,  0,  0,  0, 42,  0,  0,  0,  5,115,101,108,102,  0,  0,
  0,  0,  4,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,  5, 99,111,
110,100,  0,  2,  0,  0,  0,  6,119,114,105,116,101,  0,  2,  0,  0,  0,  5,108,
105,110,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  4,  0,  0,  0, 50,
  0,  0,  0, 14, 64,118,101,114, 98, 97,116,105,109, 46,108,117, 97,  0,  0,  0,
  0, 52,  6,  3, 60, 51, 15,  2, 13,  1, 11,  3, 42,  2,  0,  1, 60, 52, 15,  2,
 13,  1, 11,  4, 42, 13,  0, 18,  6, 42, 11,  7, 42,  2,  0,  1, 60, 53, 15,  2,
 13,  1, 11,  8, 42, 13,  2, 42,  2,  0,  1, 60, 54,  0,  0,  0,  0,  3,  0,  0,
  0, 50,  0,  0,  0,  5,115,101,108,102,  0,  0,  0,  0, 50,  0,  0,  0,  6,105,
100,101,110,116,  0,  0,  0,  0, 50,  0,  0,  0,  6, 99,108,111,115,101,  0,  0,
  0,  0,  9,  2,  0,  0,  0,  6,105,100,101,110,116,  0,  2,  0,  0,  0,  6, 99,
108,111,115,101,  0,  2,  0,  0,  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0,
 10, 86,101,114, 98, 97,116,105,109,123,  0,  2,  0,  0,  0, 10, 32,108,105,110,
101, 32, 61, 32, 39,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,  2,  0,  0,  0,
  5,108,105,110,101,  0,  2,  0,  0,  0,  3, 39, 44,  0,  2,  0,  0,  0,  2,125,
  0,  2,  0,  0,  0, 10, 95, 86,101,114, 98, 97,116,105,109,  0,  4,  0,  0,  0,
 58,  0,  0,  0, 14, 64,118,101,114, 98, 97,116,105,109, 46,108,117, 97,  0,  0,
  0,  0, 40,  4,  1, 60, 59, 13,  0, 11,  1, 15,  2, 26, 60, 60, 15,  3, 13,  0,
 15,  4,  2,  0,  2, 60, 61, 15,  5, 13,  0,  2,  0,  1, 60, 62, 13,  0,  1,  1,
 60, 63,  0,  0,  0,  0,  1,  0,  0,  0, 58,  0,  0,  0,  2,116,  0,  0,  0,  0,
  6,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,
  0,  0,  0, 14, 99,108, 97,115,115, 86,101,114, 98, 97,116,105,109,  0,  2,  0,
  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97,
 95,116, 97,103,  0,  2,  0,  0,  0,  7, 97,112,112,101,110,100,  0,  2,  0,  0,
  0,  9, 86,101,114, 98, 97,116,105,109,  0,  4,  0,  0,  0, 67,  0,  0,  0, 14,
 64,118,101,114, 98, 97,116,105,109, 46,108,117, 97,  0,  0,  0,  0, 75,  8,  1,
 60, 68,  4,  0, 60, 69, 15,  2, 13,  0,  7,  1,  7,  1,  2,  1,  3, 11,  3, 32,
 52, 21, 60, 70,  7,  1, 23,  1, 60, 71, 15,  2, 13,  0,  7,  2,  2,  1,  2, 23,
  0, 50,  2, 60, 72, 60, 73, 15,  4, 22,  2, 60, 74, 11,  5, 13,  0, 11,  6, 60,
 75, 13,  1, 30,  1, 60, 76,  3,  2,  1, 60, 77,  0,  0,  0,  0,  2,  0,  0,  0,
 67,  0,  0,  0,  2,108,  0,  0,  0,  0, 68,  0,  0,  0,  2, 99,  0,  0,  0,  0,
  7,  2,  0,  0,  0,  2,108,  0,  2,  0,  0,  0,  2, 99,  0,  2,  0,  0,  0,  7,
115,116,114,115,117, 98,  0,  2,  0,  0,  0,  2, 36,  0,  2,  0,  0,  0, 10, 95,
 86,101,114, 98, 97,116,105,109,  0,  2,  0,  0,  0,  5,108,105,110,101,  0,  2,
  0,  0,  0,  5, 99,111,110,100,  0,
};

/* code.lo */
static char B16[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 10, 64, 99,111,100,101, 46,
108,117, 97,  0,  0,  0,  0, 66,  5,  0, 60, 19, 22,  2, 60, 20, 11,  1, 11,  2,
 11,  3, 60, 21, 15,  4, 30,  1, 60, 22, 25,  0, 60, 23, 15,  5, 15,  0, 15,  6,
  2,  0,  2, 60, 26, 15,  0, 11,  7, 11,  8, 26, 60, 63, 15,  0, 11,  9, 11, 10,
 26, 60, 71, 11, 12, 25, 11, 60, 80, 11, 14, 25, 13,  0,  0,  0,  0,  0,  0,  0,
  0, 15,  2,  0,  0,  0, 10, 99,108, 97,115,115, 67,111,100,101,  0,  2,  0,  0,
  0,  5,116,101,120,116,  0,  2,  0,  0,  0,  1,  0,  2,  0,  0,  0,  6, 95, 98,
 97,115,101,  0,  2,  0,  0,  0, 13, 99,108, 97,115,115, 70,101, 97,116,117,114,
101,  0,  2,  0,  0,  0,  7,115,101,116,116, 97,103,  0,  2,  0,  0,  0, 10,116,
111,108,117, 97, 95,116, 97,103,  0,  2,  0,  0,  0,  9,114,101,103,105,115,116,
101,114,  0,  4,  0,  0,  0, 26,  0,  0,  0, 10, 64, 99,111,100,101, 46,108,117,
 97,  0,  0,  0,  0,239, 13,  1, 60, 27, 15,  1,  2,  1,  0, 60, 28, 15,  1,  2,
  1,  0, 60, 29, 15,  4, 13,  2, 11,  5,  2,  1,  2, 60, 30, 13,  3, 44, 52, 11,
 60, 31, 15,  6, 11,  7,  2,  0,  1, 50,  2, 60, 32, 60, 34, 15,  8, 13,  3, 13,
  0, 18, 10,  2,  0,  2, 60, 35, 15, 11, 13,  3,  2,  0,  1, 60, 36, 15, 12, 11,
 13, 13,  1, 42, 11, 14, 42, 13,  2, 42,  2,  0,  1, 60, 37, 15, 15, 13,  2,  2,
  0,  1, 60, 40, 15,  4, 13,  1, 11, 17,  2,  1,  2, 60, 41, 13,  4,  4,  0, 32,
 52, 11, 60, 42, 15,  6, 11,  7,  2,  0,  1, 50,  2, 60, 43, 60, 44, 15, 19, 13,
  4, 11, 20,  2,  1,  2, 60, 45, 15, 11, 13,  4,  2,  0,  1, 60, 46, 15, 15, 13,
  1,  2,  0,  1, 60, 48, 15, 21, 11, 22,  2,  0,  1, 60, 49, 15, 21, 11, 23,  2,
  0,  1, 60, 50, 22,  1, 11,  2,  7,  0, 30,  0, 60, 51, 15, 21, 15, 25, 13,  5,
 11, 26, 13,  6, 58, 27,  1, 60, 55,  2,  1,  3,  2,  0,  1, 60, 56, 15, 21, 11,
 28,  2,  0,  1, 60, 57, 15, 21, 11, 29,  2,  0,  1, 60, 58, 15, 21, 11, 30,  2,
  0,  1, 60, 59,  0,  0,  0,  0,  7,  0,  0,  0, 26,  0,  0,  0,  5,115,101,108,
102,  0,  0,  0,  0, 27,  0,  0,  0,  2,111,  0,  0,  0,  0, 28,  0,  0,  0,  2,
110,  0,  0,  0,  0, 29,  0,  0,  0,  2,102,  0,  0,  0,  0, 40,  0,  0,  0,  3,
102,112,  0,  0,  0,  0, 44,  0,  0,  0,  2,115,  0,  0,  0,  0, 50,  0,  0,  0,
  2,116,  0,  0,  0,  0, 31,  2,  0,  0,  0,  2,111,  0,  2,  0,  0,  0,  8,116,
109,112,110, 97,109,101,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,  2,102,
  0,  2,  0,  0,  0,  9,111,112,101,110,102,105,108,101,  0,  2,  0,  0,  0,  2,
119,  0,  2,  0,  0,  0,  6,101,114,114,111,114,  0,  2,  0,  0,  0, 61, 10, 32,
 32, 32, 99, 97,110,110,111,116, 32,111,112,101,110, 32,116,101,109,112,111,114,
 97,114,121, 32,102,105,108,101, 32,116,111, 32,112,114,111, 99, 99,101,115,115,
 32,101,109, 98,101,100,100,101,100, 32, 76,117, 97, 32, 99,111,100,101,  0,  2,
  0,  0,  0,  6,119,114,105,116,101,  0,  2,  0,  0,  0,  5,115,101,108,102,  0,
  2,  0,  0,  0,  5,116,101,120,116,  0,  2,  0,  0,  0, 10, 99,108,111,115,101,
102,105,108,101,  0,  2,  0,  0,  0,  8,101,120,101, 99,117,116,101,  0,  2,  0,
  0,  0,  9,108,117, 97, 99, 32, 45,111, 32,  0,  2,  0,  0,  0,  2, 32,  0,  2,
  0,  0,  0,  7,114,101,109,111,118,101,  0,  2,  0,  0,  0,  3,102,112,  0,  2,
  0,  0,  0,  3,114, 98,  0,  2,  0,  0,  0,  2,115,  0,  2,  0,  0,  0,  5,114,
101, 97,100,  0,  2,  0,  0,  0,  3, 46, 42,  0,  2,  0,  0,  0,  7,111,117,116,
112,117,116,  0,  2,  0,  0,  0, 35, 10, 32,123, 32, 47, 42, 32, 98,101,103,105,
110, 32,101,109, 98,101,100,100,101,100, 32,108,117, 97, 32, 99,111,100,101, 32,
 42, 47, 10,  0,  2,  0,  0,  0, 35, 32, 32,115,116, 97,116,105, 99, 32,117,110,
115,105,103,110,101,100, 32, 99,104, 97,114, 32, 66, 91, 93, 32, 61, 32,123, 10,
 32, 32, 32,  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  5,103,115,117, 98,
  0,  2,  0,  0,  0,  4, 40, 46, 41,  0,  4,  0,  0,  0, 51,  0,  0,  0, 10, 64,
 99,111,100,101, 46,108,117, 97,  0,  0,  0,  0, 61,  6,  1, 60, 52, 11,  2, 60,
 53, 12,  0, 11,  4, 12,  0, 18,  4,  7,  1, 37, 26, 12,  0, 18,  4,  7, 20, 32,
 52, 11, 12,  0, 11,  4,  7,  0, 26, 11,  5, 23,  1, 60, 54, 15,  6, 11,  7, 15,
  8, 13,  0,  2,  1,  1, 13,  1,  3,  2,  3, 60, 55,  0,  0,  0,  0,  2,  0,  0,
  0, 51,  0,  0,  0,  2, 99,  0,  0,  0,  0, 52,  0,  0,  0,  2,101,  0,  0,  0,
  0,  9,  2,  0,  0,  0,  2, 99,  0,  2,  0,  0,  0,  2,101,  0,  2,  0,  0,  0,
  1,  0,  2,  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,  0,  0,
  5, 10, 32, 32, 32,  0,  2,  0,  0,  0,  7,102,111,114,109, 97,116,  0,  2,  0,
  0,  0,  7, 37, 51,117, 44, 37,115,  0,  2,  0,  0,  0,  8,115,116,114, 98,121,
116,101,  0,  2,  0,  0,  0,  6, 32, 32,125, 59, 10,  0,  2,  0,  0,  0, 56, 32,
 32,108,117, 97, 95,100,111, 98,117,102,102,101,114, 40, 66, 44,115,105,122,101,
111,102, 40, 66, 41, 44, 34,116,111,108,117, 97, 58, 32,101,109, 98,101,100,100,
101,100, 32, 76,117, 97, 32, 99,111,100,101, 34, 41, 59,  0,  2,  0,  0,  0, 36,
 32,125, 32, 47, 42, 32,101,110,100, 32,111,102, 32,101,109, 98,101,100,100,101,
100, 32,108,117, 97, 32, 99,111,100,101, 32, 42, 47, 10, 10,  0,  2,  0,  0,  0,
  6,112,114,105,110,116,  0,  4,  0,  0,  0, 63,  0,  0,  0, 10, 64, 99,111,100,
101, 46,108,117, 97,  0,  0,  0,  0, 52,  6,  3, 60, 64, 15,  2, 13,  1, 11,  3,
 42,  2,  0,  1, 60, 65, 15,  2, 13,  1, 11,  4, 42, 13,  0, 18,  6, 42, 11,  7,
 42,  2,  0,  1, 60, 66, 15,  2, 13,  1, 11,  8, 42, 13,  2, 42,  2,  0,  1, 60,
 67,  0,  0,  0,  0,  3,  0,  0,  0, 63,  0,  0,  0,  5,115,101,108,102,  0,  0,
  0,  0, 63,  0,  0,  0,  6,105,100,101,110,116,  0,  0,  0,  0, 63,  0,  0,  0,
  6, 99,108,111,115,101,  0,  0,  0,  0,  9,  2,  0,  0,  0,  6,105,100,101,110,
116,  0,  2,  0,  0,  0,  6, 99,108,111,115,101,  0,  2,  0,  0,  0,  6,112,114,
105,110,116,  0,  2,  0,  0,  0,  6, 67,111,100,101,123,  0,  2,  0,  0,  0, 11,
 32,116,101,120,116, 32, 61, 32, 91, 91,  0,  2,  0,  0,  0,  5,115,101,108,102,
  0,  2,  0,  0,  0,  5,116,101,120,116,  0,  2,  0,  0,  0,  4, 93, 93, 44,  0,
  2,  0,  0,  0,  2,125,  0,  2,  0,  0,  0,  6, 95, 67,111,100,101,  0,  4,  0,
  0,  0, 71,  0,  0,  0, 10, 64, 99,111,100,101, 46,108,117, 97,  0,  0,  0,  0,
 40,  4,  1, 60, 72, 13,  0, 11,  1, 15,  2, 26, 60, 73, 15,  3, 13,  0, 15,  4,
  2,  0,  2, 60, 74, 15,  5, 13,  0,  2,  0,  1, 60, 75, 13,  0,  1,  1, 60, 76,
  0,  0,  0,  0,  1,  0,  0,  0, 71,  0,  0,  0,  2,116,  0,  0,  0,  0,  6,  2,
  0,  0,  0,  2,116,  0,  2,  0,  0,  0,  6, 95, 98, 97,115,101,  0,  2,  0,  0,
  0, 10, 99,108, 97,115,115, 67,111,100,101,  0,  2,  0,  0,  0,  7,115,101,116,
116, 97,103,  0,  2,  0,  0,  0, 10,116,111,108,117, 97, 95,116, 97,103,  0,  2,
  0,  0,  0,  7, 97,112,112,101,110,100,  0,  2,  0,  0,  0,  5, 67,111,100,101,
  0,  4,  0,  0,  0, 80,  0,  0,  0, 10, 64, 99,111,100,101, 46,108,117, 97,  0,
  0,  0,  0, 24,  5,  1, 60, 81, 15,  1, 22,  1, 60, 82, 11,  2, 13,  0, 30,  0,
 60, 83,  3,  1,  1, 60, 84,  0,  0,  0,  0,  1,  0,  0,  0, 80,  0,  0,  0,  2,
108,  0,  0,  0,  0,  3,  2,  0,  0,  0,  2,108,  0,  2,  0,  0,  0,  6, 95, 67,
111,100,101,  0,  2,  0,  0,  0,  5,116,101,120,116,  0,
};

/* doit.lo */
static char B17[]={
 27, 76,117, 97, 50,  0,  0,  0,  0,  0,  0,  0,  0, 10, 64,100,111,105,116, 46,
108,117, 97,  0,  0,  0,  1, 92,  6,  0, 60, 17, 15,  0, 18,  1, 52, 38, 60, 18,
 15,  4, 15,  0, 18,  1,  2,  2,  1, 60, 19, 13,  0, 44, 52, 14, 60, 20, 15,  5,
 11,  6, 13,  1, 42,  2,  0,  1, 50,  2, 60, 21,  5,  2, 50,  2, 60, 22, 60, 25,
 15,  0, 18,  7, 44, 52, 43, 60, 26, 15,  0, 18,  1, 52, 22, 60, 27, 15,  0, 11,
  7, 15,  8, 15,  0, 18,  1, 11,  9, 11, 10,  2,  1,  3, 26, 50, 11, 60, 29, 15,
  5, 11, 11,  2,  0,  1, 60, 30, 50,  2, 60, 31, 60, 33, 15, 13, 15,  0, 18,  7,
  2,  1,  1, 60, 35, 15,  0, 18,  1, 52,  9, 60, 36, 15,  4,  2,  0,  0, 50,  2,
 60, 37, 60, 39, 15,  0, 18, 12, 52,  4, 60, 41,  1,  1, 60, 43, 15,  0, 18, 14,
 52, 38, 60, 44, 15, 15, 15,  0, 18, 14,  2,  2,  1, 60, 45, 13,  1, 44, 52, 14,
 60, 46, 15,  5, 11,  6, 13,  2, 42,  2,  0,  1, 50,  2, 60, 47,  5,  2, 50,  2,
 60, 48, 60, 50, 15,  0, 18, 16, 52, 11, 60, 51, 13,  0, 20, 17,  2,  0,  1, 50,
 38, 60, 53, 13,  0, 20, 18,  2,  0,  1, 60, 54, 13,  0, 20, 19,  2,  0,  1, 60,
 55, 13,  0, 20, 20,  2,  0,  1, 60, 56, 13,  0, 20, 21,  2,  0,  1, 60, 57, 60,
 59, 15,  0, 18, 14, 52,  9, 60, 60, 15, 15,  2,  0,  0, 50,  2, 60, 61, 60, 64,
 15,  0, 18, 16, 44, 52, 66, 60, 65, 15,  0, 18, 22, 52, 54, 60, 66, 15, 15, 15,
  0, 18, 22,  2,  2,  1, 60, 67, 13,  1, 44, 52, 14, 60, 68, 15,  5, 11,  6, 13,
  2, 42,  2,  0,  1, 50,  2, 60, 69, 60, 70, 13,  0, 20, 23,  2,  0,  1, 60, 71,
 15, 15,  2,  0,  0,  5,  2, 50,  2, 60, 72, 50,  2, 60, 73,  0,  0,  0,  0,  0,
  0,  0,  0, 24,  2,  0,  0,  0,  6,102,108, 97,103,115,  0,  2,  0,  0,  0,  2,
102,  0,  2,  0,  0,  0,  3,115,116,  0,  2,  0,  0,  0,  4,109,115,103,  0,  2,
  0,  0,  0,  9,114,101, 97,100,102,114,111,109,  0,  2,  0,  0,  0,  6,101,114,
114,111,114,  0,  2,  0,  0,  0,  2, 35,  0,  2,  0,  0,  0,  2,110,  0,  2,  0,
  0,  0,  5,103,115,117, 98,  0,  2,  0,  0,  0,  5, 37, 46, 46, 42,  0,  2,  0,
  0,  0,  1,  0,  2,  0,  0,  0, 41, 35,110,111, 32,112, 97, 99,107, 97,103,101,
 32,110, 97,109,101, 32,110,111,114, 32,105,110,112,117,116, 32,102,105,108,101,
 32,112,114,111,118,105,100,101,100,  0,  2,  0,  0,  0,  2,112,  0,  2,  0,  0,
  0,  8, 80, 97, 99,107, 97,103,101,  0,  2,  0,  0,  0,  2,111,  0,  2,  0,  0,
  0,  8,119,114,105,116,101,116,111,  0,  2,  0,  0,  0,  2, 80,  0,  2,  0,  0,
  0,  6,112,114,105,110,116,  0,  2,  0,  0,  0,  9,112,114,101, 97,109, 98,108,
101,  0,  2,  0,  0,  0,  8,115,117,112, 99,111,100,101,  0,  2,  0,  0,  0,  9,
114,101,103,105,115,116,101,114,  0,  2,  0,  0,  0, 11,117,110,114,101,103,105,
115,116,101,114,  0,  2,  0,  0,  0,  2, 72,  0,  2,  0,  0,  0,  7,104,101, 97,
100,101,114,  0,
};

 lua_dobuffer(B1,sizeof(B1),"basic.lo");
 lua_dobuffer(B2,sizeof(B2),"feature.lo");
 lua_dobuffer(B3,sizeof(B3),"declaration.lo");
 lua_dobuffer(B4,sizeof(B4),"container.lo");
 lua_dobuffer(B5,sizeof(B5),"package.lo");
 lua_dobuffer(B6,sizeof(B6),"module.lo");
 lua_dobuffer(B7,sizeof(B7),"class.lo");
 lua_dobuffer(B8,sizeof(B8),"typedef.lo");
 lua_dobuffer(B9,sizeof(B9),"define.lo");
 lua_dobuffer(B10,sizeof(B10),"enumerate.lo");
 lua_dobuffer(B11,sizeof(B11),"variable.lo");
 lua_dobuffer(B12,sizeof(B12),"array.lo");
 lua_dobuffer(B13,sizeof(B13),"function.lo");
 lua_dobuffer(B14,sizeof(B14),"operator.lo");
 lua_dobuffer(B15,sizeof(B15),"verbatim.lo");
 lua_dobuffer(B16,sizeof(B16),"code.lo");
 lua_dobuffer(B17,sizeof(B17),"doit.lo");
}
tome-235-src/src/lua/lobject.c0000644000076400017500000000601211012107763014023 0ustar  dgdg/*
** $Id: lobject.c,v 1.3 2001/11/26 23:00:24 darkgod Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/

#include 
#include 
#include 
#include 
#include 

#include "lua.h"

#include "lmem.h"
#include "lobject.h"
#include "lstate.h"



const TObject luaO_nilobject = {LUA_TNIL, {NULL}};


const char *const luaO_typenames[] = {
  "userdata", "nil", "number", "string", "table", "function"
};



/*
** returns smaller power of 2 larger than `n' (minimum is MINPOWER2) 
*/
lint32 luaO_power2 (lint32 n) {
  lint32 p = MINPOWER2;
  while (p<=n) p<<=1;
  return p;
}


int luaO_equalObj (const TObject *t1, const TObject *t2) {
  if (ttype(t1) != ttype(t2)) return 0;
  switch (ttype(t1)) {
    case LUA_TNUMBER:
      return nvalue(t1) == nvalue(t2);
    case LUA_TSTRING: case LUA_TUSERDATA:
      return tsvalue(t1) == tsvalue(t2);
    case LUA_TTABLE: 
      return hvalue(t1) == hvalue(t2);
    case LUA_TFUNCTION:
      return clvalue(t1) == clvalue(t2);
    default:
      LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type");
      return 1; /* LUA_TNIL */
  }
}


char *luaO_openspace (lua_State *L, size_t n) {
  if (n > L->Mbuffsize) {
    luaM_reallocvector(L, L->Mbuffer, n, char);
    L->nblocks += (n - L->Mbuffsize)*sizeof(char);
    L->Mbuffsize = n;
  }
  return L->Mbuffer;
}


int luaO_str2d (const char *s, Number *result) {  /* LUA_NUMBER */
  char *endptr;
  Number res = lua_str2number(s, &endptr);
  if (endptr == s) return 0;  /* no conversion */
  while (isspace((unsigned char)*endptr)) endptr++;
  if (*endptr != '\0') return 0;  /* invalid trailing characters? */
  *result = res;
  return 1;
}


/* maximum length of a string format for `luaO_verror' */
#define MAX_VERROR	280

/* this function needs to handle only '%d' and '%.XXs' formats */
void luaO_verror (lua_State *L, const char *fmt, ...) {
  va_list argp;
  char buff[MAX_VERROR];  /* to hold formatted message */
  va_start(argp, fmt);
  vsprintf(buff, fmt, argp);
  va_end(argp);
  lua_error(L, buff);
}


void luaO_chunkid (char *out, const char *source, int bufflen) {
  if (*source == '=') {
    strncpy(out, source+1, bufflen);  /* remove first char */
    out[bufflen-1] = '\0';  /* ensures null termination */
  }
  else {
    if (*source == '@') {
      int l;
      source++;  /* skip the `@' */
      bufflen -= sizeof("file `...%s'");
      l = strlen(source);
      if (l>bufflen) {
        source += (l-bufflen);  /* get last part of file name */
        sprintf(out, "file `...%.99s'", source);
      }
      else
        sprintf(out, "file `%.99s'", source);
    }
    else {
      int len = strcspn(source, "\n");  /* stop at first newline */
      bufflen -= sizeof("string \"%.*s...\"");
      if (len > bufflen) len = bufflen;
      if (source[len] != '\0') {  /* must truncate? */
        strcpy(out, "string \"");
        out += strlen(out);
        strncpy(out, source, len);
        strcpy(out+len, "...\"");
      }
      else
        sprintf(out, "string \"%.99s\"", source);
    }
  }
}
tome-235-src/src/lua/lobject.h0000644000076400017500000001125211012107763014032 0ustar  dgdg/*
** $Id: lobject.h,v 1.3 2001/11/26 23:00:24 darkgod Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/

#ifndef lobject_h
#define lobject_h


#include "llimits.h"
#include "lua.h"


#ifdef LUA_DEBUG
#undef NDEBUG
#include 
#define LUA_INTERNALERROR(s)	assert(((void)s,0))
#define LUA_ASSERT(c,s)		assert(((void)s,(c)))
#else
#define LUA_INTERNALERROR(s)	/* empty */
#define LUA_ASSERT(c,s)		/* empty */
#endif


#ifdef LUA_DEBUG
/* to avoid warnings, and make sure value is really unused */
#define UNUSED(x)	(x=0, (void)(x))
#else
#define UNUSED(x)	((void)(x))	/* to avoid warnings */
#endif


/* mark for closures active in the stack */
#define LUA_TMARK	6


/* tags for values visible from Lua == first user-created tag */
#define NUM_TAGS	6


/* check whether `t' is a mark */
#define is_T_MARK(t)	((t) == LUA_TMARK)


typedef union {
  struct TString *ts;	/* LUA_TSTRING, LUA_TUSERDATA */
  struct Closure *cl;	/* LUA_TFUNCTION */
  struct Hash *a;	/* LUA_TTABLE */
  struct CallInfo *i;	/* LUA_TLMARK */
  Number n;		/* LUA_TNUMBER */
} Value;


/* Macros to access values */
#define ttype(o)        ((o)->ttype)
#define nvalue(o)       ((o)->value.n)
#define tsvalue(o)      ((o)->value.ts)
#define clvalue(o)      ((o)->value.cl)
#define hvalue(o)       ((o)->value.a)
#define infovalue(o)	((o)->value.i)
#define svalue(o)       (tsvalue(o)->str)


typedef struct lua_TObject {
  int ttype;
  Value value;
} TObject;


/*
** String headers for string table
*/

/*
** most `malloc' libraries allocate memory in blocks of 8 bytes. TSPACK
** tries to make sizeof(TString) a multiple of this granularity, to reduce
** waste of space.
*/
#define TSPACK	((int)sizeof(int))

typedef struct TString {
  union {
    struct {  /* for strings */
      unsigned long hash;
      int constindex;  /* hint to reuse constants */
    } s;
    struct {  /* for userdata */
      int tag;
      void *value;
    } d;
  } u;
  size_t len;
  struct TString *nexthash;  /* chain for hash table */
  int marked;
  char str[TSPACK];   /* variable length string!! must be the last field! */
} TString;


/*
** Function Prototypes
*/
typedef struct Proto {
  Number *knum;  /* Number numbers used by the function */
  int nknum;  /* size of `knum' */
  struct TString **kstr;  /* strings used by the function */
  int nkstr;  /* size of `kstr' */
  struct Proto **kproto;  /* functions defined inside the function */
  int nkproto;  /* size of `kproto' */
  Instruction *code;
  int ncode;  /* size of `code'; when 0 means an incomplete `Proto' */
  short numparams;
  short is_vararg;
  short maxstacksize;
  short marked;
  struct Proto *next;
  /* debug information */
  int *lineinfo;  /* map from opcodes to source lines */
  int nlineinfo;  /* size of `lineinfo' */
  int nlocvars;
  struct LocVar *locvars;  /* information about local variables */
  int lineDefined;
  TString  *source;
} Proto;


typedef struct LocVar {
  TString *varname;
  int startpc;  /* first point where variable is active */
  int endpc;    /* first point where variable is dead */
} LocVar;


/*
** Closures
*/
typedef struct Closure {
  union {
    lua_CFunction c;  /* C functions */
    struct Proto *l;  /* Lua functions */
  } f;
  struct Closure *next;
  struct Closure *mark;  /* marked closures (point to itself when not marked) */
  short isC;  /* 0 for Lua functions, 1 for C functions */
  short nupvalues;
  TObject upvalue[1];
} Closure;


#define iscfunction(o)	(ttype(o) == LUA_TFUNCTION && clvalue(o)->isC)


typedef struct Node {
  TObject key;
  TObject val;
  struct Node *next;  /* for chaining */
} Node;

typedef struct Hash {
  Node *node;
  int htag;
  int size;
  Node *firstfree;  /* this position is free; all positions after it are full */
  struct Hash *next;
  struct Hash *mark;  /* marked tables (point to itself when not marked) */
} Hash;


/* unmarked tables and closures are represented by pointing `mark' to
** themselves
*/
#define ismarked(x)	((x)->mark != (x))


/*
** informations about a call (for debugging)
*/
typedef struct CallInfo {
  struct Closure *func;  /* function being called */
  const Instruction **pc;  /* current pc of called function */
  int lastpc;  /* last pc traced */
  int line;  /* current line */
  int refi;  /* current index in `lineinfo' */
} CallInfo;


extern const TObject luaO_nilobject;
extern const char *const luaO_typenames[];


#define luaO_typename(o)	(luaO_typenames[ttype(o)])


lint32 luaO_power2 (lint32 n);
char *luaO_openspace (lua_State *L, size_t n);

int luaO_equalObj (const TObject *t1, const TObject *t2);
int luaO_str2d (const char *s, Number *result);

void luaO_verror (lua_State *L, const char *fmt, ...);
void luaO_chunkid (char *out, const char *source, int len);


#endif
tome-235-src/src/lua/define.lua0000644000076400017500000000306211012107763014174 0ustar  dgdg-- tolua: define class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: define.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Define class
-- Represents a numeric const definition
-- The following filds are stored:
--   name = constant name
classDefine = {
 name = '',
 _base = classFeature,
}
settag(classDefine,tolua_tag)

-- register define
function classDefine:register ()
 local p = self:inmodule()
 if p then
  output(' tolua_constant(tolua_S,"'..p..'","'..self.lname..'",'..self.name..');') 
 else
  output(' tolua_constant(tolua_S,NULL,"'..self.lname..'",'..self.name..');') 
 end
end

-- unregister define
function classDefine:unregister ()
 if not self:inmodule() then
  output(' lua_pushnil(tolua_S); lua_setglobal(tolua_S,"'..self.lname..'");') 
 end
end

-- Print method
function classDefine:print (ident,close)
 print(ident.."Define{")
 print(ident.." name = '"..self.name.."',")
 print(ident.." lname = '"..self.lname.."',")
 print(ident.."}"..close)
end


-- Internal constructor
function _Define (t)
 t._base = classDefine
 settag(t,tolua_tag)

 if t.name == '' then
  error("#invalid define")
 end

 append(t)
 return t
end

-- Constructor
-- Expects a string representing the constant name
function Define (n)
 local t = split(n,'@')
 return _Define {
  name = t[1],
  lname = t[2] or t[1]
 }
end


tome-235-src/src/lua/class.lua0000644000076400017500000000347011012107763014052 0ustar  dgdg-- tolua: class class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: class.lua,v 1.2 2001/11/26 23:00:23 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications.


-- Class class
-- Represents a class definition.
-- Stores the following fields:
--    name = class name
--    base = class base, if any (only single inheritance is supported)
--    {i}  = list of members
classClass = {
 _base = classContainer,
 type = 'class',
 name = '',
 base = '',
}
settag(classClass,tolua_tag)


-- register class
function classClass:register ()
 output(' tolua_cclass(tolua_S,"'..self.name..'","'..self.base..'");')
 local i=1
 while self[i] do
  self[i]:register()
  i = i+1
 end
end

-- unregister class
function classClass:unregister ()
 output(' lua_pushnil(tolua_S); lua_setglobal(tolua_S,"'..self.name..'");')
end

-- output tags
function classClass:decltag ()
 self.itype,self.tag = tagvar(self.name);
 self.citype,self.ctag = tagvar(self.name,'const');
 local i=1
 while self[i] do
  self[i]:decltag()
  i = i+1
 end
end


-- Print method
function classClass:print (ident,close)
 print(ident.."Class{")
 print(ident.." name = '"..self.name.."',")
 print(ident.." base = '"..self.base.."';")
 local i=1
 while self[i] do
  self[i]:print(ident.." ",",")
  i = i+1
 end
 print(ident.."}"..close)
end

-- Internal constructor
function _Class (t)
 t._base = classClass
 settag(t,tolua_tag)
 append(t)
 return t
end

-- Constructor
-- Expects the name, the base and the body of the class.
function Class (n,p,b)
 local c = _Class(_Container{name=n, base=p})
 push(c)
 c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
 pop()
end


tome-235-src/src/lua/variable.lua0000644000076400017500000001175411012107763014536 0ustar  dgdg-- tolua: variable class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: variable.lua,v 1.4 2004/06/04 13:42:10 neil Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Variable class
-- Represents a extern variable or a public member of a class.
-- Stores all fields present in a declaration.
classVariable = {
 _base = classDeclaration,
}

settag(classVariable,tolua_tag)

-- Print method
function classVariable:print (ident,close)
 print(ident.."Variable{")
 print(ident.." mod  = '"..self.mod.."',")
 print(ident.." type = '"..self.type.."',")
 print(ident.." ptr  = '"..self.ptr.."',")
 print(ident.." name = '"..self.name.."',")
 print(ident.." def  = '"..self.def.."',")
 print(ident.." ret  = '"..self.ret.."',")
 print(ident.."}"..close)
end

-- get variable value
function classVariable:getvalue (class,static)
 if class and static then
  return class..'::'..self.name
 elseif class then
  return 'self->'..self.name
 else
  return self.name
 end
end

-- Write binding functions
function classVariable:supcode ()
 local class = self:inclass()

 -- get function ------------------------------------------------
 if class then
  output("/* get function:",self.name," of class ",class," */")
 else
  output("/* get function:",self.name," */")
 end
 self.cgetname = self:cfuncname("toluaI_get")
 output("static int",self.cgetname,"(lua_State* tolua_S)") 
 output("{")

 -- declare self, if the case
 local _,_,static = strfind(self.mod,'^%s*(static)')
 if class and static==nil then
  output(' ',class,'*','self = ')
  output('(',class,'*) ')
  output('tolua_getusertype(tolua_S,1,0);')
 elseif static then
  _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
 end


 -- check self value
 if class and static==nil then
  output('  if (!self) TOLUA_ERR_SELF;');
 end

 -- return value
 local t,ct = isbasic(self.type)
 if t then
  output('  tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
 else
  if self.ptr == '&' or self.ptr == '' then
   output('  tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',',self.tag,');')
  else
   output('  tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',',self.tag,');')
  end
 end
 output(' return 1;')
 output('}')
 output('\n')

 -- set function ------------------------------------------------
 if not strfind(self.mod,'const') then
  if class then
   output("/* set function:",self.name," of class ",class," */")
  else
   output("/* set function:",self.name," */")
  end
  self.csetname = self:cfuncname("toluaI_set")
  output("static int",self.csetname,"(lua_State* tolua_S)")
  output("{")

  -- declare self, if the case
  local narg=1
  if class and static==nil then
   output(' ',class,'*','self = ')
   output('(',class,'*) ')
   output('tolua_getusertype(tolua_S,1,0);')
   -- check self value
   output('  if (!self) TOLUA_ERR_SELF;');
   narg = narg+1
  elseif static then
   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
   narg = narg+1
  end

  -- check type
  output('  if (!'..self:outchecktype(narg)..')')
  output('   TOLUA_ERR_ASSIGN;')
 
  -- assign value
  local ptr = ''
  if self.ptr~='' then ptr = '*' end
  output(' ')
  if class and static then
   output(class..'::'..self.name)
  elseif class then
   output('self->'..self.name)
  else
   output(self.name)
  end
  local t = isbasic(self.type)
  output(' = ')
  if not t and ptr=='' then output('*') end
  output('((',self.mod,self.type)
  if not t then
   output('*')
  end
  output(') ')
  local def = 0
  if self.def ~= '' then def = self.def end
  if t then
   output('tolua_get'..t,'(tolua_S,',narg,',',def,'));')
  else
   output('tolua_getusertype(tolua_S,',narg,',',def,'));')
  end
  output(' return 0;')
  output('}')
  output('\n')
 end 

end

function classVariable:register ()
 local parent = self:inclass() or self:inmodule()
 if parent then
  if self.csetname then
   output(' tolua_tablevar(tolua_S,"'..parent..'","'..self.lname..'",'..self.cgetname..','..self.csetname..');')
  else
   output(' tolua_tablevar(tolua_S,"'..parent..'","'..self.lname..'",'..self.cgetname..',NULL);')
  end
 else
  if self.csetname then
   output(' tolua_globalvar(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
  else
   output(' tolua_globalvar(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
  end
 end
end

function classVariable:unregister ()
 if self:inclass()==nil and self:inmodule()==nil then
  output(' lua_getglobals(tolua_S);') 
  output(' lua_pushstring(tolua_S,"',self.lname,'"); lua_pushnil(tolua_S); lua_rawset(tolua_S,-3);')
  output(' lua_pop(tolua_S,1);')
 end
end 
 

-- Internal constructor
function _Variable (t)
 t._base = classVariable
 settag(t,tolua_tag)
 append(t)
 return t
end

-- Constructor
-- Expects a string representing the variable declaration.
function Variable (s)
 return _Variable (Declaration(s,'var'))
end


tome-235-src/src/lua/tolualua.pkg0000644000076400017500000000042111012107763014564 0ustar  dgdg$[
$
$
$
$
$
$
$
$
$
$
$
$
$
$
$
$
$
$
$]

tome-235-src/src/lua/lstring.c0000644000076400017500000001012411012107763014062 0ustar  dgdg/*
** $Id: lstring.c,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/


#include 

#include "lua.h"

#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"


/*
** type equivalent to TString, but with maximum alignment requirements
*/
union L_UTString {
  TString ts;
  union L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
};



void luaS_init (lua_State *L) {
  L->strt.hash = luaM_newvector(L, 1, TString *);
  L->udt.hash = luaM_newvector(L, 1, TString *);
  L->nblocks += 2*sizeof(TString *);
  L->strt.size = L->udt.size = 1;
  L->strt.nuse = L->udt.nuse = 0;
  L->strt.hash[0] = L->udt.hash[0] = NULL;
}


void luaS_freeall (lua_State *L) {
  LUA_ASSERT(L->strt.nuse==0, "non-empty string table");
  L->nblocks -= (L->strt.size + L->udt.size)*sizeof(TString *);
  luaM_free(L, L->strt.hash);
  LUA_ASSERT(L->udt.nuse==0, "non-empty udata table");
  luaM_free(L, L->udt.hash);
}


static unsigned long hash_s (const char *s, size_t l) {
  unsigned long h = l;  /* seed */
  size_t step = (l>>5)|1;  /* if string is too long, don't hash all its chars */
  for (; l>=step; l-=step)
    h = h ^ ((h<<5)+(h>>2)+(unsigned char)*(s++));
  return h;
}


void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
  TString **newhash = luaM_newvector(L, newsize, TString *);
  int i;
  for (i=0; isize; i++) {
    TString *p = tb->hash[i];
    while (p) {  /* for each node in the list */
      TString *next = p->nexthash;  /* save next */
      unsigned long h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value);
      int h1 = h&(newsize-1);  /* new position */
      LUA_ASSERT(h%newsize == (h&(newsize-1)),
                    "a&(x-1) == a%x, for x power of 2");
      p->nexthash = newhash[h1];  /* chain it in new position */
      newhash[h1] = p;
      p = next;
    }
  }
  luaM_free(L, tb->hash);
  L->nblocks += (newsize - tb->size)*sizeof(TString *);
  tb->size = newsize;
  tb->hash = newhash;
}


static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) {
  ts->nexthash = tb->hash[h];  /* chain new entry */
  tb->hash[h] = ts;
  tb->nuse++;
  if (tb->nuse > (lint32)tb->size && tb->size < MAX_INT/2)  /* too crowded? */
    luaS_resize(L, tb, tb->size*2);
}



TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
  unsigned long h = hash_s(str, l);
  int h1 = h & (L->strt.size-1);
  TString *ts;
  for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) {
    if (ts->len == l && (memcmp(str, ts->str, l) == 0))
      return ts;
  }
  /* not found */
  ts = (TString *)luaM_malloc(L, sizestring(l));
  ts->marked = 0;
  ts->nexthash = NULL;
  ts->len = l;
  ts->u.s.hash = h;
  ts->u.s.constindex = 0;
  memcpy(ts->str, str, l);
  ts->str[l] = 0;  /* ending 0 */
  L->nblocks += sizestring(l);
  newentry(L, &L->strt, ts, h1);  /* insert it on table */
  return ts;
}


TString *luaS_newudata (lua_State *L, size_t s, void *udata) {
  union L_UTString *uts = (union L_UTString *)luaM_malloc(L,
                                (lint32)sizeof(union L_UTString)+s);
  TString *ts = &uts->ts;
  ts->marked = 0;
  ts->nexthash = NULL;
  ts->len = s;
  ts->u.d.tag = 0;
  ts->u.d.value = (udata == NULL) ? uts+1 : udata;
  L->nblocks += sizestring(s);
 /* insert it on table */
  newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1));
  return ts;
}


TString *luaS_createudata (lua_State *L, void *udata, int tag) {
  int h1 = IntPoint(udata) & (L->udt.size-1);
  TString *ts;
  for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) {
    if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG))
      return ts;
  }
  /* not found */
  ts = luaS_newudata(L, 0, udata);
  if (tag != LUA_ANYTAG)
    ts->u.d.tag = tag;
  return ts;
}


TString *luaS_new (lua_State *L, const char *str) {
  return luaS_newlstr(L, str, strlen(str));
}


TString *luaS_newfixed (lua_State *L, const char *str) {
  TString *ts = luaS_new(L, str);
  if (ts->marked == 0) ts->marked = FIXMARK;  /* avoid GC */
  return ts;
}

tome-235-src/src/lua/lstring.h0000644000076400017500000000166111012107763014075 0ustar  dgdg/*
** $Id: lstring.h,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/

#ifndef lstring_h
#define lstring_h


#include "lobject.h"
#include "lstate.h"


/*
** any TString with mark>=FIXMARK is never collected.
** Marks>=RESERVEDMARK are used to identify reserved words.
*/
#define FIXMARK		2
#define RESERVEDMARK	3


#define sizestring(l)	((long)sizeof(TString) + \
                         ((long)(l+1)-TSPACK)*(long)sizeof(char))


void luaS_init (lua_State *L);
void luaS_resize (lua_State *L, stringtable *tb, int newsize);
TString *luaS_newudata (lua_State *L, size_t s, void *udata);
TString *luaS_createudata (lua_State *L, void *udata, int tag);
void luaS_freeall (lua_State *L);
TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
TString *luaS_new (lua_State *L, const char *str);
TString *luaS_newfixed (lua_State *L, const char *str);


#endif
tome-235-src/src/lua/lstrlib.c0000644000076400017500000004200611012107763014057 0ustar  dgdg/*
** $Id: lstrlib.c,v 1.3 2001/11/26 23:00:26 darkgod Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 
#include 
#include 

#include "lua.h"

#include "lauxlib.h"
#include "lualib.h"



static int str_len (lua_State *L) {
  size_t l;
  luaL_check_lstr(L, 1, &l);
  lua_pushnumber(L, l);
  return 1;
}


static long posrelat (long pos, size_t len) {
  /* relative string position: negative means back from end */
  return (pos>=0) ? pos : (long)len+pos+1;
}


static int str_sub (lua_State *L) {
  size_t l;
  const char *s = luaL_check_lstr(L, 1, &l);
  long start = posrelat(luaL_check_long(L, 2), l);
  long end = posrelat(luaL_opt_long(L, 3, -1), l);
  if (start < 1) start = 1;
  if (end > (long)l) end = l;
  if (start <= end)
    lua_pushlstring(L, s+start-1, end-start+1);
  else lua_pushstring(L, "");
  return 1;
}


static int str_lower (lua_State *L) {
  size_t l;
  size_t i;
  luaL_Buffer b;
  const char *s = luaL_check_lstr(L, 1, &l);
  luaL_buffinit(L, &b);
  for (i=0; i 0)
    luaL_addlstring(&b, s, l);
  luaL_pushresult(&b);
  return 1;
}


static int str_byte (lua_State *L) {
  size_t l;
  const char *s = luaL_check_lstr(L, 1, &l);
  long pos = posrelat(luaL_opt_long(L, 2, 1), l);
  luaL_arg_check(L, 0level && cap->capture[l].len != -1))
    lua_error(L, "invalid capture index");
  return l;
}


static int capture_to_close (lua_State *L, struct Capture *cap) {
  int level = cap->level;
  for (level--; level>=0; level--)
    if (cap->capture[level].len == -1) return level;
  lua_error(L, "invalid pattern capture");
  return 0;  /* to avoid warnings */
}


const char *luaI_classend (lua_State *L, const char *p) {
  switch (*p++) {
    case ESC:
      if (*p == '\0') lua_error(L, "malformed pattern (ends with `%')");
      return p+1;
    case '[':
      if (*p == '^') p++;
      do {  /* look for a ']' */
        if (*p == '\0') lua_error(L, "malformed pattern (missing `]')");
        if (*(p++) == ESC && *p != '\0') p++;  /* skip escapes (e.g. '%]') */
      } while (*p != ']');
      return p+1;
    default:
      return p;
  }
}


static int match_class (int c, int cl) {
  int res;
  switch (tolower(cl)) {
    case 'a' : res = isalpha(c); break;
    case 'c' : res = iscntrl(c); break;
    case 'd' : res = isdigit(c); break;
    case 'l' : res = islower(c); break;
    case 'p' : res = ispunct(c); break;
    case 's' : res = isspace(c); break;
    case 'u' : res = isupper(c); break;
    case 'w' : res = isalnum(c); break;
    case 'x' : res = isxdigit(c); break;
    case 'z' : res = (c == '\0'); break;
    default: return (cl == c);
  }
  return (islower(cl) ? res : !res);
}



static int matchbracketclass (int c, const char *p, const char *endclass) {
  int sig = 1;
  if (*(p+1) == '^') {
    sig = 0;
    p++;  /* skip the '^' */
  }
  while (++p < endclass) {
    if (*p == ESC) {
      p++;
      if (match_class(c, (unsigned char)*p))
        return sig;
    }
    else if ((*(p+1) == '-') && (p+2 < endclass)) {
      p+=2;
      if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p)
        return sig;
    }
    else if ((int)(unsigned char)*p == c) return sig;
  }
  return !sig;
}



int luaI_singlematch (int c, const char *p, const char *ep) {
  switch (*p) {
    case '.':  /* matches any char */
      return 1;
    case ESC:
      return match_class(c, (unsigned char)*(p+1));
    case '[':
      return matchbracketclass(c, p, ep-1);
    default:
      return ((unsigned char)*p == c);
  }
}


static const char *match (lua_State *L, const char *s, const char *p,
                          struct Capture *cap);


static const char *matchbalance (lua_State *L, const char *s, const char *p,
                                 struct Capture *cap) {
  if (*p == 0 || *(p+1) == 0)
    lua_error(L, "unbalanced pattern");
  if (*s != *p) return NULL;
  else {
    int b = *p;
    int e = *(p+1);
    int cont = 1;
    while (++s < cap->src_end) {
      if (*s == e) {
        if (--cont == 0) return s+1;
      }
      else if (*s == b) cont++;
    }
  }
  return NULL;  /* string ends out of balance */
}


static const char *max_expand (lua_State *L, const char *s, const char *p,
                               const char *ep, struct Capture *cap) {
  long i = 0;  /* counts maximum expand for item */
  while ((s+i)src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
    i++;
  /* keeps trying to match with the maximum repetitions */
  while (i>=0) {
    const char *res = match(L, (s+i), ep+1, cap);
    if (res) return res;
    i--;  /* else didn't match; reduce 1 repetition to try again */
  }
  return NULL;
}


static const char *min_expand (lua_State *L, const char *s, const char *p,
                               const char *ep, struct Capture *cap) {
  for (;;) {
    const char *res = match(L, s, ep+1, cap);
    if (res != NULL)
      return res;
    else if (ssrc_end && luaI_singlematch((unsigned char)*s, p, ep))
      s++;  /* try with one more repetition */
    else return NULL;
  }
}


static const char *start_capture (lua_State *L, const char *s, const char *p,
                                  struct Capture *cap) {
  const char *res;
  int level = cap->level;
  if (level >= MAX_CAPTURES) lua_error(L, "too many captures");
  cap->capture[level].init = s;
  cap->capture[level].len = -1;
  cap->level = level+1;
  if ((res=match(L, s, p+1, cap)) == NULL)  /* match failed? */
    cap->level--;  /* undo capture */
  return res;
}


static const char *end_capture (lua_State *L, const char *s, const char *p,
                                struct Capture *cap) {
  int l = capture_to_close(L, cap);
  const char *res;
  cap->capture[l].len = s - cap->capture[l].init;  /* close capture */
  if ((res = match(L, s, p+1, cap)) == NULL)  /* match failed? */
    cap->capture[l].len = -1;  /* undo capture */
  return res;
}


static const char *match_capture (lua_State *L, const char *s, int level,
                                  struct Capture *cap) {
  int l = check_capture(L, level, cap);
  size_t len = cap->capture[l].len;
  if ((size_t)(cap->src_end-s) >= len &&
      memcmp(cap->capture[l].init, s, len) == 0)
    return s+len;
  else return NULL;
}


static const char *match (lua_State *L, const char *s, const char *p,
                          struct Capture *cap) {
  init: /* using goto's to optimize tail recursion */
  switch (*p) {
    case '(':  /* start capture */
      return start_capture(L, s, p, cap);
    case ')':  /* end capture */
      return end_capture(L, s, p, cap);
    case ESC:  /* may be %[0-9] or %b */
      if (isdigit((unsigned char)(*(p+1)))) {  /* capture? */
        s = match_capture(L, s, *(p+1), cap);
        if (s == NULL) return NULL;
        p+=2; goto init;  /* else return match(L, s, p+2, cap) */
      }
      else if (*(p+1) == 'b') {  /* balanced string? */
        s = matchbalance(L, s, p+2, cap);
        if (s == NULL) return NULL;
        p+=4; goto init;  /* else return match(L, s, p+4, cap); */
      }
      else goto dflt;  /* case default */
    case '\0':  /* end of pattern */
      return s;  /* match succeeded */
    case '$':
      if (*(p+1) == '\0')  /* is the '$' the last char in pattern? */
        return (s == cap->src_end) ? s : NULL;  /* check end of string */
      else goto dflt;
    default: dflt: {  /* it is a pattern item */
      const char *ep = luaI_classend(L, p);  /* points to what is next */
      int m = ssrc_end && luaI_singlematch((unsigned char)*s, p, ep);
      switch (*ep) {
        case '?': {  /* optional */
          const char *res;
          if (m && ((res=match(L, s+1, ep+1, cap)) != NULL))
            return res;
          p=ep+1; goto init;  /* else return match(L, s, ep+1, cap); */
        }
        case '*':  /* 0 or more repetitions */
          return max_expand(L, s, p, ep, cap);
        case '+':  /* 1 or more repetitions */
          return (m ? max_expand(L, s+1, p, ep, cap) : NULL);
        case '-':  /* 0 or more repetitions (minimum) */
          return min_expand(L, s, p, ep, cap);
        default:
          if (!m) return NULL;
          s++; p=ep; goto init;  /* else return match(L, s+1, ep, cap); */
      }
    }
  }
}



static const char *lmemfind (const char *s1, size_t l1,
                             const char *s2, size_t l2) {
  if (l2 == 0) return s1;  /* empty strings are everywhere */
  else if (l2 > l1) return NULL;  /* avoids a negative `l1' */
  else {
    const char *init;  /* to search for a `*s2' inside `s1' */
    l2--;  /* 1st char will be checked by `memchr' */
    l1 = l1-l2;  /* `s2' cannot be found after that */
    while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
      init++;   /* 1st char is already checked */
      if (memcmp(init, s2+1, l2) == 0)
        return init-1;
      else {  /* correct `l1' and `s1' to try again */
        l1 -= init-s1;
        s1 = init;
      }
    }
    return NULL;  /* not found */
  }
}


static int push_captures (lua_State *L, struct Capture *cap) {
  int i;
  luaL_checkstack(L, cap->level, "too many captures");
  for (i=0; ilevel; i++) {
    int l = cap->capture[i].len;
    if (l == -1) lua_error(L, "unfinished capture");
    lua_pushlstring(L, cap->capture[i].init, l);
  }
  return cap->level;  /* number of strings pushed */
}


static int str_find (lua_State *L) {
  size_t l1, l2;
  const char *s = luaL_check_lstr(L, 1, &l1);
  const char *p = luaL_check_lstr(L, 2, &l2);
  long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1;
  struct Capture cap;
  luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range");
  if (lua_gettop(L) > 3 ||  /* extra argument? */
      strpbrk(p, SPECIALS) == NULL) {  /* or no special characters? */
    const char *s2 = lmemfind(s+init, l1-init, p, l2);
    if (s2) {
      lua_pushnumber(L, s2-s+1);
      lua_pushnumber(L, s2-s+l2);
      return 2;
    }
  }
  else {
    int anchor = (*p == '^') ? (p++, 1) : 0;
    const char *s1=s+init;
    cap.src_end = s+l1;
    do {
      const char *res;
      cap.level = 0;
      if ((res=match(L, s1, p, &cap)) != NULL) {
        lua_pushnumber(L, s1-s+1);  /* start */
        lua_pushnumber(L, res-s);   /* end */
        return push_captures(L, &cap) + 2;
      }
    } while (s1++capture[level].init, cap->capture[level].len);
        }
      }
    }
  }
  else {  /* is a function */
    int n;
    lua_pushvalue(L, 3);
    n = push_captures(L, cap);
    lua_rawcall(L, n, 1);
    if (lua_isstring(L, -1))
      luaL_addvalue(b);  /* add return to accumulated result */
    else
      lua_pop(L, 1);  /* function result is not a string: pop it */
  }
}


static int str_gsub (lua_State *L) {
  size_t srcl;
  const char *src = luaL_check_lstr(L, 1, &srcl);
  const char *p = luaL_check_string(L, 2);
  int max_s = luaL_opt_int(L, 4, srcl+1);
  int anchor = (*p == '^') ? (p++, 1) : 0;
  int n = 0;
  struct Capture cap;
  luaL_Buffer b;
  luaL_arg_check(L,
    lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
    3, "string or function expected");
  luaL_buffinit(L, &b);
  cap.src_end = src+srcl;
  while (n < max_s) {
    const char *e;
    cap.level = 0;
    e = match(L, src, p, &cap);
    if (e) {
      n++;
      add_s(L, &b, &cap);
    }
    if (e && e>src) /* non empty match? */
      src = e;  /* skip it */
    else if (src < cap.src_end)
      luaL_putchar(&b, *src++);
    else break;
    if (anchor) break;
  }
  luaL_addlstring(&b, src, cap.src_end-src);
  luaL_pushresult(&b);
  lua_pushnumber(L, n);  /* number of substitutions */
  return 2;
}

/* }====================================================== */


static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) {
  size_t l;
  const char *s = luaL_check_lstr(L, arg, &l);
  luaL_putchar(b, '"');
  while (l--) {
    switch (*s) {
      case '"':  case '\\':  case '\n':
        luaL_putchar(b, '\\');
        luaL_putchar(b, *s);
        break;
      case '\0': luaL_addlstring(b, "\\000", 4); break;
      default: luaL_putchar(b, *s);
    }
    s++;
  }
  luaL_putchar(b, '"');
}

/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
#define MAX_ITEM	512
/* maximum size of each format specification (such as '%-099.99d') */
#define MAX_FORMAT	20

static int str_format (lua_State *L) {
  int arg = 1;
  const char *strfrmt = luaL_check_string(L, arg);
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (*strfrmt) {
    if (*strfrmt != '%')
      luaL_putchar(&b, *strfrmt++);
    else if (*++strfrmt == '%')
      luaL_putchar(&b, *strfrmt++);  /* %% */
    else { /* format item */
      struct Capture cap;
      char form[MAX_FORMAT];  /* to store the format ('%...') */
      char buff[MAX_ITEM];  /* to store the formatted item */
      const char *initf = strfrmt;
      form[0] = '%';
      if (isdigit((unsigned char)*initf) && *(initf+1) == '$') {
        arg = *initf - '0';
        initf += 2;  /* skip the 'n$' */
      }
      arg++;
      cap.src_end = strfrmt+strlen(strfrmt)+1;
      cap.level = 0;
      strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
      if (cap.capture[0].len > 2 || cap.capture[1].len > 2 ||  /* < 100? */
          strfrmt-initf > MAX_FORMAT-2)
        lua_error(L, "invalid format (width or precision too long)");
      strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
      form[strfrmt-initf+2] = 0;
      switch (*strfrmt++) {
        case 'c':  case 'd':  case 'i':
          sprintf(buff, form, luaL_check_int(L, arg));
          break;
        case 'o':  case 'u':  case 'x':  case 'X':
          sprintf(buff, form, (unsigned int)luaL_check_number(L, arg));
          break;
        case 'e':  case 'E': case 'f': case 'g': case 'G':
          sprintf(buff, form, luaL_check_number(L, arg));
          break;
        case 'q':
          luaI_addquoted(L, &b, arg);
          continue;  /* skip the "addsize" at the end */
        case 's': {
          size_t l;
          const char *s = luaL_check_lstr(L, arg, &l);
          if (cap.capture[1].len == 0 && l >= 100) {
            /* no precision and string is too long to be formatted;
               keep original string */
            lua_pushvalue(L, arg);
            luaL_addvalue(&b);
            continue;  /* skip the "addsize" at the end */
          }
          else {
            sprintf(buff, form, s);
            break;
          }
        }
        default:  /* also treat cases 'pnLlh' */
          lua_error(L, "invalid option in `format'");
      }
      luaL_addlstring(&b, buff, strlen(buff));
    }
  }
  luaL_pushresult(&b);
  return 1;
}


static const struct luaL_reg strlib[] = {
{"strlen", str_len},
{"strsub", str_sub},
{"strlower", str_lower},
{"strupper", str_upper},
{"strchar", str_char},
{"strrep", str_rep},
{"ascii", str_byte},  /* for compatibility with 3.0 and earlier */
{"strbyte", str_byte},
{"format", str_format},
{"strfind", str_find},
{"gsub", str_gsub}
};


/*
** Open string library
*/
LUALIB_API void lua_strlibopen (lua_State *L) {
  luaL_openl(L, strlib);
}
tome-235-src/src/lua/.cvsignore0000644000076400017500000000001311012107763014230 0ustar  dgdgtolua
host
tome-235-src/src/lua/llimits.h0000644000076400017500000001065511012107763014073 0ustar  dgdg/*
** $Id: llimits.h,v 1.2 2001/11/26 23:00:24 darkgod Exp $
** Limits, basic types, and some other "installation-dependent" definitions
** See Copyright Notice in lua.h
*/

#ifndef llimits_h
#define llimits_h


#include 
#include 



/*
** try to find number of bits in an integer
*/
#ifndef BITS_INT
/* avoid overflows in comparison */
#if INT_MAX-20 < 32760
#define	BITS_INT	16
#else
#if INT_MAX > 2147483640L
/* machine has at least 32 bits */
#define BITS_INT	32
#else
#error "you must define BITS_INT with number of bits in an integer"
#endif
#endif
#endif


/*
** Define the type `number' of Lua
** GREP LUA_NUMBER to change that
*/
#ifndef LUA_NUM_TYPE
#define LUA_NUM_TYPE long
#endif

typedef LUA_NUM_TYPE Number;

/* function to convert a Number to a string */
#define NUMBER_FMT	"%ld"		/* LUA_NUMBER */
#define lua_number2str(s,n)	sprintf((s), NUMBER_FMT, (n))

/* function to convert a string to a Number */
#define lua_str2number(s,p)	strtol((s), (p), 10)



typedef unsigned long lint32;  /* unsigned int with at least 32 bits */


#define MAX_SIZET	((size_t)(~(size_t)0)-2)


#define MAX_INT (INT_MAX-2)  /* maximum value of an int (-2 for safety) */

/*
** conversion of pointer to int (for hashing only)
** (the shift removes bits that are usually 0 because of alignment)
*/
#define IntPoint(p)  (((unsigned long)(p)) >> 3)



#define MINPOWER2       4       /* minimum size for "growing" vectors */



#ifndef DEFAULT_STACK_SIZE
#define DEFAULT_STACK_SIZE      1024
#endif



/* type to ensure maximum alignment */
union L_Umaxalign { long d; char *s; long l; };



/*
** type for virtual-machine instructions
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
** For a very small machine, you may change that to 2 bytes (and adjust
** the following limits accordingly)
*/
typedef unsigned long Instruction;


/*
** size and position of opcode arguments.
** For an instruction with 2 bytes, size is 16, and size_b can be 5
** (accordingly, size_u will be 10, and size_a will be 5)
*/
#define SIZE_INSTRUCTION        32
#define SIZE_B          9

#define SIZE_OP         6
#define SIZE_U          (SIZE_INSTRUCTION-SIZE_OP)
#define POS_U           SIZE_OP
#define POS_B           SIZE_OP
#define SIZE_A          (SIZE_INSTRUCTION-(SIZE_OP+SIZE_B))
#define POS_A           (SIZE_OP+SIZE_B)


/*
** limits for opcode arguments.
** we use (signed) int to manipulate most arguments,
** so they must fit in BITS_INT-1 bits (-1 for sign)
*/
#if SIZE_U < BITS_INT-1
#define MAXARG_U        ((1<>1)		/* `S' is signed */
#else
#define MAXARG_U        MAX_INT
#define MAXARG_S        MAX_INT
#endif

#if SIZE_A < BITS_INT-1
#define MAXARG_A        ((1< MAXARG_B
#undef MAXSTACK
#define MAXSTACK	MAXARG_B
#endif


/* maximum number of local variables */
#ifndef MAXLOCALS
#define MAXLOCALS 200           /* arbitrary limit (=MAXSTACK
#undef MAXLOCALS
#define MAXLOCALS	(MAXSTACK-1)
#endif


/* maximum number of upvalues */
#ifndef MAXUPVALUES
#define MAXUPVALUES 32          /* arbitrary limit (<=MAXARG_B) */
#endif
#if MAXUPVALUES>MAXARG_B
#undef MAXUPVALUES
#define MAXUPVALUES	MAXARG_B
#endif


/* maximum number of variables in the left side of an assignment */
#ifndef MAXVARSLH
#define MAXVARSLH 100           /* arbitrary limit (=MULT_RET
#undef MAXVARSLH
#define MAXVARSLH	(MULT_RET-1)
#endif


/* maximum number of parameters in a function */
#ifndef MAXPARAMS
#define MAXPARAMS 100           /* arbitrary limit (=MAXLOCALS
#undef MAXPARAMS
#define MAXPARAMS	(MAXLOCALS-1)
#endif


/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH	64
#if LFIELDS_PER_FLUSH>(MAXSTACK/4)
#undef LFIELDS_PER_FLUSH
#define LFIELDS_PER_FLUSH	(MAXSTACK/4)
#endif

/* number of record items to accumulate before a SETMAP instruction */
/* (each item counts 2 elements on the stack: an index and a value) */
#define RFIELDS_PER_FLUSH	(LFIELDS_PER_FLUSH/2)


/* maximum lookback to find a real constant (for code generation) */
#ifndef LOOKBACKNUMS
#define LOOKBACKNUMS    20      /* arbitrary constant */
#endif


#endif
tome-235-src/src/lua/print.h0000644000076400017500000000467311012107763013555 0ustar  dgdg/*
** $Id: print.h,v 1.2 2001/11/26 23:00:27 darkgod Exp $
** extracted automatically from lopcodes.h by mkprint.lua -- DO NOT EDIT
** See Copyright Notice in lua.h
*/

  case OP_END: P_OP("END"); P_NONE; break;
  case OP_RETURN: P_OP("RETURN"); P_U; break;
  case OP_CALL: P_OP("CALL"); P_AB; break;
  case OP_TAILCALL: P_OP("TAILCALL"); P_AB; break;
  case OP_PUSHNIL: P_OP("PUSHNIL"); P_U; break;
  case OP_POP: P_OP("POP"); P_U; break;
  case OP_PUSHINT: P_OP("PUSHINT"); P_S; break;
  case OP_PUSHSTRING: P_OP("PUSHSTRING"); P_Q; break;
  case OP_PUSHNUM: P_OP("PUSHNUM"); P_N; break;
  case OP_PUSHNEGNUM: P_OP("PUSHNEGNUM"); P_N; break;
  case OP_PUSHUPVALUE: P_OP("PUSHUPVALUE"); P_U; break;
  case OP_GETLOCAL: P_OP("GETLOCAL"); P_L; break;
  case OP_GETGLOBAL: P_OP("GETGLOBAL"); P_K; break;
  case OP_GETTABLE: P_OP("GETTABLE"); P_NONE; break;
  case OP_GETDOTTED: P_OP("GETDOTTED"); P_K; break;
  case OP_GETINDEXED: P_OP("GETINDEXED"); P_L; break;
  case OP_PUSHSELF: P_OP("PUSHSELF"); P_K; break;
  case OP_CREATETABLE: P_OP("CREATETABLE"); P_U; break;
  case OP_SETLOCAL: P_OP("SETLOCAL"); P_L; break;
  case OP_SETGLOBAL: P_OP("SETGLOBAL"); P_K; break;
  case OP_SETTABLE: P_OP("SETTABLE"); P_AB; break;
  case OP_SETLIST: P_OP("SETLIST"); P_AB; break;
  case OP_SETMAP: P_OP("SETMAP"); P_U; break;
  case OP_ADD: P_OP("ADD"); P_NONE; break;
  case OP_ADDI: P_OP("ADDI"); P_S; break;
  case OP_SUB: P_OP("SUB"); P_NONE; break;
  case OP_MULT: P_OP("MULT"); P_NONE; break;
  case OP_DIV: P_OP("DIV"); P_NONE; break;
  case OP_POW: P_OP("POW"); P_NONE; break;
  case OP_CONCAT: P_OP("CONCAT"); P_U; break;
  case OP_MINUS: P_OP("MINUS"); P_NONE; break;
  case OP_NOT: P_OP("NOT"); P_NONE; break;
  case OP_JMPNE: P_OP("JMPNE"); P_J; break;
  case OP_JMPEQ: P_OP("JMPEQ"); P_J; break;
  case OP_JMPLT: P_OP("JMPLT"); P_J; break;
  case OP_JMPLE: P_OP("JMPLE"); P_J; break;
  case OP_JMPGT: P_OP("JMPGT"); P_J; break;
  case OP_JMPGE: P_OP("JMPGE"); P_J; break;
  case OP_JMPT: P_OP("JMPT"); P_J; break;
  case OP_JMPF: P_OP("JMPF"); P_J; break;
  case OP_JMPONT: P_OP("JMPONT"); P_J; break;
  case OP_JMPONF: P_OP("JMPONF"); P_J; break;
  case OP_JMP: P_OP("JMP"); P_J; break;
  case OP_PUSHNILJMP: P_OP("PUSHNILJMP"); P_NONE; break;
  case OP_FORPREP: P_OP("FORPREP"); P_J; break;
  case OP_FORLOOP: P_OP("FORLOOP"); P_J; break;
  case OP_LFORPREP: P_OP("LFORPREP"); P_J; break;
  case OP_LFORLOOP: P_OP("LFORLOOP"); P_J; break;
  case OP_CLOSURE: P_OP("CLOSURE"); P_F; break;
tome-235-src/src/lua/operator.lua0000644000076400017500000000565311012107763014605 0ustar  dgdg-- tolua: operator class
-- Written by Waldemar Celes
-- TeCGraf/PUC-Rio
-- Jul 1998
-- $Id: operator.lua,v 1.2 2001/11/26 23:00:27 darkgod Exp $

-- This code is free software; you can redistribute it and/or modify it.
-- The software provided hereunder is on an "as is" basis, and
-- the author has no obligation to provide maintenance, support, updates,
-- enhancements, or modifications. 


-- Operator class
-- Represents an operator function or a class operator method.
-- It stores the same fields as functions do plus:
--  kind = set of character representing the operator (as it appers in C++ code)
classOperator = {
 kind = '',
 _base = classFunction,
}
settag(classOperator,tolua_tag)

-- table to transform operator kind into the appropriate tag method name
_TM = {['+'] = 'operator_add',
       ['-'] = 'operator_sub',
       ['*'] = 'operator_mul',
       ['/'] = 'operator_div',
       ['<'] = 'operator_lt',
       ['[]'] = 'operator_get',
       ['&[]'] = 'operator_set',
      }
       

-- Print method
function classOperator:print (ident,close)
 print(ident.."Operator{")
 print(ident.." kind  = '"..self.kind.."',")
 print(ident.." mod  = '"..self.mod.."',")
 print(ident.." type = '"..self.type.."',")
 print(ident.." ptr  = '"..self.ptr.."',")
 print(ident.." name = '"..self.name.."',")
 print(ident.." const = '"..self.const.."',")
 print(ident.." cname = '"..self.cname.."',")
 print(ident.." lname = '"..self.lname.."',")
 print(ident.." args = {")
 local i=1
 while self.args[i] do
  self.args[i]:print(ident.."  ",",")
  i = i+1
 end
 print(ident.." }")
 print(ident.."}"..close)
end

-- Internal constructor
function _Operator (t)
 t._base = classOperator
 settag(t,tolua_tag)

 if t.const ~= 'const' and t.const ~= '' then
  error("#invalid 'const' specification")
 end

 append(t)
 if not t:inclass() then
  error("#operator can only be defined as class member")
 end

 t.cname = t:cfuncname("toluaI")..t:overload(t)
 t.name = t.name..t.kind
 return t
end

-- Constructor
-- Expects three strings: one representing the function declaration,
-- another representing the argument list, and the third representing
-- the "const" or empty string.
function Operator (d,k,a,c)
 local t = split(strsub(a,2,strlen(a)-1),',') -- eliminate braces
 local i=1
 local l = {n=0}
 while t[i] do
  l.n = l.n+1
  l[l.n] = Declaration(t[i],'var')
  i = i+1
 end
 if k == '[]' then
  d = gsub(d,'&','')
 elseif k=='&[]' then
  l.n = l.n+1
  l[l.n] = Declaration(d,'var')
  l[l.n].name = 'toluaI_value'
 end
 local f = Declaration(d,'func')
 if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then
  error('operator[] can only be defined for numeric index.')
 end
 f.args = l
 f.const = c
 f.kind = gsub(k,"%s","")
 f.lname = _TM[f.kind]
 if not f.lname then
  error("tolua: no support for operator" .. f.kind)
 end
 if f.kind == '[]' and not strfind(f.mod,'const') then
  Operator(d,'&'..k,a,c) 	-- create correspoding set operator
 end
 return _Operator(f)
end


tome-235-src/src/lua/liolib.c0000644000076400017500000004423511012107763013664 0ustar  dgdg/*
** $Id: liolib.c,v 1.5 2004/06/04 13:42:10 neil Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/


#include 
#include 
#include 
#include 
#include 

#include "lua.h"

#include "lauxlib.h"
#include "luadebug.h"
#include "lualib.h"


#ifndef OLD_ANSI
#include 
#include 
#define realloc(b,s)    ((b) == NULL ? malloc(s) : (realloc)(b, s))
#define free(b)         if (b) (free)(b)
#else
/* no support for locale and for strerror: fake them */
#define setlocale(a,b)	((void)a, strcmp((b),"C")==0?"C":NULL)
#define LC_ALL		0
#define LC_COLLATE	0
#define LC_CTYPE	0
#define LC_MONETARY	0
#define LC_NUMERIC	0
#define LC_TIME		0
#define strerror(e)	"generic I/O error"
#define errno		(-1)
#endif



#ifdef POPEN
/* FILE *popen();
int pclose(); */
#define CLOSEFILE(L, f)    ((pclose(f) == -1) ? fclose(f) : 0)
#else
/* no support for popen */
#define popen(x,y) NULL  /* that is, popen always fails */
#define CLOSEFILE(L, f)    (fclose(f))
#endif


#define INFILE	0
#define OUTFILE 1

typedef struct IOCtrl {
  int ref[2];  /* ref for strings _INPUT/_OUTPUT */
  int iotag;    /* tag for file handles */
  int closedtag;  /* tag for closed handles */
} IOCtrl;



static const char *const filenames[] = {"_INPUT", "_OUTPUT"};


static int pushresult (lua_State *L, int i) {
  if (i) {
    lua_pushuserdata(L, NULL);
    return 1;
  }
  else {
    lua_pushnil(L);
    lua_pushstring(L, strerror(errno));
    lua_pushnumber(L, errno);
    return 3;;
  }
}


/*
** {======================================================
** FILE Operations
** =======================================================
*/


static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) {
  void *p = lua_touserdata(L, f);
  if (p != NULL) {  /* is `f' a userdata ? */
    int ftag = lua_tag(L, f);
    if (ftag == ctrl->iotag)  /* does it have the correct tag? */
      return (FILE *)p;
    else if (ftag == ctrl->closedtag)
      lua_error(L, "cannot access a closed file");
    /* else go through */
  }
  return NULL;
}


static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
  FILE *f = gethandle(L, ctrl, arg);
  luaL_arg_check(L, f, arg, "invalid file handle");
  return f;
}


static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) {
  FILE *f;
  lua_getglobals(L);
  lua_getref(L, ctrl->ref[inout]);
  lua_rawget(L, -2);
  f = gethandle(L, ctrl, -1);
  if (f == NULL)
    luaL_verror(L, "global variable `%.10s' is not a file handle",
                filenames[inout]);
  return f;
}


static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f,
                           const char *name) {
  lua_pushusertag(L, f, ctrl->iotag);
  lua_setglobal(L, name);
}


#define setfile(L,ctrl,f,inout)	(setfilebyname(L,ctrl,f,filenames[inout]))


static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
  if (f == NULL)
    return pushresult(L, 0);
  else {
    setfile(L, ctrl, f, inout);
    lua_pushusertag(L, f, ctrl->iotag);
    return 1;
  }
}


static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
  if (f == stdin || f == stdout || f == stderr)
    return 1;
  else {
    lua_pushusertag(L, f, ctrl->iotag);
    lua_settag(L, ctrl->closedtag);
    return (CLOSEFILE(L, f) == 0);
  }
}


static int io_close (lua_State *L) {
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  lua_pop(L, 1);  /* remove upvalue */
  return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 1)));
}


static int file_collect (lua_State *L) {
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  FILE *f = getnonullfile(L, ctrl, 1);
  if (f != stdin && f != stdout && f != stderr)
    CLOSEFILE(L, f);
  return 0;
}


static int io_open (lua_State *L) {
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  FILE *f;
  lua_pop(L, 1);  /* remove upvalue */
  f = fopen(luaL_check_string(L, 1), luaL_check_string(L, 2));
  if (f) {
    lua_pushusertag(L, f, ctrl->iotag);
    return 1;
  }
  else
    return pushresult(L, 0);
}



static int io_fromto (lua_State *L, int inout, const char *mode) {
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  FILE *current;
  lua_pop(L, 1);  /* remove upvalue */
  if (lua_isnull(L, 1)) {
    closefile(L, ctrl, getfilebyref(L, ctrl, inout));
    current = (inout == 0) ? stdin : stdout;    
  }
  else if (lua_tag(L, 1) == ctrl->iotag)  /* deprecated option */
    current = (FILE *)lua_touserdata(L, 1);
  else {
    const char *s = luaL_check_string(L, 1);
    current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode);
  }
  return setreturn(L, ctrl, current, inout);
}


static int io_readfrom (lua_State *L) {
  return io_fromto(L, INFILE, "r");
}


static int io_writeto (lua_State *L) {
  return io_fromto(L, OUTFILE, "w");
}


static int io_appendto (lua_State *L) {
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  FILE *current;
  lua_pop(L, 1);  /* remove upvalue */
  current = fopen(luaL_check_string(L, 1), "a");
  return setreturn(L, ctrl, current, OUTFILE);
}



/*
** {======================================================
** READ
** =======================================================
*/



#ifdef LUA_COMPAT_READPATTERN

/*
** We cannot lookahead without need, because this can lock stdin.
** This flag signals when we need to read a next char.
*/
#define NEED_OTHER (EOF-1)  /* just some flag different from EOF */


static int read_pattern (lua_State *L, FILE *f, const char *p) {
  int inskip = 0;  /* {skip} level */
  int c = NEED_OTHER;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  while (*p != '\0') {
    switch (*p) {
      case '{':
        inskip++;
        p++;
        continue;
      case '}':
        if (!inskip) lua_error(L, "unbalanced braces in read pattern");
        inskip--;
        p++;
        continue;
      default: {
        const char *ep = luaI_classend(L, p);  /* get what is next */
        int m;  /* match result */
        if (c == NEED_OTHER) c = getc(f);
        m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
        if (m) {
          if (!inskip) luaL_putchar(&b, c);
          c = NEED_OTHER;
        }
        switch (*ep) {
          case '+':  /* repetition (1 or more) */
            if (!m) goto break_while;  /* pattern fails? */
            /* else go through */
          case '*':  /* repetition (0 or more) */
            while (m) {  /* reads the same item until it fails */
              c = getc(f);
              m = (c==EOF) ? 0 : luaI_singlematch(c, p, ep);
              if (m && !inskip) luaL_putchar(&b, c);
            }
            /* go through to continue reading the pattern */
          case '?':  /* optional */
            p = ep+1;  /* continues reading the pattern */
            continue;
          default:
            if (!m) goto break_while;  /* pattern fails? */
            p = ep;  /* else continues reading the pattern */
        }
      }
    }
  } break_while:
  if (c != NEED_OTHER) ungetc(c, f);
  luaL_pushresult(&b);  /* close buffer */
  return (*p == '\0');
}

#else

#define read_pattern(L, f, p) (lua_error(L, "read patterns are deprecated"), 0)

#endif


static int read_number (lua_State *L, FILE *f) {
  long d;
  if (fscanf(f, "%ld", &d) == 1) {
    lua_pushnumber(L, d);
    return 1;
  }
  else return 0;  /* read fails */
}


static int read_word (lua_State *L, FILE *f) {
  int c;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  do { c = fgetc(f); } while (isspace(c));  /* skip spaces */
  while (c != EOF && !isspace(c)) {
    luaL_putchar(&b, c);
    c = fgetc(f);
  }
  ungetc(c, f);
  luaL_pushresult(&b);  /* close buffer */
  return (lua_strlen(L, -1) > 0);
}


static int read_line (lua_State *L, FILE *f) {
  int n = 0;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  for (;;) {
    char *p = luaL_prepbuffer(&b);
    if (!fgets(p, LUAL_BUFFERSIZE, f))  /* read fails? */
      break;
    n = strlen(p);
    if (p[n-1] != '\n')
      luaL_addsize(&b, n); 
    else {
      luaL_addsize(&b, n-1);  /* do not add the `\n' */
      break;
    }
  }
  luaL_pushresult(&b);  /* close buffer */
  return (n > 0);  /* read something? */
}


static void read_file (lua_State *L, FILE *f) {
  size_t len = 0;
  size_t size = BUFSIZ;
  char *buffer = NULL;
  for (;;) {
    char *newbuffer = (char *)realloc(buffer, size);
    if (newbuffer == NULL) {
      free(buffer);
      lua_error(L, "not enough memory to read a file");
    }
    buffer = newbuffer;
    len += fread(buffer+len, sizeof(char), size-len, f);
    if (len < size) break;  /* did not read all it could */
    size *= 2;
  }
  lua_pushlstring(L, buffer, len);
  free(buffer);
}


static int read_chars (lua_State *L, FILE *f, size_t n) {
  char *buffer;
  size_t n1;
  char statbuff[BUFSIZ];
  if (n <= BUFSIZ)
    buffer = statbuff;
  else {
    buffer = (char  *)malloc(n);
    if (buffer == NULL)
      lua_error(L, "not enough memory to read a file");
  }
  n1 = fread(buffer, sizeof(char), n, f);
  lua_pushlstring(L, buffer, n1);
  if (buffer != statbuff) free(buffer);
  return (n1 > 0 || n == 0);
}


static int io_read (lua_State *L) {
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  int lastarg = lua_gettop(L) - 1;
  int firstarg = 1;
  FILE *f = gethandle(L, ctrl, firstarg);
  int n;
  if (f) firstarg++;
  else f = getfilebyref(L, ctrl, INFILE);  /* get _INPUT */
  lua_pop(L, 1);
  if (firstarg > lastarg) {  /* no arguments? */
    lua_settop(L, 0);  /* erase upvalue and other eventual garbage */
    firstarg = lastarg = 1;  /* correct indices */
    lua_pushstring(L, "*l");  /* push default argument */
  }
  else  /* ensure stack space for all results and for auxlib's buffer */
    luaL_checkstack(L, lastarg-firstarg+1+LUA_MINSTACK, "too many arguments");
  for (n = firstarg; n<=lastarg; n++) {
    int success;
    if (lua_isnumber(L, n))
      success = read_chars(L, f, (size_t)lua_tonumber(L, n));
    else {
      const char *p = luaL_check_string(L, n);
      if (p[0] != '*')
        success = read_pattern(L, f, p);  /* deprecated! */
      else {
        switch (p[1]) {
          case 'n':  /* number */
            if (!read_number(L, f)) goto endloop;  /* read fails */
            continue;  /* number is already pushed; avoid the "pushstring" */
          case 'l':  /* line */
            success = read_line(L, f);
            break;
          case 'a':  /* file */
            read_file(L, f);
            success = 1; /* always success */
            break;
          case 'w':  /* word */
            success = read_word(L, f);
            break;
          default:
            luaL_argerror(L, n, "invalid format");
            success = 0;  /* to avoid warnings */
        }
      }
    }
    if (!success) {
      lua_pop(L, 1);  /* remove last result */
      break;  /* read fails */
    }
  } endloop:
  return n - firstarg;
}

/* }====================================================== */


static int io_write (lua_State *L) {
  int lastarg = lua_gettop(L) - 1;
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  int arg = 1;
  int status = 1;
  FILE *f = gethandle(L, ctrl, arg);
  if (f) arg++;
  else f = getfilebyref(L, ctrl, OUTFILE);  /* get _OUTPUT */
  for (; arg <=  lastarg; arg++) {
    if (lua_type(L, arg) == LUA_TNUMBER) {  /* LUA_NUMBER */
      /* optimization: could be done exactly as for strings */
      status = status && fprintf(f, "%ld", lua_tonumber(L, arg)) > 0;
    }
    else {
      size_t l;
      const char *s = luaL_check_lstr(L, arg, &l);
      status = status && (fwrite(s, sizeof(char), l, f) == l);
    }
  }
  pushresult(L, status);
  return 1;
}


static int io_seek (lua_State *L) {
  static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
  static const char *const modenames[] = {"set", "cur", "end", NULL};
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  FILE *f;
  int op;
  long offset;
  lua_pop(L, 1);  /* remove upvalue */
  f = getnonullfile(L, ctrl, 1);
  op = luaL_findstring(luaL_opt_string(L, 2, "cur"), modenames);
  offset = luaL_opt_long(L, 3, 0);
  luaL_arg_check(L, op != -1, 2, "invalid mode");
  op = fseek(f, offset, mode[op]);
  if (op)
    return pushresult(L, 0);  /* error */
  else {
    lua_pushnumber(L, ftell(f));
    return 1;
  }
}


static int io_flush (lua_State *L) {
  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1);
  FILE *f;
  lua_pop(L, 1);  /* remove upvalue */
  f = gethandle(L, ctrl, 1);
  luaL_arg_check(L, f || lua_isnull(L, 1), 1, "invalid file handle");
  return pushresult(L, fflush(f) == 0);
}

/* }====================================================== */


/*
** {======================================================
** Other O.S. Operations
** =======================================================
*/

static int io_execute (lua_State *L) {
  lua_pushnumber(L, system(luaL_check_string(L, 1)));
  return 1;
}


static int io_remove (lua_State *L) {
  return pushresult(L, remove(luaL_check_string(L, 1)) == 0);
}


static int io_rename (lua_State *L) {
  return pushresult(L, rename(luaL_check_string(L, 1),
                    luaL_check_string(L, 2)) == 0);
}


static int io_getenv (lua_State *L) {
  lua_pushstring(L, getenv(luaL_check_string(L, 1)));  /* if NULL push nil */
  return 1;
}


static int io_clock (lua_State *L) {
  lua_pushnumber(L, ((long)clock())/CLOCKS_PER_SEC);
  return 1;
}


static int io_date (lua_State *L) {
  char b[256];
  const char *s = luaL_opt_string(L, 1, "%c");
  struct tm *stm;
  time_t t;
  time(&t); stm = localtime(&t);
  if (strftime(b, sizeof(b), s, stm))
    lua_pushstring(L, b);
  else
    lua_error(L, "invalid `date' format");
  return 1;
}


static int setloc (lua_State *L) {
  static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
                      LC_NUMERIC, LC_TIME};
  static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
     "numeric", "time", NULL};
  int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames);
  luaL_arg_check(L, op != -1, 2, "invalid option");
  lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1)));
  return 1;
}


static int io_exit (lua_State *L) {
  exit(luaL_opt_int(L, 1, EXIT_SUCCESS));
  return 0;  /* to avoid warnings */
}

/* }====================================================== */



static int io_debug (lua_State *L) {
  for (;;) {
    char buffer[250];
    fprintf(stderr, "lua_debug> ");
    if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
        strcmp(buffer, "cont\n") == 0)
      return 0;
    lua_dostring(L, buffer);
    lua_settop(L, 0);  /* remove eventual returns */
  }
}


#define LEVELS1	12	/* size of the first part of the stack */
#define LEVELS2	10	/* size of the second part of the stack */

static int errorfb (lua_State *L) {
  int level = 1;  /* skip level 0 (it's this function) */
  int firstpart = 1;  /* still before eventual `...' */
  lua_Debug ar;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  luaL_addstring(&b, "error: ");
  luaL_addstring(&b, luaL_check_string(L, 1));
  luaL_addstring(&b, "\n");
  while (lua_getstack(L, level++, &ar)) {
    char buff[120];  /* enough to fit following `sprintf's */
    if (level == 2)
      luaL_addstring(&b, "stack traceback:\n");
    else if (level > LEVELS1 && firstpart) {
      /* no more than `LEVELS2' more levels? */
      if (!lua_getstack(L, level+LEVELS2, &ar))
        level--;  /* keep going */
      else {
        luaL_addstring(&b, "       ...\n");  /* too many levels */
        while (lua_getstack(L, level+LEVELS2, &ar))  /* find last levels */
          level++;
      }
      firstpart = 0;
      continue;
    }
    sprintf(buff, "%4d:  ", level-1);
    luaL_addstring(&b, buff);
    lua_getinfo(L, "Snl", &ar);
    switch (*ar.namewhat) {
      case 'g':  case 'l':  /* global, local */
        sprintf(buff, "function `%.50s'", ar.name);
        break;
      case 'f':  /* field */
        sprintf(buff, "method `%.50s'", ar.name);
        break;
      case 't':  /* tag method */
        sprintf(buff, "`%.50s' tag method", ar.name);
        break;
      default: {
        if (*ar.what == 'm')  /* main? */
          sprintf(buff, "main of %.70s", ar.short_src);
        else if (*ar.what == 'C')  /* C function? */
          sprintf(buff, "%.70s", ar.short_src);
        else
          sprintf(buff, "function <%d:%.70s>", ar.linedefined, ar.short_src);
        ar.source = NULL;  /* do not print source again */
      }
    }
    luaL_addstring(&b, buff);
    if (ar.currentline > 0) {
      sprintf(buff, " at line %d", ar.currentline);
      luaL_addstring(&b, buff);
    }
    if (ar.source) {
      sprintf(buff, " [%.70s]", ar.short_src);
      luaL_addstring(&b, buff);
    }
    luaL_addstring(&b, "\n");
  }
  luaL_pushresult(&b);
  lua_getglobal(L, LUA_ALERT);
  if (lua_isfunction(L, -1)) {  /* avoid loop if _ALERT is not defined */
    lua_pushvalue(L, -2);  /* error message */
    lua_rawcall(L, 1, 0);
  }
  return 0;
}



static const struct luaL_reg iolib[] = {
  {LUA_ERRORMESSAGE, errorfb},
  {"clock",     io_clock},
  {"date",     io_date},
  {"debug",    io_debug},
  {"execute",  io_execute},
  {"exit",     io_exit},
  {"getenv",   io_getenv},
  {"remove",   io_remove},
  {"rename",   io_rename},
  {"setlocale", setloc},
};


static const struct luaL_reg iolibtag[] = {
  {"appendto", io_appendto},
  {"closefile",   io_close},
  {"flush",     io_flush},
  {"openfile",   io_open},
  {"read",     io_read},
  {"readfrom", io_readfrom},
  {"seek",     io_seek},
  {"write",    io_write},
  {"writeto",  io_writeto}
};


static void openwithcontrol (lua_State *L) {
  IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl));
  unsigned int i;
  ctrl->iotag = lua_newtag(L);
  ctrl->closedtag = lua_newtag(L);
  for (i=0; iref[INFILE] = lua_ref(L, 1);
  lua_pushstring(L, filenames[OUTFILE]);
  ctrl->ref[OUTFILE] = lua_ref(L, 1);
  /* predefined file handles */
  setfile(L, ctrl, stdin, INFILE);
  setfile(L, ctrl, stdout, OUTFILE);
  setfilebyname(L, ctrl, stdin, "_STDIN");
  setfilebyname(L, ctrl, stdout, "_STDOUT");
  setfilebyname(L, ctrl, stderr, "_STDERR");
  /* close files when collected */
  lua_pushcclosure(L, file_collect, 1);  /* pops `ctrl' from stack */
  lua_settagmethod(L, ctrl->iotag, "gc");
}


LUALIB_API void lua_iolibopen (lua_State *L) {
  luaL_openl(L, iolib);
  openwithcontrol(L);
}

tome-235-src/src/q_invas.c0000644000076400017500000001457711012107763013277 0ustar  dgdg#undef cquest
#define cquest (quest[QUEST_INVASION])

bool quest_invasion_gen_hook(char *fmt)
{
	int x, y;
	int xstart = 2;
	int ystart = 2;

	if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;

	/* Start with perm walls */
	for (y = 0; y < cur_hgt; y++)
	{
		for (x = 0; x < cur_wid; x++)
		{
			cave_set_feat(y, x, FEAT_PERM_SOLID);
		}
	}
	dun_level = quest[p_ptr->inside_quest].level;

	/* Set the correct monster hook */
	set_mon_num_hook();

	/* Prepare allocation table */
	get_mon_num_prep();

	init_flags = INIT_CREATE_DUNGEON;
	process_dungeon_file_full = TRUE;
	process_dungeon_file(NULL, "maeglin.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE);
	process_dungeon_file_full = FALSE;

	for (x = 3; x < xstart; x++)
		for (y = 3; y < ystart; y++)
		{
			if (cave[y][x].feat == FEAT_MARKER)
			{
				cquest.data[0] = y;
				cquest.data[1] = x;
				p_ptr->py = y;
				p_ptr->px = x;
				cave_set_feat(p_ptr->py, p_ptr->px, FEAT_LESS);
			}
		}

	return TRUE;
}
bool quest_invasion_ai_hook(char *fmt)
{
	monster_type *m_ptr;
	s32b m_idx;

	m_idx = get_next_arg(fmt);
	m_ptr = &m_list[m_idx];

	if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;

	/* Ugly but thats better than a call to test_monster_name which is SLOW */
	if (m_ptr->r_idx == 825)
	{
		/* Oups he fleed */
		if ((m_ptr->fy == cquest.data[0]) && (m_ptr->fx == cquest.data[1]))
		{
			delete_monster_idx(m_idx);

			cmsg_print(TERM_YELLOW, "Maeglin found the way to Gondolin! All hope is lost now!");
			cquest.status = QUEST_STATUS_FAILED;
			town_info[2].destroyed = TRUE;
			return (FALSE);
		}

		/* Attack or flee ?*/
		if (distance(m_ptr->fy, m_ptr->fx, p_ptr->py, p_ptr->px) <= 2)
		{
			return (FALSE);
		}
		else
		{
			process_hooks_return[0].num = cquest.data[0];
			process_hooks_return[1].num = cquest.data[1];
			return (TRUE);
		}
	}

	return (FALSE);
}
bool quest_invasion_turn_hook(char *fmt)
{
	bool old_quick_messages = quick_messages;

	if (cquest.status != QUEST_STATUS_UNTAKEN) return (FALSE);
	if (p_ptr->lev < 45) return (FALSE);

	/* Wait until the end of the current quest */
	if (p_ptr->inside_quest) return ( FALSE);

	/* Wait until the end of the astral mode */
	if (p_ptr->astral) return ( FALSE);

	/* Ok give the quest */
	quick_messages = FALSE;
	cmsg_print(TERM_YELLOW, "A Thunderlord appears in front of you and says:");
	cmsg_print(TERM_YELLOW, "'Hello, noble hero. I am Liron, rider of Tolan. Turgon, King of Gondolin sent me.'");
	cmsg_print(TERM_YELLOW, "'Gondolin is being invaded; he needs your help now or everything will be lost.'");
	cmsg_print(TERM_YELLOW, "'I can bring you to Gondolin, but we must go now.'");
	/* This is SO important a question that flush pending inputs */
	flush();

	if (!get_check("Will you come?"))
	{
		cmsg_print(TERM_YELLOW, "'Turgon overestimated you... Now Gondolin will fall.'");
		cmsg_print(TERM_YELLOW, "'I will return alone and die there. May you be doomed!'");

		cquest.status = QUEST_STATUS_FAILED;
		town_info[2].destroyed = TRUE;

		quick_messages = old_quick_messages;

		del_hook(HOOK_END_TURN, quest_invasion_turn_hook);
		process_hooks_restart = TRUE;
		return (FALSE);
	}
	cmsg_print(TERM_YELLOW, "'You made the right decision! Quickly, jump on Tolan!'");
	cmsg_print(TERM_YELLOW, "'Here we are: Gondolin. You must speak with Turgon now.'");

	p_ptr->wild_mode = FALSE;
	p_ptr->wilderness_x = 49;
	p_ptr->wilderness_y = 11;
	p_ptr->town_num = 2;
	p_ptr->oldpx = p_ptr->px = 117;
	p_ptr->oldpy = p_ptr->py = 24;
	dun_level = 0;
	p_ptr->leaving = TRUE;

	cmsg_print(TERM_YELLOW, "'Turgon hails you.'");
	quest_describe(QUEST_INVASION);
	cquest.status = QUEST_STATUS_TAKEN;

	quick_messages = old_quick_messages;

	quest_invasion_init_hook(QUEST_INVASION);
	del_hook(HOOK_END_TURN, quest_invasion_turn_hook);
	process_hooks_restart = TRUE;
	return (FALSE);
}
bool quest_invasion_dump_hook(char *fmt)
{
	if (cquest.status == QUEST_STATUS_FAILED)
	{
		fprintf(hook_file, "\n You abandoned Gondolin when it most needed you, thus causing its destruction.");
	}
	if ((cquest.status == QUEST_STATUS_FINISHED) || (cquest.status == QUEST_STATUS_REWARDED) || (cquest.status == QUEST_STATUS_COMPLETED))
	{
		fprintf(hook_file, "\n You saved Gondolin from destruction.");
	}
	return (FALSE);
}
bool quest_invasion_death_hook(char *fmt)
{
	s32b r_idx, m_idx;

	m_idx = get_next_arg(fmt);
	r_idx = m_list[m_idx].r_idx;

	if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;

	if (r_idx == test_monster_name("Maeglin, the Traitor of Gondolin"))
	{
		cmsg_print(TERM_YELLOW, "You did it! Gondolin will remain hidden.");
		cquest.status = QUEST_STATUS_COMPLETED;
		del_hook(HOOK_MONSTER_DEATH, quest_invasion_death_hook);
		process_hooks_restart = TRUE;
		return (FALSE);
	}

	return FALSE;
}
bool quest_invasion_stair_hook(char *fmt)
{
	cptr down;

	down = get_next_arg_str(fmt);

	if (p_ptr->inside_quest != QUEST_INVASION) return FALSE;

	if (cave[p_ptr->py][p_ptr->px].feat != FEAT_LESS) return TRUE;

	if (!strcmp(down, "up"))
	{
		if (cquest.status == QUEST_STATUS_FAILED)
		{
			cmsg_print(TERM_YELLOW, "The armies of Morgoth totally devastated Gondolin, leaving nothing but ruins...");
		}
		else if (cquest.status == QUEST_STATUS_COMPLETED)
		{
			cmsg_print(TERM_YELLOW, "Turgon appears before you and speaks:");
			cmsg_print(TERM_YELLOW, "'I will never be able to thank you enough.'");
			cmsg_print(TERM_YELLOW, "'My most powerful mages will cast a powerful spell for you, giving you extra life.'");

			p_ptr->hp_mod += 150;
			p_ptr->update |= (PU_HP);
			cquest.status = QUEST_STATUS_FINISHED;
		}
		else
		{
			/* Flush input */
			flush();

			if (!get_check("Really abandon the quest?")) return TRUE;
			cmsg_print(TERM_YELLOW, "You flee away from Maeglin and his army...");
			cquest.status = QUEST_STATUS_FAILED;
			town_info[2].destroyed = TRUE;
		}
		del_hook(HOOK_STAIR, quest_invasion_stair_hook);
		process_hooks_restart = TRUE;
		return (FALSE);
	}

	return TRUE;
}
bool quest_invasion_init_hook(int q_idx)
{
	add_hook(HOOK_END_TURN, quest_invasion_turn_hook, "invasion_turn");
	add_hook(HOOK_CHAR_DUMP, quest_invasion_dump_hook, "invasion_dump");
	if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_MONSTER_AI, quest_invasion_ai_hook, "invasion_ai");
		add_hook(HOOK_GEN_QUEST, quest_invasion_gen_hook, "invasion_gen");
		add_hook(HOOK_MONSTER_DEATH, quest_invasion_death_hook, "invasion_death");
		add_hook(HOOK_STAIR, quest_invasion_stair_hook, "invasion_stair");
	}
	return (FALSE);
}
tome-235-src/src/makefile.sdliso0000644000076400017500000003412111012107763014452 0ustar  dgdg# File: Makefile

# This is not a very "nice" Makefile, but it usually works.

#
# Note that you may have to make modifications below according
# to your machine, available libraries, compilation options,
# and your "visual module" of choice.  This Makefile is intended
# for use with Unix machines running X11, Curses, Ncurses, or Vt100,
# or possibly for "Atari" or "Amiga" computers with "Curses" ports,
# see below for more information.
#
# Note that "main-mac.c" and "main-crb.c", the visual modules for
# the Macintosh, must be compiled in a special way, see elsewhere.
#
# Note that "main-win.c", the visual module for Windows,
# must be compiled in a special way, see elsewhere.
#
# Note that "main-ibm.c" and "main-emx.c", the visual modules
# for various types of IBM-PC computers, must be compiled with
# special Makefiles, see elsewhere.
#
# Note that "main-lsl.c", the visual module for Linux-SVGALIB
# must be compiled with "Makefile.lsl", see elsewhere.
#
# Note that "main-acn.c", the visual module for Risc Acorn,
# must be compiled with "Makefile.acn", see elsewhere.
#
# Note that "Makefile.wat" is a slight variation on "Makefile.ibm",
# which allow the use of "main-ibm.c" with special compiler
# (might be out-of-date).
#
# If you are able to construct "main-xxx.c" and/or "Makefile.xxx"
# files for a currently unsupported system, please send them to me
# (rr9@angband.org) for inclusion in future versions.
#

##
## 1. Installation locations and such
##
## LIBDIR, BINDIR and OWNER should be set appropriately for
## multiuser installations.
##
## If you want to keep it private or don't have root privilege
## required by "make install", set LIBDIR to ./lib/ or an absolute
## path pointing to your lib directory, and don't run "make install".
##
## NOTE: If LIBDIR is set to ./lib/ , you have to cd to parent directory
## of lib before you start the game.
##

# Where lib/ files goes
#LIBDIR = /usr/lib/games/tome/
# Sysadmins of commercial Unix and/or BSD might prefer this
#LIBDIR = /usr/local/lib/tome/
# If you like the old default, use this one
LIBDIR = ./lib/
# Another example: single user installation using absolute path
#LIBDIR = /home/myloginname/lib/tome/


# Where ToME binary goes
BINDIR = /usr/local/games
# Another common location
#BINDIR = /usr/local/bin

# The game will run suid to this user
OWNER = games

# Ignore this if you're not making a package
DESTDIR=

##
## 2. Some "system" definitions
##
## No changes are needed to compile a version that will run on both
## X11 and Curses, in debugging mode, with maximal warnings, on many
## normal Unix machines of the Sun OS variety (non-solaris).
##
## To use an "alternative" definition, simply "modify" (or "replace")
## the definition below with one that you like.  For example, you can
## change the compiler to "cc", or remove the "debugging" options, or
## remove the X11 or Curses support, etc, as desired.
##
## See also "config.h" and "h-config.h" for important information.
##
## Some "examples" are given below, they can be used by simply
## removing the FIRST column of "#" signs from the "block" of lines
## you wish to use, and commenting out "standard" block below.
##
## This is not intended to be a "good" Makefile, just a "simple" one.
##


#
# This is my compiler of choice, it seems to work most everywhere
#
CC = gcc

# Profiling options
# PROFILECOPTS = -pg
# PROFILELDFLAGS = -pg

#
# Standard version (see main-x11.c and main-gcu.c)
#
# This version supports both "X11" and "curses" in a single executable.
#
# You may have to add various X11 include/library directories to the
# "INCLUDES", if your machine places files in a weird location
# (e.g. -I/usr/X11R6/include, as is almost always the case with
# linux and *BSD). Since we have seen many linux users -- arguably
# the largest unix population -- confused by this, and adding this
# usually doesn't hurt, the default rule has been changed to search
# for /usr/X11R6/include.
#
# You may be able to remove "-ltermcap" on some machines (ex: Solaris).
#
# You may have to replace "-lcurses" with "-lncurses" to use the
# "new curses" library instead of the "old curses" library, and
# you may have to add "-I/usr/include/ncurses" to the "INCLUDES",
# and/or "-DUSE_NCURSES" to "DEFINES".
#
# See "main-gcu.c" and "config.h" for some optional "curses" defines,
# including "USE_GETCH" and "USE_CURS_SET".  Note that "config.h" will
# attempt to "guess" at many of these flags based on your system.
#
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 \
#	-DUSE_EGO_GRAPHICS -DUSE_TRANSPARENCY -DSUPPORT_GAMMA \
#	-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK
#LIBS = -lX11 -L/usr/X11R6/lib

##
## Variation -- Only support "main-gtk.c" (not "main-gcu.c, main-x11.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = `gtk-config --cflags`
#DEFINES = -DUSE_GTK -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = `gtk-config --libs`

#
# Variation -- Only support "main-x11.c" (not "main-gcu.c")
#
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -L/usr/X11R6/lib


##
## Variation -- Only support "main-gcu.c" (not "main-x11.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap


##
## Variation -- Use "main-xaw.c" instead of "main-x11.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_XAW -DUSE_GCU \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lXaw -lXmu -lXt -lX11 -lcurses -ltermcap -L/usr/X11R6/lib

##
## Variation -- Use "main-sdl.c" instead of "main-x11.c"
##
SDL_CONFIG ?= sdl-config
COPTS = -Wall -O1 -pipe -g
INCLUDES = `$(SDL_CONFIG) --cflags`
DEFINES = -DUSE_SDL -DUSE_GCU \
	-DUSE_EGO_GRAPHICS -DUSE_TRANSPARENCY \
	-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK -DSUPPORT_GAMMA \
	-DUSE_ISO
LIBS = `$(SDL_CONFIG) --libs` -lSDL_image -lSDL_ttf -lcurses

##
## Variation -- Use "main-cap.c" instead of "main-gcu.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_CAP \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -ltermcap


##
## Variation -- Only work on simple vt100 terminals
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_CAP -DUSE_HARDCODE


##
## Variation -- this might work for Linux 1.1.93 using ncurses-1.8.7.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lncurses -L/usr/X11R6/lib


##
## Variation -- this might work better than the suggestion above
##
#COPTS = -Wall -O2 -fomit-frame-pointer
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_TPOSIX -DUSE_CURS_SET \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lncurses -L/usr/X11R6/lib
#LDFLAGS = -s


##
## Variation -- compile for FreeBSD with ncurses
## -- BSD curses gives you B&W display.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_NCURSES \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lncurses -L/usr/X11R6/lib


##
## Variation -- compile for Solaris
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSOLARIS \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lsocket -lcurses


##
## Variation -- compile for SGI Indigo runnig Irix
## The SGI has hardware gamma correction.
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSGI \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS
#LIBS = -lX11 -lcurses -ltermcap -lsun



##
## Variation -- compile for Dec ALPHA OSF/1 v2.0
##
#CC     = cc
##COPTS = -std -O -g3 -Olimit 4000
#COPTS = -std -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS   = -lX11 -lcurses -ltermcap -lrpcsvc


##
## Variation -- compile for Interactive Unix (ISC) systems
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DISC \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lcurses -lnsl_s -linet -lcposix


##
## Variation -- Support fat binaries under NEXTSTEP
##
#COPTS = -Wall -O1 -pipe -g -arch m68k -arch i386
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap


### End of configurable section ###

#
# The "source" and "object" files.
#

BASESRCS = \
  main-gtk.c main-gcu.c main-x11.c main-xaw.c main-dmy.c \
  z-rand.c z-util.c z-form.c z-virt.c z-term.c z-sock.c \
  variable.c tables.c plots.c util.c cave.c dungeon.c \
  melee1.c melee2.c modules.c \
  object1.c object2.c randart.c squeltch.c traps.c \
  monster1.c monster2.c monster3.c ghost.c \
  xtra1.c xtra2.c skills.c powers.c gods.c \
  spells1.c spells2.c \
  status.c files.c notes.c loadsave.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c \
  help.c \
  generate.c gen_maze.c gen_evol.c wild.c levels.c store.c bldg.c \
  cmovie.c irc.c \
  wizard2.c init2.c birth.c wizard1.c init1.c \
  iso/simgraph.c iso/simview.c iso/world_adaptor.c iso/world_view.c \
  main-sdl-iso.c maim-iso.c


BASEOBJS = \
  main-gtk.o main-gcu.o main-x11.o main-xaw.o main-dmy.o \
  z-rand.o z-util.o z-form.o z-virt.o z-term.o z-sock.o \
  variable.o tables.o plots.o util.o cave.o dungeon.o \
  melee1.o melee2.o modules.o \
  object1.o object2.o randart.o squeltch.o traps.o \
  monster1.o monster2.o monster3.o ghost.o \
  xtra1.o xtra2.o skills.o powers.o gods.o \
  spells1.o spells2.o \
  status.o files.o notes.o loadsave.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  help.o \
  generate.o gen_maze.o gen_evol.o wild.o levels.o store.o bldg.o \
  cmovie.o irc.o \
  wizard2.o init2.o birth.o wizard1.o init1.o \
  iso/simgraph.o iso/simview.o iso/world_adaptor.o iso/world_view.o \
  main-sdl-iso.o maim-iso.o


LUASRCS = \
  script.c lua_bind.c \
  w_util.c w_player.c w_z_pack.c w_obj.c w_mnster.c w_spells.c w_quest.c w_play_c.c w_dun.c

TOLUASRCS = \
  lua/lapi.c lua/lcode.c lua/ldebug.c lua/ldo.c lua/lfunc.c lua/lgc.c \
  lua/llex.c lua/lmem.c lua/lobject.c lua/lparser.c lua/lstate.c lua/lstring.c \
  lua/ltable.c lua/ltests.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c \
  lua/lauxlib.c lua/lbaselib.c lua/ldblib.c lua/liolib.c lua/lstrlib.c \
  lua/tolua_lb.c lua/tolua_rg.c lua/tolua_tt.c lua/tolua_tm.c lua/tolua_gp.c \
  lua/tolua_eh.c lua/tolua_bd.c

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

#
# Base sources and objects
#

SRCS = $(BASESRCS)
OBJS = $(BASEOBJS)


#
# Compiler options
#

CFLAGS = $(COPTS) $(PROFILECOPTS) $(INCLUDES) $(DEFINES) -DDEFAULT_PATH=\"$(LIBDIR)\"


#
# Lua support
#

INCLUDES += -Ilua -I.
DEFINES += -DUSE_LUA
SRCS = $(LUASRCS) $(TOLUASRCS) $(BASESRCS)
OBJS = $(LUAOBJS) $(TOLUAOBJS) $(BASEOBJS)

# Force recreation of stub files when lua source files are updated
# To be included in dependency rules
TOLUADEP = $(TOLUASRCS) lua/tolua.c lua/tolualua.c

#
# IRC support
#

IRC_SERVER=irc.worldirc.org
IRC_PORT=6667
IRC_CHANNEL=\#tome

DEFINES += \
	-DIRC_SERVER=\"$(IRC_SERVER)\" \
	-DIRC_PORT=\"$(IRC_PORT)\" \
	-DIRC_CHANNEL=\"$(IRC_CHANNEL)\"

# Build the binary. The new base target.
#

TARGET = tome

TOLUA = ./tolua

default: $(TOLUA) $(TARGET)
	@echo "*** Note: In order to use the install rule, which now actually"
	@echo "*** handles the installation of the library dir, you need to edit"
	@echo "*** this makefile, going to the top and making sure LIBDIR suits"
	@echo "*** your desired install dir properly. The LIBRARY_DIR you used"
	@echo "*** to set in config.h is now ignored and obsolete with respect"
	@echo "*** to this makefile. Note that if you edit this makefile, you may"
	@echo "*** need to recompile so all the files that reference those defines"
	@echo "*** notice the changes."

$(TARGET): $(OBJS)
	$(CC) $(PROFILELDFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(PROFILELDFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)

#
# An install rule.
#
mini_install: default
	cp -f $(TARGET) ..

install: default
	[ -d $(DESTDIR)$(LIBDIR) ] || mkdir -p $(DESTDIR)$(LIBDIR)
	[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
	cp -r ../lib/* $(DESTDIR)$(LIBDIR)
	chown -R $(OWNER) $(DESTDIR)$(LIBDIR)
	cp -f $(TARGET) $(DESTDIR)$(BINDIR)/$(TARGET)
	chown $(OWNER) $(DESTDIR)$(BINDIR)/$(TARGET)
	chmod 4755 $(DESTDIR)$(BINDIR)/$(TARGET)

# old-install: $(TARGET)
#	cp $(TARGET) ..


#
# Clean up old junk
#

clean:
	rm -f *.bak *.o lua/*.o


#
# Generate dependancies automatically
#

depend:
	makedepend $(INCLUDES) $(DEFINES) -D__MAKEDEPEND__ $(SRCS)

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c


#
# Quests
#
plots.o: q_rand.c q_main.c q_one.c q_ultrag.c q_ultrae.c \
	q_thief.c q_hobbit.c q_nazgul.c q_troll.c q_wight.c \
	q_spider.c q_poison.c \
	q_eol.c q_nirna.c q_invas.c \
	q_betwen.c \
	q_narsil.c q_shroom.c q_thrain.c q_wolves.c q_dragons.c q_haunted.c q_evil.c

#
# Lua library compilation rules
#

w_mnster.c: monster.pkg $(TOLUADEP)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUADEP)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUADEP)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUADEP)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUADEP)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUADEP)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUADEP)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUADEP)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

# DO NOT DELETE THIS LINE - make depend depends on it.
tome-235-src/src/dungeon.pkg0000644000076400017500000010072311012107763013622 0ustar  dgdg/* File: dungeon.pkg */

/*
 * Purpose: Lua interface defitions for dungeon routines.
 * To be processed by tolua to generate C source code.
 */

$#include "angband.h"

/** @typedef cptr
 * @note String
 */
typedef char* cptr;

/** @typedef errr
 * @note Number
 */
typedef int errr;

/** @typedef bool
 * @note Boolean
 */
typedef unsigned char bool;

/** @typedef byte
 * @note Number
 */
typedef unsigned char byte;

/** @typedef s16b
 * @note Number
 */
typedef signed short s16b;

/** @typedef u16b
 * @note Number
 */
typedef unsigned short u16b;

/** @typedef s32b
 * @note Number
 */
typedef signed int s32b;

/** @typedef u32b
 * @note Number
 */
typedef unsigned int u32b;

/** @name Cave Grid
 * @note Special cave grid flags
 * @{
 */

/** @def CAVE_MARK
 * @note memorized feature 
 */
#define CAVE_MARK       0x0001    

/** @def CAVE_GLOW
 * @note self-illuminating 
 */
#define CAVE_GLOW       0x0002    

/** @def CAVE_ICKY
 * @note part of a vault 
 */
#define CAVE_ICKY       0x0004    

/** @def CAVE_ROOM
 * @note part of a room 
 */
#define CAVE_ROOM       0x0008    

/** @def CAVE_SEEN
 * @note seen flag  
 */
#define CAVE_SEEN       0x0010    

/** @def CAVE_VIEW
 * @note view flag 
 */
#define CAVE_VIEW       0x0020    

/** @def CAVE_TEMP
 * @note temp flag 
 */
#define CAVE_TEMP       0x0040    

/** @def CAVE_WALL
 * @note wall flag 
 */
#define CAVE_WALL       0x0080    

/** @def CAVE_TRDT
 * @note trap detected 
 */
#define CAVE_TRDT       0x0100    

/** @def CAVE_IDNT
 * @note grid identified (fountains) 
 */
#define CAVE_IDNT       0x0200    

/** @def CAVE_SPEC
 * @note special mark(quests) 
 */
#define CAVE_SPEC       0x0400    

/** @def CAVE_FREE
 * @note no random generation on it 
 */
#define CAVE_FREE       0x0800    

/** @def CAVE_DETECT
 * @note Traps detected here 
 */
#define CAVE_DETECT     0x1000    

/** @def CAVE_PLIT
 * @note Player lit grid 
 */
#define CAVE_PLIT       0x2000    

/** @def CAVE_MLIT
 * @note Monster lit grid 
 */
#define CAVE_MLIT       0x4000    
/** @} */

/** @name Terrain Feature Indexes
 * @note (see "lib/edit/f_info.txt")
 * @{
 */

/* Nothing */
/** @def FEAT_NONE */
#define FEAT_NONE               0x00


/* Basic features */
/** @def FEAT_FLOOR */
#define FEAT_FLOOR              0x01

/** @def FEAT_FOUNTAIN */
#define FEAT_FOUNTAIN           0x02

/** @def FEAT_GLYPH */
#define FEAT_GLYPH              0x03

/** @def FEAT_OPEN */
#define FEAT_OPEN               0x04

/** @def FEAT_BROKEN */
#define FEAT_BROKEN             0x05

/** @def FEAT_LESS */
#define FEAT_LESS               0x06

/** @def FEAT_MORE */
#define FEAT_MORE               0x07


/* Quest features -KMW- */
/** @def FEAT_QUEST_ENTER */
#define FEAT_QUEST_ENTER        0x08

/** @def FEAT_QUEST_EXIT */
#define FEAT_QUEST_EXIT         0x09

/** @def FEAT_QUEST_DOWN */
#define FEAT_QUEST_DOWN         0x0A

/** @def FEAT_QUEST_UP */
#define FEAT_QUEST_UP           0x0B


/* Shafts -GSN- */
/** @def FEAT_SHAFT_DOWN */
#define FEAT_SHAFT_DOWN         0x0D

/** @def FEAT_SHAFT_UP */
#define FEAT_SHAFT_UP           0x0E


/* Basic feature */
/** @def FEAT_EMPTY_FOUNTAIN */
#define FEAT_EMPTY_FOUNTAIN     0x0F


/* Feature 0x10 -- web */

/* Traps */
/** @def FEAT_TRAP */
#define FEAT_TRAP               0x11


/* Features 0x12 - 0x1F -- unused */

/* Doors */
/** @def FEAT_DOOR_HEAD */
#define FEAT_DOOR_HEAD          0x20

/** @def FEAT_DOOR_TAIL */
#define FEAT_DOOR_TAIL          0x2F


/* Extra */
/** @def FEAT_SECRET */
#define FEAT_SECRET             0x30

/** @def FEAT_RUBBLE */
#define FEAT_RUBBLE             0x31


/* Seams */
/** @def FEAT_MAGMA */
#define FEAT_MAGMA              0x32

/** @def FEAT_QUARTZ */
#define FEAT_QUARTZ             0x33

/** @def FEAT_MAGMA_H */
#define FEAT_MAGMA_H            0x34

/** @def FEAT_QUARTZ_H */
#define FEAT_QUARTZ_H           0x35

/** @def FEAT_MAGMA_K */
#define FEAT_MAGMA_K            0x36

/** @def FEAT_QUARTZ_K */
#define FEAT_QUARTZ_K           0x37


/* Walls */
/** @def FEAT_WALL_EXTRA */
#define FEAT_WALL_EXTRA         0x38

/** @def FEAT_WALL_INNER */
#define FEAT_WALL_INNER         0x39

/** @def FEAT_WALL_OUTER */
#define FEAT_WALL_OUTER         0x3A

/** @def FEAT_WALL_SOLID */
#define FEAT_WALL_SOLID         0x3B

/** @def FEAT_PERM_EXTRA */
#define FEAT_PERM_EXTRA         0x3C

/** @def FEAT_PERM_INNER */
#define FEAT_PERM_INNER         0x3D

/** @def FEAT_PERM_OUTER */
#define FEAT_PERM_OUTER         0x3E

/** @def FEAT_PERM_SOLID */
#define FEAT_PERM_SOLID         0x3F


/* Explosive rune */
/** @def FEAT_MINOR_GLYPH */
#define FEAT_MINOR_GLYPH        0x40


/* Pattern */
/** @def FEAT_PATTERN_START */
#define FEAT_PATTERN_START      0x41

/** @def FEAT_PATTERN_1 */
#define FEAT_PATTERN_1          0x42

/** @def FEAT_PATTERN_2 */
#define FEAT_PATTERN_2          0x43

/** @def FEAT_PATTERN_3 */
#define FEAT_PATTERN_3          0x44

/** @def FEAT_PATTERN_4 */
#define FEAT_PATTERN_4          0x45

/** @def FEAT_PATTERN_END */
#define FEAT_PATTERN_END        0x46

/** @def FEAT_PATTERN_OLD */
#define FEAT_PATTERN_OLD        0x47

/** @def FEAT_PATTERN_XTRA1 */
#define FEAT_PATTERN_XTRA1      0x48

/** @def FEAT_PATTERN_XTRA2 */
#define FEAT_PATTERN_XTRA2      0x49


/* Shops */
/** @def FEAT_SHOP */
#define FEAT_SHOP               0x4A


/* Permanent walls for quests */
/** @def FEAT_QUEST1 */
#define FEAT_QUEST1             0x4B

/** @def FEAT_QUEST2 */
#define FEAT_QUEST2             0x4C

/** @def FEAT_QUEST3 */
#define FEAT_QUEST3             0x4D

/** @def FEAT_QUEST4 */
#define FEAT_QUEST4             0x4E


/* Features 0x4F - 0x53 -- unused */

/* Additional terrains */
/** @def FEAT_SHAL_WATER */
#define FEAT_SHAL_WATER         0x54

/** @def FEAT_DEEP_LAVA */
#define FEAT_DEEP_LAVA          0x55

/** @def FEAT_SHAL_LAVA */
#define FEAT_SHAL_LAVA          0x56

/** @def FEAT_DARK_PIT */
#define FEAT_DARK_PIT           0x57

/** @def FEAT_DIRT */
#define FEAT_DIRT               0x58

/** @def FEAT_GRASS */
#define FEAT_GRASS              0x59

/** @def FEAT_ICE */
#define FEAT_ICE                0x5A

/** @def FEAT_SAND */
#define FEAT_SAND               0x5B

/** @def FEAT_DEAD_TREE */
#define FEAT_DEAD_TREE          0x5C

/** @def FEAT_ASH */
#define FEAT_ASH                0x5D

/** @def FEAT_MUD */
#define FEAT_MUD                0x5E

/** @def FEAT_ICE_WALL */
#define FEAT_ICE_WALL           0x5F

/** @def FEAT_TREES */
#define FEAT_TREES              0x60

/** @def FEAT_MOUNTAIN */
#define FEAT_MOUNTAIN           0x61

/** @def FEAT_SANDWALL */
#define FEAT_SANDWALL           0x62

/** @def FEAT_SANDWALL_H */
#define FEAT_SANDWALL_H         0x63

/** @def FEAT_SANDWALL_K */
#define FEAT_SANDWALL_K         0x64

/* Feature 0x65 -- high mountain chain */
/* Feature 0x66 -- nether mist */

/* Features 0x67 - 0x9F -- unused */

/** @def FEAT_BETWEEN
 * @note 160 
 */
#define FEAT_BETWEEN            0xA0 

/* Altars */
/** @def FEAT_ALTAR_HEAD
 * @note 161 
 */
#define FEAT_ALTAR_HEAD         0xA1 

/** @def FEAT_ALTAR_TAIL
 * @note 171 
 */
#define FEAT_ALTAR_TAIL         0xAB 

/** @def FEAT_MARKER
 * @note 172 
 */
#define FEAT_MARKER             0xAC 

/* Feature 0xAD -- Underground Tunnel */
/** @def FEAT_TAINTED_WATER
 * @note 174 
 */
#define FEAT_TAINTED_WATER      0xAE 

/** @def FEAT_MON_TRAP
 * @note 175 
 */
#define FEAT_MON_TRAP           0xAF 

/** @def FEAT_BETWEEN2
 * @note 176 
 */
#define FEAT_BETWEEN2           0xB0 

/** @def FEAT_LAVA_WALL
 * @note 177 
 */
#define FEAT_LAVA_WALL          0xB1

/** @def FEAT_GREAT_FIRE
 * @note 178 
 */
#define FEAT_GREAT_FIRE         0xB2 

/** @def FEAT_WAY_MORE
 * @note 179 
 */
#define FEAT_WAY_MORE           0xB3 

/** @def FEAT_WAY_LESS
 * @note 180 
 */
#define FEAT_WAY_LESS           0xB4 

/* Feature 0xB5 -- field */

/** @def FEAT_EKKAIA
 * @note 182 
 */
#define FEAT_EKKAIA             0xB6 

/* Features 0xB7 - 0xBA -- unused */

/** @def FEAT_DEEP_WATER
 * @note 187 
 */
#define FEAT_DEEP_WATER         0xBB 

/** @def FEAT_GLASS_WALL
 * @note 188 
 */
#define FEAT_GLASS_WALL         0xBC 

/** @def FEAT_ILLUS_WALL
 * @note 189 
 */
#define FEAT_ILLUS_WALL         0xBD 

/* Feature 0xBE -- grass roof */
/* Feature 0xBF -- grass roof top */
/* Feature 0xC0 -- grass roof chimney */
/* Feature 0xC1 -- brick roof */
/* Feature 0xC2 -- brick roof top */
/* Feature 0xC3 -- brick roof chimney */
/* Feature 0xC4 -- window */
/* Feature 0xC5 -- small window */
/* Feature 0xC6 -- rain barrel */

/** @def FEAT_FLOWER
 * @note 199 
 */
#define FEAT_FLOWER             0xC7 

/* Feature 0xC8 -- cobblestone road */
/* Feature 0xC9 -- cobblestone with outlet */

/** @def FEAT_SMALL_TREES
 * @note 202 
 */
#define FEAT_SMALL_TREES        0xCA 

/** @def FEAT_TOWN
 * @note 203 
 */
#define FEAT_TOWN               0xCB 

/* Feature 0xCC -- Underground Tunnel */

/** @def FEAT_FIRE
 * @note 205 
 */
#define FEAT_FIRE               0xCD 

/* Feature 0xCE -- pile of rubble (permanent) */
/* Features 0xCF - 0xFF -- unused */
/** @} */

/** @name Dungeon Type Flags (part 1)
 * @{ */

/** @def DF1_PRINCIPAL
 * @note Is a principal dungeon 
 */
#define DF1_PRINCIPAL           0x00000001L	
/** @def DF1_MAZE
 * @note Is a maze-type dungeon 
 */
#define DF1_MAZE                0x00000002L	
/** @def DF1_SMALLEST
 * @note Creates VERY small levels like The Maze 
 */
#define DF1_SMALLEST            0x00000004L	
/** @def DF1_SMALL
 * @note Creates small levels like Dol Goldor 
 */
#define DF1_SMALL               0x00000008L	
/** @def DF1_BIG
 * @note Creates big levels like Moria, and Angband dungeons 
 */
#define DF1_BIG                 0x00000010L	
/** @def DF1_NO_DOORS
 * @note No doors on rooms, like Barrowdowns, Old Forest etc) 
 */
#define DF1_NO_DOORS            0x00000020L	
/** @def DF1_WATER_RIVER
 * @note Allow a single water streamer on a level 
 */
#define DF1_WATER_RIVER         0x00000040L	
/** @def DF1_LAVA_RIVER
 * @note Allow a single lava streamer on a level 
 */
#define DF1_LAVA_RIVER          0x00000080L	
/** @def DF1_WATER_RIVERS
 * @note Allow multiple water streamers on a level 
 */
#define DF1_WATER_RIVERS        0x00000100L	
/** @def DF1_LAVA_RIVERS
 * @note Allow multiple lava streamers on a level 
 */
#define DF1_LAVA_RIVERS         0x00000200L	
/** @def DF1_CAVE
 * @note Allow orc-cave like 'fractal' rooms 
 */
#define DF1_CAVE                0x00000400L	
/** @def DF1_CAVERN
 * @note Allow cavern rooms 
 */
#define DF1_CAVERN              0x00000800L	
/** @def DF1_NO_UP
 * @note Disallow up stairs 
 */
#define DF1_NO_UP               0x00001000L	
/** @def DF1_HOT
 * @note Corpses on ground and in pack decay quicker through heat 
 */
#define DF1_HOT                 0x00002000L	
/** @def DF1_COLD
 * @note Corpses on ground and in pack decay quicker through cold 
 */
#define DF1_COLD                0x00004000L	
/** @def DF1_FORCE_DOWN
 * @note No up stairs generated 
 */
#define DF1_FORCE_DOWN          0x00008000L	
/** @def DF1_FORGET
 * @note Features are forgotten, like the Maze and Illusory Castle 
 */
#define DF1_FORGET              0x00010000L	
/** @def DF1_NO_DESTROY
 * @note No destroyed levels in dungeon 
 */
#define DF1_NO_DESTROY          0x00020000L	
/** @def DF1_SAND_VEIN
 * @note Like in the sandworm lair 
 */
#define DF1_SAND_VEIN           0x00040000L	
/** @def DF1_CIRCULAR_ROOMS
 * @note Allow circular rooms 
 */
#define DF1_CIRCULAR_ROOMS      0x00080000L	
/** @def DF1_EMPTY
 * @note Allow arena levels 
 */
#define DF1_EMPTY               0x00100000L	
/** @def DF1_DAMAGE_FEAT
 * @note Effect specified in will affect all grids incl. terrain and monsters 
 */
#define DF1_DAMAGE_FEAT         0x00200000L	
/** @def DF1_FLAT
 * @note Creates paths to next areas at edge of level, like Barrowdowns 
 */
#define DF1_FLAT                0x00400000L	
/** @def DF1_TOWER
 * @note You start at bottom and go up rather than the reverse 
 */
#define DF1_TOWER               0x00800000L	
/** @def DF1_RANDOM_TOWNS
 * @note Allow random towns 
 */
#define DF1_RANDOM_TOWNS        0x01000000L	
/** @def DF1_DOUBLE
 * @note Generates everything at double size like Helcaraxe and Erebor 
 */
#define DF1_DOUBLE              0x02000000L	
/** @def DF1_LIFE_LEVEL
 * @note Creates dungeon level on modified 'game of life' algorithm 
 */
#define DF1_LIFE_LEVEL          0x04000000L	
/** @def DF1_EVOLVE
 * @note Evolving, pulsing levels like Heart of the Earth 
 */
#define DF1_EVOLVE              0x08000000L	
/** @def DF1_ADJUST_LEVEL_1
 * @note Minimum monster level will be equal to dungeon level 
 */
#define DF1_ADJUST_LEVEL_1      0x10000000L	
/** @def DF1_ADJUST_LEVEL_2
 * @note Minimum monster level will be double the dungeon level 
 */
#define DF1_ADJUST_LEVEL_2      0x20000000L	
/** @def DF1_NO_RECALL
 * @note No recall allowed 
 */
#define DF1_NO_RECALL           0x40000000L	
/** @def DF1_NO_STREAMERS
 * @note No streamers 
 */
#define DF1_NO_STREAMERS        0x80000000L	
/** @} */

/** @name Dungeon Type Flags (part 2)
 * @{ */

/** @def DF2_ADJUST_LEVEL_1_2
 * @note Minimum monster level will be half the dungeon level 
 */
#define DF2_ADJUST_LEVEL_1_2    0x00000001L	

/** @def DF2_NO_SHAFT
 * @note No shafts 
 */
#define DF2_NO_SHAFT            0x00000002L	

/** @def DF2_ADJUST_LEVEL_PLAYER
 * @note Uses player level*2 instead of dungeon level for other ADJUST_LEVEL flags 
 */
#define DF2_ADJUST_LEVEL_PLAYER 0x00000004L	

/** @def DF2_NO_TELEPORT */
#define DF2_NO_TELEPORT         0x00000008L

/** @def DF2_ASK_LEAVE */
#define DF2_ASK_LEAVE           0x00000010L

/** @def DF2_NO_STAIR */
#define DF2_NO_STAIR            0x00000020L

/** @def DF2_SPECIAL */
#define DF2_SPECIAL             0x00000040L

/** @def DF2_NO_NEW_MONSTER */
#define DF2_NO_NEW_MONSTER      0x00000080L

/** @def DF2_DESC */
#define DF2_DESC                0x00000100L

/** @def DF2_NO_GENO */
#define DF2_NO_GENO             0x00000200L

/** @def DF2_NO_BREATH
 * @note Oups, cannot breath here 
 */
#define DF2_NO_BREATH           0x00000400L     

/** @def DF2_WATER_BREATH
 * @note Oups, cannot breath here, need water breathing 
 */
#define DF2_WATER_BREATH        0x00000800L     

/** @def DF2_ELVEN
 * @note Try to create elven monster ego 
 */
#define DF2_ELVEN               0x00001000L     

/** @def DF2_DWARVEN
 * @note Try to create dwarven monster ego 
 */
#define DF2_DWARVEN             0x00002000L     

/** @def DF2_NO_EASY_MOVE
 * @note Forbid stuff like teleport level, probability travel, ... 
 */
#define DF2_NO_EASY_MOVE        0x00004000L     

/** @def DF2_NO_RECALL_OUT
 * @note Cannot recall out of the place 
 */
#define DF2_NO_RECALL_OUT       0x00008000L     

/** @def DF2_DESC_ALWAYS
 * @note Always shows the desc 
 */
#define DF2_DESC_ALWAYS         0x00010000L     
/** @} */

/** @var level_flags1;
 * @brief Number
 */
extern u32b dungeon_flags1@level_flags1;

/** @var level_flags2;
 * @brief Number
 */
extern u32b dungeon_flags2@level_flags2;

/** @def MAX_HGT
 * @note Maximum dungeon height in grids, must be a multiple of SCREEN_HGT,
 * probably hard-coded to SCREEN_HGT * 3.
 */
#define MAX_HGT         66


/** @def MAX_WID
 * @note Maximum dungeon width in grids, must be a multiple of SCREEN_WID,
 * probably hard-coded to SCREEN_WID * 3.
 */
#define MAX_WID         198


/** @name Town Defines
 * @{ */

/** @def TOWN_RANDOM
 * @note First random town 
 */
#define TOWN_RANDOM     20              

/** @def TOWN_DUNGEON
 * @note Maximun number of towns per dungeon 
 */
#define TOWN_DUNGEON    4               

/** @def TOWN_CHANCE
 * @note Chance of 1 town 
 */
#define TOWN_CHANCE     50              

/** @} */

/** @name Wilderness Terrains
 * @{
 */

/** @def TERRAIN_EDGE
 * @note Edge of the World 
 */
#define TERRAIN_EDGE             0 

/** @def TERRAIN_TOWN
 * @note Town 
 */
#define TERRAIN_TOWN             1 

/** @def TERRAIN_DEEP_WATER
 * @note Deep water 
 */
#define TERRAIN_DEEP_WATER       2 

/** @def TERRAIN_SHALLOW_WATER
 * @note Shallow water 
 */
#define TERRAIN_SHALLOW_WATER    3 

/** @def TERRAIN_SWAMP
 * @note Swamp 
 */
#define TERRAIN_SWAMP            4 

/** @def TERRAIN_DIRT
 * @note Dirt 
 */
#define TERRAIN_DIRT             5 

/** @def TERRAIN_GRASS
 * @note Grass 
 */
#define TERRAIN_GRASS            6 

/** @def TERRAIN_TREES
 * @note Trees 
 */
#define TERRAIN_TREES            7 

/** @def TERRAIN_DESERT
 * @note Desert 
 */
#define TERRAIN_DESERT           8 

/** @def TERRAIN_SHALLOW_LAVA
 * @note Shallow lava 
 */
#define TERRAIN_SHALLOW_LAVA     9 

/** @def TERRAIN_DEEP_LAVA
 * @note Deep lava 
 */
#define TERRAIN_DEEP_LAVA       10 

/** @def TERRAIN_MOUNTAIN
 * @note Mountain 
 */
#define TERRAIN_MOUNTAIN        11 

/** @def MAX_WILD_TERRAIN */
#define MAX_WILD_TERRAIN        18
/** @} */

/** @struct border_type
 * @note Border
 */
struct border_type 
{
	/** @structvar north[MAX_WID]
	 * @brief Number
	 */
	byte 	north[MAX_WID];

	/** @structvar south[MAX_WID]
	 * @brief Number
	 */
	byte 	south[MAX_WID];

	/** @structvar east[MAX_HGT]
	 * @brief Number
	 */
	byte 	east[MAX_HGT];

	/** @structvar west[MAX_HGT]
	 * @brief Number
	 */
	byte 	west[MAX_HGT];

	/** @structvar north_west
	 * @brief Number
	 */
	byte	north_west;

	/** @structvar north_east
	 * @brief Number
	 */
	byte	north_east;

	/** @structvar south_west
	 * @brief Number
	 */
	byte	south_west;

	/** @structvar south_east
	 * @brief Number
	 */
	byte	south_east;
};


/** @struct wilderness_type_info
 * @note A structure describing a wilderness area
 * with a terrain, a town or a dungeon entrance
 */
struct wilderness_type_info
{
	/** @structvar name
	 * @brief Number
	 * @note Name (offset) 
	 */
	u32b    name;

	/** @structvar text
	 * @brief Number
	 * @note Text (offset) 
	 */
	u32b    text;

	/** @structvar entrance
	 * @brief Number
	 * @note Which town is there(<1000 i's a town, >=1000 it a dungeon) 
	 */
	u16b    entrance;

	/** @structvar road
	 * @brief Number
	 * @note Flags of road 
	 */
	byte    road;

	/** @structvar level
	 * @brief Number
	 * @note Difficulty level 
	 */
	int     level;

	/** @structvar flags1
	 * @brief Number
	 * @note Some flags 
	 */
	u32b    flags1;

	/** @structvar feat
	 * @brief Number
	 * @note The feature of f_info.txt that is used to allow passing, ... and to get a char/color/graph 
	 */
	byte    feat;

	/** @structvar terrain_idx
	 * @brief Number
	 * @note Terrain index(defined in defines.h) 
	 */
	byte    terrain_idx;

	/** @structvar terrain[MAX_WILD_TERRAIN]
	 * @brief Number
	 * @note Feature types for the plasma generator 
	 */
	byte    terrain[MAX_WILD_TERRAIN];
};

/** @struct wilderness_map
 * @note A structure describing a wilderness map
 */
struct wilderness_map
{
	/** @structvar feat
	 * @brief Number
	 * @note Wilderness feature 
	 */
	int     feat;

	/** @structvar seed
	 * @brief Number
	 * @note Seed for the RNG 
	 */
	u32b    seed;

	/** @structvar entrance
	 * @brief Number
	 * @note Entrance for dungeons 
	 */
	u16b    entrance;

	/** @structvar known
	 * @brief Boolean
	 * @note Is it seen by the player ? 
	 */
	bool    known;
};


/** @struct town_type
 * @note A structure describing a town with
 * stores and buildings
 */
struct town_type
{
	/** @structvar name
	 * @brief String
	 */
	cptr name;

	/** @structvar seed
	 * @brief Number
	 * @note Seed for RNG 
	 */
	u32b seed;

	/** @structvar *store
	 * @brief store_type
	 * @note The stores [max_st_idx] 
	 */
	store_type store[max_st_idx];

	/** @structvar numstores
	 * @brief Number
	 */
	byte numstores;

	/** @structvar flags
	 * @brief Number
	 * @note Town flags 
	 */
	byte flags;

        /** @structvar stocked
         * @brief Boolean
         * @note Is the town actually stocked ? 
         * Left this for the sake of compatibility
         */
        bool stocked;

        /** @structvar destroyed
         * @brief Boolean
         * @note Is the town destroyed? 
         */
        bool destroyed;
};

/** @var max_towns
 * @brief Number
 */
extern u16b max_towns;

/** @var town_info[max_towns]
 * @brief town_type
 */
extern town_type town_info[max_towns];

/** @struct rule_type
 * Define monster generation rules
 */
struct rule_type
{
	/** @structvar mode
	 * @brief Number
	 * @note Mode of combination of the monster flags 
	 */
	byte mode;

	/** @structvar percent
	 * @brief Number
	 * @note Percent of monsters affected by the rule 
	 */
	byte percent;

	/** @structvar mflags1
	 * @brief Number
	 * @note The monster flags that are allowed 
	 */
	u32b mflags1;

	/** @structvar mflags2
	 * @brief Number
	 */
	u32b mflags2;

	/** @structvar mflags3
	 * @brief Number
	 */
	u32b mflags3;

	/** @structvar mflags4
	 * @brief Number
	 */
	u32b mflags4;

	/** @structvar mflags5
	 * @brief Number
	 */
	u32b mflags5;

	/** @structvar mflags6
	 * @brief Number
	 */
	u32b mflags6;

	/** @structvar mflags7
	 * @brief Number
	 */
	u32b mflags7;

	/** @structvar mflags8
	 * @brief Number
	 */
	u32b mflags8;

	/** @structvar mflags9
	 * @brief Number
	 */
	u32b mflags9;

	/** @structvar r_char[5]
	 * @brief String
	 * @note Monster race allowed 
	 */
	char r_char[5];
};

/** @struct obj_theme
 * @brief "Themed" objects.
 * @note Probability in percent for each class of objects to be dropped.
 * This could perhaps be an array - but that wouldn't be as clear.
 */
struct obj_theme
{
	/** @structvar treasure
	 * @brief Number
	 */
	byte treasure;

	/** @structvar combat
	 * @brief Number
	 */
	byte combat;

	/** @structvar magic
	 * @brief Number
	 */
	byte magic;

	/** @structvar tools
	 * @brief Number
	 */
	byte tools;
};

/** @struct dungeon_info_type
 * A structure for the != dungeon types
 */
struct dungeon_info_type
{
	/** @structvar name
	 * @brief Number
	 * @note Name 
	 */
	u32b name;

	/** @structvar text
	 * @brief Number
	 * @note Description 
	 */
	u32b text;

	/** @structvar short_name[3]
	 * @brief String
	 * @note Short name 
	 */
	char short_name[3];

	/** @structvar floor1
	 * @brief Number
	 * @note Floor tile 1 
	 */
	s16b floor1;

	/** @structvar floor_percent1[2]
	 * @brief Number
	 * @note Chance of type 1 
	 */
	byte floor_percent1[2];

	/** @structvar floor2
	 * @brief Number
	 * @note Floor tile 2 
	 */
	s16b floor2;

	/** @structvar floor_percent2[2]
	 * @brief Number
	 * @note Chance of type 2 
	 */
	byte floor_percent2[2];

	/** @structvar floor3
	 * @brief Number
	 * @note Floor tile 3 
	 */
	s16b floor3;

	/** @structvar floor_percent3[2]
	 * @brief Number
	 * @note Chance of type 3 
	 */
	byte floor_percent3[2];

	/** @structvar outer_wall
	 * @brief Number
	 * @note Outer wall tile 
	 */
	s16b outer_wall;

	/** @structvar inner_wall
	 * @brief Number
	 * @note Inner wall tile 
	 */
	s16b inner_wall;

	/** @structvar fill_type1
	 * @brief Number
	 * @note Cave tile 1 
	 */
	s16b fill_type1;

	/** @structvar fill_percent1[2]
	 * @brief Number
	 * @note Chance of type 1 
	 */
	byte fill_percent1[2];

	/** @structvar fill_type2
	 * @brief Number
	 * @note Cave tile 2 
	 */
	s16b fill_type2;

	/** @structvar fill_percent2[2]
	 * @brief Number
	 * @note Chance of type 2 
	 */
	byte fill_percent2[2];

	/** @structvar fill_type3
	 * @brief Number
	 * @note Cave tile 3 
	 */
	s16b fill_type3;

	/** @structvar fill_percent3[2]
	 * @brief Number
	 * @note Chance of type 3 
	 */
	byte fill_percent3[2];

	/** @structvar fill_method
	 * @brief Number
	 * @note Smoothing parameter for the above 
	 */
	byte fill_method;

	/** @structvar mindepth
	 * @brief Number
	 * @note Minimal depth 
	 */
	s16b mindepth;

	/** @structvar maxdepth
	 * @brief Number
	 * @note Maximal depth 
	 */
	s16b maxdepth;

	/** @structvar principal
	 * @brief Boolean
	 * @note If it's a part of the main dungeon 
	 */
	bool principal;

	/** @structvar next
	 * @brief Number
	 * @note The next part of the main dungeon 
	 */
	byte next;

	/** @structvar min_plev
	 * @brief Number
	 * @note Minimal plev needed to enter -- it's an anti-cheating mesure 
	 */
	byte min_plev;

	/** @structvar min_m_alloc_level
	 * @brief Number
	 * @note Minimal number of monsters per level 
	 */
	int min_m_alloc_level;

	/** @structvar max_m_alloc_chance
	 * @brief Number
	 * @note There is a 1/max_m_alloc_chance chance per round of creating a new monster 
	 */
	int max_m_alloc_chance;

	/** @structvar flags1
	 * @brief Number
	 * @note Flags 1 
	 */
	u32b flags1;

	/** @structvar flags2
	 * @brief Number
	 * @note Flags 1 
	 */
	u32b flags2;

        /** @structvar size_x
         * @brief Number
         */
        int size_x;

        /** @structvar size_y
         * @brief Number
         * @note Desired numers of panels 
         */
        int size_y;

	/** @structvar rule_percents[100]
	 * @brief Number
	 * @note Flat rule percents 
	 */
	byte rule_percents[100];

	/** @structvar rules[5]
	 * @brief rule_type
	 * @note Monster generation rules 
	 */
	rule_type rules[5];

	/** @structvar final_object
	 * @brief Number
	 * @note The object you'll find at the bottom 
	 */
	int final_object;

	/** @structvar final_artifact
	 * @brief Number
	 * @note The artifact you'll find at the bottom 
	 */
	int final_artifact;

	/** @structvar final_guardian
	 * @brief Number
	 * @note The artifact's guardian. If an artifact is specified, then it's NEEDED 
	 */
	int final_guardian;

	/** @structvar ix
	 * @brief Number
	 */
	int ix;
    
        /** @structvar iy
         * @brief Number
         */
        int iy;
    
        /** @structvar ox
         * @brief Number
         */
        int ox;
    
        /** @structvar oy
         * @brief Number
         * @note Wilderness coordinates of the entrance/output of the dungeon 
         */
        int oy;

	/** @structvar objs
	 * @brief obj_theme
	 * @note The drops type 
	 */
	obj_theme objs;

	/** @structvar d_dice[4]
	 * @brief Number
	 * @note Number of dices 
	 */
	int d_dice[4];
    
	/** @structvar d_side[4]
	 * @brief Number
	 * @note Number of sides 
	 */
	int d_side[4];
    
	/** @structvar d_frequency[4]
	 * @brief Number
	 * @note Frequency of damage (1 is the minimum) 
	 */
	int d_frequency[4];
    
	/** @structvar d_type[4]
	 * @brief Number
	 * @note Type of damage 
	 */
	int d_type[4];

	/** @structvar t_idx[TOWN_DUNGEON]
	 * @brief Number
	 * @note The towns 
	 */
	s16b t_idx[TOWN_DUNGEON];
    
	/** @structvar t_level[TOWN_DUNGEON]
	 * @brief Number
	 * @note The towns levels 
	 */
	s16b t_level[TOWN_DUNGEON];
    
	/** @structvar t_num
	 * @brief Number
	 * @note Number of towns 
	 */
	s16b t_num;
};

/** @var max_d_idx
 * @brief Number
 */
extern u16b max_d_idx;

/** @var d_info[max_d_idx]
 * @brief dungeon_info_type
 */
extern dungeon_info_type d_info[max_d_idx];

/** @var *d_name
 * @brief String
 */
extern char *d_name;

/** @var *d_text
 * @brief String
 */
extern char *d_text;

/** @var max_wild_x
 * @brief Number
 */
extern u16b max_wild_x;

/** @var max_wild_y
 * @brief Number
 */
extern u16b max_wild_y;

/** @var max_wf_idx
 * @brief Number
 */
extern u16b max_wf_idx;

/** @var wf_info[max_wf_idx]
 * @brief wilderness_type_info
 */
extern wilderness_type_info wf_info[max_wf_idx];

/** @var *wf_name
 * @brief String
 */
extern char *wf_name;

/** @var *wf_text
 * @brief String
 */
extern char *wf_text;

/** @var DUNGEON_DEATH
 * @brief Number
 */
extern s32b DUNGEON_DEATH;

/** @var current_dungeon_idx;
 * @brief Number
 */
extern byte dungeon_type@current_dungeon_idx;

/*
 * tolua doesnt like wierd arraysn, I'll use accessing functions
 * extern wilderness_map wild_map[max_wild_y][max_wild_x];
 */
$static wilderness_map* lua_get_wild_map(int y, int x) { return &wild_map[y][x]; }
     
/** @fn wild_map(int y, int x);
 * @brief Return a map of the wilderness at coordinate (y,x).\n
 * @param y Number \n y coordinate of wilderness map
 * @brief Y-coordinate
 * @param x Number \n x coordinate of wilderness map
 * @brief X-coordinate
 * @return wilderness_map \n map of wilderness at coordinate (y,x)
 * @note (see file w_dun.c)
 */
wilderness_map* lua_get_wild_map@wild_map(int y, int x);

/** @fn place_trap(int y, int x)
 * @brief Place a random trap at the given location.\n
 * @param y Number \n y coordinate of dungeon
 * @brief Y-coordinate
 * @param x Number \n x coordinate of dungeon
 * @brief X-coordinate
 * @note
 * Places a random trap at the given location.\n
 * The location must be a valid, empty, clean, floor grid.
 * @note (see file traps.c)
 */
extern void place_trap(int y, int x);

/** @fn place_floor(int y, int x)
 * @brief Place floor terrain at (y, x).\n
 * @param y Number \n y coordinate of dungeon
 * @brief Y-coordinate
 * @param x Number \n x coordinate of dungeon
 * @brief X-coordinate
 * @note
 * Place floor terrain at (y, x) according to dungeon info.
 * @note (see file cave.c)
 */
extern void place_floor(int y, int x);

/** @fn place_filler(int y, int x)
 * @brief Place a cave filler at (y, x).\n
 * @param y Number \n y coordinate of dungeon
 * @brief Y-coordinate
 * @param x Number \n x coordinate of dungeon
 * @brief X-coordinate
 * @note (see file generate.c)
 */
extern void place_filler(int y, int x);

/** @fn add_scripted_generator(cptr name, bool stairs, bool monsters, bool objects, bool miscs)
 * @dgonly
 * @param name String \n Name of generator
 * @param stairs Boolean \n TRUE if stairs can be generated, otherwise FALSE
 * @param monsters Boolean \n TRUE if monsters can be generated, otherwise FALSE
 * @param objects Boolean \n TRUE if objects can be generated, otherwise FALSE
 * @param miscs Boolean \n TRUE if other stuff can be generated, otherwise FALSE
 * @note (defined in file lua_bind.c)
 */
extern void add_scripted_generator(cptr name, bool stairs, bool monsters, bool objects, bool miscs);

/** @fn new_player_spot(int branch)
 * @brief Places player in a new location.\n
 * @param branch Number \n branch is the dungeon branch (if any).
 * @brief Dungeon branch
 * @return Boolean \n TRUE if player was placed successfully, otherwise FALSE.
 * The global values py and px are updated.
 * @note
 * Up to 5000 attempts are made to place the player in the dungeon. The grid
 * must be a naked floor and not an anti-teleport grid. In some circumstances
 * stairs or ways in/out may be created under the player.
 * @note (see file generate.c)
 */
extern bool new_player_spot(int branch);

/** @fn get_level_desc(char *buf)
 * @brief Return the special level desc.\n
 * @param *buf String
 * @brief Description
 * @return *buf String \n The level description
 * @return Boolean \n TRUE if a level description was returned, otherwise FALSE
 * @note
 * This is the 'D' line in the dngn files.
 * @note (see file levels.c)
 */
extern bool get_level_desc(char *buf);

/** @fn get_level_flags()
 * These are the 'F' lines in the dngn files.
 * @note (see file levels.c)
 */
extern void get_level_flags();

/** @fn get_dungeon_name(char *buf)
 * @brief Return the special level name.\n
 * @param *buf String
 * @brief Name
 * @return *buf String \n The level name
 * @return Boolean \n TRUE if a level name was returned, otherwise FALSE
 * @note
 * This is the 'N' line in the dngn files.
 * @note (see file levels.c)
 */
extern bool get_dungeon_name(char *buf);

/** @fn get_dungeon_special(char *buf)
 * @brief Return the map filename.\n
 * @param *buf String
 * @brief Map filename
 * @return *buf String \n The map filename
 * @return Boolean \n TRUE if a map filename was returned, otherwise FALSE
 * @note
 * This is the 'S' line in the dngn files.
 * @note (see file levels.c)
 */
extern bool get_dungeon_special(char *buf);

/** @fn get_command(const char *file, char comm, char *param)
 * @brief Return the parameter of command "comm" in file "*file".\n
 * @param *file String \n name of the dungeon file.
 * @brief Dungeon file
 * @param comm String \n The command \n
 * 'A' = father branch, 'B' = branch, 'D' = desccription, 'L' = father level,
 * 'N' = name, 'S' = savefile extension, 'U' = map filename
 * @brief Command
 * @param *param String
 * @brief Parameter
 * @return *param String \n The result of the command
 * @return Boolean \n TRUE if a result is returned, otherwise FALSE
 * @note (see file levels.c)
 */
extern bool get_command(const char *file, char comm, char *param);

/** @fn get_branch()
 * @brief return the dungeon branch starting form the current dungeon/level.
 * @return Number \n The branch
 * @note
 * This is the 'B' line in the dngn files.
 * @note (see file levels.c)
 */
extern int get_branch();

/** @fn get_fbranch()
 * @brief Return the father dungeon branch.
 * @return Number \n The father branch
 * @note
 * This is the 'A' line in the dngn files.
 * @note (see file levels.c)
 */
extern int get_fbranch();

/** @fn get_flevel()
 * @brief Return the father dungeon level.
 * @return Number \n The father level
 * @note
 * This is the 'L' line in the dngn files.
 * @note (see file levels.c)
 */
extern int get_flevel();

/** @fn get_dungeon_save(char *buf)
 * @brief Return the extension of the savefile for the level.\n
 * @param *buf String
 * @brief Savefile extension
 * @return *buf String \n The savefile extension
 * @return Boolean \n TRUE if a savefile extension was returned, otherwise FALSE
 * This is the 'S' line in the dngn files.
 * @note (see file levels.c)
 */
extern bool get_dungeon_save(char *buf);
tome-235-src/src/variable.c0000644000076400017500000007704711012107763013425 0ustar  dgdg/* File: variable.c */

/* Purpose: Angband variables */

/*
 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
 *
 * This software may be copied and distributed for educational, research, and
 * not for profit purposes provided that this copyright and statement are
 * included in all such copies.
 */

#include "angband.h"


/*
 * Hack -- Link a copyright message into the executable
 */
cptr copyright[5] =
{
	"Copyright (c) 1989 James E. Wilson, Robert A. Keoneke",
	"",
	"This software may be copied and distributed for educational, research,",
	"and not for profit purposes provided that this copyright and statement",
	"are included in all such copies."
};

int max_macrotrigger = 0;
char *macro_template = NULL;
char *macro_modifier_chr;
char *macro_modifier_name[MAX_MACRO_MOD];
char *macro_trigger_name[MAX_MACRO_TRIG];
char *macro_trigger_keycode[2][MAX_MACRO_TRIG];

/*
 * Executable version
 */
byte version_major;
byte version_minor;
byte version_patch;
byte version_extra = VERSION_EXTRA;

/*
 * Savefile version
 */
byte sf_major; 			/* Savefile's "version_major" */
byte sf_minor; 			/* Savefile's "version_minor" */
byte sf_patch; 			/* Savefile's "version_patch" */
byte sf_extra; 			/* Savefile's "version_extra" */
u32b vernum;

/*
 * Savefile information
 */
u32b sf_xtra; 			/* Operating system info */
u32b sf_when; 			/* Time when savefile created */
u16b sf_lives; 			/* Number of past "lives" with this file */
u16b sf_saves; 			/* Number of "saves" during this life */

/*
 * Run-time arguments
 */
bool arg_fiddle; 			/* Command arg -- Request fiddle mode */
bool arg_wizard; 			/* Command arg -- Request wizard mode */
bool arg_sound; 				/* Command arg -- Request special sounds */
bool arg_graphics; 			/* Command arg -- Request graphics mode */
bool arg_force_original; 	/* Command arg -- Request original keyset */
bool arg_force_roguelike; 	/* Command arg -- Request roguelike keyset */
bool arg_bigtile = FALSE; 	/* Command arg -- Request big tile mode */

/*
 * Various things
 */

bool character_generated; 	/* The character exists */
bool character_dungeon; 		/* The character has a dungeon */
bool character_loaded; 		/* The character was loaded from a savefile */
bool character_saved; 		/* The character was just saved to a savefile */

bool character_icky; 		/* The game is in an icky full screen mode */
bool character_xtra; 		/* The game is in an icky startup mode */

u32b seed_flavor; 		/* Hack -- consistent object colors */
u32b seed_town; 			/* Hack -- consistent town layout */
u32b seed_dungeon;               /* Simulate persisten dungeons */

s16b command_cmd; 		/* Current "Angband Command" */

s16b command_arg; 		/* Gives argument of current command */
s16b command_rep; 		/* Gives repetition of current command */
s16b command_dir; 		/* Gives direction of current command */

s16b command_see; 		/* See "cmd1.c" */
s16b command_wrk; 		/* See "cmd1.c" */

s16b command_new; 		/* Command chaining from inven/equip view */

s32b energy_use;                 /* Energy use this turn */

bool create_up_stair; 	/* Auto-create "up stairs" */
bool create_down_stair; 	/* Auto-create "down stairs" */

bool create_up_shaft;  /* Auto-create "up shaft" */
bool create_down_shaft;        /* Auto-create "down shaft" */

bool msg_flag; 			/* Used in msg_print() for "buffering" */

bool alive; 				/* True if game is running */

bool death; 				/* True if player has died */

s16b running; 			/* Current counter for running, if any */
s16b resting; 			/* Current counter for resting, if any */

s16b cur_hgt; 			/* Current dungeon height */
s16b cur_wid; 			/* Current dungeon width */
s16b dun_level; 			/* Current dungeon level */
s16b old_dun_level;              /* Old dungeon level */
s16b num_repro; 			/* Current reproducer count */
s16b object_level; 		/* Current object creation level */
s16b monster_level; 		/* Current monster creation level */

s32b turn; 				/* Current game turn */
s32b old_turn; 			/* Turn when level began (feelings) */

bool wizard; 			/* Is the player currently in Wizard mode? */

bool use_sound; 			/* The "sound" mode is enabled */
bool use_graphics; 		/* The "graphics" mode is enabled */
bool use_bigtile = FALSE;
byte graphics_mode; 		/* Current graphics mode */

u16b total_winner; 		/* Semi-Hack -- Game has been won */
u16b has_won;               /* Semi-Hack -- Game has been won */

u16b panic_save; 		/* Track some special "conditions" */
u16b noscore; 			/* Track various "cheating" conditions */

s16b signal_count; 		/* Hack -- Count interupts */

bool inkey_base; 		/* See the "inkey()" function */
bool inkey_xtra; 		/* See the "inkey()" function */
bool inkey_scan; 		/* See the "inkey()" function */
bool inkey_flag; 		/* See the "inkey()" function */

s16b coin_type; 			/* Hack -- force coin type */

bool opening_chest; 		/* Hack -- prevent chest generation */

bool shimmer_monsters;           /* Hack -- optimize multi-hued monsters */
bool shimmer_objects;            /* Hack -- optimize multi-hued objects */

bool repair_monsters; 	/* Hack -- optimize detect monsters */
bool repair_objects; 	/* Hack -- optimize detect objects */

s16b inven_nxt; 			/* Hack -- unused */
bool hack_mind;
bool hack_corruption;
int artifact_bias;
bool is_autosave = FALSE;

s16b inven_cnt; 			/* Number of items in inventory */
s16b equip_cnt; 			/* Number of items in equipment */

s16b o_max = 1; 			/* Number of allocated objects */
s16b o_cnt = 0; 			/* Number of live objects */

s16b m_max = 1; 			/* Number of allocated monsters */
s16b m_cnt = 0; 			/* Number of live monsters */

s16b hack_m_idx = 0; 	/* Hack -- see "process_monsters()" */
s16b hack_m_idx_ii = 0;
bool multi_rew = FALSE;
char summon_kin_type;    /* Hack, by Julian Lighton: summon 'relatives' */

int total_friends = 0;
s32b total_friend_levels = 0;

int leaving_quest = 0;



/*
 * Hack - the destination file for text_out_to_file.
 */
FILE *text_out_file = NULL;


/*
 * Hack -- function hook to output (colored) text to the
 * screen or to a file.
 */
void (*text_out_hook)(byte a, cptr str) = text_out_to_screen;


/*
 * Hack -- Where to wrap the text when using text_out().  Use the default
 * value (for example the screen width) when 'text_out_wrap' is 0.
 */
int text_out_wrap = 0;


/*
 * Hack -- Indentation for the text when using text_out().
 */
int text_out_indent = 0;


/*
 * The "highscore" file descriptor, if available.
 */
int highscore_fd = -1;


/*
 * Software options (set via the '=' command).  See "tables.c"
 */


/* Option Set 1 -- User Interface */

bool rogue_like_commands; 	/* Rogue-like commands */
bool quick_messages; 		/* Activate quick messages */
bool other_query_flag; 		/* Prompt for various information */
bool carry_query_flag; 		/* Prompt before picking things up */
bool use_old_target; 		/* Use old target by default */
bool always_pickup;              /* Pick things up by default */
bool prompt_pickup_heavy;        /* Don't pick up the corpses */
bool always_repeat;              /* Repeat obvious commands */
bool depth_in_feet;              /* Show dungeon level in feet */

bool stack_force_notes; 		/* Merge inscriptions when stacking */
bool stack_force_costs; 		/* Merge discounts when stacking */

bool show_labels; 			/* Show labels in object listings */
bool show_weights; 			/* Show weights in object listings */
bool show_choices; 			/* Show choices in certain sub-windows */
bool show_details; 			/* Show details in certain sub-windows */

bool ring_bell; 				/* Ring the bell (on errors, etc) */
bool use_color; 				/* Use color if possible (slow) */

bool show_inven_graph; 		/* Show graphics in inventory */
bool show_equip_graph; 		/* Show graphics in equip list */
bool show_store_graph; 		/* Show graphics in store */



/* Option Set 2 -- Disturbance */

bool find_ignore_stairs; 	/* Run past stairs */
bool find_ignore_doors; 		/* Run through open doors */
bool find_cut; 				/* Run past known corners */
bool find_examine; 			/* Run into potential corners */

bool disturb_move; 			/* Disturb whenever any monster moves */
bool disturb_near; 			/* Disturb whenever viewable monster moves */
bool disturb_panel; 			/* Disturb whenever map panel changes */
bool disturb_detect; 		/* Disturb whenever leaving trap-detected area */
bool disturb_state; 			/* Disturn whenever player state changes */
bool disturb_minor; 			/* Disturb whenever boring things happen */
bool disturb_other; 			/* Disturb whenever various things happen */

bool alert_hitpoint; 		/* Alert user to critical hitpoints */
bool alert_failure; 		/* Alert user to various failures */
bool last_words; 		/* Get last words upon dying */
bool speak_unique; 		/* Speaking uniques + shopkeepers */
bool small_levels; 		/* Allow unusually small dungeon levels */
bool empty_levels; 		/* Allow empty 'arena' levels */
bool always_small_level;         /* Small levels */
#if 0 /* It's controlled by insanity -- pelpel */
bool flavored_attacks;           /* Show silly messages when fighting */
#endif
bool player_symbols; 		/* Use varying symbols for the player char */
bool plain_descriptions; 	/* Plain object descriptions */
bool stupid_monsters; 		/* Monsters use old AI */
bool auto_destroy; 		/* Known worthless items are destroyed without confirmation */
bool confirm_stairs; 		/* Prompt before staircases... */
bool wear_confirm; 		/* Confirm before putting on known cursed items */
bool disturb_pets; 		/* Pets moving nearby disturb us */


/* Option Set 3 -- Game-Play */

bool auto_haggle; 			/* Auto-haggle in stores */

bool auto_scum; 				/* Auto-scum for good levels */

bool stack_allow_items; 		/* Allow weapons and armor to stack */
bool stack_allow_wands; 		/* Allow wands/staffs/rods to stack */

bool expand_look; 			/* Expand the power of the look command */
bool expand_list; 			/* Expand the power of the list commands */

bool view_perma_grids; 		/* Map remembers all perma-lit grids */
bool view_torch_grids; 		/* Map remembers all torch-lit grids */

bool monster_lite; 			/* Allow some monsters to carry light */

bool dungeon_align; 			/* Generate dungeons with aligned rooms */
bool dungeon_stair; 			/* Generate dungeons with connected stairs */

bool flow_by_sound; 			/* Monsters track new player location */
bool flow_by_smell; 			/* Monsters track old player location */

bool track_follow; 			/* Monsters follow the player */
bool track_target; 			/* Monsters target the player */

bool smart_learn; 			/* Monsters learn from their mistakes */
bool smart_cheat; 			/* Monsters exploit player weaknesses */


/* Option Set 4 -- Efficiency */

bool view_reduce_lite; 		/* Reduce lite-radius when running */
bool view_reduce_view; 		/* Reduce view-radius in town */

bool avoid_abort; 			/* Avoid checking for user abort */
bool avoid_shimmer; 			/* Avoid processing extra shimmering */
bool avoid_other; 			/* Avoid processing special colors */

bool flush_failure; 			/* Flush input on any failure */
bool flush_disturb; 			/* Flush input on disturbance */
bool flush_command; 			/* Flush input before every command */

bool fresh_before; 			/* Flush output before normal commands */
bool fresh_after; 			/* Flush output after normal commands */
bool fresh_message; 			/* Flush output after all messages */

bool compress_savefile; 		/* Compress messages in savefiles */

bool hilite_player; 			/* Hilite the player with the cursor */

bool view_yellow_lite; 		/* Use special colors for torch-lit grids */
bool view_bright_lite; 		/* Use special colors for 'viewable' grids */

bool view_granite_lite; 		/* Use special colors for wall grids (slow) */
bool view_special_lite; 		/* Use special colors for floor grids (slow) */

/* Option set 5 -- Testing */

bool testing_stack; 			/* Test the stacking code */

bool testing_carry; 			/* Test the carrying code */


/* Cheating options */

bool cheat_peek; 		/* Peek into object creation */
bool cheat_hear; 		/* Peek into monster creation */
bool cheat_room; 		/* Peek into dungeon creation */
bool cheat_xtra; 		/* Peek into something else */
bool cheat_know; 		/* Know complete monster info */
bool cheat_live; 		/* Allow player to avoid death */


/* Special options */

byte hitpoint_warn; 		/* Hitpoint warning (0 to 9) */

byte delay_factor; 		/* Delay factor (0 to 9) */

bool autosave_l;         /* Autosave before entering new levels */
bool autosave_t;         /* Timed autosave */
s16b autosave_freq;      /* Autosave frequency */


/*
 * Dungeon variables
 */

s16b feeling; 			/* Most recent feeling */
s16b rating; 			/* Level's current rating */

bool good_item_flag; 		/* True if "Artifact" on this level */

bool closing_flag; 		/* Dungeon is closing */

/*
 * Dungeon size info
 */

s16b max_panel_rows, max_panel_cols;
s16b panel_row_min, panel_row_max;
s16b panel_col_min, panel_col_max;
s16b panel_col_prt, panel_row_prt;

/*
 * Dungeon graphics info
 * Why the first two are byte and the rest s16b???
 */
byte feat_wall_outer = FEAT_WALL_OUTER; 	/* Outer wall of rooms */
byte feat_wall_inner = FEAT_WALL_INNER; 	/* Inner wall of rooms */
s16b floor_type[100]; 	/* Dungeon floor */
s16b fill_type[100]; 	/* Dungeon filler */

/*
 * Targetting variables
 */
s16b target_who;
s16b target_col;
s16b target_row;

/*
 * Health bar variable -DRS-
 */
s16b health_who;

/*
 * Monster race to track
 */
s16b monster_race_idx;
s16b monster_ego_idx;

/*
 * Object to track
 */
object_type *tracked_object;



/*
 * User info
 */
int player_uid;
int player_euid;
int player_egid;

/*
 * Current player's character name
 */
char player_name[32];

/*
 * Stripped version of "player_name"
 */
char player_base[32];

/*
 * What killed the player
 */
char died_from[80];

/*
 * Hack -- Textual "history" for the Player
 */
char history[4][60];

/*
 * Buffer to hold the current savefile name
 */
char savefile[1024];
bool savefile_setuid = TRUE;


/*
 * Array of grids lit by player lite (see "cave.c")
 */
s16b lite_n;
s16b lite_y[LITE_MAX];
s16b lite_x[LITE_MAX];

/*
 * Array of grids viewable to the player (see "cave.c")
 */
s16b view_n;
byte view_y[VIEW_MAX];
byte view_x[VIEW_MAX];

/*
 * Array of grids for use by various functions (see "cave.c")
 */
s16b temp_n;
byte temp_y[TEMP_MAX];
byte temp_x[TEMP_MAX];


/*
 * Number of active macros.
 */
s16b macro__num;

/*
 * Array of macro patterns [MACRO_MAX]
 */
cptr *macro__pat;

/*
 * Array of macro actions [MACRO_MAX]
 */
cptr *macro__act;

/*
 * Array of macro types [MACRO_MAX]
 */
bool *macro__cmd;

/*
 * Current macro action [1024]
 */
char *macro__buf;


/*
 * The number of quarks
 */
s16b quark__num;

/*
 * The pointers to the quarks [QUARK_MAX]
 */
cptr *quark__str;


/*
 * The next "free" index to use
 */
u16b message__next;

/*
 * The index of the oldest message (none yet)
 */
u16b message__last;

/*
 * The next "free" offset
 */
u16b message__head;

/*
 * The offset to the oldest used char (none yet)
 */
u16b message__tail;

/*
 * The array of offsets, by index [MESSAGE_MAX]
 */
u16b *message__ptr;

/*
 * The array of colors, by index [MESSAGE_MAX]
 */
byte *message__color;

/*
 * The array of type, by index [MESSAGE_MAX]
 */
byte *message__type;

/*
 * The array of message counts, by index [MESSAGE_MAX]
 */
u16b *message__count;

/*
 * The array of chars, by offset [MESSAGE_BUF]
 */
char *message__buf;


/*
 * The array of normal options
 */
u32b option_flag[8];
u32b option_mask[8];


/*
 * The array of window options
 */
u32b window_flag[8];
u32b window_mask[8];


/*
 * The array of window pointers
 */
term *angband_term[ANGBAND_TERM_MAX];


/*
 * Standard window names
 */
char angband_term_name[ANGBAND_TERM_MAX][80] =
{
	"ToME",
	"Mirror",
	"Recall",
	"Choice",
	"Term-4",
	"Term-5",
	"Term-6",
	"Term-7"
};


/*
 * Global table of color definitions
 */
byte angband_color_table[256][4] =
{
	{0x00, 0x00, 0x00, 0x00}, 	/* TERM_DARK */
	{0x00, 0xFF, 0xFF, 0xFF}, 	/* TERM_WHITE */
	{0x00, 0x80, 0x80, 0x80}, 	/* TERM_SLATE */
	{0x00, 0xFF, 0x80, 0x00}, 	/* TERM_ORANGE */
	{0x00, 0xC0, 0x00, 0x00}, 	/* TERM_RED */
	{0x00, 0x00, 0x80, 0x40}, 	/* TERM_GREEN */
	{0x00, 0x00, 0x00, 0xFF}, 	/* TERM_BLUE */
	{0x00, 0x80, 0x40, 0x00}, 	/* TERM_UMBER */
	{0x00, 0x40, 0x40, 0x40}, 	/* TERM_L_DARK */
	{0x00, 0xC0, 0xC0, 0xC0}, 	/* TERM_L_WHITE */
	{0x00, 0xFF, 0x00, 0xFF}, 	/* TERM_VIOLET */
	{0x00, 0xFF, 0xFF, 0x00}, 	/* TERM_YELLOW */
	{0x00, 0xFF, 0x00, 0x00}, 	/* TERM_L_RED */
	{0x00, 0x00, 0xFF, 0x00}, 	/* TERM_L_GREEN */
	{0x00, 0x00, 0xFF, 0xFF}, 	/* TERM_L_BLUE */
	{0x00, 0xC0, 0x80, 0x40}	/* TERM_L_UMBER */
};


#ifdef SUPPORT_GAMMA

/*
 * Gamma correction - gamma_val == (int)(256 / gamma)
 * The value of 0 means no gamma correction (== 1.0)
 */
u16b gamma_val;

#endif /* SUPPORT_GAMMA */


/*
 * Standard sound names
 */
char angband_sound_name[SOUND_MAX][16] =
{
	"",
	"hit",
	"miss",
	"flee",
	"drop",
	"kill",
	"level",
	"death",
	"study",
	"teleport",
	"shoot",
	"quaff",
	"zap",
	"walk",
	"tpother",
	"hitwall",
	"eat",
	"store1",
	"store2",
	"store3",
	"store4",
	"dig",
	"opendoor",
	"shutdoor",
	"tplevel",
	"scroll",
	"buy",
	"sell",
	"warn",
	"rocket",
	"n_kill",
	"u_kill",
	"quest",
	"heal",
	"x_heal",
	"bite",
	"claw",
	"m_spell",
	"summon",
	"breath",
	"ball",
	"m_heal",
	"atkspell",
	"evil",
	"touch",
	"sting",
	"crush",
	"slime",
	"wail",
	"winner",
	"fire",
	"acid",
	"elec",
	"cold",
	"illegal",
	"fail",
	"wakeup",
	"invuln",
	"fall",
	"pain",
	"destitem",
	"moan",
	"show",
	"unused",
	"explode",
};


/*
 * The array of "cave grids" [MAX_WID][MAX_HGT].
 * Not completely allocated, that would be inefficient
 * Not completely hardcoded, that would overflow memory
 */
cave_type *cave[MAX_HGT];

/*
 * The array of dungeon items [max_o_idx]
 */
object_type *o_list;

/*
 * The array of dungeon monsters [max_m_idx]
 */
monster_type *m_list;

/*
 * The array of to keep monsters [max_m_idx]
 */
monster_type *km_list;


/*
 * Maximum number of towns
 */
u16b max_towns;
u16b max_real_towns;

/*
 * The towns [max_towns]
 */
town_type *town_info;

/*
 * The size of "alloc_kind_table" (at most max_k_idx * 4)
 */
s16b alloc_kind_size;

/*
 * The entries in the "kind allocator table"
 */
alloc_entry *alloc_kind_table;

/*
 * The flag to tell if alloc_kind_table contains valid entries
 * for normal (i.e. kind_is_legal) object allocation
 */
bool alloc_kind_table_valid = FALSE;


/*
 * The size of "alloc_race_table" (at most max_r_idx)
 */
s16b alloc_race_size;

/*
 * The entries in the "race allocator table"
 */
alloc_entry *alloc_race_table;


/*
 * Specify attr/char pairs for visual special effects
 * Be sure to use "index & 0x7F" to avoid illegal access
 */
byte misc_to_attr[256];
char misc_to_char[256];


/*
 * Specify attr/char pairs for inventory items (by tval)
 * Be sure to use "index & 0x7F" to avoid illegal access
 */
byte tval_to_attr[128];
char tval_to_char[128];


/*
 * Keymaps for each "mode" associated with each keypress.
 */
cptr keymap_act[KEYMAP_MODES][256];



/*** Player information ***/

/*
 * Static player info record
 */
player_type p_body;

/*
 * Pointer to the player info
 */
player_type *p_ptr = &p_body;

/*
 * Pointer to the player tables
 * (sex, race, race mod, class, magic)
 */
player_sex *sp_ptr;
player_race *rp_ptr;
player_race_mod *rmp_ptr;
player_class *cp_ptr;
player_spec *spp_ptr;


/*
 * More spell info
 */
u32b alchemist_known_egos[32];
u32b alchemist_known_artifacts[6];
u32b alchemist_gained;


/*
 * Calculated base hp values for player at each level,
 * store them so that drain life + restore life does not
 * affect hit points.  Also prevents shameless use of backup
 * savefiles for hitpoint acquirement.
 */
s16b player_hp[PY_MAX_LEVEL];

/*
 * The alchemy recipe arrays
 */
header *al_head;
alchemist_recipe *alchemist_recipes;
char *al_name;
artifact_select_flag *a_select_flags;

/*
 * The vault generation arrays
 */
header *v_head;
vault_type *v_info;
char *v_name;
char *v_text;

/*
 * The terrain feature arrays
 */
header *f_head;
feature_type *f_info;
char *f_name;
char *f_text;

/*
 * The object kind arrays
 */
header *k_head;
object_kind *k_info;
char *k_name;
char *k_text;

/*
 * The artifact arrays
 */
header *a_head;
artifact_type *a_info;
char *a_name;
char *a_text;

/*
 * The item set arrays
 */
header *set_head;
set_type *set_info;
char *set_name;
char *set_text;

/*
 * The ego-item arrays
 */
header *e_head;
ego_item_type *e_info;
char *e_name;
char *e_text;

/*
 * The randart arrays
 */
header *ra_head;
randart_part_type *ra_info;
randart_gen_type ra_gen[30];

/* jk */
/* the trap-arrays */
header *t_head;
trap_type *t_info;
char *t_name;
char *t_text;

/*
 * The monster race arrays
 */
header *r_head;
monster_race *r_info;
char *r_name;
char *r_text;

/*
 * The monster ego race arrays
 */
header *re_head;
monster_ego *re_info;
char *re_name;

/*
 * The dungeon types arrays
 */
header *d_head;
dungeon_info_type *d_info;
char *d_name;
char *d_text;

/*
 * Player abilities arrays
 */
header *ab_head;
ability_type *ab_info;
char *ab_name;
char *ab_text;

/*
 * Player skills arrays
 */
header *s_head;
skill_type *s_info;
char *s_name;
char *s_text;

/*
 * Player race arrays
 */
header *rp_head;
player_race *race_info;
char *rp_name;
char *rp_text;

/*
 * Player mod race arrays
 */
header *rmp_head;
player_race_mod *race_mod_info;
char *rmp_name;
char *rmp_text;

/*
 * Player class arrays
 */
header *c_head;
player_class *class_info;
char *c_name;
char *c_text;
meta_class_type *meta_class_info;

/*
 * The wilderness features arrays
 */
header *wf_head;
wilderness_type_info *wf_info;
char *wf_name;
char *wf_text;
int wildc2i[256];

/*
 * The store/building types arrays
 */
header *st_head;
store_info_type *st_info;
char *st_name;
/* char *st_text; */

/*
 * The building actions types arrays
 */
header *ba_head;
store_action_type *ba_info;
char *ba_name;
/* char *ba_text; */

/*
 * The owner types arrays
 */
header *ow_head;
owner_type *ow_info;
char *ow_name;
/* char *ow_text; */

/*
 * The dungeon types arrays
 */
header *d_head;
dungeon_info_type *d_info;
char *d_name;
char *d_text;

/*
 * Hack -- The special Angband "System Suffix"
 * This variable is used to choose an appropriate "pref-xxx" file
 */
cptr ANGBAND_SYS = "xxx";

/*
 * Hack -- The special Angband "Keyboard Suffix"
 * This variable is used to choose an appropriate macro-trigger definition
 */
#ifdef JP
cptr ANGBAND_KEYBOARD = "JAPAN";
#else
cptr ANGBAND_KEYBOARD = "0";
#endif

/*
 * Hack -- The special Angband "Graphics Suffix"
 * This variable is used to choose an appropriate "graf-xxx" file
 */
cptr ANGBAND_GRAF = "old";

/*
 * Path name: The main "lib" directory
 * This variable is not actually used anywhere in the code
 */
cptr ANGBAND_DIR;

/*
 * High score files (binary)
 * These files may be portable between platforms
 */
cptr ANGBAND_DIR_APEX;

/*
 * Bone files for player ghosts (ascii)
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_BONE;

/*
 * Core lua system
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_CORE;

/*
 * Textual dungeon level definition files
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_DNGN;

/*
 * Binary image files for the "*_info" arrays (binary)
 * These files are not portable between platforms
 */
cptr ANGBAND_DIR_DATA;

/*
 * Textual template files for the "*_info" arrays (ascii)
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_EDIT;

/*
 * Various extra files (ascii)
 * These files may be portable between platforms
 */
cptr ANGBAND_DIR_FILE;

/*
 * Help files (normal) for the online help (ascii)
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_HELP;

/*
 * Help files (spoilers) for the online help (ascii)
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_INFO;

/*
 * Modules, those subdirectories are half-mirrors of lib/
 */
cptr ANGBAND_DIR_MODULES;

/*
 * Patches, contains one subdir per patch with a patch.lua file
 * in it and a patch_init() function in it
 */
cptr ANGBAND_DIR_PATCH;

/*
 * Textual template files for the plot files (ascii)
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_NOTE;

/*
 * Savefiles for current characters (binary)
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_SAVE;

/*
 * Scripts.
 * These files are portable between platforms
 */
cptr ANGBAND_DIR_SCPT;

/*
 * Default "preference" files (ascii)
 * These files are rarely portable between platforms
 */
cptr ANGBAND_DIR_PREF;

/*
 * User "preference" files (ascii)
 * These files are rarely portable between platforms
 */
cptr ANGBAND_DIR_USER;

/*
 * Various extra files (binary)
 * These files are rarely portable between platforms
 */
cptr ANGBAND_DIR_XTRA;

/*
 * Cmovie files of entire games (ascii)
 * Apart from possible newline things, likely portable btw platforms
 */

cptr ANGBAND_DIR_CMOV;

/*
 * Some variables values are created on the fly XXX XXX
 */

char pref_tmp_value[8];



/*
 * Total Hack -- allow all items to be listed (even empty ones)
 * This is only used by "do_cmd_inven_e()" and is cleared there.
 */
bool item_tester_full;


/*
 * Here is a "pseudo-hook" used during calls to "get_item()" and
 * "show_inven()" and "show_equip()", and the choice window routines.
 */
byte item_tester_tval;


/*
 * Here is a "hook" used during calls to "get_item()" and
 * "show_inven()" and "show_equip()", and the choice window routines.
 */
bool (*item_tester_hook)(object_type*);



/*
 * Current "comp" function for ang_sort()
 */
bool (*ang_sort_comp)(vptr u, vptr v, int a, int b);


/*
 * Current "swap" function for ang_sort()
 */
void (*ang_sort_swap)(vptr u, vptr v, int a, int b);



/*
 * Hack -- function hooks to restrict "get_mon_num_prep()" function
 */
bool (*get_mon_num_hook)(int r_idx);
bool (*get_mon_num2_hook)(int r_idx);


/*
 * Hack -- function hook to restrict "get_obj_num_prep()" function
 */
bool (*get_obj_num_hook)(int k_idx);


/* Hack, monk armour */
bool monk_armour_aux;
bool monk_notify_aux;

#ifdef ALLOW_EASY_OPEN /* TNB */
bool easy_open = TRUE;
#endif /* ALLOW_EASY_OPEN -- TNB */

#ifdef ALLOW_EASY_DISARM /* TNB */
bool easy_disarm = TRUE;
#endif /* ALLOW_EASY_DISARM -- TNB */

bool easy_tunnel = FALSE;


/*
 * Maximum size of the wilderness map
 */
u16b max_wild_x;
u16b max_wild_y;

/*
 * Wilderness map
 */
wilderness_map **wild_map;


/*
 * Maximum number of skills in s_info.txt
 */
u16b old_max_s_idx = 0;
u16b max_s_idx;

/*
 * Maximum number of abilities in ab_info.txt
 */
u16b max_ab_idx;

/*
 * Maximum number of monsters in r_info.txt
 */
u16b max_r_idx;

/*
 * Maximum number of ego monsters in re_info.txt
 */
u16b max_re_idx;

/*
 * Maximum number of items in k_info.txt
 */
u16b max_k_idx;

/*
 * Maximum number of vaults in v_info.txt
 */
u16b max_v_idx;

/*
 * Maximum number of terrain features in f_info.txt
 */
u16b max_f_idx;

/*
 * Maximum number of alchemist recipies in al_info.txt
 */
u16b max_al_idx;

/*
 * Maximum number of artifacts in a_info.txt
 */
u16b max_a_idx;

/*
 * Maximum number of ego-items in e_info.txt
 */
u16b max_e_idx;

/*
 * Maximum number of randarts in ra_info.txt
 */
u16b max_ra_idx;

/*
 * Maximum number of dungeon types in d_info.txt
 */
u16b max_d_idx;

/*
 * Maximum number of stores types in st_info.txt
 */
u16b max_st_idx;

/*
 * Item sets
 */
s16b max_set_idx = 1;

/*
 * Maximum number of players info in p_info.txt
 */
u16b max_rp_idx;
u16b max_rmp_idx;
u16b max_c_idx;
u16b max_mc_idx;

/*
 * Maximum number of actions types in ba_info.txt
 */
u16b max_ba_idx;

/*
 * Maximum number of owner types in ow_info.txt
 */
u16b max_ow_idx;

/*
 * Maximum number of objects in the level
 */
u16b max_o_idx;

/*
 * Maximum number of monsters in the level
 */
u16b max_m_idx;

/*
 * Maximum number of traps in tr_info.txt
 */
u16b max_t_idx;

/*
 * Maximum number of wilderness features in wf_info.txt
 */
u16b max_wf_idx;

/*
 * Flags for initialization
 */
int init_flags;

/* True if on an ambush */
bool ambush_flag;

/* True if on fated level */
bool fate_flag;

/* No breeders */
u16b no_breeds;

/* Carried monsters can't take the damage if this is them which attack the player */
bool carried_monster_hit = FALSE;

/*
 * Random artifacts.
 */
random_artifact random_artifacts[MAX_RANDARTS];
/* These three used to be constants but now are set by modules */
s32b RANDART_WEAPON;
s32b RANDART_ARMOR;
s32b RANDART_JEWEL;

/*
 * Current bounties. An array of tuples of two, with the first being the
 * r_idx of the monster, and the second the monster's worth.
 */
s16b bounties[MAX_BOUNTIES][2];

/*
 * Spell description
 */
bool info_spell = FALSE;
char spell_txt[50];

/*
 * Random spells.
 */
random_spell random_spells[MAX_SPELLS];
s16b spell_num;

/*
 * Runecrafter's selfmade spells.
 */
rune_spell rune_spells[MAX_RUNES];
s16b rune_num;

/*
 * Fate.
 */
fate fates[MAX_FATES];

/*
 * Vanilla town.
 */
byte vanilla_town = FALSE;

/*
 * Which dungeon ?
 * 0 = Wilderness
 * 1 = Mirkwood
 * 2 = Mordor
 * 3 = Angband
 * 4 = Barrow Downs
 * 5 = Mount Doom
 * 6 = Nether Realm
 * etc. (see d_info.txt)
 */
byte dungeon_type;
s16b *max_dlv;

/*
 * Number of total bounties the player had had.
 */
u32b total_bounties;

/* The Doppleganger index in m_list */
s16b doppleganger;

/* To allow wilderness encounters */
bool generate_encounter;

/* Permanent dungeons ? */
bool permanent_levels;

/* Autoroler */
bool autoroll;

/* Point based */
bool point_based;

/* Maximize, preserve, special levels, ironman_rooms */
bool maximize, preserve, special_lvls, ironman_rooms;

/* In inventory option window, just erase the letters,
 * rather that displaying the list without the invalid
 * selections */
bool inventory_no_move;

/* Notes patch */
bool take_notes, auto_notes;

/*
 * Such an ugly hack ...
 */
bool *m_allow_special;
bool *k_allow_special;
bool *a_allow_special;

/*
 * Gives a random object to newly created characters
 */
bool rand_birth;

/*
 * Fast autoroller
 */
bool fast_autoroller;

/*
 * Which monsters are allowed ?
 */
bool joke_monsters;

/*
 * How will mana staf & weapons of life act
 */
bool munchkin_multipliers = TRUE;

/*
 * Center view
 */
bool center_player = FALSE;

/*
 * Plots
 */
s16b plots[MAX_PLOTS];

/*
 * Random quest
 */
random_quest random_quests[MAX_RANDOM_QUEST];

/*
 * Show exp left
 */
bool exp_need;

/*
 * Auto load old colors;
 */
bool autoload_old_colors;

/*
 * Fated ?
 */
bool fate_option;

/*
 * Special levels
 */
bool *special_lvl[MAX_DUNGEON_DEPTH];
bool generate_special_feeling = FALSE;

/*
 * Auto more
 */
bool auto_more;

/*
 * Dungeon flags
 */
u32b dungeon_flags1;
u32b dungeon_flags2;

/*
 * The last character displayed
 */
birther previous_char;

/*
 * Race histories
 */
hist_type *bg;
int max_bg_idx;

/*
 * Powers
 */
s16b power_max = POWER_MAX_INIT;
power_type *powers_type;

/*
 * Variable savefile stuff
 */
s32b extra_savefile_parts = 0;

/*
 * Quests
 */
s16b max_q_idx = MAX_Q_IDX_INIT;
quest_type *quest;

/*
 * Display the player as a special symbol when in bad health ?
 */
bool player_char_health;


/*
 * The spell list of schools
 */
s16b max_spells;
spell_type *school_spells;
s16b max_schools;
school_type *schools;

/*
 * Lasting spell effects
 */
int project_time = 0;
s32b project_time_effect = 0;
effect_type effects[MAX_EFFECTS];

/*
 * General skills set
 */
char gen_skill_basem[MAX_SKILLS];
u32b gen_skill_base[MAX_SKILLS];
char gen_skill_modm[MAX_SKILLS];
s16b gen_skill_mod[MAX_SKILLS];

/*
 * Display stats as linear
 */
bool linear_stats;

/*
 * Table of "cli" macros.
 */
cli_comm *cli_info;
int cli_total = 0;

/*
 * max_bact, only used so that lua scripts can add new bacts without worrying about the numbers
 */
int max_bact = 54;

/*
 * Max corruptions
 */
s16b max_corruptions = 0;

/*
 * Ingame contextual help
 */
bool option_ingame_help = TRUE;

/*
 * Automatizer enabled status
 */
bool automatizer_enabled = FALSE;

/*
 * Location of the last teleportation thath affected the level
 */
s16b last_teleportation_y = -1;
s16b last_teleportation_x = -1;

/*
 * The current game module
 */
cptr game_module;
s32b VERSION_MAJOR;
s32b VERSION_MINOR;
s32b VERSION_PATCH;

/*
 * Some module info
 */
s32b max_plev = 50;
s32b DUNGEON_DEATH = 28;

/*
 * Gods
 */
deity_type *deity_info;
s32b max_gods = MAX_GODS_INIT;

/*
 * Timers
 */
timer_type *gl_timers = NULL;
tome-235-src/src/q_ultrae.c0000644000076400017500000000024611012107763013437 0ustar  dgdg/*
 * Here takes place the Evil ultra ending
 */

#undef cquest
#define cquest (quest[QUEST_ULTRA_EVIL])

bool quest_ultra_evil_init_hook(int q)
{
	return (FALSE);
}
tome-235-src/src/q_ultrag.c0000644000076400017500000002151311012107763013441 0ustar  dgdg/*
 * Here takes place the Good ultra ending
 */

#undef cquest
#define cquest (quest[QUEST_ULTRA_GOOD])

bool quest_ultra_good_move_hook(char *fmt)
{
	s32b y, x;
	cave_type *c_ptr;

	y = get_next_arg(fmt);
	x = get_next_arg(fmt);
	c_ptr = &cave[y][x];

	if (cquest.status == QUEST_STATUS_UNTAKEN)
	{
		bool old_quick_messages = quick_messages;

		if (quest[QUEST_MORGOTH].status < QUEST_STATUS_FINISHED) return (FALSE);

		/* The mirror of Galadriel */
		if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 23)) return (FALSE);

		quick_messages = FALSE;
		cmsg_print(TERM_L_BLUE, "You meet Galadriel.");
		cmsg_print(TERM_YELLOW, "'I still cannot believe this is all over.'");
		cmsg_print(TERM_YELLOW, "'Morgoth's reign of terror is over at last!'");
		cmsg_print(TERM_YELLOW, "'His spirit has been banished to the Void where he cannot do much harm.'");
		cmsg_print(TERM_YELLOW, "'We can never thank you enough, hero!'");
		cmsg_print(TERM_L_BLUE, "Although everything seems all right, Galadriel seems a little subdued.");
		cmsg_print(TERM_YELLOW, "'The spirit of Morgoth is not destroyed however -- only banished.'");
		cmsg_print(TERM_YELLOW, "'He can still control his allies left on Arda.'");
		cmsg_print(TERM_YELLOW, "'Maybe... maybe there could be a way to remove the threat of evil forever.'");
		cmsg_print(TERM_YELLOW, "'Somebody would have to go into the Void to do it.'");
		cmsg_print(TERM_YELLOW, "'But going there is certain death; we cannot ask it of anyone.'");
		cmsg_print(TERM_YELLOW, "'But you may choose, of your own free will, to attempt it...'");
		cmsg_print(TERM_L_BLUE, "Galadriel plainly presents the choice that now lies before you:");

		cmsg_print(TERM_YELLOW, "'You have earned the right to make whatever you wish of your future.'");
		cmsg_print(TERM_YELLOW, "'Become a ruler of Arda if you so desire; reign long, enjoying'");
		cmsg_print(TERM_YELLOW, "'the adulation of all, and have a happy life. Or, you can turn your'");
		cmsg_print(TERM_YELLOW, "'back on safety. Enter the Void, alone, to fight a hopeless battle'");
		cmsg_print(TERM_YELLOW, "'and face certain death.'");

		/* This is SO important a question that flush pending inputs */
		flush();

		if (!get_check("Will you stay on Arda and lead a happy life?"))
		{
			cmsg_print(TERM_YELLOW, "'So be it. I will open a portal to the Void.'");
			cmsg_print(TERM_YELLOW, "'But you must know this: the portal can only lead one way.'");
			cmsg_print(TERM_YELLOW, "'It will close once you enter, so as not to permit the horrors'");
			cmsg_print(TERM_YELLOW, "'that lurk in the Void to enter Arda. Your only way to come back'");
			cmsg_print(TERM_YELLOW, "'is to defeat the spirit of Morgoth, known as Melkor.'");
			cmsg_print(TERM_YELLOW, "'You will not be able to recall back either.'");
			cmsg_print(TERM_YELLOW, "'You can still choose to retire; it is not too late'");
			cmsg_print(TERM_YELLOW, "'to save your life.'");
			cmsg_print(TERM_YELLOW, "'One last thing: It is quite certain that Melkor will have erected'");
			cmsg_print(TERM_YELLOW, "'powerful magical barriers around him. You certainly will'");
			cmsg_print(TERM_YELLOW, "'need to find a way to break them to get to him.'");

			/* Create the entrance */
			cave_set_feat(y - 5, x, FEAT_MORE);
			cave[y - 5][x].special = 11;

			/* Continue the plot */
			cquest.status = QUEST_STATUS_TAKEN;
			cquest.init(QUEST_ULTRA_GOOD);
		}
		quick_messages = old_quick_messages;

		return TRUE;
	}

	return FALSE;
}

bool quest_ultra_good_stair_hook(char *fmt)
{
	cptr dir;

	dir = get_next_arg_str(fmt);

	if (dungeon_type != DUNGEON_VOID)
		return FALSE;

	/* Cant leave */
	if ((!strcmp(dir, "up")) && (dun_level == 128))
	{
		cmsg_print(TERM_YELLOW, "The portal to Arda is now closed.");
		return TRUE;
	}
	/* there is no coming back */
	if ((!strcmp(dir, "up")) && (dun_level == 150))
	{
		cmsg_print(TERM_YELLOW, "The barrier seems to be impenetrable from this side.");
		cmsg_print(TERM_YELLOW, "You will have to move on.");
		return TRUE;
	}
	/* Cant enter without the flame imperishable */
	if ((!strcmp(dir, "down")) && (dun_level == 149))
	{
		int i;
		bool ultimate = FALSE;

		/* Now look for an ULTIMATE artifact, that is, one imbued with the flame */
		for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
		{
			u32b f1, f2, f3, f4, f5, esp;
			object_type *o_ptr = &p_ptr->inventory[i];

			if (!o_ptr->k_idx) continue;

			/* Examine the gloves */
			object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);

			if (f4 & TR4_ULTIMATE)
			{
				ultimate = TRUE;
				break;
			}
		}

		if (!ultimate)
		{
			cmsg_print(TERM_YELLOW, "It seems the level is protected by an impassable barrier of pure magic.");
			cmsg_print(TERM_YELLOW, "Only the most powerful magic could remove it. You will need to use");
			cmsg_print(TERM_YELLOW, "the Flame Imperishable to pass. The source of Eru Iluvatar's own power.");
			return TRUE;
		}
		else
		{
			cmsg_print(TERM_YELLOW, "The power of the Flame Imperishable shatters the magical barrier.");
			cmsg_print(TERM_YELLOW, "The way before you is free.");
		}
	}

	return FALSE;
}

bool quest_ultra_good_recall_hook(char *fmt)
{
	if ((dungeon_type != DUNGEON_VOID) && (dungeon_type != DUNGEON_NETHER_REALM))
		return FALSE;

	cmsg_print(TERM_YELLOW, "You cannot recall. The portal to Arda is closed.");
	return TRUE;
}

bool quest_ultra_good_death_hook(char *fmt)
{
	s32b m_idx = get_next_arg(fmt);

	monster_type *m_ptr = &m_list[m_idx];

	/* Melkor is dead! */
	if (m_ptr->r_idx == 1044)
	{
		/* Total winner */
		total_winner = WINNER_ULTRA;
		has_won = WINNER_ULTRA;
		quest[QUEST_ULTRA_GOOD].status = QUEST_STATUS_FINISHED;

		/* Redraw the "title" */
		p_ptr->redraw |= (PR_TITLE);

		/* Congratulations */
		cmsg_print(TERM_L_GREEN, "****** CONGRATULATIONS ******");
		cmsg_print(TERM_L_GREEN, "You have done more than the impossible. You ended the threat of");
		cmsg_print(TERM_L_GREEN, "Melkor forever. Thanks to you, Arda will live in eternal peace.");
		cmsg_print(TERM_L_GREEN, "You feel the spirit of Eru touching you. You feel your spirit rising!");
		cmsg_print(TERM_L_GREEN, "Before you, a portal to Arda opens. You can now come back to your world");
		cmsg_print(TERM_L_GREEN, "and live happily ever after.");
		cmsg_print(TERM_L_GREEN, "What you do now is up to you, but your deeds shall ever be remembered.");
		cmsg_print(TERM_L_GREEN, "You may retire (commit suicide) when you are ready.");

		/* Create the entrance */
		cave_set_feat(p_ptr->py, p_ptr->px, FEAT_MORE);

		/* Remove now used hook */
		del_hook(HOOK_MONSTER_DEATH, quest_ultra_good_death_hook);
		process_hooks_restart = TRUE;

		/* End plot */
		*(quest[QUEST_ULTRA_GOOD].plot) = QUEST_NULL;
	}

	/* Tik'svvrzllat is dead! */
	if (m_ptr->r_idx == 1032)
	{
		int i;

		/* Get local object */
		object_type forge, *q_ptr = &forge;

		/* Mega-Hack -- Prepare to make the Flame Imperishable */
		object_prep(q_ptr, lookup_kind(TV_JUNK, 255));

		/* Mega-Hack -- Actually create the Flame Imperishable */
		k_allow_special[296] = TRUE;
		apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
		k_allow_special[296] = FALSE;

		/* Identify it fully */
		object_aware(q_ptr);
		object_known(q_ptr);

		/* Mark the item as fully known */
		q_ptr->ident |= (IDENT_MENTAL);

		/* Find a space */
		for (i = 0; i < INVEN_PACK; i++)
		{
			/* Skip non-objects */
			if (!p_ptr->inventory[i].k_idx) break;
		}
		/* Arg, no space ! */
		if (i == INVEN_PACK)
		{
			char o_name[200];

			object_desc(o_name, &p_ptr->inventory[INVEN_PACK - 1], FALSE, 0);

			/* Drop the item */
			inven_drop(INVEN_PACK - 1, 99, p_ptr->py, p_ptr->px, FALSE);

			cmsg_format(TERM_VIOLET, "You feel the urge to drop your %s to make room in your inventory.", o_name);
		}

		/* Carry it */
		cmsg_format(TERM_VIOLET, "You feel the urge to pick up the Flame Imperishable.");
		inven_carry(q_ptr, FALSE);
	}
	return (FALSE);
}
bool quest_ultra_good_dump_hook(char *fmt)
{
	if (quest[QUEST_ULTRA_GOOD].status >= QUEST_STATUS_TAKEN)
	{
		/* Ultra winner ! */
		if (total_winner == WINNER_ULTRA)
		{
			fprintf(hook_file, "\n You destroyed Melkor forever and have been elevated to the status of Vala by Eru Iluvatar.");
			fprintf(hook_file, "\n Arda will forever be free.");
		}
		else
		{
			/* Tried and failed */
			if (death)
			{
				fprintf(hook_file, "\n You tried to destroy Melkor forever, but died in the attempt.");
				fprintf(hook_file, "\n Arda will be quiet, but not free from evil.");
			}
		}
	}
	return (FALSE);
}


bool quest_ultra_good_init_hook(int q)
{
	if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_STAIR, quest_ultra_good_stair_hook, "ultrag_stair");
		add_hook(HOOK_RECALL, quest_ultra_good_recall_hook, "ultrag_recall");
		add_hook(HOOK_MONSTER_DEATH, quest_ultra_good_death_hook, "ultrag_death");
	}
	if (cquest.status == QUEST_STATUS_UNTAKEN)
	{
		add_hook(HOOK_MOVE, quest_ultra_good_move_hook, "ultrag_move");
	}
	add_hook(HOOK_CHAR_DUMP, quest_ultra_good_dump_hook, "ultrag_dump");
	return (FALSE);
}
tome-235-src/src/irc.c0000644000076400017500000001560611012107763012406 0ustar  dgdg/* File: irc.c */

/* Purpose: irc chat */

/*
 * Copyright (c) 2001 DarkGod, Andrew Sidwell
 *
 * This software may be copied and distributed for educational, research, and
 * not for profit purposes provided that this copyright and statement are
 * included in all such copies.
 */

#include "angband.h"

#define IRC_SERVER "irc.worldirc.org"
#define IRC_PORT "6667"
#define IRC_CHANNEL "#tome"

/*
 * By the way, CTCP's for unique kills and artefact finds would be nice to
 * have, for example:
 *
 * *pelpel finds Long Sword 'Ringil' (4d5) (+22,+25) (+10 to speed) :)
 */

ip_connection tome_irc_forge;
ip_connection *tome_irc = &tome_irc_forge;
bool irc_can_join = FALSE;
char irc_nick[30];
char irc_world[100];

void irc_connect()
{
	char buf[500], *s;
	int rnd_name = randint(999);

	if (tome_irc->connected) return;

	sprintf(irc_world, "%99s", IRC_CHANNEL);
	sprintf(irc_nick, "Dummy_%03d", rnd_name);
	get_string("Enter Nickname: ", irc_nick, 10);

	zsock.setup(tome_irc, IRC_SERVER, atoi(IRC_PORT), ZSOCK_TYPE_TCP, FALSE);
	zsock.open(tome_irc);
	zsock.write_simple(tome_irc, format("NICK %s\r\n", irc_nick));
	zsock.wait(tome_irc, 40);
	zsock.read_simple(tome_irc, buf, 500);
	s = strchr(buf, ':');
	zsock.write_simple(tome_irc, format("PONG %s\r\n", s));
	zsock.write_simple(tome_irc, format("USER tome 0 *BIRC :%s %d.%d.%d User\r\n",
	                                    game_module, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH));
#if 0 /* Pfft spoilsport */
	while (!irc_can_join)
		irc_poll();
#endif

	zsock.write_simple(tome_irc, format("JOIN %s\r\n", irc_world));

	cmsg_print(TERM_L_GREEN, "Connected to IRC");

	zsock.add_timer(irc_poll);
}

void irc_change_nick()
{
	return;
}

void irc_disconnect()
{
	if (!tome_irc->connected) return;
	irc_can_join = FALSE;

	irc_quit(format("%s %d.%d.%d", game_module, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH));

	cmsg_print(TERM_L_RED, "Disconnected from IRC");
}

void irc_disconnect_aux(char *str, bool message)
{
	if (!tome_irc->connected) return;
	irc_can_join = FALSE;

	irc_quit(str);

	if (message) cmsg_print(TERM_L_RED, "Disconnected from IRC");
}

void irc_emote(char *buf)
{
	char *b;
	char *base = "PRIVMSG %s :%cACTION %s%c\r\n";

	if (!tome_irc->connected) return;

	C_MAKE(b, strlen(buf) + strlen(base) + 1, char);
	sprintf(b, base, irc_world, 1, buf, 1);
	zsock.write_simple(tome_irc, b);
	sprintf(b, "* %s %s", irc_nick, buf);
	message_add(MESSAGE_IRC, b, TERM_YELLOW);
	C_FREE(b, strlen(buf) + strlen(base) + 1, char);
	fix_irc_message();
}

void irc_chat()
{
	char buf[80] = "";

	if (!tome_irc->connected) return;
	if (get_string("Say: ", buf, 80))
	{
		if (prefix(buf, "/me "))
		{
			irc_emote(buf + 4);
		}
		else if ((prefix(buf, "/join ")) && (buf[6] != '\0'))
		{
			zsock.write_simple(tome_irc, format("PART %s\r\n", irc_world));
			sprintf(irc_world, "%99s", buf + 6);
			zsock.write_simple(tome_irc, format("JOIN %s\r\n", irc_world));
		}
		else
		{
			zsock.write_simple(tome_irc, format("PRIVMSG %s :%s\r\n", irc_world, buf /*, 3, irc_world */));
			message_add(MESSAGE_IRC, format("<%s> #w%s", irc_nick, buf), TERM_L_BLUE);
			fix_irc_message();
		}
	}
}

#define TERM_CTCP	TERM_L_GREEN
#define TERM_SERVER	TERM_L_BLUE
#define TERM_CHAT1	TERM_YELLOW
#define TERM_CHAT2	TERM_WHITE

void irc_poll()
{
	char buf[5000], *next, *nick, *space;

	if (tome_irc->connected && zsock.can_read(tome_irc))
	{
		zsock.read_simple(tome_irc, buf, 2500);

		if (prefix(buf, "PING "))
		{
			message_add(MESSAGE_IRC, format("*** Recieved a PING request from server %s.", buf + 6), TERM_SERVER);
			zsock.write_simple(tome_irc, format("PONG %s\r\n", buf + 5));
			return;
		}
		if (*buf != ':') return;
		nick = buf + 1;

		space = strchr(nick, ' ');
		if (space)
		{
			if (prefix(space + 1, "376"))
				irc_can_join = TRUE;
		}

		if (prefix(nick, "_"))
		{
			nick = buf + 6;
		}

		next = strchr(nick, '!');
		if (next == NULL) return;
		*next = '\0';
		next++;
		next = strchr(next, ' ');
		if (next == NULL) return;
		next++;
		if (prefix(next, "PRIVMSG"))
		{
			next = strchr(next, ':');
			if (next == NULL) return;
			*next = '\0';
			next++;
			if (*next == 1)
			{
				next++;
				if (prefix(next, "ACTION"))
				{
					u32b i = 0, j = 0, max = (79 - strlen(nick) - 3);
					bool nicked = FALSE;
					char tmp[90];

					next += 7;
					if (strlen(next)) next[strlen(next) - 1] = '\0';

					while (next[i])
					{
						tmp[j++] = next[i++];
						if (j > max)
						{
							tmp[j] = '\0';
							if (nicked)
								message_add(MESSAGE_IRC, format("%s", tmp), TERM_CHAT1);
							else
								message_add(MESSAGE_IRC, format("* %s %s", nick, tmp), TERM_CHAT1);
							nicked = TRUE;
							j = 0;
						}
					}
					if (j > 0)
					{
						tmp[j] = '\0';
						if (nicked)
							message_add(MESSAGE_IRC, format("%s", tmp), TERM_CHAT1);
						else
							message_add(MESSAGE_IRC, format("* %s %s", nick, tmp), TERM_CHAT1);
					}

					fix_irc_message();
				}
				else if (prefix(next, "PING"))
				{
					message_add(MESSAGE_IRC, format("*** PING request from %s", nick), TERM_CTCP);
					fix_irc_message();

					zsock.write_simple(tome_irc, format("NOTICE %s :%cPING %d%c\r\n", nick, 1, next, 1));
				}
				else if (prefix(next, "NICK"))
				{
					message_add(MESSAGE_IRC, format("*** NICK request from %s", nick), TERM_CTCP);
					fix_irc_message();

					zsock.write_simple(tome_irc, format("NOTICE %s :%cNICK %s%c\r\n", nick, 1, irc_nick, 1));
				}
				else if (prefix(next, "VERSION"))
				{
					message_add(MESSAGE_IRC, format("*** VERSION request from %s", nick), TERM_CTCP);
					fix_irc_message();

					zsock.write_simple(tome_irc, format("NOTICE %s :%cVERSION %s %d.%d.%d%c\r\n", nick, 1, game_module, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, 1));
				}
			}
			else
			{
				u32b i = 0, j = 0, max = (79 - strlen(nick) - 3);
				bool nicked = FALSE;
				char tmp[90];

				while (next[i])
				{
					tmp[j++] = next[i++];
					if (j > max)
					{
						tmp[j] = '\0';
						if (nicked)
							message_add(MESSAGE_IRC, format("#w%s", tmp), TERM_CHAT1);
						else
							message_add(MESSAGE_IRC, format("#y<%s> #w%s", nick, tmp), TERM_CHAT1);
						nicked = TRUE;
						j = 0;
					}
				}
				if (j > 0)
				{
					tmp[j] = '\0';
					if (nicked)
						message_add(MESSAGE_IRC, format("#w%s", tmp), TERM_CHAT1);
					else
						message_add(MESSAGE_IRC, format("#y<%s> #w%s", nick, tmp), TERM_CHAT1);
				}
				fix_irc_message();
			}
		}
		if (prefix(next, "JOIN"))
		{
			message_add(MESSAGE_IRC, format("%s has entered the Chatroom", nick), TERM_YELLOW);
			fix_irc_message();
		}
		if (prefix(next, "QUIT"))
		{
			next = strchr(next, ':');
			if (next == NULL) return;
			*next = '\0';
			next++;
			message_add(MESSAGE_IRC, format("%s has quit the Chatroom (%s)", nick, next), TERM_YELLOW);
			fix_irc_message();
		}
	}
}


void irc_quit(char *str)
{
	char buf[300];

	zsock.remove_timer(irc_poll);

	sprintf(buf, "QUIT :%s\r\n", str);

	zsock.write_simple(tome_irc, buf);
	zsock.close(tome_irc);
	zsock.unsetup(tome_irc);
}
tome-235-src/src/makefile.ami0000644000076400017500000000603611012107763013727 0ustar  dgdg# Smakefile
#
# Amiga SAS/C 6.50

all: angband

# Object files
OBJS = \
  z-util.o z-virt.o z-form.o z-rand.o z-term.o z-sock.o \
  variable.o tables.o util.o cave.o cmovie.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  xtra1.o xtra2.o spells1.o spells2.o help.o \
  melee1.o melee2.o save.o files.o notes.o \
  status.o randart.o gods.o modules.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  store.o birth.o loadsave.o ghost.o powers.o \
  wizard1.o wizard2.o wild.o plots.o \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o \
  bldg.o levels.o squeltch.o \
  main-ami.o sound-ami.o main.o

# Header files
HDRS = \
  h-basic.h \
  h-define.h h-type.h h-system.h h-config.h

# Include files
INCS = \
  angband.h \
  config.h defines.h types.h externs.h \
  z-term.h z-rand.h z-util.h z-virt.h z-form.h z-sock.h$(HDRS)

# Linking
angband: $(OBJS)
  echo Linking
  slink QUIET WITH angband.lnk

# Compiling
.c.o:
  echo Compiling $*.c
  sc DEFINE AMIGA DEFINE USE_AMI $*

# Dependencies
birth.o: birth.c $(INCS)
borg-aux.o: borg-aux.c $(INCS) borg-aux.h borg-ext.h
borg-aux.o: borg-obj.h borg-map.h borg.h
borg-ben.o: borg-ben.c $(INCS) borg-ben.h borg-aux.h borg-ext.h
borg-ben.o: borg-obj.h borg-map.h borg.h
borg-ext.o: borg-ext.c $(INCS) borg-ext.h
borg-ext.o: borg-obj.h borg-map.h borg.h
borg-obj.o: borg-obj.c $(INCS) borg-obj.h borg.h
borg-map.o: borg-map.c $(INCS) borg-map.h borg.h
borg.o: borg.c $(INCS) borg.h
cave.o: cave.c $(INCS)
cmd1.o: cmd1.c $(INCS)
cmd2.o: cmd2.c $(INCS)
cmd3.o: cmd3.c $(INCS)
cmd4.o: cmd4.c $(INCS)
cmd5.o: cmd5.c $(INCS)
cmd6.o: cmd6.c $(INCS)
cmd7.o: cmd7.c $(INCS)
cmovie.o: cmovie.c $(INCS)
dungeon.o: dungeon.c $(INCS)
files.o: files.c $(INCS)
generate.o: generate.c $(INCS)
gen_evol.o: gen_evol.c $(INCS)
gen_maze.o: gen_maze.c $(INCS)
init1.o: init1.c $(INCS)
init2.o: init2.c $(INCS)
loadsave.o: loadsave.c $(INCS)
main-ami.o: main-ami.c $(INCS) sound-ami.h
main.o: main.c $(INCS)
melee1.o: melee1.c $(INCS)
melee2.o: melee2.c $(INCS)
monster1.o: monster1.c $(INCS)
monster2.o: monster2.c $(INCS)
monster3.o: monster3.c $(INCS)
notes.o: notes.c $(INCS)
object1.o: object1.c $(INCS)
object2.o: object2.c $(INCS)
powers.o: powers.c $(INCS)
help.o: help.c $(INCS)
randart.o: randart.c $(INCS)
tarps.o: traps.c $(INCS)
bldg.o: bldg.c $(INCS)
plots.o: plots.c $(INCS)
sound-ami.o: sound-ami.c sound-ami.h
spells1.o: spells1.c $(INCS)
spells2.o: spells2.c $(INCS)
status.o: status.c $(INCS)
store.o: store.c $(INCS)
tables.o: tables.c $(INCS)
util.o: util.c $(INCS)
variable.o: variable.c $(INCS)
wizard1.o: wizard1.c $(INCS)
wizard2.o: wizard2.c $(INCS)
xtra1.o: xtra1.c $(INCS)
xtra2.o: xtra2.c $(INCS)
gods.o: gods.c $(INCS)
levels.o: levels.c $(INCS)
ghost.o: ghost.c $(INCS)
squeltch.o: squeltch.c $(INCS)
wild.o: wild.c $(INCS)
modules.o: modules.c $(INCS)
z-form.o: z-form.c $(HDRS) z-form.h z-util.h z-virt.h
z-rand.o: z-rand.c $(HDRS) z-rand.h
z-term.o: z-term.c $(HDRS) z-term.h z-virt.h
z-util.o: z-util.c $(HDRS) z-util.h
z-virt.o: z-virt.c $(HDRS) z-virt.h z-util.h
z-sock.o: z-sock.c $(HDRS) z-sock.h
tome-235-src/src/makefile.bcc0000644000076400017500000001071211012107763013704 0ustar  dgdg###################################################################
#
#  makefile.bcc - Angband makefile for Borland C++ 5.5 (Win32)
#
###################################################################


###################################################################
#
#       Borland specific directives ---
#
.AUTODEPEND

###################################################################
#
# Set tool and version names:

CPP        = bcc32
LINKER     = ilink32
RC         = brc32

###################################################################
#
# Name of the *.exe-file

EXE_FILE = tome.exe
TOLUA    = tolua.exe

###################################################################
#
# Debug mode (un-comment for debugging)

# DBGOPT= -v -N -x -xp


###################################################################
#
# Set any compiler options

CCOPTS = -jb -j1 -Hc -tW -lGn -w- \
	-D_WIN32_WINNT=0x0400 -DWINVER=0x0400 \
	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA \
	-I$(BCCDIR)\include -I. -Ilua -DUSE_LUA \
        -DUSE_PRECISE_CMOVIE \
	-DUSE_WINSOCK \
        -DIRC_SERVER=\"irc.worldirc.org\" -DIRC_PORT=\"6667\" -DIRC_CHANNEL=\"\#tome\"

# Compile flags:
CPPFLAGS= $(CCOPTS) $(DBGOPT)

######################## Targets ##################################

OBJ = \
	gods.obj \
        skills.obj \
        irc.obj \
	birth.obj \
	bldg.obj \
	cave.obj \
	cmd1.obj \
	cmd2.obj \
	cmd3.obj \
	cmd4.obj \
	cmd5.obj \
	cmd6.obj \
	cmd7.obj \
	cmovie.obj \
	dungeon.obj \
	files.obj \
	generate.obj \
        gen_maze.obj \
        gen_evol.obj \
	ghost.obj \
	help.obj \
	init1.obj \
	init2.obj \
	levels.obj \
	loadsave.obj \
	lua_bind.obj \
	main-win.obj \
	main.obj \
	melee1.obj \
	melee2.obj \
        modules.obj \
	monster1.obj \
	monster2.obj \
	monster3.obj \
	notes.obj \
	object1.obj \
	object2.obj \
	plots.obj \
	powers.obj \
	randart.obj \
	readdib.obj \
	script.obj \
	spells1.obj \
	spells2.obj \
	squeltch.obj \
	status.obj \
	store.obj \
	tables.obj \
	traps.obj \
	util.obj \
	variable.obj \
	wild.obj \
	wizard1.obj \
	wizard2.obj \
	xtra1.obj \
	xtra2.obj \
	z-form.obj \
	z-rand.obj \
	z-term.obj \
	z-util.obj \
	z-virt.obj \
        z-sock.obj \
	w_mnster.obj \
	w_obj.obj \
	w_play_c.obj \
	w_player.obj \
	w_quest.obj \
	w_spells.obj \
	w_util.obj \
	w_z_pack.obj \
        w_dun.obj \
	$(TOLUAOBJS)

TOLUAOBJS = \
	lua\lapi.obj \
	lua\lauxlib.obj \
	lua\lbaselib.obj \
	lua\lcode.obj \
	lua\ldblib.obj \
	lua\ldebug.obj \
	lua\ldo.obj \
	lua\lfunc.obj \
	lua\lgc.obj \
	lua\liolib.obj \
	lua\llex.obj \
	lua\lmem.obj \
	lua\lobject.obj \
	lua\lparser.obj \
	lua\lstate.obj \
	lua\lstring.obj \
	lua\lstrlib.obj \
	lua\ltable.obj \
	lua\ltests.obj \
	lua\ltm.obj \
	lua\lundump.obj \
	lua\lvm.obj \
	lua\lzio.obj \
	lua\tolua.obj \
	lua\tolua_bd.obj \
	lua\tolua_eh.obj \
	lua\tolua_gp.obj \
	lua\tolua_lb.obj \
	lua\tolua_rg.obj \
	lua\tolua_tm.obj \
	lua\tolua_tt.obj \
	lua\tolualua.obj \

all : $(EXE_FILE)
	copy $(EXE_FILE) ..

clean:
	-@if exist *.obj del *.obj >nul
	-@if exist lua\*.obj del lua\*.obj >nul
	-@if exist *.exe del *.exe >nul
	-@if exist *.res del *.res >nul
	-@if exist *.tds del *.tds >nul
	-@if exist *.ilc del *.ilc >nul
	-@if exist *.ild del *.ild >nul
	-@if exist *.ilf del *.ilf >nul
	-@if exist *.ils del *.ils >nul

install: $(EXE_FILE)
	copy $(EXE_FILE) ..


########################### Explicit Rules ########################
$(EXE_FILE): $(OBJ) angband.res
	$(LINKER) -aa -L$(BCCDIR)\lib -x $(OBJ) c0w32.obj, $(EXE_FILE),, cw32.lib import32.lib,, angband.res

$(TOLUA): $(TOLUAOBJS)
        $(LINKER) -aa -L$(BCCDIR)\lib -x $(TOLUAOBJS) c0x32.obj, tolua.exe,, cw32.lib import32.lib

angband.res: angband.rc
	$(RC) -r angband.rc

w_mnster.c: monster.pkg $(TOLUA)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUA)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUA)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUA)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUA)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUA)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUA)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUA)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

########################### Implicit Rules ########################
.c.obj:
	$(CPP) $(CPPFLAGS) -c -o$*.obj $*.c

.obj.exe:
	$(CPP) $(CPPFLAGS) $<

tome-235-src/src/makefile.bsd0000644000076400017500000002121411012107763013724 0ustar  dgdg# This is based on Makefile.std but stripped and tuned for FreeBSD (and
# presumably will cooperate with other BSDs)

# Comment out this line if you don't want the IRC support
IRC=TRUE

## Installation locations and such
##
## LIBDIR, BINDIR and OWNER should be set appropriately for
## multiuser installations.
##
## If you want to keep it private or don't have root privilege
## required by "make install", set LIBDIR to ./lib/ or an absolute
## path pointing to your lib directory, and don't run "make install".
##
## NOTE: If LIBDIR is set to ./lib/ , you have to cd to parent directory
## of lib before you start the game.
##

PREFIX ?= /usr/local
X11BASE ?= /usr/X11R6

# Where lib/ files goes
LIBDIR = $(PREFIX)/share/tome

# Where ToME binary goes
BINDIR = $(PREFIX)/bin

# The game will run suid to this user
OWNER = root
GROUP = games
FILE_MODE = 0664

## Some "system" definitions
##
## No changes are needed to compile a version that will run on both
## X11 and Curses, in debugging mode, with maximal warnings, on many
## normal Unix machines of the Sun OS variety (non-solaris).
##
## To use an "alternative" definition, simply "modify" (or "replace")
## the definition below with one that you like.  For example, you can
## change the compiler to "cc", or remove the "debugging" options, or
## remove the X11 or Curses support, etc, as desired.
##
## See also "config.h" and "h-config.h" for important information.
##
## Some "examples" are given below, they can be used by simply
## removing the FIRST column of "#" signs from the "block" of lines
## you wish to use, and commenting out "standard" block below.
##
## This is not intended to be a "good" Makefile, just a "simple" one.
##


# This is my compiler of choice, it seems to work most everywhere
#
CC ?= cc

# Standard version (see main-x11.c and main-gcu.c)
#
# This version supports both "X11" and "curses" in a single executable.
#
# You may have to add various X11 include/library directories to the
# "INCLUDES", if your machine places files in a weird location
# (e.g. -I/usr/X11R6/include, as is almost always the case with
# linux and *BSD). Since we have seen many linux users -- arguably
# the largest unix population -- confused by this, and adding this
# usually doesn't hurt, the default rule has been changed to search
# for /usr/X11R6/include.
#
# You may be able to remove "-ltermcap" on some machines (ex: Solaris).
#
# You may have to replace "-lcurses" with "-lncurses" to use the
# "new curses" library instead of the "old curses" library, and
# you may have to add "-I/usr/include/ncurses" to the "INCLUDES",
# and/or "-DUSE_NCURSES" to "DEFINES".
#
# See "main-gcu.c" and "config.h" for some optional "curses" defines,
# including "USE_GETCH" and "USE_CURS_SET".  Note that "config.h" will
# attempt to "guess" at many of these flags based on your system.
#
COPTS = -Wall -g
INCLUDES = -I$(X11BASE)/include
DEFINES = -DUSE_X11 -DUSE_GCU\
	-DUSE_EGO_GRAPHICS -DUSE_TRANSPARENCY -DSUPPORT_GAMMA \
	-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK -DFILE_MODE=$(FILE_MODE)
LIBS = -lX11 -lcurses -L$(X11BASE)/lib


### End of configurable section ###

#
# The "source" and "object" files.
#

BASESRCS = \
  main-gtk.c main-gcu.c main-x11.c main-xaw.c main-sdl.c \
  z-rand.c z-util.c z-form.c z-virt.c z-term.c z-sock.c \
  variable.c tables.c plots.c util.c cave.c dungeon.c \
  melee1.c melee2.c modules.c \
  object1.c object2.c randart.c squeltch.c traps.c \
  monster1.c monster2.c monster3.c ghost.c \
  xtra1.c xtra2.c skills.c powers.c gods.c \
  spells1.c spells2.c \
  status.c files.c notes.c loadsave.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c \
  help.c \
  generate.c gen_maze.c gen_evol.c wild.c levels.c store.c bldg.c \
  cmovie.c irc.c \
  wizard2.c init2.c birth.c wizard1.c init1.c main.c

BASEOBJS = \
  main-gtk.o main-gcu.o main-x11.o main-xaw.o main-sdl.o \
  z-rand.o z-util.o z-form.o z-virt.o z-term.o z-sock.o \
  variable.o tables.o plots.o util.o cave.o dungeon.o \
  melee1.o melee2.o modules.o \
  object1.o object2.o randart.o squeltch.o traps.o \
  monster1.o monster2.o monster3.o ghost.o \
  xtra1.o xtra2.o skills.o powers.o gods.o \
  spells1.o spells2.o \
  status.o files.o notes.o loadsave.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  help.o \
  generate.o gen_maze.o gen_evol.o wild.o levels.o store.o bldg.o \
  cmovie.o irc.o \
  wizard2.o init2.o birth.o wizard1.o init1.o main.o

LUASRCS = \
  script.c lua_bind.c \
  w_util.c w_player.c w_z_pack.c w_obj.c w_mnster.c w_spells.c w_quest.c w_play_c.c w_dun.c

TOLUASRCS = \
  lua/lapi.c lua/lcode.c lua/ldebug.c lua/ldo.c lua/lfunc.c lua/lgc.c \
  lua/llex.c lua/lmem.c lua/lobject.c lua/lparser.c lua/lstate.c lua/lstring.c \
  lua/ltable.c lua/ltests.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c \
  lua/lauxlib.c lua/lbaselib.c lua/ldblib.c lua/liolib.c lua/lstrlib.c \
  lua/tolua_lb.c lua/tolua_rg.c lua/tolua_tt.c lua/tolua_tm.c lua/tolua_gp.c \
  lua/tolua_eh.c lua/tolua_bd.c

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

#
# Base sources and objects
#

SRCS = $(BASESRCS)
OBJS = $(BASEOBJS)


#
# Compiler options
#

CFLAGS += $(COPTS) $(INCLUDES) $(DEFINES) -DDEFAULT_PATH=\"$(LIBDIR)\"


#
# Lua support
#

INCLUDES += -Ilua -I.
DEFINES += -DUSE_LUA
SRCS = $(LUASRCS) $(TOLUASRCS) $(BASESRCS)
OBJS = $(LUAOBJS) $(TOLUAOBJS) $(BASEOBJS)

# Force recreation of stub files when lua source files are updated
# To be included in dependency rules
TOLUADEP = $(TOLUA) $(TOLUASRCS) lua/tolua.c lua/tolualua.c

#
# IRC support
#

IRC_SERVER=irc.worldirc.org
IRC_PORT=6667
IRC_CHANNEL=\#tome

DEFINES += \
	-DIRC_SERVER=\"$(IRC_SERVER)\" \
	-DIRC_PORT=\"$(IRC_PORT)\" \
	-DIRC_CHANNEL=\"$(IRC_CHANNEL)\"


# Build the binary. The new base target.
#

TARGET = tome

TOLUA = ./tolua

default: $(TOLUA) $(TARGET)
	@echo "*** Note: In order to use the install rule, which now actually"
	@echo "*** handles the installation of the library dir, you need to edit"
	@echo "*** this makefile, going to the top and making sure LIBDIR suits"
	@echo "*** your desired install dir properly. The LIBRARY_DIR you used"
	@echo "*** to set in config.h is now ignored and obsolete with respect"
	@echo "*** to this makefile. Note that if you edit this makefile, you may"
	@echo "*** need to recompile so all the files that reference those defines"
	@echo "*** notice the changes."

$(TARGET): $(OBJS)
	$(CC) $(PROFILELDFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(PROFILELDFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)

#
# An install rule.
#
mini_install: default
	cp -f $(TARGET) ..

install: default
	[ -d $(LIBDIR) ] || mkdir -p $(LIBDIR)
	[ -d $(BINDIR) ] || mkdir -p $(BINDIR)
	cp -r ../lib/* $(LIBDIR)
	chown -R $(OWNER):$(GROUP) $(LIBDIR)
	chmod -R g+w $(LIBDIR)
	cp -f $(TARGET) $(BINDIR)/$(TARGET)
	strip $(BINDIR)/$(TARGET)
	chown $(OWNER):$(GROUP) $(BINDIR)/$(TARGET)
	chmod 2755 $(BINDIR)/$(TARGET)

# old-install: $(TARGET)
#	cp $(TARGET) ..


#
# Clean up old junk
#

clean:
	rm -f *.bak *.o lua/*.o  w_*.c


#
# Generate dependancies automatically
#

depend:
	makedepend $(INCLUDES) $(DEFINES) -D__MAKEDEPEND__ $(SRCS)

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c


#
# Quests
#
plots.o: q_rand.c q_main.c q_one.c q_ultrag.c q_ultrae.c \
	q_thief.c q_hobbit.c q_nazgul.c q_troll.c q_wight.c \
	q_spider.c q_poison.c \
	q_eol.c q_nirna.c q_invas.c \
	q_betwen.c \
	q_narsil.c q_shroom.c q_thrain.c q_wolves.c q_dragons.c q_haunted.c q_evil.c

#
# Lua library compilation rules
#

w_mnster.c: monster.pkg $(TOLUADEP)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUADEP)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUADEP)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUADEP)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUADEP)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUADEP)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUADEP)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUADEP)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

# DO NOT DELETE THIS LINE - make depend depends on it.
tome-235-src/src/makefile.cyg0000644000076400017500000002606511012107763013747 0ustar  dgdg# This is a makefile for the Cygwin tools which may
# be downloaded by following the links from the URL:
# http://sources.redhat.com/cygwin/
#
# To compile with this makefile, rename it from 'makefile.cyg'
# to 'makefile', then enter the src directory and type
# 'make install'.

##
## Before you type "make depend; make", please follow these three steps.
##
## 1. Lua-support and GNU Make ifdef's
##
## The ifdef ... endif struct may not be supported by 'make'
## you are using.  GNU make does and Berkeley make doesn't, for example.
## If it doesn't, you can still manually enable/disable them with minimum
## amount of effort:
## (1) Search for lines containing ifdef and endif (one occurence for each)
## (2) Comment these lines out
## (3-optional) Comment out lines surrounded by these if you are
##     *not* going to compile the game with Lua scripting enabled.
##

# Comment out this line if you don't want Lua scripting
LUA=TRUE

#IRCARGS = -DIRC_SERVER=\"irc.worldirc.org\" -DIRC_PORT=\"6667\" -DIRC_CHANNEL=\"\#tome\"



##
## 2. Installation locations and such
##
## LIBDIR, BINDIR and OWNER should be set appropriately for
## multiuser installations.
##
## If you want to keep it private or don't have root privilege
## required by "make install", set LIBDIR to ./lib/ or an absolute
## path pointing to your lib directory, and don't run "make install".
##
## NOTE: If LIBDIR is set to ./lib/ , you have to cd to parent directory
## of lib before you start the game.
##

# Where lib/ files goes
#LIBDIR = /usr/lib/games/pernband/
# Sysadmins of commercial Unix and/or BSD might prefer this
#LIBDIR = /usr/local/lib/pernband/
# If you like the old default, use this one
LIBDIR = ./lib/
# Another example: single user installation using absolute path
#LIBDIR = /home/myloginname/lib/pern/


# Where PernAngband binary goes
#BINDIR = /usr/local/games
# Another common location
#BINDIR = /usr/local/bin

# The game will run suid to this user
#OWNER = games

##
## 3. Some "system" definitions
##
## No changes are needed to compile a version that will run on both
## X11 and Curses, in debugging mode, with maximal warnings, on many
## normal Unix machines of the Sun OS variety (non-solaris).
##
## To use an "alternative" definition, simply "modify" (or "replace")
## the definition below with one that you like.  For example, you can
## change the compiler to "cc", or remove the "debugging" options, or
## remove the X11 or Curses support, etc, as desired.
##
## See also "config.h" and "h-config.h" for important information.
##
## Some "examples" are given below, they can be used by simply
## removing the FIRST column of "#" signs from the "block" of lines
## you wish to use, and commenting out "standard" block below.
##
## This is not intended to be a "good" Makefile, just a "simple" one.
##


#
# This is my compiler of choice, it seems to work most everywhere
#
CC = gcc

#
# resource complier
#

WRES = windres

#
# Standard version (see main-x11.c and main-gcu.c)
#
# This version supports both "X11" and "curses" in a single executable.
#
# You may have to add various X11 include/library directories to the
# "INCLUDES", if your machine places files in a weird location
# (e.g. -I/usr/X11R6/include, as is almost always the case with
# linux and *BSD). Since we have seen many linux users -- arguably
# the largest unix population -- confused by this, and adding this
# usually doesn't hurt, the default rule has been changed to search
# for /usr/X11R6/include.
#
# You may be able to remove "-ltermcap" on some machines (ex: Solaris).
#
# You may have to replace "-lcurses" with "-lncurses" to use the
# "new curses" library instead of the "old curses" library, and
# you may have to add "-I/usr/include/ncurses" to the "INCLUDES",
# and/or "-DUSE_NCURSES" to "DEFINES".
#
# See "main-gcu.c" and "config.h" for some optional "curses" defines,
# including "USE_GETCH" and "USE_CURS_SET".  Note that "config.h" will
# attempt to "guess" at many of these flags based on your system.
#
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_GCU
#LIBS = -lX11 -lcurses -L/usr/X11R6/lib


##
## For cygwin
##
COPTS = -s -Wall -mno-cygwin -O2 -fno-strength-reduce
INCLUDES =
DEFINES = -DWINDOWS -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA \
	-DUSE_PRECISE_CMOVIE \
        -DUSE_WINSOCK \
        $(IRCARGS)

LIBS = -mno-cygwin -mwindows -e _mainCRTStartup -lwinmm -lwsock32


##
## Variation -- Only support "main-gtk.c" (not "main-gcu.c, main-x11.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = `gtk-config --cflags`
#DEFINES = -DUSE_GTK -DUSE_TRANSPARENCY
#LIBS = -lX11 -L/usr/X11R6/lib `gtk-config --libs`

##
## Variation -- Only support "main-x11.c" (not "main-gcu.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11
#LIBS = -lX11 -L/usr/X11R6/lib


##
## Variation -- Only support "main-gcu.c" (not "main-x11.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap


##
## Variation -- Use "main-xaw.c" instead of "main-x11.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_XAW -DUSE_GCU
#LIBS = -lXaw -lXmu -lXt -lX11 -lcurses -ltermcap -L/usr/X11R6/lib


##
## Variation -- Use "main-cap.c" instead of "main-gcu.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_CAP
#LIBS = -lX11 -ltermcap


##
## Variation -- Only work on simple vt100 terminals
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_CAP -DUSE_HARDCODE


##
## Variation -- this might work for Linux 1.1.93 using ncurses-1.8.7.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU
#LIBS = -L/usr/X11R6/lib -lX11 -lncurses


##
## Variation -- this might work better than the suggestion above
##
#COPTS = -Wall -O2 -fomit-frame-pointer
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_TPOSIX -DUSE_CURS_SET
#LIBS = -lX11 -lncurses
#LDFLAGS = -s


##
## Variation -- compile for FreeBSD with ncurses
## -- BSD curses gives you B&W display.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_NCURSES
#LIBS = -L/usr/X11R6/lib -lX11 -lncurses


##
## Variation -- compile for Solaris
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSOLARIS
#LIBS = -lX11 -lsocket -lcurses


##
## Variation -- compile for SGI Indigo runnig Irix
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSGI
#LIBS = -lX11 -lcurses -ltermcap -lsun



##
## Variation -- compile for Dec ALPHA OSF/1 v2.0
##
#CC     = cc
##COPTS = -std -O -g3 -Olimit 4000
#COPTS = -std -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU
#LIBS   = -lX11 -lcurses -ltermcap -lrpcsvc


##
## Variation -- compile for Interactive Unix (ISC) systems
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DISC
#LIBS = -lX11 -lcurses -lnsl_s -linet -lcposix


##
## Variation -- Support fat binaries under NEXTSTEP
##
#COPTS = -Wall -O1 -pipe -g -arch m68k -arch i386
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap


### End of configurable section ###

#
# The "source" and "object" files.
#

BASESRCS = \
  z-util.c z-virt.c z-form.c z-rand.c z-term.c z-sock.c \
  variable.c tables.c util.c cave.c cmovie.c \
  object1.c object2.c traps.c monster1.c monster2.c monster3.c \
  xtra1.c xtra2.c spells1.c spells2.c \
  melee1.c melee2.c loadsave.c files.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c \
  store.c birth.c notes.c help.c \
  status.c randart.c gods.c modules.c \
  wizard1.c wizard2.c levels.c ghost.c \
  generate.c gen_maze.c gen_evol.c dungeon.c init1.c init2.c \
  bldg.c squeltch.c wild.c powers.c plots.c \
  irc.c skills.c \
  readdib.c angband.rc main-win.c main.c

BASEOBJS = \
  z-term.o z-rand.o z-form.o z-virt.o z-util.o z-sock.o \
  main.o main-win.o readdib.o angband.res \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o plots.o help.o \
  store.o birth.o wizard1.o wizard2.o bldg.o cmovie.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  loadsave.o files.o levels.o notes.o squeltch.o \
  status.o randart.o irc.o skills.o gods.o modules.o \
  xtra1.o xtra2.o spells1.o spells2.o melee1.o melee2.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  variable.o tables.o util.o cave.o ghost.o wild.o powers.o

LUASRCS = \
  script.c lua_bind.c \
  w_util.c w_player.c w_z_pack.c w_obj.c w_mnster.c w_spells.c w_quest.c w_play_c.c w_dun.c

TOLUASRCS = \
  lua/lapi.c lua/lcode.c lua/ldebug.c lua/ldo.c lua/lfunc.c lua/lgc.c \
  lua/llex.c lua/lmem.c lua/lobject.c lua/lparser.c lua/lstate.c lua/lstring.c \
  lua/ltable.c lua/ltests.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c \
  lua/lauxlib.c lua/lbaselib.c lua/ldblib.c lua/liolib.c lua/lstrlib.c \
  lua/tolua_lb.c lua/tolua_rg.c lua/tolua_tt.c lua/tolua_tm.c lua/tolua_gp.c \
  lua/tolua_eh.c lua/tolua_bd.c

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

#
# Base sources and objects
#

SRCS = $(BASESRCS)
OBJS = $(BASEOBJS)


#
# Compiler options
#

CFLAGS = $(COPTS) $(INCLUDES) $(DEFINES) -DDEFAULT_PATH=\"$(LIBDIR)\"


#
# Lua support
#

LUAFLAGS = -DUSE_LUA -Ilua -I.

ifdef LUA
SRCS += $(LUASRCS)
OBJS += $(LUAOBJS)
SRCS += $(TOLUASRCS)
OBJS += $(TOLUAOBJS)
CFLAGS += $(LUAFLAGS)
endif


#
# Build the binary. The new base target.
#

TARGET = tome
TOLUA = ./tolua

default: $(TARGET) $(TOLUA)

$(TARGET): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)

#
# An install rule.
#
install: default
	cp -f $(TARGET) ..


#
# Clean up old junk
#

clean:
	rm -f *.bak $(OBJS)


#
# Generate dependancies automatically
#

depend:
	makedepend $(INCLUDES) $(DEFINES) -D__MAKEDEPEND__ $(SRCS)

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c

.SUFFIXES: .rc .res
.rc.res:
	$(WRES) $< -O coff -o $@

#
# Lua library compilation rules
#

ifdef LUA
w_mnster.c: monster.pkg $(TOLUA)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUA)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUA)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUA)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUA)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUA)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUA)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUA)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

endif

# DO NOT DELETE THIS LINE - make depend depends on it.
tome-235-src/src/makefile.dos0000644000076400017500000000736611012107763013755 0ustar  dgdg# File: Makefile.dos

# Purpose: Makefile support for "main-dos.c"

#
# Note: Rename to "Makefile" before using
#
# Allegro support by Robert Ruehlmann (rr9@angband.org)
#

# Compiling with MOD-file support:
# - Get the JG-MOD library from http://www.jgmod.home.ml.org and install it.
# - Insert -ljgmod in front of -lalleg to the Libraries section.
# - Add -DUSE_MOD_FILES to the compiler flags.
# - Copy your MOD-files into the "lib/xtra/music" folder.

# Enable lua scripting supoprt
LUA = TRUE

# Enable the IRC client -- need libsocket
#IRC = TRUE

#
# Basic definitions
#

# Objects
OBJS = \
  main.o main-dos.o main-ibm.o irc.o \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o plots.o help.o \
  store.o birth.o wizard1.o wizard2.o bldg.o cmovie.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  loadsave.o files.o levels.o notes.o squeltch.o \
  status.o randart.o skills.o gods.o modules.o \
  xtra1.o xtra2.o spells1.o spells2.o melee1.o melee2.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  variable.o tables.o util.o cave.o ghost.o wild.o powers.o \
  z-term.o z-rand.o z-form.o z-virt.o z-util.o z-sock.o

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

ifdef LUA
OBJS += $(LUAOBJS)
OBJS += $(TOLUAOBJS)
endif

# Compiler
CC = gcc

ifdef LUA
LUAFLAGS = -DUSE_LUA -I. -I./lua
endif

# Compiler flags
CFLAGS = -Wall -O2 -s -DUSE_DOS -DUSE_IBM -DUSE_BACKGROUND \
-DUSE_TRANSPARENCY $(LUAFLAGS)

# Libraries
LIBS = -lpc -lalleg $(LUALIBS)

ifdef IRC
CFLAGS += -DUSE_SOCK -DUSE_DOSSOCK
LIBS += -lsocket

# cant get libsocket to resolve hosts
CFLAGS += -DIRC_SERVER=\"216.41.105.77\"
CFLAGS += -DIRC_PORT=\"6667\"
CFLAGS += -DIRC_CHANNEL=\"\#tome\"

endif

#
# Targets
#

TOLUA = tolua.exe

default: ../tome.exe $(TOLUA)

release: ../tome.exe
	upx -9 ../tome.exe
#         copy tome.exe ..
#         del tome.exe

install: ../tome.exe
#        copy tome.exe ..

all: ../tome.exe
#        @echo All done.  Use 'make install' to install.

re: clean all

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)


#
# Link executables
#

../tome.exe: $(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)


#
# Compile source files
#

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c


#
# Clean up
#

clean:
	del *.o

cleanall: clean
	del *.exe

plots.o: q_rand.c q_main.c q_one.c \
	q_thief.c q_hobbit.c q_nazgul.c q_troll.c q_wight.c q_shroom.c \
	q_spider.c q_poison.c \
	q_eol.c q_nirna.c q_invas.c \
	q_betwen.c \
        q_narsil.c q_wolves.c q_drag~1.c q_haun~1.c q_evil.c

LUA_RECOMP = true
ifdef LUA_RECOMP
w_mnster.c: monster.pkg $(TOLUA)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUA)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUA)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUA)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUA)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUA)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUA)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUA)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

endif
tome-235-src/src/makefile.emx0000644000076400017500000001557111012107763013756 0ustar  dgdg# File: Makefile.emx

# Purpose: Makefile support for "main-emx.c"

# Note: Use 'dmake -B -r -f makefile.emx' to compile (see "main-emx.c" for details).
#       Use 'dmake -B -r -f makefile.emx install' to install the executables
#       and the batch file used for multiple VIO windows in the parent directory.
#
#       Use 'dmake -B -r -f makefile.emx clean' to remove temporary files.
#
# Advanced targets (used only by developers):
#
#       'patches': If the original sources are located in "..\old\src",
#                  then a file "..\patches.txt" will be created which contains
#                  all changed files (diff -c). "..\exp\patches.uue" will 
#                  contain the same file gziped and uuencodes. "..\exp\files.uue"
#		   will contain the three emx-specific files tared, gziped and
#                  uuencoded. Needs 4OS2.
#
#       'export': The file "..\exp\$(EXPORT)" is created so that it 
#                 can directly be uploaded as an official distribution archive.
#		  Needs 4OS2.
#

VERSION         = 279v5
EXPORT          = angband-$(VERSION).os2.zip

CC		= gcc
AR		= ar
CFLAGS		= -MMD -O3 -DUSE_EMX -Zmt 
LFLAGS		= -lvideo 

# Uncomment this if you have nice installed
#NICE		= nice -i -n -30

###################################################################################

.KEEP_STATE:

default: all depends :-)

install: ..\angband.exe ..\aclient.exe ..\startwnd.cmd

clean:
	-+@ del angband.exe
	-+@ del aclient.exe
	-+@ del depends
	-+@ del _state.mk
	-+@ del *.a
	-+@ del *.d
	-+@ del *.o

patches:  ..\patches.txt ..\exp\patches.uue ..\exp\files.uue

export: ..\exp\$(EXPORT) 

####################################################################################
###   You don't have to change anything below.   ###################################
####################################################################################

OBJS = \
  z-util.o z-virt.o z-form.o z-rand.o z-term.o z-sock.o \
  variable.o tables.o util.o cave.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  xtra1.o xtra2.o spells1.o spells2.o \
  melee1.o melee2.o files.o cmovie.o \
  status.o randart.o gods.o modules.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  store.o birth.o loadsave.o notes.o squeltch.o \
  wizard1.o wizard2.o levels.o ghost.o plots.o \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o \
  bldg.o wild.o powers.o help.o

.c.o:
	$(NICE) $(CC) $(CFLAGS) -c $*.c

all .PHONY: angband.exe aclient.exe 
	+@echo. 
	+@echo Now type 
	+@echo. 
	+@echo       '$(MAKECMD) $(MFLAGS) $(MAKEFILE) install'
	+@echo. 
	+@echo to install Angband in the parent directory, and/or
	+@echo. 
	+@echo       '$(MAKECMD) $(MFLAGS) $(MAKEFILE) clean'
	+@echo. 
	+@echo to remove a bunch of temporary files used during compilation!
	+@echo You may want to remove the src subdirectory, now that you have
	+@echo working executables.
	+@echo. 

EXPFILES = angband.exe;aclient.exe;patches.txt;readme;startwnd.cmd

..\exp\$(EXPORT) .PHONY .IGNORE: install patches
# Needs 4OS2!
	+@ md ..\exp >& nul                          ^ \
		md ..\exp\tmpdir >& nul              ^ \
		cd ..\exp\tmpdir                     ^ \
		copy ...\$(EXPFILES) > nul           ^ \
		md lib                               ^ \
		copy ...\lib\ lib\ /s >& nul         ^ \
		del lib\save\player >& nul           ^ \
		zip -m -r $(EXPORT) * > nul          ^ \
		move $(EXPORT) ..                    ^ \
		cd ..                                ^ \
		del tmpdir /xsqy >& nul
	
PATCHFILES  = *.c *.h makefile* ..\lib\user\pref-emx.prf

# Needs 4OS2! 
..\patches.txt .PHONY .IGNORE:
	+@ echo These are the changes to the original source  > ..\patches.txt		^ \
	echo archive ($(VERSION)). You don't need to apply them >> ..\patches.txt	^ \
	echo if you can get the latest archive, which will >> ..\patches.txt		^ \
	echo have them applied already. >> ..\patches.txt				^ \
	echo. >> ..\patches.txt								^ \
	except (*~) for %a in ($(PATCHFILES))						  \
	do (diff -c ..\old\src\%a %a >> ..\patches.txt)

# Needs 4OS2!
..\exp\patches.uue: ..\patches.txt
	+@ md ..\exp >& nul                                         ^ \
	cd ..\exp                                                ^ \
	copy ..\patches.txt patches-$(VERSION).os2               ^ \
	gzip -f patches-$(VERSION).os2                           ^ \
	uuencode patches-$(VERSION).os2.gz >& nul                ^ \
	del patches-$(VERSION).os2.gz                            ^ \
	move patches-$(VERSION).os2.gz.uue patches.uue           

FILES  = main-emx.c makefile.emx ..\lib\user\pref-emx.prf 
FILESP = main-emx.c makefile.emx pref-emx.prf 

# Needs 4OS2!
..\exp\files.uue: $(FILES)
	+@ md ..\exp >& nul                                        ^ \
	cd ..\exp                                               ^ \
	for %a in ($(FILES)) copy ..\src\%a > nul               ^ \
	tar -cvf files.tar $(FILESP)                            ^ \
	del $(FILESP)						^ \
	gzip files.tar                                          ^ \
	uuencode files.tar.gz                                   ^ \
	del files.tar.gz >& nul                                 ^ \
	move files.tar.gz.uue files.uue                          

depends .IGNORE: $(OBJS)
	+ echo. > depends
	+ for %a in (*.d) type %a >> depends

..\angband.exe: angband.exe
	+ copy angband.exe ..
	emxbind -s ..\angband.exe

..\aclient.exe: aclient.exe
	+ copy aclient.exe ..
	emxbind -s ..\aclient.exe

EC=+@ echo 
ECF=>> ..\startwnd.cmd

..\startwnd.cmd: 
	$(EC) /* rexx, sir */						> ..\startwnd.cmd
	$(EC).								$(ECF)
	$(EC) call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'	$(ECF)
	$(EC) call SysLoadFuncs						$(ECF)
	$(EC).								$(ECF)
	$(EC) /* This file starts up Angband and up to seven other views. The */	$(ECF)
	$(EC) /* optional number behind the name sets the number of lines for */	$(ECF)
	$(EC) /* that screen.  Choose contents for each via the game options. */	$(ECF)
	$(EC).								$(ECF)
	$(EC) say 'starting up terminals...'				$(ECF)
	$(EC).								$(ECF)
	$(EC) '@start /b /win /n aclient Mirror 23'			$(ECF)
	$(EC) '@start /b /win /n aclient Recall 10'			$(ECF)
	$(EC) /*							$(ECF)
	$(EC) '@start /b /win /n aclient Choice'			$(ECF)
	$(EC) '@start /b /win /n aclient Term-4'			$(ECF)
	$(EC) '@start /b /win /n aclient Term-5'			$(ECF)
	$(EC) '@start /b /win /n aclient Term-6'			$(ECF)
	$(EC) '@start /b /win /n aclient Term-7'			$(ECF)
	$(EC) */							$(ECF)
	$(EC) call SysSleep(2)						$(ECF)
	$(EC) '@angband 'ARG(1)						$(ECF)
	$(EC) exit							$(ECF)

angband.exe: angband.a main.o main-emx.o main-epm.o
	$(CC) -o angband.exe main.o main-emx.o angband.a $(LFLAGS) 

angband.a: $(OBJS)
	$(AR) r angband.a $(OBJS)

aclient.exe: main-emx.c
	$(NICE) $(CC) $(CFLAGS) -Wall -D__EMX__CLIENT__ -o aclient.exe main-emx.c -lvideo

main-emx.o: main-emx.c
	$(NICE) $(CC) $(CFLAGS) -Wall -c main-emx.c -o main-emx.o

main-epm.o: main-emx.c
	$(NICE) $(CC) $(CFLAGS) -Wall -DEMXPM -c main-emx.c -o main-epm.o

# Forgive me :)
":-)":
	+@echo.

.INCLUDE .IGNORE: depends

tome-235-src/src/makefile.gdb0000644000076400017500000000703211012107763013712 0ustar  dgdg# File: Makefile.gdb
# By DarkGod, to create a tome.bin to be used with gdb

# Purpose: Makefile support for "main-dos.c"

#
# Note: Rename to "Makefile" before using
#
# Allegro support by Robert Ruehlmann (rr9@angband.org)
#

# Compiling with MOD-file support:
# - Get the JG-MOD library from http://www.jgmod.home.ml.org and install it.
# - Insert -ljgmod in front of -lalleg to the Libraries section.
# - Add -DUSE_MOD_FILES to the compiler flags.
# - Copy your MOD-files into the "lib/xtra/music" folder.

# Enable lua scripting supoprt
LUA = TRUE

#
# Basic definitions
#

# Objects
OBJS = \
  main.o main-dos.o main-ibm.o \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o plots.o help.o \
  store.o birth.o wizard1.o wizard2.o bldg.o cmovie.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  loadsave.o files.o levels.o notes.o squeltch.o \
  status.o randart.o gods.o skills.o modules.o \
  xtra1.o xtra2.o spells1.o spells2.o melee1.o melee2.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  variable.o tables.o util.o cave.o ghost.o wild.o powers.o \
  z-term.o z-rand.o z-form.o z-virt.o z-util.o z-sock.o

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

ifdef LUA
OBJS += $(LUAOBJS)
OBJS += $(TOLUAOBJS)
endif

# Compiler
CC = gcc

ifdef LUA
LUAFLAGS = -DUSE_LUA -DLUA_NUM_TYPE='long long' -I. -I./lua
endif

# Compiler flags
CFLAGS = -Wall -g -DUSE_DOS -DUSE_IBM -DUSE_BACKGROUND \
-DUSE_TRANSPARENCY $(LUAFLAGS)

# Libraries
LIBS = -lpc -lalleg $(LUALIBS)


#
# Targets
#

TOLUA = tolua.exe

default: ../tome.exe $(TOLUA)

release: ../tome.exe
	upx -9 ../tome.exe
#         copy tome.exe ..
#         del tome.exe

install: ../tome.exe
#        copy tome.exe ..

all: ../tome.exe
#        @echo All done.  Use 'make install' to install.

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)


#
# Link executables
#

../tome.exe: $(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)


#
# Compile source files
#

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c


#
# Clean up
#

clean:
	del *.o

cleanall: clean
	del *.exe

plots.o: q_rand.c q_main.c q_one.c \
	q_thief.c q_hobbit.c q_nazgul.c q_troll.c q_wight.c q_shroom.c \
	q_spider.c q_poison.c \
	q_eol.c q_nirna.c q_invas.c \
	q_betwen.c \
	q_narsil.c q_wolves.c q_dragons.c q_haunted.c q_evil.c

LUA_RECOMP = true
ifdef LUA_RECOMP
w_mnster.c: monster.pkg $(TOLUA)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUA)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUA)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUA)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUA)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUA)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUA)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUA)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

endif
tome-235-src/src/makefile.ibm0000644000076400017500000000722611012107763013732 0ustar  dgdg# File: Makefile.dos

# Purpose: Makefile support for "main-dos.c"

#
# Note: Rename to "Makefile" before using
#
# Allegro support by Robert Ruehlmann (rr9@angband.org)
#

# Compiling with MOD-file support:
# - Get the JG-MOD library from http://www.jgmod.home.ml.org and install it.
# - Insert -ljgmod in front of -lalleg to the Libraries section.
# - Add -DUSE_MOD_FILES to the compiler flags.
# - Copy your MOD-files into the "lib/xtra/music" folder.

# Enable lua scripting supoprt
LUA = TRUE

# Enable the IRC client -- need libsocket
#IRC = TRUE

#
# Basic definitions
#

# Objects
OBJS = \
  main.o main-dos.o main-ibm.o irc.o \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o plots.o help.o \
  store.o birth.o wizard1.o wizard2.o bldg.o cmovie.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  loadsave.o files.o levels.o notes.o squeltch.o \
  status.o randart.o skills.o gods.o modules.o \
  xtra1.o xtra2.o spells1.o spells2.o melee1.o melee2.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  variable.o tables.o util.o cave.o ghost.o wild.o powers.o \
  z-term.o z-rand.o z-form.o z-virt.o z-util.o z-sock.o

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

OBJS += $(LUAOBJS)
OBJS += $(TOLUAOBJS)

# Compiler
CC = gcc

LUAFLAGS = -DUSE_LUA -I. -I./lua

# Compiler flags
CFLAGS = $(LUAFLAGS) -Wall -g -DUSE_IBM

# Libraries
LIBS = -lpc $(LUALIBS)

ifdef IRC
CFLAGS += -DUSE_SOCK -DUSE_DOSSOCK
LIBS += -lsocket

# cant get libsocket to resolve hosts
CFLAGS += -DIRC_SERVER=\"216.41.105.77\"
CFLAGS += -DIRC_PORT=\"6667\"
CFLAGS += -DIRC_CHANNEL=\"\#
angband\"

endif

#
# Targets
#

TOLUA = tolua.exe

default: ../tome.exe $(TOLUA)

release: ../tome.exe
	upx -9 ../tome.exe
#         copy tome.exe ..
#         del tome.exe

install: ../tome.exe
#        copy tome.exe ..

all: ../tome.exe
#        @echo All done.  Use 'make install' to install.

re: clean all

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)


#
# Link executables
#

../tome.exe: $(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)


#
# Compile source files
#

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c


#
# Clean up
#

clean:
	del *.o

cleanall: clean
	del *.exe

plots.o: q_rand.c q_main.c q_one.c \
	q_thief.c q_hobbit.c q_nazgul.c q_troll.c q_wight.c q_shroom.c \
	q_spider.c q_poison.c \
	q_eol.c q_nirna.c q_invas.c \
	q_betwen.c \
	q_narsil.c q_wolves.c q_dragons.c q_haunted.c q_evil.c

LUA_RECOMP = true
ifdef LUA_RECOMP
w_mnster.c: monster.pkg $(TOLUA)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUA)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUA)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUA)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUA)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUA)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUA)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUA)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

endif
tome-235-src/src/makefile.lsl0000644000076400017500000000252011012107763013745 0ustar  dgdg# File: Makefile.lsl

# Purpose: Makefile for Linux + SVGA library

SRCS = \
  z-util.c z-virt.c z-form.c z-rand.c z-term.c z-sock.c \
  variable.c tables.c util.c cave.c cmovie.c \
  object1.c object2.c traps.c monster1.c monster2.c monster3.c \
  xtra1.c xtra2.c spells1.c spells2.c help.c \
  melee1.c melee2.c save.c files.c notes.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c  \
  status.c randart.c gods.c modules.c \
  store.c birth.c loadsave.c ghost.c \
  wizard1.c wizard2.c wild.c powers.c \
  generate.c gen_maze.c gen_evol.c dungeon.c init1.c init2.c \
  bldg.c levels.c squeltch.c plots.c \
  main-ami.c main.c

OBJS = \
  z-util.o z-virt.o z-form.o z-rand.o z-term.o z-sock.o \
  variable.o tables.o util.o cave.o cmovie.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  xtra1.o xtra2.o spells1.o spells2.o help.o \
  melee1.o melee2.o files.o notes.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  status.o randart.o gods.o modules.o \
  store.o birth.o loadsave.o ghost.c \
  wizard1.o wizard2.o wild.o powers.o \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o \
  bldg.o levels.o squeltch.o plots.o \
  main-lsl.o main.o

CC = gcc

CFLAGS = -Wall -O6 -D"USE_LSL"
LIBS = -lvgagl -lvga

# Build the program

angsvga: $(SRCS) $(OBJS)
	$(CC) $(CFLAGS)  -o angband $(OBJS) $(LDFLAGS) $(LIBS)

tome-235-src/src/makefile.osx0000644000076400017500000001420711012107763013771 0ustar  dgdgBUNDLENAME = ToME
BUNDLEDIR = ../$(BUNDLENAME).app
CONTENTSDIR = $(BUNDLEDIR)/Contents
BINDIR = $(CONTENTSDIR)/MacOS
RESOURCEDIR = $(CONTENTSDIR)/Resources
LIBDIR = $(RESOURCEDIR)

CC = MACOSX_DEPLOYMENT_TARGET="10.1" cc

COPTS = -Wall -Os -g -pipe -fpascal-strings
#-Wno-deprecated-declarations
DEFINES = -DUSE_MACOSX -DMACH_O_CARBON \
	-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK \
	-DUSE_EGO_GRAPHICS -DUSE_TRANSPARENCY -DSUPPORT_GAMMA
LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon

# Universal binary support
COPTS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc
LIBS += -arch i386 -arch ppc -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk

BASESRCS = \
  main-crb.c \
  z-rand.c z-util.c z-form.c z-virt.c z-term.c z-sock.c \
  variable.c tables.c plots.c util.c cave.c dungeon.c \
  melee1.c melee2.c modules.c \
  object1.c object2.c randart.c squeltch.c traps.c \
  monster1.c monster2.c monster3.c ghost.c \
  xtra1.c xtra2.c skills.c powers.c gods.c \
  spells1.c spells2.c \
  status.c files.c notes.c loadsave.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c \
  help.c \
  generate.c gen_maze.c gen_evol.c wild.c levels.c store.c bldg.c \
  cmovie.c irc.c \
  wizard2.c init2.c birth.c wizard1.c init1.c

BASEOBJS = \
  main-crb.o \
  z-rand.o z-util.o z-form.o z-virt.o z-term.o z-sock.o \
  variable.o tables.o plots.o util.o cave.o dungeon.o \
  melee1.o melee2.o modules.o \
  object1.o object2.o randart.o squeltch.o traps.o \
  monster1.o monster2.o monster3.o ghost.o \
  xtra1.o xtra2.o skills.o powers.o gods.o \
  spells1.o spells2.o \
  status.o files.o notes.o loadsave.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  help.o \
  generate.o gen_maze.o gen_evol.o wild.o levels.o store.o bldg.o \
  cmovie.o irc.o \
  wizard2.o init2.o birth.o wizard1.o init1.o

LUASRCS = \
  script.c lua_bind.c \
  w_util.c w_player.c w_z_pack.c w_obj.c w_mnster.c w_spells.c w_quest.c w_play_c.c w_dun.c

TOLUASRCS = \
  lua/lapi.c lua/lcode.c lua/ldebug.c lua/ldo.c lua/lfunc.c lua/lgc.c \
  lua/llex.c lua/lmem.c lua/lobject.c lua/lparser.c lua/lstate.c lua/lstring.c \
  lua/ltable.c lua/ltests.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c \
  lua/lauxlib.c lua/lbaselib.c lua/ldblib.c lua/liolib.c lua/lstrlib.c \
  lua/tolua_lb.c lua/tolua_rg.c lua/tolua_tt.c lua/tolua_tm.c lua/tolua_gp.c \
  lua/tolua_eh.c lua/tolua_bd.c

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

#
# Base sources and objects
#

SRCS = $(BASESRCS)
OBJS = $(BASEOBJS)


#
# Compiler options
#

CFLAGS = $(COPTS) $(INCLUDES) $(DEFINES)


#
# Lua support
#

INCLUDES += -Ilua -I.
DEFINES += -DUSE_LUA
SRCS = $(LUASRCS) $(TOLUASRCS) $(BASESRCS)
OBJS = $(LUAOBJS) $(TOLUAOBJS) $(BASEOBJS)

# Force recreation of stub files when lua source files are updated
# To be included in dependency rules
TOLUADEP = $(TOLUASRCS) lua/tolua.c lua/tolualua.c $(TOLUA)

# Build the binary. The new base target.
#

TARGET = tome

TOLUA = ./tolua

default: $(TOLUA) $(TARGET)

$(TARGET): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)

install: default
	[ -d $(BUNDLEDIR) ] || mkdir $(BUNDLEDIR)
	[ -d $(CONTENTSDIR) ] || mkdir $(CONTENTSDIR)
	[ -d $(BINDIR) ]  || mkdir $(BINDIR)
	[ -d $(RESOURCEDIR) ]  || mkdir $(RESOURCEDIR)
	install -m 755 $(TARGET) $(BINDIR)
	install -m 644 carbon/*.icns $(RESOURCEDIR)
	/Developer/Tools/Rez -i /Developer/Headers/FlatCarbon -d MACH_O -o $(RESOURCEDIR)/tome.rsrc carbon/Carbon.r
	install -m 644 carbon/Info.plist $(CONTENTSDIR)/Info.plist
	/Developer/Tools/SetFile -a B $(BUNDLEDIR)
	rsync -r --exclude="*CVS*" --exclude="*xtra/graf*" --exclude="*xtra/font*" ../lib/* $(RESOURCEDIR)
	rsync ../lib/mods/*.lua $(RESOURCEDIR)/core
	rsync ../lib/xtra/graf/*.png $(RESOURCEDIR)

BUNDLEDIR := ../ToME.app
APPVERSION := `carbon/getversion`
IMAGENAME := ToME $(APPVERSION)
IMAGEPATH := /Volumes/$(IMAGENAME)

image: install
	[ -d "$(IMAGEPATH)" ] && diskutil eject "$(IMAGEPATH)" || true

	hdiutil create -fs HFS+ -volname "$(IMAGENAME)" -ov -type SPARSE -attach "$(IMAGENAME)"
	cp -r "$(BUNDLEDIR)" ../changes.txt ../credits.txt ../changes.old "$(IMAGEPATH)"
	cp carbon/Image-DS_Store "$(IMAGEPATH)/.DS_Store"
	diskutil eject "$(IMAGEPATH)"

	rm -f "$(IMAGENAME).dmg"
	hdiutil convert "$(IMAGENAME).sparseimage" -format UDZO -o "$(IMAGENAME)"
	rm "$(IMAGENAME).sparseimage"

#
# Clean up old junk
#

clean:
	rm -f *.bak *.o lua/*.o w_*.c $(TOLUA) $(TARGET)

#
# Generate dependancies automatically
#

depend:
	makedepend $(INCLUDES) $(DEFINES) -D__MAKEDEPEND__ $(SRCS)

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c


#
# Quests
#
plots.o: q_rand.c q_main.c q_one.c q_ultrag.c q_ultrae.c \
	q_thief.c q_hobbit.c q_nazgul.c q_troll.c q_wight.c \
	q_spider.c q_poison.c \
	q_eol.c q_nirna.c q_invas.c \
	q_betwen.c \
	q_narsil.c q_shroom.c q_thrain.c q_wolves.c q_dragons.c q_haunted.c q_evil.c

#
# Lua library compilation rules
#

w_mnster.c: monster.pkg $(TOLUADEP)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUADEP)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUADEP)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUADEP)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUADEP)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUADEP)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUADEP)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUADEP)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

# DO NOT DELETE THIS LINE - make depend depends on it.
tome-235-src/src/makefile.ros0000644000076400017500000001021111012107763013752 0ustar  dgdg# Project: ToME
# Make: make
# Wimpslot: 5000k
#
# To use this makefile, the current working directory must be where
# this makefile is (if this makefile is at "raFS::Temp.$.ang.src.makefile",
# the CWD must be "raFS::Temp.$.ang.src").
#
# This is a GNU make makefile
  
# Defaults
COMPILER := norcroft
default: standard

# Set this to the location of StubsG if using Norcroft
STUBSG := .clib.o.StubsG

# Lua object files
LUAOBJS := lapi.o ldebug.o lmem.o lstrlib.o lvm.o \
  tolua_lb.o lauxlib.o ldo.o lobject.o ltable.o \
  lzio.o tolua_rg.o lbaselib.o lfunc.o lparser.o \
  tolua_bd.o tolua_tm.o lcode.o lgc.o \
  lstate.o ltm.o tolua_eh.o tolua_tt.o ldblib.o \
  llex.o lstring.o lundump.o tolua_gp.o \
  liolib.o

# toLua object files
TOLUAOBJS := tolua.o tolualua.o liolib.o $(LUAOBJS)

# Lua package files:
LUAPKGS := \
  script.c lua_bind.c \
  w_util.c w_player.c w_z_pack.c w_obj.c w_mnster.c w_spells.c w_quest.c w_play_c.c w_dun.c

# The standard object files:
OBJS := \
  z-rand.o z-util.o z-form.o z-virt.o z-term.o z-sock.o \
  variable.o tables.o plots.o util.o cave.o dungeon.o \
  melee1.o melee2.o modules.o \
  object1.o object2.o randart.o squeltch.o traps.o \
  monster1.o monster2.o monster3.o ghost.o \
  xtra1.o xtra2.o skills.o powers.o gods.o \
  spells1.o spells2.o \
  status.o files.o notes.o loadsave.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  help.o \
  generate.o gen_maze.o gen_evol.o wild.o levels.o store.o bldg.o \
  cmovie.o irc.o \
  wizard2.o init2.o birth.o wizard1.o init1.o\
   script.o lua_bind.o w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o \
  main-ros.o



# Defaults for norcy
ifeq (norcroft, $(COMPILER))  
  # Tools:
  CC := cc -DRISCOS -Ilua 
  LD := link
  RM := remove    
  tolua := tolua

  # Libraries:
  LIBS := $(STUBSG) .o.DeskLib

  CCFLAGS_BASIC := -apcs 3/32/fpe2/swst/fp/nofpr -c -Wan
       
  SLUAOBJS := $(addprefix lua/,$(LUAOBJS))
  STOLUAOBJS := $(addprefix lua/,$(TOLUAOBJS))
  
  DLUAOBJS := $(addprefix lua.,$(LUAOBJS))
  DTOLUAOBJS := $(addprefix lua.,$(TOLUAOBJS))

endif
   
# Defaults for gcc
ifeq (gcc, $(COMPILER))
  WARNINGS := -ansi -pedantic -Wall -Wno-unused -Wno-long-long -W -Wcast-qual
       
  # Tools:
  CC := gcc -mlibscl -c -DRISCOS -Ilua
  LD := gcc -mlibscl
  RM := remove
  tolua := tolua

  # Libraries:
  LIBS := .o.DeskLib

  WARNINGS := -ansi -pedantic -Wall -Wundef -Wpointer-arith \
            -Wcast-align -Wwrite-strings -Wstrict-prototypes \
            -Wmissing-prototypes -Wmissing-declarations -Wnested-externs \
            -Winline -Wno-unused -Wno-long-long -W -Wcast-qual

  CCFLAGS_BASIC := -O2 $(WARNINGS) -mthrowback -mpoke-function-name
         
  SLUAOBJS := $(addprefix lua/,$(LUAOBJS))
  STOLUAOBJS := $(addprefix lua/,$(TOLUAOBJS))
  
  DLUAOBJS := $(SLUAOBJS)
  DTOLUAOBJS := $(STOLUAOBJS)
endif


#
# Rules to make the various targets
#
ALL_TARGETS := standard fullscreen

$(ALL_TARGETS): tolua

standard: CCFLAGS := $(CCFLAGS_BASIC)
standard: $(LUAPKGS) $(OBJS) $(SLUAOBJS)  $(LIBS)
	$(LD) $(LDFLAGS) -o ^.!RunImage $(OBJS) $(DLUAOBJS) $(LIBS)

fullscreen: CCFLAGS := -DFULLSCREEN_ONLY $(CCFLAGS_BASIC)  
fullscreen: $(LUAPKGS) $(OBJS) $(SLUAOBJS) $(LIBS)
	$(LD) $(LDFLAGS) -o ^.!RunImageF $(OBJS) $(DLUAOBJS)  $(LIBS)

# tolua
tolua: $(STOLUAOBJS)
	$(LD) -o tolua $(DTOLUAOBJS) $(LDFLAGS) $(LIBS)

# Lua packages
w_mnster.c: monster.pkg $(tolua)
	$(tolua) -n monster -o c.w_mnster monster/pkg

w_player.c: player.pkg $(tolua)
	$(tolua) -n player -o c.w_player player/pkg

w_play_c.c: player_c.pkg $(tolua)
	$(tolua) -n player_c -o c.w_play_c player_c/pkg

w_z_pack.c: z_pack.pkg $(tolua)
	$(tolua) -n z_pack -o c.w_z_pack z_pack/pkg

w_obj.c: object.pkg $(tolua)
	$(tolua) -n object -o c.w_obj object/pkg

w_util.c: util.pkg $(tolua)
	$(tolua) -n util -o c.w_util util/pkg

w_spells.c: spells.pkg $(tolua)
	$(tolua) -n spells -o c.w_spells spells/pkg

w_quest.c: quest.pkg $(tolua)
	$(tolua) -n quest -o c.w_quest quest/pkg

w_dun.c: dungeon.pkg $(tolua)
	$(tolua) -n dungeon -o c.w_dun dungeon/pkg


# Suffix rules
.SUFFIXES: .o .c

# A basic rule
.c.o:;	$(CC) $(CCFLAGS) -o $@ $<

# Dynamic dependencies:

tome-235-src/src/makefile.std0000644000076400017500000004162311012107763013754 0ustar  dgdg# File: Makefile

# This is not a very "nice" Makefile, but it usually works.

#
# Note that you may have to make modifications below according
# to your machine, available libraries, compilation options,
# and your "visual module" of choice.  This Makefile is intended
# for use with Unix machines running X11, Curses, Ncurses, or Vt100,
# or possibly for "Atari" or "Amiga" computers with "Curses" ports,
# see below for more information.
#
# Note that "main-mac.c" and "main-crb.c", the visual modules for
# the Macintosh, must be compiled in a special way, see elsewhere.
#
# Note that "main-win.c", the visual module for Windows,
# must be compiled in a special way, see elsewhere.
#
# Note that "main-ibm.c" and "main-emx.c", the visual modules
# for various types of IBM-PC computers, must be compiled with
# special Makefiles, see elsewhere.
#
# Note that "main-lsl.c", the visual module for Linux-SVGALIB
# must be compiled with "Makefile.lsl", see elsewhere.
#
# Note that "main-acn.c", the visual module for Risc Acorn,
# must be compiled with "Makefile.acn", see elsewhere.
#
# Note that "Makefile.wat" is a slight variation on "Makefile.ibm",
# which allow the use of "main-ibm.c" with special compiler
# (might be out-of-date).
#
# If you are able to construct "main-xxx.c" and/or "Makefile.xxx"
# files for a currently unsupported system, please send them to me
# (rr9@angband.org) for inclusion in future versions.
#

##
## 1. Installation locations and such
##
## LIBDIR, BINDIR and OWNER should be set appropriately for
## multiuser installations.
##
## If you want to keep it private or don't have root privilege
## required by "make install", set LIBDIR to ./lib/ or an absolute
## path pointing to your lib directory, and don't run "make install".
##
## NOTE: If LIBDIR is set to ./lib/ , you have to cd to parent directory
## of lib before you start the game.
##

# Where lib/ files goes
#LIBDIR = /usr/lib/games/tome/
# Sysadmins of commercial Unix and/or BSD might prefer this
#LIBDIR = /usr/local/lib/tome/
# If you like the old default, use this one
LIBDIR = ./lib/
# Another example: single user installation using absolute path
#LIBDIR = /home/myloginname/lib/tome/


# Where ToME binary goes
BINDIR = /usr/local/games
# Another common location
#BINDIR = /usr/local/bin

# The game will run suid to this user
OWNER = games

# Ignore this if you're not making a package
DESTDIR=

##
## 2. Some "system" definitions
##
## No changes are needed to compile a version that will run on both
## X11 and Curses, in debugging mode, with maximal warnings, on many
## normal Unix machines of the Sun OS variety (non-solaris).
##
## To use an "alternative" definition, simply "modify" (or "replace")
## the definition below with one that you like.  For example, you can
## change the compiler to "cc", or remove the "debugging" options, or
## remove the X11 or Curses support, etc, as desired.
##
## See also "config.h" and "h-config.h" for important information.
##
## Some "examples" are given below, they can be used by simply
## removing the FIRST column of "#" signs from the "block" of lines
## you wish to use, and commenting out "standard" block below.
##
## This is not intended to be a "good" Makefile, just a "simple" one.
##


#
# This is my compiler of choice, it seems to work most everywhere
#
CC = gcc

# Profiling options
# PROFILECOPTS = -pg
# PROFILELDFLAGS = -pg

#
# Standard version (see main-x11.c)
#
# This version supports "X11" only.
#
# You may have to add various X11 include/library directories to the
# "INCLUDES", if your machine places files in a weird location
# (e.g. -I/usr/X11R6/include, as is almost always the case with
# linux and *BSD). Since we have seen many linux users -- arguably
# the largest unix population -- confused by this, and adding this
# usually doesn't hurt, the default rule has been changed to search
# for /usr/X11R6/include.
#
# You may be able to remove "-ltermcap" on some machines (ex: Solaris).
#
# You may have to replace "-lcurses" with "-lncurses" to use the
# "new curses" library instead of the "old curses" library, and
# you may have to add "-I/usr/include/ncurses" to the "INCLUDES",
# and/or "-DUSE_NCURSES" to "DEFINES".
#
# See "main-gcu.c" and "config.h" for some optional "curses" defines,
# including "USE_GETCH" and "USE_CURS_SET".  Note that "config.h" will
# attempt to "guess" at many of these flags based on your system.
#
COPTS = -Wall -O1 -pipe -g
INCLUDES = -I/usr/X11R6/include
DEFINES = -DUSE_X11 \
	-DUSE_EGO_GRAPHICS -DUSE_TRANSPARENCY -DSUPPORT_GAMMA \
	-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK
LIBS = -L/usr/X11R6/lib -lX11

##
## Variation -- Only support "main-gtk2.c" (not "main-gcu.c, main-x11.c")
## this variation uses pkg-config and gnu make
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = $(shell pkg-config --cflags-only-I gtk+-2.0)
#DEFINES = -DUSE_GTK2 -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = $(shell pkg-config --libs gtk+-2.0)
#GTK_SRC_FILE= main-gtk2.c
#GTK_OBJ_FILE= main-gtk2.o

##
## Variation -- Only support "main-gtk2.c" (not "main-gcu.c, main-x11.c")
## this variation uses pkg-config
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = `pkg-config --cflags-only-I gtk+-2.0`
#DEFINES = -DUSE_GTK2 -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = `pkg-config --libs gtk+-2.0`
#GTK_SRC_FILE= main-gtk2.c
#GTK_OBJ_FILE= main-gtk2.o

##
## Variation -- Only support "main-gtk.c" (not "main-gcu.c, main-x11.c")
## this variation uses pkg-config
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = `pkg-config --cflags-only-I gtk+-2.0`
#DEFINES = -DUSE_GTK -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = `pkg-config --libs gtk+-2.0`
#GTK_SRC_FILE= main-gtk.c
#GTK_OBJ_FILE= main-gtk.o

##
## Variation -- Only support "main-gtk.c" (not "main-gcu.c, main-x11.c")
## this variation uses gtk-config
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = `gtk-config --cflags`
#DEFINES = -DUSE_GTK -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = `gtk-config --libs`
#GTK_SRC_FILE= main-gtk.c
#GTK_OBJ_FILE= main-gtk.o

##
## Variation -- Both "main-x11.c" and "main-gcu.c" in a single executable.
##
## Your Unix system's curses library may be called "-lcurses" instead of
## "-lncurses", and you may also need to add "-ltermlib" to the end of the
## LIBS on some platforms.
#
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS \
#	-DUSE_TRANSPARENCY -DSUPPORT_GAMMA \
#	-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK
#LIBS = -L/usr/X11R6/lib -lX11 -lncurses


##
## Variation -- Only support "main-gcu.c" (not "main-x11.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap


##
## Variation -- Use "main-xaw.c" instead of "main-x11.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_XAW -DUSE_GCU \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lXaw -lXmu -lXt -lX11 -lcurses -ltermcap -L/usr/X11R6/lib

##
## Variation -- Use "main-sdl.c" instead of "main-x11.c"
##
#SDL_CONFIG ?= sdl-config
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = `$(SDL_CONFIG) --cflags`
#DEFINES = -DUSE_SDL -DUSE_GCU \
#	-DUSE_EGO_GRAPHICS -DUSE_TRANSPARENCY \
#	-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK -DSUPPORT_GAMMA
#LIBS = `$(SDL_CONFIG) --libs` -lSDL_image -lSDL_ttf -lcurses

##
## Variation -- Use "main-cap.c" instead of "main-gcu.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_CAP \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -ltermcap


##
## Variation -- Only work on simple vt100 terminals
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_CAP -DUSE_HARDCODE


##
## Variation -- this might work for Linux 1.1.93 using ncurses-1.8.7.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lncurses -L/usr/X11R6/lib


##
## Variation -- this might work better than the suggestion above
##
#COPTS = -Wall -O2 -fomit-frame-pointer
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_TPOSIX -DUSE_CURS_SET \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lncurses -L/usr/X11R6/lib
#LDFLAGS = -s


##
## Variation -- compile for FreeBSD with ncurses
## -- BSD curses gives you B&W display.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_NCURSES \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lncurses -L/usr/X11R6/lib


##
## Variation -- compile for Solaris
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSOLARIS \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lsocket -lcurses


##
## Variation -- compile for SGI Indigo runnig Irix
## The SGI has hardware gamma correction.
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSGI \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS
#LIBS = -lX11 -lcurses -ltermcap -lsun

##
## Variation -- compile for Dec ALPHA OSF/1 v2.0
##
#CC     = cc
##COPTS = -std -O -g3 -Olimit 4000
#COPTS = -std -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS   = -lX11 -lcurses -ltermcap -lrpcsvc


##
## Variation -- compile for Interactive Unix (ISC) systems
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DISC \
#	-DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA
#LIBS = -lX11 -lcurses -lnsl_s -linet -lcposix


##
## Variation -- Support fat binaries under NEXTSTEP
##
#COPTS = -Wall -O1 -pipe -g -arch m68k -arch i386
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap

#
# Variation -- compile for 64 bit machines where the size of long is 64 bits.
#
# On some machines it may be necessary to change the -L directory so that
# it points at a library directory containing 64-bit libraries. For example,
# on Suse 10.x you need to change it to:  -L/usr/X11R6/lib64.
#
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DLUA_NUM_TYPE=int -DUSE_X11 \
#		-DUSE_EGO_GRAPHICS -DUSE_TRANSPARAENCY -DSUPPORT_GAMMA \
#		-DUSE_PRECISE_CMOVIE -DUSE_UNIXSOCK
#LIBS = -L/usr/X11R6/lib -LX11

### End of configurable section ###

#
# The "source" and "object" files.
#

BASESRCS = \
  $(GTK_SRC_FILE) main-gcu.c main-x11.c main-xaw.c main-sdl.c main-dmy.c \
  z-rand.c z-util.c z-form.c z-virt.c z-term.c z-sock.c \
  variable.c tables.c plots.c util.c cave.c dungeon.c \
  melee1.c melee2.c modules.c \
  object1.c object2.c randart.c squeltch.c traps.c \
  monster1.c monster2.c monster3.c ghost.c \
  xtra1.c xtra2.c skills.c powers.c gods.c \
  spells1.c spells2.c \
  status.c files.c notes.c loadsave.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c \
  help.c \
  generate.c gen_maze.c gen_evol.c wild.c levels.c store.c bldg.c \
  cmovie.c irc.c \
  wizard2.c init2.c birth.c wizard1.c init1.c main.c

BASEOBJS = \
  $(GTK_OBJ_FILE) main-gcu.o main-x11.o main-xaw.o main-sdl.o main-dmy.o \
  z-rand.o z-util.o z-form.o z-virt.o z-term.o z-sock.o \
  variable.o tables.o plots.o util.o cave.o dungeon.o \
  melee1.o melee2.o modules.o \
  object1.o object2.o randart.o squeltch.o traps.o \
  monster1.o monster2.o monster3.o ghost.o \
  xtra1.o xtra2.o skills.o powers.o gods.o \
  spells1.o spells2.o \
  status.o files.o notes.o loadsave.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  help.o \
  generate.o gen_maze.o gen_evol.o wild.o levels.o store.o bldg.o \
  cmovie.o irc.o \
  wizard2.o init2.o birth.o wizard1.o init1.o main.o

LUASRCS = \
  script.c lua_bind.c \
  w_util.c w_player.c w_z_pack.c w_obj.c w_mnster.c w_spells.c w_quest.c w_play_c.c w_dun.c

TOLUASRCS = \
  lua/lapi.c lua/lcode.c lua/ldebug.c lua/ldo.c lua/lfunc.c lua/lgc.c \
  lua/llex.c lua/lmem.c lua/lobject.c lua/lparser.c lua/lstate.c lua/lstring.c \
  lua/ltable.c lua/ltests.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c \
  lua/lauxlib.c lua/lbaselib.c lua/ldblib.c lua/liolib.c lua/lstrlib.c \
  lua/tolua_lb.c lua/tolua_rg.c lua/tolua_tt.c lua/tolua_tm.c lua/tolua_gp.c \
  lua/tolua_eh.c lua/tolua_bd.c

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

#
# Base sources and objects
#

SRCS = $(BASESRCS)
OBJS = $(BASEOBJS)


#
# Compiler options
#

CFLAGS = $(COPTS) $(PROFILECOPTS) $(INCLUDES) $(DEFINES) -DDEFAULT_PATH=\"$(LIBDIR)\"


#
# Lua support
#

INCLUDES += -Ilua -I.
DEFINES += -DUSE_LUA
SRCS = $(LUASRCS) $(TOLUASRCS) $(BASESRCS)
OBJS = $(LUAOBJS) $(TOLUAOBJS) $(BASEOBJS)

# Force recreation of stub files when lua source files are updated
# To be included in dependency rules
TOLUADEP = $(TOLUA) $(TOLUASRCS) lua/tolua.c lua/tolualua.c

#
# IRC support
#

IRC_SERVER=irc.worldirc.org
IRC_PORT=6667
IRC_CHANNEL=\#tome

DEFINES += \
	-DIRC_SERVER=\"$(IRC_SERVER)\" \
	-DIRC_PORT=\"$(IRC_PORT)\" \
	-DIRC_CHANNEL=\"$(IRC_CHANNEL)\"

# Build the binary. The new base target.
#

TARGET = tome

TOLUA = ./tolua

default: $(TOLUA) $(TARGET)
	@echo "*** Note: In order to use the install rule, which now actually"
	@echo "*** handles the installation of the library dir, you need to edit"
	@echo "*** this makefile, going to the top and making sure LIBDIR suits"
	@echo "*** your desired install dir properly. The LIBRARY_DIR you used"
	@echo "*** to set in config.h is now ignored and obsolete with respect"
	@echo "*** to this makefile. Note that if you edit this makefile, you may"
	@echo "*** need to recompile so all the files that reference those defines"
	@echo "*** notice the changes."

$(TARGET): $(OBJS)
	$(CC) $(PROFILELDFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(PROFILELDFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)

#
# An install rule.
#
mini_install: default
	cp -f $(TARGET) ..

install: default
	[ -d $(DESTDIR)$(LIBDIR) ] || mkdir -p $(DESTDIR)$(LIBDIR)
	[ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR)
	cp -r ../lib/* $(DESTDIR)$(LIBDIR)
	chown -R $(OWNER) $(DESTDIR)$(LIBDIR)
	cp -f $(TARGET) $(DESTDIR)$(BINDIR)/$(TARGET)
	chown $(OWNER) $(DESTDIR)$(BINDIR)/$(TARGET)
	chmod 4755 $(DESTDIR)$(BINDIR)/$(TARGET)

# old-install: $(TARGET)
#	cp $(TARGET) ..


#
# Clean up old junk
#

clean:
	rm -f *.bak *.o lua/*.o w_*.c $(TOLUA) $(TARGET)


# Make a src dist
TARGET_VERSION=`fgrep '[V]' ../changes.txt | sed 's/\[V\]-*\s*T.o.M.E \(.\).\(.\).\(.\) .*/\1\2\3/g'`
DIST_TARGET_VERSION=../dist/tome-$(TARGET_VERSION)-src
DIST_TARGET=../dist/tome-xxx-src
dist: clean
	mkdir -p $(DIST_TARGET)
	cp -r ../lib $(DIST_TARGET)
	cp -r ../src $(DIST_TARGET)
	../tome -c ../changes.txt $(DIST_TARGET)/changes.txt
	cp ../changes.old $(DIST_TARGET)
	cp ../credits.txt $(DIST_TARGET)
	cp ../tome.ini $(DIST_TARGET)
	cp ../angdos.cfg $(DIST_TARGET)
	rm -f $(DIST_TARGET)/src/tome $(DIST_TARGET)/src/tolua
	find $(DIST_TARGET) -name '*~' -exec rm {} \;
	find $(DIST_TARGET)/lib/data/ -name '*.raw' -exec rm {} \;
	find $(DIST_TARGET)/lib/xtra/graf/ -name '*.gif' -exec rm {} \;
	find $(DIST_TARGET)/lib/xtra/font/ -name '*.hex' -exec rm {} \;
	rm -rf `find $(DIST_TARGET) -name 'CVS'`
	rm -rf `find $(DIST_TARGET)/lib/mods/ -mindepth 1 -maxdepth 1 -type d`
	sed -i 's/(CVS)//' $(DIST_TARGET)/src/defines.h
	mv $(DIST_TARGET) $(DIST_TARGET_VERSION)
	cd ../dist; tar -cvjf tome-$(TARGET_VERSION)-src.tar.bz2 tome-$(TARGET_VERSION)-src

#
# Generate dependancies automatically
#

depend:
	makedepend $(INCLUDES) $(DEFINES) -D__MAKEDEPEND__ $(SRCS)

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c


#
# Quests
#
plots.o: q_rand.c q_main.c q_one.c q_ultrag.c q_ultrae.c \
	q_thief.c q_hobbit.c q_nazgul.c q_troll.c q_wight.c \
	q_spider.c q_poison.c \
	q_eol.c q_nirna.c q_invas.c \
	q_betwen.c \
	q_narsil.c q_shroom.c q_thrain.c q_wolves.c q_dragons.c q_haunted.c q_evil.c

#
# Lua library compilation rules
#

w_mnster.c: monster.pkg $(TOLUADEP)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUADEP)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUADEP)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUADEP)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUADEP)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUADEP)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUADEP)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUADEP)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

# DO NOT DELETE THIS LINE - make depend depends on it.
tome-235-src/src/makefile.wat0000644000076400017500000000432711012107763013755 0ustar  dgdg# File: Makefile.wat

# Purpose: Makefile support for "main-ibm.c" for Watcom C/C++

# From: akemi@netcom.com (David Boeren)
# Extra program targets by: mrmarcel@eos.ncsu.edu (Mike Marcelais)

CC = wcc386

CFLAGS  = /mf /3r /3 /wx /s /oneatx /DUSE_IBM /DUSE_WAT
# CFLAGS  = /mf /3r /3 /wx /oaeilmnrt /DUSE_IBM /DUSE_WAT

OBJS = &
  z-util.obj z-virt.obj z-form.obj z-rand.obj z-term.obj z-sock.obj &
  variable.obj tables.obj util.obj cave.obj cmovie.obj &
  object1.obj object2.obj traps.obj monster1.obj monster2.obj monster3.obj &
  xtra1.obj xtra2.obj spells1.obj spells2.obj melee1.obj melee2.obj &
  loadsave.obj files.obj ghost.obj powers.obj &
  cmd1.obj cmd2.obj cmd3.obj cmd4.obj cmd5.obj cmd6.obj cmd7.obj &
  store.obj birth.obj wizard1.obj wizard2.obj &
  status.obj randart.obj &
  generate.obj gen_maze.obj gen_evol.obj dungeon.obj init1.obj init2.obj plots.obj &
  bldg.obj levels.obj notes.obj squeltch.obj wild.obj help.obj &
  main-ibm.obj main.obj

all: angband.exe gredit.exe makepref.exe

# Use whichever of these two you wish...
angband.exe: $(OBJS) angband.lnk
   wlink system dos4g @angband.lnk
#   wlink system pmodew @angband.lnk

# Use whichever of these two you wish...
gredit.exe: gredit.obj gredit.lnk
   wlink system dos4g @gredit.lnk
#   wlink system pmodew @gredit.lnk

# Use whichever of these two you wish...
makepref.exe: makepref.obj makepref.lnk
   wlink system dos4g @makepref.lnk
#   wlink system pmodew @makepref.lnk

angband.lnk:
    %create  angband.lnk
#   @%append angband.lnk debug all
    @%append angband.lnk OPTION CASEEXACT
    @%append angband.lnk OPTION STACK=16k
    @%append angband.lnk name angband
    @for %i in ($(OBJS)) do @%append angband.lnk file %i

makepref.lnk:
    %create  makepref.lnk
#   @%append makepref.lnk debug all
    @%append makepref.lnk OPTION CASEEXACT
    @%append makepref.lnk OPTION STACK=16k
    @%append makepref.lnk name makepref
    @%append makepref.lnk file makepref.obj

gredit.lnk:
    %create  gredit.lnk
#   @%append gredit.lnk debug all
    @%append gredit.lnk OPTION CASEEXACT
    @%append gredit.lnk OPTION STACK=16k
    @%append gredit.lnk name gredit
    @%append gredit.lnk file gredit.obj

.c.obj:
    $(CC) $(CFLAGS) $[*.c

clean:
    del *.err *.obj *.exe *.lnk
tome-235-src/src/makefile.win0000644000076400017500000001157311012107763013760 0ustar  dgdg# File: Makefile.win

# For Borland C++ 4.52 Win16 and Win32

.autodepend

# change this to suit your taste

CC = c:\apps\bc45\bin\bcc.exe +bccw16.cfg
CC32 = c:\apps\bc45\bin\bcc32.exe +bccw32.cfg
LINK = c:\apps\bc45\bin\tlink.exe
LINK32 = c:\apps\bc45\bin\tlink32.exe
RC = c:\apps\bc45\bin\brc.exe
RC32 = c:\apps\bc45\bin\brc32.exe
LIBDIR = c:\apps\bc45\lib
INCLDIR = c:\apps\bc45\include;c:\angband\ext-win\src

# shouldn't need to change anything below

SRCS = \
  z-util.c z-virt.c z-form.c z-rand.c z-term.c z-sock.c \
  variable.c tables.c util.c cave.c cmovie.c modules.c \
  object1.c object2.c traps.c monster1.c monster2.c monster3.c \
  xtra1.c xtra2.c spells1.c spells2.c \
  melee1.c melee2.c files.c plots.c help.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c \
  status.c randart.c gods.c \
  store.c birth.c loadsave.c notes.c squeltch.c \
  wizard1.c wizard2.c levels.c ghost.c \
  generate.c gen_maze.c gen_evol.c dungeon.c init1.c init2.c \
  main-win.c readdib.c \
  bldg.c wild.c powers.c

OBJS = \
  z-util.obj z-virt.obj z-form.obj z-rand.obj z-term.obj z-sock.obj \
  variable.obj tables.obj util.obj cave.obj cmovie.obj modules.obj \
  object1.obj object2.obj traps.obj monster1.obj monster2.obj monster3.obj \
  xtra1.obj xtra2.obj spells1.obj spells2.obj \
  melee1.obj melee2.obj files.obj plots.obj help.obj \
  cmd1.obj cmd2.obj cmd3.obj cmd4.obj cmd5.obj cmd6.obj cmd7.obj \
  status.obj randart.obj gods.obj \
  store.obj birth.obj loadsave.obj notes.obj squeltch.obj \
  wizard1.obj wizard2.obj levels.obj ghost.obj \
  generate.obj gen_maze.obj gen_evol.obj dungeon.obj init1.obj init2.obj \
  main-win.obj readdib.obj \
  bldg.obj wild.obj powers.obj

OBJS32 = \
  z-util.o32 z-virt.o32 z-form.o32 z-rand.o32 z-term.o32 z-sock.o32 \
  variable.o32 tables.o32 util.o32 cave.o32 cmovie.o32 modules.o32 \
  object1.o32 object2.o32 traps.o32 monster1.o32 monster2.o32 monster3.o32 \
  xtra1.o32 xtra2.o32 spells1.o32 spells2.o32 \
  melee1.o32 melee2.o32 files.o32 plots.o32 help.o32 \
  cmd1.o32 cmd2.o32 cmd3.o32 cmd4.o32 cmd5.o32 cmd6.o32 cmd7.o32 \
  status.o32 randart.o32 gods.o32 \
  store.o32 birth.o32 loadsave.o32 notes.o32 squeltch.o32 \
  wizard1.o32 wizard2.o32 levels.o32 ghost.o32 \
  generate.o32 gen_maze.o32 gen_evol.o32 dungeon.o32 init1.o32 init2.o32 \
  main-win.o32 readdib.o32 \
  bldg.o32 wild.o32

default: bccw16.cfg angband cleanobj bccw32.cfg angband32 cleanobj32

clean:
	del *.obj
	del ..\*.map
	del ..\angband.exe

cleanobj:
	del *.obj
	del bccw16.cfg

cleanobj32:
	del *.o32
	del bccw32.cfg

bccw16.cfg: makefile.win
	if not exist ..\angband.ini copy ..\ext-win\src\angband.ini ..
	copy &&|
-I$(INCLDIR)
-L$(LIBDIR)
-ml
-WE
-x-
-K
-y-
-v-
-N-
-f-
-3
-dc
-Ff=8
-r
-b-
-p-
-Os
-Oa
-OW
-O
-d
-Ob
-Oe
-Og
-Ol
-Om
-Ot
-Op
-Ov
-k-
-Z
-w-
-X
-D__STDC__=1
| bccw16.cfg

bccw32.cfg: makefile.win
	copy &&|
-I$(INCLDIR)
-L$(LIBDIR)
-WE
-x-
-K
-y-
-v-
-N-
-f-
-5
-r
-b-
-p-
-Os
-OW
-O
-d
-Oa
-Ob
-Oe
-Og
-Ol
-Om
-Ot
-Op
-Ov
-k-
-Z
-w-
-X
-D__STDC__=1
| bccw32.cfg

.c.obj:
	$(CC) -c $<

generate.obj: generate.c
	$(CC) -c generate.c

readdib.obj: ..\ext-win\src\readdib.c ..\ext-win\src\readdib.h
	$(CC) -c ..\ext-win\src\readdib.c

angband: $(OBJS) ..\ext-win\src\angband.rc
	$(LINK) /L$(LIBDIR) @&&|
-Twe -P -d -x -Gn -Oc -yx4096 +
c0wl+
z-util z-virt z-form z-rand z-term z-sock +
variable tables util cave cmovie modules +
object1 object2 traps monster1 monster2 monster3 +
xtra1 xtra2 spells1 spells2 +
melee1 melee2 files plots help +
cmd1 cmd2 cmd3 cmd4 cmd5 cmd6 cmd7 +
status randart gods +
store birth loadsave notes squeltch +
wizard1 wizard2 levels ghost +
generate gen_maze gen_evol dungeon init1 init2 +
main-win readdib bldg wild powers +
..\angband.exe,..\angband.map,import cwl,..\ext-win\src\angband.def
|
	$(RC) -31 ..\ext-win\src\angband.rc ..\angband.exe

.c.o32:
	$(CC32) -c -o$@ $<

# bug in BC4.5 optimizer scrambles town level
generate.o32: generate.c
	$(CC32) -c -ogenerate.o32 -O- generate.c

readdib.o32: ..\ext-win\src\readdib.c ..\ext-win\src\readdib.h
	$(CC32) -c -oreaddib.o32 ..\ext-win\src\readdib.c

angband32: $(OBJS32) ..\ext-win\src\angband.rc
	$(LINK32) /L$(LIBDIR) @&&|
-aa -B:0x400000 -S:0x100000 -P -x +
c0w32 +
z-util.o32 z-virt.o32 z-form.o32 z-rand.o32 z-term.o32 z-sock.o32 +
variable.o32 tables.o32 util.o32 cave.o32 cmovie.o32 modules.o32 +
object1.o32 object2.o32 traps.o32 monster1.o32 monster2.o32 monster3.o32 +
xtra1.o32 xtra2.o32 spells1.o32 spells2.o32 +
melee1.o32 melee2.o32 files.o32 plots.o32 help.o32 +
cmd1.o32 cmd2.o32 cmd3.o32 cmd4.o32 cmd5.o32 cmd6.o32 cmd7.o32 +
status.o32 randart.o32 gods.o32 +
store.o32 birth.o32 loadsave.o32 notes.o32 squeltch.o32 +
wizard1.o32 wizard2.o32 levels.o32 ghost.o32 +
generate.o32 gen_maze.o32 gen_evol.o32 dungeon.o32 init1.o32 init2.o32 +
main-win.o32 readdib.o32 bldg.o32 wild.o32 powers.o32+
..\angband32.exe,..\angband.map,import32 cw32,..\ext-win\src\angband.def
|
	$(RC32) -w32 ..\ext-win\src\angband.rc ..\angband32.exe
tome-235-src/src/xtra1.c0000644000076400017500000030562211012107763012670 0ustar  dgdg/* File: misc.c */

/* Purpose: misc code */

/*
 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
 *
 * This software may be copied and distributed for educational, research, and
 * not for profit purposes provided that this copyright and statement are
 * included in all such copies.
 */

#include "angband.h"


/*
 * Converts stat num into a six-char (right justified) string
 */
void cnv_stat(int val, char *out_val)
{
	if (!linear_stats)
	{
		/* Above 18 */
		if (val > 18)
		{
			int bonus = (val - 18);

			if (bonus >= 220)
			{
				sprintf(out_val, "18/%3s", "***");
			}
			else if (bonus >= 100)
			{
				sprintf(out_val, "18/%03d", bonus);
			}
			else
			{
				sprintf(out_val, " 18/%02d", bonus);
			}
		}

		/* From 3 to 18 */
		else
		{
			sprintf(out_val, "    %2d", val);
		}
	}
	else
	{
		/* Above 18 */
		if (val > 18)
		{
			int bonus = (val - 18);

			if (bonus >= 220)
			{
				sprintf(out_val, "    40");
			}
			else
			{
				sprintf(out_val, "    %2d", 18 + (bonus / 10));
			}
		}

		/* From 3 to 18 */
		else
		{
			sprintf(out_val, "    %2d", val);
		}
	}
}



/*
 * Modify a stat value by a "modifier", return new value
 *
 * Stats go up: 3,4,...,17,18,18/10,18/20,...,18/220
 * Or even: 18/13, 18/23, 18/33, ..., 18/220
 *
 * Stats go down: 18/220, 18/210,..., 18/10, 18, 17, ..., 3
 * Or even: 18/13, 18/03, 18, 17, ..., 3
 */
s16b modify_stat_value(int value, int amount)
{
	int i;

	/* Reward */
	if (amount > 0)
	{
		/* Apply each point */
		for (i = 0; i < amount; i++)
		{
			/* One point at a time */
			if (value < 18) value++;

			/* Ten "points" at a time */
			else value += 10;
		}
	}

	/* Penalty */
	else if (amount < 0)
	{
		/* Apply each point */
		for (i = 0; i < (0 - amount); i++)
		{
			/* Ten points at a time */
			if (value >= 18 + 10) value -= 10;

			/* Hack -- prevent weirdness */
			else if (value > 18) value = 18;

			/* One point at a time */
			else if (value > 3) value--;
		}
	}

	/* Return new value */
	return (value);
}



/*
 * Print character info at given row, column in a 13 char field
 */
static void prt_field(cptr info, int row, int col)
{
	/* Dump 13 spaces to clear */
	c_put_str(TERM_WHITE, "             ", row, col);

	/* Dump the info itself */
	c_put_str(TERM_L_BLUE, info, row, col);
}

/*
 * Prints players max/cur piety
 */
static void prt_piety(void)
{
	char tmp[32];

	/* Do not show piety unless it matters */
	if (!p_ptr->pgod) return;

	c_put_str(TERM_L_WHITE, "Pt ", ROW_PIETY, COL_PIETY);

	sprintf(tmp, "%9ld", p_ptr->grace);

	c_put_str((p_ptr->praying) ? TERM_L_BLUE : TERM_GREEN, tmp, ROW_PIETY,
		COL_PIETY + 3);
}


/*
 * Prints the player's current sanity.
 */
static void prt_sane(void)
{
	char tmp[32];
	byte color;
	int perc;

	if (p_ptr->msane == 0)
	{
		perc = 100;
	}
	else
	{
		perc = (100 * p_ptr->csane) / p_ptr->msane;
	}

	c_put_str(TERM_ORANGE, "SN ", ROW_SANITY, COL_SANITY);

	sprintf(tmp, "%4d/%4d", p_ptr->csane, p_ptr->msane);

	if (perc >= 100)
	{
		color = TERM_L_GREEN;
	}
	else if (perc > (10 * hitpoint_warn))
	{
		color = TERM_YELLOW;
	}
	else
	{
		color = TERM_RED;
	}

	c_put_str(color, tmp, ROW_SANITY, COL_SANITY + 3);
}


/*
 * Print character stat in given row, column
 */
static void prt_stat(int stat)
{
	char tmp[32];

	cnv_stat(p_ptr->stat_use[stat], tmp);

	/* Display "injured" stat */
	if (p_ptr->stat_cur[stat] < p_ptr->stat_max[stat])
	{
		int colour;

		if (p_ptr->stat_cnt[stat])
			colour = TERM_ORANGE;
		else
			colour = TERM_YELLOW;

		put_str(format("%s: ", stat_names_reduced[stat]), ROW_STAT + stat, 0);
		c_put_str(colour, tmp, ROW_STAT + stat, COL_STAT + 6);
	}

	/* Display "healthy" stat */
	else
	{
		put_str(format("%s: ", stat_names[stat]), ROW_STAT + stat, 0);
		c_put_str(TERM_L_GREEN, tmp, ROW_STAT + stat, COL_STAT + 6);
	}

	/* Display "boosted" stat */
	if (p_ptr->stat_cur[stat] > p_ptr->stat_max[stat])
	{
		put_str(format("%s: ", stat_names[stat]), ROW_STAT + stat, 0);
		c_put_str(TERM_VIOLET, tmp, ROW_STAT + stat, COL_STAT + 6);
	}

	/* Indicate natural maximum */
	if (p_ptr->stat_max[stat] == 18 + 100)
	{
		put_str("!", ROW_STAT + stat, 3);
	}
}




/*
 * Prints "title", including "wizard" or "winner" as needed.
 */
static void prt_title(void)
{
	cptr p = "";

	/* Mimic shape */
	if (p_ptr->mimic_form)
	{
		call_lua("get_mimic_info", "(d,s)", "s", p_ptr->mimic_form, "show_name", &p);
	}

	/* Wizard */
	else if (wizard)
	{
		p = "[=-WIZARD-=]";
	}

	/* Winner */
	else if (total_winner == WINNER_NORMAL)
	{
		p = "***WINNER***";
	}

	/* Ultra Winner */
	else if (total_winner == WINNER_ULTRA)
	{
		p = "***GOD***";
	}

	/* Normal */
	else
	{
		p = cp_ptr->titles[(p_ptr->lev - 1) / 5] + c_text;

	}

	prt_field(p, ROW_TITLE, COL_TITLE);
}


/*
 * Prints level
 */
static void prt_level(void)
{
	char tmp[32];

	sprintf(tmp, "%6d", p_ptr->lev);

	if (p_ptr->lev >= p_ptr->max_plv)
	{
		put_str("LEVEL ", ROW_LEVEL, 0);
		c_put_str(TERM_L_GREEN, tmp, ROW_LEVEL, COL_LEVEL + 6);
	}
	else
	{
		put_str("Level ", ROW_LEVEL, 0);
		c_put_str(TERM_YELLOW, tmp, ROW_LEVEL, COL_LEVEL + 6);
	}
}


/*
 * Display the experience
 */
static void prt_exp(void)
{
	char out_val[32];

	if (!exp_need)
	{
		(void)sprintf(out_val, "%8ld", (long)p_ptr->exp);
	}
	else
	{
		if ((p_ptr->lev >= PY_MAX_LEVEL) || (p_ptr->lev >= max_plev))
		{
			(void)sprintf(out_val, "********");
		}
		else
		{
			(void)sprintf(out_val, "%8ld", (long)(player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L) - p_ptr->exp);
		}
	}

	if (p_ptr->exp >= p_ptr->max_exp)
	{
		put_str("EXP ", ROW_EXP, 0);
		c_put_str(TERM_L_GREEN, out_val, ROW_EXP, COL_EXP + 4);
	}
	else
	{
		put_str("Exp ", ROW_EXP, 0);
		c_put_str(TERM_YELLOW, out_val, ROW_EXP, COL_EXP + 4);
	}
}


/*
 * Prints current gold
 */
static void prt_gold(void)
{
	char tmp[32];

	put_str("AU ", ROW_GOLD, COL_GOLD);
	sprintf(tmp, "%9ld", (long)p_ptr->au);
	c_put_str(TERM_L_GREEN, tmp, ROW_GOLD, COL_GOLD + 3);
}



/*
 * Prints current AC
 */
static void prt_ac(void)
{
	char tmp[32];

	put_str("Cur AC ", ROW_AC, COL_AC);
	sprintf(tmp, "%5d", p_ptr->dis_ac + p_ptr->dis_to_a);
	c_put_str(TERM_L_GREEN, tmp, ROW_AC, COL_AC + 7);
}


/*
 * Prints Cur/Max hit points
 */
static void prt_hp(void)
{
	char tmp[32];

	byte color;

	if (player_char_health) lite_spot(p_ptr->py, p_ptr->px);

	if (p_ptr->necro_extra & CLASS_UNDEAD)
	{
		c_put_str(TERM_L_DARK, "DP ", ROW_HP, COL_HP);

		sprintf(tmp, "%4d/%4d", p_ptr->chp, p_ptr->mhp);

		if (p_ptr->chp >= p_ptr->mhp)
		{
			color = TERM_L_BLUE;
		}
		else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10)
		{
			color = TERM_VIOLET;
		}
		else
		{
			color = TERM_L_RED;
		}
		c_put_str(color, tmp, ROW_HP, COL_HP + 3);
	}
	else
	{
		c_put_str(TERM_RED, "HP ", ROW_HP, COL_HP);

		sprintf(tmp, "%4d/%4d", p_ptr->chp, p_ptr->mhp);

		if (p_ptr->chp >= p_ptr->mhp)
		{
			color = TERM_L_GREEN;
		}
		else if (p_ptr->chp > (p_ptr->mhp * hitpoint_warn) / 10)
		{
			color = TERM_YELLOW;
		}
		else
		{
			color = TERM_RED;
		}
		c_put_str(color, tmp, ROW_HP, COL_HP + 3);
	}
}

/*
 * Prints Cur/Max monster hit points
 */
static void prt_mh(void)
{
	char tmp[32];

	byte color;

	object_type *o_ptr;
	monster_race *r_ptr;

	/* Get the carried monster */
	o_ptr = &p_ptr->inventory[INVEN_CARRY];

	if (!o_ptr->pval2)
	{
		put_str("             ", ROW_MH, COL_MH);
		return;
	}

	r_ptr = &r_info[o_ptr->pval];

	put_str("MH ", ROW_MH, COL_MH);

	sprintf(tmp, "%4d/%4d", o_ptr->pval2, (int)o_ptr->pval3);
	if (o_ptr->pval2 >= o_ptr->pval3)
	{
		color = TERM_L_GREEN;
	}
	else if (o_ptr->pval2 > (o_ptr->pval3 * hitpoint_warn) / 10)
	{
		color = TERM_YELLOW;
	}
	else
	{
		color = TERM_RED;
	}
	c_put_str(color, tmp, ROW_MH, COL_MH + 3);
}


/*
 * Prints players max/cur spell points
 */
static void prt_sp(void)
{
	char tmp[32];
	byte color;


	c_put_str(TERM_L_GREEN, "SP ", ROW_SP, COL_SP);

	sprintf(tmp, "%4d/%4d", p_ptr->csp, p_ptr->msp);
	if (p_ptr->csp >= p_ptr->msp)
	{
		color = TERM_L_GREEN;
	}
	else if (p_ptr->csp > (p_ptr->msp * hitpoint_warn) / 10)
	{
		color = TERM_YELLOW;
	}
	else
	{
		color = TERM_RED;
	}
	c_put_str(color, tmp, ROW_SP, COL_SP + 3);
}


/*
 * Prints depth in stat area
 */
static void prt_depth(void)
{
	char depths[32];
	dungeon_info_type *d_ptr = &d_info[dungeon_type];

	if (p_ptr->wild_mode)
	{
		strcpy(depths, "             ");
	}
	else if (p_ptr->inside_arena)
	{
		strcpy(depths, "Arena");
	}
	else if (get_dungeon_name(depths))
	{
		/* Empty */
	}
	else if (dungeon_flags2 & DF2_SPECIAL)
	{
		strcpy(depths, "Special");
	}
	else if (p_ptr->inside_quest)
	{
		strcpy(depths, "Quest");
	}
	else if (!dun_level)
	{
		if (wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name + wf_name)
			strcpy(depths, wf_info[wild_map[p_ptr->wilderness_y][p_ptr->wilderness_x].feat].name + wf_name);
		else
			strcpy(depths, "Town/Wild");
	}
	else if (depth_in_feet)
	{
		if (dungeon_flags1 & DF1_TOWER)
		{
			(void)strnfmt(depths, 32, "%c%c%c -%d ft",
			              d_ptr->short_name[0],
			              d_ptr->short_name[1],
			              d_ptr->short_name[2],
			              dun_level * 50);
		}
		else
		{
			(void)strnfmt(depths, 32, "%c%c%c %d ft",
			              d_ptr->short_name[0],
			              d_ptr->short_name[1],
			              d_ptr->short_name[2],
			              dun_level * 50);
		}
	}
	else
	{
		if (dungeon_flags1 & DF1_TOWER)
		{
			(void)strnfmt(depths, 32, "%c%c%c -%d",
			              d_ptr->short_name[0],
			              d_ptr->short_name[1],
			              d_ptr->short_name[2],
			              dun_level);
		}
		else
		{
			(void)strnfmt(depths, 32, "%c%c%c %d",
			              d_ptr->short_name[0],
			              d_ptr->short_name[1],
			              d_ptr->short_name[2],
			              dun_level);
		}
	}

	/* Right-Adjust the "depth", and clear old values */
	if (p_ptr->word_recall)
		c_prt(TERM_ORANGE, format("%13s", depths), ROW_DEPTH, COL_DEPTH);
	else
		prt(format("%13s", depths), ROW_DEPTH, COL_DEPTH);
}


/*
 * Prints status of hunger
 */
static void prt_hunger(void)
{
	/* Fainting / Starving */
	if (p_ptr->food < PY_FOOD_FAINT)
	{
		c_put_str(TERM_RED, "Weak  ", ROW_HUNGRY, COL_HUNGRY);
	}

	/* Weak */
	else if (p_ptr->food < PY_FOOD_WEAK)
	{
		c_put_str(TERM_ORANGE, "Weak  ", ROW_HUNGRY, COL_HUNGRY);
	}

	/* Hungry */
	else if (p_ptr->food < PY_FOOD_ALERT)
	{
		c_put_str(TERM_YELLOW, "Hungry", ROW_HUNGRY, COL_HUNGRY);
	}

	/* Normal */
	else if (p_ptr->food < PY_FOOD_FULL)
	{
		c_put_str(TERM_L_GREEN, "      ", ROW_HUNGRY, COL_HUNGRY);
	}

	/* Full */
	else if (p_ptr->food < PY_FOOD_MAX)
	{
		c_put_str(TERM_L_GREEN, "Full  ", ROW_HUNGRY, COL_HUNGRY);
	}

	/* Gorged */
	else
	{
		c_put_str(TERM_GREEN, "Gorged", ROW_HUNGRY, COL_HUNGRY);
	}
}


/*
 * Prints Blind status
 */
static void prt_blind(void)
{
	if (p_ptr->blind)
	{
		c_put_str(TERM_ORANGE, "Blind", ROW_BLIND, COL_BLIND);
	}
	else
	{
		put_str("     ", ROW_BLIND, COL_BLIND);
	}
}


/*
 * Prints Confusion status
 */
static void prt_confused(void)
{
	if (p_ptr->confused)
	{
		c_put_str(TERM_ORANGE, "Conf", ROW_CONFUSED, COL_CONFUSED);
	}
	else
	{
		put_str("    ", ROW_CONFUSED, COL_CONFUSED);
	}
}


/*
 * Prints Fear status
 */
static void prt_afraid(void)
{
	if (p_ptr->afraid)
	{
		c_put_str(TERM_ORANGE, "Afraid", ROW_AFRAID, COL_AFRAID);
	}
	else
	{
		put_str("      ", ROW_AFRAID, COL_AFRAID);
	}
}


/*
 * Prints Poisoned status
 */
static void prt_poisoned(void)
{
	if (p_ptr->poisoned)
	{
		c_put_str(TERM_ORANGE, "Poison", ROW_POISONED, COL_POISONED);
	}
	else
	{
		put_str("      ", ROW_POISONED, COL_POISONED);
	}
}


/*
 * Prints trap detection status
 */
static void prt_dtrap(void)
{
	if (cave[p_ptr->py][p_ptr->px].info & CAVE_DETECT)
	{
		c_put_str(TERM_L_GREEN, "DTrap", ROW_DTRAP, COL_DTRAP);
	}
	else
	{
		put_str("     ", ROW_DTRAP, COL_DTRAP);
	}
}


/*
 * Prints Searching, Resting, Paralysis, or 'count' status
 * Display is always exactly 10 characters wide (see below)
 *
 * This function was a major bottleneck when resting, so a lot of
 * the text formatting code was optimized in place below.
 */
static void prt_state(void)
{
	byte attr = TERM_WHITE;

	char text[16];


	/* Paralysis */
	if (p_ptr->paralyzed)
	{
		attr = TERM_RED;

		strcpy(text, "Paralyzed!");
	}

	/* Resting */
	else if (resting)
	{
		int i;

		/* Start with "Rest" */
		strcpy(text, "Rest      ");

		/* Extensive (timed) rest */
		if (resting >= 1000)
		{
			i = resting / 100;
			text[9] = '0';
			text[8] = '0';
			text[7] = '0' + (i % 10);
			if (i >= 10)
			{
				i = i / 10;
				text[6] = '0' + (i % 10);
				if (i >= 10)
				{
					text[5] = '0' + (i / 10);
				}
			}
		}

		/* Long (timed) rest */
		else if (resting >= 100)
		{
			i = resting;
			text[9] = '0' + (i % 10);
			i = i / 10;
			text[8] = '0' + (i % 10);
			text[7] = '0' + (i / 10);
		}

		/* Medium (timed) rest */
		else if (resting >= 10)
		{
			i = resting;
			text[9] = '0' + (i % 10);
			text[8] = '0' + (i / 10);
		}

		/* Short (timed) rest */
		else if (resting > 0)
		{
			i = resting;
			text[9] = '0' + (i);
		}

		/* Rest until healed */
		else if (resting == -1)
		{
			text[5] = text[6] = text[7] = text[8] = text[9] = '*';
		}

		/* Rest until done */
		else if (resting == -2)
		{
			text[5] = text[6] = text[7] = text[8] = text[9] = '&';
		}
	}

	/* Repeating */
	else if (command_rep)
	{
		if (command_rep > 999)
		{
			(void)sprintf(text, "Rep. %3d00", command_rep / 100);
		}
		else
		{
			(void)sprintf(text, "Repeat %3d", command_rep);
		}
	}

	/* Searching */
	else if (p_ptr->searching)
	{
		strcpy(text, "Searching ");
	}

	/* Nothing interesting */
	else
	{
		strcpy(text, "          ");
	}

	/* Display the info (or blanks) */
	c_put_str(attr, text, ROW_STATE, COL_STATE);
}


/*
 * Prints the speed of a character.			-CJS-
 */
static void prt_speed(void)
{
	int i = p_ptr->pspeed;

	byte attr = TERM_WHITE;
	char buf[32] = "";

	/* Hack -- Visually "undo" the Search Mode Slowdown */
	if (p_ptr->searching) i += 10;

	/* Fast */
	if (i > 110)
	{
		attr = TERM_L_GREEN;
		sprintf(buf, "Fast (+%d)", (i - 110));
	}

	/* Slow */
	else if (i < 110)
	{
		attr = TERM_L_UMBER;
		sprintf(buf, "Slow (-%d)", (110 - i));
	}

	/* Display the speed */
	c_put_str(attr, format("%-10s", buf), ROW_SPEED, COL_SPEED);
}


static void prt_study(void)
{
	if (p_ptr->skill_points)
	{
		put_str("Skill", ROW_STUDY, COL_STUDY);
	}
	else
	{
		put_str("     ", ROW_STUDY, COL_STUDY);
	}
}


static void prt_cut(void)
{
	int c = p_ptr->cut;

	if (c > 1000)
	{
		c_put_str(TERM_L_RED, "Mortal wound", ROW_CUT, COL_CUT);
	}
	else if (c > 200)
	{
		c_put_str(TERM_RED, "Deep gash   ", ROW_CUT, COL_CUT);
	}
	else if (c > 100)
	{
		c_put_str(TERM_RED, "Severe cut  ", ROW_CUT, COL_CUT);
	}
	else if (c > 50)
	{
		c_put_str(TERM_ORANGE, "Nasty cut   ", ROW_CUT, COL_CUT);
	}
	else if (c > 25)
	{
		c_put_str(TERM_ORANGE, "Bad cut     ", ROW_CUT, COL_CUT);
	}
	else if (c > 10)
	{
		c_put_str(TERM_YELLOW, "Light cut   ", ROW_CUT, COL_CUT);
	}
	else if (c)
	{
		c_put_str(TERM_YELLOW, "Graze       ", ROW_CUT, COL_CUT);
	}
	else
	{
		put_str("            ", ROW_CUT, COL_CUT);
	}
}



static void prt_stun(void)
{
	int s = p_ptr->stun;

	if (s > 100)
	{
		c_put_str(TERM_RED, "Knocked out ", ROW_STUN, COL_STUN);
	}
	else if (s > 50)
	{
		c_put_str(TERM_ORANGE, "Heavy stun  ", ROW_STUN, COL_STUN);
	}
	else if (s)
	{
		c_put_str(TERM_ORANGE, "Stun        ", ROW_STUN, COL_STUN);
	}
	else
	{
		put_str("            ", ROW_STUN, COL_STUN);
	}
}



/*
 * Redraw the "monster health bar"	-DRS-
 * Rather extensive modifications by	-BEN-
 *
 * The "monster health bar" provides visual feedback on the "health"
 * of the monster currently being "tracked".  There are several ways
 * to "track" a monster, including targetting it, attacking it, and
 * affecting it (and nobody else) with a ranged attack.
 *
 * Display the monster health bar (affectionately known as the
 * "health-o-meter").  Clear health bar if nothing is being tracked.
 * Auto-track current target monster when bored.  Note that the
 * health-bar stops tracking any monster that "disappears".
 */
static void health_redraw(void)
{

#ifdef DRS_SHOW_HEALTH_BAR

	/* Not tracking */
	if (!health_who)
	{
		/* Erase the health bar */
		Term_erase(COL_INFO, ROW_INFO, 12);
	}

	/* Tracking an unseen monster */
	else if (!m_list[health_who].ml)
	{
		/* Indicate that the monster health is "unknown" */
		Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");
	}

	/* Tracking a hallucinatory monster */
	else if (p_ptr->image)
	{
		/* Indicate that the monster health is "unknown" */
		Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");
	}

	/* Tracking a dead monster (???) */
	else if (!m_list[health_who].hp < 0)
	{
		/* Indicate that the monster health is "unknown" */
		Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");
	}

	/* Tracking a visible monster */
	else
	{
		int pct, len;

		monster_type *m_ptr = &m_list[health_who];

		/* Default to almost dead */
		byte attr = TERM_RED;

		/* Extract the "percent" of health */
		pct = 100L * m_ptr->hp / m_ptr->maxhp;

		/* Badly wounded */
		if (pct >= 10) attr = TERM_L_RED;

		/* Wounded */
		if (pct >= 25) attr = TERM_ORANGE;

		/* Somewhat Wounded */
		if (pct >= 60) attr = TERM_YELLOW;

		/* Healthy */
		if (pct >= 100) attr = TERM_L_GREEN;

		/* Afraid */
		if (m_ptr->monfear) attr = TERM_VIOLET;

		/* Asleep */
		if (m_ptr->csleep) attr = TERM_BLUE;

		/* Poisoned */
		if (m_ptr->poisoned) attr = TERM_GREEN;

		/* Bleeding */
		if (m_ptr->bleeding) attr = TERM_RED;

		/* Convert percent into "health" */
		len = (pct < 10) ? 1 : (pct < 90) ? (pct / 10 + 1) : 10;

		/* Default to "unknown" */
		Term_putstr(COL_INFO, ROW_INFO, 12, TERM_WHITE, "[----------]");

		/* Dump the current "health" (use '*' symbols) */
		Term_putstr(COL_INFO + 1, ROW_INFO, len, attr, "**********");
	}

#endif

}



/*
 * Display basic info (mostly left of map)
 */
static void prt_frame_basic(void)
{
	int i;

	/* Race and Class */
	prt_field(rp_ptr->title + rp_name, ROW_RACE, COL_RACE);
	prt_field(spp_ptr->title + c_name, ROW_CLASS, COL_CLASS);

	/* Title */
	prt_title();

	/* Level/Experience */
	prt_level();
	prt_exp();

	/* All Stats */
	for (i = 0; i < 6; i++) prt_stat(i);

	/* Armor */
	prt_ac();

	/* Hitpoints */
	prt_hp();

	/* Current sanity */
	prt_sane();

	/* Spellpoints */
	prt_sp();

	/* Piety */
	prt_piety();

	/* Monster hitpoints */
	prt_mh();

	/* Gold */
	prt_gold();

	/* Current depth */
	prt_depth();

	/* Special */
	health_redraw();
}


/*
 * Display extra info (mostly below map)
 */
static void prt_frame_extra(void)
{
	/* Cut/Stun */
	prt_cut();
	prt_stun();

	/* Food */
	prt_hunger();

	/* Various */
	prt_blind();
	prt_confused();
	prt_afraid();
	prt_poisoned();
	prt_dtrap();

	/* State */
	prt_state();

	/* Speed */
	prt_speed();

	/* Study spells */
	prt_study();
}


/*
 * Hack -- display inventory in sub-windows
 */
static void fix_inven(void)
{
	int j;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_INVEN))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Display inventory */
		display_inven();

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}



/*
 * Hack -- display equipment in sub-windows
 */
static void fix_equip(void)
{
	int j;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_EQUIP))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Display equipment */
		display_equip();

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}

/*
 * Hack -- display character in sub-windows
 */
static void fix_player(void)
{
	int j;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_PLAYER))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Display player */
		display_player(0);

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}



/*
 * Hack -- display recent messages in sub-windows
 *
 * XXX XXX XXX Adjust for width and split messages
 */
void fix_message(void)
{
	int j, i;
	int w, h;
	int x, y;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_MESSAGE))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Get size */
		Term_get_size(&w, &h);

		/* Dump messages */
		for (i = 0; i < h; i++)
		{
			/* Dump the message on the appropriate line */
			display_message(0, (h - 1) - i, strlen(message_str((s16b)i)), message_color((s16b)i), message_str((s16b)i));

			/* Cursor */
			Term_locate(&x, &y);

			/* Clear to end of line */
			Term_erase(x, y, 255);
		}

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}


/*
 * Hack -- display recent IRC messages in sub-windows
 *
 * XXX XXX XXX Adjust for width and split messages
 */
void fix_irc_message(void)
{
	int j, i, k;
	int w, h;
	int x, y;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_IRC))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Get size */
		Term_get_size(&w, &h);

		Term_clear();

		/* Dump messages */
		k = 0;
		for (i = 0; ; i++)
		{
			byte type = message_type((s16b)i);

			if (k >= h) break;
			if (MESSAGE_NONE == type) break;
			if (MESSAGE_IRC != type) continue;

			/* Dump the message on the appropriate line */
			display_message(0, (h - 1) - k, strlen(message_str((s16b)i)), message_color((s16b)i), message_str((s16b)i));

			/* Cursor */
			Term_locate(&x, &y);

			/* Clear to end of line */
			Term_erase(x, y, 255);

			k++;
		}

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}


/*
 * Hack -- display overhead view in sub-windows
 *
 * Note that the "player" symbol does NOT appear on the map.
 */
static void fix_overhead(void)
{
	int j;

	int cy, cx;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_OVERHEAD))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Redraw map */
		display_map(&cy, &cx);

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}


/*
 * Hack -- display monster recall in sub-windows
 */
static void fix_monster(void)
{
	int j;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_MONSTER))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Display monster race info */
		if (monster_race_idx) display_roff(monster_race_idx, monster_ego_idx);

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}


/*
 * Hack -- display object recall in sub-windows
 */
static void fix_object(void)
{
	int j;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_OBJECT))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Clear */
		Term_clear();

		/* Display object info */
		if (tracked_object)
			if (!object_out_desc(tracked_object, NULL, FALSE, FALSE)) text_out("You see nothing special.");

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}

/* Show the monster list in a window */

static void fix_m_list(void)
{
	int i, j;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		term *old = Term;

		int c = 0;

		/* No window */
		if (!angband_term[j]) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_M_LIST))) continue;

		/* Activate */
		Term_activate(angband_term[j]);

		/* Clear */
		Term_clear();

		/* Hallucination */
		if (p_ptr->image)
		{
			c_prt(TERM_WHITE, "You can not see clearly", 0, 0);

			/* Fresh */
			Term_fresh();

			/* Restore */
			Term_activate(old);

			return;
		}

		/* reset visible count */
		for (i = 1; i < max_r_idx; i++)
		{
			monster_race *r_ptr = &r_info[i];

			r_ptr->total_visible = 0;
		}

		/* Count up the number visible in each race */
		for (i = 1; i < m_max; i++)
		{
			monster_type *m_ptr = &m_list[i];
			monster_race *r_ptr = &r_info[m_ptr->r_idx];

			/* Skip dead monsters */
			if (m_ptr->hp < 0) continue;

			/* Skip unseen monsters */
			if (r_ptr->flags9 & RF9_MIMIC)
			{
				object_type *o_ptr;

				/* Acquire object */
				o_ptr = &o_list[m_ptr->hold_o_idx];

				/* Memorized objects */
				if (!o_ptr->marked) continue;
			}
			else
			{
				if (!m_ptr->ml) continue;
			}

			/* Increase for this race */
			r_ptr->total_visible++;

			/* Increase total Count */
			c++;
		}

		/* Are monsters visible? */
		if (c)
		{
			int w, h, num = 0;

			(void)Term_get_size(&w, &h);

			c_prt(TERM_WHITE, format("You can see %d monster%s", c, (c > 1 ? "s:" : ":")), 0, 0);

			for (i = 1; i < max_r_idx; i++)
			{
				monster_race *r_ptr = &r_info[i];

				/* Default Colour */
				byte attr = TERM_SLATE;

				/* Only visible monsters */
				if (!r_ptr->total_visible) continue;

				/* Uniques */
				if (r_ptr->flags1 & RF1_UNIQUE)
				{
					attr = TERM_L_BLUE;
				}

				/* Have we ever killed one? */
				if (r_ptr->r_tkills)
				{
					if (r_ptr->level > dun_level)
					{
						attr = TERM_VIOLET;

						if (r_ptr->flags1 & RF1_UNIQUE)
						{
							attr = TERM_RED;
						}
					}
				}
				else
				{
					if (!(r_ptr->flags1 & RF1_UNIQUE)) attr = TERM_GREEN;
				}


				/* Dump the monster name */
				if (r_ptr->total_visible == 1)
				{
					c_prt(attr, (r_name + r_ptr->name), (num % (h - 1)) + 1, (num / (h - 1) * 26));
				}
				else
				{
					c_prt(attr, format("%s (x%d)", r_name + r_ptr->name, r_ptr->total_visible), (num % (h - 1)) + 1, (num / (h - 1)) * 26);
				}

				num++;

			}

		}
		else
		{
			c_prt(TERM_WHITE, "You see no monsters.", 0, 0);
		}

		/* Fresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}


/*
 * Calculate number of spells player should have, and forget,
 * or remember, spells until that number is properly reflected.
 *
 * Note that this function induces various "status" messages,
 * which must be bypasses until the character is created.
 */
static void calc_spells(void)
{
	p_ptr->new_spells = 0;
}

/* Ugly hack */
bool calc_powers_silent = FALSE;

/* Calc the player powers */
static void calc_powers(void)
{
	int i, p = 0;
	bool *old_powers;

	/* Hack -- wait for creation */
	if (!character_generated) return;

	/* Hack -- handle "xtra" mode */
	if (character_xtra) return;

	C_MAKE(old_powers, power_max, bool);

	/* Save old powers */
	for (i = 0; i < power_max; i++) old_powers[i] = p_ptr->powers[i];

	/* Get intrinsincs */
	for (i = 0; i < POWER_MAX_INIT; i++) p_ptr->powers[i] = p_ptr->powers_mod[i];
	for (; i < power_max; i++) p_ptr->powers[i] = 0;

	/* Hooked powers */
	process_hooks(HOOK_CALC_POWERS, "()");

	/* Add objects powers */
	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
	{
		object_type *o_ptr = &p_ptr->inventory[i];

		if (!o_ptr->k_idx) continue;

		p = object_power(o_ptr);
		if (p != -1) p_ptr->powers[p] = TRUE;
	}

	if ((!p_ptr->tim_mimic) && (!p_ptr->body_monster))
	{
		/* Add in racial and subracial powers */
		for (i = 0; i < 4; i++)
		{
			p = rp_ptr->powers[i];
			if (p != -1) p_ptr->powers[p] = TRUE;

			p = rmp_ptr->powers[i];
			if (p != -1) p_ptr->powers[p] = TRUE;
		}
	}
	else if (p_ptr->mimic_form)
		call_lua("calc_mimic_power", "(d)", "", p_ptr->mimic_form);

	/* Add in class powers */
	for (i = 0; i < 4; i++)
	{
		p = cp_ptr->powers[i];
		if (p != -1) p_ptr->powers[p] = TRUE;
	}

	if (p_ptr->disembodied)
	{
		p = PWR_INCARNATE;
		p_ptr->powers[p] = TRUE;
	}

	/* Now lets warn the player */
	for (i = 0; i < power_max; i++)
	{
		s32b old = old_powers[i];
		s32b new = p_ptr->powers[i];

		if (new > old)
		{
			if (!calc_powers_silent) cmsg_print(TERM_GREEN, powers_type[i].gain_text);
		}
		else if (new < old)
		{
			if (!calc_powers_silent) cmsg_print(TERM_RED, powers_type[i].lose_text);
		}
	}

	calc_powers_silent = FALSE;
	C_FREE(old_powers, power_max, bool);
}


/*
 * Calculate the player's sanity
 */

void calc_sanity(void)
{
	int bonus, msane;

	/* Hack -- use the con/hp table for sanity/wis */
	bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_WIS]]) - 128);

	/* Hack -- assume 5 sanity points per level. */
	msane = 5 * (p_ptr->lev + 1) + (bonus * p_ptr->lev / 2);

	if (msane < p_ptr->lev + 1) msane = p_ptr->lev + 1;

	if (p_ptr->msane != msane)
	{
		/* Sanity carries over between levels. */
		p_ptr->csane += (msane - p_ptr->msane);

		p_ptr->msane = msane;

		if (p_ptr->csane >= msane)
		{
			p_ptr->csane = msane;
			p_ptr->csane_frac = 0;
		}

		p_ptr->redraw |= (PR_SANITY);
		p_ptr->window |= (PW_PLAYER);
	}
}


/*
 * Calculate maximum mana.  You do not need to know any spells.
 * Note that mana is lowered by heavy (or inappropriate) armor.
 *
 * This function induces status messages.
 */
static void calc_mana(void)
{
	int msp, levels, cur_wgt, max_wgt;
	u32b f1, f2, f3, f4, f5, esp;

	object_type *o_ptr;

	levels = p_ptr->lev;

	/* Hack -- no negative mana */
	if (levels < 0) levels = 0;

	/* Extract total mana */
	msp = get_skill_scale(SKILL_MAGIC, 200) +
	      (adj_mag_mana[
	               (p_ptr->stat_ind[A_INT] > p_ptr->stat_ind[A_WIS]) ?
	               p_ptr->stat_ind[A_INT] : p_ptr->stat_ind[A_WIS]
	       ] * levels / 4);

	/* Hack -- usually add one mana */
	if (msp) msp++;

	/* Possessors mana is different */
	if (p_ptr->body_monster && (!p_ptr->disembodied))
	{
		monster_race *r_ptr = &r_info[p_ptr->body_monster];
		int f = 100 / (r_ptr->freq_spell ? r_ptr->freq_spell : 1);

		msp = 21 - f;

		if (msp < 1) msp = 1;
	}

	/* Apply race mod mana */
	msp = msp * rmp_ptr->mana / 100;

	/* Apply class mana */
	msp += msp * cp_ptr->mana / 100;

	/* Apply Eru mana */
	GOD(GOD_ERU)
	{
		s32b tmp = p_ptr->grace;

		if (tmp >= 35000) tmp = 35000;
		tmp /= 100;
		msp += msp * tmp / 1000;
	}

	/* Only mages are affected */
	if (forbid_gloves())
	{
		/* Assume player is not encumbered by gloves */
		p_ptr->cumber_glove = FALSE;

		/* Get the gloves */
		o_ptr = &p_ptr->inventory[INVEN_HANDS];

		/* Examine the gloves */
		object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);

		/* Normal gloves hurt mage-type spells */
		if (o_ptr->k_idx &&
		                !(f2 & (TR2_FREE_ACT)) &&
		                !((f1 & (TR1_DEX)) && (o_ptr->pval > 0)) &&
		                !(f5 & TR5_SPELL_CONTAIN))
		{
			/* Encumbered */
			p_ptr->cumber_glove = TRUE;

			/* Reduce mana */
			msp = (3 * msp) / 4;
		}
	}

	/* Augment mana */
	if (munchkin_multipliers)
	{
		if (p_ptr->to_m) msp += msp * p_ptr->to_m / 5;
	}
	else
	{
		if (p_ptr->to_m) msp += msp * p_ptr->to_m / 10;
	}

	/* Assume player not encumbered by armor */
	p_ptr->cumber_armor = FALSE;

	/* Weigh the armor */
	cur_wgt = 0;
	cur_wgt += p_ptr->inventory[INVEN_BODY].weight;
	cur_wgt += p_ptr->inventory[INVEN_HEAD].weight;
	cur_wgt += p_ptr->inventory[INVEN_ARM].weight;
	cur_wgt += p_ptr->inventory[INVEN_OUTER].weight;
	cur_wgt += p_ptr->inventory[INVEN_HANDS].weight;
	cur_wgt += p_ptr->inventory[INVEN_FEET].weight;

	/* Determine the weight allowance */
	max_wgt = 200 + get_skill_scale(SKILL_COMBAT, 500);

	/* Heavy armor penalizes mana */
	if (((cur_wgt - max_wgt) / 10) > 0)
	{
		/* Encumbered */
		p_ptr->cumber_armor = TRUE;

		/* Reduce mana */
		msp -= ((cur_wgt - max_wgt) / 10);
	}

	/* When meditating your mana is increased ! */
	if (p_ptr->meditation)
	{
		msp += 50;
		p_ptr->csp += 50;
	}

	/* Sp mods? */
	if (process_hooks_ret(HOOK_CALC_MANA, "d", "(d)", msp))
	{
		msp = process_hooks_return[0].num;
	}

	/* Mana can never be negative */
	if (msp < 0) msp = 0;


	/* Maximum mana has changed */
	if (p_ptr->msp != msp)
	{
		/* Save new limit */
		p_ptr->msp = msp;

		/* Enforce new limit */
		if (p_ptr->csp >= msp)
		{
			p_ptr->csp = msp;
			p_ptr->csp_frac = 0;
		}

		/* Display mana later */
		p_ptr->redraw |= (PR_MANA);

		/* Window stuff */
		p_ptr->window |= (PW_PLAYER);
	}


	/* Hack -- handle "xtra" mode */
	if (character_xtra) return;

	/* Take note when "glove state" changes */
	if (p_ptr->old_cumber_glove != p_ptr->cumber_glove)
	{
		/* Message */
		if (p_ptr->cumber_glove)
		{
			msg_print("Your covered hands feel unsuitable for spellcasting.");
		}
		else
		{
			msg_print("Your hands feel more suitable for spellcasting.");
		}

		/* Save it */
		p_ptr->old_cumber_glove = p_ptr->cumber_glove;
	}


	/* Take note when "armor state" changes */
	if (p_ptr->old_cumber_armor != p_ptr->cumber_armor)
	{
		/* Message */
		if (p_ptr->cumber_armor)
		{
			msg_print("The weight of your armor encumbers your movement.");
		}
		else
		{
			msg_print("You feel able to move more freely.");
		}

		/* Save it */
		p_ptr->old_cumber_armor = p_ptr->cumber_armor;
	}
}



/*
 * Calculate the players (maximal) hit points
 * Adjust current hitpoints if necessary
 */
void calc_hitpoints(void)
{
	int bonus, mhp;

	/* Un-inflate "half-hitpoint bonus per level" value */
	bonus = ((int)(adj_con_mhp[p_ptr->stat_ind[A_CON]]) - 128);

	/* Calculate hitpoints */
	mhp = player_hp[p_ptr->lev - 1] + (bonus * p_ptr->lev / 2);

	/* Always have at least one hitpoint per level */
	if (mhp < p_ptr->lev + 1) mhp = p_ptr->lev + 1;

	/* Factor in the pernament hp modifications */
	mhp += p_ptr->hp_mod;
	if (mhp < 1) mhp = 1;

	/* Hack: Sorcery impose a hp penality */
	if (mhp && (get_skill(SKILL_SORCERY)))
	{
		mhp -= mhp * get_skill_scale(SKILL_SORCERY, 50) / 100;
		if (mhp < 1) mhp = 1;
	}

	/* Factor in the melkor hp modifications */
	GOD(GOD_MELKOR)
	{
		mhp -= (p_ptr->melkor_sacrifice * 10);
		if (mhp < 1) mhp = 1;
	}

	/* Factor in the hero / superhero settings */
	if (p_ptr->hero) mhp += 10;
	if (p_ptr->shero) mhp += 30;

	/* Augment Hitpoint */
	if (munchkin_multipliers)
	{
		mhp += mhp * p_ptr->to_l / 5;
	}
	else
	{
		mhp += mhp * p_ptr->to_l / 10;
	}
	if (mhp < 1) mhp = 1;

	if (p_ptr->body_monster)
	{
		monster_race *r_ptr = &r_info[p_ptr->body_monster];
		u32b rhp = maxroll(r_ptr->hdice, r_ptr->hside);

		/* Adjust the hp with the possession skill */
		rhp = (rhp * (20 + get_skill_scale(SKILL_POSSESSION, 80))) / 100;

		mhp = (rhp + sroot(rhp) + mhp) / 3;
	}
	if (p_ptr->disembodied) mhp = 1;

	/* HACK - being undead means less DP */
	if (p_ptr->necro_extra & CLASS_UNDEAD)
	{
		int divisor = p_ptr->lev / 4;

		/* Beware of the horrible division by zero ! :) */
		if (divisor == 0) divisor = 1;

		/* Actually decrease the max hp */
		mhp /= divisor;

		/* Never less than 1 */
		if (mhp < 1) mhp = 1;
	}

	/* Hp mods? */
	if (process_hooks_ret(HOOK_CALC_HP, "d", "(d)", mhp))
	{
		mhp = process_hooks_return[0].num;
	}

	/* Never less than 1 */
	if (mhp < 1) mhp = 1;

	/* New maximum hitpoints */
	if (p_ptr->mhp != mhp)
	{
		/* XXX XXX XXX New hitpoint maintenance */

		/* Enforce maximum */
		if (p_ptr->chp >= mhp)
		{
			p_ptr->chp = mhp;
			p_ptr->chp_frac = 0;
		}

		/* Save the new max-hitpoints */
		p_ptr->mhp = mhp;

		/* Display hitpoints (later) */
		p_ptr->redraw |= (PR_HP);

		/* Window stuff */
		p_ptr->window |= (PW_PLAYER);
	}
}



/*
 * Extract and set the current "lite radius"
 *
 * SWD: Experimental modification: multiple light sources have additive effect.
 *
 */
static void calc_torch(void)
{
	int i;
	object_type *o_ptr;
	u32b f1, f2, f3, f4, f5, esp;

	/* Assume no light */
	p_ptr->cur_lite = 0;

	/* Loop through all wielded items */
	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
	{
		o_ptr = &p_ptr->inventory[i];

		/* Skip empty slots */
		if (!o_ptr->k_idx) continue;

		/* Extract the flags */
		object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);

		/* does this item glow? */
		if (((f4 & TR4_FUEL_LITE) && (o_ptr->timeout > 0)) || (!(f4 & TR4_FUEL_LITE)))
		{
			if (f3 & TR3_LITE1) p_ptr->cur_lite++;
			if (f4 & TR4_LITE2) p_ptr->cur_lite += 2;
			if (f4 & TR4_LITE3) p_ptr->cur_lite += 3;
		}

	}

	if (p_ptr->tim_lite) p_ptr->cur_lite += 2;

	if (p_ptr->holy) p_ptr->cur_lite += 1;

	/* max radius is 5 without rewriting other code -- */
	/* see cave.c:update_lite() and defines.h:LITE_MAX */
	if (p_ptr->cur_lite > 5) p_ptr->cur_lite = 5;

	/* check if the player doesn't have a lite source, */
	/* but does glow as an intrinsic.                  */
	if (p_ptr->cur_lite == 0 && p_ptr->lite) p_ptr->cur_lite = 1;

	/* Hooked powers */
	process_hooks(HOOK_CALC_LITE, "()");

	/* end experimental mods */

	/* Reduce lite in the small-scale wilderness map */
	if (p_ptr->wild_mode)
	{
		/* Reduce the lite radius if needed */
		if (p_ptr->cur_lite > WILDERNESS_SEE_RADIUS)
		{
			p_ptr->cur_lite = WILDERNESS_SEE_RADIUS;
		}
	}


	/* Reduce lite when running if requested */
	if (running && view_reduce_lite)
	{
		/* Reduce the lite radius if needed */
		if (p_ptr->cur_lite > 1) p_ptr->cur_lite = 1;
	}

	/* Notice changes in the "lite radius" */
	if (p_ptr->old_lite != p_ptr->cur_lite)
	{
		/* Update the view */
		p_ptr->update |= (PU_VIEW);

		/* Update the monsters */
		p_ptr->update |= (PU_MONSTERS);

		/* Remember the old lite */
		p_ptr->old_lite = p_ptr->cur_lite;
	}
}



/*
 * Computes current weight limit.
 */
int weight_limit(void)
{
	int i;

	/* Weight limit based only on strength */
	i = adj_str_wgt[p_ptr->stat_ind[A_STR]] * 100;

	if (process_hooks_ret(HOOK_CALC_WEIGHT, "d", "(d)", i))
		i = process_hooks_return[0].num;

	/* Return the result */
	return (i);
}

void calc_wield_monster()
{
	object_type *o_ptr;
	monster_race *r_ptr;

	/* Get the carried monster */
	o_ptr = &p_ptr->inventory[INVEN_CARRY];

	if (o_ptr->k_idx)
	{
		r_ptr = &r_info[o_ptr->pval];

		if (r_ptr->flags2 & RF2_INVISIBLE)
			p_ptr->invis += 20;
		if (r_ptr->flags2 & RF2_REFLECTING)
			p_ptr->reflect = TRUE;
		if (r_ptr->flags7 & RF7_CAN_FLY)
			p_ptr->ffall = TRUE;
		if (r_ptr->flags7 & RF7_AQUATIC)
			p_ptr->water_breath = TRUE;
	}
}

/*
 * Calc which body parts the player have, based on the
 * monster he incarnate, note that that's bnot a hack
 * since body parts of the player when in it's own body
 * are also defined in r_info(monster 0)
 */
void calc_body()
{
	monster_race *r_ptr = &r_info[p_ptr->body_monster];
	int i, b_weapon, b_legs, b_arms;
	byte *body_parts, bp[BODY_MAX];

	if (!p_ptr->body_monster)
	{
		body_parts = bp;
		for (i = 0; i < BODY_MAX; i++)
		{
			int b;

			b = rp_ptr->body_parts[i] + rmp_ptr->body_parts[i];
			if (b < 0) b = 0;

			if (p_ptr->mimic_form == resolve_mimic_name("Bear"))
			{
				if (i == BODY_ARMS) b = 0;
				else if (i == BODY_LEGS) b = 0;
			}

			bp[i] = b;
		}
	}
	else
	{
		body_parts = bp;
		for (i = 0; i < BODY_MAX; i++)
		{
			int b;

			b = r_ptr->body_parts[i];
			if (b < 0) b = 0;

			bp[i] = b;
		}
	}

	/* Do we need more parts ? ;) */
	for (i = 0; i < BODY_MAX; i++)
		p_ptr->extra_body_parts[i] = 0;
	process_hooks(HOOK_BODY_PARTS, "()");

	for (i = 0; i < BODY_MAX; i++)
	{
		int b;

		b = bp[i] + cp_ptr->body_parts[i] + p_ptr->extra_body_parts[i];
		if (b < 0) b = 0;
		if (b > max_body_part[i]) b = max_body_part[i];

		bp[i] = b;
	}

	b_weapon = body_parts[BODY_WEAPON];
	b_arms = body_parts[BODY_ARMS];
	b_legs = body_parts[BODY_LEGS];

	if (p_ptr->mimic_extra & CLASS_ARMS)
	{
		b_weapon++;
		b_arms++;

		if (b_weapon > 3) b_weapon = 3;
		if (b_arms > 3) b_arms = 3;
	}

	if (p_ptr->mimic_extra & CLASS_LEGS)
	{
		b_legs++;

		if (b_legs > 2) b_legs = 2;
	}

	for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++)
		p_ptr->body_parts[i] = 0;

	for (i = 0; i < b_weapon; i++)
		p_ptr->body_parts[INVEN_WIELD - INVEN_WIELD + i] = INVEN_WIELD;
	if (body_parts[BODY_WEAPON])
		p_ptr->body_parts[INVEN_BOW - INVEN_WIELD] = INVEN_BOW;

	for (i = 0; i < body_parts[BODY_TORSO]; i++)
	{
		p_ptr->body_parts[INVEN_BODY - INVEN_WIELD + i] = INVEN_BODY;
		p_ptr->body_parts[INVEN_OUTER - INVEN_WIELD + i] = INVEN_OUTER;
		p_ptr->body_parts[INVEN_LITE - INVEN_WIELD + i] = INVEN_LITE;
		p_ptr->body_parts[INVEN_AMMO - INVEN_WIELD + i] = INVEN_AMMO;
		p_ptr->body_parts[INVEN_CARRY - INVEN_WIELD + i] = INVEN_CARRY;
	}

	for (i = 0; i < body_parts[BODY_FINGER]; i++)
		p_ptr->body_parts[INVEN_RING - INVEN_WIELD + i] = INVEN_RING;

	for (i = 0; i < body_parts[BODY_HEAD]; i++)
	{
		p_ptr->body_parts[INVEN_HEAD - INVEN_WIELD + i] = INVEN_HEAD;
		p_ptr->body_parts[INVEN_NECK - INVEN_WIELD + i] = INVEN_NECK;
	}

	for (i = 0; i < b_arms; i++)
	{
		p_ptr->body_parts[INVEN_ARM - INVEN_WIELD + i] = INVEN_ARM;
		p_ptr->body_parts[INVEN_HANDS - INVEN_WIELD + i] = INVEN_HANDS;
	}
	if (body_parts[BODY_ARMS])
		p_ptr->body_parts[INVEN_TOOL - INVEN_WIELD] = INVEN_TOOL;

	for (i = 0; i < b_legs; i++)
		p_ptr->body_parts[INVEN_FEET - INVEN_WIELD + i] = INVEN_FEET;

	/* Ok now if the player lost a body part, he must drop the object he had on it */
	for (i = 0; i < INVEN_TOTAL - INVEN_WIELD; i++)
	{
		if ((!p_ptr->body_parts[i]) && (p_ptr->inventory[i + INVEN_WIELD].k_idx))
		{
			/* Drop it NOW ! */
			inven_takeoff(i + INVEN_WIELD, 255, TRUE);
		}
	}
}

/* Should be called by every calc_bonus call */
void calc_body_bonus()
{
	monster_race *r_ptr = &r_info[p_ptr->body_monster];

	/* If in the player body nothing have to be done */
	if (!p_ptr->body_monster) return;

	if (p_ptr->disembodied)
	{
		p_ptr->wraith_form = TRUE;
		return;
	}

	p_ptr->ac += r_ptr->ac;
	p_ptr->pspeed = r_ptr->speed;

	if (r_ptr->flags1 & RF1_NEVER_MOVE) p_ptr->immovable = TRUE;
	if (r_ptr->flags2 & RF2_STUPID) p_ptr->stat_add[A_INT] -= 1;
	if (r_ptr->flags2 & RF2_SMART) p_ptr->stat_add[A_INT] += 1;
	if (r_ptr->flags2 & RF2_REFLECTING) p_ptr->reflect = TRUE;
	if (r_ptr->flags2 & RF2_INVISIBLE) p_ptr->invis += 20;
	if (r_ptr->flags2 & RF2_REGENERATE) p_ptr->regenerate = TRUE;
	if (r_ptr->flags2 & RF2_AURA_FIRE) p_ptr->sh_fire = TRUE;
	if (r_ptr->flags2 & RF2_AURA_ELEC) p_ptr->sh_elec = TRUE;
	if (r_ptr->flags2 & RF2_PASS_WALL) p_ptr->wraith_form = TRUE;
	if (r_ptr->flags3 & RF3_SUSCEP_FIRE) p_ptr->sensible_fire = TRUE;
	if (r_ptr->flags3 & RF3_IM_ACID) p_ptr->resist_acid = TRUE;
	if (r_ptr->flags3 & RF3_IM_ELEC) p_ptr->resist_elec = TRUE;
	if (r_ptr->flags3 & RF3_IM_FIRE) p_ptr->resist_fire = TRUE;
	if (r_ptr->flags3 & RF3_IM_POIS) p_ptr->resist_pois = TRUE;
	if (r_ptr->flags3 & RF3_IM_COLD) p_ptr->resist_cold = TRUE;
	if (r_ptr->flags3 & RF3_RES_NETH) p_ptr->resist_neth = TRUE;
	if (r_ptr->flags3 & RF3_RES_NEXU) p_ptr->resist_nexus = TRUE;
	if (r_ptr->flags3 & RF3_RES_DISE) p_ptr->resist_disen = TRUE;
	if (r_ptr->flags3 & RF3_NO_FEAR) p_ptr->resist_fear = TRUE;
	if (r_ptr->flags3 & RF3_NO_SLEEP) p_ptr->free_act = TRUE;
	if (r_ptr->flags3 & RF3_NO_CONF) p_ptr->resist_conf = TRUE;
	if (r_ptr->flags7 & RF7_CAN_FLY) p_ptr->ffall = TRUE;
	if (r_ptr->flags7 & RF7_AQUATIC) p_ptr->water_breath = TRUE;
}


byte calc_mimic()
{
	s32b blow = 0;

	call_lua("calc_mimic", "(d)", "d", p_ptr->mimic_form, &blow);
	return blow;
}

/* Returns the blow information based on class */
void analyze_blow(int *num, int *wgt, int *mul)
{
	*num = cp_ptr->blow_num;
	*wgt = cp_ptr->blow_wgt;
	*mul = cp_ptr->blow_mul;

	/* Count bonus abilities */
	if (has_ability(AB_MAX_BLOW1)) (*num)++;
	if (has_ability(AB_MAX_BLOW2)) (*num)++;
}

/* Are all the weapons wielded of the right type ? */
int get_weaponmastery_skill()
{
	int i, skill = 0;
	object_type *o_ptr;

	i = 0;
	/* All weapons must be of the same type */
	while ((p_ptr->body_parts[i] == INVEN_WIELD) && (i < INVEN_TOTAL))
	{
		o_ptr = &p_ptr->inventory[INVEN_WIELD + i];

		if (!o_ptr->k_idx)
		{
			i++;
			continue;
		}
		switch (o_ptr->tval)
		{
		case TV_DAEMON_BOOK:
		case TV_SWORD:
			if ((!skill) || (skill == SKILL_SWORD)) skill = SKILL_SWORD;
			else skill = -1;
			break;
		case TV_AXE:
			if ((!skill) || (skill == SKILL_AXE)) skill = SKILL_AXE;
			else skill = -1;
			break;
		case TV_HAFTED:
			if ((!skill) || (skill == SKILL_HAFTED)) skill = SKILL_HAFTED;
			else skill = -1;
			break;
		case TV_POLEARM:
			if ((!skill) || (skill == SKILL_POLEARM)) skill = SKILL_POLEARM;
			else skill = -1;
			break;
		}
		i++;
	}

	/* Everything is ok */
	return skill;
}

/* Are all the ranged weapons wielded of the right type ? */
int get_archery_skill()
{
	int i, skill = 0;
	object_type *o_ptr;

	i = INVEN_BOW - INVEN_WIELD;
	/* All weapons must be of the same type */
	while (p_ptr->body_parts[i] == INVEN_BOW)
	{
		o_ptr = &p_ptr->inventory[INVEN_WIELD + i];

		if (p_ptr->inventory[INVEN_WIELD + i].tval == TV_BOW)
		{
			switch (p_ptr->inventory[INVEN_WIELD + i].sval / 10)
			{
			case 0:
				if ((!skill) || (skill == SKILL_SLING)) skill = SKILL_SLING;
				else skill = -1;
				break;
			case 1:
				if ((!skill) || (skill == SKILL_BOW)) skill = SKILL_BOW;
				else skill = -1;
				break;
			case 2:
				if ((!skill) || (skill == SKILL_XBOW)) skill = SKILL_XBOW;
				else skill = -1;
				break;
			}
		}
		else
		{
			if ((!skill) || (skill == SKILL_BOOMERANG)) skill = SKILL_BOOMERANG;
			else skill = -1;
		}

		i++;
	}

	/* Everything is ok */
	return skill;
}

/* Apply gods */
void calc_gods()
{
	/* Boost WIS if the player follows Eru */
	GOD(GOD_ERU)
	{
		if (p_ptr->grace > 10000) p_ptr->stat_add[A_WIS] += 1;
		if (p_ptr->grace > 20000) p_ptr->stat_add[A_WIS] += 1;
		if (p_ptr->grace > 30000) p_ptr->stat_add[A_WIS] += 1;
	}

	/* Boost str, con, chr and reduce int, wis if the player follows Melkor */
	GOD(GOD_MELKOR)
	{
		if (p_ptr->grace > 10000) p_ptr->stat_add[A_STR] += 1;
		if (p_ptr->grace > 20000) p_ptr->stat_add[A_STR] += 1;
		if (p_ptr->grace > 30000) p_ptr->stat_add[A_STR] += 1;

		if (p_ptr->grace > 10000) p_ptr->stat_add[A_CON] += 1;
		if (p_ptr->grace > 20000) p_ptr->stat_add[A_CON] += 1;
		if (p_ptr->grace > 30000) p_ptr->stat_add[A_CON] += 1;

		if (p_ptr->grace > 10000) p_ptr->stat_add[A_CHR] += 1;
		if (p_ptr->grace > 20000) p_ptr->stat_add[A_CHR] += 1;
		if (p_ptr->grace > 30000) p_ptr->stat_add[A_CHR] += 1;

		if (p_ptr->grace > 10000) p_ptr->stat_add[A_INT] -= 1;
		if (p_ptr->grace > 20000) p_ptr->stat_add[A_INT] -= 1;
		if (p_ptr->grace > 30000) p_ptr->stat_add[A_INT] -= 1;

		if (p_ptr->grace > 10000) p_ptr->stat_add[A_WIS] -= 1;
		if (p_ptr->grace > 20000) p_ptr->stat_add[A_WIS] -= 1;
		if (p_ptr->grace > 30000) p_ptr->stat_add[A_WIS] -= 1;

		PRAY_GOD(GOD_MELKOR)
		{
			if (p_ptr->grace > 5000) p_ptr->invis += 30;
			if (p_ptr->grace > 15000) p_ptr->immune_fire = TRUE;
		}
		p_ptr->resist_fire = TRUE;
	}

	/* Gifts of Manwe if the player is praying to Manwe */
	PRAY_GOD(GOD_MANWE)
	{
		s32b add = p_ptr->grace;

		/* provides speed every 5000 grace */
		if (add > 35000) add = 35000;
		add /= 5000;
		p_ptr->pspeed += add;

		/* Provides fly & FA */
		if (p_ptr->grace >= 7000) p_ptr->free_act = TRUE;
		if (p_ptr->grace >= 15000) p_ptr->fly = TRUE;
	}

	/* Manwe bonus not requiring the praying status */
	GOD(GOD_MANWE)
	{
		if (p_ptr->grace >= 2000) p_ptr->ffall = TRUE;
	}

	/* Boost Str and Con if the player is following Tulkas */
	GOD(GOD_TULKAS)
	{
		if (p_ptr->grace > 5000) p_ptr->stat_add[A_CON] += 1;
		if (p_ptr->grace > 10000) p_ptr->stat_add[A_CON] += 1;
		if (p_ptr->grace > 15000) p_ptr->stat_add[A_CON] += 1;

		if (p_ptr->grace > 10000) p_ptr->stat_add[A_STR] += 1;
		if (p_ptr->grace > 15000) p_ptr->stat_add[A_STR] += 1;
		if (p_ptr->grace > 20000) p_ptr->stat_add[A_STR] += 1;
	}
}

/* Apply flags */
static int extra_blows;
static int extra_shots;
void apply_flags(u32b f1, u32b f2, u32b f3, u32b f4, u32b f5, u32b esp, s16b pval, s16b tval, s16b to_h, s16b to_d, s16b to_a)
{
	/* Affect stats */
	if (f1 & (TR1_STR)) p_ptr->stat_add[A_STR] += pval;
	if (f1 & (TR1_INT)) p_ptr->stat_add[A_INT] += pval;
	if (f1 & (TR1_WIS)) p_ptr->stat_add[A_WIS] += pval;
	if (f1 & (TR1_DEX)) p_ptr->stat_add[A_DEX] += pval;
	if (f1 & (TR1_CON)) p_ptr->stat_add[A_CON] += pval;
	if (f1 & (TR1_CHR)) p_ptr->stat_add[A_CHR] += pval;
	if (f5 & (TR5_LUCK)) p_ptr->luck_cur += pval;

	/* Affect spell power */
	if (f1 & (TR1_SPELL)) p_ptr->to_s += pval;

	/* Affect mana capacity */
	if (f1 & (TR1_MANA)) p_ptr->to_m += pval;

	/* Affect life capacity */
	if (f2 & (TR2_LIFE)) p_ptr->to_l += pval;

	/* Affect stealth */
	if (f1 & (TR1_STEALTH)) p_ptr->skill_stl += pval;

	/* Affect searching ability (factor of five) */
	if (f1 & (TR1_SEARCH)) p_ptr->skill_srh += (pval * 5);

	/* Affect searching frequency (factor of five) */
	if (f1 & (TR1_SEARCH)) p_ptr->skill_fos += (pval * 5);

	/* Affect infravision */
	if (f1 & (TR1_INFRA)) p_ptr->see_infra += pval;

	/* Affect digging (factor of 20) */
	if (f1 & (TR1_TUNNEL)) p_ptr->skill_dig += (pval * 20);

	/* Affect speed */
	if (f1 & (TR1_SPEED)) p_ptr->pspeed += pval;

	/* Affect blows */
	if (f1 & (TR1_BLOWS)) extra_blows += pval;
	if (f5 & (TR5_CRIT)) p_ptr->xtra_crit += pval;

	/* Hack -- Sensible fire */
	if (f2 & (TR2_SENS_FIRE)) p_ptr->sensible_fire = TRUE;

	/* Hack -- cause earthquakes */
	if (f1 & (TR1_IMPACT)) p_ptr->impact = TRUE;

	/* Affect invisibility */
	if (f2 & (TR2_INVIS)) p_ptr->invis += (pval * 10);

	/* Boost shots */
	if (f3 & (TR3_XTRA_SHOTS)) extra_shots++;

	/* Various flags */
	if (f3 & (TR3_AGGRAVATE)) p_ptr->aggravate = TRUE;
	if (f3 & (TR3_TELEPORT)) p_ptr->teleport = TRUE;
	if (f5 & (TR5_DRAIN_MANA)) p_ptr->drain_mana++;
	if (f5 & (TR5_DRAIN_HP)) p_ptr->drain_life++;
	if (f3 & (TR3_DRAIN_EXP)) p_ptr->exp_drain = TRUE;
	if (f3 & (TR3_BLESSED)) p_ptr->bless_blade = TRUE;
	if (f3 & (TR3_XTRA_MIGHT)) p_ptr->xtra_might += pval;
	if (f3 & (TR3_SLOW_DIGEST)) p_ptr->slow_digest = TRUE;
	if (f3 & (TR3_REGEN)) p_ptr->regenerate = TRUE;
	if (esp) p_ptr->telepathy |= esp;
	if ((tval != TV_LITE) && (f3 & (TR3_LITE1))) p_ptr->lite = TRUE;
	if ((tval != TV_LITE) && (f4 & (TR4_LITE2))) p_ptr->lite = TRUE;
	if ((tval != TV_LITE) && (f4 & (TR4_LITE3))) p_ptr->lite = TRUE;
	if (f3 & (TR3_SEE_INVIS)) p_ptr->see_inv = TRUE;
	if (f2 & (TR2_FREE_ACT)) p_ptr->free_act = TRUE;
	if (f2 & (TR2_HOLD_LIFE)) p_ptr->hold_life = TRUE;
	if (f3 & (TR3_WRAITH)) p_ptr->wraith_form = TRUE;
	if (f3 & (TR3_FEATHER)) p_ptr->ffall = TRUE;
	if (f4 & (TR4_FLY)) p_ptr->fly = TRUE;
	if (f4 & (TR4_CLIMB)) p_ptr->climb = TRUE;

	/* Immunity flags */
	if (f2 & (TR2_IM_FIRE)) p_ptr->immune_fire = TRUE;
	if (f2 & (TR2_IM_ACID)) p_ptr->immune_acid = TRUE;
	if (f2 & (TR2_IM_COLD)) p_ptr->immune_cold = TRUE;
	if (f2 & (TR2_IM_ELEC)) p_ptr->immune_elec = TRUE;

	/* Resistance flags */
	if (f2 & (TR2_RES_ACID)) p_ptr->resist_acid = TRUE;
	if (f2 & (TR2_RES_ELEC)) p_ptr->resist_elec = TRUE;
	if (f2 & (TR2_RES_FIRE)) p_ptr->resist_fire = TRUE;
	if (f2 & (TR2_RES_COLD)) p_ptr->resist_cold = TRUE;
	if (f2 & (TR2_RES_POIS)) p_ptr->resist_pois = TRUE;
	if (f2 & (TR2_RES_FEAR)) p_ptr->resist_fear = TRUE;
	if (f2 & (TR2_RES_CONF)) p_ptr->resist_conf = TRUE;
	if (f2 & (TR2_RES_SOUND)) p_ptr->resist_sound = TRUE;
	if (f2 & (TR2_RES_LITE)) p_ptr->resist_lite = TRUE;
	if (f2 & (TR2_RES_DARK)) p_ptr->resist_dark = TRUE;
	if (f2 & (TR2_RES_CHAOS)) p_ptr->resist_chaos = TRUE;
	if (f2 & (TR2_RES_DISEN)) p_ptr->resist_disen = TRUE;
	if (f2 & (TR2_RES_SHARDS)) p_ptr->resist_shard = TRUE;
	if (f2 & (TR2_RES_NEXUS)) p_ptr->resist_nexus = TRUE;
	if (f2 & (TR2_RES_BLIND)) p_ptr->resist_blind = TRUE;
	if (f2 & (TR2_RES_NETHER)) p_ptr->resist_neth = TRUE;
	if (f4 & (TR4_IM_NETHER)) p_ptr->immune_neth = TRUE;

	if (f2 & (TR2_REFLECT)) p_ptr->reflect = TRUE;
	if (f3 & (TR3_SH_FIRE)) p_ptr->sh_fire = TRUE;
	if (f3 & (TR3_SH_ELEC)) p_ptr->sh_elec = TRUE;
	if (f3 & (TR3_NO_MAGIC)) p_ptr->anti_magic = TRUE;
	if (f3 & (TR3_NO_TELE)) p_ptr->anti_tele = TRUE;

	/* Sustain flags */
	if (f2 & (TR2_SUST_STR)) p_ptr->sustain_str = TRUE;
	if (f2 & (TR2_SUST_INT)) p_ptr->sustain_int = TRUE;
	if (f2 & (TR2_SUST_WIS)) p_ptr->sustain_wis = TRUE;
	if (f2 & (TR2_SUST_DEX)) p_ptr->sustain_dex = TRUE;
	if (f2 & (TR2_SUST_CON)) p_ptr->sustain_con = TRUE;
	if (f2 & (TR2_SUST_CHR)) p_ptr->sustain_chr = TRUE;

	if (f4 & (TR4_PRECOGNITION)) p_ptr->precognition = TRUE;

	if (f4 & (TR4_ANTIMAGIC_50))
	{
		s32b tmp;

		tmp = 10 + get_skill_scale(SKILL_ANTIMAGIC, 40)
		      - to_h - to_d - pval - to_a;
		if (tmp > 0) p_ptr->antimagic += tmp;

		tmp = 1 + get_skill_scale(SKILL_ANTIMAGIC, 4)
		      - (to_h + to_d + pval + to_a) / 15;
		if (tmp > 0) p_ptr->antimagic_dis += tmp;
	}

	if (f4 & (TR4_ANTIMAGIC_30))
	{
		s32b tmp;

		tmp = 7 + get_skill_scale(SKILL_ANTIMAGIC, 33)
		      - to_h - to_d - pval - to_a;
		if (tmp > 0) p_ptr->antimagic += tmp;

		tmp = 1 + get_skill_scale(SKILL_ANTIMAGIC, 2)
		      - (to_h + to_d + pval + to_a) / 15;
		if (tmp > 0) p_ptr->antimagic_dis += tmp;
	}

	if (f4 & (TR4_ANTIMAGIC_20))
	{
		s32b tmp;

		tmp = 5 + get_skill_scale(SKILL_ANTIMAGIC, 15)
		      - to_h - to_d - pval - to_a;
		if (tmp > 0) p_ptr->antimagic += tmp;

		p_ptr->antimagic_dis += 2;
	}

	if (f4 & (TR4_ANTIMAGIC_10))
	{
		s32b tmp;

		tmp = 1 + get_skill_scale(SKILL_ANTIMAGIC, 9)
		      - to_h - to_d - pval - to_a;
		if (tmp > 0) p_ptr->antimagic += tmp;

		p_ptr->antimagic_dis += 1;
	}

	if (f4 & (TR4_AUTO_ID))
	{
		p_ptr->auto_id = TRUE;
	}

	/* The new code implementing Tolkien's concept of "Black Breath"
	 * takes advantage of the existing drain_exp character flag, renamed
	 * "black_breath". This flag can also be set by a unlucky blow from
	 * an undead.  -LM-
	 */
	if (f4 & (TR4_BLACK_BREATH)) p_ptr->black_breath = TRUE;

	if (f5 & (TR5_IMMOVABLE)) p_ptr->immovable = TRUE;

	/* Breaths */
	if (f5 & (TR5_WATER_BREATH)) p_ptr->water_breath = TRUE;
	if (f5 & (TR5_MAGIC_BREATH))
	{
		p_ptr->magical_breath = TRUE;
		p_ptr->water_breath = TRUE;
	}
}

/*
 * Calculate the players current "state", taking into account
 * not only race/class intrinsics, but also objects being worn
 * and temporary spell effects.
 *
 * See also calc_mana() and calc_hitpoints().
 *
 * Take note of the new "speed code", in particular, a very strong
 * player will start slowing down as soon as he reaches 150 pounds,
 * but not until he reaches 450 pounds will he be half as fast as
 * a normal kobold.  This both hurts and helps the player, hurts
 * because in the old days a player could just avoid 300 pounds,
 * and helps because now carrying 300 pounds is not very painful.
 *
 * The "weapon" and "bow" do *not* add to the bonuses to hit or to
 * damage, since that would affect non-combat things.  These values
 * are actually added in later, at the appropriate place.
 *
 * This function induces various "status" messages, unless silent is
 * TRUE.
 */
void calc_bonuses(bool silent)
{
	int i, j, hold;
	int old_invis;
	int old_speed;
	u32b old_telepathy;
	int old_see_inv;
	int old_dis_ac;
	int old_dis_to_a;
	object_type *o_ptr;
	u32b f1, f2, f3, f4, f5, esp;


	/* Save the old speed */
	old_speed = p_ptr->pspeed;

	/* Save the old vision stuff */
	old_telepathy = p_ptr->telepathy;
	old_see_inv = p_ptr->see_inv;

	/* Save the old armor class */
	old_dis_ac = p_ptr->dis_ac;
	old_dis_to_a = p_ptr->dis_to_a;

	/* Save the old invisibility */
	old_invis = p_ptr->invis;

	/* Clear extra blows/shots */
	extra_blows = extra_shots = 0;

	/* Clear the stat modifiers */
	for (i = 0; i < 6; i++) p_ptr->stat_add[i] = 0;

	/* Mana multiplier */
	p_ptr->to_m = 0;

	/* Life multiplier */
	p_ptr->to_l = 0;

	/* Spell power */
	p_ptr->to_s = 0;

	/* Clear the Displayed/Real armor class */
	p_ptr->dis_ac = p_ptr->ac = 0;

	/* Clear the Displayed/Real Bonuses */
	p_ptr->dis_to_h = p_ptr->to_h = p_ptr->to_h_melee = p_ptr->to_h_ranged = 0;
	p_ptr->dis_to_d = p_ptr->to_d = p_ptr->to_d_melee = p_ptr->to_d_ranged = 0;
	p_ptr->dis_to_a = p_ptr->to_a = 0;

	/* Start with "normal" speed */
	p_ptr->pspeed = 110;

	/* Start with 0% additionnal crits */
	p_ptr->xtra_crit = 0;

	/* Start with a single blow per turn */
	p_ptr->num_blow = 1;

	/* Start with a single shot per turn */
	p_ptr->num_fire = 1;

	/* Starts with single throwing damage */
	p_ptr->throw_mult = 1;

	/* Reset the "xtra" tval */
	p_ptr->tval_xtra = 0;

	/* Reset the "ammo" tval */
	p_ptr->tval_ammo = 0;

	/* Clear all the flags */
	p_ptr->invis = 0;
	p_ptr->immovable = FALSE;
	p_ptr->aggravate = FALSE;
	p_ptr->teleport = FALSE;
	p_ptr->exp_drain = FALSE;
	p_ptr->drain_mana = 0;
	p_ptr->drain_life = 0;
	p_ptr->bless_blade = FALSE;
	p_ptr->xtra_might = 0;
	p_ptr->auto_id = FALSE;
	p_ptr->impact = FALSE;
	p_ptr->see_inv = FALSE;
	p_ptr->free_act = FALSE;
	p_ptr->slow_digest = FALSE;
	p_ptr->regenerate = FALSE;
	p_ptr->fly = FALSE;
	p_ptr->climb = FALSE;
	p_ptr->ffall = FALSE;
	p_ptr->hold_life = FALSE;
	p_ptr->telepathy = 0;
	p_ptr->lite = FALSE;
	p_ptr->sustain_str = FALSE;
	p_ptr->sustain_int = FALSE;
	p_ptr->sustain_wis = FALSE;
	p_ptr->sustain_con = FALSE;
	p_ptr->sustain_dex = FALSE;
	p_ptr->sustain_chr = FALSE;
	p_ptr->resist_acid = FALSE;
	p_ptr->resist_elec = FALSE;
	p_ptr->resist_fire = FALSE;
	p_ptr->resist_cold = FALSE;
	p_ptr->resist_pois = FALSE;
	p_ptr->resist_conf = FALSE;
	p_ptr->resist_sound = FALSE;
	p_ptr->resist_lite = FALSE;
	p_ptr->resist_dark = FALSE;
	p_ptr->resist_chaos = FALSE;
	p_ptr->resist_disen = FALSE;
	p_ptr->resist_shard = FALSE;
	p_ptr->resist_nexus = FALSE;
	p_ptr->resist_blind = FALSE;
	p_ptr->resist_neth = FALSE;
	p_ptr->immune_neth = FALSE;
	p_ptr->resist_fear = FALSE;
	p_ptr->resist_continuum = FALSE;
	p_ptr->reflect = FALSE;
	p_ptr->sh_fire = FALSE;
	p_ptr->sh_elec = FALSE;
	p_ptr->anti_magic = FALSE;
	p_ptr->anti_tele = FALSE;
	p_ptr->water_breath = FALSE;
	p_ptr->magical_breath = FALSE;

	p_ptr->sensible_fire = FALSE;
	p_ptr->sensible_lite = FALSE;

	p_ptr->immune_acid = FALSE;
	p_ptr->immune_elec = FALSE;
	p_ptr->immune_fire = FALSE;
	p_ptr->immune_cold = FALSE;

	p_ptr->precognition = FALSE;

	p_ptr->wraith_form = FALSE;

	/* The anti magic field surrounding the player */
	p_ptr->antimagic = 0;
	p_ptr->antimagic_dis = 0;


	/* Base infravision (purely racial) */
	p_ptr->see_infra = rp_ptr->infra + rmp_ptr->infra;


	/* Base skill -- disarming */
	p_ptr->skill_dis = 0;

	/* Base skill -- magic devices */
	p_ptr->skill_dev = 0;

	/* Base skill -- saving throw */
	p_ptr->skill_sav = 0;

	/* Base skill -- stealth */
	p_ptr->skill_stl = 0;

	/* Base skill -- searching ability */
	p_ptr->skill_srh = 0;

	/* Base skill -- searching frequency */
	p_ptr->skill_fos = 0;

	/* Base skill -- combat (normal) */
	p_ptr->skill_thn = 0;

	/* Base skill -- combat (shooting) */
	p_ptr->skill_thb = 0;

	/* Base skill -- combat (throwing) */
	p_ptr->skill_tht = 0;


	/* Base skill -- digging */
	p_ptr->skill_dig = 0;

	/* Xtra player flags */
	p_ptr->xtra_f1 = 0;
	p_ptr->xtra_f2 = 0;
	p_ptr->xtra_f3 = 0;
	p_ptr->xtra_f4 = 0;
	p_ptr->xtra_f5 = 0;
	p_ptr->xtra_esp = 0;

	/* Hide the skills that should auto hide */
	for (i = 0; i < max_s_idx; i++)
	{
		if (s_info[i].flags1 & SKF1_AUTO_HIDE)
			s_info[i].hidden = TRUE;
	}

	/* Base Luck */
	p_ptr->luck_cur = p_ptr->luck_base;

	/* Mimic override body's bonuses */
	if (p_ptr->mimic_form)
	{
		extra_blows += calc_mimic();
	}
	else
	{
		calc_body_bonus();
	}

	/* Let the scripts do what they need */
	process_hooks(HOOK_CALC_BONUS, "()");

	/* The powers gived by the wielded monster */
	calc_wield_monster();

	for (i = 1; i <= p_ptr->lev; i++)
	{
		apply_flags(cp_ptr->oflags1[i], cp_ptr->oflags2[i], cp_ptr->oflags3[i], cp_ptr->oflags4[i], cp_ptr->oflags5[i], cp_ptr->oesp[i], cp_ptr->opval[i], 0, 0, 0, 0);
	}

	if (p_ptr->melee_style == SKILL_HAND)
	{
		/* Unencumbered Monks become faster every 10 levels */
		if (!(monk_heavy_armor()))
			p_ptr->pspeed += get_skill_scale(SKILL_HAND, 5);

		/* Free action if unencumbered at level 25 */
		if ((get_skill(SKILL_HAND) > 24) && !(monk_heavy_armor()))
			p_ptr->free_act = TRUE;
	}

	if (get_skill(SKILL_ANTIMAGIC))
	{
		p_ptr->antimagic += get_skill(SKILL_ANTIMAGIC);
		p_ptr->antimagic_dis += get_skill_scale(SKILL_ANTIMAGIC, 10) + 1;

		if (p_ptr->antimagic_extra & CLASS_ANTIMAGIC)
		{
			p_ptr->anti_tele = TRUE;
			p_ptr->resist_continuum = TRUE;
		}
	}

	if (get_skill(SKILL_DAEMON) > 20) p_ptr->resist_conf = TRUE;
	if (get_skill(SKILL_DAEMON) > 30) p_ptr->resist_fear = TRUE;

	if ( get_skill(SKILL_MINDCRAFT) >= 40 ) p_ptr->telepathy = ESP_ALL;

	if (p_ptr->astral)
	{
		p_ptr->wraith_form = TRUE;
	}

	/***** Races ****/
	if ((!p_ptr->mimic_form) && (!p_ptr->body_monster))
	{
		int i;

		for (i = 1; i <= p_ptr->lev; i++)
		{
			apply_flags(rp_ptr->oflags1[i], rp_ptr->oflags2[i], rp_ptr->oflags3[i], rp_ptr->oflags4[i], rp_ptr->oflags5[i], rp_ptr->oesp[i], rp_ptr->opval[i], 0, 0, 0, 0);
			apply_flags(rmp_ptr->oflags1[i], rmp_ptr->oflags2[i], rmp_ptr->oflags3[i], rmp_ptr->oflags4[i], rmp_ptr->oflags5[i], rmp_ptr->oesp[i], rmp_ptr->opval[i], 0, 0, 0, 0);
		}

		if (PRACE_FLAG(PR1_HURT_LITE))
			p_ptr->sensible_lite = TRUE;
	}

	/* The extra flags */
	apply_flags(p_ptr->xtra_f1, p_ptr->xtra_f2, p_ptr->xtra_f3, p_ptr->xtra_f4, p_ptr->xtra_f5, p_ptr->xtra_esp, 0, 0, 0, 0, 0);

	/* Hack -- apply racial/class stat maxes */
	if (p_ptr->maximize)
	{
		/* Apply the racial modifiers */
		for (i = 0; i < 6; i++)
		{
			/* Modify the stats for "race" */
			p_ptr->stat_add[i] += (rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i]);
		}
	}


	/* Scan the usable inventory */
	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
	{
		o_ptr = &p_ptr->inventory[i];

		/* Skip non-objects */
		if (!o_ptr->k_idx) continue;

		/* Extract the item flags */
		object_flags_no_set = TRUE;
		object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);
		object_flags_no_set = FALSE;

		/* MEGA ugly hack -- set spacetime distortion resistance */
		if (o_ptr->name1 == ART_ANCHOR)
		{
			p_ptr->resist_continuum = TRUE;
		}

		/* Hack - don't give the Black Breath when merely inspecting a weapon */
		if (silent)
		{
			f4 &= ~TR4_BLACK_BREATH;
		}

		apply_flags(f1, f2, f3, f4, f5, esp, o_ptr->pval, o_ptr->tval, o_ptr->to_h, o_ptr->to_d, o_ptr->to_a);

		if (o_ptr->name1)
		{
			apply_set(o_ptr->name1, a_info[o_ptr->name1].set);
		}

		/* Modify the base armor class */
		p_ptr->ac += o_ptr->ac;

		/* The base armor class is always known */
		p_ptr->dis_ac += o_ptr->ac;

		/* Apply the bonuses to armor class */
		p_ptr->to_a += o_ptr->to_a;

		/* Apply the mental bonuses to armor class, if known */
		if (object_known_p(o_ptr)) p_ptr->dis_to_a += o_ptr->to_a;

		/* Hack -- do not apply "weapon" bonuses */
		if (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_WIELD) continue;

		/* Hack -- do not apply "bow" bonuses */
		if (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_BOW) continue;

		/* Hack -- do not apply "ammo" bonuses */
		if (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_AMMO) continue;

		/* Hack -- do not apply "tool" bonuses */
		if (p_ptr->body_parts[i - INVEN_WIELD] == INVEN_TOOL) continue;

		/* Apply the bonuses to hit/damage */
		p_ptr->to_h += o_ptr->to_h;
		p_ptr->to_d += o_ptr->to_d;

		/* Apply the mental bonuses tp hit/damage, if known */
		if (object_known_p(o_ptr)) p_ptr->dis_to_h += o_ptr->to_h;
		if (object_known_p(o_ptr)) p_ptr->dis_to_d += o_ptr->to_d;
	}

	/* Monks get extra ac for armour _not worn_ */
	if ((p_ptr->melee_style == SKILL_HAND) && !(monk_heavy_armor()))
	{
		if (!(p_ptr->inventory[INVEN_BODY].k_idx))
		{
			p_ptr->to_a += get_skill_scale(SKILL_HAND, 75);
			p_ptr->dis_to_a += get_skill_scale(SKILL_HAND, 75);
		}
		if (!(p_ptr->inventory[INVEN_OUTER].k_idx) && (get_skill(SKILL_HAND) > 15))
		{
			p_ptr->to_a += ((get_skill(SKILL_HAND) - 13) / 3);
			p_ptr->dis_to_a += ((get_skill(SKILL_HAND) - 13) / 3);
		}
		if (!(p_ptr->inventory[INVEN_ARM].k_idx) && (get_skill(SKILL_HAND) > 10))
		{
			p_ptr->to_a += ((get_skill(SKILL_HAND) - 8) / 3);
			p_ptr->dis_to_a += ((get_skill(SKILL_HAND) - 8) / 3);
		}
		if (!(p_ptr->inventory[INVEN_HEAD].k_idx) && (get_skill(SKILL_HAND) > 4))
		{
			p_ptr->to_a += (get_skill(SKILL_HAND) - 2) / 3;
			p_ptr->dis_to_a += (get_skill(SKILL_HAND) - 2) / 3;
		}
		if (!(p_ptr->inventory[INVEN_HANDS].k_idx))
		{
			p_ptr->to_a += (get_skill(SKILL_HAND) / 2);
			p_ptr->dis_to_a += (get_skill(SKILL_HAND) / 2);
		}
		if (!(p_ptr->inventory[INVEN_FEET].k_idx))
		{
			p_ptr->to_a += (get_skill(SKILL_HAND) / 3);
			p_ptr->dis_to_a += (get_skill(SKILL_HAND) / 3);
		}
	}

	/* Hack -- aura of fire also provides light */
	if (p_ptr->sh_fire) p_ptr->lite = TRUE;

	if (PRACE_FLAG(PR1_AC_LEVEL))
	{
		p_ptr->to_a += 20 + (p_ptr->lev / 5);
		p_ptr->dis_to_a += 20 + (p_ptr->lev / 5);
	}

	/* Take care of gods */
	calc_gods();

	/* Calculate stats */
	for (i = 0; i < 6; i++)
	{
		int top, use, ind;


		/* Extract the new "stat_use" value for the stat */
		top = modify_stat_value(p_ptr->stat_max[i], p_ptr->stat_add[i]);

		/* Notice changes */
		if (p_ptr->stat_top[i] != top)
		{
			/* Save the new value */
			p_ptr->stat_top[i] = top;

			/* Redisplay the stats later */
			p_ptr->redraw |= (PR_STATS);

			/* Window stuff */
			p_ptr->window |= (PW_PLAYER);
		}

		/* Extract the new "stat_use" value for the stat */
		use = modify_stat_value(p_ptr->stat_cur[i], p_ptr->stat_add[i]);

		/* Notice changes */
		if (p_ptr->stat_use[i] != use)
		{
			/* Save the new value */
			p_ptr->stat_use[i] = use;

			/* Redisplay the stats later */
			p_ptr->redraw |= (PR_STATS);

			/* Window stuff */
			p_ptr->window |= (PW_PLAYER);
		}


		/* Values: 3, 4, ..., 17 */
		if (use <= 18) ind = (use - 3);

		/* Ranges: 18/00-18/09, ..., 18/210-18/219 */
		else if (use <= 18 + 219) ind = (15 + (use - 18) / 10);

		/* Range: 18/220+ */
		else ind = (37);

		/* Notice changes */
		if (p_ptr->stat_ind[i] != ind)
		{
			/* Save the new index */
			p_ptr->stat_ind[i] = ind;

			/* Change in CON affects Hitpoints */
			if (i == A_CON)
			{
				p_ptr->update |= (PU_HP);
			}

			/* Change in WIS affects Sanity Points */
			else if (i == A_WIS)
			{
				p_ptr->update |= (PU_MANA | PU_SANITY);
			}

			/* Change in spell stat affects Mana/Spells */
			if (i == A_INT)
			{
				p_ptr->update |= (PU_MANA | PU_SPELLS);
			}

			/* Window stuff */
			p_ptr->window |= (PW_PLAYER);
		}
	}

	/* Provide the damage we get from sacrifice */
	GOD(GOD_MELKOR)
	{
		int x = wisdom_scale(4);
		if (x < 1) x = 1;

		p_ptr->dis_to_d += x * p_ptr->melkor_sacrifice;
		p_ptr->to_d += x * p_ptr->melkor_sacrifice;
	}

	/* jk - add in the tactics */
	p_ptr->dis_to_h += tactic_info[(byte)p_ptr->tactic].to_hit;
	p_ptr->to_h += tactic_info[(byte)p_ptr->tactic].to_hit;
	p_ptr->dis_to_d += tactic_info[(byte)p_ptr->tactic].to_dam;
	p_ptr->to_d += tactic_info[(byte)p_ptr->tactic].to_dam;
	p_ptr->dis_to_a += tactic_info[(byte)p_ptr->tactic].to_ac;
	p_ptr->to_a += tactic_info[(byte)p_ptr->tactic].to_ac;

	p_ptr->skill_stl += tactic_info[(byte)p_ptr->tactic].to_stealth;
	p_ptr->skill_dis += tactic_info[(byte)p_ptr->tactic].to_disarm;
	p_ptr->skill_sav += tactic_info[(byte)p_ptr->tactic].to_saving;

	p_ptr->pspeed += move_info[(byte)p_ptr->movement].to_speed;
	p_ptr->skill_srh += move_info[(byte)p_ptr->movement].to_search;
	p_ptr->skill_fos += move_info[(byte)p_ptr->movement].to_percep;
	p_ptr->skill_stl += move_info[(byte)p_ptr->movement].to_stealth;

	/* Apply temporary "stun" */
	if (p_ptr->stun > 50)
	{
		p_ptr->to_h -= 20;
		p_ptr->dis_to_h -= 20;
		p_ptr->to_d -= 20;
		p_ptr->dis_to_d -= 20;
	}
	else if (p_ptr->stun)
	{
		p_ptr->to_h -= 5;
		p_ptr->dis_to_h -= 5;
		p_ptr->to_d -= 5;
		p_ptr->dis_to_d -= 5;
	}


	/* Invulnerability */
	if (p_ptr->invuln)
	{
		p_ptr->to_a += 100;
		p_ptr->dis_to_a += 100;
	}

	/* Breath */
	if (p_ptr->tim_water_breath)
	{
		p_ptr->water_breath = TRUE;
	}
	if (p_ptr->tim_magic_breath)
	{
		p_ptr->magical_breath = TRUE;
	}

	/* wraith_form */
	if (p_ptr->tim_wraith)
	{
		if (p_ptr->disembodied)
		{
			p_ptr->to_a += 10;
			p_ptr->dis_to_a += 10;
		}
		else
		{
			p_ptr->to_a += 50;
			p_ptr->dis_to_a += 50;
			p_ptr->reflect = TRUE;
		}
		p_ptr->wraith_form = TRUE;
	}

	/* Temporary holy aura */
	if (p_ptr->holy)
	{
		p_ptr->hold_life = TRUE;
		p_ptr->luck_cur += 5;
	}

	/* Temporary blessing */
	if (p_ptr->blessed)
	{
		p_ptr->to_a += 5;
		p_ptr->dis_to_a += 5;
		p_ptr->to_h += 10;
		p_ptr->dis_to_h += 10;
	}

	/* Temporary invisibility */
	if (p_ptr->tim_invisible)
	{
		p_ptr->invis += p_ptr->tim_inv_pow;
	}

	/* Temporary shield */
	if (p_ptr->shield)
	{
		p_ptr->to_a += p_ptr->shield_power;
		p_ptr->dis_to_a += p_ptr->shield_power;
	}

	/* Temporary "Hero" */
	if (p_ptr->hero)
	{
		p_ptr->to_h += 12;
		p_ptr->dis_to_h += 12;
	}

	/* Temporary "roots" */
	if (p_ptr->tim_roots)
	{
		set_stun(0);
		p_ptr->to_d_melee += p_ptr->tim_roots_dam;
		p_ptr->to_a += p_ptr->tim_roots_ac;
		p_ptr->dis_to_a += p_ptr->tim_roots_ac;
	}

	/* Temporary "Beserk" */
	if (p_ptr->shero)
	{
		p_ptr->to_h += 24;
		p_ptr->dis_to_h += 24;
		p_ptr->to_a -= 10;
		p_ptr->dis_to_a -= 10;
	}

	/* Temporary "Accurancy" */
	if (p_ptr->strike)
	{
		p_ptr->to_d += 15;
		p_ptr->dis_to_d += 15;
		p_ptr->to_h += 15;
		p_ptr->dis_to_h += 15;
	}

	/* Temporary "Meditation" */
	if (p_ptr->meditation)
	{
		p_ptr->to_d -= 25;
		p_ptr->dis_to_d -= 25;
		p_ptr->to_h -= 25;
		p_ptr->dis_to_h -= 25;
	}

	/* Temporary "Reflection" */
	if (p_ptr->tim_reflect)
	{
		p_ptr->reflect = TRUE;
	}

	/* Temporary "Time Resistance" */
	if (p_ptr->tim_res_time)
	{
		p_ptr->resist_continuum = TRUE;
	}

	/* Temporary "Levitation" and "Flying" */
	if (p_ptr->tim_ffall)
	{
		p_ptr->ffall = TRUE;
	}
	if (p_ptr->tim_fly)
	{
		p_ptr->fly = TRUE;
	}

	/* Temporary "Fire Aura" */
	if (p_ptr->tim_fire_aura)
	{
		p_ptr->sh_fire = TRUE;
	}

	/* Oppose Light & Dark */
	if (p_ptr->oppose_ld)
	{
		p_ptr->resist_lite = TRUE;
		p_ptr->resist_dark = TRUE;
	}

	/* Oppose Chaos & Confusion */
	if (p_ptr->oppose_cc)
	{
		p_ptr->resist_chaos = TRUE;
		p_ptr->resist_conf = TRUE;
	}

	/* Oppose Sound & Shards */
	if (p_ptr->oppose_ss)
	{
		p_ptr->resist_sound = TRUE;
		p_ptr->resist_shard = TRUE;
	}

	/* Oppose Nexus */
	if (p_ptr->oppose_nex)
	{
		p_ptr->resist_nexus = TRUE;
	}

	/* Mental barrier */
	if (p_ptr->tim_mental_barrier)
	{
		p_ptr->sustain_int = TRUE;
		p_ptr->sustain_wis = TRUE;
	}

	/* Temporary "fast" */
	if (p_ptr->fast)
	{
		p_ptr->pspeed += p_ptr->speed_factor;
	}

	/* Temporary "light speed" */
	if (p_ptr->lightspeed)
	{
		p_ptr->pspeed += 50;
	}

	/* Temporary "slow" */
	if (p_ptr->slow)
	{
		p_ptr->pspeed -= 10;
	}

	if (p_ptr->tim_esp)
	{
		p_ptr->telepathy |= ESP_ALL;
	}

	/* Temporary see invisible */
	if (p_ptr->tim_invis)
	{
		p_ptr->see_inv = TRUE;
	}

	/* Temporary infravision boost */
	if (p_ptr->tim_infra)
	{
		p_ptr->see_infra++;
	}

	/* Hack -- Magic breath -> Water breath */
	if (p_ptr->magical_breath)
	{
		p_ptr->water_breath = TRUE;
	}

	/* Hack -- Can Fly -> Can Levitate */
	if (p_ptr->fly)
	{
		p_ptr->ffall = TRUE;
	}

	/* Hack -- Res Chaos -> Res Conf */
	if (p_ptr->resist_chaos)
	{
		p_ptr->resist_conf = TRUE;
	}

	/* Hack -- Hero/Shero -> Res fear */
	if (p_ptr->hero || p_ptr->shero)
	{
		p_ptr->resist_fear = TRUE;
	}


	/* Hack -- Telepathy Change */
	if (p_ptr->telepathy != old_telepathy)
	{
		p_ptr->update |= (PU_MONSTERS);
	}

	/* Hack -- See Invis Change */
	if (p_ptr->see_inv != old_see_inv)
	{
		p_ptr->update |= (PU_MONSTERS);
	}


	/* Extract the current weight (in tenth pounds) */
	j = calc_total_weight();

	/* Extract the "weight limit" (in tenth pounds) */
	i = weight_limit();

	/* XXX XXX XXX Apply "encumbrance" from weight */
	if (j > i / 2) p_ptr->pspeed -= ((j - (i / 2)) / (i / 10));

	/* Bloating slows the player down (a little) */
	if (p_ptr->food >= PY_FOOD_MAX) p_ptr->pspeed -= 10;

	/* Searching slows the player down */
	if (p_ptr->searching) p_ptr->pspeed -= 10;

	/* In order to get a "nice" mana path druids need to ahve a 0 speed */
	if ((p_ptr->druid_extra2 == CLASS_MANA_PATH) && (p_ptr->pspeed > 110))
		p_ptr->pspeed = 110;

	/* Display the speed (if needed) */
	if (p_ptr->pspeed != old_speed) p_ptr->redraw |= (PR_SPEED);


	/* Actual Modifier Bonuses (Un-inflate stat bonuses) */
	p_ptr->to_a += ((int)(adj_dex_ta[p_ptr->stat_ind[A_DEX]]) - 128);
	p_ptr->to_d += ((int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
	p_ptr->to_h += ((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
	p_ptr->to_h += ((int)(adj_str_th[p_ptr->stat_ind[A_STR]]) - 128);

	/* Displayed Modifier Bonuses (Un-inflate stat bonuses) */
	p_ptr->dis_to_a += ((int)(adj_dex_ta[p_ptr->stat_ind[A_DEX]]) - 128);
	p_ptr->dis_to_d += ((int)(adj_str_td[p_ptr->stat_ind[A_STR]]) - 128);
	p_ptr->dis_to_h += ((int)(adj_dex_th[p_ptr->stat_ind[A_DEX]]) - 128);
	p_ptr->dis_to_h += ((int)(adj_str_th[p_ptr->stat_ind[A_STR]]) - 128);

	/* Redraw armor (if needed) */
	if ((p_ptr->dis_ac != old_dis_ac) || (p_ptr->dis_to_a != old_dis_to_a))
	{
		/* Redraw */
		p_ptr->redraw |= (PR_ARMOR);

		/* Window stuff */
		p_ptr->window |= (PW_PLAYER);
	}


	/* Obtain the "hold" value */
	hold = adj_str_hold[p_ptr->stat_ind[A_STR]];


	/* Examine the "current bow" */
	o_ptr = &p_ptr->inventory[INVEN_BOW];


	/* Assume not heavy */
	p_ptr->heavy_shoot = FALSE;

	/* It is hard to carholdry a heavy bow */
	if (hold < o_ptr->weight / 10)
	{
		/* Hard to wield a heavy bow */
		p_ptr->to_h += 2 * (hold - o_ptr->weight / 10);
		p_ptr->dis_to_h += 2 * (hold - o_ptr->weight / 10);

		/* Heavy Bow */
		p_ptr->heavy_shoot = TRUE;
	}

	/* Take note of required "tval" for missiles */
	switch (o_ptr->sval)
	{
	case SV_SLING:
		{
			p_ptr->tval_ammo = TV_SHOT;
			break;
		}

	case SV_SHORT_BOW:
	case SV_LONG_BOW:
		{
			p_ptr->tval_ammo = TV_ARROW;
			break;
		}

	case SV_LIGHT_XBOW:
	case SV_HEAVY_XBOW:
		{
			p_ptr->tval_ammo = TV_BOLT;
			break;
		}
	}

	/* Compute "extra shots" if needed */
	if (o_ptr->k_idx && !p_ptr->heavy_shoot)
	{
		int archery = get_archery_skill();

		if (archery != -1)
		{
			p_ptr->to_h_ranged += get_skill_scale(archery, 25);
			p_ptr->num_fire += (get_skill(archery) / 16);
			p_ptr->xtra_might += (get_skill(archery) / 25);
			switch (archery)
			{
			case SKILL_SLING:
				if (p_ptr->tval_ammo == TV_SHOT) p_ptr->xtra_might += get_skill(archery) / 30;
				break;
			case SKILL_BOW:
				if (p_ptr->tval_ammo == TV_ARROW) p_ptr->xtra_might += get_skill(archery) / 30;
				break;
			case SKILL_XBOW:
				if (p_ptr->tval_ammo == TV_BOLT) p_ptr->xtra_might += get_skill(archery) / 30;
				break;
			}
		}

		/* Add in the "bonus shots" */
		p_ptr->num_fire += extra_shots;

		/* Require at least one shot */
		if (p_ptr->num_fire < 1) p_ptr->num_fire = 1;
	}

	if (PRACE_FLAG(PR1_XTRA_MIGHT_BOW) && p_ptr->tval_ammo == TV_ARROW)
		p_ptr->xtra_might += 1;

	if (PRACE_FLAG(PR1_XTRA_MIGHT_SLING) && p_ptr->tval_ammo == TV_SHOT)
		p_ptr->xtra_might += 1;

	if (PRACE_FLAG(PR1_XTRA_MIGHT_XBOW) && p_ptr->tval_ammo == TV_BOLT)
		p_ptr->xtra_might += 1;

	/* Examine the "current tool" */
	o_ptr = &p_ptr->inventory[INVEN_TOOL];

	/* Boost digging skill by tool weight */
	if (o_ptr->k_idx && (o_ptr->tval == TV_DIGGING))
	{
		p_ptr->skill_dig += (o_ptr->weight / 10);
	}

	/* Examine the main weapon */
	o_ptr = &p_ptr->inventory[INVEN_WIELD];

	/* Assume not heavy */
	p_ptr->heavy_wield = FALSE;

	/* Normal weapons */
	if (o_ptr->k_idx && !p_ptr->heavy_wield)
	{
		int str_index, dex_index;

		int num = 0, wgt = 0, mul = 0, div = 0;

		analyze_blow(&num, &wgt, &mul);

		/* Enforce a minimum "weight" (tenth pounds) */
		div = ((o_ptr->weight < wgt) ? wgt : o_ptr->weight);

		/* Access the strength vs weight */
		str_index = (adj_str_blow[p_ptr->stat_ind[A_STR]] * mul / div);

		/* Maximal value */
		if (str_index > 11) str_index = 11;

		/* Index by dexterity */
		dex_index = (adj_dex_blow[p_ptr->stat_ind[A_DEX]]);

		/* Maximal value */
		if (dex_index > 11) dex_index = 11;

		/* Use the blows table */
		p_ptr->num_blow = blows_table[str_index][dex_index];

		/* Maximal value */
		if (p_ptr->num_blow > num) p_ptr->num_blow = num;

		/* Add in the "bonus blows" */
		p_ptr->num_blow += extra_blows;

		/* Special class bonus blows */
		p_ptr->num_blow += p_ptr->lev * cp_ptr->extra_blows / 50;

		/* Weapon specialization bonus blows */
		if (get_weaponmastery_skill() != -1)
			p_ptr->num_blow += get_skill_scale(get_weaponmastery_skill(), 2);

		/* Bonus blows for plain weaponmastery skill */
		p_ptr->num_blow += get_skill_scale(SKILL_MASTERY, 3);

		/* Require at least one blow */
		if (p_ptr->num_blow < 1) p_ptr->num_blow = 1;
	}
	/* Different calculation for bear form with empty hands */
	else if ((p_ptr->melee_style == SKILL_HAND) && monk_empty_hands())
	{
		int plev = get_skill(SKILL_HAND);

		p_ptr->num_blow = 0;

		if (plev > 9) p_ptr->num_blow++;
		if (plev > 19) p_ptr->num_blow++;
		if (plev > 29) p_ptr->num_blow++;
		if (plev > 34) p_ptr->num_blow++;
		if (plev > 39) p_ptr->num_blow++;
		if (plev > 44) p_ptr->num_blow++;
		if (plev > 49) p_ptr->num_blow++;

		if (monk_heavy_armor()) p_ptr->num_blow /= 2;

		p_ptr->num_blow += 1 + extra_blows;

		if (!monk_heavy_armor())
		{
			p_ptr->to_h += (plev / 3);
			p_ptr->to_d += (plev / 3);

			p_ptr->dis_to_h += (plev / 3);
			p_ptr->dis_to_d += (plev / 3);
		}
	}

	/* Monsters that only have their "natural" attacks */
	else if (!r_info[p_ptr->body_monster].body_parts[BODY_WEAPON])
	{
		int str_index, dex_index;
		int num = 0, wgt = 0, mul = 0;
		monster_race *r_ptr = race_info_idx(p_ptr->body_monster, 0);

		analyze_blow(&num, &wgt, &mul);

		/* Access the strength vs weight */
		str_index = (adj_str_blow[p_ptr->stat_ind[A_STR]] * mul / 3);

		/* Maximal value */
		if (str_index > 11) str_index = 11;

		/* Index by dexterity */
		dex_index = (adj_dex_blow[p_ptr->stat_ind[A_DEX]]);

		/* Maximal value */
		if (dex_index > 11) dex_index = 11;

		/* Use the blows table */
		p_ptr->num_blow = blows_table[str_index][dex_index];

		/* Add in the "bonus blows" */
		p_ptr->num_blow += extra_blows;

		/* Maximal value */
		if (p_ptr->num_blow > 4) p_ptr->num_blow = 4;

		/* Require at least one blow */
		if (p_ptr->num_blow < 1) p_ptr->num_blow = 1;

		/* Limit as defined by monster body */
		for (num = 0; num < p_ptr->num_blow; num++)
			if (!r_ptr->blow[num].effect)
				break;
		p_ptr->num_blow = num;
	}

	/* Different calculation for monks with empty hands */
	else if ((!p_ptr->body_monster) && (p_ptr->mimic_form == resolve_mimic_name("Bear")) && (p_ptr->melee_style == SKILL_BEAR))
	{
		int plev = get_skill(SKILL_BEAR);

		p_ptr->num_blow = 0;

		p_ptr->num_blow += 2 + (plev / 5) + extra_blows;

		p_ptr->to_h -= (plev / 5);
		p_ptr->dis_to_h -= (plev / 5);

		p_ptr->to_d += (plev / 2);
		p_ptr->dis_to_d += (plev / 2);
	}

	/* Assume okay */
	p_ptr->icky_wield = FALSE;
	monk_armour_aux = FALSE;

	if (get_weaponmastery_skill() != -1)
	{
		int lev = get_skill(get_weaponmastery_skill());

		p_ptr->to_h_melee += lev;
		p_ptr->to_d_melee += lev / 2;
	}

	if (get_skill(SKILL_COMBAT))
	{
		int lev = get_skill_scale(SKILL_COMBAT, 10);

		p_ptr->to_d += lev;
		p_ptr->dis_to_d += lev;
	}

	if (get_skill(SKILL_DODGE))
	{
		/* Get the armor weight */
		int cur_wgt = 0;

		cur_wgt += p_ptr->inventory[INVEN_BODY].weight;
		cur_wgt += p_ptr->inventory[INVEN_HEAD].weight;
		cur_wgt += p_ptr->inventory[INVEN_ARM].weight;
		cur_wgt += p_ptr->inventory[INVEN_OUTER].weight;
		cur_wgt += p_ptr->inventory[INVEN_HANDS].weight;
		cur_wgt += p_ptr->inventory[INVEN_FEET].weight;

		/* Base dodge chance */
		p_ptr->dodge_chance = get_skill_scale(SKILL_DODGE, 150) + get_skill(SKILL_HAND);

		/* Armor weight bonus/penalty */
		p_ptr->dodge_chance -= cur_wgt * 2;

		/* Encumberance bonus/penalty */
		p_ptr->dodge_chance = p_ptr->dodge_chance - (calc_total_weight() / 100);

		/* Never below 0 */
		if (p_ptr->dodge_chance < 0) p_ptr->dodge_chance = 0;
	}
	else
	{
		p_ptr->dodge_chance = 0;
	}

	/* Parse all the weapons */
	i = 0;
	while (p_ptr->body_parts[i] == INVEN_WIELD)
	{
		o_ptr = &p_ptr->inventory[INVEN_WIELD + i];

		/* 2handed weapon and shield = less damage */
		if (p_ptr->inventory[INVEN_WIELD + i].k_idx && p_ptr->inventory[INVEN_ARM + i].k_idx)
		{
			/* Extract the item flags */
			object_flags(&p_ptr->inventory[INVEN_WIELD + i], &f1, &f2, &f3, &f4, &f5, &esp);

			if (f4 & TR4_COULD2H)
			{
				int tmp;

				/* Reduce the bonuses */
				tmp = o_ptr->to_h / 2;
				if (tmp < 0) tmp = -tmp;
				p_ptr->to_h_melee -= tmp;

				tmp = o_ptr->to_d / 2;
				if (tmp < 0) tmp = -tmp;
				tmp += (o_ptr->dd * o_ptr->ds) / 2;
				p_ptr->to_d_melee -= tmp;
			}
		}

		/* Priest weapon penalty for non-blessed edged weapons */
		if (((forbid_non_blessed()) && (!p_ptr->bless_blade) &&
		                ((o_ptr->tval == TV_AXE) || (o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM))) && (o_ptr->k_idx))
		{
			/* Reduce the real bonuses */
			p_ptr->to_h -= 15;
			p_ptr->to_d -= 15;

			/* Reduce the mental bonuses */
			p_ptr->dis_to_h -= 15;
			p_ptr->dis_to_d -= 15;

			/* Icky weapon */
			p_ptr->icky_wield = TRUE;
		}

		/* Sorcerer can't wield a weapon unless it's a mage staff */
		if (get_skill(SKILL_SORCERY))
		{
			int malus = get_skill_scale(SKILL_SORCERY, 100);

			if ((o_ptr->tval != TV_MSTAFF) && (o_ptr->k_idx))
			{
				/* Reduce the real bonuses */
				p_ptr->to_h -= malus;
				p_ptr->to_d -= malus;

				/* Reduce the mental bonuses */
				p_ptr->dis_to_h -= malus;
				p_ptr->dis_to_d -= malus;

				/* Icky weapon */
				p_ptr->icky_wield = TRUE;
			}
			else
			{
				/* Reduce the real bonuses */
				p_ptr->to_h -= malus / 10;
				p_ptr->to_d -= malus / 10;

				/* Reduce the mental bonuses */
				p_ptr->dis_to_h -= malus / 10;
				p_ptr->dis_to_d -= malus / 10;
			}
		}

		/* Check next weapon */
		i++;
	}

	if (monk_heavy_armor())
	{
		monk_armour_aux = TRUE;
	}

	/* Affect Skill -- stealth (bonus one) */
	p_ptr->skill_stl += 1;

	/* Affect Skill -- disarming (DEX and INT) */
	p_ptr->skill_dis += adj_dex_dis[p_ptr->stat_ind[A_DEX]];
	p_ptr->skill_dis += adj_int_dis[p_ptr->stat_ind[A_INT]];

	/* Affect Skill -- magic devices (INT) */
	p_ptr->skill_dev += get_skill_scale(SKILL_DEVICE, 20);

	/* Affect Skill -- saving throw (WIS) */
	p_ptr->skill_sav += adj_wis_sav[p_ptr->stat_ind[A_WIS]];

	/* Affect Skill -- digging (STR) */
	p_ptr->skill_dig += adj_str_dig[p_ptr->stat_ind[A_STR]];

	/* Affect Skill -- disarming (skill) */
	p_ptr->skill_dis += (get_skill_scale(SKILL_DISARMING, 75));

	/* Affect Skill -- magic devices (skill) */
	p_ptr->skill_dev += (get_skill_scale(SKILL_DEVICE, 150));

	/* Affect Skill -- saving throw (skill and level) */
	p_ptr->skill_sav += (get_skill_scale(SKILL_SPIRITUALITY, 75));

	/* Affect Skill -- stealth (skill) */
	p_ptr->skill_stl += (get_skill_scale(SKILL_STEALTH, 25));

	/* Affect Skill -- search ability (Sneakiness skill) */
	p_ptr->skill_srh += (get_skill_scale(SKILL_SNEAK, 35));

	/* Affect Skill -- search frequency (Sneakiness skill) */
	p_ptr->skill_fos += (get_skill_scale(SKILL_SNEAK, 25));

	/* Affect Skill -- combat (Combat skill + mastery) */
	p_ptr->skill_thn += (50 * (((7 * get_skill(p_ptr->melee_style)) + (3 * get_skill(SKILL_COMBAT))) / 10) / 10);

	/* Affect Skill -- combat (shooting) (Level, by Class) */
	p_ptr->skill_thb += (50 * (((7 * get_skill(SKILL_ARCHERY)) + (3 * get_skill(SKILL_COMBAT))) / 10) / 10);

	/* Affect Skill -- combat (throwing) (Level) */
	p_ptr->skill_tht += (50 * p_ptr->lev / 10);


	/* Limit Skill -- stealth from 0 to 30 */
	if (p_ptr->skill_stl > 30) p_ptr->skill_stl = 30;
	if (p_ptr->skill_stl < 0) p_ptr->skill_stl = 0;

	/* Limit Skill -- digging from 1 up */
	if (p_ptr->skill_dig < 1) p_ptr->skill_dig = 1;

	if ((p_ptr->anti_magic) && (p_ptr->skill_sav < 95)) p_ptr->skill_sav = 95;

	/* Hack -- handle "xtra" mode */
	if (character_xtra) return;

	/* Take note when "heavy bow" changes */
	if (p_ptr->old_heavy_shoot != p_ptr->heavy_shoot)
	{
		if (silent)
		{
			/* do nothing */
		}
		/* Message */
		else if (p_ptr->heavy_shoot)
		{
			msg_print("You have trouble wielding such a heavy bow.");
		}
		else if (p_ptr->inventory[INVEN_BOW].k_idx)
		{
			msg_print("You have no trouble wielding your bow.");
		}
		else
		{
			msg_print("You feel relieved to put down your heavy bow.");
		}

		/* Save it */
		p_ptr->old_heavy_shoot = p_ptr->heavy_shoot;
	}


	/* Take note when "heavy weapon" changes */
	if (p_ptr->old_heavy_wield != p_ptr->heavy_wield)
	{
		if (silent)
		{
			/* do nothing */
		}
		/* Message */
		else if (p_ptr->heavy_wield)
		{
			msg_print("You have trouble wielding such a heavy weapon.");
		}
		else if (p_ptr->inventory[INVEN_WIELD].k_idx)
		{
			msg_print("You have no trouble wielding your weapon.");
		}
		else
		{
			msg_print("You feel relieved to put down your heavy weapon.");
		}

		/* Save it */
		p_ptr->old_heavy_wield = p_ptr->heavy_wield;
	}


	/* Take note when "illegal weapon" changes */
	if (p_ptr->old_icky_wield != p_ptr->icky_wield)
	{
		if (silent)
		{
			/* do nothing */
		}
		/* Message */
		else if (p_ptr->icky_wield)
		{
			msg_print("You do not feel comfortable with your weapon.");
		}
		else if (p_ptr->inventory[INVEN_WIELD].k_idx)
		{
			msg_print("You feel comfortable with your weapon.");
		}
		else
		{
			msg_print("You feel more comfortable after removing your weapon.");
		}

		/* Save it */
		p_ptr->old_icky_wield = p_ptr->icky_wield;
	}

	if (monk_armour_aux != monk_notify_aux)
	{
		if ((p_ptr->melee_style != SKILL_HAND) || silent)
		{
			/* do nothing */
		}
		else if (monk_heavy_armor())
			msg_print("The weight of your armor disrupts your balance.");
		else
			msg_print("You regain your balance.");
		monk_notify_aux = monk_armour_aux;
	}

	/* Resist lite & senseible lite negates one an other */
	if (p_ptr->resist_lite && p_ptr->sensible_lite)
	{
		p_ptr->resist_lite = p_ptr->sensible_lite = FALSE;
	}

	/* resistance to fire cancel sensibility to fire */
	if (p_ptr->resist_fire || p_ptr->oppose_fire || p_ptr->immune_fire)
		p_ptr->sensible_fire = FALSE;

	/* Minimum saving throw */
	if(p_ptr->skill_sav <= 10)
		p_ptr->skill_sav = 10;
	else
		p_ptr->skill_sav += 10;

	/* Let the scripts do what they need */
	process_hooks(HOOK_CALC_BONUS_END, "(d)", silent);
}



/*
 * Handle "p_ptr->notice"
 */
void notice_stuff(void)
{
	/* Notice stuff */
	if (!p_ptr->notice) return;


	/* Combine the pack */
	if (p_ptr->notice & (PN_COMBINE))
	{
		p_ptr->notice &= ~(PN_COMBINE);
		combine_pack();
	}

	/* Reorder the pack */
	if (p_ptr->notice & (PN_REORDER))
	{
		p_ptr->notice &= ~(PN_REORDER);
		reorder_pack();
	}
}


/*
 * Handle "p_ptr->update"
 */
void update_stuff(void)
{
	/* Update stuff */
	if (!p_ptr->update) return;


	if (p_ptr->update & (PU_BODY))
	{
		p_ptr->update &= ~(PU_BODY);
		calc_body();
	}

	if (p_ptr->update & (PU_BONUS))
	{
		/* Ok now THAT is an ugly hack */
		p_ptr->update &= ~(PU_POWERS);
		calc_powers();

		p_ptr->update &= ~(PU_BONUS);
		calc_bonuses(FALSE);
	}

	if (p_ptr->update & (PU_TORCH))
	{
		p_ptr->update &= ~(PU_TORCH);
		calc_torch();
	}

	if (p_ptr->update & (PU_HP))
	{
		p_ptr->update &= ~(PU_HP);
		calc_hitpoints();
	}

	if (p_ptr->update & (PU_SANITY))
	{
		p_ptr->update &= ~(PU_SANITY);
		calc_sanity();
	}

	if (p_ptr->update & (PU_MANA))
	{
		p_ptr->update &= ~(PU_MANA);
		calc_mana();
	}

	if (p_ptr->update & (PU_SPELLS))
	{
		p_ptr->update &= ~(PU_SPELLS);
		calc_spells();
	}

	if (p_ptr->update & (PU_POWERS))
	{
		p_ptr->update &= ~(PU_POWERS);
		calc_powers();
	}

	/* Character is not ready yet, no screen updates */
	if (!character_generated) return;


	/* Character is in "icky" mode, no screen updates */
	if (character_icky) return;


	if (p_ptr->update & (PU_UN_VIEW))
	{
		p_ptr->update &= ~(PU_UN_VIEW);
		forget_view();
	}

	if (p_ptr->update & (PU_VIEW))
	{
		p_ptr->update &= ~(PU_VIEW);
		update_view();
	}

	if (p_ptr->update & (PU_FLOW))
	{
		p_ptr->update &= ~(PU_FLOW);
		update_flow();
	}

	if (p_ptr->update & (PU_DISTANCE))
	{
		p_ptr->update &= ~(PU_DISTANCE);
		p_ptr->update &= ~(PU_MONSTERS);
		update_monsters(TRUE);
	}

	if (p_ptr->update & (PU_MONSTERS))
	{
		p_ptr->update &= ~(PU_MONSTERS);
		update_monsters(FALSE);
	}

	if (p_ptr->update & (PU_MON_LITE))
	{
		p_ptr->update &= ~(PU_MON_LITE);
		if (monster_lite) update_mon_lite();
	}
}


/*
 * Handle "p_ptr->redraw"
 */
void redraw_stuff(void)
{
	/* Redraw stuff */
	if (!p_ptr->redraw) return;


	/* Character is not ready yet, no screen updates */
	if (!character_generated) return;


	/* Character is in "icky" mode, no screen updates */
	if (character_icky) return;


	/* Should we tell lua to redisplay too ? */
	process_hooks(HOOK_REDRAW, "()");


	/* Hack -- clear the screen */
	if (p_ptr->redraw & (PR_WIPE))
	{
		p_ptr->redraw &= ~(PR_WIPE);
		msg_print(NULL);
		Term_clear();
	}


	if (p_ptr->redraw & (PR_MAP))
	{
		p_ptr->redraw &= ~(PR_MAP);
		prt_map();
	}


	if (p_ptr->redraw & (PR_BASIC))
	{
		p_ptr->redraw &= ~(PR_BASIC);
		p_ptr->redraw &= ~(PR_MISC | PR_TITLE | PR_STATS);
		p_ptr->redraw &= ~(PR_LEV | PR_EXP | PR_GOLD);
		p_ptr->redraw &= ~(PR_ARMOR | PR_HP | PR_MANA | PR_PIETY | PR_MH);
		p_ptr->redraw &= ~(PR_DEPTH | PR_HEALTH);
		prt_frame_basic();
	}

	if (p_ptr->redraw & (PR_MISC))
	{
		p_ptr->redraw &= ~(PR_MISC);
		prt_field(rp_ptr->title + rp_name, ROW_RACE, COL_RACE);
		prt_field(spp_ptr->title + c_name, ROW_CLASS, COL_CLASS);
	}

	if (p_ptr->redraw & (PR_TITLE))
	{
		p_ptr->redraw &= ~(PR_TITLE);
		prt_title();
	}

	if (p_ptr->redraw & (PR_LEV))
	{
		p_ptr->redraw &= ~(PR_LEV);
		prt_level();
	}

	if (p_ptr->redraw & (PR_EXP))
	{
		p_ptr->redraw &= ~(PR_EXP);
		prt_exp();
	}

	if (p_ptr->redraw & (PR_STATS))
	{
		p_ptr->redraw &= ~(PR_STATS);
		prt_stat(A_STR);
		prt_stat(A_INT);
		prt_stat(A_WIS);
		prt_stat(A_DEX);
		prt_stat(A_CON);
		prt_stat(A_CHR);
	}

	if (p_ptr->redraw & (PR_ARMOR))
	{
		p_ptr->redraw &= ~(PR_ARMOR);
		prt_ac();
	}

	if (p_ptr->redraw & (PR_HP))
	{
		p_ptr->redraw &= ~(PR_HP);
		prt_hp();
	}

	if (p_ptr->redraw & (PR_MANA))
	{
		p_ptr->redraw &= ~(PR_MANA);
		prt_sp();
	}

	if (p_ptr->redraw & (PR_PIETY))
	{
		p_ptr->redraw &= ~(PR_PIETY);
		prt_piety();
	}

	if (p_ptr->redraw & (PR_MH))
	{
		p_ptr->redraw &= ~(PR_MH);
		prt_mh();
	}

	if (p_ptr->redraw & (PR_GOLD))
	{
		p_ptr->redraw &= ~(PR_GOLD);
		prt_gold();
	}

	if (p_ptr->redraw & (PR_DEPTH))
	{
		p_ptr->redraw &= ~(PR_DEPTH);
		prt_depth();
	}

	if (p_ptr->redraw & (PR_HEALTH))
	{
		p_ptr->redraw &= ~(PR_HEALTH);
		health_redraw();
	}


	if (p_ptr->redraw & (PR_EXTRA))
	{
		p_ptr->redraw &= ~(PR_EXTRA);
		p_ptr->redraw &= ~(PR_CUT | PR_STUN);
		p_ptr->redraw &= ~(PR_HUNGER);
		p_ptr->redraw &= ~(PR_BLIND | PR_CONFUSED);
		p_ptr->redraw &= ~(PR_AFRAID | PR_POISONED);
		p_ptr->redraw &= ~(PR_STATE | PR_SPEED | PR_STUDY | PR_SANITY);
		prt_frame_extra();
	}

	if (p_ptr->redraw & (PR_CUT))
	{
		p_ptr->redraw &= ~(PR_CUT);
		prt_cut();
	}

	if (p_ptr->redraw & (PR_STUN))
	{
		p_ptr->redraw &= ~(PR_STUN);
		prt_stun();
	}

	if (p_ptr->redraw & (PR_HUNGER))
	{
		p_ptr->redraw &= ~(PR_HUNGER);
		prt_hunger();
	}

	if (p_ptr->redraw & (PR_BLIND))
	{
		p_ptr->redraw &= ~(PR_BLIND);
		prt_blind();
	}

	if (p_ptr->redraw & (PR_CONFUSED))
	{
		p_ptr->redraw &= ~(PR_CONFUSED);
		prt_confused();
	}

	if (p_ptr->redraw & (PR_AFRAID))
	{
		p_ptr->redraw &= ~(PR_AFRAID);
		prt_afraid();
	}

	if (p_ptr->redraw & (PR_POISONED))
	{
		p_ptr->redraw &= ~(PR_POISONED);
		prt_poisoned();
	}

	if (p_ptr->redraw & (PR_DTRAP))
	{
		p_ptr->redraw &= ~(PR_DTRAP);
		prt_dtrap();
	}

	if (p_ptr->redraw & (PR_STATE))
	{
		p_ptr->redraw &= ~(PR_STATE);
		prt_state();
	}

	if (p_ptr->redraw & (PR_SPEED))
	{
		p_ptr->redraw &= ~(PR_SPEED);
		prt_speed();
	}

	if (p_ptr->redraw & (PR_STUDY))
	{
		p_ptr->redraw &= ~(PR_STUDY);
		prt_study();
	}

	if (p_ptr->redraw & (PR_SANITY))
	{
		p_ptr->redraw &= ~(PR_SANITY);
		prt_sane();
	}
}


/*
 * Handle "p_ptr->window"
 */
void window_stuff(void)
{
	int j;

	u32b mask = 0L;


	/* Nothing to do */
	if (!p_ptr->window) return;

	/* Scan windows */
	for (j = 0; j < 8; j++)
	{
		/* Save usable flags */
		if (angband_term[j]) mask |= window_flag[j];
	}

	/* Apply usable flags */
	p_ptr->window &= mask;

	/* Nothing to do */
	if (!p_ptr->window) return;


	/* Display p_ptr->inventory */
	if (p_ptr->window & (PW_INVEN))
	{
		p_ptr->window &= ~(PW_INVEN);
		fix_inven();
	}

	/* Display equipment */
	if (p_ptr->window & (PW_EQUIP))
	{
		p_ptr->window &= ~(PW_EQUIP);
		fix_equip();
	}

	/* Display player */
	if (p_ptr->window & (PW_PLAYER))
	{
		p_ptr->window &= ~(PW_PLAYER);
		fix_player();
	}

	/* Display monster list */
	if (p_ptr->window & (PW_M_LIST))
	{
		p_ptr->window &= ~(PW_M_LIST);
		fix_m_list();
	}

	/* Display overhead view */
	if (p_ptr->window & (PW_MESSAGE))
	{
		p_ptr->window &= ~(PW_MESSAGE);
		fix_message();
	}

	/* Display overhead view */
	if (p_ptr->window & (PW_IRC))
	{
		p_ptr->window &= ~(PW_IRC);
		fix_irc_message();
	}

	/* Display overhead view */
	if (p_ptr->window & (PW_OVERHEAD))
	{
		p_ptr->window &= ~(PW_OVERHEAD);
		fix_overhead();
	}

	/* Display monster recall */
	if (p_ptr->window & (PW_MONSTER))
	{
		p_ptr->window &= ~(PW_MONSTER);
		fix_monster();
	}

	/* Display object recall */
	if (p_ptr->window & (PW_OBJECT))
	{
		p_ptr->window &= ~(PW_OBJECT);
		fix_object();
	}
}


/*
 * Handle "p_ptr->update" and "p_ptr->redraw" and "p_ptr->window"
 */
void handle_stuff(void)
{
	/* Update stuff */
	if (p_ptr->update) update_stuff();

	/* Redraw stuff */
	if (p_ptr->redraw) redraw_stuff();

	/* Window stuff */
	if (p_ptr->window) window_stuff();
}


bool monk_empty_hands(void)
{
	int i;
	object_type *o_ptr;

	if (p_ptr->melee_style != SKILL_HAND) return FALSE;

	i = 0;
	while (p_ptr->body_parts[i] == INVEN_WIELD)
	{
		o_ptr = &p_ptr->inventory[INVEN_WIELD + i];

		if (o_ptr->k_idx) return FALSE;

		i++;
	}

	return TRUE;
}

bool monk_heavy_armor(void)
{
	u16b monk_arm_wgt = 0;

	if (p_ptr->melee_style != SKILL_HAND) return FALSE;

	/* Weight the armor */
	monk_arm_wgt += p_ptr->inventory[INVEN_BODY].weight;
	monk_arm_wgt += p_ptr->inventory[INVEN_HEAD].weight;
	monk_arm_wgt += p_ptr->inventory[INVEN_ARM].weight;
	monk_arm_wgt += p_ptr->inventory[INVEN_OUTER].weight;
	monk_arm_wgt += p_ptr->inventory[INVEN_HANDS].weight;
	monk_arm_wgt += p_ptr->inventory[INVEN_FEET].weight;

	return (monk_arm_wgt > (100 + (get_skill(SKILL_HAND) * 4))) ;
}

static int get_artifact_idx(int level)
{
	int count = 0, i;
	bool OK = FALSE;

	while (count < 1000)
	{
		artifact_type *a_ptr;

		count++;
		i = randint(max_a_idx - 1);
		a_ptr = &a_info[i];
		if (!a_ptr->tval) continue;

		/* It is found/lost */
		if (a_ptr->cur_num) continue;

		/* OoD */
		if (a_ptr->level > level) continue;

		/* Avoid granting SPECIAL_GENE artifacts */
		if (a_ptr->flags4 & TR4_SPECIAL_GENE) continue;

		OK = TRUE;
		break;
	}

	/* No matches found */
	if (OK == FALSE)
	{
#if 0 /* pelpel */
		/* XXX XXX XXX Grant the Phial */
		i = 1;
#endif /* pelpel */

		/* Grant a randart */
		i = 0;
	}

	return i;
}

/* Chose a fate */
void gain_fate(byte fate)
{
	int i;
	int level;

	for (i = 0; i < MAX_FATES; i++)
	{
		if (!fates[i].fate)
		{
			fates[i].level = 0;

			cmsg_print(TERM_VIOLET, "More of your prophecy has been unearthed!");
			cmsg_print(TERM_VIOLET, "You should see a soothsayer quickly.");

			if (fate)
				fates[i].fate = fate;
			else
				/* If lucky (current luck > 0) avoid death fate */
				switch (rand_int(p_ptr->luck_cur > 0 ? 17 : 18))
				{
				case 6:
				case 2:
				case 3:
				case 7:
				case 8:
				case 9:
				case 13:
					fates[i].fate = FATE_FIND_O;
					break;
				case 1:
				case 4:
				case 5:
				case 10:
				case 11:
				case 12:
				case 14:
					fates[i].fate = FATE_FIND_R;
					break;
				case 15:
				case 16:
					fates[i].fate = FATE_FIND_A;
					break;
				case 17:
					fates[i].fate = FATE_DIE;
					break;
				case 0:
					{
						/* The deepest the better */
						int chance = dun_level / 4;

						/* No more than 1/2 chances */
						if (chance > 50) chance = 50;

						/* It's HARD to get now */
						if (magik(chance))
						{
							fates[i].fate = FATE_NO_DIE_MORTAL;
						}
						else
						{
							fates[i].fate = FATE_FIND_O;
						}
						break;
					}
				}

			switch (fates[i].fate)
			{
			case FATE_FIND_O:
				{
					while (TRUE)
					{
						object_kind *k_ptr;
						obj_theme theme;

						/* No themes */
						theme.treasure = 100;
						theme.combat = 100;
						theme.magic = 100;
						theme.tools = 100;
						init_match_theme(theme);

						/* Apply restriction */
						get_obj_num_hook = kind_is_legal;

						/* Rebuild allocation table */
						get_obj_num_prep();

						fates[i].o_idx = get_obj_num(max_dlv[dungeon_type] + randint(10));

						/* Invalidate the cached allocation table */
						alloc_kind_table_valid = FALSE;

						k_ptr = &k_info[fates[i].o_idx];

						if (!(k_ptr->flags3 & TR3_INSTA_ART) && !(k_ptr->flags3 & TR3_NORM_ART)) break;
					}
					level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
					fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
					fates[i].serious = rand_int(2);
					fates[i].know = FALSE;
					if (wizard) msg_format("New fate : Find object %d on level %d", fates[i].o_idx, fates[i].level);
					break;
				}
			case FATE_FIND_R:
				/* Prepare allocation table */
				get_mon_num_prep();

				fates[i].r_idx = get_mon_num(max_dlv[dungeon_type] + randint(10));
				level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
				fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
				fates[i].serious = rand_int(2);
				fates[i].know = FALSE;
				if (wizard) msg_format("New fate : Meet monster %d on level %d", fates[i].r_idx, fates[i].level);
				break;

			case FATE_FIND_A:
				fates[i].a_idx = get_artifact_idx(max_dlv[dungeon_type] + randint(10));
				level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
				fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
				fates[i].serious = TRUE;
				fates[i].know = FALSE;
				if (wizard) msg_format("New fate : Find artifact %d on level %d", fates[i].a_idx, fates[i].level);
				break;

			case FATE_DIE:
				level = rand_range(max_dlv[dungeon_type] - 20, max_dlv[dungeon_type] + 20);
				fates[i].level = (level < 1) ? 1 : (level > 98) ? 98 : level;
				fates[i].serious = TRUE;
				fates[i].know = FALSE;
				if ((wizard) || (p_ptr->precognition)) msg_format("New fate : Death on level %d", fates[i].level);
				break;

			case FATE_NO_DIE_MORTAL:
				fates[i].serious = TRUE;
				p_ptr->no_mortal = TRUE;
				if ((wizard) || (p_ptr->precognition)) msg_format("New fate : Never to die by the hand of a mortal being.");
				break;
			}

			break;
		}
	}
}

void fate_desc(char *desc, int fate)
{
	char buf[120];

	if (fates[fate].serious)
	{
		strcpy(desc, "You are fated to ");
	}
	else
	{
		strcpy(desc, "You may ");
	}
	switch (fates[fate].fate)
	{
	case FATE_FIND_O:
		{
			object_type *o_ptr, forge;
			char o_name[80];

			o_ptr = &forge;
			object_prep(o_ptr, fates[fate].o_idx);
			object_desc_store(o_name, o_ptr, 1, 0);

			sprintf(buf, "find %s on level %d.", o_name, fates[fate].level);
			strcat(desc, buf);
			break;
		}
	case FATE_FIND_A:
		{
			object_type *q_ptr, forge;
			char o_name[80];
			artifact_type *a_ptr = &a_info[fates[fate].a_idx];
			int I_kind;

			/* Failed artefact allocation XXX XXX XXX */
			if (fates[fate].a_idx == 0)
			{
				strcpy(o_name, "something special");
			}

			/* Legal artefacts */
			else
			{
				/* Get local object */
				q_ptr = &forge;

				/* Wipe the object */
				object_wipe(q_ptr);

				/* Acquire the "kind" index */
				I_kind = lookup_kind(a_ptr->tval, a_ptr->sval);

				/* Create the artifact */
				object_prep(q_ptr, I_kind);

				/* Save the name */
				q_ptr->name1 = fates[fate].a_idx;

				/* Extract the fields */
				q_ptr->pval = a_ptr->pval;
				q_ptr->ac = a_ptr->ac;
				q_ptr->dd = a_ptr->dd;
				q_ptr->ds = a_ptr->ds;
				q_ptr->to_a = a_ptr->to_a;
				q_ptr->to_h = a_ptr->to_h;
				q_ptr->to_d = a_ptr->to_d;
				q_ptr->weight = a_ptr->weight;

				/* Hack -- acquire "cursed" flag */
				if (a_ptr->flags3 & (TR3_CURSED)) q_ptr->ident |= (IDENT_CURSED);

				random_artifact_resistance(q_ptr);

				object_desc_store(o_name, q_ptr, 1, 0);
			}

			sprintf(buf, "find %s on level %d.", o_name, fates[fate].level);
			strcat(desc, buf);
			break;
		}
	case FATE_FIND_R:
		{
			char m_name[80];

			monster_race_desc(m_name, fates[fate].r_idx, 0);
			sprintf(buf, "meet %s on level %d.", m_name, fates[fate].level);
			strcat(desc, buf);
			break;
		}
	case FATE_DIE:
		{
			sprintf(buf, "die on level %d.", fates[fate].level);
			strcat(desc, buf);
			break;
		}
	case FATE_NO_DIE_MORTAL:
		{
			strcat(desc, "never to die by the hand of a mortal being.");
			break;
		}
	}
}

void dump_fates(FILE *outfile)
{
	int i;
	char buf[120];

	if (!outfile) return;

	for (i = 0; i < MAX_FATES; i++)
	{
		if ((fates[i].fate) && (fates[i].know))
		{
			fate_desc(buf, i);
			fprintf(outfile, "%s\n", buf);
		}
	}
}

/*
 * Return a luck number between a certain range
 */
int luck(int min, int max)
{
	int luck = p_ptr->luck_cur;
	int range = max - min;

	if (luck < -30) luck = -30;
	if (luck > 30) luck = 30;
	luck += 30;

	luck *= range;
	luck /= 60;

	return (luck + min);
}
tome-235-src/src/xtra2.c0000644000076400017500000043224011012107763012666 0ustar  dgdg/* File: xtra2.c */
/* File: xtra2.c */

/* Purpose: effects of various "objects", targetting and panel handling */

/*
 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
 *
 * This software may be copied and distributed for educational, research, and
 * not for profit purposes provided that this copyright and statement are
 * included in all such copies.
 */

#include "angband.h"

/*
 * Invoke The Rush
 */
bool set_rush(int v)
{
	int j;

	/* Invoke The Bust */
	if (!v)
	{
		p_ptr->rush = 0;

		j = 50 - randint(p_ptr->lev);
		set_paralyzed(j);
		set_slow(j + 50 - randint(p_ptr->lev));
		return TRUE;
	}

	/* When is The Bust going to happen? */
	p_ptr->rush = v;

	/* The bonuses of The Rush */
	set_hero(p_ptr->hero + v);
	set_tim_deadly(p_ptr->tim_deadly + v);
	set_strike(p_ptr->strike + v);
	if (magik(p_ptr->lev / 2))
	{
		set_light_speed(p_ptr->lightspeed + v);
	}
	else
	{
		set_fast(p_ptr->fast + v, 10);
	}
	if (magik(p_ptr->lev / 2)) set_tim_esp(p_ptr->tim_esp + v);
	return TRUE;
}


/*
 * Set "p_ptr->parasite" and "p_ptr->parasite_r_idx"
 * notice observable changes
 */
bool set_parasite(int v, int r)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->parasite)
		{
			msg_print("You feel something growing in you.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->parasite)
		{
			if (magik(80))
			{
				char r_name[80];
				int wx, wy;
				int attempts = 500;

				monster_race_desc(r_name, p_ptr->parasite_r_idx, 0);

				do
				{
					scatter(&wy, &wx, p_ptr->py, p_ptr->px, 10, 0);
				}
				while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);

				if (place_monster_one(wy, wx, p_ptr->parasite_r_idx, 0, FALSE, MSTATUS_ENEMY))
				{
					cmsg_format(TERM_L_BLUE, "Your body convulses and spawns %s.", r_name);
					p_ptr->food -= 750;
					if (p_ptr->food < 100) p_ptr->food = 100;
				}
			}
			else
			{
				cmsg_print(TERM_L_BLUE, "The hideous thing growing in you seems to die.");
			}
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->parasite = v;
	p_ptr->parasite_r_idx = r;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_project" and others
 * notice observable changes
 */
bool set_project(int v, s16b gf, s16b dam, s16b rad, s16b flag)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_project)
		{
			msg_print("Your weapon starts glowing.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_project)
		{
			msg_print("Your weapon stops glowing.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_project = v;
	p_ptr->tim_project_gf = gf;
	p_ptr->tim_project_dam = dam;
	p_ptr->tim_project_rad = rad;
	p_ptr->tim_project_flag = flag;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_roots" and others
 * notice observable changes
 */
bool set_roots(int v, s16b ac, s16b dam)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_roots)
		{
			msg_print("Roots dive into the floor from your feet.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_roots)
		{
			msg_print("The roots of your feet suddenly vanish.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_roots = v;
	p_ptr->tim_roots_dam = dam;
	p_ptr->tim_roots_ac = ac;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_(magic|water)_breath" and others
 * notice observable changes
 */
bool set_tim_breath(int v, bool magical)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (magical)
		{
			if (!p_ptr->tim_magic_breath)
			{
				msg_print("Air seems to fill your lungs without breathing.");
				notice = TRUE;
			}
		}
		else
		{
			if (!p_ptr->tim_water_breath)
			{
				msg_print("Water seems to fill your lungs.");
				notice = TRUE;
			}
		}
	}

	/* Shut */
	else
	{
		if (magical)
		{
			if (p_ptr->tim_magic_breath)
			{
				msg_print("You need to breathe again.");
				notice = TRUE;
			}
		}
		else
		{
			if (p_ptr->tim_water_breath)
			{
				msg_print("The water filling your lungs evaporates.");
				notice = TRUE;
			}
		}
	}

	/* Use the value */
	if (magical)
		p_ptr->tim_magic_breath = v;
	else
		p_ptr->tim_water_breath = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->absorb_soul"
 * notice observable changes
 */
bool set_absorb_soul(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->absorb_soul)
		{
			cmsg_print(TERM_L_DARK, "You start absorbing the souls of your foes.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->absorb_soul)
		{
			cmsg_print(TERM_L_DARK, "You stop absorbing the souls of dead foes.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->absorb_soul = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->disrupt_shield"
 * notice observable changes
 */
bool set_disrupt_shield(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->disrupt_shield)
		{
			cmsg_print(TERM_L_BLUE, "You feel invulnerable.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->disrupt_shield)
		{
			cmsg_print(TERM_L_RED, "You are more vulnerable.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->disrupt_shield = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->prob_travel"
 * notice observable changes
 */
bool set_prob_travel(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->prob_travel)
		{
			msg_print("You feel instable.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->prob_travel)
		{
			msg_print("You are more stable.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->prob_travel = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_invis", and "p_ptr->tim_inv_pow",
 * notice observable changes
 */
bool set_invis(int v, int p)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_invisible)
		{
			msg_print("You feel your body fade away.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_invisible)
		{
			msg_print("You are no longer invisible.");
			notice = TRUE;
			p = 0;
		}
	}

	/* Use the value */
	p_ptr->tim_invisible = v;
	p_ptr->tim_inv_pow = p;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_poison",
 * notice observable changes
 */
bool set_poison(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_poison)
		{
			msg_print("Your hands are dripping with venom.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_poison)
		{
			msg_print("The venom source dries out.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_poison = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "no_breeds"
 */
bool set_no_breeders(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!no_breeds)
		{
			msg_print("You feel an anti-sexual aura.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (no_breeds)
		{
			msg_print("You no longer feel an anti-sexual aura.");
			notice = TRUE;
		}
	}

	/* Use the value */
	no_breeds = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_deadly"
 */
bool set_tim_deadly(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_deadly)
		{
			msg_print("You feel extremely accurate.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_deadly)
		{
			msg_print("You are suddenly much less accurate.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_deadly = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_ffall"
 */
bool set_tim_ffall(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_ffall)
		{
			msg_print("You feel very light.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_ffall)
		{
			msg_print("You are suddenly heavier.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_ffall = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_fly"
 */
bool set_tim_fly(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_fly)
		{
			msg_print("You feel able to reach the clouds.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_fly)
		{
			msg_print("You are suddenly a lot heavier.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_fly = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->meditation"
 */
bool set_meditation(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->meditation)
		{
			msg_print("You start meditating on yourself...");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->meditation)
		{
			msg_print("You stop your self meditation.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->meditation = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);
	p_ptr->update |= (PU_MANA);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_reflect"
 */
bool set_tim_reflect(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_reflect)
		{
			msg_print("You start reflecting the world around you.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_reflect)
		{
			msg_print("You stop reflecting.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_reflect = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_res_time"
 */
bool set_tim_res_time(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_res_time)
		{
			msg_print("You are now protected against space-time distortions.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_res_time)
		{
			msg_print("You are no longer protected against space-time distortions.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_res_time = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_fire_aura"
 */
bool set_tim_fire_aura(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_fire_aura)
		{
			msg_print("You are enveloped in flames.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_fire_aura)
		{
			msg_print("You are no longer enveloped in flames.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_fire_aura = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->strike"
 */
bool set_strike(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->strike)
		{
			msg_print("You feel very accurate.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->strike)
		{
			msg_print("You are no longer very accurate.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->strike = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->oppose_ld"
 */
bool set_oppose_ld(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_ld)
		{
			msg_print("You feel protected against light's fluctuation.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_ld)
		{
			msg_print("You are no longer protected against light's fluctuation.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_ld = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->oppose_cc"
 */
bool set_oppose_cc(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_cc)
		{
			msg_print("You feel protected against raw chaos.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_cc)
		{
			msg_print("You are no longer protected against chaos.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_cc = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->oppose_ss"
 */
bool set_oppose_ss(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_ss)
		{
			msg_print("You feel protected against the ravages of sound and shards.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_ss)
		{
			msg_print("You are no longer protected against the ravages of sound and shards.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_ss = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->oppose_nex"
 */
bool set_oppose_nex(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_nex)
		{
			msg_print("You feel protected against the strange forces of nexus.");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_nex)
		{
			msg_print("You are no longer protected against the strange forces of nexus.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_nex = v;

	/* Nothing to notice */
	if (!notice)
		return (FALSE);

	/* Disturb */
	if (disturb_state)
		disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_mimic", and "p_ptr->mimic_form",
 * notice observable changes
 */
bool set_mimic(int v, int p, int level)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_mimic)
		{
			msg_print("You feel your body change.");
			p_ptr->mimic_form = p;
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_mimic)
		{
			msg_print("You are no longer transformed.");
			p_ptr->mimic_form = 0;
			notice = TRUE;
			if (p == resolve_mimic_name("Bear"))
			{
				s_info[SKILL_BEAR].hidden = TRUE;
				select_default_melee();
			}
			p = 0;
		}
	}

	/* Use the value */
	p_ptr->tim_mimic = v;
	p_ptr->mimic_level = level;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Redraw title */
	p_ptr->redraw |= (PR_TITLE);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BODY | PU_BONUS | PU_SANITY);

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->blind", notice observable changes
 *
 * Note the use of "PU_UN_VIEW", which is needed to memorize any terrain
 * features which suddenly become "visible".
 * Note that blindness is currently the only thing which can affect
 * "player_can_see_bold()".
 */
bool set_blind(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->blind)
		{
			msg_print("You are blind!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->blind)
		{
			msg_print("You can see again.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->blind = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Fully update the visuals */
	p_ptr->update |= (PU_UN_VIEW | PU_VIEW | PU_MONSTERS | PU_MON_LITE);

	/* Redraw map */
	p_ptr->redraw |= (PR_MAP);

	/* Redraw the "blind" */
	p_ptr->redraw |= (PR_BLIND);

	/* Window stuff */
	p_ptr->window |= (PW_OVERHEAD);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_lite", notice observable changes
 *
 * Note the use of "PU_VIEW", which is needed to
 * memorize any terrain features which suddenly become "visible".
 * Note that blindness is currently the only thing which can affect
 * "player_can_see_bold()".
 */
bool set_lite(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_lite)
		{
			msg_print("You suddenly seem brighter!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_lite)
		{
			msg_print("You are no longer bright.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_lite = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Fully update the visuals */
	p_ptr->update |= (PU_VIEW | PU_MONSTERS);

	/* Redraw map */
	p_ptr->redraw |= (PR_MAP);

	/* Window stuff */
	p_ptr->window |= (PW_OVERHEAD);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->confused", notice observable changes
 */
bool set_confused(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->confused)
		{
			msg_print("You are confused!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->confused)
		{
			msg_print("You feel less confused now.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->confused = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Redraw the "confused" */
	p_ptr->redraw |= (PR_CONFUSED);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->poisoned", notice observable changes
 */
bool set_poisoned(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->poisoned)
		{
			msg_print("You are poisoned!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->poisoned)
		{
			msg_print("You are no longer poisoned.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->poisoned = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Redraw the "poisoned" */
	p_ptr->redraw |= (PR_POISONED);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->afraid", notice observable changes
 */
bool set_afraid(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->afraid)
		{
			msg_print("You are terrified!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->afraid)
		{
			msg_print("You feel bolder now.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->afraid = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Redraw the "afraid" */
	p_ptr->redraw |= (PR_AFRAID);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->paralyzed", notice observable changes
 */
bool set_paralyzed(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->paralyzed)
		{
			msg_print("You are paralyzed!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->paralyzed)
		{
			msg_print("You can move again.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->paralyzed = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Redraw the state */
	p_ptr->redraw |= (PR_STATE);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->image", notice observable changes
 *
 * Note that we must redraw the map when hallucination changes.
 */
bool set_image(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->image)
		{
			msg_print("Oh, wow! Everything looks so cosmic now!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->image)
		{
			msg_print("You can see clearly again.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->image = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Redraw map */
	p_ptr->redraw |= (PR_MAP);

	/* Update monsters */
	p_ptr->update |= (PU_MONSTERS);

	/* Window stuff */
	p_ptr->window |= (PW_OVERHEAD | PW_M_LIST);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->lightspeed", notice observable changes
 */
bool set_light_speed(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->lightspeed)
		{
			msg_print("You feel as if time has stopped!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->lightspeed)
		{
			msg_print("You feel time returning to its normal rate.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->lightspeed = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

bool set_fast(int v, int p)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->fast)
		{
			msg_print("You feel yourself moving faster!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->fast)
		{
			msg_print("You feel yourself slow down.");
			p = 0;
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->fast = v;
	p_ptr->speed_factor = p;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->slow", notice observable changes
 */
bool set_slow(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->slow)
		{
			msg_print("You feel yourself moving slower!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->slow)
		{
			msg_print("You feel yourself speed up.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->slow = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->shield", notice observable changes
 */
bool set_shield(int v, int p, s16b o, s16b d1, s16b d2)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->shield)
		{
			msg_print("A mystic shield forms around your body!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->shield)
		{
			msg_print("Your mystic shield crumbles away.");
			notice = TRUE;
			p = 0;
		}
	}

	/* Use the value */
	p_ptr->shield = v;
	p_ptr->shield_power = p;
	p_ptr->shield_opt = o;
	p_ptr->shield_power_opt = d1;
	p_ptr->shield_power_opt2 = d2;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}



/*
 * Set "p_ptr->blessed", notice observable changes
 */
bool set_blessed(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->blessed)
		{
			msg_print("You feel righteous!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->blessed)
		{
			msg_print("The prayer has expired.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->blessed = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->hero", notice observable changes
 */
bool set_hero(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->hero)
		{
			msg_print("You feel like a hero!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->hero)
		{
			msg_print("The heroism wears off.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->hero = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Recalculate hitpoints */
	p_ptr->update |= (PU_HP);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->holy", notice observable changes
 */
bool set_holy(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->holy)
		{
			msg_print("You feel a holy aura around you!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->holy)
		{
			msg_print("The holy aura vanishes.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->holy = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->walk_water", notice observable changes
 */
bool set_walk_water(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->walk_water)
		{
			msg_print("You feel strangely buoyant!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->walk_water)
		{
			msg_print("You feel much less buoyant.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->walk_water = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->shero", notice observable changes
 */
bool set_shero(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->shero)
		{
			msg_print("You feel like a killing machine!");
			notice = TRUE;

			/* Redraw map */
			p_ptr->redraw |= (PR_MAP);

			/* Update monsters */
			p_ptr->update |= (PU_MONSTERS);

			/* Window stuff */
			p_ptr->window |= (PW_OVERHEAD);
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->shero)
		{
			msg_print("You feel less berserk.");
			notice = TRUE;

			/* Redraw map */
			p_ptr->redraw |= (PR_MAP);

			/* Update monsters */
			p_ptr->update |= (PU_MONSTERS);

			/* Window stuff */
			p_ptr->window |= (PW_OVERHEAD);
		}
	}

	/* Use the value */
	p_ptr->shero = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Recalculate hitpoints */
	p_ptr->update |= (PU_HP);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->protevil", notice observable changes
 */
bool set_protevil(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->protevil)
		{
			msg_print("You feel safe from evil!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->protevil)
		{
			msg_print("You no longer feel safe from evil.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->protevil = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->protgood", notice observable changes
 */
bool set_protgood(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->protgood)
		{
			msg_print("You feel safe from good!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->protgood)
		{
			msg_print("You no longer feel safe from good.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->protgood = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->protundead", notice observable changes
 */
bool set_protundead(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->protundead)
		{
			msg_print("You feel safe from undead!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->protundead)
		{
			msg_print("You no longer feel safe from undead.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->protundead = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->set_shadow", notice observable changes
 */
bool set_shadow(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_wraith)
		{

			msg_print("You leave the physical world and turn into a wraith-being!");
			notice = TRUE;

			{
				/* Redraw map */
				p_ptr->redraw |= (PR_MAP);

				/* Update monsters */
				p_ptr->update |= (PU_MONSTERS);

				/* Window stuff */
				p_ptr->window |= (PW_OVERHEAD);
			}
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_wraith)
		{
			msg_print("You feel opaque.");
			notice = TRUE;
			{
				/* Redraw map */
				p_ptr->redraw |= (PR_MAP);

				/* Update monsters */
				p_ptr->update |= (PU_MONSTERS);

				/* Window stuff */
				p_ptr->window |= (PW_OVERHEAD);
			}
		}
	}

	/* Use the value */
	p_ptr->tim_wraith = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);




	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);

}




/*
 * Set "p_ptr->invuln", notice observable changes
 */
bool set_invuln(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->invuln)
		{

			cmsg_print(TERM_L_BLUE, "Invulnerability!");
			notice = TRUE;

			{
				/* Redraw map */
				p_ptr->redraw |= (PR_MAP);

				/* Update monsters */
				p_ptr->update |= (PU_MONSTERS);

				/* Window stuff */
				p_ptr->window |= (PW_OVERHEAD);
			}
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->invuln)
		{
			cmsg_print(TERM_L_RED, "The invulnerability wears off.");
			notice = TRUE;
			{
				/* Redraw map */
				p_ptr->redraw |= (PR_MAP);

				/* Update monsters */
				p_ptr->update |= (PU_MONSTERS);

				/* Window stuff */
				p_ptr->window |= (PW_OVERHEAD);
			}
		}
	}

	/* Use the value */
	p_ptr->invuln = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);




	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);

}



/*
 * Set "p_ptr->tim_esp", notice observable changes
 */
bool set_tim_esp(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_esp)
		{
			msg_print("You feel your consciousness expand!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_esp)
		{
			msg_print("Your consciousness contracts again.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_esp = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Update the monsters */
	p_ptr->update |= (PU_MONSTERS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_thunder", notice observable changes
 */
bool set_tim_thunder(int v, int p1, int p2)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_thunder)
		{
			msg_print("The air around you charges with lightning!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_thunder)
		{
			msg_print("The air around you discharges.");
			notice = TRUE;
			p1 = p2 = 0;
		}
	}

	/* Use the value */
	p_ptr->tim_thunder = v;
	p_ptr->tim_thunder_p1 = p1;
	p_ptr->tim_thunder_p2 = p2;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Update the monsters */
	p_ptr->update |= (PU_MONSTERS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->tim_invis", notice observable changes
 */
bool set_tim_invis(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_invis)
		{
			msg_print("Your eyes feel very sensitive!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_invis)
		{
			msg_print("Your eyes feel less sensitive.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_invis = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Update the monsters */
	p_ptr->update |= (PU_MONSTERS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->tim_infra", notice observable changes
 */
bool set_tim_infra(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_infra)
		{
			msg_print("Your eyes begin to tingle!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_infra)
		{
			msg_print("Your eyes stop tingling.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_infra = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Update the monsters */
	p_ptr->update |= (PU_MONSTERS);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->tim_mental_barrier", notice observable changes
 */
bool set_mental_barrier(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_mental_barrier)
		{
			msg_print("Your mind grows stronger!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_mental_barrier)
		{
			msg_print("Your mind is no longer especially strong.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_mental_barrier = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

/*
 * Set "p_ptr->oppose_acid", notice observable changes
 */
bool set_oppose_acid(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_acid)
		{
			msg_print("You feel resistant to acid!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_acid)
		{
			msg_print("You feel less resistant to acid.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_acid = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->oppose_elec", notice observable changes
 */
bool set_oppose_elec(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_elec)
		{
			msg_print("You feel resistant to electricity!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_elec)
		{
			msg_print("You feel less resistant to electricity.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_elec = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->oppose_fire", notice observable changes
 */
bool set_oppose_fire(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_fire)
		{
			msg_print("You feel resistant to fire!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_fire)
		{
			msg_print("You feel less resistant to fire.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_fire = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->oppose_cold", notice observable changes
 */
bool set_oppose_cold(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_cold)
		{
			msg_print("You feel resistant to cold!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_cold)
		{
			msg_print("You feel less resistant to cold.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_cold = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->oppose_pois", notice observable changes
 */
bool set_oppose_pois(int v)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->oppose_pois)
		{
			msg_print("You feel resistant to poison!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->oppose_pois)
		{
			msg_print("You feel less resistant to poison.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->oppose_pois = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->tim_regen", notice observable changes
 */
bool set_tim_regen(int v, int p)
{
	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	/* Open */
	if (v)
	{
		if (!p_ptr->tim_regen)
		{
			msg_print("Your body regenerates much more quickly!");
			notice = TRUE;
		}
	}

	/* Shut */
	else
	{
		if (p_ptr->tim_regen)
		{
			p = 0;
			msg_print("Your body regenerates much more slowly.");
			notice = TRUE;
		}
	}

	/* Use the value */
	p_ptr->tim_regen = v;
	p_ptr->tim_regen_pow = p;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->stun", notice observable changes
 *
 * Note the special code to only notice "range" changes.
 */
bool set_stun(int v)
{
	int old_aux, new_aux;
	bool notice = FALSE;


	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	if (PRACE_FLAG(PR1_NO_STUN)) v = 0;

	/* Knocked out */
	if (p_ptr->stun > 100)
	{
		old_aux = 3;
	}

	/* Heavy stun */
	else if (p_ptr->stun > 50)
	{
		old_aux = 2;
	}

	/* Stun */
	else if (p_ptr->stun > 0)
	{
		old_aux = 1;
	}

	/* None */
	else
	{
		old_aux = 0;
	}

	/* Knocked out */
	if (v > 100)
	{
		new_aux = 3;
	}

	/* Heavy stun */
	else if (v > 50)
	{
		new_aux = 2;
	}

	/* Stun */
	else if (v > 0)
	{
		new_aux = 1;
	}

	/* None */
	else
	{
		new_aux = 0;
	}

	/* Increase cut */
	if (new_aux > old_aux)
	{
		/* Describe the state */
		switch (new_aux)
		{
			/* Stun */
		case 1:
			msg_print("You have been stunned.");
			break;

			/* Heavy stun */
		case 2:
			msg_print("You have been heavily stunned.");
			break;

			/* Knocked out */
		case 3:
			msg_print("You have been knocked out.");
			break;
		}

		if (randint(1000) < v || randint(16) == 1)
		{

			msg_print("A vicious blow hits your head.");
			if (randint(3) == 1)
			{
				if (!p_ptr->sustain_int)
				{
					(void) do_dec_stat(A_INT, STAT_DEC_NORMAL);
				}
				if (!p_ptr->sustain_wis)
				{
					(void) do_dec_stat(A_WIS, STAT_DEC_NORMAL);
				}
			}
			else if (randint(2) == 1)
			{
				if (!p_ptr->sustain_int)
				{
					(void) do_dec_stat(A_INT, STAT_DEC_NORMAL);
				}
			}
			else
			{
				if (!p_ptr->sustain_wis)
				{
					(void) do_dec_stat(A_WIS, STAT_DEC_NORMAL);
				}
			}
		}

		/* Notice */
		notice = TRUE;
	}

	/* Decrease cut */
	else if (new_aux < old_aux)
	{
		/* Describe the state */
		switch (new_aux)
		{
			/* None */
		case 0:
			msg_print("You are no longer stunned.");
			if (disturb_state) disturb(0, 0);
			break;
		}

		/* Notice */
		notice = TRUE;
	}

	/* Use the value */
	p_ptr->stun = v;

	/* No change */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Redraw the "stun" */
	p_ptr->redraw |= (PR_STUN);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Set "p_ptr->cut", notice observable changes
 *
 * Note the special code to only notice "range" changes.
 */
bool set_cut(int v)
{
	int old_aux, new_aux;

	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;

	if (PRACE_FLAG(PR1_NO_CUT)) v = 0;

	/* Mortal wound */
	if (p_ptr->cut > 1000)
	{
		old_aux = 7;
	}

	/* Deep gash */
	else if (p_ptr->cut > 200)
	{
		old_aux = 6;
	}

	/* Severe cut */
	else if (p_ptr->cut > 100)
	{
		old_aux = 5;
	}

	/* Nasty cut */
	else if (p_ptr->cut > 50)
	{
		old_aux = 4;
	}

	/* Bad cut */
	else if (p_ptr->cut > 25)
	{
		old_aux = 3;
	}

	/* Light cut */
	else if (p_ptr->cut > 10)
	{
		old_aux = 2;
	}

	/* Graze */
	else if (p_ptr->cut > 0)
	{
		old_aux = 1;
	}

	/* None */
	else
	{
		old_aux = 0;
	}

	/* Mortal wound */
	if (v > 1000)
	{
		new_aux = 7;
	}

	/* Deep gash */
	else if (v > 200)
	{
		new_aux = 6;
	}

	/* Severe cut */
	else if (v > 100)
	{
		new_aux = 5;
	}

	/* Nasty cut */
	else if (v > 50)
	{
		new_aux = 4;
	}

	/* Bad cut */
	else if (v > 25)
	{
		new_aux = 3;
	}

	/* Light cut */
	else if (v > 10)
	{
		new_aux = 2;
	}

	/* Graze */
	else if (v > 0)
	{
		new_aux = 1;
	}

	/* None */
	else
	{
		new_aux = 0;
	}

	/* Increase cut */
	if (new_aux > old_aux)
	{
		/* Describe the state */
		switch (new_aux)
		{
			/* Graze */
		case 1:
			msg_print("You have been given a graze.");
			break;

			/* Light cut */
		case 2:
			msg_print("You have been given a light cut.");
			break;

			/* Bad cut */
		case 3:
			msg_print("You have been given a bad cut.");
			break;

			/* Nasty cut */
		case 4:
			msg_print("You have been given a nasty cut.");
			break;

			/* Severe cut */
		case 5:
			msg_print("You have been given a severe cut.");
			break;

			/* Deep gash */
		case 6:
			msg_print("You have been given a deep gash.");
			break;

			/* Mortal wound */
		case 7:
			msg_print("You have been given a mortal wound.");
			break;
		}

		/* Notice */
		notice = TRUE;

		if (randint(1000) < v || randint(16) == 1)
		{
			if (!p_ptr->sustain_chr)
			{
				msg_print("You have been horribly scarred.");

				do_dec_stat(A_CHR, STAT_DEC_NORMAL);
			}
		}
	}

	/* Decrease cut */
	else if (new_aux < old_aux)
	{
		/* Describe the state */
		switch (new_aux)
		{
			/* None */
		case 0:
			msg_print("You are no longer bleeding.");
			if (disturb_state) disturb(0, 0);
			break;
		}

		/* Notice */
		notice = TRUE;
	}

	/* Use the value */
	p_ptr->cut = v;

	/* No change */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Redraw the "cut" */
	p_ptr->redraw |= (PR_CUT);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}

void drop_from_wild()
{
	/* Hack -- Not if player were in normal mode in previous turn */
	if (!p_ptr->old_wild_mode) return;

	if (p_ptr->wild_mode && (!dun_level))
	{
		p_ptr->wilderness_x = p_ptr->px;
		p_ptr->wilderness_y = p_ptr->py;
		change_wild_mode();
		p_ptr->energy = 100;
		energy_use = 0;
	}
}

/*
 * Set "p_ptr->food", notice observable changes
 *
 * The "p_ptr->food" variable can get as large as 20000, allowing the
 * addition of the most "filling" item, Elvish Waybread, which adds
 * 7500 food units, without overflowing the 32767 maximum limit.
 *
 * Perhaps we should disturb the player with various messages,
 * especially messages about hunger status changes.  XXX XXX XXX
 *
 * Digestion of food is handled in "dungeon.c", in which, normally,
 * the player digests about 20 food units per 100 game turns, more
 * when "fast", more when "regenerating", less with "slow digestion",
 * but when the player is "gorged", he digests 100 food units per 10
 * game turns, or a full 1000 food units per 100 game turns.
 *
 * Note that the player's speed is reduced by 10 units while gorged,
 * so if the player eats a single food ration (5000 food units) when
 * full (15000 food units), he will be gorged for (5000/100)*10 = 500
 * game turns, or 500/(100/5) = 25 player turns (if nothing else is
 * affecting the player speed).
 */
bool set_food(int v)
{
	int old_aux, new_aux;

	bool notice = FALSE;

	/* Hack -- Force good values */
	v = (v > 20000) ? 20000 : (v < 0) ? 0 : v;

	/* Fainting / Starving */
	if (p_ptr->food < PY_FOOD_FAINT)
	{
		old_aux = 0;
	}

	/* Weak */
	else if (p_ptr->food < PY_FOOD_WEAK)
	{
		old_aux = 1;
	}

	/* Hungry */
	else if (p_ptr->food < PY_FOOD_ALERT)
	{
		old_aux = 2;
	}

	/* Normal */
	else if (p_ptr->food < PY_FOOD_FULL)
	{
		old_aux = 3;
	}

	/* Full */
	else if (p_ptr->food < PY_FOOD_MAX)
	{
		old_aux = 4;
	}

	/* Gorged */
	else
	{
		old_aux = 5;
	}

	/* Fainting / Starving */
	if (v < PY_FOOD_FAINT)
	{
		new_aux = 0;
	}

	/* Weak */
	else if (v < PY_FOOD_WEAK)
	{
		new_aux = 1;
	}

	/* Hungry */
	else if (v < PY_FOOD_ALERT)
	{
		new_aux = 2;
	}

	/* Normal */
	else if (v < PY_FOOD_FULL)
	{
		new_aux = 3;
	}

	/* Full */
	else if (v < PY_FOOD_MAX)
	{
		new_aux = 4;
	}

	/* Gorged */
	else
	{
		new_aux = 5;
	}

	/* Food increase */
	if (new_aux > old_aux)
	{
		/* Describe the state */
		switch (new_aux)
		{
			/* Weak */
		case 1:
			msg_print("You are still weak.");
			break;

			/* Hungry */
		case 2:
			msg_print("You are still hungry.");
			break;

			/* Normal */
		case 3:
			msg_print("You are no longer hungry.");
			break;

			/* Full */
		case 4:
			msg_print("You are full!");
			break;

			/* Bloated */
		case 5:
			msg_print("You have gorged yourself!");
			break;
		}

		/* Change */
		notice = TRUE;
	}

	/* Food decrease */
	else if (new_aux < old_aux)
	{
		/* Describe the state */
		switch (new_aux)
		{
			/* Fainting / Starving */
		case 0:
			msg_print("You are getting faint from hunger!");
			drop_from_wild();
			break;

			/* Weak */
		case 1:
			msg_print("You are getting weak from hunger!");
			drop_from_wild();
			break;

			/* Hungry */
		case 2:
			msg_print("You are getting hungry.");
			break;

			/* Normal */
		case 3:
			msg_print("You are no longer full.");
			break;

			/* Full */
		case 4:
			msg_print("You are no longer gorged.");
			break;
		}

		/* Change */
		notice = TRUE;
	}

	/* Use the value */
	p_ptr->food = v;

	/* Nothing to notice */
	if (!notice) return (FALSE);

	/* Disturb */
	if (disturb_state) disturb(0, 0);

	/* Recalculate bonuses */
	p_ptr->update |= (PU_BONUS);

	/* Redraw hunger */
	p_ptr->redraw |= (PR_HUNGER);

	/* Handle stuff */
	handle_stuff();

	/* Result */
	return (TRUE);
}


/*
 * Advance experience levels and print experience
 */
void check_experience(void)
{
	int i, gained = 0;
	bool level_reward = FALSE;
	bool level_corruption = FALSE;


	/* Note current level */
	i = p_ptr->lev;

	/* Hack -- lower limit */
	if (p_ptr->exp < 0) p_ptr->exp = 0;

	/* Hack -- lower limit */
	if (p_ptr->max_exp < 0) p_ptr->max_exp = 0;

	/* Hack -- upper limit */
	if (p_ptr->exp > PY_MAX_EXP) p_ptr->exp = PY_MAX_EXP;

	/* Hack -- upper limit */
	if (p_ptr->max_exp > PY_MAX_EXP) p_ptr->max_exp = PY_MAX_EXP;

	/* Hack -- maintain "max" experience */
	if (p_ptr->exp > p_ptr->max_exp) p_ptr->max_exp = p_ptr->exp;

	/* Redraw experience */
	p_ptr->redraw |= (PR_EXP);

	/* Handle stuff */
	handle_stuff();


	/* Lose levels while possible */
	while ((p_ptr->lev > 1) &&
	                (p_ptr->exp < (player_exp[p_ptr->lev - 2] * p_ptr->expfact / 100L)))
	{
		/* Lose a level */
		p_ptr->lev--;
		gained--;
		lite_spot(p_ptr->py, p_ptr->px);

		/* Update some stuff */
		p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_SANITY);

		/* Redraw some stuff */
		p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);

		/* Window stuff */
		p_ptr->window |= (PW_PLAYER);

		/* Handle stuff */
		handle_stuff();
	}


	/* Gain levels while possible */
	while ((p_ptr->lev < PY_MAX_LEVEL) && (p_ptr->lev < max_plev) &&
	                (p_ptr->exp >= (player_exp[p_ptr->lev - 1] * p_ptr->expfact / 100L)))
	{
		/* Gain a level */
		p_ptr->lev++;
		gained++;
		lite_spot(p_ptr->py, p_ptr->px);

		/* Save the highest level */
		if (p_ptr->lev > p_ptr->max_plv)
		{
			p_ptr->max_plv = p_ptr->lev;
			if ((PRACE_FLAG(PR1_CORRUPT)) &&
			                (randint(3) == 1))
			{
				level_corruption = TRUE;
			}
		}

		/* Sound */
		sound(SOUND_LEVEL);

		/* Message */
		cmsg_format(TERM_L_GREEN, "Welcome to level %d.", p_ptr->lev);

		if (p_ptr->skill_last_level < p_ptr->lev)
		{
			s32b pts;
			call_lua("exec_module_info", "(s)", "d", "skill_per_level", &pts);

			p_ptr->skill_last_level = p_ptr->lev;
			p_ptr->skill_points += pts;
			cmsg_format(TERM_L_GREEN, "You can increase %d more skills.", p_ptr->skill_points);
			p_ptr->redraw |= PR_STUDY;
		}

		/* Gain this level's abilities */
		apply_level_abilities(p_ptr->lev);

		/* If auto-note taking enabled, write a note to the file.
		 * Only write this note when the level is gained for the first
		 * time.
		 */
		if (take_notes && auto_notes)
		{
			char note[80];

			/* Write note */
			sprintf(note, "Reached level %d", p_ptr->lev);
			add_note(note, 'L');
		}

		/* Update some stuff */
		p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_SANITY);

		/* Redraw some stuff */
		p_ptr->redraw |= (PR_LEV | PR_TITLE | PR_EXP);

		/* Window stuff */
		p_ptr->window |= (PW_PLAYER);

		/* Handle stuff */
		handle_stuff();

		if (level_reward)
		{
			gain_level_reward(0);
			level_reward = FALSE;
		}

		if (level_corruption)
		{
			msg_print("You feel different...");
			corrupt_corrupted();
			level_corruption = FALSE;
		}
	}

	/* Hook it! */
	process_hooks(HOOK_PLAYER_LEVEL, "(d)", gained);
}
/*
 * Advance experience levels and print experience
 */
void check_experience_obj(object_type *o_ptr)
{
	int i;

	/* Note current level */
	i = o_ptr->elevel;

	/* Hack -- lower limit */
	if (o_ptr->exp < 0) o_ptr->exp = 0;

	/* Hack -- upper limit */
	if (o_ptr->exp > PY_MAX_EXP) o_ptr->exp = PY_MAX_EXP;

	/* Gain levels while possible */
	while ((o_ptr->elevel < PY_MAX_LEVEL) &&
	                (o_ptr->exp >= (player_exp[o_ptr->elevel - 1] * 5 / 2)))
	{
		char buf[100];

		/* Add a level */
		o_ptr->elevel++;

		/* Get object name */
		object_desc(buf, o_ptr, 1, 0);
		cmsg_format(TERM_L_BLUE, "%s gains a level!", buf);

		/* What does it gains ? */
		object_gain_level(o_ptr);
	}
}


/*
 * Gain experience (share it to objects if needed)
 */
void gain_exp(s32b amount)
{
	int i, num = 1;

	/* Count the gaining xp objects */
	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
	{
		object_type *o_ptr = &p_ptr->inventory[i];
		u32b f1, f2, f3, f4, f5, esp;

		object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);

		if (!o_ptr->k_idx) continue;

		if (f4 & TR4_ART_EXP) num++;
	}

	/* Now give the xp */
	for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
	{
		object_type *o_ptr = &p_ptr->inventory[i];
		u32b f1, f2, f3, f4, f5, esp;

		object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);

		if (!o_ptr->k_idx) continue;

		if (f4 & TR4_ART_EXP)
		{
			o_ptr->exp += 2 * amount / (num * 3);

			/* Hack -- upper limit */
			if (o_ptr->exp > PY_MAX_EXP) o_ptr->exp = PY_MAX_EXP;
		}
	}

	if ((p_ptr->max_exp > 0) && (PRACE_FLAG(PR1_CORRUPT)))
	{
		if ((randint(p_ptr->max_exp) < amount) || (randint(12000000) < amount))
		{
			msg_print("You feel different...");
			corrupt_corrupted();
		};
		/* 12,000,000 is equal to double Morgoth's raw XP value (60,000 * his Dlev (100))*/
	};

	/* Gain some experience */
	p_ptr->exp += amount / num;

	/* Hook it! */
	process_hooks(HOOK_PLAYER_EXP, "(d)", amount / num);

	/* Slowly recover from experience drainage */
	if (p_ptr->exp < p_ptr->max_exp)
	{
		/* Gain max experience (20%) (was 10%) */
		p_ptr->max_exp += amount / 5;
	}

	/* Check Experience */
	check_experience();
}


/*
 * Lose experience
 */
void lose_exp(s32b amount)
{
	/* Never drop below zero experience */
	if (amount > p_ptr->exp) amount = p_ptr->exp;

	/* Lose some experience */
	p_ptr->exp -= amount;

	/* Hook it! */
	process_hooks(HOOK_PLAYER_EXP, "(d)", amount);

	/* Check Experience */
	check_experience();
}




/*
 * Hack -- Return the "automatic coin type" of a monster race
 * Used to allocate proper treasure when "Creeping coins" die
 *
 * XXX XXX XXX Note the use of actual "monster names"
 */
int get_coin_type(monster_race *r_ptr)
{
	cptr name = (r_name + r_ptr->name);

	/* Analyze "coin" monsters */
	if (r_ptr->d_char == '$')
	{
		/* Look for textual clues */
		if (strstr(name, " copper ")) return (2);
		if (strstr(name, " silver ")) return (5);
		if (strstr(name, " gold ")) return (10);
		if (strstr(name, " mithril ")) return (16);
		if (strstr(name, " adamantite ")) return (17);

		/* Look for textual clues */
		if (strstr(name, "Copper ")) return (2);
		if (strstr(name, "Silver ")) return (5);
		if (strstr(name, "Gold ")) return (10);
		if (strstr(name, "Mithril ")) return (16);
		if (strstr(name, "Adamantite ")) return (17);
	}

	/* Assume nothing */
	return (0);
}

/*
 * This routine handles the production of corpses/skeletons/heads/skulls
 * when a monster is killed.
 */
void place_corpse(monster_type *m_ptr)
{
	monster_race *r_ptr = race_inf(m_ptr);

	object_type *i_ptr;
	object_type object_type_body;

	int x = m_ptr->fx;
	int y = m_ptr->fy;

#if 0 /* If I can find some time to implement the decapitation ... */
	object_type *w_ptr = &p_ptr->inventory[INVEN_WIELD];

	int i = w_ptr->weight + ((p_ptr->to_h + w_ptr->to_h) * 5) + (p_ptr->lev * 3);

	/* Handle decapitations. This is not allowed with hafted weapons. */
	bool crit = (randint(5000) <= i);

	bool decapitate = ((rand_int(m_ptr->maxhp) <= -(m_ptr->hp)) &&
	                   (w_ptr->tval != TV_HAFTED) && crit);
#endif

	/* Get local object */
	i_ptr = &object_type_body;

	/* It has a physical form */
	if (r_ptr->flags9 & RF9_DROP_CORPSE)
	{
		/* Wipe the object */
		object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_CORPSE));

		/* Unique corpses are unique */
		if (r_ptr->flags1 & RF1_UNIQUE)
		{
			object_aware(i_ptr);
			i_ptr->name1 = 201;
		}

		/* Calculate length of time before decay */
		i_ptr->pval = r_ptr->weight + rand_int(r_ptr->weight);

		/* Set weight */
		i_ptr->weight = (r_ptr->weight + rand_int(r_ptr->weight) / 10) + 1;

		/* Remember what we are */
		i_ptr->pval2 = m_ptr->r_idx;

		/* Some hp */
		i_ptr->pval3 = ((maxroll(r_ptr->hdice, r_ptr->hside) + p_ptr->mhp) / 2);
		i_ptr->pval3 -= randint(i_ptr->pval3) / 3;

		i_ptr->found = OBJ_FOUND_MONSTER;
		i_ptr->found_aux1 = m_ptr->r_idx;
		i_ptr->found_aux2 = m_ptr->ego;
		i_ptr->found_aux3 = dungeon_type;
		i_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);

		/* Drop it in the dungeon */
		drop_near(i_ptr, -1, y, x);
	}

	/* The creature is an animated skeleton. */
	if (!(r_ptr->flags9 & RF9_DROP_CORPSE) && (r_ptr->flags9 & RF9_DROP_SKELETON))
	{
		/* Wipe the object */
		object_prep(i_ptr, lookup_kind(TV_CORPSE, SV_CORPSE_SKELETON));

		/* Unique corpses are unique */
		if (r_ptr->flags1 & RF1_UNIQUE)
		{
			object_aware(i_ptr);
			i_ptr->name1 = 201;
		}

		i_ptr->pval = 0;

		/* Set weight */
		i_ptr->weight = (r_ptr->weight / 4 + rand_int(r_ptr->weight) / 40) + 1;

		/* Remember what we are */
		i_ptr->pval2 = m_ptr->r_idx;

		i_ptr->found = OBJ_FOUND_MONSTER;
		i_ptr->found_aux1 = m_ptr->r_idx;
		i_ptr->found_aux2 = m_ptr->ego;
		i_ptr->found_aux3 = dungeon_type;
		i_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);

		/* Drop it in the dungeon */
		drop_near(i_ptr, -1, y, x);
	}

}


/*
 * Handle the "death" of a monster.
 *
 * Disperse treasures centered at the monster location based on the
 * various flags contained in the monster flags fields.
 *
 * Check for "Quest" completion when a quest monster is killed.
 *
 * Note that only the player can induce "monster_death()" on Uniques.
 * Thus (for now) all Quest monsters should be Uniques.
 *
 * Note that monsters can now carry objects, and when a monster dies,
 * it drops all of its objects, which may disappear in crowded rooms.
 */
void monster_death(int m_idx)
{
	int i, y, x, ny, nx;

	int dump_item = 0;
	int dump_gold = 0;

	s16b this_o_idx, next_o_idx = 0;

	monster_type *m_ptr = &m_list[m_idx];

	monster_race *r_ptr = race_inf(m_ptr);

	bool visible = (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE)));


	bool cloned = FALSE;
	bool create_stairs = FALSE;
	int force_coin = get_coin_type(r_ptr);

	object_type forge;
	object_type *q_ptr;

	/* Get the location */
	y = m_ptr->fy;
	x = m_ptr->fx;

	/* Process the appropriate hooks */
	process_hooks(HOOK_MONSTER_DEATH, "(d)", m_idx);

	/* If companion dies, take note */
	if (m_ptr->status == MSTATUS_COMPANION) p_ptr->companion_killed++;

	/* Handle reviving if undead */
	if ((p_ptr->necro_extra & CLASS_UNDEAD) && p_ptr->necro_extra2)
	{
		p_ptr->necro_extra2--;

		if (!p_ptr->necro_extra2)
		{
			msg_print("Your death has been avenged -- you return to life.");
			p_ptr->necro_extra &= ~CLASS_UNDEAD;

			/* Display the hitpoints */
			p_ptr->update |= (PU_HP);
			p_ptr->redraw |= (PR_HP);

			/* Window stuff */
			p_ptr->window |= (PW_PLAYER);
		}
		else
		{
			msg_format("You still have to kill %d monster%s.", p_ptr->necro_extra2, (p_ptr->necro_extra2 == 1) ? "" : "s");
		}
	}

	/* Handle the possibility of player vanquishing arena combatant -KMW- */
	if (p_ptr->inside_arena)
	{
		p_ptr->exit_bldg = TRUE;
		msg_print("Victorious! You're on your way to becoming Champion.");
		p_ptr->arena_number++;
	}

	if (m_ptr->smart &(SM_CLONED)) cloned = TRUE;

	/* If the doppleganger die, the variable must be set accordingly */
	if (r_ptr->flags9 & RF9_DOPPLEGANGER) doppleganger = 0;

	/* Drop objects being carried */
	for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
	{
		object_type * o_ptr;

		/* Acquire object */
		o_ptr = &o_list[this_o_idx];

		/* Acquire next object */
		next_o_idx = o_ptr->next_o_idx;

		/* Paranoia */
		o_ptr->held_m_idx = 0;

		/* Get local object */
		q_ptr = &forge;

		/* Copy the object */
		object_copy(q_ptr, o_ptr);

		/* Delete the object */
		delete_object_idx(this_o_idx);

		if (q_ptr->tval == TV_GOLD) dump_gold++;
		else dump_item++;

		/* Drop it */
		drop_near(q_ptr, -1, y, x);
	}

	/* Forget objects */
	m_ptr->hold_o_idx = 0;

	/* Average dungeon and monster levels */
	object_level = (dun_level + m_ptr->level) / 2;

	/* Mega^2-hack -- destroying the Stormbringer gives it us! */
	if (strstr((r_name + r_ptr->name), "Stormbringer"))
	{
		/* Get local object */
		q_ptr = &forge;

		/* Prepare to make the Stormbringer */
		object_prep(q_ptr, lookup_kind(TV_SWORD, SV_BLADE_OF_CHAOS));

		/* Mega-Hack -- Name the sword  */

		q_ptr->art_name = quark_add("'Stormbringer'");
		q_ptr->to_h = 16;
		q_ptr->to_d = 16;
		q_ptr->ds = 6;
		q_ptr->dd = 6;
		q_ptr->pval = 2;

		q_ptr->art_flags1 |= ( TR1_VAMPIRIC | TR1_STR | TR1_CON | TR1_BLOWS );
		q_ptr->art_flags2 |= ( TR2_FREE_ACT | TR2_HOLD_LIFE |
		                       TR2_RES_NEXUS | TR2_RES_CHAOS | TR2_RES_NETHER |
		                       TR2_RES_CONF );  /* No longer resist_disen */
		q_ptr->art_flags3 |= ( TR3_IGNORE_ACID | TR3_IGNORE_ELEC |
		                       TR3_IGNORE_FIRE | TR3_IGNORE_COLD);
		/* Just to be sure */

		q_ptr->art_flags3 |= TR3_NO_TELE;  /* How's that for a downside? */

		/* For game balance... */
		q_ptr->art_flags3 |= (TR3_CURSED | TR3_HEAVY_CURSE);
		q_ptr->ident |= IDENT_CURSED;

		if (randint(2) == 1)
			q_ptr->art_flags3 |= (TR3_DRAIN_EXP);
		else
			q_ptr->art_flags3 |= (TR3_AGGRAVATE);

		q_ptr->found = OBJ_FOUND_MONSTER;
		q_ptr->found_aux1 = m_ptr->r_idx;
		q_ptr->found_aux2 = m_ptr->ego;
		q_ptr->found_aux3 = dungeon_type;
		q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);

		/* Drop it in the dungeon */
		drop_near(q_ptr, -1, y, x);
	}

	/*
	 * Mega^3-hack: killing a 'Warrior of the Dawn' is likely to
	 * spawn another in the fallen one's place!
	 */
	else if (strstr((r_name + r_ptr->name), "the Dawn"))
	{
		if (!(randint(20) == 13))
		{
			int wy = p_ptr->py, wx = p_ptr->px;
			int attempts = 100;

			do
			{
				scatter(&wy, &wx, p_ptr->py, p_ptr->px, 20, 0);
			}
			while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);

			if (attempts > 0)
			{
				if (is_friend(m_ptr) > 0)
				{
					if (summon_specific_friendly(wy, wx, 100, SUMMON_DAWN, FALSE))
					{
						if (player_can_see_bold(wy, wx))
							msg_print ("A new warrior steps forth!");
					}
				}
				else
				{
					if (summon_specific(wy, wx, 100, SUMMON_DAWN))
					{
						if (player_can_see_bold(wy, wx))
							msg_print ("A new warrior steps forth!");
					}
				}
			}
		}
	}

	/* One more ultra-hack: An Unmaker goes out with a big bang! */
	else if (strstr((r_name + r_ptr->name), "Unmaker"))
	{
		int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
		(void)project(m_idx, 6, y, x, 100, GF_CHAOS, flg);
	}
	/* Pink horrors are replaced with 2 Blue horrors */
	else if (strstr((r_name + r_ptr->name), "ink horror"))
	{
		for (i = 0; i < 2; i++)
		{
			int wy = p_ptr->py, wx = p_ptr->px;
			int attempts = 100;

			do
			{
				scatter(&wy, &wx, p_ptr->py, p_ptr->px, 3, 0);
			}
			while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);

			if (attempts > 0)
			{
				if (summon_specific(wy, wx, 100, SUMMON_BLUE_HORROR))
				{
					if (player_can_see_bold(wy, wx))
						msg_print ("A blue horror appears!");
				}
			}
		}
	}

	/* Mega-Hack -- drop "winner" treasures */
	else if (r_ptr->flags1 & (RF1_DROP_CHOSEN))
	{
		if (strstr((r_name + r_ptr->name), "Morgoth, Lord of Darkness"))
		{
			/* Get local object */
			q_ptr = &forge;

			/* Mega-Hack -- Prepare to make "Grond" */
			object_prep(q_ptr, lookup_kind(TV_HAFTED, SV_GROND));

			/* Mega-Hack -- Mark this item as "Grond" */
			q_ptr->name1 = ART_GROND;

			/* Mega-Hack -- Actually create "Grond" */
			apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);

			/* Drop it in the dungeon */
			drop_near(q_ptr, -1, y, x);

			/* Get local object */
			q_ptr = &forge;

			/* Mega-Hack -- Prepare to make "Morgoth" */
			object_prep(q_ptr, lookup_kind(TV_CROWN, SV_MORGOTH));

			/* Mega-Hack -- Mark this item as "Morgoth" */
			q_ptr->name1 = ART_MORGOTH;

			/* Mega-Hack -- Actually create "Morgoth" */
			apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);

			q_ptr->found = OBJ_FOUND_MONSTER;
			q_ptr->found_aux1 = m_ptr->r_idx;
			q_ptr->found_aux2 = m_ptr->ego;
			q_ptr->found_aux3 = dungeon_type;
			q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);

			/* Drop it in the dungeon */
			drop_near(q_ptr, -1, y, x);
		}
		else if (strstr((r_name + r_ptr->name), "Smeagol"))
		{
			/* Get local object */
			q_ptr = &forge;

			object_wipe(q_ptr);

			/* Mega-Hack -- Prepare to make a ring of invisibility */
			object_prep(q_ptr, lookup_kind(TV_RING, SV_RING_INVIS));
			q_ptr->number = 1;

			apply_magic(q_ptr, -1, TRUE, TRUE, FALSE);

			q_ptr->found = OBJ_FOUND_MONSTER;
			q_ptr->found_aux1 = m_ptr->r_idx;
			q_ptr->found_aux2 = m_ptr->ego;
			q_ptr->found_aux3 = dungeon_type;
			q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);

			/* Drop it in the dungeon */
			drop_near(q_ptr, -1, y, x);
		}
		else if (r_ptr->flags7 & RF7_NAZGUL)
		{
			/* Get local object */
			q_ptr = &forge;

			object_wipe(q_ptr);

			/* Mega-Hack -- Prepare to make a Ring of Power */
			object_prep(q_ptr, lookup_kind(TV_RING, SV_RING_SPECIAL));
			q_ptr->number = 1;

			apply_magic(q_ptr, -1, TRUE, TRUE, FALSE);

			/* Create a random artifact */
			create_artifact(q_ptr, TRUE, FALSE);

			/* Save the inscription */
			q_ptr->art_name = quark_add(format("of %s", r_name + r_ptr->name));

			q_ptr->found = OBJ_FOUND_MONSTER;
			q_ptr->found_aux1 = m_ptr->r_idx;
			q_ptr->found_aux2 = m_ptr->ego;
			q_ptr->found_aux3 = dungeon_type;
			q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);

			/* Drop it in the dungeon */
			drop_near(q_ptr, -1, y, x);
		}
		else
		{
			byte a_idx = 0;
			int chance = 0;
			int I_kind = 0;

			if (strstr((r_name + r_ptr->name), "Marda, rider of the Gold Laronth"))
			{
				a_idx = ART_MARDA;
				chance = 50;
			}
			else if (strstr((r_name + r_ptr->name), "Saruman of Many Colours"))
			{
				a_idx = ART_PALANTIR;
				chance = 30;
			}
			else if (strstr((r_name + r_ptr->name), "Hagen, son of Alberich"))
			{
				a_idx = ART_NIMLOTH;
				chance = 66;
			}
			else if (strstr((r_name + r_ptr->name), "Durin's Bane"))
			{
				a_idx = ART_CALRIS;
				chance = 60;
			}
			else if (strstr((r_name + r_ptr->name), "Gothmog, the High Captain of Balrogs"))
			{
				a_idx = ART_GOTHMOG;
				chance = 50;
			}
			else if (strstr((r_name + r_ptr->name), "Eol, the Dark Elf"))
			{
				a_idx = ART_ANGUIREL;
				chance = 50;
			}

			if ((a_idx > 0) && ((randint(99) < chance) || (wizard)))
			{
				if (a_info[a_idx].cur_num == 0)
				{
					artifact_type *a_ptr = &a_info[a_idx];

					/* Get local object */
					q_ptr = &forge;

					/* Wipe the object */
					object_wipe(q_ptr);

					/* Acquire the "kind" index */
					I_kind = lookup_kind(a_ptr->tval, a_ptr->sval);

					/* Create the artifact */
					object_prep(q_ptr, I_kind);

					/* Save the name */
					q_ptr->name1 = a_idx;

					/* Extract the fields */
					q_ptr->pval = a_ptr->pval;
					q_ptr->ac = a_ptr->ac;
					q_ptr->dd = a_ptr->dd;
					q_ptr->ds = a_ptr->ds;
					q_ptr->to_a = a_ptr->to_a;
					q_ptr->to_h = a_ptr->to_h;
					q_ptr->to_d = a_ptr->to_d;
					q_ptr->weight = a_ptr->weight;

					/* Hack -- acquire "cursed" flag */
					if (a_ptr->flags3 & (TR3_CURSED)) q_ptr->ident |= (IDENT_CURSED);

					random_artifact_resistance(q_ptr);

					a_info[a_idx].cur_num = 1;

					q_ptr->found = OBJ_FOUND_MONSTER;
					q_ptr->found_aux1 = m_ptr->r_idx;
					q_ptr->found_aux2 = m_ptr->ego;
					q_ptr->found_aux3 = dungeon_type;
					q_ptr->found_aux4 = level_or_feat(dungeon_type, dun_level);

					/* Drop the artifact from heaven */
					drop_near(q_ptr, -1, y, x);
				}
			}
		}
	}

	/* Hack - the protected monsters must be advanged */
	else if (r_ptr->flags9 & RF9_WYRM_PROTECT)
	{
		int xx = x, yy = y;
		int attempts = 100;

		cmsg_print(TERM_VIOLET, "This monster was under the protection of a Great Wyrm of Power!");

		do
		{
			scatter(&yy, &xx, y, x, 6, 0);
		}
		while (!(in_bounds(yy, xx) && cave_floor_bold(yy, xx)) && --attempts);

		place_monster_aux(yy, xx, test_monster_name("Great Wyrm of Power"), FALSE, FALSE, m_ptr->status);
	}

	/* Let monsters explode! */
	for (i = 0; i < 4; i++)
	{
		if (m_ptr->blow[i].method == RBM_EXPLODE)
		{
			int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
			int typ = GF_MISSILE;
			int d_dice = m_ptr->blow[i].d_dice;
			int d_side = m_ptr->blow[i].d_side;
			int damage = damroll(d_dice, d_side);

			switch (m_ptr->blow[i].effect)
			{
			case RBE_HURT:
				typ = GF_MISSILE;
				break;
			case RBE_POISON:
				typ = GF_POIS;
				break;
			case RBE_UN_BONUS:
				typ = GF_DISENCHANT;
				break;
			case RBE_UN_POWER:
				typ = GF_MISSILE;
				break;  /* ToDo: Apply the correct effects */
			case RBE_EAT_GOLD:
				typ = GF_MISSILE;
				break;
			case RBE_EAT_ITEM:
				typ = GF_MISSILE;
				break;
			case RBE_EAT_FOOD:
				typ = GF_MISSILE;
				break;
			case RBE_EAT_LITE:
				typ = GF_MISSILE;
				break;
			case RBE_ACID:
				typ = GF_ACID;
				break;
			case RBE_ELEC:
				typ = GF_ELEC;
				break;
			case RBE_FIRE:
				typ = GF_FIRE;
				break;
			case RBE_COLD:
				typ = GF_COLD;
				break;
			case RBE_BLIND:
				typ = GF_MISSILE;
				break;
			case RBE_HALLU:
				typ = GF_CONFUSION;
				break;
			case RBE_CONFUSE:
				typ = GF_CONFUSION;
				break;
			case RBE_TERRIFY:
				typ = GF_MISSILE;
				break;
			case RBE_PARALYZE:
				typ = GF_MISSILE;
				break;
			case RBE_LOSE_STR:
				typ = GF_MISSILE;
				break;
			case RBE_LOSE_DEX:
				typ = GF_MISSILE;
				break;
			case RBE_LOSE_CON:
				typ = GF_MISSILE;
				break;
			case RBE_LOSE_INT:
				typ = GF_MISSILE;
				break;
			case RBE_LOSE_WIS:
				typ = GF_MISSILE;
				break;
			case RBE_LOSE_CHR:
				typ = GF_MISSILE;
				break;
			case RBE_LOSE_ALL:
				typ = GF_MISSILE;
				break;
			case RBE_PARASITE:
				typ = GF_MISSILE;
				break;
			case RBE_SHATTER:
				typ = GF_ROCKET;
				break;
			case RBE_EXP_10:
				typ = GF_MISSILE;
				break;
			case RBE_EXP_20:
				typ = GF_MISSILE;
				break;
			case RBE_EXP_40:
				typ = GF_MISSILE;
				break;
			case RBE_EXP_80:
				typ = GF_MISSILE;
				break;
			case RBE_DISEASE:
				typ = GF_POIS;
				break;
			case RBE_TIME:
				typ = GF_TIME;
				break;
			case RBE_SANITY:
				typ = GF_MISSILE;
				break;
			}

			project(m_idx, 3, y, x, damage, typ, flg);
			break;
		}
	}

	if ((!force_coin) && (magik(10 + get_skill_scale(SKILL_PRESERVATION, 75))) && (!(m_ptr->mflag & MFLAG_NO_DROP)))
		place_corpse(m_ptr);

	/* Take note of any dropped treasure */
	if (visible && (dump_item || dump_gold))
	{
		/* Take notes on treasure */
		lore_treasure(m_idx, dump_item, dump_gold);
	}

	/* Current quest */
	i = p_ptr->inside_quest;

	/* Create a magical staircase */
	if (create_stairs && (dun_level < d_info[dungeon_type].maxdepth))
	{
		int i, j;

		for (i = -1; i <= 1; i++)
			for (j = -1; j <= 1; j++)
				if (!(f_info[cave[y + j][x + i].feat].flags1 & FF1_PERMANENT)) cave_set_feat(y + j, x + i, d_info[dungeon_type].floor1);

		/* Stagger around */
		while (!cave_valid_bold(y, x))
		{
			int d = 1;

			/* Pick a location */
			scatter(&ny, &nx, y, x, d, 0);

			/* Stagger */
			y = ny;
			x = nx;
		}

		/* Destroy any objects */
		delete_object(y, x);

		/* Explain the staircase */
		msg_print("A magical staircase appears...");

		/* Create stairs down */
		cave_set_feat(y, x, FEAT_MORE);

		/* Remember to update everything */
		p_ptr->update |= (PU_VIEW | PU_FLOW | PU_MONSTERS);
	}
}




/*
 * Decreases monsters hit points, handling monster death.
 *
 * We return TRUE if the monster has been killed (and deleted).
 *
 * We announce monster death (using an optional "death message"
 * if given, and a otherwise a generic killed/destroyed message).
 *
 * Only "physical attacks" can induce the "You have slain" message.
 * Missile and Spell attacks will induce the "dies" message, or
 * various "specialized" messages.  Note that "You have destroyed"
 * and "is destroyed" are synonyms for "You have slain" and "dies".
 *
 * Hack -- unseen monsters yield "You have killed it." message.
 *
 * Added fear (DGK) and check whether to print fear messages -CWS
 *
 * Genericized name, sex, and capitilization -BEN-
 *
 * Hack -- we "delay" fear messages by passing around a "fear" flag.
 *
 * XXX XXX XXX Consider decreasing monster experience over time, say,
 * by using "(m_exp * m_lev * (m_lev)) / (p_lev * (m_lev + n_killed))"
 * instead of simply "(m_exp * m_lev) / (p_lev)", to make the first
 * monster worth more than subsequent monsters.  This would also need
 * to induce changes in the monster recall code.
 */
bool mon_take_hit(int m_idx, int dam, bool *fear, cptr note)
{
	monster_type *m_ptr = &m_list[m_idx];
	monster_race *r_ptr = race_inf(m_ptr);
	s32b div, new_exp, new_exp_frac;


	/* Redraw (later) if needed */
	if (health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);

	/* Some mosnters are immune to death */
	if (r_ptr->flags7 & RF7_NO_DEATH) return FALSE;

	/* Wake it up */
	m_ptr->csleep = 0;

	/* Hurt it */
	m_ptr->hp -= dam;

	/* It is dead now */
	if (m_ptr->hp < 0)
	{
		char m_name[80];

		/* Lets face it, you cannot get rid of a possessor that easily */
		if (m_ptr->possessor)
		{
			ai_deincarnate(m_idx);

			return FALSE;
		}

		/* Extract monster name */
		monster_desc(m_name, m_ptr, 0);

		if ((r_ptr->flags7 & RF7_DG_CURSE) && (randint(2) == 1))
		{
			int curses = 2 + randint(5);

			cmsg_format(TERM_VIOLET, "%^s puts a terrible Morgothian curse on you!", m_name);
			curse_equipment_dg(100, 50);

			do
			{
				activate_dg_curse();
			}
			while (--curses);
		}

		if (speak_unique && (r_ptr->flags2 & (RF2_CAN_SPEAK)))
		{
			char line_got[80];
			/* Dump a message */

			get_rnd_line("mondeath.txt", line_got);
			msg_format("%^s says: %s", m_name, line_got);
		}


		/* Make a sound */
		sound(SOUND_KILL);

		/* Death by Missile/Spell attack */
		if (note)
		{
			cmsg_format(TERM_L_RED, "%^s%s", m_name, note);
		}

		/* Death by physical attack -- invisible monster */
		else if (!m_ptr->ml)
		{
			cmsg_format(TERM_L_RED, "You have killed %s.", m_name);
		}

		/* Death by Physical attack -- non-living monster */
		else if ((r_ptr->flags3 & (RF3_DEMON)) ||
		                (r_ptr->flags3 & (RF3_UNDEAD)) ||
		                (r_ptr->flags2 & (RF2_STUPID)) ||
		                (r_ptr->flags3 & (RF3_NONLIVING)) ||
		                (strchr("Evg", r_ptr->d_char)))
		{
			cmsg_format(TERM_L_RED, "You have destroyed %s.", m_name);
		}

		/* Death by Physical attack -- living monster */
		else
		{
			cmsg_format(TERM_L_RED, "You have slain %s.", m_name);
		}

		/* Maximum player level */
		div = p_ptr->max_plv;

		if (m_ptr->status < MSTATUS_FRIEND)
		{
			/* Give some experience for the kill */
			new_exp = ((long)r_ptr->mexp * m_ptr->level) / div;

			/* Handle fractional experience */
			new_exp_frac = ((((long)r_ptr->mexp * m_ptr->level) % div)
			                * 0x10000L / div) + p_ptr->exp_frac;

			/* Keep track of experience */
			if (new_exp_frac >= 0x10000L)
			{
				new_exp++;
				p_ptr->exp_frac = new_exp_frac - 0x10000L;
			}
			else
			{
				p_ptr->exp_frac = new_exp_frac;
			}

			/* Gain experience */
			gain_exp(new_exp);
		}

		if (!note)
		{
			object_type *o_ptr;
			object_kind *k_ptr;
			u32b f1, f2, f3, f4, f5, esp;

			/* Access the weapon */
			o_ptr = &p_ptr->inventory[INVEN_WIELD];
			k_ptr = &k_info[o_ptr->k_idx];
			object_flags(o_ptr, &f1, &f2, &f3, &f4, &f5, &esp);

			/* Can the weapon gain levels ? */
			if ((o_ptr->k_idx) && (f4 & TR4_LEVELS))
			{
				/* Give some experience for the kill */
				new_exp = ((long)r_ptr->mexp * m_ptr->level) / (div * 2);

				/* Gain experience */
				o_ptr->exp += new_exp;
				check_experience_obj(o_ptr);
			}
		}

		/* When the player kills a Unique, it stays dead */
		if (r_ptr->flags1 & (RF1_UNIQUE))
		{
			r_ptr->max_num = 0;
		}

		/* Generate treasure */
		monster_death(m_idx);

		/* Eru doesn't appreciate good monster death */
		if (r_ptr->flags3 & RF3_GOOD)
		{
			inc_piety(GOD_ERU, -7 * m_ptr->level);
			inc_piety(GOD_MANWE, -10 * m_ptr->level);
			inc_piety(GOD_MELKOR, 3 * m_ptr->level);
		}
		else
		{
			inc_piety(GOD_MELKOR, 1 + m_ptr->level / 2);
		}

		/* Manwe appreciate evil monster death */
		if (r_ptr->flags3 & RF3_EVIL)
		{
			int inc = m_ptr->level / 2;

			if (!inc) inc = 1;
			PRAY_GOD(GOD_MANWE) inc_piety(GOD_MANWE, inc);

			if (inc < 2) inc = 2;
			inc_piety(GOD_TULKAS, inc / 2);
			PRAY_GOD(GOD_TULKAS)
			{
				inc_piety(GOD_TULKAS, inc / 2);
				if (r_ptr->flags3 & RF3_DEMON) inc_piety(GOD_TULKAS, inc);
			}
		}

		/* Yavanna likes when corruption is destroyed */
		if ((r_ptr->flags3 & RF3_NONLIVING) || (r_ptr->flags3 & RF3_DEMON) || (r_ptr->flags3 & RF3_UNDEAD))
		{
			int inc = m_ptr->level / 2;

			if (!inc) inc = 1;
			inc_piety(GOD_YAVANNA, inc);
		}

		/* Yavanna doesnt like any killing in her name */
		PRAY_GOD(GOD_YAVANNA)
		{
			int inc = m_ptr->level / 2;

			if (!inc) inc = 1;
			inc_piety(GOD_YAVANNA, -inc);

			/* Killing animals in her name is a VERY bad idea */
			if (r_ptr->flags3 & RF3_ANIMAL)
				inc_piety(GOD_YAVANNA, -(inc * 3));
		}

		/* SHould we absorb its soul? */
		if (p_ptr->absorb_soul && (!(r_ptr->flags3 & RF3_UNDEAD)) && (!(r_ptr->flags3 & RF3_NONLIVING)))
		{
			msg_print("You absorb the life of the dying soul.");
			hp_player(1 + (m_ptr->level / 2) + get_skill_scale(SKILL_NECROMANCY, 40));
		}

		/*
		* XXX XXX XXX Mega-Hack -- Remove random quest rendered
		* impossible
		*/
		if (r_ptr->flags1 & (RF1_UNIQUE))
		{
			int i;

			/* Search for all the random quests */
			for (i = 0; i < MAX_RANDOM_QUEST; i++)
			{
				random_quest *q_ptr = &random_quests[i];

				/* Ignore invalid entries */
				if (q_ptr->type == 0) continue;

				/* It's done */
				if (q_ptr->done) continue;

				/*
				 * XXX XXX XXX Not yet completed quest is
				 * to kill a unique you've just killed
				 */
				if (r_ptr == &r_info[q_ptr->r_idx])
				{
					/* Invalidate it */
					q_ptr->type = 0;
				}
			}
		}

#if 0 /* DGDGDG -- pfft */
		/* XXX XXX Mega-Hack -- allow another ghost later
		 * Remove the slain bone file */
		if (m_ptr->r_idx == max_r_idx - 1)
		{
			r_ptr->max_num = 1;

			/* Delete the bones file */
			sprintf(tmp, "%s%sbone%03d.%03d", ANGBAND_DIR_BONE, PATH_SEP, dungeon_type, dun_level);

			/* Grab permission */
			safe_setuid_grab();

			/* Remove the bone file */
			fd_kill(tmp);

			/* Drop permission */
			safe_setuid_drop();
		}
#endif
		/* If the player kills a Unique, and the notes options are on, write a note */
		if ((r_ptr->flags1 & RF1_UNIQUE) && take_notes && auto_notes)
		{
			char note[80];

			/* Get true name even if blinded/hallucinating */
			cptr monst = (r_name + r_ptr->name);

			/* Write note */
			sprintf(note, "Killed %s", monst);

			add_note(note, 'U');
		}

		/* Recall even invisible uniques or winners */
		if (m_ptr->ml || (r_ptr->flags1 & (RF1_UNIQUE)))
		{
			/* Count kills this life */
			if (r_ptr->r_pkills < MAX_SHORT) r_ptr->r_pkills++;

			/* Count kills in all lives */
			if (r_ptr->r_tkills < MAX_SHORT) r_ptr->r_tkills++;

			/* Hack -- Auto-recall */
			monster_race_track(m_ptr->r_idx, m_ptr->ego);
		}

		/* Delete the monster */
		delete_monster_idx(m_idx);

		/* Not afraid */
		(*fear) = FALSE;

		/* Monster is dead */
		return (TRUE);
	}


#ifdef ALLOW_FEAR

	/* Mega-Hack -- Pain cancels fear */
	if (m_ptr->monfear && (dam > 0))
	{
		int tmp = randint(dam);

		/* Cure a little fear */
		if (tmp < m_ptr->monfear)
		{
			/* Reduce fear */
			m_ptr->monfear -= tmp;
		}

		/* Cure all the fear */
		else
		{
			/* Cure fear */
			m_ptr->monfear = 0;

			/* No more fear */
			(*fear) = FALSE;
		}
	}

	/* Sometimes a monster gets scared by damage */
	if (!m_ptr->monfear && !(r_ptr->flags3 & (RF3_NO_FEAR)))
	{
		int percentage;

		/* Percentage of fully healthy */
		percentage = (100L * m_ptr->hp) / m_ptr->maxhp;

		/*
		 * Run (sometimes) if at 10% or less of max hit points,
		 * or (usually) when hit for half its current hit points
		 */
		if (((percentage <= 10) && (rand_int(10) < percentage)) ||
		                ((dam >= m_ptr->hp) && (rand_int(100) < 80)))
		{
			/* Hack -- note fear */
			(*fear) = TRUE;

			/* XXX XXX XXX Hack -- Add some timed fear */
			m_ptr->monfear = (randint(10) +
			                  (((dam >= m_ptr->hp) && (percentage > 7)) ?
			                   20 : ((11 - percentage) * 5)));
		}
	}

#endif


	/* Not dead yet */
	return (FALSE);
}


/*
 * Get term size and calculate screen size
 */
void get_screen_size(int *wid_p, int *hgt_p)
{
	Term_get_size(wid_p, hgt_p);
	*hgt_p -= ROW_MAP + 1;
	*wid_p -= COL_MAP + 1;
	if (use_bigtile) *wid_p /= 2;
}

/*
 * Calculates current boundaries
 * Called below.
 */
static void panel_bounds(void)
{
	int wid, hgt;

	/* Retrieve current screen size */
	get_screen_size(&wid, &hgt);

	/* + 24 - 1 - 2 =  + 21 */
	panel_row_max = panel_row_min + hgt - 1;
	panel_row_prt = panel_row_min - ROW_MAP;

	/* Paranoia -- Boundary check */
	if (panel_row_max > cur_hgt - 1) panel_row_max = cur_hgt - 1;

	panel_col_max = panel_col_min + wid - 1;
	panel_col_prt = panel_col_min - COL_MAP;

	/* Paranoia -- Boundary check */
	if (panel_col_max > cur_wid - 1) panel_col_max = cur_wid - 1;
}


/*
 * Handle a request to change the current panel
 *
 * Return TRUE if the panel was changed.
 *
 * Also used in do_cmd_locate()
 */
bool change_panel(int dy, int dx)
{
	int y, x;
	int wid, hgt;

	/* Get size */
	get_screen_size(&wid, &hgt);

	/* Apply the motion */
	y = panel_row_min + dy * (hgt / 2);
	x = panel_col_min + dx * (wid / 2);

	/* Calculate bounds */
	if (y > cur_hgt - hgt) y = cur_hgt - hgt;
	if (y < 0) y = 0;
	if (x > cur_wid - wid) x = cur_wid - wid;
	if (x < 0) x = 0;

	/* Handle changes */
	if ((y != panel_row_min) || (x != panel_col_min))
	{
		/* Save the new panel info */
		panel_row_min = y;
		panel_col_min = x;

		/* Recalculate the boundaries */
		panel_bounds();

		/* Update stuff */
		p_ptr->update |= (PU_MONSTERS);

		/* Redraw map */
		p_ptr->redraw |= (PR_MAP);

		/* Handle stuff */
		handle_stuff();

		/* Success */
		return (TRUE);
	}

	/* No changes */
	return (FALSE);
}


/*
 * Given an row (y) and col (x), this routine detects when a move
 * off the screen has occurred and figures new borders. -RAK-
 *
 * "Update" forces a "full update" to take place.
 *
 * The map is reprinted if necessary, and "TRUE" is returned.
 */
void verify_panel(void)
{
	int y = p_ptr->py;
	int x = p_ptr->px;

	int wid, hgt;

	int prow_min;
	int pcol_min;

	int panel_hgt, panel_wid;

	int max_prow_min;
	int max_pcol_min;


	/*
	 * Make sure panel_row/col_max have correct values -- now taken care of
	 * by the hook function below, which eliminates glitches, but does it
	 * in a very hackish way XXX XXX XXX
	 */
	/* panel_bounds(); */

	/* Get size */
	get_screen_size(&wid, &hgt);

	/* Calculate scroll amount */
	panel_hgt = hgt / 2;
	panel_wid = wid / 2;

	/* Upper boundary of panel_row/col_min */
	max_prow_min = cur_hgt - hgt;
	max_pcol_min = cur_wid - wid;

	/* Boundary check */
	if (max_prow_min < 0) max_prow_min = 0;
	if (max_pcol_min < 0) max_pcol_min = 0;

	/* An option: center on player */
	if (center_player)
	{
		/* Center vertically */
		prow_min = y - panel_hgt;

		/* Boundary check */
		if (prow_min < 0) prow_min = 0;
		else if (prow_min > max_prow_min) prow_min = max_prow_min;

		/* Center horizontally */
		pcol_min = x - panel_wid;

		/* Boundary check */
		if (pcol_min < 0) pcol_min = 0;
		else if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
	}

	/* No centering */
	else
	{
		prow_min = panel_row_min;
		pcol_min = panel_col_min;

		/* Scroll screen when 2 grids from top/bottom edge */
		if (y > panel_row_max - 2)
		{
			while (y > prow_min + hgt - 2)
			{
				prow_min += panel_hgt;
			}

			if (prow_min > max_prow_min) prow_min = max_prow_min;
		}

		if (y < panel_row_min + 2)
		{
			while (y < prow_min + 2)
			{
				prow_min -= panel_hgt;
			}

			if (prow_min < 0) prow_min = 0;
		}

		/* Scroll screen when 4 grids from left/right edge */
		if (x > panel_col_max - 4)
		{
			while (x > pcol_min + wid - 4)
			{
				pcol_min += panel_wid;
			}

			if (pcol_min > max_pcol_min) pcol_min = max_pcol_min;
		}

		if (x < panel_col_min + 4)
		{
			while (x < pcol_min + 4)
			{
				pcol_min -= panel_wid;
			}

			if (pcol_min < 0) pcol_min = 0;
		}
	}

	/* Check for "no change" */
	if ((prow_min == panel_row_min) && (pcol_min == panel_col_min)) return;

	/* Save the new panel info */
	panel_row_min = prow_min;
	panel_col_min = pcol_min;

	/* Hack -- optional disturb on "panel change" */
	if (disturb_panel && !center_player) disturb(0, 0);

	/* Recalculate the boundaries */
	panel_bounds();

	/* Hack - merchants detect items */
#if 0 /* DGDGDGDG -- use a skill */
	if (cp_ptr->magic_key == MKEY_TELEKINESIS)
	{
		hack_no_detect_message = TRUE;
		detect_objects_normal(DEFAULT_RADIUS);
		detect_objects_gold(DEFAULT_RADIUS);
		hack_no_detect_message = FALSE;
	}
#endif
	/* Update stuff */
	p_ptr->update |= (PU_MONSTERS);

	/* Redraw map */
	p_ptr->redraw |= (PR_MAP);

	/* Window stuff */
	p_ptr->window |= (PW_OVERHEAD);
}


/*
 * Map resizing whenever the main term changes size
 */
void resize_map(void)
{
	/* Only if the dungeon exists */
	if (!character_dungeon) return;

	/* Mega-Hack -- No panel yet, assume illegal panel */
	panel_row_min = cur_hgt;
	panel_row_max = 0;
	panel_col_min = cur_wid;
	panel_col_max = 0;

	/* Select player panel */
	verify_panel();

	/*
	 * The following should be the same as the main window code
	 * in the do_cmd_redraw()
	 */

	/* Combine and reorder the pack (later) */
	p_ptr->notice |= (PN_COMBINE | PN_REORDER);

	/* Update torch */
	p_ptr->update |= (PU_TORCH);

	/* Update stuff */
	p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS | PU_POWERS |
	                  PU_SANITY | PU_BODY);

	/* Forget and update view */
	p_ptr->update |= (PU_UN_VIEW | PU_VIEW | PU_MONSTERS | PU_MON_LITE);

	/* Redraw everything */
	p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP);

	/* Hack -- update */
	handle_stuff();

	/* Redraw */
	Term_redraw();

	/* Refresh */
	Term_fresh();
}


/*
 * Redraw a term when it is resized
 */
void resize_window(void)
{
	/* Only if the dungeon exists */
	if (!character_dungeon) return;

	/* Hack -- Activate the Angband window for the redraw */
	Term_activate(&term_screen[0]);

	/* Hack -- react to changes */
	Term_xtra(TERM_XTRA_REACT, 0);

	/* Window stuff */
	p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);

	/* Window stuff */
	p_ptr->window |= (PW_M_LIST | PW_IRC | PW_MESSAGE | PW_OVERHEAD |
	                  PW_MONSTER | PW_OBJECT);


	/* Hack -- update */
	handle_stuff();

	/* Refresh */
	Term_fresh();
}




/*
 * Monster health description
 */
cptr look_mon_desc(int m_idx)
{
	monster_type *m_ptr = &m_list[m_idx];
	monster_race *r_ptr = race_inf(m_ptr);

	bool living = TRUE;
	int perc;


	/* Determine if the monster is "living" (vs "undead") */
	if (r_ptr->flags3 & (RF3_UNDEAD)) living = FALSE;
	if (r_ptr->flags3 & (RF3_DEMON)) living = FALSE;
	if (r_ptr->flags3 & (RF3_NONLIVING)) living = FALSE;
	if (strchr("Egv", r_ptr->d_char)) living = FALSE;


	/* Healthy monsters */
	if (m_ptr->hp >= m_ptr->maxhp)
	{
		/* No damage */
		return (living ? "unhurt" : "undamaged");
	}


	/* Calculate a health "percentage" */
	perc = 100L * m_ptr->hp / m_ptr->maxhp;

	if (perc >= 60)
	{
		return (living ? "somewhat wounded" : "somewhat damaged");
	}

	if (perc >= 25)
	{
		return (living ? "wounded" : "damaged");
	}

	if (perc >= 10)
	{
		return (living ? "badly wounded" : "badly damaged");
	}

	return (living ? "almost dead" : "almost destroyed");
}



/*
 * Angband sorting algorithm -- quick sort in place
 *
 * Note that the details of the data we are sorting is hidden,
 * and we rely on the "ang_sort_comp()" and "ang_sort_swap()"
 * function hooks to interact with the data, which is given as
 * two pointers, and which may have any user-defined form.
 */
void ang_sort_aux(vptr u, vptr v, int p, int q)
{
	int z, a, b;

	/* Done sort */
	if (p >= q) return;

	/* Pivot */
	z = p;

	/* Begin */
	a = p;
	b = q;

	/* Partition */
	while (TRUE)
	{
		/* Slide i2 */
		while (!(*ang_sort_comp)(u, v, b, z)) b--;

		/* Slide i1 */
		while (!(*ang_sort_comp)(u, v, z, a)) a++;

		/* Done partition */
		if (a >= b) break;

		/* Swap */
		(*ang_sort_swap)(u, v, a, b);

		/* Advance */
		a++, b--;
	}

	/* Recurse left side */
	ang_sort_aux(u, v, p, b);

	/* Recurse right side */
	ang_sort_aux(u, v, b + 1, q);
}


/*
 * Angband sorting algorithm -- quick sort in place
 *
 * Note that the details of the data we are sorting is hidden,
 * and we rely on the "ang_sort_comp()" and "ang_sort_swap()"
 * function hooks to interact with the data, which is given as
 * two pointers, and which may have any user-defined form.
 */
void ang_sort(vptr u, vptr v, int n)
{
	/* Sort the array */
	ang_sort_aux(u, v, 0, n - 1);
}



/*** Targetting Code ***/


/*
 * Determine is a monster makes a reasonable target
 *
 * The concept of "targetting" was stolen from "Morgul" (?)
 *
 * The player can target any location, or any "target-able" monster.
 *
 * Currently, a monster is "target_able" if it is visible, and if
 * the player can hit it with a projection, and the player is not
 * hallucinating.  This allows use of "use closest target" macros.
 *
 * Future versions may restrict the ability to target "trappers"
 * and "mimics", but the semantics is a little bit weird.
 */
bool target_able(int m_idx)
{
	monster_type *m_ptr = &m_list[m_idx];

	/* Monster must be alive */
	if (!m_ptr->r_idx) return (FALSE);

	/* Monster must be visible */
	if (!m_ptr->ml) return (FALSE);

	/* Monster must be projectable */
	if (!projectable(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx)) return (FALSE);

	/* Hack -- no targeting hallucinations */
	if (p_ptr->image) return (FALSE);

	/* Dont target pets */
	if (is_friend(m_ptr) > 0) return (FALSE);

	/* Honor flag */
	if (r_info[m_ptr->r_idx].flags7 & RF7_NO_TARGET) return (FALSE);

	/* XXX XXX XXX Hack -- Never target trappers */
	/* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */

	/* Assume okay */
	return (TRUE);
}




/*
 * Update (if necessary) and verify (if possible) the target.
 *
 * We return TRUE if the target is "okay" and FALSE otherwise.
 */
bool target_okay(void)
{
	/* Accept stationary targets */
	if (target_who < 0) return (TRUE);

	/* Check moving targets */
	if (target_who > 0)
	{
		/* Accept reasonable targets */
		if (target_able(target_who))
		{
			monster_type *m_ptr = &m_list[target_who];

			/* Acquire monster location */
			target_row = m_ptr->fy;
			target_col = m_ptr->fx;

			/* Good target */
			return (TRUE);
		}
	}

	/* Assume no target */
	return (FALSE);
}



/*
 * Sorting hook -- comp function -- by "distance to player"
 *
 * We use "u" and "v" to point to arrays of "x" and "y" positions,
 * and sort the arrays by double-distance to the player.
 */
static bool ang_sort_comp_distance(vptr u, vptr v, int a, int b)
{
	byte *x = (byte*)(u);
	byte *y = (byte*)(v);

	int da, db, kx, ky;

	/* Absolute distance components */
	kx = x[a];
	kx -= p_ptr->px;
	kx = ABS(kx);
	ky = y[a];
	ky -= p_ptr->py;
	ky = ABS(ky);

	/* Approximate Double Distance to the first point */
	da = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));

	/* Absolute distance components */
	kx = x[b];
	kx -= p_ptr->px;
	kx = ABS(kx);
	ky = y[b];
	ky -= p_ptr->py;
	ky = ABS(ky);

	/* Approximate Double Distance to the first point */
	db = ((kx > ky) ? (kx + kx + ky) : (ky + ky + kx));

	/* Compare the distances */
	return (da <= db);
}


/*
 * Sorting hook -- swap function -- by "distance to player"
 *
 * We use "u" and "v" to point to arrays of "x" and "y" positions,
 * and sort the arrays by distance to the player.
 */
static void ang_sort_swap_distance(vptr u, vptr v, int a, int b)
{
	byte *x = (byte*)(u);
	byte *y = (byte*)(v);

	byte temp;

	/* Swap "x" */
	temp = x[a];
	x[a] = x[b];
	x[b] = temp;

	/* Swap "y" */
	temp = y[a];
	y[a] = y[b];
	y[b] = temp;
}



/*
 * Hack -- help "select" a location (see below)
 */
static s16b target_pick(int y1, int x1, int dy, int dx)
{
	int i, v;

	int x2, y2, x3, y3, x4, y4;

	int b_i = -1, b_v = 9999;


	/* Scan the locations */
	for (i = 0; i < temp_n; i++)
	{
		/* Point 2 */
		x2 = temp_x[i];
		y2 = temp_y[i];

		/* Directed distance */
		x3 = (x2 - x1);
		y3 = (y2 - y1);

		/* Verify quadrant */
		if (dx && (x3 * dx <= 0)) continue;
		if (dy && (y3 * dy <= 0)) continue;

		/* Absolute distance */
		x4 = ABS(x3);
		y4 = ABS(y3);

		/* Verify quadrant */
		if (dy && !dx && (x4 > y4)) continue;
		if (dx && !dy && (y4 > x4)) continue;

		/* Approximate Double Distance */
		v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4));

		/* XXX XXX XXX Penalize location */

		/* Track best */
		if ((b_i >= 0) && (v >= b_v)) continue;

		/* Track best */
		b_i = i;
		b_v = v;
	}

	/* Result */
	return (b_i);
}


/*
 * Hack -- determine if a given location is "interesting"
 */
static bool target_set_accept(int y, int x)
{
	cave_type *c_ptr;

	s16b this_o_idx, next_o_idx = 0;


	/* Player grid is always interesting */
	if ((y == p_ptr->py) && (x == p_ptr->px)) return (TRUE);


	/* Handle hallucination */
	if (p_ptr->image) return (FALSE);


	/* Examine the grid */
	c_ptr = &cave[y][x];

	/* Visible monsters */
	if (c_ptr->m_idx && c_ptr->m_idx < max_r_idx)
	{

		monster_type *m_ptr = &m_list[c_ptr->m_idx];
		/* Visible monsters */
		if (m_ptr->ml) return (TRUE);
	}

	/* Scan all objects in the grid */
	for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
	{
		object_type * o_ptr;

		/* Acquire object */
		o_ptr = &o_list[this_o_idx];

		/* Acquire next object */
		next_o_idx = o_ptr->next_o_idx;

		/* Memorized object */
		if (o_ptr->marked) return (TRUE);
	}

	/* Interesting memorized features */
	if (c_ptr->info & (CAVE_MARK))
	{
		/* Traps are interesting */
		if (c_ptr->info & (CAVE_TRDT)) return (TRUE);

		/* Hack -- Doors are boring */
		if (c_ptr->feat == FEAT_OPEN) return (FALSE);
		if (c_ptr->feat == FEAT_BROKEN) return (FALSE);
		if ((c_ptr->feat >= FEAT_DOOR_HEAD) &&
		                (c_ptr->feat <= FEAT_DOOR_TAIL)) return (FALSE);

		/* Accept 'naturally' interesting features */
		if (f_info[c_ptr->feat].flags1 & FF1_NOTICE) return (TRUE);
	}

	/* Nope */
	return (FALSE);
}


/*
 * Prepare the "temp" array for "target_set"
 *
 * Return the number of target_able monsters in the set.
 */
static void target_set_prepare(int mode)
{
	int y, x;

	/* Reset "temp" array */
	temp_n = 0;

	/* Scan the current panel */
	for (y = panel_row_min; y <= panel_row_max; y++)
	{
		for (x = panel_col_min; x <= panel_col_max; x++)
		{
			cave_type *c_ptr = &cave[y][x];

			/* Require line of sight, unless "look" is "expanded" */
			if (!expand_look && !player_has_los_bold(y, x)) continue;

			/* Require "interesting" contents */
			if (!target_set_accept(y, x)) continue;

			/* Require target_able monsters for "TARGET_KILL" */
			if ((mode & (TARGET_KILL)) && !target_able(c_ptr->m_idx)) continue;

			/* Save the location */
			temp_x[temp_n] = x;
			temp_y[temp_n] = y;
			temp_n++;
		}
	}

	/* Set the sort hooks */
	ang_sort_comp = ang_sort_comp_distance;
	ang_sort_swap = ang_sort_swap_distance;

	/* Sort the positions */
	ang_sort(temp_x, temp_y, temp_n);
}


bool target_object(int y, int x, int mode, cptr info, bool *boring,
                   object_type *o_ptr, char *out_val, cptr *s1, cptr *s2, cptr *s3,
                   int *query)
{
	char o_name[80];

	/* Not boring */
	*boring = FALSE;

	/* Obtain an object description */
	object_desc(o_name, o_ptr, TRUE, 3);

	/* Describe the object */
	sprintf(out_val, "%s%s%s%s [%s]", *s1, *s2, *s3, o_name, info);
	prt(out_val, 0, 0);
	move_cursor_relative(y, x);
	*query = inkey();

	/* Always stop at "normal" keys */
	if ((*query != '\r') && (*query != '\n') && (*query != ' ')) return (TRUE);

	/* Sometimes stop at "space" key */
	if ((*query == ' ') && !(mode & (TARGET_LOOK))) return (TRUE);

	/* Change the intro */
	*s1 = "It is ";

	/* Plurals */
	if (o_ptr->number != 1) *s1 = "They are ";

	/* Preposition */
	*s2 = "on ";
	return (FALSE);
}

/*
 * Examine a grid, return a keypress.
 *
 * The "mode" argument contains the "TARGET_LOOK" bit flag, which
 * indicates that the "space" key should scan through the contents
 * of the grid, instead of simply returning immediately.  This lets
 * the "look" command get complete information, without making the
 * "target" command annoying.
 *
 * The "info" argument contains the "commands" which should be shown
 * inside the "[xxx]" text.  This string must never be empty, or grids
 * containing monsters will be displayed with an extra comma.
 *
 * Note that if a monster is in the grid, we update both the monster
 * recall info and the health bar info to track that monster.
 *
 * Eventually, we may allow multiple objects per grid, or objects
 * and terrain features in the same grid. XXX XXX XXX
 *
 * This function must handle blindness/hallucination.
 */
static int target_set_aux(int y, int x, int mode, cptr info)
{
	cave_type *c_ptr = &cave[y][x];

	s16b this_o_idx, next_o_idx = 0;

	cptr s1, s2, s3;

	bool boring;

	int feat;

	int query;

	char out_val[160];


	/* Repeat forever */
	while (1)
	{
		/* Paranoia */
		query = ' ';

		/* Assume boring */
		boring = TRUE;

		/* Default */
		s1 = "You see ";
		s2 = "";
		s3 = "";

		/* Hack -- under the player */
		if ((y == p_ptr->py) && (x == p_ptr->px))
		{
			/* Description */
			s1 = "You are ";

			/* Preposition */
			s2 = "on ";
		}


		/* Hack -- hallucination */
		if (p_ptr->image)
		{
			cptr name = "something strange";

			/* Display a message */
			sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			query = inkey();

			/* Stop on everything but "return" */
			if ((query != '\r') && (query != '\n')) break;

			/* Repeat forever */
			continue;
		}


		/* Actual monsters */
		if (c_ptr->m_idx)
		{
			monster_type *m_ptr = &m_list[c_ptr->m_idx];
			monster_race *r_ptr = race_inf(m_ptr);

			/* Mimics special treatment -- looks like an object */
			if ((r_ptr->flags9 & RF9_MIMIC) && (m_ptr->csleep))
			{
				object_type *o_ptr;

				/* Acquire object */
				o_ptr = &o_list[m_ptr->hold_o_idx];

				if (o_ptr->marked)
				{
					if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break;
				}
			}
			else
			{
				/* Visible */
				if (m_ptr->ml)
				{
					bool recall = FALSE;

					char m_name[80];

					/* Not boring */
					boring = FALSE;

					/* Get the monster name ("a kobold") */
					monster_desc(m_name, m_ptr, 0x08);

					/* Hack -- track this monster race */
					monster_race_track(m_ptr->r_idx, m_ptr->ego);

					/* Hack -- health bar for this monster */
					health_track(c_ptr->m_idx);

					/* Hack -- handle stuff */
					handle_stuff();

					/* Interact */
					while (1)
					{
						/* Recall */
						if (recall)
						{
							/* Save */
							character_icky = TRUE;
							Term_save();

							/* Recall on screen */
							screen_roff(m_ptr->r_idx, m_ptr->ego, 0);

							/* Hack -- Complete the prompt (again) */
							Term_addstr( -1, TERM_WHITE, format("  [r,%s]", info));

							/* Command */
							query = inkey();

							/* Restore */
							Term_load();
							character_icky = FALSE;
						}

						/* Normal */
						else
						{
							cptr mstat;

							switch (m_ptr->status)
							{
							case MSTATUS_NEUTRAL:
							case MSTATUS_NEUTRAL_M:
							case MSTATUS_NEUTRAL_P:
								mstat = " (neutral) ";
								break;
							case MSTATUS_PET:
								mstat = " (pet) ";
								break;
							case MSTATUS_FRIEND:
								mstat = " (coaligned) ";
								break;
							case MSTATUS_COMPANION:
								mstat = " (companion) ";
								break;
							default:
								mstat = " ";
								break;
							}
							if (m_ptr->mflag & MFLAG_PARTIAL) mstat = " (partial) ";

							/* Describe, and prompt for recall */
							sprintf(out_val, "%s%s%s%s (level %d, %s%s)%s%s[r,%s]",
							        s1, s2, s3, m_name,
							        m_ptr->level, look_mon_desc(c_ptr->m_idx),
							        (m_ptr->mflag & MFLAG_QUEST) ? ", quest" : "",
							        (m_ptr->smart & SM_CLONED ? " (clone)" : ""),
							        (mstat), info);

							prt(out_val, 0, 0);

							/* Place cursor */
							move_cursor_relative(y, x);

							/* Command */
							query = inkey();
						}

						/* Normal commands */
						if (query != 'r') break;

						/* Toggle recall */
						recall = !recall;
					}

					/* Always stop at "normal" keys */
					if ((query != '\r') && (query != '\n') && (query != ' ')) break;

					/* Sometimes stop at "space" key */
					if ((query == ' ') && !(mode & (TARGET_LOOK))) break;

					/* Change the intro */
					s1 = "It is ";

					/* Hack -- take account of gender */
					if (r_ptr->flags1 & (RF1_FEMALE)) s1 = "She is ";
					else if (r_ptr->flags1 & (RF1_MALE)) s1 = "He is ";

					/* Use a preposition */
					s2 = "carrying ";

					/* Scan all objects being carried */
					for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
					{
						char o_name[80];

						object_type *o_ptr;

						/* Acquire object */
						o_ptr = &o_list[this_o_idx];

						/* Acquire next object */
						next_o_idx = o_ptr->next_o_idx;

						/* Obtain an object description */
						object_desc(o_name, o_ptr, TRUE, 3);

						/* Describe the object */
						sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, o_name, info);
						prt(out_val, 0, 0);
						move_cursor_relative(y, x);
						query = inkey();

						/* Always stop at "normal" keys */
						if ((query != '\r') && (query != '\n') && (query != ' ')) break;

						/* Sometimes stop at "space" key */
						if ((query == ' ') && !(mode & (TARGET_LOOK))) break;

						/* Change the intro */
						s2 = "also carrying ";
					}

					/* Double break */
					if (this_o_idx) break;

					/* Use a preposition */
					s2 = "on ";
				}
			}
		}



		/* Scan all objects in the grid */
		for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
		{
			object_type * o_ptr;

			/* Acquire object */
			o_ptr = &o_list[this_o_idx];

			/* Acquire next object */
			next_o_idx = o_ptr->next_o_idx;

			/* Describe it */
			if (o_ptr->marked)
			{
				if (target_object(y, x, mode, info, &boring, o_ptr, out_val, &s1, &s2, &s3, &query)) break;
			}
		}

		/* Double break */
		if (this_o_idx) break;

		/* Actual traps */
		if ((c_ptr->info & (CAVE_TRDT)) && c_ptr->t_idx)
		{
			cptr name = "a trap", s4;

			/* Name trap */
			if (t_info[c_ptr->t_idx].ident)
			{
				s4 = format("(%s)", t_name + t_info[c_ptr->t_idx].name);
			}
			else
			{
				s4 = "an unknown trap";
			}

			/* Display a message */
			sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, s4);
			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			query = inkey();

			/* Stop on everything but "return" */
			if ((query != '\r') && (query != '\n')) break;

			/* Repeat forever */
			continue;
		}

		/* Feature (apply "mimic") */
		if (c_ptr->mimic)
		{
			feat = c_ptr->mimic;
		}
		else
		{
			feat = f_info[c_ptr->feat].mimic;
		}

		/* Require knowledge about grid, or ability to see grid */
		if (!(c_ptr->info & (CAVE_MARK)) && !player_can_see_bold(y, x))
		{
			/* Forget feature */
			feat = FEAT_NONE;
		}

		/* Terrain feature if needed */
		if (boring || (feat >= FEAT_GLYPH))
		{
			cptr name;

			/* Hack -- special handling for building doors */
			if (feat == FEAT_SHOP)
			{
				name = st_name + st_info[c_ptr->special].name;
			}
			else
			{
				name = f_name + f_info[feat].name;
			}

			/* Hack -- handle unknown grids */
			if (feat == FEAT_NONE) name = "unknown grid";

			/* Pick a prefix */
			if (*s2 &&
			                (((feat >= FEAT_MINOR_GLYPH) &&
			                  (feat <= FEAT_PATTERN_XTRA2)) ||
			                 (feat == FEAT_DIRT) ||
			                 (feat == FEAT_GRASS) ||
			                 (feat == FEAT_FLOWER))) s2 = "on ";
			else if (*s2 && (feat == FEAT_SMALL_TREES)) s2 = "by ";
			else if (*s2 && (feat >= FEAT_DOOR_HEAD)) s2 = "in ";

			/* Pick proper indefinite article */
			s3 = (is_a_vowel(name[0])) ? "an " : "a ";

			/* Hack -- special introduction for store & building doors */
			if (feat == FEAT_SHOP)
			{
				s3 = "the entrance to the ";
			}

			if ((feat == FEAT_MORE) && c_ptr->special)
			{
				s3 = "";
				name = d_text + d_info[c_ptr->special].text;
			}

			if (p_ptr->wild_mode && (feat == FEAT_TOWN))
			{
				s3 = "";
				name = format("%s(%s)",
				              wf_name + wf_info[wild_map[y][x].feat].name,
				              wf_text + wf_info[wild_map[y][x].feat].text);
			}

			if ((feat == FEAT_FOUNTAIN) && (c_ptr->info & CAVE_IDNT))
			{
				object_kind *k_ptr;
				int tv, sv;

				if (c_ptr->special <= SV_POTION_LAST)
				{
					tv = TV_POTION;
					sv = c_ptr->special;
				}
				else
				{
					tv = TV_POTION2;
					sv = c_ptr->special - SV_POTION_LAST;
				}

				k_ptr = &k_info[lookup_kind(tv, sv)];
				info = k_name + k_ptr->name;
			}

			/* Display a message */
			if (!wizard)
			{
				sprintf(out_val, "%s%s%s%s [%s]", s1, s2, s3, name, info);
			}
			else
			{
				sprintf(out_val, "%s%s%s%s [%s] (%d:%d:%d)",
				        s1, s2, s3, name, info,
				        c_ptr->feat, c_ptr->mimic, c_ptr->special);
			}
			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			query = inkey();

			/* Always stop at "normal" keys */
			if ((query != '\r') && (query != '\n') && (query != ' ')) break;
		}

		/* Stop on everything but "return" */
		if ((query != '\r') && (query != '\n')) break;
	}

	/* Keep going */
	return (query);
}




/*
 * Handle "target" and "look".
 *
 * Note that this code can be called from "get_aim_dir()".
 *
 * All locations must be on the current panel.  Consider the use of
 * "panel_bounds()" to allow "off-panel" targets, perhaps by using
 * some form of "scrolling" the map around the cursor.  XXX XXX XXX
 * That is, consider the possibility of "auto-scrolling" the screen
 * while the cursor moves around.  This may require changes in the
 * "update_mon()" code to allow "visibility" even if off panel, and
 * may require dynamic recalculation of the "temp" grid set.
 *
 * Hack -- targetting/observing an "outer border grid" may induce
 * problems, so this is not currently allowed.
 *
 * The player can use the direction keys to move among "interesting"
 * grids in a heuristic manner, or the "space", "+", and "-" keys to
 * move through the "interesting" grids in a sequential manner, or
 * can enter "location" mode, and use the direction keys to move one
 * grid at a time in any direction.  The "t" (set target) command will
 * only target a monster (as opposed to a location) if the monster is
 * target_able and the "interesting" mode is being used.
 *
 * The current grid is described using the "look" method above, and
 * a new command may be entered at any time, but note that if the
 * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
 * where "space" has no obvious meaning) then "space" will scan
 * through the description of the current grid until done, instead
 * of immediately jumping to the next "interesting" grid.  This
 * allows the "target" command to retain its old semantics.
 *
 * The "*", "+", and "-" keys may always be used to jump immediately
 * to the next (or previous) interesting grid, in the proper mode.
 *
 * The "return" key may always be used to scan through a complete
 * grid description (forever).
 *
 * This command will cancel any old target, even if used from
 * inside the "look" command.
 */
bool target_set(int mode)
{
	int i, d, m;
	int y = p_ptr->py;
	int x = p_ptr->px;

	bool done = FALSE;

	bool flag = TRUE;

	char query;

	char info[80];

	cave_type *c_ptr;

	int screen_wid, screen_hgt;
	int panel_wid, panel_hgt;

	/* Get size */
	get_screen_size(&screen_wid, &screen_hgt);

	/* Calculate the amount of panel movement */
	panel_hgt = screen_hgt / 2;
	panel_wid = screen_wid / 2;

	/* Cancel target */
	target_who = 0;


	/* Cancel tracking */
	/* health_track(0); */


	/* Prepare the "temp" array */
	target_set_prepare(mode);

	/* Start near the player */
	m = 0;

	/* Interact */
	while (!done)
	{
		/* Interesting grids */
		if (flag && temp_n)
		{
			y = temp_y[m];
			x = temp_x[m];

			/* Access */
			c_ptr = &cave[y][x];

			/* Allow target */
			if (target_able(c_ptr->m_idx))
			{
				strcpy(info, "q,t,p,o,+,-,'dir'");
			}

			/* Dis-allow target */
			else
			{
				strcpy(info, "q,p,o,+,-,'dir'");
			}

			/* Describe and Prompt */
			query = target_set_aux(y, x, mode, info);

			/* Cancel tracking */
			/* health_track(0); */

			/* Assume no "direction" */
			d = 0;

			/* Analyze */
			switch (query)
			{
			case ESCAPE:
			case 'q':
				{
					done = TRUE;
					break;
				}

			case 't':
			case '.':
			case '5':
			case '0':
				{
					if (target_able(c_ptr->m_idx))
					{
						health_track(c_ptr->m_idx);
						target_who = c_ptr->m_idx;
						target_row = y;
						target_col = x;
						done = TRUE;
					}
					else
					{
						bell();
					}
					break;
				}

			case ' ':
			case '*':
			case '+':
				{
					if (++m == temp_n)
					{
						m = 0;
						if (!expand_list) done = TRUE;
					}
					break;
				}

			case '-':
				{
					if (m-- == 0)
					{
						m = temp_n - 1;
						if (!expand_list) done = TRUE;
					}
					break;
				}

			case 'p':
				{
					/* Recenter the map around the player */
					verify_panel();

					/* Update stuff */
					p_ptr->update |= (PU_MONSTERS);

					/* Redraw map */
					p_ptr->redraw |= (PR_MAP);

					/* Window stuff */
					p_ptr->window |= (PW_OVERHEAD);

					/* Handle stuff */
					handle_stuff();

					/* Recalculate interesting grids */
					target_set_prepare(mode);

					y = p_ptr->py;
					x = p_ptr->px;

					/* Fall through... */
				}

			case 'o':
				{
					flag = FALSE;
					break;
				}

			case 'm':
				{
					break;
				}

			default:
				{
					/* Extract the action (if any) */
					d = get_keymap_dir(query);

					if (!d) bell();
					break;
				}
			}

			/* Hack -- move around */
			if (d)
			{
				/* Find a new monster */
				i = target_pick(temp_y[m], temp_x[m], ddy[d], ddx[d]);

				/* Scroll to find interesting grid */
				if (i < 0)
				{
					int dy;
					int dx;

					dy = ddy[d];
					dx = ddx[d];

					/* Note panel change */
					if (change_panel(dy, dx))
					{
						int ty = temp_y[m];
						int tx = temp_x[m];

						/* Recalculate interesting grids */
						target_set_prepare(mode);

						/* Find a new monster */
						i = target_pick(ty, tx, dy, dx);

						/* Restore panel if needed */
						if (i < 0)
						{
							/* Restore panel */
							change_panel( -dy, -dx);

							/* Recalculate interesting grids */
							target_set_prepare(mode);
						}
					}
				}

				/* Use that grids */
				if (i >= 0) m = i;
			}
		}

		/* Arbitrary grids */
		else
		{
			/* Access */
			c_ptr = &cave[y][x];

			/* Default prompt */
			strcpy(info, "q,t,p,m,+,-,'dir'");

			/* Describe and Prompt (enable "TARGET_LOOK") */
			query = target_set_aux(y, x, mode | TARGET_LOOK, info);

			/* Cancel tracking */
			/* health_track(0); */

			/* Assume no direction */
			d = 0;

			/* Analyze the keypress */
			switch (query)
			{
			case ESCAPE:
			case 'q':
				{
					done = TRUE;
					break;
				}

			case 't':
			case '.':
			case '5':
			case '0':
				{
					target_who = -1;
					target_row = y;
					target_col = x;
					done = TRUE;
					break;
				}

			case ' ':
			case '*':
			case '+':
			case '-':
				{
					break;
				}

			case 'p':
				{
					y = p_ptr->py;
					x = p_ptr->px;
				}

			case 'o':
				{
					break;
				}

			case 'm':
				{
					flag = TRUE;
					break;
				}

			default:
				{
					/* Extract the action (if any) */
					d = get_keymap_dir(query);

					if (!d) bell();
					break;
				}
			}

			/* Handle "direction" */
			if (d)
			{
				int dy = ddy[d];
				int dx = ddx[d];

				/* Move */
				y += dy;
				x += dx;

				/* Do not move horizontally if unnecessary */
				if (((x < panel_col_min + panel_wid) && (dx > 0)) ||
				                ((x > panel_col_min + panel_wid) && (dx < 0)))
				{
					dx = 0;
				}

				/* Do not move vertically if unnecessary */
				if (((y < panel_row_min + panel_hgt) && (dy > 0)) ||
				                ((y > panel_row_min + panel_hgt) && (dy < 0)))
				{
					dy = 0;
				}
				/* Apply the motion */
				if ((y >= panel_row_min + screen_hgt) ||
				                (y < panel_row_min) ||
				                (x > panel_col_min + screen_wid) ||
				                (x < panel_col_min))
				{
					/* Change panel and recalculate interesting grids */
					if (change_panel(dy, dx)) target_set_prepare(mode);
				}

				/* Boundary checks */
				if (!wizard)
				{
					/* Hack -- Verify y */
					if (y <= 0) y = 1;
					else if (y >= cur_hgt - 1) y = cur_hgt - 2;

					/* Hack -- Verify x */
					if (x <= 0) x = 1;
					else if (x >= cur_wid - 1) x = cur_wid - 2;
				}
				else
				{
					/* Hack -- Verify y */
					if (y < 0) y = 0;
					else if (y > cur_hgt - 1) y = cur_hgt - 1;

					/* Hack -- Verify x */
					if (x < 0) x = 0;
					else if (x > cur_wid - 1) x = cur_wid - 1;
				}
			}
		}
	}

	/* Forget */
	temp_n = 0;

	/* Clear the top line */
	prt("", 0, 0);

	/* Recenter the map around the player */
	verify_panel();

	/* Update stuff */
	p_ptr->update |= (PU_MONSTERS);

	/* Redraw map */
	p_ptr->redraw |= (PR_MAP);

	/* Window stuff */
	p_ptr->window |= (PW_OVERHEAD);

	/* Handle stuff */
	handle_stuff();

	/* Failure to set target */
	if (!target_who) return (FALSE);

	/* Success */
	return (TRUE);
}



/*
 * Get an "aiming direction" from the user.
 *
 * The "dir" is loaded with 1,2,3,4,6,7,8,9 for "actual direction", and
 * "0" for "current target", and "-1" for "entry aborted".
 *
 * Note that "Force Target", if set, will pre-empt user interaction,
 * if there is a usable target already set.
 *
 * Note that confusion over-rides any (explicit?) user choice.
 */
bool get_aim_dir(int *dp)
{
	int dir;

	char command;

	cptr p;

#ifdef ALLOW_REPEAT /* TNB */

	if (repeat_pull(dp))
	{
		/* Confusion? */

		/* Verify */
		if (!(*dp == 5 && !target_okay()))
		{
			return (TRUE);
		}
	}

#endif /* ALLOW_REPEAT -- TNB */

	/* Initialize */
	(*dp) = 0;

	/* Global direction */
	dir = command_dir;

	/* Hack -- auto-target if requested */
	if (use_old_target && target_okay()) dir = 5;

	/* Ask until satisfied */
	while (!dir)
	{
		/* Choose a prompt */
		if (!target_okay())
		{
			p = "Direction ('*' to choose a target, Escape to cancel)? ";
		}
		else
		{
			p = "Direction ('5' for target, '*' to re-target, Escape to cancel)? ";
		}

		/* Get a command (or Cancel) */
		if (!get_com(p, &command)) break;

		/* Convert various keys to "standard" keys */
		switch (command)
		{
			/* Use current target */
		case 'T':
		case 't':
		case '.':
		case '5':
		case '0':
			{
				dir = 5;
				break;
			}

			/* Set new target */
		case '*':
			{
				if (target_set(TARGET_KILL)) dir = 5;
				break;
			}

		default:
			{
				/* Extract the action (if any) */
				dir = get_keymap_dir(command);

				break;
			}
		}

		/* Verify requested targets */
		if ((dir == 5) && !target_okay()) dir = 0;

		/* Error */
		if (!dir) bell();
	}

	/* No direction */
	if (!dir) return (FALSE);

	/* Save the direction */
	command_dir = dir;

	/* Check for confusion */
	if (p_ptr->confused)
	{
		/* XXX XXX XXX */
		/* Random direction */
		dir = ddd[rand_int(8)];
	}

	/* Notice confusion */
	if (command_dir != dir)
	{
		/* Warn the user */
		msg_print("You are confused.");
	}

	/* Save direction */
	(*dp) = dir;

#ifdef ALLOW_REPEAT /* TNB */

	repeat_push(dir);

#endif /* ALLOW_REPEAT -- TNB */

	/* A "valid" direction was entered */
	return (TRUE);
}



/*
 * Request a "movement" direction (1,2,3,4,6,7,8,9) from the user,
 * and place it into "command_dir", unless we already have one.
 *
 * This function should be used for all "repeatable" commands, such as
 * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
 * as all commands which must reference a grid adjacent to the player,
 * and which may not reference the grid under the player.  Note that,
 * for example, it is no longer possible to "disarm" or "open" chests
 * in the same grid as the player.
 *
 * Direction "5" is illegal and will (cleanly) abort the command.
 *
 * This function tracks and uses the "global direction", and uses
 * that as the "desired direction", to which "confusion" is applied.
 */
bool get_rep_dir(int *dp)
{
	int dir;

#ifdef ALLOW_REPEAT /* TNB */

	if (repeat_pull(dp))
	{
		return (TRUE);
	}

#endif /* ALLOW_REPEAT -- TNB */

	/* Initialize */
	(*dp) = 0;

	/* Global direction */
	dir = command_dir;

	/* Get a direction */
	while (!dir)
	{
		char ch;

		/* Get a command (or Cancel) */
		if (!get_com("Direction (Escape to cancel)? ", &ch)) break;

		/* Look up the direction */
		dir = get_keymap_dir(ch);

		/* Oops */
		if (!dir) bell();
	}

	/* Prevent weirdness */
	if (dir == 5) dir = 0;

	/* Aborted */
	if (!dir) return (FALSE);

	/* Save desired direction */
	command_dir = dir;

	/* Apply "confusion" */
	if (p_ptr->confused)
	{
		/* Standard confusion */
		if (rand_int(100) < 75)
		{
			/* Random direction */
			dir = ddd[rand_int(8)];
		}
	}

	/* Notice confusion */
	if (command_dir != dir)
	{
		/* Warn the user */
		msg_print("You are confused.");
	}

	/* Save direction */
	(*dp) = dir;

#ifdef ALLOW_REPEAT /* TNB */

	repeat_push(dir);

#endif /* ALLOW_REPEAT -- TNB */

	/* Success */
	return (TRUE);
}


int get_chaos_patron(void)
{
	return (((p_ptr->age) + (p_ptr->sc)) % MAX_PATRON);
}


void gain_level_reward(int chosen_reward)
{
	object_type *q_ptr;
	object_type forge;
	char wrath_reason[32] = "";
	int nasty_chance = 6;
	int dummy = 0, dummy2 = 0;
	int type, effect;


#if 0
	if (!chosen_reward)
	{
		if (multi_rew) return;
		else multi_rew = TRUE;
	}
#endif

	if (p_ptr->lev == 13) nasty_chance = 2;
	else if (!(p_ptr->lev % 13)) nasty_chance = 3;
	else if (!(p_ptr->lev % 14)) nasty_chance = 12;

	if (randint(nasty_chance) == 1)
		type = randint(20);  /* Allow the 'nasty' effects */
	else
		type = randint(15) + 5;  /* Or disallow them */

	if (type < 1) type = 1;
	if (type > 20) type = 20;
	type--;


	sprintf(wrath_reason, "the Wrath of %s",
	        chaos_patrons[p_ptr->chaos_patron]);

	effect = chaos_rewards[p_ptr->chaos_patron][type];

	if ((randint(6) == 1) && !chosen_reward)
	{
		msg_format("%^s rewards you with a corruption!",
		           chaos_patrons[p_ptr->chaos_patron]);
		(void)gain_random_corruption(0);
		return;
	}

	switch (chosen_reward ? chosen_reward : effect)
	{
	case REW_POLY_SLF :
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thou needst a new form, mortal!'");
		do_poly_self();
		break;

	case REW_GAIN_EXP:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Well done, mortal! Lead on!'");
		if (p_ptr->exp < PY_MAX_EXP)
		{
			s32b ee = (p_ptr->exp / 2) + 10;
			if (ee > 100000L) ee = 100000L;
			msg_print("You feel more experienced.");
			gain_exp(ee);
		}
		break;

	case REW_LOSE_EXP:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thou didst not deserve that, slave.'");
		lose_exp(p_ptr->exp / 6);
		break;

	case REW_GOOD_OBJ:
		msg_format("The voice of %s whispers:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Use my gift wisely.'");
		acquirement(p_ptr->py, p_ptr->px, 1, FALSE, FALSE);
		break;

	case REW_GREA_OBJ:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Use my gift wisely.'");
		acquirement(p_ptr->py, p_ptr->px, 1, TRUE, FALSE);
		break;

	case REW_CHAOS_WP:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thy deed hath earned thee a worthy blade.'");
		/* Get local object */
		q_ptr = &forge;
		dummy = TV_SWORD;
		switch (randint(p_ptr->lev))
		{
		case 0:
		case 1:
			dummy2 = SV_DAGGER;
			break;
		case 2:
		case 3:
			dummy2 = SV_MAIN_GAUCHE;
			break;
		case 4:
		case 5:
		case 6:
			dummy2 = SV_RAPIER;
			break;
		case 7:
		case 8:
			dummy2 = SV_SMALL_SWORD;
			break;
		case 9:
		case 10:
			dummy2 = SV_BASILLARD;
			break;
		case 11:
		case 12:
		case 13:
			dummy2 = SV_SHORT_SWORD;
			break;
		case 14:
		case 15:
			dummy2 = SV_SABRE;
			break;
		case 16:
		case 17:
			dummy2 = SV_CUTLASS;
			break;
		case 18:
		case 19:
			dummy2 = SV_KHOPESH;
			break;
		case 20:
			dummy2 = SV_TULWAR;
			break;
		case 21:
			dummy2 = SV_BROAD_SWORD;
			break;
		case 22:
		case 23:
			dummy2 = SV_LONG_SWORD;
			break;
		case 24:
		case 25:
			dummy2 = SV_SCIMITAR;
			break;
		case 26:
		case 27:
			dummy2 = SV_KATANA;
			break;
		case 28:
		case 29:
			dummy2 = SV_BASTARD_SWORD;
			break;
		case 30:
			dummy2 = SV_GREAT_SCIMITAR;
			break;
		case 31:
			dummy2 = SV_CLAYMORE;
			break;
		case 32:
			dummy2 = SV_ESPADON;
			break;
		case 33:
			dummy2 = SV_TWO_HANDED_SWORD;
			break;
		case 34:
			dummy2 = SV_FLAMBERGE;
			break;
		case 35:
		case 36:
			dummy2 = SV_EXECUTIONERS_SWORD;
			break;
		case 37:
			dummy2 = SV_ZWEIHANDER;
			break;
		default:
			dummy2 = SV_BLADE_OF_CHAOS;
		}

		object_prep(q_ptr, lookup_kind(dummy, dummy2));
		q_ptr->to_h = 3 + (randint(dun_level)) % 10;
		q_ptr->to_d = 3 + (randint(dun_level)) % 10;
		random_resistance(q_ptr, FALSE, (randint(34) + 4));
		q_ptr->name2 = EGO_CHAOTIC;

		/* Apply the ego */
		apply_magic(q_ptr, dun_level, FALSE, FALSE, FALSE);

		/* Drop it in the dungeon */
		drop_near(q_ptr, -1, p_ptr->py, p_ptr->px);
		break;

	case REW_GOOD_OBS:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thy deed hath earned thee a worthy reward.'");
		acquirement(p_ptr->py, p_ptr->px, randint(2) + 1, FALSE, FALSE);
		break;

	case REW_GREA_OBS:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Behold, mortal, how generously I reward thy loyalty.'");
		acquirement(p_ptr->py, p_ptr->px, randint(2) + 1, TRUE, FALSE);
		break;

	case REW_TY_CURSE:
		msg_format("The voice of %s thunders:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thou art growing arrogant, mortal.'");
		activate_ty_curse();
		break;

	case REW_SUMMON_M:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'My pets, destroy the arrogant mortal!'");
		for (dummy = 0; dummy < randint(5) + 1; dummy++)
		{
			(void)summon_specific(p_ptr->py, p_ptr->px, dun_level, 0);
		}
		break;

	case REW_H_SUMMON:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thou needst worthier opponents!'");
		activate_hi_summon();
		break;

	case REW_DO_HAVOC:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Death and destruction! This pleaseth me!'");
		call_chaos();
		break;

	case REW_GAIN_ABL:
		msg_format("The voice of %s rings out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Stay, mortal, and let me mold thee.'");
		if ((randint(3) == 1) &&
		                !(chaos_stats[p_ptr->chaos_patron] < 0))
			do_inc_stat(chaos_stats[p_ptr->chaos_patron]);
		else
			do_inc_stat(randint(6) - 1);
		break;

	case REW_LOSE_ABL:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'I grow tired of thee, mortal.'");
		if ((randint(3) == 1) &&
		                !(chaos_stats[p_ptr->chaos_patron] < 0))
			do_dec_stat(chaos_stats[p_ptr->chaos_patron], STAT_DEC_NORMAL);
		else
			(void)do_dec_stat(randint(6) - 1, STAT_DEC_NORMAL);
		break;

	case REW_RUIN_ABL:
		msg_format("The voice of %s thunders:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thou needst a lesson in humility, mortal!'");
		msg_print("You feel less powerful!");
		for (dummy = 0; dummy < 6; dummy++)
		{
			(void)dec_stat(dummy, 10 + randint(15), TRUE);
		}
		break;

	case REW_POLY_WND:
		msg_format("You feel the power of %s touch you.",
		           chaos_patrons[p_ptr->chaos_patron]);
		do_poly_wounds();
		break;

	case REW_AUGM_ABL:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Receive this modest gift from me!'");
		for (dummy = 0; dummy < 6; dummy++)
		{
			(void) do_inc_stat(dummy);
		}
		break;

	case REW_HURT_LOT:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Suffer, pathetic fool!'");
		fire_ball(GF_DISINTEGRATE, 0, (p_ptr->lev * 4), 4);
		take_hit(p_ptr->lev * 4, wrath_reason);
		break;

	case REW_HEAL_FUL:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Rise, my servant!'");
		restore_level();
		(void)set_poisoned(0);
		(void)set_blind(0);
		(void)set_confused(0);
		(void)set_image(0);
		(void)set_stun(0);
		(void)set_cut(0);
		hp_player(5000);
		for (dummy = 0; dummy < 6; dummy++)
		{
			(void) do_res_stat(dummy, TRUE);
		}
		break;

	case REW_CURSE_WP:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thou reliest too much on thy weapon.'");
		(void)curse_weapon();
		break;

	case REW_CURSE_AR:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Thou reliest too much on thine equipment.'");
		(void)curse_armor();
		break;

	case REW_PISS_OFF:
		msg_format("The voice of %s whispers:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Now thou shalt pay for annoying me.'");
		switch (randint(4))
		{
		case 1:
			activate_ty_curse();
			break;
		case 2:
			activate_hi_summon();
			break;
		case 3:
			if (randint(2) == 1) (void)curse_weapon();
			else (void)curse_armor();
			break;
		default:
			for (dummy = 0; dummy < 6; dummy++)
			{
				(void) dec_stat(dummy, 10 + randint(15), TRUE);
			}
			break;
		}
		break;

	case REW_WRATH:
		msg_format("The voice of %s thunders:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Die, mortal!'");
		take_hit(p_ptr->lev * 4, wrath_reason);
		for (dummy = 0; dummy < 6; dummy++)
		{
			(void) dec_stat(dummy, 10 + randint(15), FALSE);
		}
		activate_hi_summon();
		activate_ty_curse();
		if (randint(2) == 1) (void)curse_weapon();
		if (randint(2) == 1) (void)curse_armor();
		break;

	case REW_DESTRUCT:
		/* Prevent destruction of quest levels and town */
		if (!is_quest(dun_level) && dun_level)
		{
			msg_format("The voice of %s booms out:",
			           chaos_patrons[p_ptr->chaos_patron]);
			msg_print("'Death and destruction! This pleaseth me!'");
			destroy_area(p_ptr->py, p_ptr->px, 25, TRUE, FALSE);
		}
		break;

	case REW_GENOCIDE:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Let me relieve thee of thine oppressors!'");
		(void) genocide(FALSE);
		break;

	case REW_MASS_GEN:
		msg_format("The voice of %s booms out:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_print("'Let me relieve thee of thine oppressors!'");
		(void) mass_genocide(FALSE);
		break;

	case REW_DISPEL_C:
		msg_format("You can feel the power of %s assault your enemies!",
		           chaos_patrons[p_ptr->chaos_patron]);
		(void) dispel_monsters(p_ptr->lev * 4);
		break;

	case REW_IGNORE:
		msg_format("%s ignores you.",
		           chaos_patrons[p_ptr->chaos_patron]);
		break;

	case REW_SER_DEMO:
		msg_format("%s rewards you with a demonic servant!", chaos_patrons[p_ptr->chaos_patron]);
		if (!(summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_DEMON, FALSE)))
			msg_print("Nobody ever turns up...");
		break;

	case REW_SER_MONS:
		msg_format("%s rewards you with a servant!", chaos_patrons[p_ptr->chaos_patron]);
		if (!(summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_NO_UNIQUES, FALSE)))
			msg_print("Nobody ever turns up...");
		break;

	case REW_SER_UNDE:
		msg_format("%s rewards you with an undead servant!", chaos_patrons[p_ptr->chaos_patron]);
		if (!(summon_specific_friendly(p_ptr->py, p_ptr->px, dun_level, SUMMON_UNDEAD, FALSE)))
			msg_print("Nobody ever turns up...");
		break;

	default:
		msg_format("The voice of %s stammers:",
		           chaos_patrons[p_ptr->chaos_patron]);
		msg_format("'Uh... uh... the answer's %d/%d, what's the question?'", type,
		           effect );
		break;
	}
}


/*
 * old -- from PsiAngband.
 */
bool tgt_pt(int *x, int *y)
{
	char ch = 0;
	int d, cu, cv;
	int screen_wid, screen_hgt;
	bool success = FALSE;

	*x = p_ptr->px;
	*y = p_ptr->py;

	/* Get size */
	get_screen_size(&screen_wid, &screen_hgt);

	cu = Term->scr->cu;
	cv = Term->scr->cv;
	Term->scr->cu = 0;
	Term->scr->cv = 1;
	msg_print("Select a point and press space.");

	while ((ch != 27) && (ch != ' '))
	{
		move_cursor_relative(*y, *x);
		ch = inkey();
		switch (ch)
		{
		case 27:
			break;
		case ' ':
			success = TRUE;
			break;
		default:
			/* Look up the direction */
			d = get_keymap_dir(ch);

			if (!d) break;

			*x += ddx[d];
			*y += ddy[d];

			/* Hack -- Verify x */
			if ((*x >= cur_wid - 1) || (*x >= panel_col_min + screen_wid)) (*x)--;
			else if ((*x <= 0) || (*x <= panel_col_min)) (*x)++;

			/* Hack -- Verify y */
			if ((*y >= cur_hgt - 1) || (*y >= panel_row_min + screen_hgt)) (*y)--;
			else if ((*y <= 0) || (*y <= panel_row_min)) (*y)++;

			break;
		}
	}

	Term->scr->cu = cu;
	Term->scr->cv = cv;
	Term_fresh();
	return success;
}


bool gain_random_corruption(int choose_mut)
{
	exec_lua("gain_corruption()");
	return (FALSE);
}

bool lose_corruption(int choose_mut)
{
	exec_lua("lose_corruption()");
	return (FALSE);
}

bool lose_all_corruptions(void)
{
	exec_lua("lose_all_corruptions()");
	return (FALSE);
}

bool get_hack_dir(int *dp)
{
	int dir;
	cptr p;
	char command;


	/* Initialize */
	(*dp) = 0;

	/* Global direction */
	dir = 0;

	/* (No auto-targetting */

	/* Ask until satisfied */
	while (!dir)
	{
		/* Choose a prompt */
		if (!target_okay())
		{
			p = "Direction ('*' to choose a target, Escape to cancel)? ";
		}
		else
		{
			p = "Direction ('5' for target, '*' to re-target, Escape to cancel)? ";
		}

		/* Get a command (or Cancel) */
		if (!get_com(p, &command)) break;

		/* Convert various keys to "standard" keys */
		switch (command)
		{
			/* Use current target */
		case 'T':
		case 't':
		case '.':
		case '5':
		case '0':
			{
				dir = 5;
				break;
			}

			/* Set new target */
		case '*':
			{
				if (target_set(TARGET_KILL)) dir = 5;
				break;
			}

		default:
			{
				/* Look up the direction */
				dir = get_keymap_dir(command);

				break;
			}
		}

		/* Verify requested targets */
		if ((dir == 5) && !target_okay()) dir = 0;

		/* Error */
		if (!dir) bell();
	}

	/* No direction */
	if (!dir) return (FALSE);

	/* Save the direction */
	command_dir = dir;

	/* Check for confusion */
	if (p_ptr->confused)
	{
		/* XXX XXX XXX */
		/* Random direction */
		dir = ddd[rand_int(8)];
	}

	/* Notice confusion */
	if (command_dir != dir)
	{
		/* Warn the user */
		msg_print("You are confused.");
	}

	/* Save direction */
	(*dp) = dir;

	/* A "valid" direction was entered */
	return (TRUE);
}

/*
 * Do we have at least one corruption?
 */
bool got_corruptions()
{
	int i, max;

	max = exec_lua("return __corruptions_max");

	for (i = 0; i < max; i++)
	{
		if (exec_lua(format("if test_depend_corrupt(%d) == TRUE then return TRUE else return FALSE end", i)))
		{
			return TRUE;
		}
	}
	return FALSE;
}

/*
 * Dump the corruption list
 */
void dump_corruptions(FILE *fff, bool color)
{
	int i, max;

	if (!fff) return;

	max = exec_lua("return __corruptions_max");

	for (i = 0; i < max; i++)
	{
		if (exec_lua(format("if test_depend_corrupt(%d) == TRUE then return TRUE else return FALSE end", i)))
		{
			int c = exec_lua(format("return __corruptions[%d].color", i));

			if (color)
				fprintf(fff, "#####%c%s:\n", conv_color[c], string_exec_lua(format("return __corruptions[%d].name", i)));
			else
				fprintf(fff, "%s:\n", string_exec_lua(format("return __corruptions[%d].name", i)));
			fprintf(fff, "%s\n", string_exec_lua(format("return __corruptions[%d].desc", i)));
		}
	}
}

/*
 * Set "p_ptr->grace", notice observable changes
 */
void set_grace(s32b v)
{
	if (v < -300000) v = -300000;
	if (v > 300000) v = 300000;
	p_ptr->grace = v;
	p_ptr->update |= PU_BONUS;
	p_ptr->redraw |= (PR_PIETY);
	handle_stuff();
}

bool test_object_wish(char *name, object_type *o_ptr, object_type *forge, char *what)
{
	int i, j, jb, save_aware;
	char buf[200];

	/* try all objects, this *IS* a very ugly and slow method :( */
	for (i = 0; i < max_k_idx; i++)
	{
		object_kind *k_ptr = &k_info[i];

		o_ptr = forge;

		if (!k_ptr->name) continue;
		if (k_ptr->flags3 & TR3_NORM_ART) continue;
		if (k_ptr->flags3 & TR3_INSTA_ART) continue;
		if (k_ptr->tval == TV_GOLD) continue;

		object_prep(o_ptr, i);
		o_ptr->name1 = 0;
		o_ptr->name2 = 0;
		apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
		/* Hack : aware status must be restored after describing the item name */
		save_aware = k_ptr->aware;
		object_aware(o_ptr);
		object_known(o_ptr);
		object_desc(buf, o_ptr, FALSE, 0);
		strlower(buf);
		k_ptr->aware = save_aware;

		if (strstr(name, buf) ||
		   /* Hack hack hackery */
		   (o_ptr->tval == TV_ROD_MAIN && strstr(name, "rod of")))
		{
#if 0 // DGDGDGDG
			/* You can't wish for a wish! */
			if ((o_ptr->tval == TV_STAFF) && (o_ptr->sval == SV_STAFF_WISHING))
			{
				msg_format("You cannot %s for a wish!", what);
				return FALSE;
			}
#endif
			/* try all ego */
			for (j = max_e_idx - 1; j >= 0; j--)
			{
				ego_item_type *e_ptr = &e_info[j];
				bool ok = FALSE;

				if (j && !e_ptr->name) continue;

				/* Must have the correct fields */
				if (j)
				{
					int z;

					for (z = 0; z < 6; z++)
					{
						if (e_ptr->tval[z] == k_ptr->tval)
						{
							if ((e_ptr->min_sval[z] <= k_ptr->sval) &&
							                (e_ptr->max_sval[z] >= k_ptr->sval)) ok = TRUE;
						}
						if (ok) break;
					}
					if (!ok)
					{
						continue;
					}
				}

				/* try all ego */
				for (jb = max_e_idx - 1; jb >= 0; jb--)
				{
					ego_item_type *eb_ptr = &e_info[jb];
					bool ok = FALSE;

					if (jb && !eb_ptr->name) continue;

					if (j && jb && (e_ptr->before == eb_ptr->before)) continue;

					/* Must have the correct fields */
					if (jb)
					{
						int z;

						for (z = 0; z < 6; z++)
						{
							if (eb_ptr->tval[z] == k_ptr->tval)
							{
								if ((eb_ptr->min_sval[z] <= k_ptr->sval) &&
								                (eb_ptr->max_sval[z] >= k_ptr->sval)) ok = TRUE;
							}
							if (ok) break;
						}
						if (!ok)
						{
							continue;
						}
					}

					object_prep(o_ptr, i);
					o_ptr->name1 = 0;
					o_ptr->name2 = j;
					o_ptr->name2b = jb;
					apply_magic(o_ptr, dun_level, FALSE, FALSE, FALSE);
					object_aware(o_ptr);
					object_known(o_ptr);
					object_desc(buf, o_ptr, FALSE, 0);
					strlower(buf);

					if (!stricmp(buf, name))
					{
						/* Don't search any more */
						return TRUE;
					}
					else
					{
						/* Restore again the aware status */
						k_ptr->aware = save_aware;
					}
				}
			}
		}
	}
	return FALSE;
}

void clean_wish_name(char *buf, char *name)
{
	char *p;
	int i, j;

	/* Lowercase the wish */
	strlower(buf);

	/* Nuke uneccesary spaces */
	p = buf;
	while (*p == ' ') p++;
	i = 0;
	j = 0;
	while (p[i])
	{
		if ((p[i] == ' ') && (p[i + 1] == ' '))
		{
			i++;
			continue;
		}
		name[j++] = p[i++];
	}
	name[j++] = '\0';
	if (j)
	{
		j--;
		while (j && (name[j] == ' '))
		{
			name[j] = '\0';
			j--;
		}
	}
}

/*
 * Allow the player to make a wish
 */
void make_wish(void)
{
	char buf[200], name[200], *mname;
	int i, j, mstatus = MSTATUS_ENEMY;
	object_type forge, *o_ptr = &forge;

	/* Make an empty string */
	buf[0] = 0;

	/* Ask for the wish */
	if (!get_string("Wish for what? ", buf, 80)) return;

	clean_wish_name(buf, name);

	/* You can't wish for a wish! */
	if (strstr(name, "wish"))
	{
		msg_print("You can't wish for a wish!");
		return;
	}

	if (test_object_wish(name, o_ptr, &forge, "wish"))
	{
		msg_print("Your wish becomes truth!");

		/* Give it to the player */
		drop_near(o_ptr, -1, p_ptr->py, p_ptr->px);

		return;
	}

	/* try monsters */
	if (prefix(name, "enemy "))
	{
		mstatus = MSTATUS_ENEMY;
		mname = name + 6;
	}
	else if (prefix(name, "neutral "))
	{
		mstatus = MSTATUS_NEUTRAL;
		mname = name + 8;
	}
	else if (prefix(name, "friendly "))
	{
		mstatus = MSTATUS_FRIEND;
		mname = name + 9;
	}
	else if (prefix(name, "pet "))
	{
		mstatus = MSTATUS_PET;
		mname = name + 4;
	}
	else if (prefix(name, "companion "))
	{
		if (can_create_companion()) mstatus = MSTATUS_COMPANION;
		else mstatus = MSTATUS_PET;
		mname = name + 10;
	}
	else mname = name;
	for (i = 1; i < max_r_idx; i++)
	{
		monster_race *r_ptr = &r_info[i];

		if (!r_ptr->name) continue;

		if (r_ptr->flags9 & RF9_SPECIAL_GENE) continue;
		if (r_ptr->flags9 & RF9_NEVER_GENE) continue;
		if (r_ptr->flags1 & RF1_UNIQUE) continue;

		sprintf(buf, "%s", r_ptr->name + r_name);
		strlower(buf);

		if (strstr(mname, buf))
		{
			/* try all ego */
			for (j = max_re_idx - 1; j >= 0; j--)
			{
				monster_ego *re_ptr = &re_info[j];

				if (j && !re_ptr->name) continue;

				if (!mego_ok(i, j)) continue;

				if (j)
				{
					if (re_ptr->before) sprintf(buf, "%s %s", re_name + re_ptr->name, r_ptr->name + r_name);
					else sprintf(buf, "%s %s", r_ptr->name + r_name, re_name + re_ptr->name);
				}
				else
				{
					sprintf(buf, "%s", r_ptr->name + r_name);
				}
				strlower(buf);

				if (!stricmp(mname, buf))
				{
					int wy = p_ptr->py, wx = p_ptr->px;
					int attempts = 100;

					do
					{
						scatter(&wy, &wx, p_ptr->py, p_ptr->px, 5, 0);
					}
					while (!(in_bounds(wy, wx) && cave_floor_bold(wy, wx)) && --attempts);

					/* Create the monster */
					if (place_monster_one(wy, wx, i, j, FALSE, mstatus))
						msg_print("Your wish becomes truth!");

					/* Don't search any more */
					return;
				}
			}
		}
	}
}


/*
 * Corrupted have a 1/3 chance of losing a mutation each time this is called, 
 * assuming they have any in the first place
 */
void corrupt_corrupted(void)
{
	if (magik(45))
	{
		lose_corruption(0);
	}
	else
	{
		gain_random_corruption(0);
	}

	/* We are done. */
	return;
}

/*
 * Change to an other class
 */
void switch_class(int sclass)
{
	p_ptr->pclass = sclass;
	cp_ptr = &class_info[p_ptr->pclass];
}

/*
 * Change to an other subclass
 */
void switch_subclass(int sclass)
{
	p_ptr->pspec = sclass;
	spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
}

/*
 * Change to an other subrace
 */
void switch_subrace(int racem, bool copy_old)
{
	if ((racem < 0) && (racem >= max_rmp_idx)) return;

	/* If we switch to the saved subrace, we copy over the old subrace data */
	if (copy_old && (racem == SUBRACE_SAVE))
	{
		s32b old_title = race_mod_info[SUBRACE_SAVE].title;
		s32b old_desc = race_mod_info[SUBRACE_SAVE].desc;

		COPY(&race_mod_info[SUBRACE_SAVE], &race_mod_info[p_ptr->pracem], player_race_mod);

		race_mod_info[SUBRACE_SAVE].title = old_title;
		race_mod_info[SUBRACE_SAVE].desc = old_desc;
		strcpy(race_mod_info[SUBRACE_SAVE].title + rmp_name, race_mod_info[p_ptr->pracem].title + rmp_name);
	}

	p_ptr->pracem = racem;
	rmp_ptr = &race_mod_info[p_ptr->pracem];
}

cptr get_subrace_title(int racem)
{
	return race_mod_info[racem].title + rmp_name;
}

void set_subrace_title(int racem, cptr name)
{
	strcpy(race_mod_info[racem].title + rmp_name, name);
}

/*
 * Rebirth, recalc hp & exp/level
 */
void do_rebirth()
{
	/* Experience factor */
	p_ptr->expfact = rp_ptr->r_exp + rmp_ptr->r_exp + cp_ptr->c_exp;

	/* Hitdice */
	p_ptr->hitdie = rp_ptr->r_mhp + rmp_ptr->r_mhp + cp_ptr->c_mhp;

	/* Recalc HP */
	do_cmd_rerate();

	/* Change the level if needed */
	check_experience();
	p_ptr->max_plv = p_ptr->lev;

	/* Redraw/calc stuff */
	p_ptr->redraw |= (PR_BASIC);
	p_ptr->update |= (PU_BONUS);
	handle_stuff();

	lite_spot(p_ptr->py, p_ptr->px);
}

/*
 * Quick mimic name to index function
 */
int resolve_mimic_name(cptr name)
{
	s32b idx;

	call_lua("resolve_mimic_name", "(s)", "d", name, &idx);
	return idx;
}
tome-235-src/src/main-sdl-iso.c0000644000076400017500000013454411012107763014130 0ustar  dgdg/* Copyright (C) 2003-2004 Neil Stevens 
 // Copyright (C) 2004 Ethan Stump 
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // in the Software without restriction, including without limitation the rights
 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 // copies of the Software, and to permit persons to whom the Software is
 // furnished to do so, subject to the following conditions:
 //
 // The above copyright notice and this permission notice shall be included in
 // all copies or substantial portions of the Software.
 //
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 // THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 // Except as contained in this notice, the name(s) of the author(s) shall not be
 // used in advertising or otherwise to promote the sale, use or other dealings
 // in this Software without prior written authorization from the author(s).
 */

#ifdef USE_SDL

#include "angband.h"
#include 
#include 
#include 

#include 

#ifdef USE_ISO
/*
 * Simugraph system (Hj. Malthaner)
 */
#include "iso/simsys.h"
#include "iso/simgraph.h"
#include "iso/world_adaptor.h"
#include "iso/world_view.h"
/*
 * Simugraph specific routines
 * by Hj. Malthaner
 */
#include "iso/hackdef.h"

/*
 * Text place marker function protype (Hj. Malthaner)
 */
static void set_spots(int x, int y, int n, bool v);

/**
 * we need to track spots with text to avoid overdrawing text with images
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
bool spots[80][24];

/**
 * mouse coordinates for Simugraph engine 
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int mx, my;

/*
 * Hajo: this flags need to be set when opening windows
 */

static int tex_width;
static int tex_height;
static int tex_xoff;
static int tex_yoff;

static unsigned int tab16[1 << 16];

/**
 * this is used if we need to fake an 8 bit array
 * @author Hj. Malthaner
 */
static unsigned short * data8;

// buffers to store char code/attr for graphics
unsigned char **iso_ap;
unsigned char **iso_cp;
unsigned char **iso_atp;
unsigned char **iso_ctp;
unsigned char **iso_aep;
unsigned char **iso_cep;

#endif /* USE_ISO */


/*************************************************
 GLOBAL SDL-ToME PROPERTIES
 *************************************************/
 
/* Default window properties - used if none are available
from other places*/
#define DEF_SCREEN_WIDTH  800
#define DEF_SCREEN_HEIGHT 600
#define DEF_SCREEN_BPP     16

/*Main window properties that may be loaded at runtime from
a preference file or environmental variables. However,
default values (defined above) can be used. */
static int arg_width = DEF_SCREEN_WIDTH;
static int arg_height = DEF_SCREEN_HEIGHT;
static int arg_bpp = DEF_SCREEN_BPP;

/**************/

/* Default font properties - used unless otherwise changed.
These properties are the size and also default font to load. */
#define DEF_FONT_SIZE 16
#define DEF_FONT_FILE "lib/xtra/font/VeraMono.ttf"

/* The font properties that may perhaps be changed at runtime,
due to environmental variables, preference files, or in-program
commands.*/
static int arg_font_size = DEF_FONT_SIZE;
static char arg_font_name[64] = DEF_FONT_FILE;

/**************/

/* The number of term_data structures to set aside mem for */
#define MAX_CONSOLE_COUNT 8

/* The number of consoles that are actually being used.
This number could be changed via preference files, environmental
variables, command-line arguments, or possibly even in-game
keypresses or menu-selections. */
static int arg_console_count = 1;

/* When rendering multiple terminals, each is drawn with a
surrounding border. These values control the width of this
border and also the color to use when drawing it. */
#define BORDER_THICKNESS 1
static int border_color = 0;

/**************/

/* some miscellaneous settings which have not been dealt
with yet */
static bool arg_old_graphics = FALSE;
static bool arg_double_width = FALSE;

/* not dealt with yet (although full screen toggle
is available using Alt-Enter) */
static bool arg_full_screen = FALSE;


/*************************************************
 GLOBAL SDL-ToME VARIABLES
 *************************************************/

/* the main screen to draw to */
static SDL_Surface *screen;

/* some helper surfaces that are used for rendering 
characters */
static SDL_Surface *worksurf;
static SDL_Surface *crayon;

/* the array of pre-rendered characters
(see loadAndRenderFont() below) */
SDL_Surface *text[128];

/* the actual TTF_Font used (XXX should get rid of this)*/
TTF_Font *font=0;

/* the width and height of the uniformly-sized pre-rendered
characters */
int t_width = 1, t_height = 1;


/*************************************************
 COLOR SETUP
 *************************************************/
int screen_black;
int screen_white;

static int color_data[16];
/* The following macro is for color defining...
 Note that the color is fully opaque... */
#define COLOR(r,g,b) \
	SDL_MapRGBA(crayon->format,r,g,b,SDL_ALPHA_OPAQUE)

/*These color macros will setup the colors to use, but must be called after
 the SDL video has been set. That way SDL can correct for any funky video
 setttings. */

#define BLACK			COLOR(0x00,0x00,0x00)
#define WHITE			COLOR(0xff,0xff,0xff)
#define MID_GREY		COLOR(0x80,0x80,0x80)
#define BRIGHT_ORANGE	COLOR(0xff,0x80,0x00)
#define RED				COLOR(0xc0,0x00,0x00)
#define GREEN			COLOR(0x00,0x80,0x40)
#define BRIGHT_BLUE		COLOR(0x00,0x00,0xff)
#define DARK_ORANGE		COLOR(0x80,0x40,0x00)
#define DARK_GREY		COLOR(0x40,0x40,0x40)
#define BRIGHT_GREY		COLOR(0xc0,0xc0,0xc0)
#define PURPLE			COLOR(0xff,0x00,0xff)
#define YELLOW			COLOR(0xff,0xff,0x00)
#define BRIGHT_RED		COLOR(0xff,0x00,0x00)
#define BRIGHT_GREEN	COLOR(0x00,0xff,0x00)
#define AQUAMARINE		COLOR(0x00,0xff,0xff)
#define BROWN			COLOR(0xc0,0x80,0x40)

/*************************************************
 TERMINAL DATA STRUCTURE SETUP
 *************************************************/

/* Forward declare */
typedef struct _term_data term_data;

/* A structure for each "term" */
struct _term_data
{
	term t;					/* the term structure, defined in z-term.h */
	cptr name;				/* name of this term sub-window */

	uint rows, cols;		/* row/column count */
	uint pos_x, pos_y;		/* upper left corner of rendering box */
	uint size_w, size_h;	/* width, height of rendering box */

	bool has_border;		/* whether this sub-window has a border or not */
	uint border_thick;		/* thickness of border to draw around window */
#ifdef USE_GRAPHICS
#ifdef USE_TRANSPARENCY
#endif
#endif
};

/* The array of term data structures */
static term_data data[MAX_CONSOLE_COUNT];

/*************************************************
 FILE-SPECIFIC MACROS
 *************************************************/

/* Debug macros! */
#define DB(str) \
	printf("main-sdl: %s\n",str);

/*************************************************
 COLOR SETUP
 *************************************************/

/* SDL Quitting function... declare a few functions first.*/
void killFontAndAlphabet(void);
static void sdl_quit(cptr string)
{
	printf("sdl_quit called.\n");
	printf("message: %s\n",string);
	/* Need to take care of font and rendered characters */
	killFontAndAlphabet();
	if (TTF_WasInit())
		TTF_Quit();
	/* Then exit SDL */
	SDL_Quit();
	/* And now for the default quit behavior */
	quit_aux = 0;
	quit(string);
}

/*************************************************
 FONT SUPPORT FUNCTIONS
 *************************************************/

/* killFontAndAlphabet will effectively de-initialize the font system;
it does this by closing the font and destroying any pre-rendered
text in memory */
void killFontAndAlphabet(void)
{
	int i;
	/* need to close a font and free all of its corresponding pre-rendered
	surfaces */
	if (font)
	{
		TTF_CloseFont(font);
		font = 0;
	}
	for (i=0;i<128;i++)
	{
		if(text[i])
		{
			SDL_FreeSurface(text[i]);
			text[i] = NULL;
		}
	}
}	

/* loadAndRenderFont is responsible for loading and initializing
a font. First, SDL_ttf calls are made to load and set the style
for the desired font. Next, a character alphabet is rendered and
each character is placed onto a uniformly-sized surface within
the text[] array. Whenever text is needed for displaying on-screen,
this array is referenced and the desired character picture is used. */
void loadAndRenderFont(char *fname, int size)
{
	int minx,maxx,miny,maxy,advance,i,midline = 0;
	SDL_Color base_color = {255,255,255,255};
	SDL_Surface *temp_surf;
	SDL_Rect tgt = {0,0,0,0};

	/* Assuming that the filename is valid,
	open the font (pointer is global var)*/
	if (fname == NULL)
		sdl_quit("Gimme a font to load!");
	font = TTF_OpenFont(fname,size);
	if (font == NULL)
		sdl_quit("Error loading that font!");
	/* Set the font style to normal */
	TTF_SetFontStyle(font,TTF_STYLE_NORMAL);

	/* Collect some measurements on this font -
	arbitrarily choose the letter 'a' to get width*/
	TTF_GlyphMetrics(font,'a',&minx,&maxx,&miny,&maxy,&advance);
	/* the width of each character tile */
	t_width = advance;
	/* the height of each character tile */
	t_height = TTF_FontHeight(font);
	/* position of the y=0 line in each tile */
	midline = TTF_FontAscent(font);
	
	/* now... render each of the individual characters */
	for (i=0;i<128;i++)
	{
		/* make a pretty blended glyph */
		temp_surf=TTF_RenderGlyph_Blended(font,i,base_color);
		/* and make sure that we got it right! */
		if (temp_surf == NULL)
			sdl_quit("Glyph failed to render!");
		/* get the metrics of this particular glyph so we can position it */
		TTF_GlyphMetrics(font,i,&minx,&maxx,&miny,&maxy,&advance);
		/* copy rendered glyph into text queue, at the right position*/
		tgt.x = minx;
		tgt.y = midline-maxy;
		/* but first... we'll need a surface in the text queue to blit to! */
		text[i] = SDL_CreateRGBSurface(SDL_HWSURFACE,t_width,\
			t_height,16,0xf000,0x0f00,0x00f0,0x000f);
		/* turn OFF src-alpha... results in brute
		 copy of the RGBA contents of surf */
		SDL_SetAlpha(temp_surf,0,0);
		SDL_BlitSurface(temp_surf,NULL,text[i],&tgt);
		/* turn OFF src-alpha since we'll be using worksurf for blitting */
		SDL_SetAlpha(text[i],0,0);
		/* kill the surface to patch up memory leaks */
		SDL_FreeSurface(temp_surf);
	}
}

/***********************************************/

#ifdef USE_ISO
/*************************************************
 ISO SUPPORT FUNCTIONS
 *************************************************/
/**
 * inits operating system stuff
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_os_init(int n, int *parameter)
{
	// Hajo:
	// unused in isov-x11
	return TRUE;
}


/**
 * opens graphics device/context/window of size w*h
 * @param w width
 * @param h height
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_os_open(int w, int h)
{
	const int left = 13;

/*	tex_width = (data[0].fd->dw * (data[0].t.wid - left + 2) + 3) & 0xFFFC;
	tex_height = data[0].fd->dh * (data[0].t.hgt - 2);

	tex_xoff = data[0].fd->dw * left;
	tex_yoff = data[0].fd->dh * 1 + 1; 
*/

	//tex_width = (data[0].size_w - (left - 2) * (data[0].size_w / data[0].cols) + 3) & 0xFFFC;
	// this is too big (but works :-))
	tex_width = data[0].size_w & 0xfffc;
	tex_height = (data[0].size_h / data[0].rows) * (data[0].rows-2);

	tex_xoff = (tex_width / data[0].cols) * left;
	tex_yoff = (tex_height / data[0].rows) * 1 + 1;
	
	return TRUE;
}


/**
 * closes operating system stuff
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_os_close()
{
	// Hajo:
	// unused in isov-x11
	return TRUE;
}


/**
 * retrieve display width
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_get_width()
{
	return data[0].size_w;
}


/**
 * retrieve display height
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_get_height()
{
	return data[0].size_h;
}


/**
 * this is used if we need to fake an 8 bit array
 * @author Hj. Malthaner
 */
static unsigned short * data8;


/**
 * creates a (maybe virtual) array of graphics data
 * @author Hj. Malthaner
 */
unsigned short * dr_textur_init()
{
	int i;

	printf("isov-sdl::dr_textur_init()\n");
	printf(" width  = %d\n", data[0].size_w);
	printf(" height = %d\n", data[0].size_h);

	for (i = 0; i < (1 << 16); i++)
	{
		// FIXME!!!
		// must consider color bits, or breaks in anything else but RGB 555
		unsigned int R;
		unsigned int G;
		unsigned int B;

		// RGB 555
		R = (i & 0x7C00) >> 10;
		G = (i & 0x03E0) >> 5;
		B = (i & 0x001F) >> 0;


		tab16[i] = SDL_MapRGB(screen->format, R << 3, G << 3, B << 3);
	}



	data8 = malloc((data[0].size_w) * (data[0].size_h) * 2);

	printf(" textur = %p\n", data8);

	// fake an 16 bit array and convert data before displaying
	return data8;
}

static void flush_area(int dest_x, int dest_y,
                       int x, int y, int w, int h)
{
	SDL_Surface *face = screen;

	if (SDL_LockSurface(face) == 0)
	{
		int i, j;
		const int bpp = screen->format->BytesPerPixel;

		for (j = 0; j < h; j++)
		{
			unsigned short * p = data8 + (y + j) * tex_width + x;
			unsigned char * row = face->pixels + (dest_y + j) * face->pitch + dest_x * bpp;


			for (i = 0; i < w; i++)
			{
				*((unsigned short*)row) = tab16[ *p++ ];
				row += bpp;
			}
		}
		SDL_UnlockSurface(face);
	}
}

/**
 * displays the array of graphics data
 * @author Hj. Malthaner
 */
void dr_textur(int xp, int yp, int w, int h)
{
	int y;

	// clipping unten
	if (yp + h > tex_height)
	{
		h = tex_height - yp;
	}

	/* debug spots
	for(y=0; y<24; y++) {
	int x;

	for(x=0; x<80; x++) {
	 if(spots[x][y]) {
	printf("X");
	 } else {
	printf(".");
	 }
}
	printf("\n");
}
	*/

	for (y = 0; y < SCREEN_HGT; y++)
	{
		const int left = 13;
		const int y1 = y + 1;
		int x = 0;

		yp = data[0].size_h / data[0].rows * y;

		spots[79][y1] = FALSE;

		do
		{
			int n = 0;
			while (x + n + left < 80 && !spots[x + n + left][y1])
			{
				n++;
			}

			xp = data[0].size_w / data[0].cols * x;


			flush_area(tex_xoff + xp, tex_yoff + yp,
			           xp, yp,
			           data[0].size_w / data[0].cols*(n),
				   data[0].size_h / data[0].rows);

			x += n;

			while (x + left < 80 && spots[x + left][y1])
			{
				x++;
			}
		}
		while (x + left < 80);
	}
}


/**
 * use this method to flush graphics pipeline (undrawn stuff) onscreen.
 * @author Hj. Malthaner
 */
void dr_flush()
{
	// Iso-view for angband needs no sync.
	// XSync(md,FALSE);
}


/**
 * set colormap entries
 * @author Hj. Malthaner
 */
void dr_setRGB8multi(int first, int count, unsigned char * data)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * display/hide mouse pointer
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void show_pointer(int yesno)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * move mouse pointer
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void move_pointer(int x, int y)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * update softpointer position
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void ex_ord_update_mx_my()
{
	// Hajo:
	// unused in isov-x11
}


/**
 * get events from the system
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void GetEvents()
{
	// Hajo:
	// unused in isov-x11
}


/**
 * get events from the system without waiting
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void GetEventsNoWait()
{
	// Hajo:
	// unused in isov-x11
}


/**
 * @returns time since progrma start in milliseconds
 * @author Hj. Malthaner
 */
long long dr_time(void)
{
	// Hajo:
	// unused in isov-x11
	return 0;
}


/**
 * sleeps some microseconds
 * @author Hj. Malthaner
 */
void dr_sleep(unsigned long usec)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * loads a sample
 * @return a handle for that sample or -1 on failure
 * @author Hj. Malthaner
 */
int dr_load_sample(const char *filename)
{
	// Hajo:
	// unused in isov-x11
	return TRUE;
}


/**
 * plays a sample
 * @param key the key for the sample to be played
 * @author Hj. Malthaner
 */
void dr_play_sample(int key, int volume)
{
	// Hajo:
	// unused in isov-x11
}

static unsigned char ** halloc(int w, int h)
{
	unsigned char **field = (unsigned char **)malloc(sizeof(unsigned char *) * h);
	int i;

	for (i = 0; i < h; i++)
	{
		field[i] = (unsigned char *)malloc(sizeof(unsigned char) * w);
		memset(field[i], 32 , w);
	}

	return field;
}

/**
 * spot array access procedure. Mark text output spots
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
static void set_spots(const int x, const int y, const int n, const bool v)
{
	int i;

	for (i = x; i < x + n; i++)
	{
		spots[i][y] = v;
	}
}


/***********************************************/
#endif /* USE_ISO */


/*** Function hooks needed by "Term" ***/

static void Term_init_sdl(term *t)
{
	term_data *td = (term_data*)(t->data);
	DB("Term_init_sdl");
	/* XXX XXX XXX */
}

static void Term_nuke_sdl(term *t)
{
	term_data *td = (term_data*)(t->data);
	DB("Term_nuke_sdl");
	/* XXX XXX XXX */
}

static errr Term_user_sdl(int n)
{
	term_data *td = (term_data*)(Term->data);
	DB("Term_user_sdl");
	/* XXX XXX XXX */

	/* Unknown */
	return (1);
}

/* KEYPRESS_STRING repeatedly sends characters to the terminal
XXX - should implement routine from maim-sdl.c, it's sooo much
cleaner */
#define KEYPRESS_STRING(str) \
strcpy(buf,str); \
n = buf; \
while (*n != '\0') { \
	Term_keypress((int)(*(n++))); \
}

/* This is the main event handling routine that will be called
whenever an event is pulled off of the queue (in Term_xtra_sdl())*/
void handleEvent(SDL_Event *event)
{
	static char buf[24];	/* a buffer used when passing key names */
	char *n;				/* and a pointer to manipulate this buffer */

	switch( event->type )
	{
	case SDL_KEYDOWN:
		{
			/* handle key presses */

			/* I'm reading that as long as the upper 9 bits of the unicode
			 * value are zero, then the lower 7 bits are direct ASCII characters.
			 * Furthermore, it seems that all basic keys return non-zero values
			 * for the lower 7 bits, but function keys and other various things
			 * return 0000000 for the lower 7 bits.
			 * Basically, if the lower 7 bits are zero, do something special
			 *  (like start a macro), but otherwise just pass along the ASCII
			 * code!
			 */
			byte ascii_part = event->key.keysym.unicode & 0x00ff;

			/* gimme the key name */
			printf("Key is: %s\n",SDL_GetKeyName(event->key.keysym.sym));

			/* allow for full screen toggling! */
			if ((event->key.keysym.sym == SDLK_RETURN) && \
				(SDL_GetModState() & KMOD_ALT))
			{
				SDL_WM_ToggleFullScreen(screen);
			}
#ifdef USE_ISO
			/* toggle tile size */
			if (event->key.keysym.sym == SDLK_SCROLLOCK) 
			{
			    switch (display_get_tile_size())
			    {
				case 32:
				    display_select_tile_size(0);
				    break;
				case 64:
				    display_select_tile_size(1);
				    break;
				default:
				    display_select_tile_size(0);
				    break;
			    }
			    reset_visuals();
			    strcpy(buf, "graf-iso.prf");
			    process_pref_file(buf);
			    refresh_display();
			    SDL_UpdateRect(screen, 0, 0, data[0].size_w, data[0].size_h);
			}
			
			/* cycle grid type none/objects+monsters only/full */
			if ((event->key.keysym.sym == '#') && \
				(SDL_GetModState() & KMOD_ALT))
			{
			    set_grid(get_grid()+1);
			    refresh_display();
			}

#endif

			/*printf("ascii_part: %d\n",ascii_part);*/
			if (ascii_part)
			{
				/* We have now determined that the ASCII part is not '0', so
				 we can safely pass along the ASCII value! */
				Term_keypress(ascii_part);
			}
			else
			{
				/* We want to ignore keypresses that are simply the modifier
				keys*/
				if (!( (event->key.keysym.sym == SDLK_RSHIFT) |
					(event->key.keysym.sym == SDLK_LSHIFT) |
					(event->key.keysym.sym == SDLK_RALT) |
					(event->key.keysym.sym == SDLK_LALT) |
					(event->key.keysym.sym == SDLK_RCTRL) |
					(event->key.keysym.sym == SDLK_LCTRL) ))
				{

					/* now build a macro string using the modifiers together
					with the key that was just pressed*/

					/* As for the formatting...
					 * We pass the key press and modifiers as follows:
					 * \[ctrl-alt-shift-"key name"]
					 * following the previously established convention...
					 *
					 * All of the things that happen are defined in pref-sdl.prf
					 */

					KEYPRESS_STRING("\[");	/*Output the first part... */
					/* See if a control key is down */
					if (event->key.keysym.mod & KMOD_CTRL)
					{
						KEYPRESS_STRING("ctrl-");
					}
					/* See if an alt key is down */
					if (event->key.keysym.mod & KMOD_ALT)
					{
						KEYPRESS_STRING("alt-");
					}
					/* See if a shift key is down */
					if (event->key.keysym.mod & KMOD_SHIFT)
					{
						KEYPRESS_STRING("shift-");
					}

					/* Add in the name of whatever key was pressed */
					KEYPRESS_STRING(SDL_GetKeyName(event->key.keysym.sym));

					/* and end it... */
					KEYPRESS_STRING("]");
				}
			}
			break;
		}
	case SDL_QUIT:
		{
			/* handle quit requests */
			sdl_quit("Quitting!\n");
			break;
		}
	default:
		{
			break;
		}
	}
}

static errr Term_xtra_sdl(int n, int v)
{
	static SDL_Event event;
	term_data *td;
	char buf[1024];

	/* Analyze */
	switch (n)
	{
	case TERM_XTRA_EVENT:
		{
			if (v)
			{
				/* Perform event checking with blocking */
				SDL_WaitEvent( &event );
				handleEvent( &event );
			} else {
				/* Perform event checking without blocking */
				if (SDL_PollEvent(&event)){
					/* We found an event! */
					handleEvent(&event);
				}
			}
			return(0);
		}

	case TERM_XTRA_FLUSH:
		{
			/* Keep doing events until the queue is empty! */
			while (SDL_PollEvent(&event))
			{
				handleEvent(&event);
			}
			return (0);
		}

	case TERM_XTRA_CLEAR:
		{
			/* Perform a full screen clear; redraw the sub-window borders.*/
			static SDL_Rect base;
			base.x = 0;
			base.y = 0;
			base.w = arg_width;
			base.h = arg_height;

			td = (term_data*)(Term->data);

			/* Lock the screen */
			if (SDL_MUSTLOCK(screen) ){
				if (SDL_LockSurface(screen) < 0) {
					printf("Can't lock the screen: %s\n", SDL_GetError());
					exit(1);
				}
			}

			/* blank the screen area */
			SDL_FillRect(screen, &base, screen_black);

			/* Unlock the screen */
			if (SDL_MUSTLOCK(screen) ){
				SDL_UnlockSurface(screen);
			}

			/* And... UPDATE the whole screen */
			SDL_Flip(screen);

			return (0);
		}

	case TERM_XTRA_SHAPE:
		{
			/*
			 * Set the cursor visibility XXX XXX XXX
			 *
			 * This action should change the visibility of the cursor,
			 * if possible, to the requested value (0=off, 1=on)
			 *
			 * This action is optional, but can improve both the
			 * efficiency (and attractiveness) of the program.
			 */

			return (0);
		}

	case TERM_XTRA_FROSH:
		{
			/*
			 * Flush a row of output XXX XXX XXX
			 *
			 * This action should make sure that row "v" of the "output"
			 * to the window will actually appear on the window.
			 *
			 * This action is optional, assuming that "Term_text_xxx()"
			 * (and similar functions) draw directly to the screen, or
			 * that the "TERM_XTRA_FRESH" entry below takes care of any
			 * necessary flushing issues.
			 */

			return (1);
		}

	case TERM_XTRA_FRESH:
		{
			/*
			 * Flush output XXX XXX XXX
			 *
			 * This action should make sure that all "output" to the
			 * window will actually appear on the window.
			 *
			 * This action is optional, assuming that "Term_text_xxx()"
			 * (and similar functions) draw directly to the screen, or
			 * that the "TERM_XTRA_FROSH" entry above takes care of any
			 * necessary flushing issues.
			 */
#ifdef USE_ISO
	 		// Hajo:
			// refresh the graphical view

			refresh_display();
			SDL_UpdateRect(screen, 0, 0, data[0].size_w, data[0].size_h);
//			SDL_UpdateRect(td->face, 0, 0, 80*td->w, 24*td->h);
#endif /* USE_ISO */
			return (1);
		}

	case TERM_XTRA_NOISE:
		{
			/*
			 * Make a noise XXX XXX XXX
			 *
			 * This action should produce a "beep" noise.
			 *
			 * This action is optional, but convenient.
			 */

			return (1);
		}

	case TERM_XTRA_SOUND:
		{
			/*
			 * Make a sound XXX XXX XXX
			 *
			 * This action should produce sound number "v", where the
			 * "name" of that sound is "sound_names[v]".  This method
			 * is still under construction.
			 *
			 * This action is optional, and not very important.
			 */

			return (1);
		}

	case TERM_XTRA_BORED:
		{
			/* Perform event checking without blocking */
			if (SDL_PollEvent(&event)){
				/* We found an event! */
				handleEvent(&event);
			}
			return(0);
		}

	case TERM_XTRA_REACT:
		{
			/*
			 * React to global changes XXX XXX XXX
			 *
			 * For example, this action can be used to react to
			 * changes in the global "color_table[256][4]" array.
			 *
			 * This action is optional, but can be very useful for
			 * handling "color changes" and the "arg_sound" and/or
			 * "arg_graphics" options.
			 */
#ifdef USE_ISO
		    	strcpy(buf, "graf-iso.prf");
			process_pref_file(buf);
#endif /* USE_ISO */
			return (1);
		}

	case TERM_XTRA_ALIVE:
		{
			/*
			 * Change the "hard" level XXX XXX XXX
			 *
			 * This action is used if the program changes "aliveness"
			 * by being either "suspended" (v=0) or "resumed" (v=1)
			 * This action is optional, unless the computer uses the
			 * same "physical screen" for multiple programs, in which
			 * case this action should clean up to let other programs
			 * use the screen, or resume from such a cleaned up state.
			 *
			 * This action is currently only used by "main-gcu.c",
			 * on UNIX machines, to allow proper "suspending".
			 */

			return (1);
		}

	case TERM_XTRA_LEVEL:
		{
			/*
			 * Change the "soft" level XXX XXX XXX
			 *
			 * This action is used when the term window changes "activation"
			 * either by becoming "inactive" (v=0) or "active" (v=1)
			 *
			 * This action can be used to do things like activate the proper
			 * font / drawing mode for the newly active term window.  This
			 * action should NOT change which window has the "focus", which
			 * window is "raised", or anything like that.
			 *
			 * This action is optional if all the other things which depend
			 * on what term is active handle activation themself, or if only
			 * one "term_data" structure is supported by this file.
			 */

			return (1);
		}

	case TERM_XTRA_DELAY:
		{
			/*
			 * Delay for some milliseconds XXX XXX XXX
			 *
			 * This action is useful for proper "timing" of certain
			 * visual effects, such as breath attacks.
			 *
			 * This action is optional, but may be required by this file,
			 * especially if special "macro sequences" must be supported.
			 */

			/* I think that this command is system independent... */
			/*sleep(v/1000);*/
			/* main-x11 uses usleep(1000*v); */
			/* main-win uses Sleep(v); */
			return (1);
		}

	case TERM_XTRA_GET_DELAY:
		{
			/*
			 * Get Delay of some milliseconds XXX XXX XXX
			 * place the result in Term_xtra_long
			 *
			 * This action is useful for proper "timing" of certain
			 * visual effects, such as recording cmovies.
			 *
			 * This action is optional, but cmovies wont perform
			 * good without it
			 */

			return (1);
		}
	}

	/* Unknown or Unhandled action */
	return (1);
}

#define TYPECOLOR(i) 	printf("  R:%d\tG:%d\tB:%d\tA:%d\t\n",\
	color_data[i]>>24,(color_data[i]&0x00ff0000)>>16,\
	(color_data[i]&0x0000ff00)>>8,(color_data[i]&0x000000ff));
/*
 * Display the cursor
 *
 * This routine should display the cursor at the given location
 * (x,y) in some manner.  On some machines this involves actually
 * moving the physical cursor, on others it involves drawing a fake
 * cursor in some form of graphics mode.  Note the "soft_cursor"
 * flag which tells "z-term.c" to treat the "cursor" as a "visual"
 * thing and not as a "hardware" cursor.
 *
 * You may assume "valid" input if the window is properly sized.
 *
 * You may use the "Term_grab(x, y, &a, &c)" function, if needed,
 * to determine what attr/char should be "under" the new cursor,
 * for "inverting" purposes or whatever.
 */
static errr Term_curs_sdl(int x, int y)
{
	term_data *td = (term_data*)(Term->data);
	DB("Term_curs_sdl");
	/* XXX XXX XXX */
#ifdef USE_ISO
	highlite_spot(x, y);
#endif

	/* Success */
	return (0);
}


/*
 * Erase some characters
 *
 * This function should erase "n" characters starting at (x,y).
 *
 * You may assume "valid" input if the window is properly sized.
 */
static errr Term_wipe_sdl(int x, int y, int n)
{
	static SDL_Rect base;
	term_data *td = (term_data*)(Term->data);
	DB("Wiping");
	/* calculate boundaries of the area to clear */
	base.x = td->pos_x + x*t_width;
	base.y = td->pos_y + y*t_height;
	base.w = n*t_width;
	base.h = t_height;

	/* Lock the screen */
	if (SDL_MUSTLOCK(screen) ){
		if (SDL_LockSurface(screen) < 0) {
			printf("Can't lock the screen: %s\n", SDL_GetError());
			sdl_quit("Bah");
		}
	}

	/* blank the screen area */
	SDL_FillRect(screen, &base, screen_black);

	/* Unlock the screen */
	if (SDL_MUSTLOCK(screen) ){
		SDL_UnlockSurface(screen);
	}

	/* And... UPDATE the rectangle we just wrote to! */
	SDL_UpdateRects(screen,1,&base);

	/* Success */
	return (0);
}


/*
 * Draw some text on the screen
 *
 * This function should actually display an array of characters
 * starting at the given location, using the given "attribute",
 * and using the given string of characters, which contains
 * exactly "n" characters and which is NOT null-terminated.
 *
 * You may assume "valid" input if the window is properly sized.
 *
 * You must be sure that the string, when written, erases anything
 * (including any visual cursor) that used to be where the text is
 * drawn.  On many machines this happens automatically, on others,
 * you must first call "Term_wipe_xxx()" to clear the area.
 *
 * In color environments, you should activate the color contained
 * in "color_data[a & 0x0F]", if needed, before drawing anything.
 *
 * You may ignore the "attribute" if you are only supporting a
 * monochrome environment, since this routine is normally never
 * called to display "black" (invisible) text, including the
 * default "spaces", and all other colors should be drawn in
 * the "normal" color in a monochrome environment.
 *
 * Note that if you have changed the "attr_blank" to something
 * which is not black, then this function must be able to draw
 * the resulting "blank" correctly.
 *
 * Note that this function must correctly handle "black" text if
 * the "always_text" flag is set, if this flag is not set, all the
 * "black" text will be handled by the "Term_wipe_xxx()" hook.
 */
static errr Term_text_sdl(int x, int y, int n, byte a, const char *cp)
{
	term_data *td = (term_data*)(Term->data);
	static SDL_Rect base;
	SDL_Rect base_back;
	int i = n;
	char old = 0;

	/* calculate place to clear off and draw to */
	base.x = td->pos_x + x*t_width;
	base.y = td->pos_y + y*t_height;
	base.w = n*t_width;
	base.h = t_height;

	base_back = base;

	/* Lock the screen */
	if (SDL_MUSTLOCK(screen) ){
		if (SDL_LockSurface(screen) < 0) {
			printf("Can't lock the screen: %s\n", SDL_GetError());
			sdl_quit("Bah");
		}
	}

	/* blank the screen area */
	SDL_FillRect(screen, &base, screen_black);

	/* Unlock the screen */
	if (SDL_MUSTLOCK(screen) ){
		SDL_UnlockSurface(screen);
	}

	/* Note that SDL docs specify that SDL_BlitSurface should not be called
	 on locked surfaces... since the character printing routine below revolves
	 around blitting, the surface has been unlocked first*/

	/* loop through the input string, drawing characters */
	i = n;
	old = 0;
	while (i--)
	{
		/* Output the character... */
		/* If character has not changed, then just blit the old surface into
		 the new location to save effort*/
		if (*cp == old)
		{
			/* the desired character/color combo is already on the work surf */
			/* just blit it! */
			SDL_BlitSurface(worksurf,NULL,screen,&base);
		} else {
			/* copy the desired character onto working surface */
			SDL_BlitSurface(text[*cp],NULL,worksurf,NULL);
			/* color our crayon surface with the desired color */
			SDL_FillRect(crayon,NULL,color_data[a&0x0f]);
			/* apply the color to the character on the working surface */
			SDL_BlitSurface(crayon,NULL,worksurf,NULL);
			/* and blit it onto our screen! */
			SDL_BlitSurface(worksurf,NULL,screen,&base);
		}
		/* Move to the next position */
		base.x += t_width;
		/* Store the old character */
		old = *cp;
	/* Increment the character pointer */
		cp++;
	}

	// And... UPDATE the rectangle we just wrote to!
	SDL_UpdateRects(screen,1,&base_back);

#ifdef USE_ISO
	if (a < 16)
	{
		set_spots(x, y, n, TRUE);
	}
	else
	{
		set_spots(x, y, n, FALSE);
	}
#endif /* USE_ISO */
	
	/* Success */
	return (0);
}

/*
 * Draw some attr/char pairs on the screen
 *
 * This routine should display the given "n" attr/char pairs at
 * the given location (x,y).  This function is only used if one
 * of the flags "always_pict" or "higher_pict" is defined.
 *
 * You must be sure that the attr/char pairs, when displayed, will
 * erase anything (including any visual cursor) that used to be at
 * the given location.  On many machines this is automatic, but on
 * others, you must first call "Term_wipe_xxx(x, y, 1)".
 *
 * With the "higher_pict" flag, this function can be used to allow
 * the display of "pseudo-graphic" pictures, for example, by using
 * the attr/char pair as an encoded index into a pixmap of special
 * "pictures".
 *
 * With the "always_pict" flag, this function can be used to force
 * every attr/char pair to be drawn by this function, which can be
 * very useful if this file can optimize its own display calls.
 *
 * This function is often associated with the "arg_graphics" flag.
 *
 * This function is only used if one of the "higher_pict" and/or
 * "always_pict" flags are set.
 */
#ifndef USE_ISO
static errr Term_pict_sdl(int x, int y, int n, const byte *ap, const char *cp)
{
	term_data *td = (term_data*)(Term->data);
	DB("Term_pict_sdl");
	/* XXX XXX XXX */
#else
// for ISO-view we need USE_TRANSPARENCY and USE_EGO_GRAPHICS defined
static errr Term_pict_sdl(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp, const byte *eap, const char *ecp)
{
	/* Hajo: memorize output */
	memcpy(&iso_ap[y][x], ap, n);
	memcpy(&iso_cp[y][x], cp, n);
	memcpy(&iso_atp[y][x], tap, n);
	memcpy(&iso_ctp[y][x], tcp, n);
	memcpy(&iso_aep[y][x], eap, n);
	memcpy(&iso_cep[y][x], ecp, n);

	// here is no text
	set_spots(x, y, n, FALSE);

#endif /* USE_ISO */
	
	/* Success */
	return (0);
}

static errr term_data_init(term_data *td, int i)
{
	term *t = &(td->t);
	int x = 0;
	int y = 0;
	int cols = 80;
	int rows = 24;

	/* Initialize the term */
	// gets: pointer to address, number of columns, number of rows, number
	//   of keypresses to queue up (guess 24?)
	term_init(t, cols, rows, 24);

	/* Use a "soft" cursor */
	t->soft_cursor = TRUE;

	// Picture routine flags
	t->always_pict = FALSE;
	t->higher_pict = FALSE;
	t->always_text = FALSE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Hooks */
	t->xtra_hook = Term_xtra_sdl;
	t->curs_hook = Term_curs_sdl;
	t->wipe_hook = Term_wipe_sdl;
	t->text_hook = Term_text_sdl;
#ifdef USE_ISO
	t->pict_hook = Term_pict_sdl;
#endif /* USE_ISO */
	

	/* Save the data */
	t->data = td;

	/* Activate (important) */
	Term_activate(t);

	// *** Initialize the rest of the term_data stuff....
	td->name = angband_term_name[i];// name of this term window

	td->rows = rows;
	td->cols = cols;
	td->pos_x = x;
	td->pos_y = y;


	td->size_w = cols*t_width;
	td->size_h = rows*t_height;

	/* Turn on a border, thickness specified by BORDER_THICKNESS */
	td->has_border = TRUE;
	td->border_thick = BORDER_THICKNESS;

#ifdef USE_GRAPHICS
#ifdef USE_TRANSPARENCY
#endif
#endif

	/* Success */
	return (0);
}

#ifdef PRIVATE_USER_PATH

/*
 * Check and create if needed the directory dirpath -- copied from main.c
 */
bool private_check_user_directory(cptr dirpath)
{
	/* Is this used anywhere else in *bands? */
	struct stat stat_buf;

	int ret;

	/* See if it already exists */
	ret = stat(dirpath, &stat_buf);

	/* It does */
	if (ret == 0)
	{
		/* Now we see if it's a directory */
		if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE);

		/*
		 * Something prevents us from create a directory with
		 * the same pathname
		 */
		return (FALSE);
	}

	/* No - this maybe the first time. Try to create a directory */
	else
	{
		/* Create the ~/.ToME directory */
		ret = mkdir(dirpath, 0700);

		/* An error occured */
		if (ret == -1) return (FALSE);

		/* Success */
		return (TRUE);
	}
}

/*
 * Check existence of ".ToME/" directory in the user's
 * home directory or try to create it if it doesn't exist.
 * Returns FALSE if all the attempts fail.
 */
static bool check_create_user_dir(void)
{
	char dirpath[1024];
	char versionpath[1024];
	char savepath[1024];

	/* Get an absolute path from the filename */
	path_parse(dirpath, 1024, PRIVATE_USER_PATH);
	strcpy(versionpath, dirpath);
	strcat(versionpath, USER_PATH_VERSION);
	strcpy(savepath, versionpath);
	strcat(savepath, "/save");

	return private_check_user_directory(dirpath) && private_check_user_directory(versionpath) && private_check_user_directory(savepath);
}

#endif /* PRIVATE_USER_PATH */

/*
 * Init some stuff - copied from main.c
 */
static void init_stuff(void)
{
	char path[1024];

	cptr tail;

	/* Get the environment variable */
	tail = getenv("TOME_PATH");

	/* Use the angband_path, or a default */
#ifndef ENABLE_BINRELOC
	strcpy(path, tail ? tail : DEFAULT_PATH);
#else /* Runtime lookup of location */
	strcpy(path, br_strcat(DATADIR, "/tome/lib"));
#endif

	/* Hack -- Add a path separator (only if needed) */
	if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);

	/* Initialize */
	init_file_paths(path);
}


errr init_sdl(int argc, char **argv)
{
	return 0;
}

int main(int argc, char *argv[])
{
	int i;

	bool done = FALSE;

	bool new_game = FALSE;

	int show_score = 0;

	cptr mstr = NULL;

	bool args = TRUE;

	float gamma;
	char filename[PATH_MAX + 1];
	/* Flags to pass to SDL_SetVideoMode */
	int videoFlags;
	/* this holds some info about our display */
	const SDL_VideoInfo *videoInfo;


#ifdef CHECK_MEMORY_LEAKS
	GC_find_leak = 1;
#endif /* CHECK_MEMORY_LEAKS */


	/* Save the "program name" XXX XXX XXX */
	argv0 = argv[0];


#ifdef USE_286
	/* Attempt to use XMS (or EMS) memory for swap space */
	if (_OvrInitExt(0L, 0L))
	{
		_OvrInitEms(0, 0, 64);
	}
#endif


#ifdef SET_UID

	/* Default permissions on files */
	(void)umask(022);

#endif /* SET_UID */


	/* Get the file paths */
	init_stuff();


#ifdef SET_UID

	/* Get the user id (?) */
	player_uid = getuid();

#ifdef VMS
	/* Mega-Hack -- Factor group id */
	player_uid += (getgid() * 1000);
#endif

# ifdef SAFE_SETUID

# ifdef _POSIX_SAVED_IDS

	/* Save some info for later */
	player_euid = geteuid();
	player_egid = getegid();

# endif

# if 0	/* XXX XXX XXX */

	/* Redundant setting necessary in case root is running the game */
	/* If not root or game not setuid the following two calls do nothing */

	if (setgid(getegid()) != 0)
	{
		sdl_quit("setgid(): cannot set permissions correctly!");
	}

	if (setuid(geteuid()) != 0)
	{
		sdl_quit("setuid(): cannot set permissions correctly!");
	}

# endif  /* XXX XXX XXX */

# endif  /* SAFE_SETUID */

#endif /* SET_UID */


#ifdef SET_UID

	/* Please note that the game is still running in the game's permission */

	/* Initialize the "time" checker */
	if (check_time_init() || check_time())
	{
		sdl_quit("The gates to Angband are closed (bad time).");
	}

	/* Initialize the "load" checker */
	if (check_load_init() || check_load())
	{
		sdl_quit("The gates to Angband are closed (bad load).");
	}


	/*
	 * Become user -- This will be the normal state for the rest of the game.
	 *
	 * Put this here because it's totally irrelevant to single user operating
	 * systems, as witnessed by huge number of cases where these functions
	 * weren't used appropriately (at least in this variant).
	 *
	 * Whenever it is necessary to open/remove/move the files in the lib folder,
	 * this convention must be observed:
	 *
	 *    safe_setuid_grab();
	 *
	 *    fd_open/fd_make/fd_kill/fd_move which requires game's permission,
	 *    i.e. manipulating files under the lib directory
	 *
	 *    safe_setuid_drop();
	 *
	 * Please never ever make unmatched calls to these grab/drop functions.
	 *
	 * Please note that temporary files used by various information commands
	 * and ANGBAND_DIR_USER files shouldn't be manipulated this way, because
	 * they reside outside of the lib directory on multiuser installations.
	 * -- pelpel
	 */
	safe_setuid_drop();


	/* Acquire the "user name" as a default player name */
	user_name(player_name, player_uid);


#ifdef PRIVATE_USER_PATH

	/*
	 * On multiuser systems, users' private directories are
	 * used to store pref files, chardumps etc.
	 */
	{
		bool ret;

		/* Create a directory for the user's files */
		ret = check_create_user_dir();

		/* Oops */
		if (ret == FALSE) sdl_quit("Cannot create directory " PRIVATE_USER_PATH);
	}

#endif /* PRIVATE_USER_PATH */

#endif /* SET_UID */

	/* Before sdl_quit could possible be called, need to make sure that the text
	array is zeroed, so that sdl_quit->killFontAndAlphabet() doesn't try to free
	SDL_Surfaces that don't exist ! */
	memset(text,0,sizeof(text));

	/* Initialize the SDL window*/
	filename[PATH_MAX] = 0;

	/* initialize SDL */
	if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
	{
		sdl_quit("Video initialization failed!");
	}
	DB("SDL Initialized!");

	/* Skip to our arguments -- (Neil)*/
	/*	for (i = 1; (i < argc) && (0 != strcmp(argv[i], "--")); ++i); */
	/* Handle our arguments -- (Neil)*/
	/*	for (++i; i < argc ; ++i)
	 {
	 if (0 == strcmp(argv[i], "-n"))
	 {
	 if (++i == argc)
	 {
	 printf("Argument missing for option -n\n");
	 return -1;
	 }

	 arg_console_count = atoi(argv[i]);
	 if (arg_console_count <= 0 || arg_console_count > MAX_CONSOLE_COUNT)
	 {
	 printf("Invalid console count given.\n");
	 arg_console_count = 1;
	 }
	 }
	 else if (0 == strcmp(argv[i], "-o"))
	 {
	 arg_old_graphics = TRUE;
	 }
	 else if (0 == strcmp(argv[i], "-b"))
	 {
	 arg_double_width = TRUE;
	 }
	 else if (0 == strcmp(argv[i], "-w"))
	 {
	 if (++i == argc)
	 {
	 printf("Argument missing for option -w\n");
	 return -1;
	 }

	 arg_width = atoi(argv[i]);
	 }
	 else if (0 == strcmp(argv[i], "-h"))
	 {
	 if (++i == argc)
	 {
	 printf("Argument missing for option -h\n");
	 return -1;
	 }

	 arg_height = atoi(argv[i]);
	 }
	 else if (0 == strcmp(argv[i], "-fs"))
	 {
	 arg_full_screen = TRUE;
	 }
	 else if (0 == strcmp(argv[i], "-bpp"))
	 {
	 if (++i == argc)
	 {
	 printf("Argument missing for option -bpp\n");
	 return -1;
	 }

	 arg_bpp = atoi(argv[i]);
	 }
	 }
	 */


	/* Now for the meat of the initialization -- (Neil)*/
	quit_aux = sdl_quit;

	/* Window Manager stuff -- (Neil)*/
	path_build(filename, PATH_MAX, ANGBAND_DIR_XTRA, "graf/icon.png");
	SDL_WM_SetIcon(IMG_Load(filename), 0);
	SDL_WM_SetCaption("ToME", "tome");

	/* how about a hardware surface with hardware palette?
	XXX XXX XXX should probably be chosen at compile-time! */
	videoFlags = SDL_HWSURFACE | SDL_HWPALETTE;

	/* XXX XXX XXX */
	if(getenv("TOME_SCREEN_WIDTH")) arg_width = atoi(getenv("TOME_SCREEN_WIDTH"));
	if(getenv("TOME_SCREEN_HEIGHT")) arg_height = atoi(getenv("TOME_SCREEN_HEIGHT"));
	if(getenv("TOME_SCREEN_BPP")) arg_bpp = atoi(getenv("TOME_SCREEN_BPP"));

	/* get a SDL surface */
	screen = SDL_SetVideoMode( arg_width, arg_height, arg_bpp, videoFlags );

	DB("Video Mode Set!");

	/* Verify there is a surface */
	if ( !screen )
	{
		DB("No screen!");
		sdl_quit("Failed to set SDL Surface.");
	}

	DB("SDL Window Created!");

	/* Now ready the fonts! */

	DB("initializing SDL_ttf");
	if(TTF_Init()==-1) {
		printf("TTF_Init: %s\n", TTF_GetError());
		sdl_quit("Bah");
	}

	DB("loading font...");
	/* XXX centralize these environment calls*/
	if(getenv("TOME_FONT_SIZE")) arg_font_size = atoi(getenv("TOME_FONT_SIZE"));

	/* load and render the font */
	loadAndRenderFont(arg_font_name,arg_font_size);

	/* Initialize the working surface and crayon surface used for rendering
	 text in different colors... */
	worksurf = SDL_CreateRGBSurface(SDL_HWSURFACE,t_width,\
		t_height,16,0xf000,0x0f00,0x00f0,0x000f);
	crayon = SDL_CreateRGBSurface(SDL_HWSURFACE,t_width,\
		t_height,16,0xf000,0x0f00,0x00f0,0x000f);

	/* The working surface will blit using alpha values... */
	SDL_SetAlpha(worksurf,SDL_SRCALPHA,0);

	/* Set up the colors using the great little color macros! */
	color_data[0]  = BLACK;
	color_data[1]  = WHITE;
	color_data[2]  = MID_GREY;
	color_data[3]  = BRIGHT_ORANGE;
	color_data[4]  = RED;
	color_data[5]  = GREEN;
	color_data[6]  = BRIGHT_BLUE;
	color_data[7]  = DARK_ORANGE;
	color_data[8]  = DARK_GREY;
	color_data[9]  = BRIGHT_GREY;
	color_data[10] = PURPLE;
	color_data[11] = YELLOW;
	color_data[12] = BRIGHT_RED;
	color_data[13] = BRIGHT_GREEN;
	color_data[14] = AQUAMARINE;
	color_data[15] = BROWN;

	/* And setup the screen black color */
	screen_black = SDL_MapRGB(screen->format,0,0,0);
	screen_white = SDL_MapRGB(screen->format,255,255,255);

	/* Initialize the windows, or whatever that means in this case */
	for (i = 0; i < MAX_CONSOLE_COUNT; i++)
	{
		term_data *td = &data[i];

		/* Initialize the term_data */
		term_data_init(td, i);
		/* Save global entry */
		angband_term[i] = Term;
	}

	/* Enable UNICODE keysyms */
	SDL_EnableUNICODE(1);

	/* By setting this value, 'pref-sdl.prf' will be loaded on start.
	 Since this contains mappings for various keys, this is important! */
	ANGBAND_SYS = "sdl";
#ifdef USE_ISO
	DB("Isometric view uses always graphics mode.\n");
	use_graphics = TRUE;

	
	/* Hajo: allocate memory for output data */
	/* These arrays are read by the iso-view and written from this file */
	iso_cp = halloc(data[0].t.wid, data[0].t.hgt);
	iso_ap = halloc(data[0].t.wid, data[0].t.hgt);
	iso_ctp = halloc(data[0].t.wid, data[0].t.hgt);
	iso_atp = halloc(data[0].t.wid, data[0].t.hgt);
	iso_cep = halloc(data[0].t.wid, data[0].t.hgt);
	iso_aep = halloc(data[0].t.wid, data[0].t.hgt);

	// Hmm, no ANGBAND_SYS in old iso-code
	// if I change this I don't have to load the *.prf manually?
	// 
	// seems not to work for the following:	
	/* Hajo: set mode */
	ANGBAND_GRAF = "iso";

	/* Hajo: init view */
	init_adaptor();
	
	center_player = TRUE;
#endif /* USE_ISO */

	printf("Signals?\n");

	/* Catch nasty signals */
	signals_init();

	printf("Initialize Angband!\n");
	/* Initialize */
	init_angband();

	printf("Angband Initialized!\n");

	/* Hack -- If requested, display scores and quit */
	if (show_score > 0) display_scores(0, show_score);

	/* Wait for response */
	pause_line(23);

	printf("Play the game!\n");
#ifdef USE_ISO
	// Juergen: HACK, but this all is just for testing ...
	data[0].t.higher_pict = TRUE;
#endif

	/* Play the game */
	play_game(new_game);

	/* Quit */
	sdl_quit("Game over, man");

	/* Exit */
	return (0);

}

#endif
tome-235-src/src/maim-iso.c0000644000076400017500000005367311012107763013352 0ustar  dgdg/*
 *
 * This file contains routines for maiming bitmaps as well as other
 * supplemental routines, all for SDL.
 *
 * Copyright 2001 Gregory Velichansky (hmaon@bumba.net)
 * You may use it under the terms of the standard Angband license (below) or
 * the GNU General Public License (GPL) Version 2 or greater. (see below)
 *
 * The Angband license states:
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.  Other copyrights may also apply.
 * 
 * The GNU GPL notice:
   main-sdl.c - SDL (http://libsdl.org) Term implementation for Angband.
	Copyright (C) 2001  Gregory Velichansky (hmaon@bumba.net)
 
	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 2
	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, please see 
	http://www.gnu.org/copyleft/gpl.html
 
 
	Please see the file COPYING for more detail regarding Angband's current
	license situation.
*/


#include "angband.h"

#if defined(USE_ISO) || defined(USE_LUA_GUI)


#include "SDL/SDL.h"
#include 
#include  /* for scaling blits */
//#include "bits/nan.h"

/*
 *
 * Supplemental SDL bitmap manipulation functions.
 *
 * These could be moved to a separate file. In mai?-x11.c, similar routines
 * are separate from the main display module implementation.
 *
 */


/* The most pedantic-a%& getpixel and putpixel ever, hopefully. */
/* There may still be endianness bugs! These will be fixed after adequte testing. XXX XXX XXX */
inline errr SDL_GetPixel (SDL_Surface *f, Uint32 x, Uint32 y, Uint8 *r, Uint8 *g, Uint8 *b)
{
	/*const Uint32 mask[] = {0x0, 0xff, 0xffff, 0xffffff, 0xffffffff};*/
	Uint32 pixel;

	Uint8 *pp;

	int n;  /* general purpose 'n'. */

	if (f == NULL) return -1;

	pp = (Uint8 *) f->pixels;

	if (x >= f->w || y >= f->h) return -1;

	pp += (f->pitch * y);

	pp += (x * f->format->BytesPerPixel);

	/* we do not lock the surface here, it would be inefficient XXX */
	/* this reads the pixel as though it was a big-endian integer XXX */
	/* I'm trying to avoid reading part the end of the pixel data by
	 * using a data-type that's larger than the pixels */
	for (n = 0, pixel = 0; n < f->format->BytesPerPixel; ++n, ++pp)
	{
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
		pixel >>= 8;
		pixel |= *pp << (f->format->BitsPerPixel - 8);
#else
pixel |= *pp;
		pixel <<= 8;
#endif
	}

	SDL_GetRGB(pixel, f->format, r, g, b);
	return 0;
}

/* This function looks remarkably similar to the one above. Yes, it's cut
 * and paste. */
inline errr SDL_PutPixel (SDL_Surface *f, Uint32 x, Uint32 y, Uint8 r, Uint8 g, Uint8 b)
{
	Uint32 pixel;

	Uint8 *pp;

	int n;

	if (f == NULL) return -1;

	pp = (Uint8 *) f->pixels;

	if (x >= f->w || y >= f->h) return -1;

	pp += (f->pitch * y);

	pp += (x * f->format->BytesPerPixel);

	pixel = SDL_MapRGB(f->format, r, g, b);

	for (n = 0; n < f->format->BytesPerPixel; ++n, ++pp)
	{
		*pp = (Uint8) (pixel & 0xFF);
		pixel >>= 8;
	}

	return 0;
}


/* This routine performs a scaling blit. It will shrink and magnify. :) */
/* It uses floating point arithmetic (because I am lazy) so it's not too fast
 * but I only intend for it to be used in pre-processing, that is image 
 * processing at load time. It's fast enough for that, at least.
 * Actually on my machine it IS fast enough to scale fonts and bitmaps
 * in real-time. :) 
 * This routine uses a weighted average, the weight being based on overlapping
 * pixel area.
 */
inline errr SDL_ScaleBlit(SDL_Surface *src, SDL_Rect *sr, SDL_Surface *dst, SDL_Rect *dr)
{
	Uint8 r, g, b;

	float rs, gs, bs;  /* sums */

	float area;

	float sx, sy;  /* current source x and y */
	float dsx, dsy;  /* source increment, per increment of 1 in destination */

	float wsx, wsy;
	/* width of source box. Equal to dsx,dsy except when either of then are
	 * smaller than 1. This is a hack for smoother magnification. XXX */


	float x, y;  /* x and y in sub-area */

	Uint32 tx, ty;  /* "to" x and y */
	Uint32 lx, ly;

	float w, e, n, s;  /* some temporary variables, named after orientations */


	if (src == NULL || sr == NULL || dst == NULL || dr == NULL) return -1;

	/* these are meaningless and would cause a divide by zero: */
	if (!dr->w || !dr->h) return -1;

	wsx = dsx = ((float) sr->w) / dr->w;
	if (wsx < 1) wsx = 1;
	wsy = dsy = ((float) sr->h) / dr->h;
	if (wsy < 1) wsy = 1;

	lx = dr->x + dr->w;
	ly = dr->y + dr->h;

	area = wsx * wsy;



	for (ty = dr->y, sy = (float)sr->y; ty < ly; ++ty, sy += dsy)
	{
		for (tx = dr->x, sx = (float)sr->x; tx < lx; ++tx, sx += dsx)
		{
			rs = gs = bs = 0.0;
			for (y = floor(sy) - 1; ceil(sy + wsy) > y; ++y)
			{
				for (x = floor(sx) - 1; ceil(sx + wsx) > x; ++x)
				{
					w = (x > sx) ? 0 : sx - x;
					n = (y > sy) ? 0 : sy - y;

					e = (sx + wsx >= x + 1) ? 1 : sx + wsx - x;
					s = (sy + wsy >= y + 1) ? 1 : sy + wsy - y;

					if (w > e || s < n ) continue;

#define gsx ((Uint32)x >= sr->x+sr->w ? sr->x+sr->w-1 : (Uint32)x)
#define gsy ((Uint32)y >= sr->y+sr->h ? sr->y+sr->h-1 : (Uint32)y)
					SDL_GetPixel (src, gsx, gsy, &r, &g, &b);



					rs += (e - w) * (s - n) * (float)r;
					gs += (e - w) * (s - n) * (float)g;
					bs += (e - w) * (s - n) * (float)b;
				}
			}
			rs /= area;
			gs /= area;
			bs /= area;

			if (rs >= 256.0 || gs >= 256.0 || bs > 256.0)
			{
				plog("weighted average error!");
				plog(format("Values: %f, %f, %f\n", rs, gs, bs));
				/**((char *)0) = 0;*/
			}
			if (rs > 255.0) rs = 255.0;
			if (gs > 255.0) gs = 255.0;
			if (bs > 255.0) bs = 255.0;

			r = (Uint8)rs;
			g = (Uint8)gs;
			b = (Uint8)bs;

			SDL_PutPixel (dst, tx, ty, r, g, b);
		}
	}

	return 0;
#undef gsx
#undef gsy
}


/* Integer math version of SDL_ScaleBlit().
 * Where necessary, a number uses the 16 high bits for the integer
 * and the 16 low bits for the decimal portion.
 *
 * eg:
 * float a = (float) (b >> 16) + (b & 0xFFFF)/65536.0;
 */

inline Uint32 ifloor(Uint32 i)
{
	return i & 0xFFFF0000;
}

inline Uint32 iceil(Uint32 i)
{
	return (i & 0xFFFF) ? i : ifloor(i) + (1 << 16);
}


errr SDL_FastScaleBlit(SDL_Surface *src, SDL_Rect *sr, SDL_Surface *dst, SDL_Rect *dr)
{
	Uint8 r, g, b;
	Uint32 rs, gs, bs;  /* sums. */

	/* temp storage for large int multiplies. Uint64 doen't exist anywhere */
	double farea;
	Uint32 area;

	Uint32 sx, sy;
	Uint32 dsx, dsy;

	Uint32 wsx, wsy;

	Uint32 x, y;  /* x and y, for sub-area */

	Uint32 tx, ty;  /* normal integers */
	Uint32 lx, ly;  /* normal integers */

	Uint32 w, e, n, s;  /* temp variables, named after compass directions */

	if (src == NULL || sr == NULL || dst == NULL || dr == NULL) return -1;

	if (!dr->w || !dr->h) return -1;


	/* TODO FIXME check for possible overflows! */

	wsx = dsx = (sr->w << 16) / dr->w;
	if (!(wsx & 0xFFFF0000)) wsx = 1 << 16;
	wsy = dsy = (sr->h << 16) / dr->h;
	if (!(wsy & 0xFFFF0000)) wsy = 1 << 16;

	lx = dr->x + dr->w;
	ly = dr->y + dr->h;

	/* lazy multiplication. Hey, it's only once per blit. :P */
	farea = ((double)wsx) * ((double)wsy);
	farea /= (double)(1 << 16);
	area = (Uint32) farea;

	/* For optimization, those setup routines should be moved into
	 * SDL_ScaleTiledBitmap() for that function.
	 */

	for (ty = dr->y, sy = sr->y << 16; ty < ly; ++ty, sy += dsy)
	{
		for (tx = dr->x, sx = sr->x << 16; tx < lx; ++tx, sx += dsx)
		{
			rs = gs = bs = 0;
			for (y = ifloor(sy); iceil(sy + wsy) > y; y += (1 << 16))
			{
				for (x = ifloor(sx); iceil(sx + wsx) > x; x += (1 << 16))
				{
					w = (x > sx) ? 0 : sx - x;
					n = (y > sy) ? 0 : sy - y;

					e = (sx + wsx >= x + (1 << 16)) ? 1 << 16 : sx + wsx - x;
					s = (sy + wsy >= y + (1 << 16)) ? 1 << 16 : sy + wsy - y;

					if (w > e || s < n) continue;

#define gsx ((x >> 16) >= sr->x+sr->w ? sr->x+sr->w-1 : x >> 16)
#define gsy ((y >> 16) >= sr->y+sr->h ? sr->y+sr->h-1 : y >> 16)

					SDL_GetPixel (src, gsx, gsy, &r, &g, &b);

					rs += ((e - w) >> 8) * ((s - n) >> 8) * r;
					gs += ((e - w) >> 8) * ((s - n) >> 8) * g;
					bs += ((e - w) >> 8) * ((s - n) >> 8) * b;
				}
			}
			rs /= area;
			gs /= area;
			bs /= area;

			if (rs >= 256 || gs >= 256 || bs >= 256)
			{
				plog("fixed point weighted average overflow!");
				plog(format("Values: %d, %d, %d\n", rs, gs, bs));
			}

			r = (Uint8) rs;
			g = (Uint8) gs;
			b = (Uint8) bs;

			SDL_PutPixel (dst, tx, ty, r, g, b);
		}
	}

	return 0;
#undef gsx
#undef gsy
}



#if 0 /* the procedure above is a more generalized version of the one below */

/* The following is a function to perform a Blit while magnifying */
/* Anti-aliasing is performed. :) */
/* It is probably very SLOW on most systems. Use it for pre-processing. XXX */
/* a Blit while shrinking is handled by a different function */
errr SDL_StretchBlit(SDL_Surface *src, SDL_Rect *sr, SDL_Surface *dst, SDL_Rect *dr)
{
	double sx, sy;  /* current source x and y */
	Uint32 isx, isy;  /* temp. values for convenience in calculation code */
	double dsx, dsy;  /* source increment, per increment of 1 in destination */
	double wx, wy;  /* temp. weight values for the color mixing calculations */
	double weight;  /* temp. weight of pixel */

	/* coordinates to get pixels from: ... */
#undef gsx
#define gsx (isx >= sr->x+sr->w ? sr->x+sr->w-1 : isx)
#undef gsy
#define gsy (isy >= sr->y+sr->h ? sr->y+sr->h-1 : isy)


	Uint32 tx, ty;  /* "to" x and y. "dx, dy" would be too confusing. */
	Uint32 lx, ly;  /* end x and y in destination, not inclusive */

	double r, g, b;  /* temporary values on which we perform calculations */
	/*double s;*/ /* scale factor calculation thing. gross hack. don't ask. */
	Uint8 ir, ig, ib;  /* same here. */

	if (src == NULL || sr == NULL || dst == NULL || dr == NULL) return -1;

	/* these are meaningless and would cause a divide by zero: */
	if (!dr->w || !dr->h) return -1;

	dsx = ((double) sr->w) / dr->w;
	dsy = ((double) sr->h) / dr->h;

	lx = dr->x + dr->w;
	ly = dr->y + dr->h;

	for (ty = dr->y, sy = (double)sr->y; ty < ly; ++ty, sy += dsy)
	{
		for (tx = dr->x, sx = (double)sr->x; tx < lx; ++tx, sx += dsx)
		{
			/* here we must consider four pixels and mix them together */
			/* the further away we are from a pixel, the less weight it has
			 * when we mix in its color. Hence the "1 - hypot(..." etc.
			 * Actually, no. Let's not use hypot().
			 */
			/*
			 * upper left pixel 
			 */
			wx = ((floor(sx) + 1) - sx);
			wy = ((floor(sy) + 1) - sy);

			isx = (Uint32) floor(sx);
			isy = (Uint32) floor(sy);

			if (SDL_GetPixel(src, gsx, gsy, &ir, &ig, &ib)) return -1;

			weight = wx * wy;
			/* the area of the overlap of our hypothetical and real pixel!!! */
			if (weight < 1 / 1024.0) weight = 0;
			r = weight * (double)ir;
			g = weight * (double)ig;
			b = weight * (double)ib;
			/*s = weight * 255.0;*/

			/*
			 * upper right pixel 
			 */
			wx = 1 - wx;
			isx += 1;

			if (SDL_GetPixel(src, gsx, gsy, &ir, &ig, &ib)) return -1;

			weight = wx * wy;
			if (weight < 1 / 1024.0) weight = 0;
			r += weight * (double)ir;
			g += weight * (double)ig;
			b += weight * (double)ib;
			/*s += weight * 255.0;*/

			/*
			 * lower right pixel 
			 */
			wy = 1 - wy;
			isy += 1;

			if (SDL_GetPixel(src, gsx, gsy, &ir, &ig, &ib)) return -1;

			weight = wx * wy;
			if (weight < 1 / 1024.0) weight = 0;
			r += weight * (double)ir;
			g += weight * (double)ig;
			b += weight * (double)ib;
			/*s += weight * 255.0;*/

			/*
			 * lower left pixel
			 */
			wx = 1 - wx;
			isx -= 1;

			if (SDL_GetPixel(src, gsx, gsy, &ir, &ig, &ib)) return -1;

			weight = wx * wy;
			if (weight < 1 / 1024.0) weight = 0;
			r += weight * (double)ir;
			g += weight * (double)ig;
			b += weight * (double)ib;
			/*s += weight * 255.0;*/


			/*
			r = 255 * (r/s);
			g = 255 * (g/s);
			b = 255 * (b/s);
			*/

			if (r >= 256.0 || g >= 256.0 || b > 256.0)
			{
				plog("mixing error!");
				plog(format("Values: %f, %f, %f\n", (double)r, (double)g, (double)b));
				/**((char *)0) = 0;*/
			}
			if (r > 255.0) r = 255.0;
			if (g > 255.0) g = 255.0;
			if (b > 255.0) b = 255.0;
			ir = (Uint8) r;
			ig = (Uint8) g;
			ib = (Uint8) b;

			SDL_PutPixel(dst, tx, ty, ir, ig, ib);
		}
	}

	return 0;
}

#endif




/* This function will take an SDL_Surface, allocate a new surface to hold
 * the resized surface, perform the scaling operation, free the old surface
 * and return the new one. This behaviour is vaguely modeled after C library
 * string functions. Returns NULL on grievous errors! 
 *
 * The scaling operation is performed one or more times to accomodate
 * images comprised by a number of sub-images whose edges must not be blurred
 * with the edges of adjacent sub-images. (Think fonts and tile sets.)
 *
 * If t_oldw and t_oldh are set to src->w and src->h respectively
 *
 * t_oldw, t_oldh are the size of the old tiles
 */
SDL_Surface *SDL_ScaleTiledBitmap (SDL_Surface *src,
                                   Uint32 t_oldw,
                                   Uint32 t_oldh,
                                   Uint32 t_neww,
                                   Uint32 t_newh,
                                   int dealloc_src)

{
	SDL_Surface *dst;
	SDL_Rect sr, dr;
	Uint32 x, y;
	Uint32 nx, ny;

	if (!t_oldw || !t_oldh || !t_neww || !t_newh || !src) return NULL;  /*dummy!*/

	if (t_oldw == t_neww && t_oldh == t_newh) return src;  /* OK... */

	/* Get the number of tiles in the image.
	 * Any possible clipped tiles at the edges are ignored.
	 */
	nx = src->w / t_oldw;
	ny = src->h / t_oldh;

	/* Allocate a new SDL_Surface of appropriate size, with settings otherwise
	 * identical to src.
	 */
	dst = SDL_CreateRGBSurface(src->flags,
	                           nx * t_neww,
	                           ny * t_newh,
	                           /*src->format->BitsPerPixel,*/
	                           16,
	                           src->format->Rmask,
	                           src->format->Gmask,
	                           src->format->Bmask,
	                           src->format->Amask);


	for (y = 0; y < ny; ++y)
	{
		for (x = 0; x < nx; ++x)
		{
			sr.w = t_oldw;
			sr.h = t_oldh;
			sr.x = x * t_oldw;
			sr.y = y * t_oldh;

			dr.w = t_neww;
			dr.h = t_newh;
			dr.x = x * t_neww;
			dr.y = y * t_newh;

			/*printf("%d,%d -> %d,%d   (%d,%d -> %d, %d)\n", sr.x, sr.y, dr.x, dr.y, sr.w, sr.h, dr.w, dr.h);*/

			/* scale-blit one tile and check for error
			 * although SDl_ScaleBlit() might not have any errors to return.
			 */
			if (SDL_FastScaleBlit(src, &sr, dst, &dr)) return NULL;
		}
	}

	if (dealloc_src) SDL_FreeSurface(src);

	return dst;
}


/* The following function will extract height and width info from a filename
 * such as 16x16.xyz or 8X13.bar or even argle8ook16.foo
 *
 * I realize now that it's also useful for reading integers out of an argument
 * such as --fooscale1=2
 */

errr strtoii(const char *str, Uint32 *w, Uint32 *h)
{
	char buf[1024];
	char *s = buf;
	char *tok;
	char *numeric = "0123456789";

	size_t l;  /* length of numeric string */

	if (!str || !w || !h) return -1;

	if (strlen(str) < 3) return -1;  /* must have room for at least "1x1" */

	strncpy(buf, str, 1023);
	buf[1023] = '\0';

	tok = strpbrk(buf, numeric);
	if (!tok) return -1;

	l = strspn(tok, numeric);
	if (!l) return -1;

	tok[l] = '\0';

	s = tok + l + 1;

	if (!sscanf(tok, "%d", w)) return -1;

	/* next token */
	tok = strpbrk(s, numeric);
	if (!tok) return -1;

	l = strspn(tok, numeric);
	if (!l) return -1;

	tok[l] = '\0';
	/* no need to set s since this is the last token */

	if (!sscanf(tok, "%d", h)) return -1;

	return 0;

}




char *formatsdlflags(Uint32 flags)
{
	return format ("%s%s%s%s%s%s%s%s%s%s (%x)",
	               (flags & SDL_HWSURFACE) ? "SDL_HWSURFACE " : "",
	               (flags & SDL_ANYFORMAT) ? "SDL_ANYFORMAT " : "",
	               (flags & SDL_HWPALETTE) ? "SDL_HWPALETTE " : "",
	               (flags & SDL_DOUBLEBUF) ? "SDL_DOUBLEBUF " : "",
	               (flags & SDL_FULLSCREEN) ? "SDL_FULLSCREEN " : "",
	               (flags & SDL_RESIZABLE) ? "SDL_RESIZABLE " : "",
	               (flags & SDL_HWACCEL) ? "SDL_HWACCEL " : "",
	               (flags & SDL_SRCCOLORKEY) ? "SDL_SRCCOLRKEY " : "",
	               (flags & SDL_RLEACCEL) ? "SDL_RLEACCEL " : "",
	               (flags & SDL_SRCALPHA) ? "SDL_SRCALPHA " : "",
	               flags);
};






/* A lot of code for handling keystrokes follow. */


typedef struct sdl_keymapt sdl_keymapt;

struct sdl_keymapt
{
	SDLKey k;  /* what we get from SDL */
	char *s;  /* what we feed to the Term_keypress */
	char *ctrl;  /* what if CTRL is pressed? (NULL if the same) */
	char *shift;  /* what if SHIFT is pressed? */
};

/* XXX XXX XXX the following keymap sucks. More comments below. */
sdl_keymapt sdl_keymap[] =
{
	/*{SDLK_UP, "", "Oa", "Ox"},
	{SDLK_DOWN, "", "Ob", "Or"},
	{SDLK_RIGHT, "", "Oc", "Ot"},
	{SDLK_LEFT, "", "Od", "Ov"},
	{SDLK_INSERT, "[2~", "[2^", "Op"},
	{SDLK_HOME, "[1~", "[1^", "Ow"},
	{SDLK_END, "[4~", "[4^", "Oq"},
	{SDLK_PAGEUP, "[5~", "[5^", "Oy"},
	{SDLK_PAGEDOWN, "[6~", "[6^", "Os"},*/
	{SDLK_F1, "[[A", NULL, NULL},
	{SDLK_F2, "[[B", NULL, NULL},
	{SDLK_F3, "[[C", NULL, NULL},
	{SDLK_F4, "[[D", NULL, NULL},
	{SDLK_F5, "[[E", NULL, NULL},
	{SDLK_F6, "[[17~", NULL, NULL},
	{SDLK_F7, "[[18~", NULL, NULL},
	{SDLK_F8, "[[19~", NULL, NULL},
	{SDLK_F9, "[[20~", NULL, NULL},
	{SDLK_F10, "[[21~", NULL, NULL},
	{SDLK_F11, "[[23~", NULL, NULL},
	{SDLK_F12, "[[24~", NULL, NULL},
	/* I have no machines with F13, F14, F15. Is that a Sun thing? */
	{SDLK_F13, "", NULL, NULL},
	{SDLK_F14, "", NULL, NULL},
	{SDLK_F15, "", NULL, NULL},
	{SDLK_RSHIFT, "", NULL, NULL},
	{SDLK_LSHIFT, "", NULL, NULL},
	{SDLK_RALT, "", NULL, NULL},
	{SDLK_LALT, "", NULL, NULL},
	{SDLK_RCTRL, "", NULL, NULL},
	{SDLK_LCTRL, "", NULL, NULL},
	{SDLK_RMETA, "", NULL, NULL},
	{SDLK_LMETA, "", NULL, NULL},
	{SDLK_NUMLOCK, "", NULL, NULL},
	{SDLK_CAPSLOCK, "", NULL, NULL},
	{SDLK_SCROLLOCK, "", NULL, NULL},
	{SDLK_LSUPER, "", NULL, NULL},
	{SDLK_RSUPER, "", NULL, NULL},
	{SDLK_HELP, "?", NULL, NULL},
	{SDLK_PRINT, "", NULL, NULL},
	{SDLK_SYSREQ, "", NULL, NULL},
	{SDLK_BREAK, "", NULL, NULL},
	{SDLK_MENU, "", NULL, NULL},
	{SDLK_POWER, "", NULL, NULL},
	{SDLK_EURO, "", NULL, NULL},
	{SDLK_0, "0", NULL, ")"},  /* XXX XXX XXX The CTRL-number keys need to be */
	{SDLK_1, "1", NULL, "!"},  /* defined since they represent digging for    */
	{SDLK_2, "2", NULL, "@"},  /* some people!. Really, this whole table      */
	{SDLK_3, "3", NULL, "#"},  /* should be replaced with something cleaner   */
	{SDLK_4, "4", NULL, "$"},  /* and an SDL pref file should be created.     */
	{SDLK_5, "5", NULL, "%"},
	{SDLK_6, "6", NULL, "^"},
	{SDLK_7, "7", NULL, "&"},
	{SDLK_8, "8", NULL, "*"},
	{SDLK_9, "9", NULL, "("},
	{SDLK_SEMICOLON, ";", NULL, ":"},
	{SDLK_COMMA, ",", NULL, "<"},
	{SDLK_PERIOD, ".", NULL, ">"},
	{SDLK_BACKSLASH, "\\", NULL, "|"},
	{SDLK_BACKQUOTE, "`", NULL, "~"},
	{SDLK_LEFTBRACKET, "[", NULL, "{"},
	{SDLK_RIGHTBRACKET, "]", NULL, "}"},
	{SDLK_MINUS, "-", NULL, "_"},
	{SDLK_EQUALS, "=", NULL, "+"},
	{SDLK_SLASH, "/", NULL, "?"},
	{SDLK_UNKNOWN, NULL, NULL, NULL} /* terminator */
};

void Multikeypress(char *k)
{
	printf("zog : '%s'\n", k);
	while (*k) Term_keypress(*k++);
}

int IsMovement(SDLKey k)
{
	switch (k)
	{
	case SDLK_UP:
	case SDLK_DOWN:
	case SDLK_RIGHT:
	case SDLK_LEFT:
	case SDLK_INSERT:
	case SDLK_HOME:
	case SDLK_END:
	case SDLK_PAGEUP:
	case SDLK_PAGEDOWN:
	case SDLK_KP0:
	case SDLK_KP1:
	case SDLK_KP2:
	case SDLK_KP3:
	case SDLK_KP4:
	case SDLK_KP5:
	case SDLK_KP6:
	case SDLK_KP7:
	case SDLK_KP8:
	case SDLK_KP9:
		return TRUE;

	default:
		return FALSE;
	}
	return 1234567;  /* all good children go to heaven */
}


char *SDL_keysymtostr(SDL_keysym *ks)
{
#ifdef bufsize
#error bufsize steps on previous define!
#endif
#define bufsize 1024
	int bufused = 0;

	/* I am returning a pointer to the below variable.
	 * I /think/ this is legal but I am not sure!  XXX XXX XXX
	 * It certainly seems to work fine, at least under GCC.
	 * It can easily be changed to a pointer passed as an argument.
	 */
	static char buf[bufsize];
	Uint8 ch;

	/* cat for strings and app[end] for characters */
#define sdlkcat(a) strncat(buf,(a),bufsize-bufused-1); bufused+=strlen((a));
#define sdlkapp(a) if(bufusedunicode);


	if (IsMovement(ks->sym))
	{
		sprintf(buf, "%c%s%s%s%s_%lX%c", 31,
		        ks->mod & KMOD_CTRL ? "N" : "",
		        ks->mod & KMOD_SHIFT ? "S" : "",
		        "",  /* for future expansion. */
		        ks->mod & KMOD_ALT ? "M" : "",
		        (unsigned long) ks->sym, 13);
		ch = 0;
	}
	else
	{
		if (ks->mod & KMOD_ALT)
		{
			sdlkapp('');
		}
		ch = ks->unicode;

	}

	if (ch) sdlkapp(ch);

	return buf;


#undef bufsize
#undef sdlkcat
#undef sdlkapp

} /* SDL_keystring */



/* Cursor hack, for testing of ideas. XXX XXX XXX */

SDL_Surface *sdl_screen_cursor = NULL;
SDL_Rect sdl_screen_cursor_sr;


/* it must be true that w * h * 4 <= maxUint32 */

errr SDL_init_screen_cursor(Uint32 w, Uint32 h)
{
	Uint32 i;

	sdl_screen_cursor_sr.x = sdl_screen_cursor_sr.y = 0;
	sdl_screen_cursor_sr.w = w;
	sdl_screen_cursor_sr.h = h;

	sdl_screen_cursor = NULL;
	sdl_screen_cursor = SDL_CreateRGBSurface(SDL_SRCALPHA, w, h, 32,
	                    0xff000000,
	                    0x00ff0000,
	                    0x0000ff00,
	                    0x00000000);

	if (!sdl_screen_cursor) return -1;

	SDL_SetAlpha(sdl_screen_cursor, SDL_SRCALPHA | SDL_RLEACCEL, 0x80);
	for (i = 0; i < w*h*4; ++i)
	{
		((Uint8 *)(sdl_screen_cursor->pixels))[i] = !(i & 2) ? 0x80 : 0xFF;
	}

	return 0;
}

errr SDL_DrawCursor(SDL_Surface *dst, SDL_Rect *dr)
{
	if (!dst || !dr || !sdl_screen_cursor) return -1;
	if (SDL_BlitSurface(sdl_screen_cursor, &sdl_screen_cursor_sr, dst, dr)) return -1;
	SDL_UpdateRect(dst, dr->x, dr->y, dr->w, dr->h);
	return 0;
}

#endif
tome-235-src/src/q_dragons.c0000644000076400017500000000706511012107763013606 0ustar  dgdg#undef cquest
#define cquest (quest[QUEST_DRAGONS])

bool quest_dragons_gen_hook(char *fmt)
{
	int x, y, i;
	int xstart = 2;
	int ystart = 2;

	if (p_ptr->inside_quest != QUEST_DRAGONS) return FALSE;

	/* Just in case we didnt talk the the mayor */
	if (cquest.status == QUEST_STATUS_UNTAKEN)
		cquest.status = QUEST_STATUS_TAKEN;

	/* Start with perm walls */
	for (y = 0; y < cur_hgt; y++)
	{
		for (x = 0; x < cur_wid; x++)
		{
			cave_set_feat(y, x, FEAT_PERM_SOLID);
		}
	}

	dun_level = quest[p_ptr->inside_quest].level;

	/* Set the correct monster hook */
	set_mon_num_hook();

	/* Prepare allocation table */
	get_mon_num_prep();

	init_flags = INIT_CREATE_DUNGEON;
	process_dungeon_file(NULL, "dragons.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE);
	dungeon_flags2 |= DF2_NO_GENO;

	/* Place some columns */
	for (i = 35; i > 0; )
	{
		int flags;
		y = rand_int(21) + 3;
		x = rand_int(31) + 3;
		/* Bar columns on even squares so the whole level is guaranteed to be
		   accessible */
		flags = f_info[cave[y][x].feat].flags1;
		if (!(flags % 2) && !(flags & FF1_PERMANENT) && (flags & FF1_FLOOR))
		{
			--i;
			cave_set_feat(y, x, FEAT_MOUNTAIN);
		}
	}

	/* Place some random dragons */
	for (i = 25; i > 0; )
	{
		int flags;
		y = rand_int(21) + 3;
		x = rand_int(31) + 3;
		flags = f_info[cave[y][x].feat].flags1;
		if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR))
		{
			/*                       blue, white, red, black, bronze, gold, green, multi-hued */
			int baby_dragons[8] = {163, 164, 167, 166, 218, 219, 165, 204};
			int young_dragons[8] = {459, 460, 563, 546, 462, 559, 461, 556};
			int mature_dragons[8] = {560, 549, 589, 592, 562, 590, 561, 593};
			int happy_dragons[8] = {601, 617, 644, 624, 602, 645, 618, 675};

			int chance, dragon, color;

			color = rand_int(8);
			chance = rand_int(100);
			if (chance == 0)
				dragon = happy_dragons[color];
			else if (chance < 33)
				dragon = baby_dragons[color];
			else if (chance < 66)
				dragon = young_dragons[color];
			else
				dragon = mature_dragons[color];

			--i;
			place_monster_one(y, x, dragon, 0, magik(33), MSTATUS_ENEMY);
		}
	}

	process_hooks_restart = TRUE;

	return TRUE;
}

bool quest_dragons_death_hook(char *fmt)
{
	int i, mcnt = 0;

	if (p_ptr->inside_quest != QUEST_DRAGONS) return FALSE;

	/* Process the monsters (backwards) */
	for (i = m_max - 1; i >= 1; i--)
	{
		/* Access the monster */
		monster_type *m_ptr = &m_list[i];

		/* Ignore "dead" monsters */
		if (!m_ptr->r_idx) continue;

		if (m_ptr->status <= MSTATUS_ENEMY) mcnt++;
	}

	/* Nobody left ? */
	if (mcnt <= 1)
	{
		quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
		del_hook(HOOK_MONSTER_DEATH, quest_dragons_death_hook);
		del_hook(HOOK_GEN_QUEST, quest_dragons_gen_hook);
		process_hooks_restart = TRUE;

		cmsg_print(TERM_YELLOW, "Gondolin is safer now.");
		return (FALSE);
	}
	return FALSE;
}

bool quest_dragons_finish_hook(char *fmt)
{
	s32b q_idx;

	q_idx = get_next_arg(fmt);

	if (q_idx != QUEST_DRAGONS) return FALSE;

	c_put_str(TERM_YELLOW, "Thank you for killing the dragons!", 8, 0);
	c_put_str(TERM_YELLOW, "You can use the cave as your house as a reward.", 9, 0);

	/* Continue the plot */
	*(quest[q_idx].plot) = QUEST_EOL;

	return TRUE;
}

bool quest_dragons_init_hook(int q_idx)
{
	if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_MONSTER_DEATH, quest_dragons_death_hook, "dragons_monster_death");
		add_hook(HOOK_QUEST_FINISH, quest_dragons_finish_hook, "dragons_finish");
		add_hook(HOOK_GEN_QUEST, quest_dragons_gen_hook, "dragons_geb");
	}
	return (FALSE);
}
tome-235-src/src/q_narsil.c0000644000076400017500000000551411012107763013436 0ustar  dgdg#undef cquest
#define cquest (quest[QUEST_NARSIL])

bool quest_narsil_move_hook(char *fmt)
{
	s32b y, x;
	cave_type *c_ptr;
	int i;
	object_type *o_ptr;

	y = get_next_arg(fmt);
	x = get_next_arg(fmt);
	c_ptr = &cave[y][x];

	if (cquest.status != QUEST_STATUS_TAKEN) return FALSE;

	/* The castle of Aragorn */
	if ((c_ptr->feat != FEAT_SHOP) || (c_ptr->special != 14)) return FALSE;

	/* Look out for Narsil */
	for (i = 0; i < INVEN_TOTAL; i++)
	{
		o_ptr = &p_ptr->inventory[i];

		if (!o_ptr->k_idx) continue;

		if (o_ptr->name1 == ART_NARSIL) break;
	}

	if (i == INVEN_TOTAL) return FALSE;

	cmsg_print(TERM_YELLOW, "I heard that the broken sword had been found!");
	cmsg_print(TERM_YELLOW, "I thought it was only a rumor... until now.");
	cmsg_print(TERM_YELLOW, "What you have is really the sword that was broken.");
	cmsg_print(TERM_YELLOW, "I will get it reforged...");
	cmsg_print(TERM_L_BLUE, "Aragorn leaves for a few hours then comes back...");
	cmsg_print(TERM_YELLOW, "Here it is, Anduril, the sword that was forged and is");
	cmsg_print(TERM_YELLOW, "reforged again. Take it; you will surely need it for your quest.");

	object_prep(o_ptr, lookup_kind(TV_SWORD, SV_LONG_SWORD));
	o_ptr->name1 = ART_ANDURIL;
	apply_magic(o_ptr, -1, TRUE, TRUE, TRUE);
	object_aware(o_ptr);
	object_known(o_ptr);
	inven_item_describe(i);
	inven_item_optimize(i);

	/* Window stuff */
	p_ptr->window |= (PW_EQUIP | PW_PLAYER | PW_INVEN);

	/* Continue the plot */
	cquest.status = QUEST_STATUS_FINISHED;

	del_hook(HOOK_MOVE, quest_narsil_move_hook);
	process_hooks_restart = TRUE;

	return TRUE;
}
bool quest_narsil_dump_hook(char *fmt)
{
	if (cquest.status >= QUEST_STATUS_COMPLETED)
	{
		fprintf(hook_file, "\n The sword that was broken is now reforged.");
	}
	return (FALSE);
}
bool quest_narsil_identify_hook(char *fmt)
{
	if (cquest.status == QUEST_STATUS_UNTAKEN)
	{
		int i;
		object_type *o_ptr;
		s32b item;

		item = get_next_arg(fmt);

		/* Inventory */
		if (item >= 0)
		{
			o_ptr = &p_ptr->inventory[item];
		}

		/* Floor */
		else
		{
			o_ptr = &o_list[0 - item];
		}

		if (o_ptr->name1 == ART_NARSIL)
		{
			cquest.status = QUEST_STATUS_TAKEN;

			for (i = 0; i < 5; i++)
			{
				if (quest[QUEST_NARSIL].desc[i][0] != '\0')
				{
					cmsg_print(TERM_YELLOW, quest[QUEST_NARSIL].desc[i]);
				}
			}

			add_hook(HOOK_MOVE, quest_narsil_move_hook, "narsil_move");
			del_hook(HOOK_IDENTIFY, quest_narsil_identify_hook);
			process_hooks_restart = TRUE;
		}
	}

	return (FALSE);
}
bool quest_narsil_init_hook(int q_idx)
{
	if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_MOVE, quest_narsil_move_hook, "narsil_move");
	}
	if (cquest.status == QUEST_STATUS_UNTAKEN) add_hook(HOOK_IDENTIFY, quest_narsil_identify_hook, "narsil_id");
	add_hook(HOOK_CHAR_DUMP, quest_narsil_dump_hook, "narsil_dump");
	return (FALSE);
}
tome-235-src/src/cmovie.c0000644000076400017500000002103211012107763013101 0ustar  dgdg/* File: cmovie.c */

/* Purpose: play cmovie files -DarkGod-Improv- */

#include "angband.h"

/*
 * Play a given cmovie
 */
s16b do_play_cmovie(cptr cmov_file)
{
	FILE *fff;

	int y, line = 0, x;
	int delay;

	char *s;

	char buf[1024];
	char cbuf[90];
	char ch;

	char mode = 0;


	/* Cmovie files are moved to the user directory on the multiuser systems */

	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_CMOV, cmov_file);

	/* File type is "TEXT" */
	FILE_TYPE(FILE_TYPE_TEXT);

	/* Grab permission */
	/* safe_setuid_grab(); */

	/* Read the file */
	fff = my_fopen(buf, "r");

	/* Drop permission */
	/* safe_setuid_drop(); */

	/* Failure */
	if (!fff) return ( -1);

	/* Save screen */
	character_icky = TRUE;
	Term_save();
	Term_clear();

	/* Give some usefull info */
	prt("While viewing the movie you can press Escape to exit, t/Space to switch between", 0, 0);
	prt("fluid more and step by step mode and any other key to step a frame in step by", 1, 0);
	prt("step mode.", 2, 0);
	prt("You can press D to do an html screenshot of the current frame.", 3, 0);
	prt("You can also use + and - to speed up/down the playing speed.", 5, 0);
	prt("Press any key when ready.", 8, 0);

	inkey();

	Term_clear();

	line = -1;

	delay = 1;

	/* Init to white */
	for (x = 0; x < 80; x++)
	{
		cbuf[x] = 'w';
	}

	/* Parse */
	while (0 == my_fgets(fff, buf, 1024))
	{
		/* Do not wait */
		inkey_scan = TRUE;
		ch = inkey();

		/* Stop */
		if (ch == ESCAPE) break;

		/* Change mode */
		else if (ch == 't')
		{
			mode = FALSE;
		}
		else if (ch == ' ')
		{
			mode = TRUE;
		}

		/* Change speed */
		else if (ch == '+')
		{
			delay--;
			if (delay < 0) delay = 0;
		}
		else if (ch == '-')
		{
			delay++;
			if (delay > 5) delay = 5;
		}
		else if (ch == 'D')
		{
			do_cmd_html_dump();
		}

		line++;

		/* Skip comments and blank lines */
		if (!buf[0] || (buf[0] == '#')) continue;

		/* Verify correct "colon" format */
		if (buf[1] != ':') break;

		/* Clean screen */
		if (buf[0] == 'C')
		{
			Term_clear();

			/* Next */
			continue;
		}

		/* Displays a textbox */
		if (buf[0] == 'B')
		{
			int len = strlen(buf + 2);

			/* Clear the line */
			Term_erase(0, 0, 255);

			/* Display the message */
			c_put_str(TERM_VIOLET, "###", 0, 0);
			c_put_str(TERM_ORANGE, buf + 2, 0, 3);
			c_put_str(TERM_VIOLET, "###", 0, 3 + len);
			c_put_str(TERM_WHITE, "(more)", 0, 6 + len);

			/* Next */
			continue;
		}

		/* Wait a key */
		if (buf[0] == 'W')
		{
			inkey();

			/* Next */
			continue;
		}

		/* Sleep */
		if (buf[0] == 'S')
		{
			long msec;

			/* Scan for the values */
			if (1 != sscanf(buf + 2, "%ld:", &msec))
			{
				return ( -2);
			}

			if (!mode)
			{
				Term_xtra(TERM_XTRA_DELAY, msec);
			}
			else
			{
				bool stop = FALSE;

				while (TRUE)
				{
					ch = inkey();

					/* Stop */
					if (ch == ESCAPE)
					{
						stop = TRUE;
						break;
					}
					/* Change mode */
					else if (ch == 't')
					{
						mode = FALSE;
						break;
					}
					/* Change mode */
					else if (ch == ' ')
					{
						if (mode) continue;
						mode = TRUE;
						break;
					}
					/* Change speed */
					else if (ch == '+')
					{
						delay--;
						if (delay < 0) delay = 0;
					}
					else if (ch == '-')
					{
						delay++;
						if (delay > 5) delay = 5;
					}
					else if (ch == 'D')
					{
						do_cmd_html_dump();
					}
					else break;
				}
				if (stop) break;
			}

			/* Next */
			continue;
		}

		/* Get color for the NEXT L line */
		if (buf[0] == 'E')
		{
			/* Find the colon before the name */
			s = strchr(buf + 2, ':');

			/* Verify that colon */
			if (!s) return ( -2);

			/* Nuke the colon, advance to the name */
			*s++ = '\0';

			/* Paranoia -- require a name */
			if (!*s) return ( -2);

			/* Get the index */
			y = atoi(buf + 2);

			C_COPY(cbuf, s, 80, char);

			/* Next... */
			continue;
		}

		/* Print a line */
		if (buf[0] == 'L')
		{
			/* Find the colon before the name */
			s = strchr(buf + 2, ':');

			/* Verify that colon */
			if (!s) return ( -2);

			/* Nuke the colon, advance to the name */
			*s++ = '\0';

			/* Paranoia -- require a name */
			if (!*s) return ( -2);

			/* Get the index */
			y = atoi(buf + 2);

			for (x = 0; x < 80; x++)
			{
				Term_putch(x, y, color_char_to_attr(cbuf[x]), s[x]);

				/* Reinit to white */
				cbuf[x] = 'w';
			}
			Term_redraw_section(0, y, 79, y);

			/* Next... */
			continue;
		}

		/* Update 1 char */
		if (buf[0] == 'P')
		{
			int x, y, a, c;

			/* Scan for the values */
			if (4 != sscanf(buf + 2, "%d:%d:%d:%d",
			                &x, &y, &c, &a))
			{
				a = 'w';
				if (3 != sscanf(buf + 2, "%d:%d:%d",
				                &x, &y, &c)) return ( -2);
			}

			Term_putch(x, y, color_char_to_attr(cbuf[x]), c);
			Term_redraw_section(x, y, x + 1, y + 1);

			/* Next... */
			continue;
		}
	}

	/* Load screen */
	Term_load();
	character_icky = FALSE;

	/* Close */
	my_fclose(fff);

	return (0);
}


/*
 * Start the recording of a cmovie
 */
void do_record_cmovie(cptr cmovie)
{
	char buf[1024];
	int fd = -1;
	int y;


	/* Build the filename */
	path_build(buf, 1024, ANGBAND_DIR_CMOV, cmovie);

	/* File type is "TEXT" */
	FILE_TYPE(FILE_TYPE_TEXT);

	/* Grab permission */
	/* safe_setuid_grab(); */

	/* Check for existing file */
	fd = fd_open(buf, O_RDONLY);

	/* Drop permission */
	/* safe_setuid_drop(); */

	/* Existing file */
	if (fd >= 0)
	{
		char out_val[160];

		/* Close the file */
		(void)fd_close(fd);

		/* Build query */
		(void)sprintf(out_val, "Replace existing file %s? ", cmovie);

		/* Ask */
		if (get_check(out_val)) fd = -1;
	}

	/* Be sure */
	if (!get_check("Ready to record(Press ctrl+D to enter a textual note while recording)?")) return;

	/* Grab privs */
	/* safe_setuid_grab(); */

	/* Open the non-existing file */
	if (fd < 0) movfile = my_fopen(buf, "w");

	/* And drop them */
	/* safe_setuid_drop(); */

	/* Invalid file */
	if (movfile == NULL)
	{
		msg_format("Cmovie recording failed!");

		return;
	}

	/* First thing: Record clear screen then enable the recording */
	fprintf(movfile, "# Generated by %s %ld.%ld.%ld\n",
	        game_module, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
	fprintf(movfile, "C:\n");
	last_paused = 0;
	do_movies = 1;
	cmovie_init_second();

	/* Mega Hack, get the screen */
	for (y = 0; y < Term->hgt; y++)
	{
		cmovie_record_line(y);
	}
}


/*
 * Stop the recording
 */
void do_stop_cmovie()
{
	if (do_movies == 1)
	{
		do_movies = 0;
		my_fclose(movfile);
	}
}


/*
 * Start a cmovie
 */
void do_start_cmovie()
{
	char name[90], rname[94];


	/* Should never happen */
	if (do_movies == 1) return;

	/* Default */
	sprintf(name, "%s", player_base);

	if (get_string("Cmovie name: ", name, 80))
	{
		if (name[0] && (name[0] != ' '))
		{
			sprintf(rname, "%s.cmv", name);

			if (get_check("Record(y), Play(n)?")) do_record_cmovie(rname);
			else do_play_cmovie(rname);
		}
	}
}


void cmovie_clean_line(int y, char *abuf, char *cbuf)
{
	const byte *ap = Term->scr->a[y];
	const char *cp = Term->scr->c[y];

	byte a;
	char c;

	int x;
	int wid, hgt;
	int screen_wid, screen_hgt;


	/* Retrieve current screen size */
	Term_get_size(&wid, &hgt);

	/* Calculate the size of dungeon map area */
	screen_wid = wid - (COL_MAP + 1);
	screen_hgt = hgt - (ROW_MAP + 1);

	/* For the time being, assume 80 column display XXX XXX XXX */
	for (x = 0; x < wid; x++)
	{
		/* Convert dungeon map into default attr/chars */
		if (!character_icky &&
		                ((x - COL_MAP) >= 0) &&
		                ((x - COL_MAP) < screen_wid) &&
		                ((y - ROW_MAP) >= 0) &&
		                ((y - ROW_MAP) < screen_hgt))
		{
			/* Retrieve default attr/char */
			map_info_default(y + panel_row_prt, x + panel_col_prt, &a, &c);

			abuf[x] = conv_color[a & 0xf];

			if (c == '\0') cbuf[x] = ' ';
			else cbuf[x] = c;
		}

		else
		{
			abuf[x] = conv_color[ap[x] & 0xf];
			cbuf[x] = cp[x];
		}
	}

	/* Null-terminate the prepared strings */
	abuf[x] = '\0';
	cbuf[x] = '\0';
}


/*
 * Write a record of a screen row into a cmovie file
 */
void cmovie_record_line(int y)
{
	char abuf[256];
	char cbuf[256];

	cmovie_clean_line(y, abuf, cbuf);

	/* Write a colour record */
	fprintf(movfile, "E:%d:%.80s\n", y, abuf);

	/* Write a char record */
	fprintf(movfile, "L:%d:%.80s\n", y, cbuf);
}


/*
 * Record a "text box"
 */
void do_cmovie_insert()
{
	char buf[81] = "";

	/* Dont record */
	do_movies = 2;

	while (get_string("Textbox(ESC to end): ", buf, 80))
	{
		fprintf(movfile, "B:%s\nW:\n", buf);
		buf[0] = '\0';
	}

	/* We reinit the time as to not count the time the user needed ot enter the text */
	cmovie_init_second();

	/* Continue recording */
	do_movies = 1;
}
tome-235-src/src/q_haunted.c0000644000076400017500000000646211012107763013601 0ustar  dgdg#undef cquest
#define cquest (quest[QUEST_HAUNTED])

bool quest_haunted_gen_hook(char *fmt)
{
	int x, y, i;
	int xstart = 2;
	int ystart = 2;

	if (p_ptr->inside_quest != QUEST_HAUNTED) return FALSE;

	/* Just in case we didnt talk the the mayor */
	if (cquest.status == QUEST_STATUS_UNTAKEN)
		cquest.status = QUEST_STATUS_TAKEN;

	/* Start with perm walls */
	for (y = 0; y < cur_hgt; y++)
	{
		for (x = 0; x < cur_wid; x++)
		{
			cave_set_feat(y, x, FEAT_PERM_SOLID);
		}
	}

	dun_level = quest[p_ptr->inside_quest].level;

	/* Set the correct monster hook */
	set_mon_num_hook();

	/* Prepare allocation table */
	get_mon_num_prep();

	init_flags = INIT_CREATE_DUNGEON;
	process_dungeon_file(NULL, "haunted.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE);
	dungeon_flags2 |= DF2_NO_GENO;

	/* Place some ghosts */
	for (i = 12; i > 0; )
	{
		int flags;
		y = rand_int(21) + 3;
		x = rand_int(31) + 3;
		flags = f_info[cave[y][x].feat].flags1;
		if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR))
		{
			place_monster_one(y, x, 477, 0, FALSE, MSTATUS_ENEMY);
			--i;
		}
	}

	/* Place some random monsters to haunt us */
	for (i = damroll(4, 4); i > 0; )
	{
		int flags;
		y = rand_int(21) + 3;
		x = rand_int(31) + 3;
		flags = f_info[cave[y][x].feat].flags1;
		if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR))
		{
			int monsters[22] = { 65, 100, 124, 125, 133, 231, 273, 327, 365, 416, 418,
			                     507, 508, 533, 534, 553, 554, 555, 577, 607, 622, 665};
			int monster = monsters[rand_int(22)];
			place_monster_one(y, x, monster, 0, FALSE, MSTATUS_ENEMY);
			--i;
		}
	}

	/* Place some random traps */
	for (i = 10 + damroll(4, 4); i > 0; )
	{
		int flags;
		y = rand_int(21) + 3;
		x = rand_int(31) + 3;
		flags = f_info[cave[y][x].feat].flags1;
		if (!(flags & FF1_PERMANENT) && (flags & FF1_FLOOR))
		{
			--i;
			place_trap(y, x);
		}
	}

	process_hooks_restart = TRUE;

	return TRUE;
}

bool quest_haunted_death_hook(char *fmt)
{
	int i, mcnt = 0;

	if (p_ptr->inside_quest != QUEST_HAUNTED) return FALSE;

	/* Process the monsters (backwards) */
	for (i = m_max - 1; i >= 1; i--)
	{
		/* Access the monster */
		monster_type *m_ptr = &m_list[i];

		/* Ignore "dead" monsters */
		if (!m_ptr->r_idx) continue;

		if (m_ptr->status <= MSTATUS_ENEMY) mcnt++;
	}

	/* Nobody left ? */
	if (mcnt <= 1)
	{
		quest[p_ptr->inside_quest].status = QUEST_STATUS_COMPLETED;
		del_hook(HOOK_MONSTER_DEATH, quest_haunted_death_hook);
		del_hook(HOOK_GEN_QUEST, quest_haunted_gen_hook);
		process_hooks_restart = TRUE;

		cmsg_print(TERM_YELLOW, "Minas Anor is safer now.");
		return (FALSE);
	}
	return FALSE;
}

bool quest_haunted_finish_hook(char *fmt)
{
	s32b q_idx;

	q_idx = get_next_arg(fmt);

	if (q_idx != QUEST_HAUNTED) return FALSE;

	c_put_str(TERM_YELLOW, "Thank you for saving us!", 8, 0);
	c_put_str(TERM_YELLOW, "You can use the building as your house as a reward.", 9, 0);

	/* Continue the plot */
	*(quest[q_idx].plot) = QUEST_BETWEEN;

	return TRUE;
}

bool quest_haunted_init_hook(int q_idx)
{
	if ((cquest.status >= QUEST_STATUS_UNTAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_MONSTER_DEATH, quest_haunted_death_hook, "haunted_monster_death");
		add_hook(HOOK_QUEST_FINISH, quest_haunted_finish_hook, "haunted_finish");
		add_hook(HOOK_GEN_QUEST, quest_haunted_gen_hook, "haunted_geb");
	}
	return (FALSE);
}
tome-235-src/src/makefile.WHICH0000644000076400017500000000524111012107763014020 0ustar  dgdgThis file documents which makefiles you should use for each system.

 * makefile.ami:
   	Amiga makefile.

 * makefile.bcc:
   	Borland C/C++ compiler version 5 makefile.

 * makefile.cyg:
   	A makefile for people using Cygwin for windows.

 * makefile.emx:
   	A makefile for OS/2. You need the EMX packages and ReXX installed for
   	this to work.
 
 * makefile.gdb:
   	Another makefile for DOS, includes debugging symbols so if you're using
   	a DOS-based debugger, things will work. Ideally would be combined into
   	makefile.dos. You want DJGPP and related tools for this.

 * makefile.ibm:
   	Another makefile for people using DOS and DJGPP. Ideally will be rolled
   	into makefile.dos eventually.

 * makefile.lsl:
   	If you want to try to use SVGAlib, this might provide a start.

 * makefile.std:
   	Most Unix users should use this. Currently the only makefile with a real
   	install rule. More instructions are found in the file itself.

 * makefile.wat:
   	Watcom C/C++ for DOS makefile.

 * makefile.win:
   	A makefile for people using Borland C 4.5x for windows.

 * ToME.proj.xml:
   	This one isn't really a makefile, but serves the same purpose. It's a
   	project file for people using CodeWarrior 6 or 7 for the Macintosh.
   	Because the IDE doesn't make things easier, IMHO, here are instructions:
   		- Launch CodeWarrior and choose File-Import Project, then select
   		  ToME.proj.xml in the src folder;
   		- Save your project as ToME.proj where you find readme files;
   		- (Optional) Convert graphics tiles to resource from PICT and put them
   		  in your top folder, i.e. where you find readmes:
   		  	8x8.rsrc - 8x8.bmp, PICT ID 1001
   		  	16x16.rsrc - 16x16.bmp, PICT ID 1002
   		  	mask.rsrc - mask.bmp, PICT ID 1003
   		  If you are using GraphicsConverter, make sure to scale the images to
   		  72 pixel per inch while keeping horizontal and vertical scale factors
   		  to 100%, and *never* add previews;
   		- (Optional) Grab Sound resources from any Angband binaries and save it
   		  as AngSound.rsrc, also in the top folder;
   		- If you don't want graphics and sound effects, remove 8x8.rsrc,
   		  16x16.rsrc, mask.rsrc and AngSound.rsrc from your project;
   		- Please take a look at the comment in A-mac-h.pch for a couple of
   		  source code modifications that may be necessary;
   		- Click on the build button, or choose that from the project menu; and
   		- Hope it works.
   	Carbon compilation requires Carbon SDK 1.1(?) or greater, freely
   	downloadable from Apple. The project file assumes that "Carbon Support"
   	folder should be placed directly beneath your CodeWarrior compiler
   	folder, i.e. where "MacOS Support", "MSL" etc are.
tome-235-src/src/lauxlib.h0000644000076400017500000000545511012107763013277 0ustar  dgdg/*
** $Id: lauxlib.h,v 1.4 2002/01/04 03:31:23 pelpel Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/


#ifndef lauxlib_h
#define lauxlib_h


#include 
#include 

#include "lua.h"


#ifndef LUALIB_API
#define LUALIB_API	extern
#endif


struct luaL_reg {
  const char *name;
  lua_CFunction func;
};


LUALIB_API void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n);
LUALIB_API void luaL_argerror (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *luaL_check_lstr (lua_State *L, int numArg, size_t *len);
LUALIB_API const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def, size_t *len);
LUALIB_API long luaL_check_number (lua_State *L, int numArg);
LUALIB_API long luaL_opt_number (lua_State *L, int numArg, long def);

LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg);
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
LUALIB_API void luaL_checkany (lua_State *L, int narg);

LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...);
LUALIB_API int luaL_findstring (const char *name, const char *const list[]);



/*
** ===============================================================
** some useful macros
** ===============================================================
*/

#define luaL_arg_check(L, cond,numarg,extramsg) if (!(cond)) \
					       luaL_argerror(L, numarg,extramsg)
#define luaL_check_string(L,n)	(luaL_check_lstr(L, (n), NULL))
#define luaL_opt_string(L,n,d)	(luaL_opt_lstr(L, (n), (d), NULL))
#define luaL_check_int(L,n)	((int)luaL_check_number(L, n))
#define luaL_check_long(L,n)	((long)luaL_check_number(L, n))
#define luaL_opt_int(L,n,d)	((int)luaL_opt_number(L, n,d))
#define luaL_opt_long(L,n,d)	((long)luaL_opt_number(L, n,d))
#define luaL_openl(L,a)		luaL_openlib(L, a, (sizeof(a)/sizeof(a[0])))


/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/


#ifndef LUAL_BUFFERSIZE
#define LUAL_BUFFERSIZE	  BUFSIZ
#endif


typedef struct luaL_Buffer {
  char *p;			/* current position in buffer */
  int level;
  lua_State *L;
  char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;

#define luaL_putchar(B,c) \
  ((void)((B)->p < &(B)->buffer[LUAL_BUFFERSIZE] || luaL_prepbuffer(B)), \
   (*(B)->p++ = (char)(c)))

#define luaL_addsize(B,n)	((B)->p += (n))

LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B);
LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B);
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s);
LUALIB_API void luaL_addvalue (luaL_Buffer *B);
LUALIB_API void luaL_pushresult (luaL_Buffer *B);


/* }====================================================== */


#endif


tome-235-src/src/makefile.mingw0000644000076400017500000002577611012107763014316 0ustar  dgdg# This is a makefile for the mingw corss platform compiler
#
# To compile with this makefile, rename it from 'makefile.mingw'
# to 'makefile', then enter the src directory and type
# 'make'.

##
## Before you type "make depend; make", please follow these three steps.
##
## 1. Lua-support and GNU Make ifdef's
##
## The ifdef ... endif struct may not be supported by 'make'
## you are using.  GNU make does and Berkeley make doesn't, for example.
## If it doesn't, you can still manually enable/disable them with minimum
## amount of effort:
## (1) Search for lines containing ifdef and endif (one occurence for each)
## (2) Comment these lines out
## (3-optional) Comment out lines surrounded by these if you are
##     *not* going to compile the game with Lua scripting enabled.
##

# Comment out this line if you don't want Lua scripting
LUA=TRUE

#IRCARGS = -DIRC_SERVER=\"irc.worldirc.org\" -DIRC_PORT=\"6667\" -DIRC_CHANNEL=\"\#tome\"



##
## 2. Installation locations and such
##
## LIBDIR, BINDIR and OWNER should be set appropriately for
## multiuser installations.
##
## If you want to keep it private or don't have root privilege
## required by "make install", set LIBDIR to ./lib/ or an absolute
## path pointing to your lib directory, and don't run "make install".
##
## NOTE: If LIBDIR is set to ./lib/ , you have to cd to parent directory
## of lib before you start the game.
##

# Where lib/ files goes
#LIBDIR = /usr/lib/games/pernband/
# Sysadmins of commercial Unix and/or BSD might prefer this
#LIBDIR = /usr/local/lib/pernband/
# If you like the old default, use this one
LIBDIR = .\lib
# Another example: single user installation using absolute path
#LIBDIR = /home/myloginname/lib/pern/


# Where PernAngband binary goes
#BINDIR = /usr/local/games
# Another common location
#BINDIR = /usr/local/bin

# The game will run suid to this user
#OWNER = games

##
## 3. Some "system" definitions
##
## No changes are needed to compile a version that will run on both
## X11 and Curses, in debugging mode, with maximal warnings, on many
## normal Unix machines of the Sun OS variety (non-solaris).
##
## To use an "alternative" definition, simply "modify" (or "replace")
## the definition below with one that you like.  For example, you can
## change the compiler to "cc", or remove the "debugging" options, or
## remove the X11 or Curses support, etc, as desired.
##
## See also "config.h" and "h-config.h" for important information.
##
## Some "examples" are given below, they can be used by simply
## removing the FIRST column of "#" signs from the "block" of lines
## you wish to use, and commenting out "standard" block below.
##
## This is not intended to be a "good" Makefile, just a "simple" one.
##


#
# This is my compiler of choice, it seems to work most everywhere
#
CC = i386-mingw32msvc-gcc

#
# resource complier
#

WRES = i386-mingw32msvc-windres

#
# Standard version (see main-x11.c and main-gcu.c)
#
# This version supports both "X11" and "curses" in a single executable.
#
# You may have to add various X11 include/library directories to the
# "INCLUDES", if your machine places files in a weird location
# (e.g. -I/usr/X11R6/include, as is almost always the case with
# linux and *BSD). Since we have seen many linux users -- arguably
# the largest unix population -- confused by this, and adding this
# usually doesn't hurt, the default rule has been changed to search
# for /usr/X11R6/include.
#
# You may be able to remove "-ltermcap" on some machines (ex: Solaris).
#
# You may have to replace "-lcurses" with "-lncurses" to use the
# "new curses" library instead of the "old curses" library, and
# you may have to add "-I/usr/include/ncurses" to the "INCLUDES",
# and/or "-DUSE_NCURSES" to "DEFINES".
#
# See "main-gcu.c" and "config.h" for some optional "curses" defines,
# including "USE_GETCH" and "USE_CURS_SET".  Note that "config.h" will
# attempt to "guess" at many of these flags based on your system.
#
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_GCU
#LIBS = -lX11 -lcurses -L/usr/X11R6/lib


##
## For cygwin
##
COPTS = -s -Wall -mno-cygwin -O2 -fno-strength-reduce
INCLUDES =
DEFINES = -DWINDOWS -DUSE_TRANSPARENCY -DUSE_EGO_GRAPHICS -DSUPPORT_GAMMA \
	-DUSE_PRECISE_CMOVIE \
        -DUSE_WINSOCK \
        $(IRCARGS)

LIBS = -mno-cygwin -mwindows -e _mainCRTStartup -lwinmm -lwsock32


##
## Variation -- Only support "main-gtk.c" (not "main-gcu.c, main-x11.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES = `gtk-config --cflags`
#DEFINES = -DUSE_GTK -DUSE_TRANSPARENCY
#LIBS = -lX11 -L/usr/X11R6/lib `gtk-config --libs`

##
## Variation -- Only support "main-x11.c" (not "main-gcu.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11
#LIBS = -lX11 -L/usr/X11R6/lib


##
## Variation -- Only support "main-gcu.c" (not "main-x11.c")
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap


##
## Variation -- Use "main-xaw.c" instead of "main-x11.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_XAW -DUSE_GCU
#LIBS = -lXaw -lXmu -lXt -lX11 -lcurses -ltermcap -L/usr/X11R6/lib


##
## Variation -- Use "main-cap.c" instead of "main-gcu.c"
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_CAP
#LIBS = -lX11 -ltermcap


##
## Variation -- Only work on simple vt100 terminals
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_CAP -DUSE_HARDCODE


##
## Variation -- this might work for Linux 1.1.93 using ncurses-1.8.7.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU
#LIBS = -L/usr/X11R6/lib -lX11 -lncurses


##
## Variation -- this might work better than the suggestion above
##
#COPTS = -Wall -O2 -fomit-frame-pointer
#INCLUDES = -I/usr/X11R6/include -I/usr/include/ncurses
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_TPOSIX -DUSE_CURS_SET
#LIBS = -lX11 -lncurses
#LDFLAGS = -s


##
## Variation -- compile for FreeBSD with ncurses
## -- BSD curses gives you B&W display.
##
#COPTS = -Wall -O2 -fomit-frame-pointer -m486
#INCLUDES = -I/usr/X11R6/include
#DEFINES = -DUSE_X11 -DUSE_GCU -DUSE_NCURSES
#LIBS = -L/usr/X11R6/lib -lX11 -lncurses


##
## Variation -- compile for Solaris
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSOLARIS
#LIBS = -lX11 -lsocket -lcurses


##
## Variation -- compile for SGI Indigo runnig Irix
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DSGI
#LIBS = -lX11 -lcurses -ltermcap -lsun



##
## Variation -- compile for Dec ALPHA OSF/1 v2.0
##
#CC     = cc
##COPTS = -std -O -g3 -Olimit 4000
#COPTS = -std -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU
#LIBS   = -lX11 -lcurses -ltermcap -lrpcsvc


##
## Variation -- compile for Interactive Unix (ISC) systems
##
#COPTS = -Wall -O1 -pipe -g
#INCLUDES =
#DEFINES = -DUSE_X11 -DUSE_GCU -DISC
#LIBS = -lX11 -lcurses -lnsl_s -linet -lcposix


##
## Variation -- Support fat binaries under NEXTSTEP
##
#COPTS = -Wall -O1 -pipe -g -arch m68k -arch i386
#INCLUDES =
#DEFINES = -DUSE_GCU
#LIBS = -lcurses -ltermcap


### End of configurable section ###

#
# The "source" and "object" files.
#

BASESRCS = \
  z-util.c z-virt.c z-form.c z-rand.c z-term.c z-sock.c \
  variable.c tables.c util.c cave.c cmovie.c \
  object1.c object2.c traps.c monster1.c monster2.c monster3.c \
  xtra1.c xtra2.c spells1.c spells2.c \
  melee1.c melee2.c loadsave.c files.c \
  cmd1.c cmd2.c cmd3.c cmd4.c cmd5.c cmd6.c cmd7.c \
  store.c birth.c notes.c help.c \
  status.c randart.c gods.c modules.c \
  wizard1.c wizard2.c levels.c ghost.c \
  generate.c gen_maze.c gen_evol.c dungeon.c init1.c init2.c \
  bldg.c squeltch.c wild.c powers.c plots.c \
  irc.c skills.c \
  readdib.c angband.rc main-win.c main.c

BASEOBJS = \
  z-term.o z-rand.o z-form.o z-virt.o z-util.o z-sock.o \
  main.o main-win.o readdib.o angband.res \
  generate.o gen_maze.o gen_evol.o dungeon.o init1.o init2.o plots.o help.o \
  store.o birth.o wizard1.o wizard2.o bldg.o cmovie.o \
  cmd1.o cmd2.o cmd3.o cmd4.o cmd5.o cmd6.o cmd7.o \
  loadsave.o files.o levels.o notes.o squeltch.o \
  status.o randart.o irc.o skills.o gods.o modules.o \
  xtra1.o xtra2.o spells1.o spells2.o melee1.o melee2.o \
  object1.o object2.o traps.o monster1.o monster2.o monster3.o \
  variable.o tables.o util.o cave.o ghost.o wild.o powers.o

LUASRCS = \
  script.c lua_bind.c \
  w_util.c w_player.c w_z_pack.c w_obj.c w_mnster.c w_spells.c w_quest.c w_play_c.c w_dun.c

TOLUASRCS = \
  lua/lapi.c lua/lcode.c lua/ldebug.c lua/ldo.c lua/lfunc.c lua/lgc.c \
  lua/llex.c lua/lmem.c lua/lobject.c lua/lparser.c lua/lstate.c lua/lstring.c \
  lua/ltable.c lua/ltests.c lua/ltm.c lua/lundump.c lua/lvm.c lua/lzio.c \
  lua/lauxlib.c lua/lbaselib.c lua/ldblib.c lua/liolib.c lua/lstrlib.c \
  lua/tolua_lb.c lua/tolua_rg.c lua/tolua_tt.c lua/tolua_tm.c lua/tolua_gp.c \
  lua/tolua_eh.c lua/tolua_bd.c

LUAOBJS = \
  script.o lua_bind.o \
  w_util.o w_player.o w_z_pack.o w_obj.o w_mnster.o w_spells.o w_quest.o w_play_c.o w_dun.o

TOLUAOBJS = \
  lua/lapi.o lua/lcode.o lua/ldebug.o lua/ldo.o lua/lfunc.o lua/lgc.o \
  lua/llex.o lua/lmem.o lua/lobject.o lua/lparser.o lua/lstate.o lua/lstring.o \
  lua/ltable.o lua/ltests.o lua/ltm.o lua/lundump.o lua/lvm.o lua/lzio.o \
  lua/lauxlib.o lua/lbaselib.o lua/ldblib.o lua/liolib.o lua/lstrlib.o \
  lua/tolua_lb.o lua/tolua_rg.o lua/tolua_tt.o lua/tolua_tm.o lua/tolua_gp.o \
  lua/tolua_eh.o lua/tolua_bd.o

#
# Base sources and objects
#

SRCS = $(BASESRCS)
OBJS = $(BASEOBJS)


#
# Compiler options
#

CFLAGS = $(COPTS) $(INCLUDES) $(DEFINES) -DDEFAULT_PATH=\"$(LIBDIR)\"


#
# Lua support
#

LUAFLAGS = -DUSE_LUA -Ilua -I.

ifdef LUA
SRCS += $(LUASRCS)
OBJS += $(LUAOBJS)
SRCS += $(TOLUASRCS)
OBJS += $(TOLUAOBJS)
CFLAGS += $(LUAFLAGS)
endif


#
# Build the binary. The new base target.
#

TARGET = tome
TOLUA = ./tolua

default: $(TARGET) $(TOLUA)

$(TARGET): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

$(TOLUA): $(TOLUAOBJS) lua/tolua.c lua/tolualua.c
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TOLUAOBJS) lua/tolua.c lua/tolualua.c $(LIBS)

#
# An install rule.
#
install: default
	cp -f $(TARGET) ..


#
# Clean up old junk
#

clean:
	rm -f *.bak $(OBJS)


#
# Generate dependancies automatically
#

depend:
	makedepend $(INCLUDES) $(DEFINES) -D__MAKEDEPEND__ $(SRCS)

.c.o:
	$(CC) $(CFLAGS) -c -o $*.o $*.c

.SUFFIXES: .rc .res
.rc.res:
	$(WRES) $< -O coff -o $@

#
# Lua library compilation rules
#

ifdef LUA
w_mnster.c: monster.pkg $(TOLUA)
	$(TOLUA) -n monster -o w_mnster.c monster.pkg

w_player.c: player.pkg $(TOLUA)
	$(TOLUA) -n player -o w_player.c player.pkg

w_play_c.c: player_c.pkg $(TOLUA)
	$(TOLUA) -n player_c -o w_play_c.c player_c.pkg

w_z_pack.c: z_pack.pkg $(TOLUA)
	$(TOLUA) -n z_pack -o w_z_pack.c z_pack.pkg

w_obj.c: object.pkg $(TOLUA)
	$(TOLUA) -n object -o w_obj.c object.pkg

w_util.c: util.pkg $(TOLUA)
	$(TOLUA) -n util -o w_util.c util.pkg

w_spells.c: spells.pkg $(TOLUA)
	$(TOLUA) -n spells -o w_spells.c spells.pkg

w_quest.c: quest.pkg $(TOLUA)
	$(TOLUA) -n quest -o w_quest.c quest.pkg

w_dun.c: dungeon.pkg $(TOLUA)
	$(TOLUA) -n dungeon -o w_dun.c dungeon.pkg

endif

# DO NOT DELETE THIS LINE - make depend depends on it.
tome-235-src/src/lua_bind.c0000644000076400017500000003272711012107763013411 0ustar  dgdg/* File: lua_bind.c */

/* Purpose: various lua bindings */

/*
 * Copyright (c) 2001 DarkGod
 *
 * This software may be copied and distributed for educational, research, and
 * not for profit purposes provided that this copyright and statement are
 * included in all such copies.
 */

#include "angband.h"

#include "lua.h"
#include "tolua.h"
extern lua_State *L;

/*
 * Get a new magic type
 */
magic_power *new_magic_power(int num)
{
	magic_power *m_ptr;
	C_MAKE(m_ptr, num, magic_power);
	return (m_ptr);
}
magic_power *grab_magic_power(magic_power *m_ptr, int num)
{
	return (&m_ptr[num]);
}
static char *magic_power_info_lua_fct;
static void magic_power_info_lua(char *p, int power)
{
	int oldtop = lua_gettop(L);

	lua_getglobal(L, magic_power_info_lua_fct);
	tolua_pushnumber(L, power);
	lua_call(L, 1, 1);
	strcpy(p, lua_tostring(L, -1));
	lua_settop(L, oldtop);
}
bool get_magic_power_lua(int *sn, magic_power *powers, int max_powers, char *info_fct, int plev, int cast_stat)
{
	magic_power_info_lua_fct = info_fct;
	return (get_magic_power(sn, powers, max_powers, magic_power_info_lua, plev, cast_stat));
}

bool lua_spell_success(magic_power *spell, int stat, char *oups_fct)
{
	int chance;
	int minfail = 0;

	/* Spell failure chance */
	chance = spell->fail;

	/* Reduce failure rate by "effective" level adjustment */
	chance -= 3 * (p_ptr->lev - spell->min_lev);

	/* Reduce failure rate by INT/WIS adjustment */
	chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[stat]] - 1);

	/* Not enough mana to cast */
	if (spell->mana_cost > p_ptr->csp)
	{
		chance += 5 * (spell->mana_cost - p_ptr->csp);
	}

	/* Extract the minimum failure rate */
	minfail = adj_mag_fail[p_ptr->stat_ind[stat]];

	/* Minimum failure rate */
	if (chance < minfail) chance = minfail;

	/* Stunning makes spells harder */
	if (p_ptr->stun > 50) chance += 25;
	else if (p_ptr->stun) chance += 15;

	/* Always a 5 percent chance of working */
	if (chance > 95) chance = 95;

	/* Failed spell */
	if (rand_int(100) < chance)
	{
		if (flush_failure) flush();
		msg_format("You failed to concentrate hard enough!");
		sound(SOUND_FAIL);

		if (oups_fct != NULL)
			exec_lua(format("%s(%d)", oups_fct, chance));
		return (FALSE);
	}
	return (TRUE);
}

/*
 * Create objects
 */
object_type *new_object()
{
	object_type *o_ptr;
	MAKE(o_ptr, object_type);
	return (o_ptr);
}

void end_object(object_type *o_ptr)
{
	FREE(o_ptr, object_type);
}

/*
 * Powers
 */
s16b add_new_power(cptr name, cptr desc, cptr gain, cptr lose, byte level, byte cost, byte stat, byte diff)
{
	/* Increase the size */
	reinit_powers_type(power_max + 1);

	/* Copy the strings */
	C_MAKE(powers_type[power_max - 1].name, strlen(name) + 1, char);
	strcpy(powers_type[power_max - 1].name, name);
	C_MAKE(powers_type[power_max - 1].desc_text, strlen(desc) + 1, char);
	strcpy(powers_type[power_max - 1].desc_text, desc);
	C_MAKE(powers_type[power_max - 1].gain_text, strlen(gain) + 1, char);
	strcpy(powers_type[power_max - 1].gain_text, gain);
	C_MAKE(powers_type[power_max - 1].lose_text, strlen(lose) + 1, char);
	strcpy(powers_type[power_max - 1].lose_text, lose);

	/* Copy the other stuff */
	powers_type[power_max - 1].level = level;
	powers_type[power_max - 1].cost = cost;
	powers_type[power_max - 1].stat = stat;
	powers_type[power_max - 1].diff = diff;

	return (power_max - 1);
}

static char *lua_item_tester_fct;
static bool lua_item_tester(object_type* o_ptr)
{
	int oldtop = lua_gettop(L);
	bool ret;

	lua_getglobal(L, lua_item_tester_fct);
	tolua_pushusertype(L, o_ptr, tolua_tag(L, "object_type"));
	lua_call(L, 1, 1);
	ret = lua_tonumber(L, -1);
	lua_settop(L, oldtop);
	return (ret);
}

void lua_set_item_tester(int tval, char *fct)
{
	if (tval)
	{
		item_tester_tval = tval;
	}
	else
	{
		lua_item_tester_fct = fct;
		item_tester_hook = lua_item_tester;
	}
}

char *lua_object_desc(object_type *o_ptr, int pref, int mode)
{
	static char buf[150];

	object_desc(buf, o_ptr, pref, mode);
	return (buf);
}

/*
 * Monsters
 */

void find_position(int y, int x, int *yy, int *xx)
{
	int attempts = 500;

	do
	{
		scatter(yy, xx, y, x, 6, 0);
	}
	while (!(in_bounds(*yy, *xx) && cave_floor_bold(*yy, *xx)) && --attempts);
}

static char *summon_lua_okay_fct;
bool summon_lua_okay(int r_idx)
{
	int oldtop = lua_gettop(L);
	bool ret;

	lua_getglobal(L, lua_item_tester_fct);
	tolua_pushnumber(L, r_idx);
	lua_call(L, 1, 1);
	ret = lua_tonumber(L, -1);
	lua_settop(L, oldtop);
	return (ret);
}

bool lua_summon_monster(int y, int x, int lev, bool friend, char *fct)
{
	summon_lua_okay_fct = fct;

	if (!friend)
		return summon_specific(y, x, lev, SUMMON_LUA);
	else
		return summon_specific_friendly(y, x, lev, SUMMON_LUA, TRUE);
}

/*
 * Quests
 */
s16b add_new_quest(char *name)
{
	int i;

	/* Increase the size */
	reinit_quests(max_q_idx + 1);
	quest[max_q_idx - 1].type = HOOK_TYPE_LUA;
	strncpy(quest[max_q_idx - 1].name, name, 39);

	for (i = 0; i < 10; i++)
		strncpy(quest[max_q_idx - 1].desc[i], "", 39);

	return (max_q_idx - 1);
}

void desc_quest(int q_idx, int d, char *desc)
{
	if (d >= 0 && d < 10)
		strncpy(quest[q_idx].desc[d], desc, 79);
}

/*
 * Misc
 */
bool get_com_lua(cptr prompt, int *com)
{
	char c;

	if (!get_com(prompt, &c)) return (FALSE);
	*com = c;
	return (TRUE);
}

/* Spell schools */
s16b new_school(int i, cptr name, s16b skill)
{
	schools[i].name = string_make(name);
	schools[i].skill = skill;
	return (i);
}

s16b new_spell(int i, cptr name)
{
	school_spells[i].name = string_make(name);
	school_spells[i].level = 0;
	school_spells[i].level = 0;
	return (i);
}

spell_type *grab_spell_type(s16b num)
{
	return (&school_spells[num]);
}

school_type *grab_school_type(s16b num)
{
	return (&schools[num]);
}

/* Change this fct if I want to switch to learnable spells */
s32b lua_get_level(s32b s, s32b lvl, s32b max, s32b min, s32b bonus)
{
	s32b tmp;

	tmp = lvl - ((school_spells[s].skill_level - 1) * (SKILL_STEP / 10));

	if (tmp >= (SKILL_STEP / 10)) /* We require at least one spell level */
		tmp += bonus;

	tmp = (tmp * (max * (SKILL_STEP / 10)) / (SKILL_MAX / 10));

	if (tmp < 0) /* Shift all negative values, so they map to appropriate integer */
		tmp -= SKILL_STEP / 10 - 1;

	/* Now, we can safely divide */
	lvl = tmp / (SKILL_STEP / 10);

	if (lvl < min)
		lvl = min;

	return lvl;
}

s32b lua_spell_chance(s32b chance, int level, int skill_level, int mana, int cur_mana, int stat)
{
	int minfail;
	/* Reduce failure rate by "effective" level adjustment */
	chance -= 3 * (level - 1);

	/* Reduce failure rate by INT/WIS adjustment */
	chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[stat]] - 1);

	/* Not enough mana to cast */
	if (chance < 0) chance = 0;
	if (mana > cur_mana)
	{
		chance += 15 * (mana - cur_mana);
	}

	/* Extract the minimum failure rate */
	minfail = adj_mag_fail[p_ptr->stat_ind[stat]];

	/*
	        * Non mage characters never get too good
	 */
	if (!(has_ability(AB_PERFECT_CASTING)))
	{
		if (minfail < 5) minfail = 5;
	}

	/* Hack -- Priest prayer penalty for "edged" weapons  -DGK */
	if ((forbid_non_blessed()) && (p_ptr->icky_wield)) chance += 25;

	/* Minimum failure rate */
	if (chance < minfail) chance = minfail;

	/* Stunning makes spells harder */
	if (p_ptr->stun > 50) chance += 25;
	else if (p_ptr->stun) chance += 15;

	/* Always a 5 percent chance of working */
	if (chance > 95) chance = 95;

	/* Return the chance */
	return (chance);
}

s32b lua_spell_device_chance(s32b chance, int level, int base_level)
{
	int minfail;

	/* Reduce failure rate by "effective" level adjustment */
	chance -= (level - 1);

	/* Extract the minimum failure rate */
	minfail = 15 - get_skill_scale(SKILL_DEVICE, 25);
	if (minfail < 0) minfail = 0;

	/* Minimum failure rate */
	if (chance < minfail) chance = minfail;

	/* Stunning makes spells harder */
	if (p_ptr->stun > 50) chance += 25;
	else if (p_ptr->stun) chance += 15;

	/* Always a 5 percent chance of working */
	if (chance > 95) chance = 95;

	/* Return the chance */
	return (chance);
}

/* Cave */
cave_type *lua_get_cave(int y, int x)
{
	return (&(cave[y][x]));
}

void set_target(int y, int x)
{
	target_who = -1;
	target_col = x;
	target_row = y;
}

void get_target(int dir, int *y, int *x)
{
	int ty, tx;

	/* Use the given direction */
	tx = p_ptr->px + (ddx[dir] * 100);
	ty = p_ptr->py + (ddy[dir] * 100);

	/* Hack -- Use an actual "target" */
	if ((dir == 5) && target_okay())
	{
		tx = target_col;
		ty = target_row;
	}
	*y = ty;
	*x = tx;
}

/* Level gen */
void get_map_size(bool full_text, char *name, int *ysize, int *xsize)
{
	*xsize = 0;
	*ysize = 0;
	init_flags = INIT_GET_SIZE;
	process_dungeon_file_full = TRUE;
	if (full_text)
		process_dungeon_file(name, "embeded map script", ysize, xsize, cur_hgt, cur_wid, TRUE);
	else
		process_dungeon_file(NULL, name, ysize, xsize, cur_hgt, cur_wid, TRUE);
	process_dungeon_file_full = FALSE;

}

void load_map(bool full_text, char *name, int *y, int *x)
{
	/* Set the correct monster hook */
	set_mon_num_hook();

	/* Prepare allocation table */
	get_mon_num_prep();

	init_flags = INIT_CREATE_DUNGEON;
	process_dungeon_file_full = TRUE;
	if (full_text)
		process_dungeon_file(name, "embeded map script", y, x, cur_hgt, cur_wid, TRUE);
	else
		process_dungeon_file(NULL, name, y, x, cur_hgt, cur_wid, TRUE);
	process_dungeon_file_full = FALSE;
}

/* Allow lua to use a temporary file */
static char lua_temp_name[1025];
static bool lua_temp_file_alloc = FALSE;
void lua_make_temp_file()
{
	if (lua_temp_file_alloc) return;

	if (path_temp(lua_temp_name, 1024)) return;

	/* Open a new file */
	hook_file = my_fopen(lua_temp_name, "w");
	lua_temp_file_alloc = TRUE;
}

void lua_close_temp_file()
{
	/* Close the file */
	my_fclose(hook_file);
}

void lua_end_temp_file()
{
	/* Remove the file */
	fd_kill(lua_temp_name);
	lua_temp_file_alloc = FALSE;
}

cptr lua_get_temp_name()
{
	return lua_temp_name;
}

bool alloc_room(int by0, int bx0, int ysize, int xsize, int *y1, int *x1, int *y2, int *x2)
{
	int xval, yval, x, y;

	/* Try to allocate space for room.  If fails, exit */
	if (!room_alloc(xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return FALSE;

	/* Get corner values */
	*y1 = yval - ysize / 2;
	*x1 = xval - xsize / 2;
	*y2 = yval + (ysize) / 2;
	*x2 = xval + (xsize) / 2;

	/* Place a full floor under the room */
	for (y = *y1 - 1; y <= *y2 + 1; y++)
	{
		for (x = *x1 - 1; x <= *x2 + 1; x++)
		{
			cave_type *c_ptr = &cave[y][x];
			cave_set_feat(y, x, floor_type[rand_int(100)]);
			c_ptr->info |= (CAVE_ROOM);
			c_ptr->info |= (CAVE_GLOW);
		}
	}
	return TRUE;
}


/* Files */
void lua_print_hook(cptr str)
{
	fprintf(hook_file, str);
}


/*
 * Finds a good random bounty monster
 * Im too lazy to write it in lua since the lua API for monsters is not very well yet
 */

/*
 * Hook for bounty monster selection.
 */
static bool lua_mon_hook_bounty(int r_idx)
{
	monster_race* r_ptr = &r_info[r_idx];


	/* Reject uniques */
	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);

	/* Reject those who cannot leave anything */
	if (!(r_ptr->flags9 & RF9_DROP_CORPSE)) return (FALSE);

	/* Accept only monsters that can be generated */
	if (r_ptr->flags9 & RF9_SPECIAL_GENE) return (FALSE);
	if (r_ptr->flags9 & RF9_NEVER_GENE) return (FALSE);

	/* Reject pets */
	if (r_ptr->flags7 & RF7_PET) return (FALSE);

	/* Reject friendly creatures */
	if (r_ptr->flags7 & RF7_FRIENDLY) return (FALSE);

	/* Accept only monsters that are not breeders */
	if (r_ptr->flags4 & RF4_MULTIPLY) return (FALSE);

	/* Forbid joke monsters */
	if (r_ptr->flags8 & RF8_JOKEANGBAND) return (FALSE);

	/* Accept only monsters that are not good */
	if (r_ptr->flags3 & RF3_GOOD) return (FALSE);

	/* The rest are acceptable */
	return (TRUE);
}

int lua_get_new_bounty_monster(int lev)
{
	int r_idx;

	/*
	 * Set up the hooks -- no bounties on uniques or monsters
	 * with no corpses
	 */
	get_mon_num_hook = lua_mon_hook_bounty;
	get_mon_num_prep();

	/* Set up the quest monster. */
	r_idx = get_mon_num(lev);

	/* Undo the filters */
	get_mon_num_hook = NULL;
	get_mon_num_prep();

	return r_idx;
}

/*
 * Some misc functions
 */
char *lua_input_box(cptr title, int max)
{
	static char buf[80];
	int wid, hgt;

	strcpy(buf, "");
	Term_get_size(&wid, &hgt);
	if (!input_box(title, hgt / 2, wid / 2, buf, (max > 79) ? 79 : max))
		return "";
	return buf;
}

char lua_msg_box(cptr title)
{
	int wid, hgt;

	Term_get_size(&wid, &hgt);
	return msg_box(title, hgt / 2, wid / 2);
}

list_type *lua_create_list(int size)
{
	list_type *l;
	cptr *list;

	MAKE(l, list_type);
	C_MAKE(list, size, cptr);
	l->list = list;
	return l;
}

void lua_delete_list(list_type *l, int size)
{
	int i;

	for (i = 0; i < size; i++)
		string_free(l->list[i]);
	C_FREE(l->list, size, cptr);
	FREE(l, list_type);
}

void lua_add_to_list(list_type *l, int idx, cptr str)
{
	l->list[idx] = string_make(str);
}

void lua_display_list(int y, int x, int h, int w, cptr title, list_type* list, int max, int begin, int sel, byte sel_color)
{
	display_list(y, x, h, w, title, list->list, max, begin, sel, sel_color);
}

/*
 * Level generators
 */
bool level_generate_script(cptr name)
{
	s32b ret = FALSE;

	call_lua("level_generate", "(s)", "d", name, &ret);

	return ret;
}

void add_scripted_generator(cptr name, bool stairs, bool monsters, bool objects, bool miscs)
{
	add_level_generator(name, level_generate_script, stairs, monsters, objects, miscs);
}

/*
 * Gods
 */
s16b add_new_gods(char *name)
{
	int i;

	/* Increase the size */
	reinit_gods(max_gods + 1);
	deity_info[max_gods - 1].name = string_make(name);

	for (i = 0; i < 10; i++)
		strncpy(deity_info[max_gods - 1].desc[i], "", 39);

	return (max_gods - 1);
}

void desc_god(int g_idx, int d, char *desc)
{
	if (d >= 0 && d < 10)
		strncpy(deity_info[g_idx].desc[d], desc, 79);
}
tome-235-src/src/q_nazgul.c0000644000076400017500000000565711012107763013456 0ustar  dgdg#undef cquest
#define cquest (quest[QUEST_NAZGUL])

bool quest_nazgul_gen_hook(char *fmt)
{
	int x = 1, y = 1, try = 10000;
	s32b small;

	small = get_next_arg(fmt);

	if ((cquest.status != QUEST_STATUS_TAKEN) || (small) || (p_ptr->town_num != 1)) return (FALSE);

	/* Find a good position */
	while (try)
	{
		/* Get a random spot */
		y = randint(cur_hgt - 4) + 2;
		x = randint(cur_wid - 4) + 2;

		/* Is it a good spot ? */
		/* Not in player los */
		if ((!los(p_ptr->py, p_ptr->px, y, x)) && cave_empty_bold(y, x)) break;

		/* One less try */
		try--;
	}

	/* Place the nazgul */
	m_allow_special[test_monster_name("Uvatha the Horseman")] = TRUE;
	place_monster_one(y, x, test_monster_name("Uvatha the Horseman"), 0, FALSE, MSTATUS_ENEMY);
	m_allow_special[test_monster_name("Uvatha the Horseman")] = FALSE;

	return FALSE;
}
bool quest_nazgul_finish_hook(char *fmt)
{
	object_type forge, *q_ptr;
	s32b q_idx;

	q_idx = get_next_arg(fmt);

	if (q_idx != QUEST_NAZGUL) return FALSE;

	c_put_str(TERM_YELLOW, "I believe he will not come back! Thank you.", 8, 0);
	c_put_str(TERM_YELLOW, "Some time ago a ranger gave me this.", 9, 0);
	c_put_str(TERM_YELLOW, "I believe it will help you on your quest.", 10, 0);

	q_ptr = &forge;
	object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_ATHELAS));
	q_ptr->found = OBJ_FOUND_REWARD;
	q_ptr->number = 6;
	object_aware(q_ptr);
	object_known(q_ptr);
	q_ptr->ident |= IDENT_STOREB;
	(void)inven_carry(q_ptr, FALSE);

	/* End the plot */
	*(quest[q_idx].plot) = QUEST_NULL;

	del_hook(HOOK_QUEST_FINISH, quest_nazgul_finish_hook);
	process_hooks_restart = TRUE;

	return TRUE;
}
bool quest_nazgul_dump_hook(char *fmt)
{
	if (cquest.status >= QUEST_STATUS_COMPLETED)
	{
		fprintf(hook_file, "\n You saved Bree from a dreadful Nazgul.");
	}
	return (FALSE);
}
bool quest_nazgul_forbid_hook(char *fmt)
{
	s32b q_idx;
	q_idx = get_next_arg(fmt);

	if (q_idx != QUEST_NAZGUL) return (FALSE);

	if (p_ptr->lev < 30)
	{
		c_put_str(TERM_WHITE, "I fear you are not ready for the next quest, come back later.", 8, 0);
		return (TRUE);
	}
	return (FALSE);
}
bool quest_nazgul_death_hook(char *fmt)
{
	s32b r_idx, m_idx;

	m_idx = get_next_arg(fmt);
	r_idx = m_list[m_idx].r_idx;

	if (cquest.status != QUEST_STATUS_TAKEN) return (FALSE);
	if (r_idx != test_monster_name("Uvatha the Horseman")) return (FALSE);

	cquest.status = QUEST_STATUS_COMPLETED;

	del_hook(HOOK_MONSTER_DEATH, quest_nazgul_death_hook);
	process_hooks_restart = TRUE;

	return (FALSE);
}
bool quest_nazgul_init_hook(int q_idx)
{
	if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_MONSTER_DEATH, quest_nazgul_death_hook, "nazgul_death");
		add_hook(HOOK_WILD_GEN, quest_nazgul_gen_hook, "nazgul_gen");
		add_hook(HOOK_QUEST_FINISH, quest_nazgul_finish_hook, "nazgul_finish");
	}
	add_hook(HOOK_CHAR_DUMP, quest_nazgul_dump_hook, "nazgul_dump");
	add_hook(HOOK_INIT_QUEST, quest_nazgul_forbid_hook, "nazgul_forbid");
	return (FALSE);
}
tome-235-src/src/q_shroom.c0000644000076400017500000002240111012107763013447 0ustar  dgdg#undef cquest
#define cquest (quest[QUEST_SHROOM])

bool quest_shroom_speak_hook(char *fmt);

bool quest_shroom_town_gen_hook(char *fmt)
{
	int x = 1, y = 1, try = 10000;
	s32b small;

	small = get_next_arg(fmt);

	/* Generate the shrooms field */
	if ((!small) && (p_ptr->wilderness_y == 21) && (p_ptr->wilderness_x == 33))
	{
		/* Create the field */
		for (x = (cur_wid / 2) - 7; x <= (cur_wid / 2) + 7; x++)
			for (y = (cur_hgt / 2) - 5; y <= (cur_hgt / 2) + 5; y++)
				cave_set_feat(y, x, 181);

		/* Throw in some 'shrooms */
		for (x = 0; x < (cquest.data[1] - cquest.data[0]); x++)
		{
			object_type forge, *q_ptr = &forge;

			object_prep(q_ptr, lookup_kind(TV_FOOD, rand_range(1, 18)));
			q_ptr->number = 1;
			/* Mark them */
			q_ptr->pval2 = 1;
			drop_near(q_ptr, -1, rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5), rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7));
		}

		/* Throw in some dogs ;) */
		y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
		x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
		m_allow_special[test_monster_name("Grip, Farmer Maggot's dog")] = TRUE;
		place_monster_one(y, x, test_monster_name("Grip, Farmer Maggot's dog"), 0, FALSE, MSTATUS_ENEMY);
		m_allow_special[test_monster_name("Grip, Farmer Maggot's dog")] = FALSE;

		y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
		x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
		m_allow_special[test_monster_name("Wolf, Farmer Maggot's dog")] = TRUE;
		place_monster_one(y, x, test_monster_name("Wolf, Farmer Maggot's dog"), 0, FALSE, MSTATUS_ENEMY);
		m_allow_special[test_monster_name("Wolf, Farmer Maggot's dog")] = FALSE;

		y = rand_range((cur_hgt / 2) - 5, (cur_hgt / 2) + 5);
		x = rand_range((cur_wid / 2) - 7, (cur_wid / 2) + 7);
		m_allow_special[test_monster_name("Fang, Farmer Maggot's dog")] = TRUE;
		place_monster_one(y, x, test_monster_name("Fang, Farmer Maggot's dog"), 0, FALSE, MSTATUS_ENEMY);
		m_allow_special[test_monster_name("Fang, Farmer Maggot's dog")] = FALSE;

		msg_print("You hear frenzied barking.");
	}

	/* Generate maggot in town, in daylight */
	if ((bst(HOUR, turn) < 6) || (bst(HOUR, turn) >= 18) || (cquest.status > QUEST_STATUS_COMPLETED) || (small) || (p_ptr->town_num != 1)) return (FALSE);

	/* Find a good position */
	while (try)
	{
		/* Get a random spot */
		y = randint(20) + (cur_hgt / 2) - 10;
		x = randint(20) + (cur_wid / 2) - 10;

		/* Is it a good spot ? */
		/* Not in player los, and avoid shop grids */
		if (!los(p_ptr->py, p_ptr->px, y, x) && cave_empty_bold(y, x) &&
		                cave_plain_floor_bold(y, x)) break;

		/* One less try */
		try--;
	}

	/* Place Farmer Maggot */
	m_allow_special[test_monster_name("Farmer Maggot")] = TRUE;
	place_monster_one(y, x, test_monster_name("Farmer Maggot"), 0, FALSE, MSTATUS_ENEMY);
	m_allow_special[test_monster_name("Farmer Maggot")] = FALSE;

	return FALSE;
}
bool quest_shroom_death_hook(char *fmt)
{
	s32b r_idx, m_idx;

	m_idx = get_next_arg(fmt);
	r_idx = m_list[m_idx].r_idx;

	if (cquest.status > QUEST_STATUS_COMPLETED) return FALSE;

	if ((r_idx == test_monster_name("Wolf, Farmer Maggot's dog")) ||
	                (r_idx == test_monster_name("Grip, Farmer Maggot's dog")) ||
	                (r_idx == test_monster_name("Fang, Farmer Maggot's dog")))
	{
		msg_print("The dog yells a last time and drops dead on the grass.");
	}

	return FALSE;
}
bool quest_shroom_give_hook(char *fmt)
{
	object_type *o_ptr;
	monster_type *m_ptr;
	s32b m_idx, item;

	m_idx = get_next_arg(fmt);
	item = get_next_arg(fmt);

	o_ptr = &p_ptr->inventory[item];
	m_ptr = &m_list[m_idx];

	if (m_ptr->r_idx != test_monster_name("Farmer Maggot")) return (FALSE);

	/* If one is dead .. its bad */
	if ((r_info[test_monster_name("Grip, Farmer Maggot's dog")].max_num == 0) ||
	                (r_info[test_monster_name("Wolf, Farmer Maggot's dog")].max_num == 0) ||
	                (r_info[test_monster_name("Fang, Farmer Maggot's dog")].max_num == 0))
	{
		cquest.status = QUEST_STATUS_FAILED_DONE;
		msg_print("My puppy!  My poor, defenceless puppy...");
		msg_print("YOU MURDERER!  Out of my sight!");
		delete_monster_idx(m_idx);

		del_hook(HOOK_GIVE, quest_shroom_give_hook);
		del_hook(HOOK_CHAT, quest_shroom_speak_hook);
		del_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
		process_hooks_restart = TRUE;
		return TRUE;
	}

	if ((o_ptr->tval != TV_FOOD) || (o_ptr->pval2 != 1)) return (FALSE);

	/* Take a mushroom */
	inven_item_increase(item, -1);
	inven_item_optimize(item);
	cquest.data[0]++;

	if (cquest.data[0] == cquest.data[1])
	{
		object_type forge, *q_ptr;

		msg_print("Oh thank you!");
		msg_print("Take my sling and those mushrooms, may they help you!");
		msg_print("Farmer Maggot heads back to his house.");

		/* Mushrooms */
		q_ptr = &forge;
		object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_CURE_SERIOUS));
		q_ptr->found = OBJ_FOUND_REWARD;
		q_ptr->number = rand_range(15, 20);
		object_aware(q_ptr);
		object_known(q_ptr);
		q_ptr->discount = 100;
		q_ptr->ident |= IDENT_STOREB;
		if (inven_carry_okay(q_ptr))
			inven_carry(q_ptr, FALSE);
		else
			drop_near(q_ptr, 0, p_ptr->py, p_ptr->px);

		/* The sling of farmer maggot */
		q_ptr = &forge;
		object_prep(q_ptr, lookup_kind(TV_BOW, SV_SLING));
		q_ptr->found = OBJ_FOUND_REWARD;
		q_ptr->number = 1;
		q_ptr->name1 = 149;
		apply_magic(q_ptr, -1, TRUE, TRUE, TRUE);
		object_aware(q_ptr);
		object_known(q_ptr);
		q_ptr->discount = 100;
		q_ptr->ident |= IDENT_STOREB;
		(void)inven_carry(q_ptr, FALSE);

		delete_monster_idx(m_idx);

		cquest.status = QUEST_STATUS_FINISHED;

		del_hook(HOOK_GIVE, quest_shroom_give_hook);
		process_hooks_restart = TRUE;
	}
	else
		msg_format("Oh thank you, but you still have %d mushrooms to bring back!", cquest.data[1] - cquest.data[0]);

	return TRUE;
}
bool quest_shroom_speak_hook(char *fmt)
{
	s32b m_idx = get_next_arg(fmt);

	if (m_list[m_idx].r_idx != test_monster_name("Farmer Maggot")) return (FALSE);

	if (cquest.status == QUEST_STATUS_UNTAKEN)
	{
		cptr m_name;

		m_name = get_next_arg_str(fmt);

		msg_format("%^s asks your help.", m_name);
		exec_lua("ingame_help('monster_chat')");
	}
	else
	{
		/* If one is dead .. its bad */
		if ((r_info[test_monster_name("Grip, Farmer Maggot's dog")].max_num == 0) ||
		                (r_info[test_monster_name("Wolf, Farmer Maggot's dog")].max_num == 0) ||
		                (r_info[test_monster_name("Fang, Farmer Maggot's dog")].max_num == 0))
		{
			cquest.status = QUEST_STATUS_FAILED_DONE;
			msg_print("My puppy!  My poor, defenceless puppy...");
			msg_print("YOU MURDERER!  Out of my sight!");
			delete_monster_idx(m_idx);

			del_hook(HOOK_GIVE, quest_shroom_give_hook);
			del_hook(HOOK_CHAT, quest_shroom_speak_hook);
			del_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
			process_hooks_restart = TRUE;
			return TRUE;
		}
		msg_format("You still have %d mushrooms to bring back!", cquest.data[1] - cquest.data[0]);
	}
	return (TRUE);
}
bool quest_shroom_chat_hook(char *fmt)
{
	monster_type *m_ptr;
	s32b m_idx;

	m_idx = get_next_arg(fmt);

	m_ptr = &m_list[m_idx];

	if (m_ptr->r_idx != test_monster_name("Farmer Maggot")) return (FALSE);

	if (cquest.status == QUEST_STATUS_UNTAKEN)
	{
		msg_print("My mushrooms, my mushrooms!");
		msg_print("The rain, a dark horrible rain, began so I had to return to my home.");
		msg_print("But when I came back my dogs were all mad and didn't let me near the field.");
		msg_print("Could you please bring me back all the mushrooms that have grown in my field");
		msg_print("to the west of Bree? Please try to not harm my dogs. They are so lovely...");

		cquest.status = QUEST_STATUS_TAKEN;
		quest[QUEST_SHROOM].init(QUEST_SHROOM);
	}
	else
	{
		/* If one is dead .. its bad */
		if ((r_info[test_monster_name("Grip, Farmer Maggot's dog")].max_num == 0) ||
		                (r_info[test_monster_name("Wolf, Farmer Maggot's dog")].max_num == 0) ||
		                (r_info[test_monster_name("Fang, Farmer Maggot's dog")].max_num == 0))
		{
			cquest.status = QUEST_STATUS_FAILED_DONE;
			msg_print("My puppy!  My poor, defenceless puppy...");
			msg_print("YOU MURDERER!  Out of my sight!");
			delete_monster_idx(m_idx);

			del_hook(HOOK_GIVE, quest_shroom_give_hook);
			del_hook(HOOK_CHAT, quest_shroom_speak_hook);
			del_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook);
			process_hooks_restart = TRUE;
			return TRUE;
		}
		msg_format("You still have %d mushrooms to bring back!", cquest.data[1] - cquest.data[0]);
	}

	return TRUE;
}
bool quest_shroom_init_hook(int q_idx)
{
	/* Get a number of 'shrooms */
	if (!cquest.data[1])
	{
		cquest.data[0] = 0;
		cquest.data[1] = rand_range(7, 14);
		if (wizard) message_add(MESSAGE_MSG, format("Shrooms number %d", cquest.data[1]), TERM_BLUE);
	}

	if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_MONSTER_DEATH, quest_shroom_death_hook, "shroom_death");
		add_hook(HOOK_GIVE, quest_shroom_give_hook, "shroom_give");
		add_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook, "shroom_town_gen");
		add_hook(HOOK_CHAT, quest_shroom_chat_hook, "shroom_chat");
		add_hook(HOOK_MON_SPEAK, quest_shroom_speak_hook, "shroom_speak");
	}
	if (cquest.status == QUEST_STATUS_UNTAKEN)
	{
		add_hook(HOOK_MON_SPEAK, quest_shroom_speak_hook, "shroom_speak");
		add_hook(HOOK_WILD_GEN, quest_shroom_town_gen_hook, "shroom_town_gen");
		add_hook(HOOK_CHAT, quest_shroom_chat_hook, "shroom_chat");
	}
	return (FALSE);
}
tome-235-src/src/main-ami.c0000644000076400017500000022273311012107763013322 0ustar  dgdg/*
 
   File:     main-ami.c
 
   Version:  2.7.9v6 (09.May.96)
 
   Purpose:  Amiga module for Angband with graphics and sound
 
   Author:   Lars Haugseth
   Email:    larshau@ifi.uio.no
   WWW:      http://www.ifi.uio.no/~larshau
 
*/

#define VERSION "Angband 2.7.9v6"

///{ "includes"

#include "angband.h"
#include "sound-ami.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

///}
///{ "macros"

/* Pen number convertion */
#define PEN( p ) ( penconv[ p ] )

/* Graphics pen number convertion */
#define GPEN( p ) ( use_pub ? pubpens[ p ] : p )

/* Failure */
#define FAIL( str ) return ( amiga_fail( str ))

/* Message */
#define MSG( x, y, txt ) amiga_text( x, y, strlen( txt ), 1, txt );

/* Char and attr under cursor */
#define CUR_A ( td->t.scr->a[ td->cursor_ypos ][ td->cursor_xpos ] )
#define CUR_C ( td->t.scr->c[ td->cursor_ypos ][ td->cursor_xpos ] )

///}
///{ "defines"

/* Color to use for cursor */
#define CURSOR_PEN 4

/* Size of graphical tile */
#define TILEW 8
#define TILEH 8

/* Size of tile image */
#define GFXW 256
#define GFXH 256
#define GFXB 32

/* Size of tombstone image */
#define TOMW 512
#define TOMH 168
#define TOMB 64

/* Filename of tile image */
#define MGFX "Angband:xtra/gfx/tiles.raw"

/* Filename of tombstone image */
#define MTOM "Angband:xtra/gfx/tomb.raw"

/* Filename of preferences file */
#define WPRF "Angband:user/settings.prf"

///}
///{ "globals"

/* DisplayID specified with option -m */
char modestr[ 256 ] = "";

/* Font specified with option -f */
char fontstr[ 32 ] = "";

/* Library bases */
struct Library *DiskfontBase = NULL;
struct Library *KeymapBase = NULL;
struct Library *GadToolsBase = NULL;

/* Term data structure */
typedef struct term_data
{
	term t;                   /* Term structure */
	cptr name;                /* Name string */

	BYTE use;                 /* Use this window */

	BYTE cols;                /* Number of columns */
	BYTE rows;                /* Number of rows */

	UWORD wx;                 /* Window x-pos */
	UWORD wy;                 /* Window y-pos */
	UWORD ww;                 /* Window width */
	UWORD wh;                 /* Window height */

	BYTE fw;                  /* Font width */
	BYTE fh;                  /* Font height */
	BYTE fb;                  /* Font baseline */

	struct TextFont *font;    /* Font pointers */

	BYTE ownf;                /* Font is owned by this term */

	struct Window *win;       /* Window pointer */
	struct RastPort *wrp;     /* RastPort of window */
	struct RastPort *rp;      /* RastPort of screen or window */

	struct BitMap *gfxbm;
	struct BitMap *mapbm;
	struct BitMap *mskbm;

	int gfx_w;
	int gfx_h;

	int map_w;
	int map_h;
	int map_x;
	int map_y;

	int mpt_w;
	int mpt_h;

	int cursor_xpos;
	int cursor_ypos;
	int cursor_visible;
	int cursor_lit;
	int cursor_frame;
	int cursor_map;

	int notitle;
	int avoidbar;
}
term_data;

/* Term data for all windows */
static term_data screen;
static term_data mirror;
static term_data recall;
static term_data choice;

/* Window names */
static char screen_name[] = "Main";
static char choice_name[] = "Choice";
static char recall_name[] = "Recall";
static char mirror_name[] = "Mirror";

/* Screen pointers */
static struct Screen *amiscr = NULL;
static struct Screen *pubscr = NULL;

/* Visual info for gadtools menus */
static APTR *visinfo;

/* TextAttr for screen font */
static struct TextAttr ScrAttr, *scrattr = &ScrAttr;

/* Screen DisplayID */
static ULONG scr_m = 0;

/* Last term for cursor */
static term_data *term_curs = NULL;

/* Temporary string */
static char tmpstr[ 256 ];

/* Iconify status of windows */
static int iconified = FALSE;

/* Use intuition menus? */
static int use_menus = TRUE;

/* Use mouseblanking? */
static int blankmouse = FALSE;

/* Window input event */
static struct InputEvent ie;

/* KickStart 3.0+ present */
static int v39 = FALSE;

/* Use a public screen */
static int use_pub = FALSE;

/* Public screen lock */
static int publock = FALSE;

/* Use a backdrop main window */
static int backdrop = FALSE;

/* Use 32 colors on custom screen */
static int deep = FALSE;

/* Invisible pointer for blanking */
static __chip UWORD blankpointer[] = { 0, 0, 0, 0, 0, 0, 0, 0 };

/* Pointer visibility status */
static int pointer_visible = TRUE;

/* Convert textual pens to screen pens */
static UWORD penconv[ 16 ] =
{
	0, 1, 2, 4, 11, 15, 9, 6, 3, 1, 13, 4, 11, 15, 8, 5
};

/* Public screen obtained pens */
static LONG pubpens[ 32 ] =
{
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1
};

/* Default color palette, 16 for graphics, 16 for text */
static ULONG default_colors[ 32 ] =
{
	0x000000, 0xf0e0d0, 0x808080, 0x505050,
	0xe0b000, 0xc0a070, 0x806040, 0x403020,
	0x00a0f0, 0x0000f0, 0x000070, 0xf00000,
	0x800000, 0x9000b0, 0x006010, 0x60f040,

	0x000000, 0xffffff, 0xc7c7c7, 0xff9200,
	0xff0000, 0x00cd00, 0x0000fe, 0xc86400,
	0x8a8a8a, 0xe0e0e0, 0xa500ff, 0xfffd00,
	0xff00bc, 0x00ff00, 0x00c8ff, 0xffcc80
};

/* Palette, 32 bits per gun */
static ULONG palette32[ 32 * 3 + 2 ];

/* Palette, 4 bits per gun */
static UWORD palette4[ 32 ];

/* Version string */
static char ver[] = "$VER: " VERSION " (" __DATE__ ")";

///}
///{ "sound"

#define NSAMPLES 25

struct AmiSound
{
	char *Name;
	int Volume;
	int Channel;
	int Rate;
	int Repeats;
	int Memory;
	struct SoundInfo *Address;
};

static struct AmiSound sound_data[ NSAMPLES ] =
{
	{ "intro.8svx", 64, 0, 0, 1, 0, NULL },  /* Intro */
	{ "hit.8svx", 64, 0, 0, 1, 1, NULL },  /* Hit */
	{ "miss.8svx", 64, 3, 0, 1, 1, NULL },  /* Miss */
	{ "flee.8svx", 64, 1, 0, 1, 1, NULL },  /* Flee */
	{ "drop.8svx", 64, 2, 0, 1, 1, NULL },  /* Drop */
	{ "kill.8svx", 64, 1, 0, 1, 1, NULL },  /* Kill */
	{ "study.8svx", 64, 2, 0, 1, 1, NULL },  /* Level */
	{ "death.8svx", 64, 0, 0, 1, 0, NULL },  /* Death */
	{ "study.8svx", 64, 2, 0, 1, 1, NULL },  /* Study */
	{ "teleport.8svx", 64, 3, 0, 1, 1, NULL },  /* Teleport */
	{ "shoot.8svx", 64, 0, 0, 1, 1, NULL },  /* Shoot */
	{ "quaff.8svx", 64, 1, 0, 1, 1, NULL },  /* Quaff */
	{ "zap.8svx", 64, 3, 0, 1, 1, NULL },  /* Zap */
	{ "walk.8svx", 64, 0, 0, 1, 1, NULL },  /* Walk */
	{ "tpother.8svx", 64, 3, 0, 1, 1, NULL },  /* Teleport Other */
	{ "hitwall.8svx", 64, 3, 0, 1, 1, NULL },  /* Hit Wall */
	{ "eat.8svx", 64, 3, 0, 1, 1, NULL },  /* Eat */
	{ "store1.8svx", 64, 0, 0, 1, 0, NULL },  /* Shopkeeper furious */
	{ "store2.8svx", 64, 0, 0, 1, 0, NULL },  /* Shopkeeper angry */
	{ "store3.8svx", 64, 0, 0, 1, 0, NULL },  /* Shopkeeper glad */
	{ "store4.8svx", 64, 0, 0, 1, 0, NULL },  /* Shopkeeper happy */
	{ "dig.8svx", 64, 0, 0, 1, 1, NULL },  /* Dig */
	{ "opendoor.8svx", 64, 0, 0, 1, 1, NULL },  /* Open door */
	{ "closedoor.8svx", 64, 0, 0, 1, 1, NULL },  /* Close door */
	{ "tplevel.8svx", 64, 0, 0, 1, 0, NULL },  /* Teleport level */
};

static int channel_last[ 4 ] = { -1, -1, -1, -1 };

static int has_sound = FALSE;

///}
///{ "menus"

#define MENUMAX 256

/* Menu userdata indexes */
#define MNU_SCALEDMAP   1001

/* Special offset indexes */
#define MNU_KEYCOM      2001
#define MNU_CKEYCOM     3001
#define MNU_OPTION      4001
#define MNU_HELP        5001

/* Macro for menu userdata keycodes and help */
#define MKC( c ) (void *)( MNU_KEYCOM + c )
#define MCC( c ) (void *)( MNU_CKEYCOM + c )
#define MHL( c ) (void *)( MNU_HELP + c )

struct Menu *menu = NULL;

/* Menu items that comes before the options */
struct NewMenu pre_item[] =
{
	{ NM_TITLE, "Options", 0, 0, 0, 0},
	{ 255, 0, 0, 0, 0, 0 }
};

/* Option menu items, titles of submenus */
struct NewMenu opt_item[] =
{
	{ NM_ITEM, "User Interface", 0, 0, 0, 0 },
	{ NM_ITEM, "Disturbance", 0, 0, 0, 0 },
	{ NM_ITEM, "Inventory", 0, 0, 0, 0 },
	{ NM_ITEM, "Game-Play", 0, 0, 0, 0 },
	{ NM_ITEM, "Efficiency", 0, 0, 0, 0 },
	{ NM_ITEM, "Special", 0, 0, 0, 0 },
	{ NM_ITEM, "Cheating", 0, 0, 0, 0 },
	{ 255, 0, 0, 0, 0, 0 }
};

/* Menu items that comes after the options */
struct NewMenu post_item[] =
{
	/*
	{ NM_ITEM, "Hitpoint Warning", 0, 0, 0, 0 },
	{ NM_SUB, "90%", 0, CHECKIT, ~1, 0 },
	{ NM_SUB, "80%", 0, CHECKIT, ~2, 0 },
	{ NM_SUB, "70%", 0, CHECKIT, ~4, 0 },
	{ NM_SUB, "60%", 0, CHECKIT, ~8, 0 },
	{ NM_SUB, "50%", 0, CHECKIT, ~16, 0 },
	{ NM_SUB, "40%", 0, CHECKIT, ~32, 0 },
	{ NM_SUB, "30%", 0, CHECKIT, ~64, 0 },
	{ NM_SUB, "20%", 0, CHECKIT, ~128, 0 },
	{ NM_SUB, "10%", 0, CHECKIT, ~256, 0 },
	{ NM_SUB, "Off", 0, CHECKIT, ~512, 0 },
	*/

	{ NM_TITLE, "Cmd1", 0, 0, 0, 0 },
	{ NM_ITEM, "a  Aim a wand", 0, 0, 0, MKC('a') },
	{ NM_ITEM, "b  Browse a book", 0, 0, 0, MKC('b') },
	{ NM_ITEM, "c  Close a door", 0, 0, 0, MKC('c') },
	{ NM_ITEM, "d  Drop an item", 0, 0, 0, MKC('d') },
	{ NM_ITEM, "e  Equipment list", 0, 0, 0, MKC('e') },
	{ NM_ITEM, "f  Fire an item", 0, 0, 0, MKC('f') },
	{ NM_ITEM, "g  Stay still", 0, 0, 0, MKC('g') },
	{ NM_ITEM, "i  Inventory list", 0, 0, 0, MKC('i') },
	{ NM_ITEM, "j  Jam a door", 0, 0, 0, MKC('j') },
	{ NM_ITEM, "k  Destroy an item", 0, 0, 0, MKC('k') },
	{ NM_ITEM, "l  Look around", 0, 0, 0, MKC('l') },

	{ NM_TITLE, "Cmd2", 0, 0, 0, 0 },
	{ NM_ITEM, "m  Cast a spell", 0, 0, 0, MKC('m') },
	{ NM_ITEM, "o  Open a door or chest", 0, 0, 0, MKC('o') },
	{ NM_ITEM, "p  Pray a prayer", 0, 0, 0, MKC('p') },
	{ NM_ITEM, "q  Quaff a potion", 0, 0, 0, MKC('q') },
	{ NM_ITEM, "r  Read a scroll", 0, 0, 0, MKC('r') },
	{ NM_ITEM, "s  Search for traps/doors", 0, 0, 0, MKC('s') },
	{ NM_ITEM, "t  Take off equipment", 0, 0, 0, MKC('t') },
	{ NM_ITEM, "u  Use a staff", 0, 0, 0, MKC('u') },
	{ NM_ITEM, "v  Throw an item", 0, 0, 0, MKC('v') },
	{ NM_ITEM, "w  Wear/wield equipment", 0, 0, 0, MKC('w') },
	{ NM_ITEM, "z  Zap a rod", 0, 0, 0, MKC('z') },

	{ NM_TITLE, "Cmd3", 0, 0, 0, 0 },
	{ NM_ITEM, "A  Activate an artifact", 0, 0, 0, MKC('A') },
	{ NM_ITEM, "B  Bash a door", 0, 0, 0, MKC('B') },
	{ NM_ITEM, "C  Character description", 0, 0, 0, MKC('C') },
	{ NM_ITEM, "D  Disarm a trap", 0, 0, 0, MKC('D') },
	{ NM_ITEM, "E  Eat some food", 0, 0, 0, MKC('E') },
	{ NM_ITEM, "F  Fuel your lantern/torch", 0, 0, 0, MKC('F') },
	{ NM_ITEM, "G  Gain new spells/prayers", 0, 0, 0, MKC('G') },
	{ NM_ITEM, "I  Observe an item", 0, 0, 0, MKC('I') },
	{ NM_ITEM, "L  Locate player on map", 0, 0, 0, MKC('L') },
	{ NM_ITEM, "M  Full dungeon map", 0, 0, 0, MKC('M') },
	{ NM_ITEM, "Q  Quit (commit suicide)", 0, 0, 0, MKC('Q') },
	{ NM_ITEM, "R  Rest for a period", 0, 0, 0, MKC('R') },
	{ NM_ITEM, "S  Toggle search mode", 0, 0, 0, MKC('S') },
	{ NM_ITEM, "T  Dig a tunnel", 0, 0, 0, MKC('T') },
	{ NM_ITEM, "V  Version info", 0, 0, 0, MKC('V') },

	{ NM_TITLE, "Cmd4", 0, 0, 0, 0 },
	{ NM_ITEM, "@  Interact with macros", 0, 0, 0, MKC('@') },
	{ NM_ITEM, "%  Interact with visuals", 0, 0, 0, MKC('%') },
	{ NM_ITEM, "&  Interact with colors", 0, 0, 0, MKC('&') },
	{ NM_ITEM, "*  Target monster or location", 0, 0, 0, MKC('*') },
	{ NM_ITEM, "(  Load screen dump", 0, 0, 0, MKC('(') },
	{ NM_ITEM, ")  Dump screen dump", 0, 0, 0, MKC(')') },
	{ NM_ITEM, "{  Inscribe an object", 0, 0, 0, MKC('{') },
	{ NM_ITEM, "}  Uninscribe an object", 0, 0, 0, MKC('}') },
	{ NM_ITEM, "-  Walk (flip pickup)", 0, 0, 0, MKC('-') },

	{ NM_TITLE, "Cmd5", 0, 0, 0, 0 },
	{ NM_ITEM, "+  Dig tunnel", 0, 0, 0, MKC('+') },
	{ NM_ITEM, "=  Set options", 0, 0, 0, MKC('=') },
	{ NM_ITEM, ";  Walk (with pickup)", 0, 0, 0, MKC(';') },
	{ NM_ITEM, ":  Take notes", 0, 0, 0, MKC(':') },
	{ NM_ITEM, "\"  Enter a user pref command", 0, 0, 0, MKC('\"') },
	{ NM_ITEM, ",  Stay still (with pickup)", 0, 0, 0, MKC(',') },
	{ NM_ITEM, "<  Go up staircase", 0, 0, 0, MKC('<') },
	{ NM_ITEM, ".  Run", 0, 0, 0, MKC('.') },
	{ NM_ITEM, ">  Go down staircase", 0, 0, 0, MKC('>') },
	{ NM_ITEM, "/  Identify symbol", 0, 0, 0, MKC('/') },
	{ NM_ITEM, "|  Check uniques", 0, 0, 0, MKC('|') },
	{ NM_ITEM, "~  Check artifacts", 0, 0, 0, MKC('~') },
	{ NM_ITEM, "?  Help", 0, 0, 0, MKC('?') },

	{ NM_TITLE, "Cmd6", 0, 0, 0, 0 },
	{ NM_ITEM, "^f  Repeat level feeling", 0, 0, 0, MCC('f') },
	{ NM_ITEM, "^k  Quit", 0, 0, 0, MCC('k') },
	{ NM_ITEM, "^p  Show previous messages", 0, 0, 0, MCC('p') },
	{ NM_ITEM, "^r  Redraw the screen", 0, 0, 0, MCC('r') },
	{ NM_ITEM, "^s  Save and don't quit", 0, 0, 0, MCC('s') },
	{ NM_ITEM, "^x  Save and quit", 0, 0, 0, MCC('x') },
	{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
	{ NM_ITEM, "Draw dungeon map", "m", 0, 0, (void *)MNU_SCALEDMAP },

	{ NM_TITLE, "Help", 0, 0, 0, 0 },
	{ NM_ITEM, "General Information", 0, 0, 0, MHL('1') },
	{ NM_ITEM, "Creating a Character", 0, 0, 0, MHL('2') },
	{ NM_ITEM, "Exploring the Dungeon", 0, 0, 0, MHL('3') },
	{ NM_ITEM, "Attacking Monsters", 0, 0, 0, MHL('4') },
	{ NM_ITEM, "List of Commands", 0, 0, 0, MHL('5') },
	{ NM_ITEM, "List of Options", 0, 0, 0, MHL('6') },
	{ NM_ITEM, "Version Information", 0, 0, 0, MHL('7') },

	{ NM_END, NULL, 0, 0, 0, 0 },
	{ 255, 0, 0, 0, 0, 0 }
};

/* Menu array */
struct NewMenu newmenu[ MENUMAX ];

///}
///{ "protos"

extern void map_info( int y, int x, byte *ap, char *cp );
extern void center_string( char *buf, cptr str );
errr init_ami( void );
static void init_term( term_data *td );
static term *link_term( term_data *td );
static void free_term( term_data *td );
static char *stripstr( char *src, char *dst );
void request_font( char *str );
void request_mode( char *str );
int read_prefs( void );
static void amiga_open( term *t );
static void amiga_nuke( term *t );
static errr amiga_curs( int x, int y );
static errr amiga_wipe( int x, int y, int n );
static errr amiga_clear( void );
static errr amiga_pict( int x, int y, byte a, char c );
static errr amiga_text( int x, int y, int n, byte a, cptr s );
static errr amiga_xtra( int n, int v );
static errr amiga_flush( int v );
static errr amiga_event( int v );
static errr amiga_react( int v );
static errr amiga_fail( char *msg );
static void cursor_on( term_data *td );
static void cursor_off( term_data *td );
void amiga_tomp( void );
void tomb_str( int y, char *str );
int load_gfx( void );
int conv_gfx( void );
int size_gfx( term_data *td );
void scale_bitmap( struct BitMap *srcbm, int srcw, int srch, struct BitMap *dstbm, int dstw, int dsth );
void remap_bitmap( struct BitMap *srcbm, struct BitMap *dstbm, long *pens, int width, int height );
static void put_gfx( struct RastPort *rp, int x, int y, int chr, int col );
static void put_gfx_map( term_data *td, int x, int y, int c, int a );
static void cursor_anim( void );
void load_palette( void );
static void amiga_map( void );
int init_sound( void );
void free_sound( void );
static void play_sound( int v );
struct BitMap *alloc_bitmap( int width, int height, int depth, ULONG flags, struct BitMap *friend );
void free_bitmap( struct BitMap *bitmap );
int depth_of_bitmap( struct BitMap *bm );
int create_menus( void );
void update_menus( void );
void handle_menupick( int mnum );
void handle_rawkey( UWORD code, UWORD qual, APTR addr );

///}

///{ "init_ami()" - Initialize all Amiga spesific stuff

errr init_ami( void )
{
	char *s;
	int i;
	LONG pen;
	struct DimensionInfo diminfo;
	int pw, ph, maxw, maxh, th, barh;

	/* XXX XXX XXX */
	use_sound = arg_sound;
	use_graphics = arg_graphics;

	/* Term data pointers */
	term_data *ts = &screen;
	term_data *tc = &choice;
	term_data *tr = &recall;
	term_data *tm = &mirror;

	/* Clear the term data */
	init_term( ts );
	init_term( tc );
	init_term( tr );
	init_term( tm );

	/* Always use the main term */
	ts->use = TRUE;

	/* We *must* have kickstart 37 or later */
	if ( IntuitionBase->LibNode.lib_Version < 37 )
		FAIL( "Sorry, this program requires KickStart 2.04 or later." );

	/* Check if we have kickstart 39 or later */
	v39 = ( IntuitionBase->LibNode.lib_Version >= 39 );

	/* Open diskfont.library */
	if (( DiskfontBase = OpenLibrary( "diskfont.library", 0 )) == NULL )
		FAIL( "Unable to open diskfont.library." );

	/* Read preferences file */
	read_prefs();

	/* Initialize keyboard stuff */
	ie.ie_NextEvent = NULL;
	ie.ie_Class = IECLASS_RAWKEY;
	ie.ie_SubClass = 0;
	if (( KeymapBase = OpenLibrary( "keymap.library", 36 )) == NULL )
		FAIL( "Unable to open keymap.library v36+." );

	/* Open gadtools.library */
	if ( use_menus )
	{
		if (( GadToolsBase = OpenLibrary( "gadtools.library", 36 )) == NULL )
		{
			use_menus = FALSE;
		}
	}

	/* Initialize color palette */
	for ( i = 0; i < 32; i++ )
	{
		/* If undefined, use default palette */
		if ( color_table[ i ][ 0 ] == 0 &&
		                color_table[ i ][ 1 ] == 0 &&
		                color_table[ i ][ 2 ] == 0 &&
		                color_table[ i ][ 3 ] == 0 )
		{
			color_table[ i ][ 0 ] = 1;
			color_table[ i ][ 1 ] = ( default_colors[ i ] & 0xff0000 ) >> 16;
			color_table[ i ][ 2 ] = ( default_colors[ i ] & 0x00ff00 ) >> 8;
			color_table[ i ][ 3 ] = ( default_colors[ i ] & 0x0000ff );
		}
	}

	/* Search for prefered screenmode or public screen */
	if ( strlen( modestr ) > 0 )
	{
		/* Convert string to long */
		scr_m = strtol( modestr, &s, 0 );

		/* It was not a number, so treat it as a public screen name */
		if ( scr_m == 0 )
		{
			/* We need kickstart 3.0+ to use a public screen */
			if ( !v39 )
			{
				FAIL( "Public screen can only be used on kickstart 3.0 or later." );
			}

			/* Try to lock the named public screen if it isn't already */
			if ( !pubscr )
			{
				pubscr = LockPubScreen( modestr );
			}

			/* Failed */
			if ( !pubscr )
			{
				sprintf( tmpstr, "Unable to get a lock on screen '%s'.", modestr );
				FAIL( tmpstr );
			}

			/* We got a lock now */
			publock = TRUE;

			scr_m = -1;

			use_pub = TRUE;

			/* Don't blank mouse on public screen */
			blankmouse = FALSE;

			/* Find suitable pens to use on public screen */
			for ( i = 0; i < 32; i++ )
			{
				pen = ObtainBestPen( pubscr->ViewPort.ColorMap,
				                     color_table[ i ][ 1 ] << 24,
				                     color_table[ i ][ 2 ] << 24,
				                     color_table[ i ][ 3 ] << 24,
				                     OBP_Precision, PRECISION_EXACT );
				if ( pen == -1 )
				{
					FAIL( "Unable to obtain suitable pens to use on public screen. ");
				}

				pubpens[ i ] = pen;
			}

			for ( i = 0; i < 16; i++ ) penconv[ i ] = (UWORD) pubpens[ i + 16 ];
		}

		/* Use specified screenmode if available */
		else
		{
			/* Check if requested mode is available */
			if ( ModeNotAvailable( scr_m )) scr_m = 0;
		}
	}

	if ( !use_pub )
	{
		/* Extra windows not allowed on custom screen */
		tc->use = tr->use = tm->use = FALSE;
	}

	/* Calculate window dimensions */
	ts->ww = ts->fw * ts->cols; ts->wh = ts->fh * ts->rows;
	tc->ww = tc->fw * tc->cols; tc->wh = tc->fh * tc->rows;
	tr->ww = tr->fw * tr->cols; tr->wh = tr->fh * tr->rows;
	tm->ww = tm->fw * tm->cols; tm->wh = tm->fh * tm->rows;

	/* Find a nice screenmode */
	if ( scr_m == 0 && v39 )
	{
		scr_m = BestModeID(
		                BIDTAG_NominalWidth, ts->ww,
		                BIDTAG_NominalHeight, ts->wh,
		                BIDTAG_DesiredWidth, ts->ww,
		                BIDTAG_DesiredHeight, ts->wh,
		                BIDTAG_Depth, 4,
		                TAG_END );
	}

	/* Use default screenmode if we don't have any */
	if ( scr_m == 0 || scr_m == INVALID_ID )
	{
		scr_m = ( DEFAULT_MONITOR_ID | HIRES_KEY );
	}

	/* Open custom screen */
	if ( !use_pub )
	{
		/* Use 32 colors with graphics */
		if ( use_graphics )
		{
			/* Get dimension data for screenmode */
			if ( GetDisplayInfoData( NULL, (UBYTE *) &diminfo, sizeof( struct DimensionInfo ), DTAG_DIMS, scr_m ))
			{
				/* Check if we support deep screens */
				if ( diminfo.MaxDepth > 4 )
				{
					/* Use 32 colors */
					deep = TRUE;

					/* Use colors 16..31 for text */
					for ( i = 0; i < 16; i++ ) penconv[ i ] = i + 16;
				}
			}
		}

		/* Use only 16 colors with no graphics */
		if ( !use_graphics )
		{
			/* Use 16 colors */
			deep = FALSE;

			/* Use colors 0..15 for text */
			for ( i = 0; i < 16; i++ ) penconv[ i ] = i;
		}

		if (( amiscr = OpenScreenTags( NULL,
		                               SA_Width, ts->ww,
		                               SA_Height, ts->wh,
		                               SA_Depth, deep ? 5 : 4,
		                               SA_DisplayID, scr_m,
		                               SA_Font, scrattr,
		                               SA_Type, CUSTOMSCREEN,
		                               SA_Title, "Angband Screen",
		                               SA_ShowTitle, FALSE,
		                               SA_Quiet, TRUE,
		                               SA_Behind, TRUE,
		                               SA_AutoScroll, TRUE,
		                               SA_Overscan, OSCAN_TEXT,
		                               v39 ? SA_Interleaved : TAG_IGNORE, TRUE,
		                               TAG_END )) == NULL)
		{
			FAIL( "Unable to open screen." );
		}

		/* Initialize screen rastport */
		ts->rp = &amiscr->RastPort;
		SetRast( ts->rp, PEN( 0 ));
		SetAPen( ts->rp, 1 );
		SetBPen( ts->rp, 0 );
		SetDrMd( ts->rp, JAM2 );
		SetFont( ts->rp, ts->font );

		/* Always use backdrop window on custom screen */
		backdrop = TRUE;
	}

	/* We are using a public screen */
	else
	{
		/* Size of public screen */
		pw = pubscr->Width;
		ph = pubscr->Height;

		/* Height difference between a window with or without a title bar */
		th = pubscr->Font->ta_YSize + 1;

		/* Find width of widest window */
		maxw = ts->ww;
		maxw = tc->ww > maxw ? tc->ww : maxw;
		maxw = tr->ww > maxw ? tr->ww : maxw;
		maxw = tm->ww > maxw ? tm->ww : maxw;
		maxw += pubscr->WBorLeft + pubscr->WBorRight;

		/* Find height of tallest window */
		maxh = ts->wh + ts->notitle ? 0 : th;
		maxh = ( tc->wh + tc->notitle ? 0 : th ) > maxh ? ( tc->wh + tc->notitle ? 0 : th ) : maxh;
		maxh = ( tr->wh + tr->notitle ? 0 : th ) > maxh ? ( tr->wh + tr->notitle ? 0 : th ) : maxh;
		maxh = ( tm->wh + tm->notitle ? 0 : th ) > maxh ? ( tm->wh + tm->notitle ? 0 : th ) : maxh;
		maxh += pubscr->WBorTop + pubscr->WBorBottom;

		/* Check if the public screen is large enough */
		if ( pw < maxw || ph < maxh )
		{
			sprintf( tmpstr, "Public screen is too small for window (%d x %d).", maxw, maxh );
			FAIL( tmpstr );
		}

		/* Use backdrop window if pubscreen is quiet */
		backdrop = ( pubscr->Flags & SCREENQUIET ) ? TRUE : FALSE;

		/* Calculate screen bar height */
		barh = pubscr->BarHeight + 1;

		/* Check if windows are to be positioned at the right or bottom */
		if ( ts->wx == -1 ) ts->wx = pw - 1;
		if ( ts->wy == -1 ) ts->wy = ph - 1;
		if ( tc->wx == -1 ) tc->wx = pw - 1;
		if ( tc->wy == -1 ) tc->wy = ph - 1;
		if ( tr->wx == -1 ) tr->wx = pw - 1;
		if ( tr->wy == -1 ) tr->wy = ph - 1;
		if ( tm->wx == -1 ) tm->wx = pw - 1;
		if ( tm->wy == -1 ) tm->wy = ph - 1;

		/* Position windows below screen bar if requested */
		if ( ts->wy == -2 ) ts->wy = barh;
		if ( tc->wy == -2 ) tc->wy = barh;
		if ( tr->wy == -2 ) tr->wy = barh;
		if ( tm->wy == -2 ) tm->wy = barh;
	}

	/* Get visual info for GadTools */
	if ( use_menus )
	{
		if (( visinfo = GetVisualInfo( use_pub ? pubscr : amiscr, TAG_END )) == NULL )
		{
			use_menus = FALSE;
		}
	}

	/* Open window, backdrop if on custom screen */
	if (( ts->win = OpenWindowTags( NULL,
	                                WA_Left, ts->wx,
	                                WA_Top, ts->wy,
	                                WA_InnerWidth, ts->ww,
	                                WA_InnerHeight, ts->wh,
	                                use_pub ? WA_PubScreen : WA_CustomScreen, use_pub ? pubscr : amiscr,
	                                WA_Backdrop, backdrop,
	                                WA_Borderless, backdrop,
	                                WA_GimmeZeroZero, !backdrop,
	                                WA_DragBar, !backdrop && !ts->notitle,
	                                WA_DepthGadget, !backdrop && !ts->notitle,
	                                WA_NewLookMenus, TRUE,
	                                backdrop ? TAG_IGNORE : WA_ScreenTitle, VERSION,
	                                ( backdrop || ts->notitle ) ? TAG_IGNORE : WA_Title, ts->name,
	                                WA_Activate, TRUE,
	                                WA_RMBTrap, !use_menus,
	                                WA_ReportMouse, TRUE,
	                                WA_IDCMP, IDCMP_RAWKEY | IDCMP_INTUITICKS | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_MENUPICK | IDCMP_MENUVERIFY,
	                                TAG_END )) == NULL )
	{
		FAIL("Unable to open window.");
	}

	/* Unlock public screen */
	if ( publock )
	{
		UnlockPubScreen( NULL, pubscr );
		publock = FALSE;
	}

	/* Initialize main rastport */
	ts->wrp = ts->win->RPort;
	SetRast( ts->wrp, PEN( 0 ));
	SetAPen( ts->wrp, 1 );
	SetBPen( ts->wrp, 0 );
	SetDrMd( ts->wrp, JAM2 );
	SetFont( ts->wrp, ts->font );

	/* Never use screen's rastport on public screen */
	if ( use_pub )
	{
		ts->rp = ts->wrp;
	}

	/* Use mirror window? */
	if ( tm->use )
	{
		/* Open mirror window */
		if (( tm->win = OpenWindowTags( NULL,
		                                WA_Left, tm->wx,
		                                WA_Top, tm->wy,
		                                WA_InnerWidth, tm->ww,
		                                WA_InnerHeight, tm->wh,
		                                WA_PubScreen, pubscr,
		                                WA_GimmeZeroZero, TRUE,
		                                WA_DragBar, !tm->notitle,
		                                WA_DepthGadget, !tm->notitle,
		                                WA_NewLookMenus, TRUE,
		                                WA_ScreenTitle, VERSION,
		                                tm->notitle ? TAG_IGNORE : WA_Title, tm->name,
		                                WA_ReportMouse, TRUE,
		                                TAG_END )) == NULL )
		{
			FAIL("Unable to open recall window.");
		}

		/* Initialize mirror rastport */
		tm->rp = tm->wrp = tm->win->RPort;
		SetRast( tm->rp, PEN( 0 ));
		SetAPen( tm->rp, 1 );
		SetBPen( tm->rp, 0 );
		SetDrMd( tm->rp, JAM2 );
		SetFont( tm->rp, tm->font );
	}

	/* Use recall window? */
	if ( tr->use )
	{
		/* Open recall window */
		if (( tr->win = OpenWindowTags( NULL,
		                                WA_Left, tr->wx,
		                                WA_Top, tr->wy,
		                                WA_InnerWidth, tr->ww,
		                                WA_InnerHeight, tr->wh,
		                                WA_PubScreen, pubscr,
		                                WA_GimmeZeroZero, TRUE,
		                                WA_DragBar, !tr->notitle,
		                                WA_DepthGadget, !tr->notitle,
		                                WA_NewLookMenus, TRUE,
		                                WA_ScreenTitle, VERSION,
		                                tr->notitle ? TAG_IGNORE : WA_Title, tr->name,
		                                WA_ReportMouse, TRUE,
		                                TAG_END )) == NULL )
		{
			FAIL("Unable to open recall window.");
		}

		/* Initialize recall rastport */
		tr->rp = tr->wrp = tr->win->RPort;
		SetRast( tr->rp, PEN( 0 ));
		SetAPen( tr->rp, 1 );
		SetBPen( tr->rp, 0 );
		SetDrMd( tr->rp, JAM2 );
		SetFont( tr->rp, tr->font );
	}

	/* Use choice window? */
	if ( tc->use )
	{
		/* Open choice window */
		if (( tc->win = OpenWindowTags( NULL,
		                                WA_Left, tc->wx,
		                                WA_Top, tc->wy,
		                                WA_InnerWidth, tc->ww,
		                                WA_InnerHeight, tc->wh,
		                                WA_PubScreen, pubscr,
		                                WA_GimmeZeroZero, TRUE,
		                                WA_DragBar, !tc->notitle,
		                                WA_DepthGadget, !tc->notitle,
		                                WA_NewLookMenus, TRUE,
		                                WA_ScreenTitle, VERSION,
		                                tc->notitle ? TAG_IGNORE : WA_Title, tc->name,
		                                WA_ReportMouse, TRUE,
		                                TAG_END )) == NULL )
		{
			FAIL("Unable to open recall window.");
		}

		/* Initialize choice rastport */
		tc->rp = tc->wrp = tc->win->RPort;
		SetRast( tc->rp, PEN( 0 ));
		SetAPen( tc->rp, 1 );
		SetBPen( tc->rp, 0 );
		SetDrMd( tc->rp, JAM2 );
		SetFont( tc->rp, tc->font );
	}

	/* Create palette for screen */
	load_palette();

	/* Link terms with the metaterm */
	if ( tc->use ) term_choice = link_term( tc );
	if ( tr->use ) term_recall = link_term( tr );
	if ( tm->use ) term_mirror = link_term( tm );
	if ( ts->use ) term_screen = link_term( ts );

	/* Bring main window to front */
	if ( !backdrop ) WindowToFront( ts->win );

	/* Bring screen to front */
	ScreenToFront( use_pub ? pubscr : amiscr );

	/* Load and convert graphics */
	if ( use_graphics )
	{
		MSG( 0, 0, "Loading graphics" );
		if ( !load_gfx() ) FAIL( NULL );

		/* Check if conversion is necessary */
		if ( use_pub || ( depth_of_bitmap( ts->rp->BitMap ) != depth_of_bitmap( ts->gfxbm )))
		{
			MSG( 0, 1, "Remapping graphics" );
			if ( !conv_gfx() ) FAIL( "Out of memory while remapping graphics." );
		}

		/* Scale the graphics to fit font sizes */
		if ( tm->use ) if ( !size_gfx( tm ) ) FAIL( "Out of memory while scaling graphics." );
		if ( tr->use ) if ( !size_gfx( tr ) ) FAIL( "Out of memory while scaling graphics." );
		if ( tc->use ) if ( !size_gfx( tc ) ) FAIL( "Out of memory while scaling graphics." );
		if ( ts->use ) if ( !size_gfx( ts ) ) FAIL( "Out of memory while scaling graphics." );

		/* Use graphics */
		use_graphics = TRUE;
	}

	/* Load sound effects */
	if ( use_sound )
	{
		MSG( 0, 2, "Loading sound effects" );
		init_sound();
	}

	/* Success */
	return ( 0 );
}
///}
///{ "init_term()"

static void init_term( term_data *td )
{
	/* Set term name */
	if ( td == &screen ) td->name = screen_name;
	if ( td == &choice ) td->name = choice_name;
	if ( td == &recall ) td->name = recall_name;
	if ( td == &mirror ) td->name = mirror_name;

	/* Term off */
	td->use = FALSE;

	/* Term size */
	td->cols = 80;
	td->rows = 24;

	/* Term dimension */
	td->wx = 0;
	td->wy = 0;
	td->ww = 0;
	td->wh = 0;

	/* System default font */
	td->font = GfxBase->DefaultFont;
	td->ownf = FALSE;
	td->fw = td->font->tf_XSize;
	td->fh = td->font->tf_YSize;
	td->fb = td->font->tf_Baseline;

	/* No window or rastports */
	td->win = NULL;
	td->wrp = NULL;
	td->rp = NULL;

	/* No bitmaps */
	td->gfxbm = NULL;
	td->mskbm = NULL;
	td->mapbm = NULL;

	/* Cursor status */
	td->cursor_xpos = 0;
	td->cursor_ypos = 0;
	td->cursor_visible = FALSE;
	td->cursor_lit = FALSE;
	td->cursor_frame = 0;
	td->cursor_map = FALSE;

	/* Use window title */
	td->notitle = FALSE;
}

///}
///{ "link_term()"

static term *link_term( term_data *td )
{
	term *t;

	/* Term pointer */
	t = &td->t;

	/* Initialize the term */
	term_init( t, td->cols, td->rows, 256 );

	/* Hooks */
	t->init_hook = amiga_open;
	t->nuke_hook = amiga_nuke;
	t->text_hook = amiga_text;
	t->pict_hook = amiga_pict;
	t->wipe_hook = amiga_wipe;
	t->curs_hook = amiga_curs;
	t->xtra_hook = amiga_xtra;

	/* We are emulating a hardware cursor */
	t->soft_cursor = FALSE;

	/* Draw graphical tiles one by one */
	t->always_text = FALSE;
	t->always_pict = FALSE;
	t->higher_pict = TRUE;

	/* Misc. efficiency flags */
	t->never_bored = TRUE;
	t->never_frosh = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Remember where we come from */
	t->data = (vptr) td;

	/* Activate it */
	Term_activate( t );

	/* Return pointer to the term */
	return ( t );
}

///}
///{ "free_term()"

static void free_term( term_data *td )
{
	/* Do we own the font? */
	if ( td->ownf && td->font ) CloseFont( td->font );

	/* Is the window opened? */
	if ( td->win ) CloseWindow( td->win );

	/* Free bitmaps */
	if ( td->gfxbm ) free_bitmap( td->gfxbm );
	if ( td->mskbm ) free_bitmap( td->mskbm );
	if ( td->mapbm ) free_bitmap( td->mapbm );
}

///}
///{ "stripstr()"

static char *stripstr( char *src, char *dst )
{
	int len;

	/* Ignore leading spaces */
	while ( *src == ' ' ) src++;

	/* Copy string */
	for ( len = 0; *src != 0; len++ ) *dst++ = *src++;
	*dst = 0;

	/* Remove trailing spaces */
	for ( dst--; *dst == ' ' && len; len-- ) *dst-- = 0;

	/* Return pointer to destination */
	return ( dst );
}

///}
///{ "yesno()"

static int yesno( char *str )
{
	char tmp[ 256 ];
	char *s;

	/* Strip spaces around string */
	stripstr( str, tmp);

	/* Make lowercase */
	for ( s = tmp; *s != 0; s++ ) *s = tolower( *s );

	return ( !strcmp( tmp, "y" ) || !strcmp( tmp, "yes" ) || !strcmp( tmp, "true" ) || !strcmp( tmp, "on" ));
}

///}
///{ "request_font()"

void request_font( char *str )
{
	struct Library *AslBase = NULL;
	struct FontRequester *req = NULL;

	/* Blank string as default */
	*str = 0;

	/* Open asl.library */
	if ( AslBase = OpenLibrary ( "asl.library", 37 ))
	{
		/* Allocate screenmode requester */
		if ( req = AllocAslRequestTags( ASL_FontRequest, TAG_DONE ))
		{
			/* Open screenmode requester */
			if ( AslRequestTags( req, ASLFO_FixedWidthOnly, TRUE, TAG_DONE ))
			{
				/* Store font name and size */
				sprintf( str, "%s/%d", req->fo_Attr.ta_Name, req->fo_Attr.ta_YSize );
			}
			/* Free requester */
			FreeAslRequest( req );
		}
		/* Close asl.library */
		CloseLibrary( AslBase );
	}
}

///}
///{ "request_mode()"

void request_mode( char *str )
{
	struct Library *AslBase = NULL;
	struct ScreenModeRequester *req = NULL;

	/* Blank string as default */
	*str = 0;

	/* Open asl.library */
	if ( AslBase = OpenLibrary ( "asl.library", 37 ))
	{
		/* Allocate screenmode requester */
		if ( req = AllocAslRequestTags( ASL_ScreenModeRequest, TAG_DONE ))
		{
			/* Open screenmode requester */
			if ( AslRequestTags( req, TAG_DONE ))
			{
				/* Store font name and size */
				sprintf( str, "0x%X", req->sm_DisplayID );
			}
			/* Free requester */
			FreeAslRequest( req );
		}
		/* Close asl.library */
		CloseLibrary( AslBase );
	}
}

///}
///{ "read_prefs()"

int read_prefs( void )
{
	BPTR file;
	char line[ 256 ];
	char fname[ 256 ];
	char *tmp, *s;
	int len;
	int fsize;
	int val;
	struct TextAttr attr;
	term_data *td;

	/* Open config file */
	if (( file = Open( WPRF, MODE_OLDFILE )) == NULL )
	{
		fprintf( stderr, "\nUnable to open file '%s'.\n", WPRF );
		return ( FALSE );
	}

	/* Read next line from file */
	while ( FGets( file, line, 256 ))
	{
		/* Cut off comments */
		if ( tmp = strchr( line, ';' )) * tmp = 0;

		/* Length of line */
		len = strlen( line );

		/* Cut off trailing newline and blanks */
		for ( tmp = line + len - 1; len > 0 && ( *tmp == '\n' || *tmp == ' ' ); len-- ) *tmp-- = 0;

		/* Ignore blank lines */
		if ( len == 0 ) continue;

		/* Extract term */
		if ( strncmp( line, "MAIN.", 5 ) == 0 ) td = &screen;
		else if ( strncmp( line, "CHOICE.", 7 ) == 0 ) td = &choice;
		else if ( strncmp( line, "RECALL.", 7 ) == 0 ) td = &recall;
		else if ( strncmp( line, "MIRROR.", 7 ) == 0 ) td = &mirror;
		else if ( strncmp( line, "SCREEN.", 7 ) != 0 &&
		                strncmp( line, "ANGBAND.", 8 ) != 0 )
		{
			printf( "PREFS: Error in line '%s'\n", line );
			continue;
		}

		/* Find start of option */
		tmp = strchr( line, '.' ) + 1;

		/* Ignore blank options */
		if ( *tmp == 0 ) continue;

		/* Option 'use' - Use this term */
		if ( !strncmp( tmp, "use", 3 ))
		{
			td->use = yesno( tmp + 3 );
		}

		/* Option 'cols' - Set number of columns for term */
		else if ( !strncmp( tmp, "cols", 4 ) && sscanf( tmp + 4, "%d", &val )) td->cols = val;

		/* Option 'rows' - Set number of rows for term */
		else if ( !strncmp( tmp, "rows", 4 ) && sscanf( tmp + 4, "%d", &val )) td->rows = val;

		/* Option 'xpos' - Set horizontal position for window */
		else if ( !strncmp( tmp, "xpos", 4 ) && sscanf( tmp + 4, "%d", &val )) td->wx = val;

		/* Option 'ypos' - Set vertical position for window */
		else if ( !strncmp( tmp, "ypos", 4 ) && sscanf( tmp + 4, "%d", &val )) td->wy = val;

		/* Option 'name' - Set window title */
		else if ( !strncmp( tmp, "title", 5 ))
		{
			/* Get parameter */
			stripstr( tmp + 5, fname );

			/* Make a copy of the title */
			if ( strlen( fname ) > 0 )
			{
				td->name = strdup( fname );
			}

			/* Don't use a title bar on this window */
			else
			{
				td->notitle = TRUE;
			}

			continue;
		}

		/* Option 'font' - Set font for this window */
		else if ( !strncmp( tmp, "font", 4 ))
		{
			/* Get value */
			stripstr( tmp + 4, fname );

			/* Ask for font? */
			if ( !strcmp( fname, "?" ))
			{
				/* Open font requester */
				request_font( fname );
			}

			/* No font specification given */
			if ( strlen( fname ) == 0 )
			{
				/* Main window */
				if ( td == &screen )
				{
					/* System default font */
					td->font = GfxBase->DefaultFont;

					/* Use default font as screen font */
					scrattr = NULL;
				}

				/* Extra window */
				else
				{
					/* Copy main window's font */
					td->font = screen.font;
				}

				/* Set font dimensions */
				td->fw = td->font->tf_XSize;
				td->fh = td->font->tf_YSize;
				td->fb = td->font->tf_Baseline;

				/* This font is not opened by us */
				td->ownf = FALSE;

				/* Next line */
				continue;
			}

			/* Get name and size */
			else
			{
				/* Find font name/size delimiter */
				if (( s = strchr( fname, '/' )) == NULL )
				{
					printf( "\nPREFS: Illegal font specification: '%s'.\n", fname );
					continue;
				}

				/* End fontname here */
				*s++ = 0;

				/* Convert size string to integer */
				fsize = atoi( s );

				/* Make sure the font name ends with .font */
				if ( !strstr( fname, ".font" )) strcat( fname, ".font" );
			}

			/* Set font attributes */
			attr.ta_Name = fname;
			attr.ta_YSize = fsize;
			attr.ta_Style = FS_NORMAL;
			attr.ta_Flags = ( !strcmp( fname, "topaz.font" ) && ( fsize == 8 || fsize == 9 )) ?
			                FPF_ROMFONT : FPF_DISKFONT;

			/* Open font from disk */
			if ( td->font = OpenDiskFont( &attr ))
			{
				/* We own this font */
				td->ownf = TRUE;

				/* Set font dimensions */
				td->fw = td->font->tf_XSize;
				td->fh = td->font->tf_YSize;
				td->fb = td->font->tf_Baseline;

				/* Copy font attr to screen font */
				if ( td == &screen )
				{
					scrattr->ta_Name = strdup( fname );
					scrattr->ta_YSize = fsize;
					scrattr->ta_Style = FS_NORMAL;
					scrattr->ta_Flags = attr.ta_Flags;
				}
			}

			/* The font could not be opened */
			else
			{
				/* Fallback to default font */
				td->font = GfxBase->DefaultFont;

				/* Use default font as screen font */
				scrattr = NULL;

				/* Output error message */
				printf( "\nUnable to open font '%s/%d'.\n", fname, fsize );
			}
		}

		/* Option .name - Set public screen name. KS 3.0+ required */
		else if ( !strncmp( tmp, "name", 4 ) && v39 )
		{
			/* Copy name */
			stripstr( tmp + 4, modestr );
		}

		/* Option .mode - Set custom screen mode */
		else if ( !strncmp( tmp, "mode", 4 ))
		{
			/* If a public screen was also specified, check if it exist */
			if ( strlen( modestr ) > 0 )
			{
				/* Don't lock it twice */
				if ( pubscr ) continue;

				/* Try to lock the named public screen */
				if ( pubscr = LockPubScreen( modestr ))
				{
					/* We got a lock now */
					publock = TRUE;

					/* Screen exist. Skip this option */
					continue;
				}
			}

			/* Get parameter */
			stripstr( tmp + 4, modestr );

			/* Ask for mode? */
			if ( !strcmp( modestr, "?" ))
			{
				/* Open screenmode requester */
				request_mode( modestr );
			}
		}

		/* Option .blankmouse - Use mouseblanking */
		else if ( !strncmp( tmp, "blankmouse", 10 ))
		{
			blankmouse = yesno( tmp + 10 );
		}

		/* Option .blankmouse - Use intuition menus */
		else if ( !strncmp( tmp, "menus", 5 ))
		{
			use_menus = yesno( tmp + 5 );
		}

		else if ( !strncmp( tmp, "sound", 5 ))
		{
			use_sound = yesno( tmp + 5 );
		}

		else if ( !strncmp( tmp, "gfx", 3 ))
		{
			use_graphics = yesno( tmp + 5 );
		}

		/* Unknown option */
		else
		{
			/* Output error message */
			printf ( "\nPREFS: Unknown option '%s'.\n", tmp );
		}
	}

	/* Close the file */
	Close( file );
}

///}
///{ "amiga_nuke()" - Free all allocated resources

static void amiga_nuke( term *t )
{
	if ( t == term_screen )
	{
		amiga_fail( NULL );
		/* Flush the output */
		fflush( stdout );
	}
}

///}
///{ "amiga_open()" - Initialize terminal

static void amiga_open( term *t )
{
	/* Nothing to do here */
}

///}
///{ "amiga_curs()" - Move the cursor to a new location

static errr amiga_curs( int x, int y )
{
	term_data *td = term_curs;

	if ( td->cursor_visible )
	{
		cursor_off( td );
	}

	td->cursor_xpos = x;
	td->cursor_ypos = y;
	td->cursor_frame = 0;

	if ( td->cursor_visible )
	{
		cursor_on( td );
	}

	return ( 0 );
}

///}
///{ "amiga_wipe()" - Erase a part of a line

static errr amiga_wipe( int x, int y, int n )
{
	term_data *td = (term_data*)(Term->data);

	if (( n > 0 ) && !iconified )
	{
		/* Erase rectangular area on screen */
		SetAPen( td->rp, PEN( 0 ) );
		RectFill( td->rp, x * td->fw, y * td->fh, ( x + n ) * td->fw - 1, ( y + 1 ) * td->fh - 1 );
	}

	return ( 0 );
}

///}
///{ "amiga_clear()" - Clear whole window

static errr amiga_clear( void )
{
	term_data *td = (term_data*)(Term->data);

	/* Fill window with background color */
	SetRast( td->rp, PEN( 0 ));

	return ( 0 );
}

///}
///{ "amiga_pict()" - Place one tile on the screen

static errr amiga_pict( int x, int y, byte a, char c )
{
	term_data *td = (term_data*)(Term->data);
	char s[2];

	/* Graphical tile */
	if ( a & 0x80 )
	{
		put_gfx( td->rp, x, y, c & 0x7f, a & 0x7f );
	}

	/* Textual character */
	else
	{
		s[0] = c;
		s[1] = 0;
		SetAPen( td->rp, PEN( a & 0x0f ));
		SetBPen( td->rp, PEN( 0 ));
		Move( td->rp, x * td->fw, y * td->fh + td->fb );
		Text( td->rp, (char *) s, 1 );
	}

	return ( 0 );
}

///}
///{ "amiga_text()" - Place some text on the screen using an attribute

static errr amiga_text( int x, int y, int n, byte a, cptr s )
{
	term_data *td = (term_data*)(Term->data);
	int i;

	if ( x >= 0 && y >= 0 && n > 0 && !iconified )
	{
		/* Draw gfx one char at a time */
		if (( a & 0xc0 ))
		{
			for ( i = 0; i < n; i++ ) put_gfx( td->rp, x + i, y, s[ i ] & 0x7f, a & 0x7f );
		}

		/* Draw the string on screen */
		else
		{
			SetAPen( td->rp, PEN( a&0x0f ));
			SetBPen( td->rp, PEN( 0 ));
			Move( td->rp, x * td->fw, y * td->fh + td->fb );
			Text( td->rp, (char *) s, n );
		}
	}

	return ( 0 );
}

///}
///{ "amiga_xtra()" - Handle a "special request"

static errr amiga_xtra( int n, int v )
{
	term_data *td = (term_data*)(Term->data);

	/* Analyze the request */
	switch ( n )
	{
		/* Wait for event */
	case TERM_XTRA_EVENT:

		return ( amiga_event( v ));


		/* Flush input */
	case TERM_XTRA_FLUSH:

		return ( amiga_flush( v ));


		/* Make a noise */
	case TERM_XTRA_CLEAR:

		return ( amiga_clear());


		/* Change cursor visibility */
	case TERM_XTRA_SHAPE:

		/* Cursor on */
		if ( v )
		{
			cursor_on( td );
			td->cursor_visible = TRUE;
		}
		/* Cursor off */
		else
		{
			cursor_off( td );
			td->cursor_visible = FALSE;
		}
		return ( 0 );


		/* Flash screen */
	case TERM_XTRA_NOISE:

		DisplayBeep( use_pub ? pubscr : amiscr );
		return ( 0 );


		/* Play a sound */
	case TERM_XTRA_SOUND:

		if ( has_sound )
		{
			play_sound( v );
		}
		return ( 0 );


		/* React on global changes */
	case TERM_XTRA_REACT:

		return ( amiga_react( v ));


	case TERM_XTRA_LEVEL:

		term_curs = td;
		return ( 0 );

	case TERM_XTRA_DELAY:

		if (v >= 20) Delay(v / 20);
		return (0);

		/* Unknown request type */
	default:

		return ( 1 );

	}

	/* Shouldn't be able to get here */
	return ( 1 );
}

///}
///{ "amiga_flush()" - Flush input buffer

static errr amiga_flush( int v )
{
	struct IntuiMessage *imsg;

	/* Ignore all messages at the port */
	while ( imsg = (struct IntuiMessage *) GetMsg( screen.win->UserPort ))
	{
		ReplyMsg(( struct Message *) imsg );
	}

	return ( 1 );
}

///}
///{ "amiga_event()" - Wait for an event, and handle it.

static errr amiga_event( int v )
{
	struct IntuiMessage *imsg;
	ULONG iclass;
	UWORD icode;
	UWORD iqual;
	APTR iaddr;

	/* Check for messages to the window */
	if (( imsg = (struct IntuiMessage *) GetMsg( screen.win->UserPort )) == NULL )
	{
		/* If we don't want blocking, return */
		if ( !v )
		{
			return ( 0 );
		}

		/* No messages, so wait for one */
		Wait( 1 << screen.win->UserPort->mp_SigBit );

		/* Get the new message */
		imsg = (struct IntuiMessage *) GetMsg( screen.win->UserPort );
	}

	/* Handle message */
	if ( imsg )
	{
		/* Get message attributes */
		iclass = imsg->Class;
		icode = imsg->Code;
		iqual = imsg->Qualifier;
		iaddr = imsg->IAddress;

		/* Update menus before displaying */
		if ( iclass == IDCMP_MENUVERIFY && icode == MENUHOT && use_menus )
		{
			update_menus();
		}

		/* Reply the message */
		ReplyMsg(( struct Message *) imsg );

		/* Do we have a keypress? */
		if ( iclass == IDCMP_RAWKEY )
		{
			handle_rawkey( icode, iqual, iaddr );
			return ( 0 );
		}

		/* Mouse event - Make pointer visible */
		if ( iclass == IDCMP_MOUSEMOVE ||
		                iclass == IDCMP_MOUSEBUTTONS ||
		                iclass == IDCMP_MENUVERIFY )
		{
			if ( blankmouse && !pointer_visible )
			{
				ClearPointer( screen.win );
				pointer_visible = TRUE;
			}

			return ( 0 );
		}

		/* Time for some cursor anim? */
		if ( iclass == IDCMP_INTUITICKS )
		{
			cursor_anim();
			return ( 0 );
		}

		/* Menu item picked? */
		if ( iclass == IDCMP_MENUPICK )
		{
			handle_menupick( icode );
		}

		/* Unknown message class */
		return ( 1 );
	}

	/* No events */
	return ( 1 );
}

///}
///{ "amiga_react()"

static errr amiga_react( int v )
{
	/* Apply color palette, in case it has changed */
	load_palette();

	/* Create menus if we don't have any */
	if ( !menu && use_menus )
	{
		create_menus();
	}

	return ( 0 );
}

///}
///{ "amiga_tomb()"

int amiga_tomb( void )
{
	cptr p;
	char tmp[160];
	time_t ct = time((time_t)0);
	BPTR file;

	char *pp;
	int plane, row, error = FALSE;
	struct BitMap *filebm, *scalbm, *convbm;
	long stdpens[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
	int depth;
	BYTE *src, *dst;
	int byt;

	int tw = screen.fw * 64;
	int th = screen.fh * 21;

	/* Allocate bitmap for tomb graphics file */
	if (( filebm = alloc_bitmap( 512, 168, 4, BMF_CLEAR, screen.rp->BitMap )) == NULL )
	{
		return ( FALSE );
	}

	/* Open tomb file */
	if (( file = Open( MTOM, MODE_OLDFILE )) == NULL )
	{
		free_bitmap( filebm );
		return ( FALSE );
	}

	/* Read file into bitmap */
	for ( plane = 0; plane < 4 && !error; plane++ )
	{
		pp = filebm->Planes[ plane ];
		for ( row = 0; row < 168 && !error; row++ )
		{
			error = ( Read( file, pp, 64 ) != 64 );
			pp += filebm->BytesPerRow;
		}
	}

	/* Close tomb file */
	Close( file );

	/* Get depth of display */
	depth = depth_of_bitmap( screen.rp->BitMap );

	/* Remapping needed? */
	if ( depth != 4 || use_pub )
	{
		/* Allocate bitmap for remapped image */
		if (( convbm = alloc_bitmap( 512, 168, depth, BMF_CLEAR, screen.rp->BitMap )) == NULL )
		{
			free_bitmap( filebm );
			return ( FALSE );
		}

		/* Simple remapping from 4 to 5 planes? */
		if ( depth == 5 && !use_pub )
		{
			for ( plane = 0; plane < 4; plane++ )
			{
				src = filebm->Planes[ plane ];
				dst = convbm->Planes[ plane ];
				for ( row = 0; row < 168; row++ )
				{
					for ( byt = 0; byt < 64; byt++ )
					{
						dst[ byt ] = src[ byt ];
					}
					src += filebm->BytesPerRow;
					dst += convbm->BytesPerRow;
				}
			}
		}

		/* Complex remapping */
		else
		{
			/* Remap old bitmap into new bitmap */
			remap_bitmap( filebm, convbm, use_pub ? pubpens : stdpens, 512, 168 );
		}

		/* Free original bitmap */
		free_bitmap( filebm );
	}

	/* No remapping needed */
	else
	{
		convbm = filebm;
	}

	/* Allocate bitmap for scaled graphics */
	if (( scalbm = alloc_bitmap( tw, th, depth, BMF_CLEAR, screen.rp->BitMap )) == NULL )
	{
		free_bitmap( convbm );
		return ( FALSE );
	}

	/* Scale the tomb bitmap */
	scale_bitmap( convbm, 512, 168, scalbm, tw, th );

	/* Free old bitmap */
	free_bitmap( convbm );

	/* Copy the tomb graphics to the screen, centered */
	BltBitMapRastPort( scalbm, 0, 0, screen.rp, ( screen.ww - tw ) / 2, 0, tw, th, 0xc0 );

	/* Free bitmap */
	free_bitmap( scalbm );

	/* King or Queen */
	if (total_winner || (p_ptr->lev > PY_MAX_LEVEL))
	{
		p = "Magnificent";
	}

	/* Normal */
	else
	{
		p = player_title[p_ptr->pclass][(p_ptr->lev - 1) / 5];
	}

	tomb_str( 3, " R.I.P." );

	tomb_str( 5, player_name );

	tomb_str( 6, "the" );

	tomb_str( 7, (char *)p );

	tomb_str( 9, (char *)cp_ptr->title );

	sprintf( tmp, "Level: %d", (int)p_ptr->lev );
	tomb_str( 10, tmp );

	sprintf( tmp, "Exp: %ld", (long)p_ptr->exp );
	tomb_str( 11, tmp );

	sprintf( tmp, "AU: %ld", (long)p_ptr->au );
	tomb_str( 12, tmp );

	sprintf( tmp, "Killed on Level %d", dun_level );
	tomb_str( 13, tmp );

	sprintf( tmp, "by %s", died_from );
	tomb_str( 14, tmp );

	sprintf( tmp, "%-.24s", ctime(&ct));
	tomb_str( 16, tmp );

	return ( TRUE );
}

///}
///{ "tomb_str()"

void tomb_str( int y, char *str )
{
	term_data *td = &screen;
	int l = strlen( str );
	int xp = ( 39 * td->fw ) - (( l + 1 ) * td->fw ) / 2;

	SetDrMd( td->rp, JAM1 );

	SetAPen( td->rp, PEN( 1 ));
	Move( td->rp, xp + 1, y * td->fh + td->fb + 1 );
	Text( td->rp, str, l );

	SetAPen( td->rp, PEN( 0 ));
	Move( td->rp, xp, y * td->fh + td->fb );
	Text( td->rp, str, l );

	SetDrMd( td->rp, JAM2 );
}

///}
///{ "handle_rawkey()"

void handle_rawkey( UWORD code, UWORD qual, APTR addr )
{
	char buf[ 80 ];
	int i;
	int len;
	UWORD q;

	/* Use a blank mouse-pointer on this window */
	if ( blankmouse && pointer_visible )
	{
		SetPointer( screen.win, blankpointer, 2, 16, 0, 0 );
		pointer_visible = FALSE;
	}

	/* Numeric keypad pressed with qualifier? */
	if (( qual & IEQUALIFIER_NUMERICPAD ) && ( qual & 0xff ))
	{
		/* Direction key? (1,2,3,4,6,7,8,9) */
		if (( code >= 0x1d && code <= 0x1f ) ||
		                ( code == 0x2d || code == 0x2f ) ||
		                ( code >= 0x3d && code <= 0x3f ))
		{
			/* Shift/Ctrl/Alt/Amiga keys */
			q = qual & 0xff;

			/* Shift + Direction */
			if ( q == IEQUALIFIER_LSHIFT || q == IEQUALIFIER_RSHIFT )
			{
				/* Fake a keypress 'run' */
				Term_keypress( '.' );

				/* Remove shift key from event */
				qual &= ~( IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT );
			}

			/* Alt + Direction */
			else if ( q == IEQUALIFIER_LALT || q == IEQUALIFIER_RALT )
			{
				/* Fake a keypress 'tunnel' */
				Term_keypress( 'T' );

				/* Remove alt key from event */
				qual &= ~( IEQUALIFIER_LALT | IEQUALIFIER_RALT );
			}

			/* Ctrl + Direction */
			else if ( q == IEQUALIFIER_CONTROL )
			{
				/* Fake a keypress 'open' */
				Term_keypress( 'o' );

				/* Remove ctrl key from event */
				qual &= ~IEQUALIFIER_CONTROL;
			}
		}
	}

	/* Convert raw keycode to ANSI sequence */
	ie.ie_Code = code;
	ie.ie_Qualifier = qual;
	ie.ie_EventAddress = (APTR *) * ((ULONG *) addr );
	len = MapRawKey( &ie, buf, 80, NULL );

	/* Send ANSI sequence to meta-terminal */
	for ( i = 0; i < len; i++ )
	{
		if ( !iconified )
		{
			Term_keypress( (unsigned char) buf[ i ]);
		}
	}
}

///}
///{ "handle_menupick()"

void handle_menupick( int mnum )
{
	struct MenuItem *item;
	ULONG ud;
	int i;

	/* Be sure to handle all selections */
	while ( mnum != MENUNULL )
	{
		/* Find address of menuitem */
		item = ItemAddress( menu, mnum );

		/* Find userdata of menuitem */
		ud = (ULONG) GTMENUITEM_USERDATA( item );

		/* Is this a help item? */
		if ( ud >= MNU_HELP )
		{
			/* Send keypresses */
			Term_keypress( '\\' );
			Term_keypress( '?' );
			Term_keypress( ud - MNU_HELP );
		}

		/* Is this an option item? */
		else if ( ud >= MNU_OPTION )
		{
			/* Option index */
			i = ud - MNU_OPTION;

			/* Set option according to checkmark status */
			*options[ i ].o_var = item->Flags & CHECKED ? TRUE : FALSE;

			/* Fake a dummy keypress to cause update */
			Term_keypress( ' ' );
		}

		/* Control key shortcuts */
		else if ( ud >= MNU_CKEYCOM )
		{
			/* Send keycode */
			Term_keypress( '\\' );
			Term_keypress( '^' );
			Term_keypress( ud - MNU_CKEYCOM );
		}

		/* Key shortcuts */
		else if ( ud >= MNU_KEYCOM )
		{
			/* Key code */
			i = ud - MNU_KEYCOM;

			/* Some functions need underlying keymap */
			if ( i != 't' && i != 'w' && i != 'T' )
			{
				Term_keypress( '\\' );
			}

			/* Send keycode */
			Term_keypress( i );
		}

		/* Scaled down Map of the dungeon */
		else if ( ud == MNU_SCALEDMAP )
		{
			/* Draw the map */
			amiga_map();
		}

		/* Find next menunumber */
		mnum = item->NextSelect;
	}
}

///}
///{ "cursor_on()"

static void cursor_on( term_data *td )
{
	int x0, y0, x1, y1;

	if ( !td->cursor_lit && !iconified )
	{
		td->cursor_frame = 0;

		/* Hack - Don't draw cursor at (0,0) */
		if ( td->cursor_xpos == 0 && td->cursor_ypos == 0 ) return;

		/* Draw an outlined cursor */
		if ( CUR_A & 0xf0 && use_graphics )
		{
			x0 = td->cursor_xpos * td->fw;
			y0 = td->cursor_ypos * td->fh;
			x1 = x0 + td->fw - 1;
			y1 = y0 + td->fh - 1;
			SetAPen( td->wrp, PEN( CURSOR_PEN ));
			Move( td->wrp, x0, y0 );
			Draw( td->wrp, x1, y0 );
			Draw( td->wrp, x1, y1 );
			Draw( td->wrp, x0, y1 );
			Draw( td->wrp, x0, y0 );
		}

		/* Draw a filled cursor */
		else
		{
			SetAPen( td->wrp, PEN( CUR_A & 0x0f ));
			SetBPen( td->wrp, PEN( CURSOR_PEN ));
			Move( td->wrp, td->fw * td->cursor_xpos, td->fh * td->cursor_ypos + td->fb );
			Text( td->wrp, &CUR_C, 1 );
		}

		td->cursor_lit = TRUE;
	}
}

///}
///{ "cursor_off()"

static void cursor_off( term_data *td )
{
	if ( td->cursor_lit && !iconified )
	{
		/* Restore graphics under cursor */
		if ( CUR_A & 0xf0 && use_graphics )
		{
			put_gfx( td->wrp, td->cursor_xpos, td->cursor_ypos, CUR_C, CUR_A );
		}

		/* Restore char/attr under cursor */
		else
		{
			SetAPen( td->wrp, PEN( CUR_A & 0x0f ));
			SetBPen( td->wrp, PEN( 0 ));
			Move( td->wrp, td->fw * td->cursor_xpos, td->fh * td->cursor_ypos + td->fb );
			Text( td->wrp, &CUR_C, 1 );
		}
		td->cursor_lit = FALSE;
	}
}

///}
///{ "cursor_anim()"

static void cursor_anim( void )
{
	term_data *td = term_curs;
	int x0, y0, x1, y1, i = p_ptr->px, j = p_ptr->py;
	byte tc, ta;

	if ( !term_curs ) return;

	td->cursor_frame = ++(td->cursor_frame) % 8;

	/* Small cursor on map */
	if ( td->cursor_map )
	{
		if ( td->cursor_frame & 2 )
		{
			SetAPen( td->wrp, PEN( CURSOR_PEN ));
			RectFill( td->wrp,
			          td->map_x + i * td->mpt_w,
			          td->map_y + j * td->mpt_h,
			          td->map_x + ( i + 1) * td->mpt_w - 1,
			          td->map_y + ( j + 1 ) * td->mpt_h - 1
			        );
		}
		else
		{
			ta = (( p_ptr->pclass * 10 + p_ptr->prace) >> 5 ) + 12;
			tc = (( p_ptr->pclass * 10 + p_ptr->prace) & 0x1f );
			put_gfx_map( td, i, j, tc, ta );
		}
	}

	else if ( td->cursor_visible && !iconified )
	{
		/* Hack - Don't draw cursor at (0,0) */
		if ( td->cursor_xpos == 0 && td->cursor_ypos == 0 ) return;

		/* Draw an outlined cursor */
		if ( CUR_A & 0x80 && use_graphics )
		{
			/* First draw the tile under cursor */
			put_gfx( td->wrp, td->cursor_xpos, td->cursor_ypos, CUR_C, CUR_A );

			if ( td->cursor_frame < 4 )
			{
				x0 = td->cursor_xpos * td->fw;
				y0 = td->cursor_ypos * td->fh;
				x1 = x0 + td->fw - 1;
				y1 = y0 + td->fh - 1;
				SetAPen( td->wrp, PEN( CURSOR_PEN ));
				Move( td->wrp, x0, y0 );
				Draw( td->wrp, x1, y0 );
				Draw( td->wrp, x1, y1 );
				Draw( td->wrp, x0, y1 );
				Draw( td->wrp, x0, y0 );
			}
		}

		/* Draw a filled cursor */
		else
		{
			SetAPen( td->wrp, PEN( CUR_A & 0x0f ));
			SetBPen( td->wrp, ( td->cursor_frame < 4 ) ? PEN( CURSOR_PEN ) : PEN( 0 ));
			Move( td->wrp, td->fw * td->cursor_xpos, td->fh * td->cursor_ypos + td->fb );
			Text( td->wrp, &CUR_C, 1 );
		}
	}
}

///}
///{ "load_gfx()"

int load_gfx( void )
{
	term_data *ts = &screen;
	BPTR file;
	char *p;
	int plane, row, error = FALSE;

	/* Allocate bitmaps */
	if (( ts->gfxbm = alloc_bitmap( GFXW, GFXH, 4, BMF_CLEAR, ts->rp->BitMap )) == NULL ) return ( FALSE );
	if (( ts->mskbm = alloc_bitmap( GFXW, GFXH, 1, BMF_CLEAR, ts->rp->BitMap )) == NULL ) return ( FALSE );

	/* Open file */
	if (( file = Open( MGFX, MODE_OLDFILE )) == NULL )
	{
		MSG( 0, 0, "Unable to open graphics file" );
		Delay( 100 );
		return ( FALSE );
	}

	/* Read file into bitmap */
	for ( plane = 0; plane < 4 && !error; plane++ )
	{
		p = ts->gfxbm->Planes[ plane ];
		for ( row = 0; row < GFXH && !error; row++ )
		{
			error = ( Read( file, p, GFXB ) != GFXB );
			p += ts->gfxbm->BytesPerRow;
		}
	}

	/* Read mask data into bitmap */
	p = ts->mskbm->Planes[ 0 ];
	for ( row = 0; row < GFXH && !error; row++ )
	{
		error = ( Read( file, p, GFXB ) != GFXB );
		p += ts->mskbm->BytesPerRow;
	}

	/* Close file */
	Close( file );

	/* Did we get any errors while reading? */
	if ( error )
	{
		MSG( 0, 0, "Error while reading graphics file" );
		Delay( 100 );
		return ( FALSE );
	}

	/* Success */
	return ( TRUE );
}
///}
///{ "conv_gfx()"

int conv_gfx( void )
{
	term_data *ts = &screen;
	struct BitMap *tmpbm;
	struct BitMap *sbm = ts->rp->BitMap;
	long stdpens[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
	long mskpens[] = { 0, -1 };
	int depth;
	BYTE *src, *dst;
	int plane, row, byt;

	/* Get depth of display */
	depth = depth_of_bitmap( sbm );

	/* We don't want 16 or 24 bit displays (yet) */
	if ( depth > 8 )
	{
		MSG( 0, 1, "Sorry, max. 8 bit display supported." );
		Delay( 100 );
		return ( FALSE );
	}

	/* Allocate new bitmap with screen's depth */
	if (( tmpbm = alloc_bitmap( GFXW, GFXH, depth, BMF_CLEAR, sbm )) == NULL )
	{
		MSG( 0, 1, "Unable to allocate temporary bitmap." );
		Delay( 100 );
		return ( FALSE );
	}

	/* Simple remapping from 4 to 5 planes? */
	if ( depth == 5 && !use_pub )
	{
		for ( plane = 0; plane < 4; plane++ )
		{
			src = ts->gfxbm->Planes[ plane ];
			dst = tmpbm->Planes[ plane ];
			for ( row = 0; row < GFXH; row++ )
			{
				for ( byt = 0; byt < GFXB; byt++ )
				{
					dst[ byt ] = src[ byt ];
				}
				src += ts->gfxbm->BytesPerRow;
				dst += tmpbm->BytesPerRow;
			}
		}
	}

	/* Complex remapping */
	else
	{
		/* Remap old bitmat into new bitmap */
		remap_bitmap( ts->gfxbm, tmpbm, use_pub ? pubpens : stdpens, GFXW, GFXH );
	}

	/* Free old bitmap */
	free_bitmap( ts->gfxbm );
	ts->gfxbm = tmpbm;

	/* Allocate new bitmap with screen's depth */
	if (( tmpbm = alloc_bitmap( GFXW, GFXH, depth, BMF_CLEAR, sbm )) == NULL )
	{
		MSG( 0, 1, "Unable to allocate temporary bitmap." );
		Delay( 100 );
		return ( FALSE );
	}

	/* Simple remapping from 4 to 5 planes? */
	if ( depth == 5 && !use_pub )
	{
		for ( plane = 0; plane < 4; plane++ )
		{
			src = ts->mskbm->Planes[ 0 ];
			dst = tmpbm->Planes[ plane ];
			for ( row = 0; row < GFXH; row++ )
			{
				for ( byt = 0; byt < GFXB; byt++ )
				{
					dst[ byt ] = src[ byt ];
				}
				src += ts->mskbm->BytesPerRow;
				dst += tmpbm->BytesPerRow;
			}
		}
	}

	/* Complex remapping */
	else
	{
		/* Remap old bitmap into new bitmap */
		remap_bitmap( ts->mskbm, tmpbm, mskpens, GFXW, GFXH );
	}

	/* Free old bitmap */
	free_bitmap( ts->mskbm );
	ts->mskbm = tmpbm;

	/* Done */
	return ( TRUE );
}

///}
///{ "size_gfx()"

int size_gfx( term_data *td )
{
	term_data *ts = &screen;
	int depth;
	struct BitMap *sbm = td->rp->BitMap;
	struct BitMap *tmpbm;

	/* Calculate tile bitmap dimensions */
	td->gfx_w = 32 * td->fw;
	td->gfx_h = 32 * td->fh;

	/* Calculate map bitmap dimensions */
	td->mpt_w = td->ww / MAX_WID;
	td->mpt_h = td->wh / MAX_HGT;
	td->map_w = td->mpt_w * 32;
	td->map_h = td->mpt_h * 32;

	/* Scale tile graphics into map size */
	depth = depth_of_bitmap( ts->gfxbm );
	if (( td->mapbm = alloc_bitmap( td->map_w, td->map_h, depth, BMF_CLEAR, sbm )) == NULL ) return ( FALSE );
	scale_bitmap( ts->gfxbm, GFXW, GFXH, td->mapbm, td->map_w, td->map_h );

	/* Scale tile graphics */
	depth = depth_of_bitmap( ts->gfxbm );
	if (( tmpbm = alloc_bitmap( td->gfx_w, td->gfx_h, depth, BMF_CLEAR, sbm )) == NULL ) return ( FALSE );
	scale_bitmap( ts->gfxbm, GFXW, GFXH, tmpbm, td->gfx_w, td->gfx_h );
	if ( td->gfxbm ) free_bitmap( td->gfxbm );
	td->gfxbm = tmpbm;

	/* Scale tile mask */
	depth = depth_of_bitmap( ts->mskbm );
	if (( tmpbm = alloc_bitmap( td->gfx_w, td->gfx_h, depth, BMF_CLEAR, sbm )) == NULL ) return ( FALSE );
	scale_bitmap( ts->mskbm, GFXW, GFXH, tmpbm, td->gfx_w, td->gfx_h );
	if ( td->mskbm ) free_bitmap( td->mskbm );
	td->mskbm = tmpbm;

	/* Success */
	return ( TRUE );
}

///}
///{ "put_gfx()"

static void put_gfx( struct RastPort *rp, int x, int y, int chr, int col )
{
	term_data *td = (term_data*)(Term->data);
	int fw = td->fw;
	int fh = td->fh;
	int x0 = x * fw;
	int y0 = y * fh;
	int x1 = x0 + fw - 1;
	int y1 = y0 + fh - 1;
	int a = col & 0x1f;
	int c = chr & 0x1f;

	/* Just a black tile */
	if ( a == 0 && c == 0 )
	{
		SetAPen( rp, PEN( 0 ));
		RectFill( rp, x0, y0, x1, y1 );
		return;
	}

	/* Player - Remap for race and class */
	if ( a == 12 && c == 0 )
	{
		a = (( p_ptr->pclass * 10 + p_ptr->prace) >> 5 ) + 12;
		c = (( p_ptr->pclass * 10 + p_ptr->prace) & 0x1f );
	}

	/* Draw tile through mask */
	if ( col & 0x40 )
	{
		SetAPen( rp, PEN(0) );
		RectFill( rp, x0, y0, x1, y1 );
		BltMaskBitMapRastPort( td->gfxbm, c * fw, a * fh, rp, x0, y0, fw, fh, (ABC | ANBC | ABNC), td->mskbm->Planes[ 0 ] );
	}

	/* Draw full tile */
	else
	{
		BltBitMapRastPort( td->gfxbm, c * fw, a * fh, rp, x0, y0, fw, fh, 0xc0 );
	}
}

///}
///{ "amiga_fail()"

static int amiga_fail( char *msg )
{
	int i;

	/* Print error message */
	if ( msg )
	{
		fprintf( stderr, "%s\n", msg );
	}

	/* Free sound memory */
	free_sound();

	/* Unlock public screen */
	if ( publock )
	{
		UnlockPubScreen( NULL, pubscr );
		publock = FALSE;
	}

	/* Remove menu from window */
	if ( menu && screen.win )
	{
		ClearMenuStrip( screen.win );
	}

	/* Free menus */
	if ( menu )
	{
		FreeMenus( menu );
		menu = NULL;
	}

	/* Free term resources */
	free_term( &mirror );
	free_term( &recall );
	free_term( &choice );
	free_term( &screen );

	/* Free obtained pens */
	if ( pubscr )
	{
		for ( i = 0; i < 32; i++)
		{
			if ( pubpens[ i ] != -1 )
			{
				ReleasePen( pubscr->ViewPort.ColorMap, pubpens[ i ]);
			}
		}
	}

	/* Free visual info */
	if ( visinfo )
	{
		FreeVisualInfo( visinfo );
		visinfo = NULL;
	}

	/* Close intuition screen */
	if ( amiscr )
	{
		CloseScreen( amiscr );
		amiscr = NULL;
	}

	/* Close gadtools.library */
	if ( GadToolsBase )
	{
		CloseLibrary( GadToolsBase );
		GadToolsBase = NULL;
	}

	/* Close keymap.library */
	if ( KeymapBase )
	{
		CloseLibrary( KeymapBase );
		KeymapBase = NULL;
	}

	/* Close keymap.library */
	if ( DiskfontBase )
	{
		CloseLibrary( DiskfontBase );
		DiskfontBase = NULL;
	}

	// Return failure
	return ( -1);
}

///}
///{ "amiga_map()"

static void amiga_map( void )
{
	term_data *td = &screen;  // (term_data*)(Term->data);
	int i, j;
	byte ta, tc;

	/* Only in graphics mode */
	if ( !use_graphics ) return;

	/* Turn off cursor */
	if ( td->cursor_visible ) cursor_off( td );

	/* Save screen */
	Term_save();

	/* Clear screen */
	Term_clear();
	Term_fresh();

	/* Calculate offset values */
	td->map_x = (( td->fw * 80 ) - ( td->mpt_w * cur_wid )) / 2;
	td->map_y = (( td->fh * 24 ) - ( td->mpt_h * cur_hgt )) / 2;

	/* Draw all "interesting" features */
	for ( i = 0; i < cur_wid; i++ )
	{
		for ( j = 0; j < cur_hgt; j++ )
		{
			/* Get frame tile */
			if ( i == 0 || i == cur_wid - 1 || j == 0 || j == cur_hgt - 1 )
			{
				ta = f_info[ 63 ].z_attr;
				tc = f_info[ 63 ].z_char;
			}

			/* Get tile from cave table */
			else
			{
				map_info( j, i, &ta, (char *) &tc );
			}

			/* Ignore non-graphics */
			if ( ta & 0x80 )
			{
				ta &= 0x1f;
				tc &= 0x1f;

				/* Player XXX XXX XXX */
				if ( ta == 12 && tc == 0 )
				{
					ta = (( p_ptr->pclass * 10 + p_ptr->prace ) >> 5 ) + 12;
					tc = (( p_ptr->pclass * 10 + p_ptr->prace ) & 0x1f );
				}

				/* Put the graphics to the screen */
				put_gfx_map( td, i, j, tc, ta );
			}
		}
	}

	/* Draw a small cursor now */
	td->cursor_map = TRUE;

	/* Wait for a keypress, flush key buffer */
	Term_inkey( &tc, TRUE, TRUE );
	Term_flush();

	/* Normal cursor again */
	td->cursor_map = FALSE;

	/* Restore screen */
	Term_clear();
	Term_fresh();
	Term_load();
	Term_fresh();

	/* Turn cursor back on */
	if ( td->cursor_visible ) cursor_on( td );
}

///}
///{ "load_palette()"

void load_palette( void )
{
	int i;
	int n;

	if ( amiscr == NULL ) return;

	n = deep ? 32 : 16;

	if ( v39 )
	{
		palette32[ 0 ] = n << 16;
		palette32[ n * 3 + 1 ] = 0;
		for ( i = 0; i < n; i++ )
		{
			palette32[ i * 3 + 1 ] = color_table[ use_graphics ? i : i + 16 ][ 1 ] << 24;
			palette32[ i * 3 + 2 ] = color_table[ use_graphics ? i : i + 16 ][ 2 ] << 24;
			palette32[ i * 3 + 3 ] = color_table[ use_graphics ? i : i + 16 ][ 3 ] << 24;
		}
		LoadRGB32( &amiscr->ViewPort, palette32 );
	}
	else
	{
		for ( i = 0; i < n; i++ )
		{
			palette4[ i ] = ( color_table[ use_graphics ? i : i + 16 ][ 1 ] >> 4 ) << 8;
			palette4[ i ] |= ( color_table[ use_graphics ? i : i + 16 ][ 2 ] >> 4 ) << 4;
			palette4[ i ] |= ( color_table[ use_graphics ? i : i + 16 ][ 3 ] >> 4 );
		}
		LoadRGB4( &amiscr->ViewPort, palette4, n );
	}
}

///}
///{ "create_menus()"

int create_menus( void )
{
	option_type *opt;
	struct NewMenu *item = newmenu;
	int nmsize = sizeof ( struct NewMenu );
	int page = -1;
	int pg = 0;
	int i, o;

	/* Copy all pre-items into array */
	for ( i = 0; pre_item[ i ].nm_Type != 255; i++ )
	{
		memcpy( item++, &pre_item[ i ], nmsize );
	}

	/* Find next option */
	for ( opt = options, o = 0; opt->o_desc; opt++, o++ )
	{
		/* Cheating options are skipped */
		if ( opt->o_page > 6 ) continue;

		/* New page of options? */
		if ( page != opt->o_page )
		{
			page = opt->o_page;

			/* Copy option header */
			memcpy( item++, &opt_item[ pg++ ], nmsize );
		}

		/* Insert fields for this option */
		item->nm_Type = NM_SUB;
		item->nm_CommKey = 0;
		item->nm_MutualExclude = 0;

		/* Use option description as menu text */
		item->nm_Label = (STRPTR) opt->o_desc;

		/* Insert option index into userdata field */
		item->nm_UserData = (void *)( MNU_OPTION + o );

		/* Use checkmark on this item */
		item->nm_Flags = CHECKIT | MENUTOGGLE;

		/* Done with this item */
		item++;
	}

	/* Copy all post-items into array */
	for ( i = 0; post_item[ i ].nm_Type != 255; i++ )
	{
		memcpy( item++, &post_item[ i ], nmsize );
	}

	/* Actually create the menu structures */
	menu = CreateMenus( newmenu, NULL );

	if ( menu )
	{
		/* Layout menus */
		if ( LayoutMenus( menu, visinfo, v39 ? GTMN_NewLookMenus : TAG_IGNORE, TRUE, TAG_END ))
		{
			/* Attach menu to window */
			SetMenuStrip( screen.win , menu );
		}

		/* Free menus */
		else
		{
			FreeMenus( menu );
			menu = NULL;
		}
	}

	/* Success */
	return ( menu != NULL );
}

///}
///{ "update_menus()"

void update_menus( void )
{
	struct MenuItem *father, *item;
	int i;

	/* Require a window and a menu */
	if ( !screen.win || !menu ) return;

	/* Detach the menu from the window */
	//   ClearMenuStrip( screen.win );

	/* Initial menuitem and subitem for options */
	father = menu->FirstItem;
	item = father->SubItem;

	/* Find next option */
	for ( i = 0; item && options[ i ].o_desc; i++ )
	{
		/* Did we find it? */
		if ( item )
		{
			/* Option is set, add a checkmark */
			if ( *(options[ i ].o_var ))
			{
				item->Flags |= CHECKED;
			}

			/* Option is not set, remove checkmark */
			else
			{
				item->Flags &= ~CHECKED;
			}
		}

		/* Menuitem not found */
		else
		{
			fprintf( stderr, "ERROR: menuitem #%d not found.\n", i );
			return;
		}

		/* Find next menuitem */
		if ((item = item->NextItem ) == NULL )
		{
			/* New set */
			father = father->NextItem;
			if ( father )
			{
				item = father->SubItem;
			}
		}
	}

	/* Enable/Disable the amiga map according to use_graphics */
	if ( item = ItemAddress( menu, FULLMENUNUM( 6, 7, 0 )))
	{
		item->Flags = use_graphics ? item->Flags | ITEMENABLED : item->Flags & ~ITEMENABLED;
	}

	/* Attach menu to window again */
	//   ResetMenuStrip( screen.win, menu );
}

///}
///{ "init_sound()"


int init_sound( void )
{
	int i;
	char tmp[256];
	char buf[256];
	struct AmiSound *snd;

	/* Load samples */
	for ( i = 0; i < NSAMPLES; i++ )
	{
		/* Pointer to sound data */
		snd = &sound_data[ i ];

		/* Should this sample be loaded into memory? */
		if ( snd->Memory )
		{
			/* Construct filename */
			path_build(buf, 255, ANGBAND_DIR_XTRA, "sound");

			/* Construct filename */
			path_build(tmp, 255, buf, snd->Name );

			/* Load the sample into memory */
			snd->Address = (struct SoundInfo *) PrepareSound( tmp );
		}
	}

	/* Success */
	has_sound = TRUE;
	use_sound = TRUE;

	return ( TRUE );
}

///}
///{ "free_sound()"

void free_sound( void )
{
	int i;

	/* Stop all channels */
	StopSound( LEFT0 );
	StopSound( LEFT1 );
	StopSound( RIGHT0 );
	StopSound( RIGHT1 );

	/* Remove all sounds from memory */
	for ( i = 0; i < NSAMPLES; i++ )
	{
		if ( sound_data[ i ].Address )
		{
			/* Remove the sound from memory */
			RemoveSound( sound_data[ i ].Address );

			/* Clear address field */
			sound_data[ i ].Address = NULL;
		}
	}

	/* Done */
	has_sound = FALSE;
	use_sound = FALSE;
}

///}
///{ "play_sound()"

static void play_sound( int v )
{
	struct AmiSound *snd;
	struct AmiSound *old_snd;
	int rate;
	int channel;
	int old;
	char buf[256];
	char tmp[256];

	if ( has_sound )
	{
		/* Pointer to sound data */
		snd = &sound_data[ v ];

		/* Channel number */
		channel = snd->Channel;

		/* Last sample played on channel */
		old = channel_last[ channel ];

		/* Sample Rate */
		rate = snd->Rate;

		/* Random rate on some sounds */
		if ( v == SOUND_HIT || v == SOUND_MISS )
		{
			rate = rate - 50 + rand_int( 150 );
		}

		/* Pointer to old sound data */
		old_snd = old >= 0 ? &sound_data[ old ] : NULL;

		/* Stop sound currently playing on this channel */
		StopSound( channel );

		/* Free old sample if required */
		if ( !old_snd->Memory && old_snd->Address && old != v )
		{
			/* Remove it from memory */
			RemoveSound( old_snd->Address );

			/* Clear address field */
			old_snd->Address = NULL;
		}

		/* Load new sample into memory if required */
		if ( !snd->Memory && snd->Address == NULL )
		{
			/* Construct filename */
			path_build(buf, 255, ANGBAND_DIR_XTRA, "sound");

			/* Construct filename */
			path_build(tmp, 255, buf, snd->Name );

			/* Load the sample into memory */
			snd->Address = (struct SoundInfo *) PrepareSound( tmp );
		}

		/* Make sure the sample is loaded into memory */
		if ( snd->Address )
		{
			/* Start playing the sound */
			PlaySound( snd->Address, snd->Volume, channel, rate, snd->Repeats );
		}

		/* Store sample number */
		channel_last[ channel ] = v;
	}
}

///}
///{ put_gfx_map()

static void put_gfx_map( term_data *td, int x, int y, int c, int a )
{
	BltBitMapRastPort(
	        td->mapbm,
	        c * td->mpt_w,
	        a * td->mpt_h,
	        td->wrp,
	        td->map_x + x * td->mpt_w,
	        td->map_y + y * td->mpt_h,
	        td->mpt_w,
	        td->mpt_h,
	        0xc0
	);
}

///}
///{ "alloc_bitmap()"

struct BitMap *alloc_bitmap( int width, int height, int depth, ULONG flags, struct BitMap *friend )
{
	int p;
	struct BitMap *bitmap;
	unsigned char *bp;

	/* Kickstart 39+ */
	if ( v39 ) return ( AllocBitMap( width, height, depth, flags, friend ));

	/* Kickstart 38- */
	else
	{
		/* Allocate bitmap structure */
		if (( bitmap = AllocMem( sizeof( struct BitMap ), MEMF_PUBLIC | MEMF_CLEAR )))
		{
			InitBitMap( bitmap, depth, width, height );
			/* Allocate bitplanes */
			for ( p = 0; p < depth; p++ )
			{
				bp = AllocRaster( width, height );
				if ( !bp ) break;
				bitmap->Planes[ p ] = bp;
			}

			/* Out of memory */
			if ( p != depth )
			{
				/* Free bitplanes */
				while ( --p >= 0 )
				{
					FreeRaster( bitmap->Planes[ p ], width, height );
				}
				/* Free bitmap structure */
				FreeMem( bitmap, sizeof( struct BitMap ));
				bitmap = NULL;
			}
		}
		return ( bitmap );
	}
}

///}
///{ "free_bitmap()"

void free_bitmap( struct BitMap *bitmap )
{
	int p;

	/* Check for NULL */
	if ( !bitmap ) return;

	/* Kickstart 39+ */
	if ( v39 ) FreeBitMap( bitmap );

	/* Kickstart 38- */
	else
	{
		/* Free bitplanes */
		for ( p = 0; p < bitmap->Depth; p++ )
		{
			FreeRaster( bitmap->Planes[ p ], bitmap->BytesPerRow * 8, bitmap->Rows );
		}
		/* Free bitmap structure */
		FreeMem( bitmap, sizeof( struct BitMap ));
	}
}

///}
///{ scale_bitmap()

void scale_bitmap( struct BitMap *srcbm, int srcw, int srch, struct BitMap *dstbm, int dstw, int dsth )
{
	struct BitScaleArgs bsa;

	/* Scale bitmap */
	bsa.bsa_SrcBitMap = srcbm;
	bsa.bsa_DestBitMap = dstbm;
	bsa.bsa_SrcX = 0;
	bsa.bsa_SrcY = 0;
	bsa.bsa_SrcWidth = srcw;
	bsa.bsa_SrcHeight = srch;
	bsa.bsa_DestX = 0;
	bsa.bsa_DestY = 0;
	bsa.bsa_XSrcFactor = srcw;
	bsa.bsa_YSrcFactor = srch;
	bsa.bsa_XDestFactor = dstw;
	bsa.bsa_YDestFactor = dsth;
	bsa.bsa_Flags = 0;
	BitMapScale( &bsa );
}

///}
///{ "remap_bitmap()"

void remap_bitmap( struct BitMap *srcbm, struct BitMap *dstbm, long *pens, int width, int height )
{
	int x, y, p, c, ox, lpr, sd, dd;
	int bm[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
	UBYTE *sp[ 4 ];
	UBYTE *dp[ 8 ];
	ULONG ls[ 4 ];
	ULONG ld[ 8 ];
	ULONG mask;

	/* Source bitplanes */
	sd = depth_of_bitmap( srcbm );
	for ( p = 0; p < sd; p++ )
	{
		sp[ p ] = srcbm->Planes[ p ];
	}

	/* Destination bitplanes */
	dd = depth_of_bitmap( dstbm );
	for ( p = 0; p < dd; p++ )
	{
		dp[ p ] = dstbm->Planes[ p ];
	}

	/* Number of longwords per row */
	lpr = width / 32;

	/* Convert graphics */
	for ( y = 0; y < height; y++ )
	{
		ox = 0;
		for ( x = 0 ; x < lpr; x++ )
		{
			/* Read source longwords */
			for ( p = 0; p < sd; p++ ) ls[ p ] = *(ULONG *)( sp[ p ] + ox);

			/* Clear destination longwords */
			for ( p = 0; p < dd; ld[ p++ ] = 0 );

			/* Remap */
			for ( mask = 0x80000000; mask != 0; mask >>= 1)
			{
				/* Find color index */
				for ( p = c = 0; p < sd; p++ ) if ( ls[ p ] & mask ) c |= bm[ p ];

				/* Remap */
				c = pens[ c ];

				/* Update destination longwords */
				for ( p = 0; p < dd; p++ ) if ( c & bm[ p ] ) ld[ p ] |= mask;
			}

			/* Write destination longwords */
			for ( p = 0; p < dd; p++ ) *(ULONG *)( dp[ p ] + ox ) = ld[ p ];

			/* Update offset */
			ox += 4;
		}

		/* Update pointers to get to next line */
		for ( p = 0; p < sd; sp[ p++ ] += srcbm->BytesPerRow );
		for ( p = 0; p < dd; dp[ p++ ] += dstbm->BytesPerRow );
	}
}

///}
///{ "depth_of_bitmap()"

int depth_of_bitmap( struct BitMap *bm )
{
	int depth;

	if ( v39 )
	{
		depth = GetBitMapAttr( bm, BMA_DEPTH );
	}
	else
	{
		depth = bm->Depth;
	}

	return ( depth );
}

///}

tome-235-src/src/main-cap.c0000644000076400017500000004512211012107763013312 0ustar  dgdg/* File: main-cap.c */

/* Purpose: Support for "term.c" using "termcap" calls */

#include "angband.h"


#ifdef USE_CAP


/*
 * This file is a total hack, but is often very helpful.  :-)
 *
 * This file allows use of the terminal without requiring the
 * "curses" routines.  In fact, if "USE_HARDCODE" is defined,
 * this file will attempt to use various hard-coded "vt100"
 * escape sequences to also avoid the use of the "termcap"
 * routines.  I do not know if this will work on System V.
 *
 * This file is intended for use only on those machines which are
 * unable, for whatever reason, to compile the "main-gcu.c" file,
 * but which seem to be able to support the "termcap" library, or
 * which at least seem able to support "vt100" terminals.
 *
 * Large portions of this file were stolen from "main-gcu.c"
 *
 * This file incorrectly handles output to column 80, I think.
 */


/*
 * Require a "system"
 */
#if !defined(USE_TERMCAP) && !defined(USE_HARDCODE)
# define USE_TERMCAP
#endif

/*
 * Hack -- try to guess which systems use what commands
 * Hack -- allow one of the "USE_Txxxxx" flags to be pre-set.
 * Mega-Hack -- try to guess when "POSIX" is available.
 * If the user defines two of these, we will probably crash.
 */
#if !defined(USE_TPOSIX)
# if !defined(USE_TERMIO) && !defined(USE_TCHARS)
# if defined(_POSIX_VERSION)
# define USE_TPOSIX
# else
# if defined(USG) || defined(linux) || defined(SOLARIS)
# define USE_TERMIO
# else
# define USE_TCHARS
# endif 
# endif 
# endif 
#endif



/*
 * POSIX stuff
 */
#ifdef USE_TPOSIX
# include 
# include 
#endif

/*
 * One version needs these files
 */
#ifdef USE_TERMIO
# include 
# include 
#endif

/*
 * The other needs these files
 */
#ifdef USE_TCHARS
# include 
# include 
# include 
# include 
# include 
#endif


/*
 * XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
 *
 * They should both work due to the "(i != 1)" test in the code
 * which checks for the result of the "read()" command.
 */
#ifndef O_NDELAY
# define O_NDELAY O_NONBLOCK
#endif




#ifdef USE_TERMCAP

/*
 * Termcap string information
 */

static char blob[1024]; 		/* The "termcap" entry */
static char area[1024]; 		/* The string extraction buffer */
static char *next = area; 	/* The current "index" into "area" */
static char *desc; 		/* The terminal name */

#endif


/*
 * Pointers into the "area"
 */

static char *cm; 	/* Move cursor */
static char *ch; 	/* Move cursor to horizontal location */
static char *cv; 	/* Move cursor to vertical location */
static char *ho; 	/* Move cursor to top left */
static char *ll; 	/* Move cursor to bottom left */
static char *cs; 	/* Set scroll area */
static char *cl; 	/* Clear screen */
static char *cd; 	/* Clear to end of display */
static char *ce; 	/* Clear to end of line */
static char *cr; 	/* Move to start of line */
static char *so; 	/* Turn on standout */
static char *se; 	/* Turn off standout */
static char *md; 	/* Turn on bold */
static char *me; 	/* Turn off bold */
static char *vi; 	/* Cursor - invisible */
static char *ve; 	/* Cursor - normal */
static char *vs; 	/* Cursor - bright */


/*
 * State variables
 */

static int rows; 	/* Screen size (Y) */
static int cols; 	/* Screen size (X) */
static int curx; 	/* Cursor location (X) */
static int cury; 	/* Cursor location (Y) */
static int curv; 	/* Cursor visibility */


/*
 * Extern functions
 */
extern char *getenv();
extern char *tgoto();
extern char *tgetstr();


/*
 * Write some chars to the terminal
 */
static void ewrite(char *str)
{
	int numtowrite, numwritten;

	/* See how much work we have */
	numtowrite = strlen(str);

	/* Write until done */
	while (numtowrite > 0)
	{
		/* Try to write the chars */
		numwritten = write(1, str, numtowrite);

		/* Handle FIFOs and EINTR */
		if (numwritten < 0) numwritten = 0;

		/* See what we completed */
		numtowrite -= numwritten;
		str += numwritten;

		/* Hack -- sleep if not done */
		if (numtowrite > 0) sleep(1);
	}
}



#ifdef USE_TERMCAP

static char write_buffer[128];
static char *write_buffer_ptr;

static void output_one(char c)
{
	*write_buffer_ptr++ = c;
}

static void tp(char *s)
{
	/* Dump the string into us */
	write_buffer_ptr = write_buffer;

	/* Write the string with padding */
	tputs (s, 1, output_one);

	/* Finish the string */
	*write_buffer_ptr = '\0';

	/* Dump the recorded buffer */
	ewrite (write_buffer);
}

#endif

#ifdef USE_HARDCODE

static void tp(char *s)
{
	ewrite(s);
}

#endif







/*
 * Clear the screen
 */
static void do_cl(void)
{
	if (cl) tp (cl);
}

/*
 * Clear to the end of the line
 */
static void do_ce(void)
{
	if (ce) tp(ce);
}


/*
 * Set the cursor visibility (0 = invis, 1 = normal, 2 = bright)
 */
static void curs_set(int vis)
{
	char *v = NULL;

	if (!vis)
	{
		v = vi;
	}
	else if (vis > 1)
	{
		v = vs ? vs : ve;
	}
	else
	{
		v = ve ? ve : vs;
	}

	if (v) tp(v);
}



/*
 * Restrict scrolling to within these rows
 */
static void do_cs(int y1, int y2)
{

#ifdef USE_TERMCAP
	if (cs) tp(tgoto(cs, y2, y1));
#endif

#ifdef USE_HARDCODE
	char temp[64];
	sprintf(temp, cs, y1, y2);
	tp (temp);
#endif

}



/*
 * Go to the given screen location directly
 */
static void do_cm(int x, int y)
{

#ifdef USE_TERMCAP
	if (cm) tp(tgoto(cm, x, y));
#endif

#ifdef USE_HARDCODE
	char temp[64];
	sprintf(temp, cm, y + 1, x + 1);
	tp(temp);
#endif

}


/*
 * Go to the given screen location in a "clever" manner
 *
 * XXX XXX XXX This function could use some work!
 */
static void do_move(int x1, int y1, int x2, int y2)
{
	/* Hack -- unknown start location */
	if ((x1 == x2) && (y1 == y2)) do_cm(x2, y2);

	/* Left edge */
	else if (x2 == 0)
	{
		if ((y2 <= 0) && ho) tp(ho);
		else if ((y2 >= rows - 1) && ll) tp(ll);
		else if ((y2 == y1) && cr) tp(cr);
#if 0
		else if ((y2 == y1 + 1) && cr && dn)
		{
			tp(cr);
			tp(dn);
		}
		else if ((y2 == y1 - 1) && cr && up)
		{
			tp(cr);
			tp(up);
		}
#endif
		else do_cm(x2, y2);
	}

#if 0
	/* Up/Down one line */
	else if ((x2 == x1) && (y2 == y1 + 1) && dn) tp(dn);
	else if ((x2 == x1) && (y2 == y1 - 1) && up) tp(up);
#endif

	/* Default -- go directly there */
	else do_cm(x2, y2);
}




/*
 * Help initialize this file (see below)
 */
errr init_cap_aux(void)
{

#ifdef USE_TERMCAP

	/* Get the terminal name (if possible) */
	desc = getenv("TERM");
	if (!desc) return (1);

	/* Get the terminal info */
	if (tgetent(blob, desc) != 1) return (2);

	/* Get the (initial) columns and rows, or default */
	if ((cols = tgetnum("co")) == -1) cols = 80;
	if ((rows = tgetnum("li")) == -1) rows = 24;

	/* Find out how to move the cursor to a given location */
	cm = tgetstr("cm", &next);
	if (!cm) return (10);

	/* Find out how to move the cursor to a given position */
	ch = tgetstr("ch", &next);
	cv = tgetstr("cv", &next);

	/* Find out how to "home" the screen */
	ho = tgetstr("ho", &next);

	/* Find out how to "last-line" the screen */
	ll = tgetstr("ll", &next);

	/* Find out how to do a "carriage return" */
	cr = tgetstr("cr", &next);
	if (!cr) cr = "\r";

	/* Find out how to clear the screen */
	cl = tgetstr("cl", &next);
	if (!cl) return (11);

	/* Find out how to clear to the end of display */
	cd = tgetstr("cd", &next);

	/* Find out how to clear to the end of the line */
	ce = tgetstr("ce", &next);

	/* Find out how to scroll (set the scroll region) */
	cs = tgetstr("cs", &next);

	/* Find out how to hilite */
	so = tgetstr("so", &next);
	se = tgetstr("se", &next);
	if (!so || !se) so = se = NULL;

	/* Find out how to bold */
	md = tgetstr("md", &next);
	me = tgetstr("me", &next);
	if (!md || !me) md = me = NULL;

	/* Check the cursor visibility stuff */
	vi = tgetstr("vi", &next);
	vs = tgetstr("vs", &next);
	ve = tgetstr("ve", &next);

#endif

#ifdef USE_HARDCODE

	/* Assume some defualt information */
	rows = 24;
	cols = 80;

	/* Clear screen */
	cl = "\033[2J\033[H"; 	/* --]--]-- */

	/* Clear to end of line */
	ce = "\033[K"; 	/* --]-- */

	/* Hilite on/off */
	so = "\033[7m"; 	/* --]-- */
	se = "\033[m"; 	/* --]-- */

	/* Scroll region */
	cs = "\033[%d;%dr"; 	/* --]-- */

	/* Move cursor */
	cm = "\033[%d;%dH"; 	/* --]-- */

#endif

	/* Success */
	return (0);
}







/*
 * Save the "normal" and "angband" terminal settings
 */

#ifdef USE_TPOSIX

static struct termios norm_termios;

static struct termios game_termios;

#endif

#ifdef USE_TERMIO

static struct termio norm_termio;

static struct termio game_termio;

#endif

#ifdef USE_TCHARS

static struct sgttyb norm_ttyb;
static struct tchars norm_tchars;
static struct ltchars norm_ltchars;
static int norm_local_chars;

static struct sgttyb game_ttyb;
static struct tchars game_tchars;
static struct ltchars game_ltchars;
static int game_local_chars;

#endif



/*
 * Are we active?  Not really needed.
 */
static int active = FALSE;


/*
 * The main screen (no sub-screens)
 */
static term term_screen_body;



/*
 * Place the "keymap" into its "normal" state
 */
static void keymap_norm(void)
{

#ifdef USE_TPOSIX

	/* restore the saved values of the special chars */
	(void)tcsetattr(0, TCSAFLUSH, &norm_termios);

#endif

#ifdef USE_TERMIO

	/* restore the saved values of the special chars */
	(void)ioctl(0, TCSETA, (char *)&norm_termio);

#endif

#ifdef USE_TCHARS

	/* restore the saved values of the special chars */
	(void)ioctl(0, TIOCSETP, (char *)&norm_ttyb);
	(void)ioctl(0, TIOCSETC, (char *)&norm_tchars);
	(void)ioctl(0, TIOCSLTC, (char *)&norm_ltchars);
	(void)ioctl(0, TIOCLSET, (char *)&norm_local_chars);

#endif

}


/*
 * Place the "keymap" into the "game" state
 */
static void keymap_game(void)
{

#ifdef USE_TPOSIX

	/* restore the saved values of the special chars */
	(void)tcsetattr(0, TCSAFLUSH, &game_termios);

#endif

#ifdef USE_TERMIO

	/* restore the saved values of the special chars */
	(void)ioctl(0, TCSETA, (char *)&game_termio);

#endif

#ifdef USE_TCHARS

	/* restore the saved values of the special chars */
	(void)ioctl(0, TIOCSETP, (char *)&game_ttyb);
	(void)ioctl(0, TIOCSETC, (char *)&game_tchars);
	(void)ioctl(0, TIOCSLTC, (char *)&game_ltchars);
	(void)ioctl(0, TIOCLSET, (char *)&game_local_chars);

#endif

}


/*
 * Save the normal keymap
 */
static void keymap_norm_prepare(void)
{

#ifdef USE_TPOSIX

	/* Get the normal keymap */
	tcgetattr(0, &norm_termios);

#endif

#ifdef USE_TERMIO

	/* Get the normal keymap */
	(void)ioctl(0, TCGETA, (char *)&norm_termio);

#endif

#ifdef USE_TCHARS

	/* Get the normal keymap */
	(void)ioctl(0, TIOCGETP, (char *)&norm_ttyb);
	(void)ioctl(0, TIOCGETC, (char *)&norm_tchars);
	(void)ioctl(0, TIOCGLTC, (char *)&norm_ltchars);
	(void)ioctl(0, TIOCLGET, (char *)&norm_local_chars);

#endif

}


/*
 * Save the keymaps (normal and game)
 */
static void keymap_game_prepare(void)
{

#ifdef USE_TPOSIX

	/* Acquire the current mapping */
	tcgetattr(0, &game_termios);

	/* Force "Ctrl-C" to interupt */
	game_termios.c_cc[VINTR] = (char)3;

	/* Force "Ctrl-Z" to suspend */
	game_termios.c_cc[VSUSP] = (char)26;

	/* Hack -- Leave "VSTART/VSTOP" alone */

	/* Disable the standard control characters */
	game_termios.c_cc[VQUIT] = (char) - 1;
	game_termios.c_cc[VERASE] = (char) - 1;
	game_termios.c_cc[VKILL] = (char) - 1;
	game_termios.c_cc[VEOF] = (char) - 1;
	game_termios.c_cc[VEOL] = (char) - 1;

	/* Normally, block until a character is read */
	game_termios.c_cc[VMIN] = 1;
	game_termios.c_cc[VTIME] = 0;

	/* Hack -- Turn off "echo" and "canonical" mode */
	game_termios.c_lflag &= ~(ECHO | ICANON);

#endif

#ifdef USE_TERMIO

	/* Acquire the current mapping */
	(void)ioctl(0, TCGETA, (char *)&game_termio);

	/* Force "Ctrl-C" to interupt */
	game_termio.c_cc[VINTR] = (char)3;

	/* Force "Ctrl-Z" to suspend */
	game_termio.c_cc[VSUSP] = (char)26;

	/* Hack -- Leave "VSTART/VSTOP" alone */

	/* Disable the standard control characters */
	game_termio.c_cc[VQUIT] = (char) - 1;
	game_termio.c_cc[VERASE] = (char) - 1;
	game_termio.c_cc[VKILL] = (char) - 1;
	game_termio.c_cc[VEOF] = (char) - 1;
	game_termio.c_cc[VEOL] = (char) - 1;

#if 0
	/* Disable the non-posix control characters */
	game_termio.c_cc[VEOL2] = (char) - 1;
	game_termio.c_cc[VSWTCH] = (char) - 1;
	game_termio.c_cc[VDSUSP] = (char) - 1;
	game_termio.c_cc[VREPRINT] = (char) - 1;
	game_termio.c_cc[VDISCARD] = (char) - 1;
	game_termio.c_cc[VWERASE] = (char) - 1;
	game_termio.c_cc[VLNEXT] = (char) - 1;
	game_termio.c_cc[VSTATUS] = (char) - 1;
#endif

	/* Normally, block until a character is read */
	game_termio.c_cc[VMIN] = 1;
	game_termio.c_cc[VTIME] = 0;

	/* Hack -- Turn off "echo" and "canonical" mode */
	game_termio.c_lflag &= ~(ECHO | ICANON);

#endif

#ifdef USE_TCHARS

	/* Get the default game characters */
	(void)ioctl(0, TIOCGETP, (char *)&game_ttyb);
	(void)ioctl(0, TIOCGETC, (char *)&game_tchars);
	(void)ioctl(0, TIOCGLTC, (char *)&game_ltchars);
	(void)ioctl(0, TIOCLGET, (char *)&game_local_chars);

	/* Force interupt (^C) */
	game_tchars.t_intrc = (char)3;

	/* Force start/stop (^Q, ^S) */
	game_tchars.t_startc = (char)17;
	game_tchars.t_stopc = (char)19;

	/* Cancel some things */
	game_tchars.t_quitc = (char) - 1;
	game_tchars.t_eofc = (char) - 1;
	game_tchars.t_brkc = (char) - 1;

	/* Force suspend (^Z) */
	game_ltchars.t_suspc = (char)26;

	/* Cancel some things */
	game_ltchars.t_dsuspc = (char) - 1;
	game_ltchars.t_rprntc = (char) - 1;
	game_ltchars.t_flushc = (char) - 1;
	game_ltchars.t_werasc = (char) - 1;
	game_ltchars.t_lnextc = (char) - 1;

	/* XXX XXX XXX XXX Verify this before use */
	/* Hack -- Turn off "echo" and "canonical" mode */
	/* game_termios.c_lflag &= ~(ECHO | ICANON); */
	game_ttyb.flag &= ~(ECHO | ICANON);

#endif

}








/*
 * Suspend/Resume
 */
static errr Term_xtra_cap_alive(int v)
{
	/* Suspend */
	if (!v)
	{
		if (!active) return (1);

		/* Hack -- make sure the cursor is visible */
		curs_set(1);

		/* Move to bottom right */
		do_move(0, rows - 1, 0, rows - 1);

		/* Go to normal keymap mode */
		keymap_norm();

		/* No longer active */
		active = FALSE;
	}

	/* Resume */
	else
	{
		if (active) return (1);

		/* Hack -- restore the cursor location */
		do_move(curx, cury, curx, cury);

		/* Hack -- restore the cursor visibility */
		curs_set(curv);

		/* Go to angband keymap mode */
		keymap_game();

		/* Now we are active */
		active = TRUE;
	}

	/* Success */
	return (0);
}



/*
 * Process an event
 */
static errr Term_xtra_cap_event(int v)
{
	int i, arg;
	char buf[2];

	/* Wait */
	if (v)
	{
		/* Wait for one byte */
		i = read(0, buf, 1);

		/* Hack -- Handle "errors" */
		if ((i <= 0) && (errno != EINTR)) exit_game_panic();
	}

	/* Do not wait */
	else
	{
		/* Get the current flags for stdin */
		if ((arg = fcntl(0, F_GETFL, 0)) < 1) return (1);

		/* Tell stdin not to block */
		if (fcntl(0, F_SETFL, arg | O_NDELAY) < 0) return (1);

		/* Read one byte, if possible */
		i = read(0, buf, 1);

		/* Replace the flags for stdin */
		if (fcntl(0, F_SETFL, arg)) return (1);
	}

	/* No keys ready */
	if ((i != 1) || (!buf[0])) return (1);

	/* Enqueue the keypress */
	Term_keypress(buf[0]);

	/* Success */
	return (0);
}




/*
 * Actually move the hardware cursor
 */
static errr Term_curs_cap(int x, int y)
{
	/* Literally move the cursor */
	do_move(curx, cury, x, y);

	/* Save the cursor location */
	curx = x;
	cury = y;

	/* Success */
	return (0);
}


/*
 * Erase a grid of space
 *
 * XXX XXX XXX Note that we will never be asked to clear the
 * bottom line all the way to the bottom right edge, since we
 * have set the "avoid the bottom right corner" flag.
 */
static errr Term_wipe_cap(int x, int y, int n)
{
	int dx;

	/* Place the cursor */
	Term_curs_cap(x, y);

	/* Wipe to end of line */
	if (x + n >= 80)
	{
		do_ce();
	}

	/* Wipe region */
	else
	{
		for (dx = 0; dx < n; ++dx)
		{
			putc(' ', stdout);
			curx++;
		}
	}

	/* Success */
	return (0);
}


/*
 * Place some text on the screen using an attribute
 */
static errr Term_text_cap(int x, int y, int n, byte a, cptr s)
{
	int i;

	/* Move the cursor */
	Term_curs_cap(x, y);

	/* Dump the text, advance the cursor */
	for (i = 0; s[i]; i++)
	{
		/* Dump the char */
		putc(s[i], stdout);

		/* Advance cursor 'X', and wrap */
		if (++curx >= cols)
		{
			/* Reset cursor 'X' */
			curx = 0;

			/* Hack -- Advance cursor 'Y', and wrap */
			if (++cury == rows) cury = 0;
		}
	}

	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_cap(int n, int v)
{
	/* Analyze the request */
	switch (n)
	{
		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		do_cl();
		do_move(0, 0, 0, 0);
		return (0);

		/* Make a noise */
	case TERM_XTRA_NOISE:
		(void)write(1, "\007", 1);
		return (0);

		/* Change the cursor visibility */
	case TERM_XTRA_SHAPE:
		curv = v;
		curs_set(v);
		return (0);

		/* Suspend/Resume */
	case TERM_XTRA_ALIVE:
		return (Term_xtra_cap_alive(v));

		/* Process events */
	case TERM_XTRA_EVENT:
		return (Term_xtra_cap_event(v));

		/* Flush events */
	case TERM_XTRA_FLUSH:
		while (!Term_xtra_cap_event(FALSE));
		return (0);

		/* Delay */
	case TERM_XTRA_DELAY:
		usleep(1000 * v);
		return (0);
	}

	/* Not parsed */
	return (1);
}




/*
 * Init a "term" for this file
 */
static void Term_init_cap(term *t)
{
	if (active) return;

	/* Assume cursor at top left */
	curx = 0;
	cury = 0;

	/* Assume visible cursor */
	curv = 1;

	/* Clear the screen */
	do_cl();

	/* Hack -- visible cursor */
	curs_set(1);

	/* Assume active */
	active = TRUE;
}


/*
 * Nuke a "term" for this file
 */
static void Term_nuke_cap(term *t)
{
	if (!active) return;

	/* Hack -- make sure the cursor is visible */
	curs_set(1);

	/* Move to bottom right */
	do_move(0, rows - 1, 0, rows - 1);

	/* Normal keymap */
	keymap_norm();

	/* No longer active */
	active = FALSE;
}










/*
 * Prepare this file for Angband usage
 */
errr init_cap(void)
{
	term *t = &term_screen_body;


	/*** Initialize ***/

	/* Initialize the screen */
	if (init_cap_aux()) return ( -1);

	/* Hack -- Require large screen, or Quit with message */
	if ((rows < 24) || (cols < 80)) quit("Screen too small!");


	/*** Prepare to play ***/

	/* Extract the normal keymap */
	keymap_norm_prepare();

	/* Extract the game keymap */
	keymap_game_prepare();

	/* Hack -- activate the game keymap */
	keymap_game();

	/* Hack -- Do NOT buffer stdout */
	setbuf(stdout, NULL);


	/*** Now prepare the term ***/

	/* Initialize the term */
	term_init(t, 80, 24, 256);

	/* Avoid the bottom right corner */
	t->icky_corner = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Set some hooks */
	t->init_hook = Term_init_cap;
	t->nuke_hook = Term_nuke_cap;

	/* Set some more hooks */
	t->text_hook = Term_text_cap;
	t->wipe_hook = Term_wipe_cap;
	t->curs_hook = Term_curs_cap;
	t->xtra_hook = Term_xtra_cap;

	/* Save the term */
	term_screen = t;

	/* Activate it */
	Term_activate(term_screen);

	/* Success */
	return (0);
}


#endif /* USE_CAP */


tome-235-src/src/main-crb.c0000644000076400017500000042114311012107763013316 0ustar  dgdg/* File: main-crb.c */

/*
 * Copyright (c) 1997 Ben Harrison, Keith Randall, Peter Ammon, Ron Anderson
 * and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband work with Macintosh computers running OS X,
 * or OS 8/9 with CarbonLib system extention.
 *
 * To use this file, use an appropriate "Makefile" or "Project File", which
 * should define "MACINTOSH".
 *
 * The official compilation uses the CodeWarrior Pro compiler.
 *
 * If you are never going to use "graphics" (especially if you are not
 * compiling support for graphics anyway) then you can delete the "pict"
 * resources with id "1001", "1002", "1003" and "1004" with no dangerous
 * side effects.
 *
 *
 * This file assumes that you will be using a PPC Mac running OS X
 * or OS 8/9 (8.6 or greater) with CarbonLib system extention enabled.
 * In fact, the game will refuse to run unless these features are available.
 *
 * MACH_O_CARBON code pushes the system requirement a bit further, and
 * I don't think it works on System 8, even with CarbonLib, because it uses
 * the Bundle services, but I may be wrong.
 *
 * Note that the "preference" file is now a simple XML text file
 * called ".plist" in case of PEF Carbon, and ".plist" for Mach-O Carbon, which contains
 * key-value paris, so it no longer has to check version stamp to validate
 * its contents.
 *
 *
 * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c"
 * should probably be "unloaded" as soon as they are no longer needed,
 * to save space, but I do not know how to do this.  XXX XXX XXX
 *
 * Stange bug -- The first "ClipRect()" call crashes if the user closes
 * all the windows, switches to another application, switches back, and
 * re-opens the main window, for example, using "command-a".  XXX XXX XXX
 *
 *
 * Initial framework (and most code) by Ben Harrison (benh@phial.com).
 *
 * Some code adapted from "MacAngband 2.6.1" by Keith Randall
 *
 * Initial PowerMac port by Maarten Hazewinkel (mmhazewi@cs.ruu.nl).
 *
 * Most Apple Event code provided by Steve Linberg (slinberg@crocker.com).
 *
 * Most of the graphics code is adapted from an extremely minimal subset of
 * the "Sprite World II" package, an amazing (and free) animation package.
 *
 * Carbon code adapted from works by Peter Ammon and Ron Anderson.
 *
 * (List of changes made by "pelpel" follow)
 * Some API calls are updated to OS 8.x-- ones.
 *
 * Pixmap locking code in Term_pict_map() follows Carbon Porting Guide
 * by Apple.
 *
 * The idle loop in TERM_XTRA_DELAY is rewritten to sleep on WaitNextEvent
 * for a couple of reasons.
 *
 * CheckEvent now really blocks whenever asked to wait.
 *
 * The unused buffer GWorld is completely removed. It has long been pure waste
 * of memory.
 *
 * The default font-size combination was changed because the old one, Monaco
 * at 12 points causes the redraw artefact problem on OS X.
 *
 * Characters in the ASCII mode are clipped by their bounding rects to reduce
 * redraw artefacts that were quite annoying in certain font-point combos.
 *
 * Transparency effect now avoids double bitblts whenever possible.
 *
 * Old tiles were drawn in a wrong fashion by the USE_TRANSPARENCY code.
 *
 * ASCII and the two graphics modes are now controlled by single graf_mode
 * variable.  arg_* and use_* variables are set when requested mode is
 * successfully initialised.
 *
 * Most of the menus are now loaded from resources.
 *
 * Moved TileWidth and TileHeight menus into Special. There were too many menus.
 *
 * Added support for 32x32 tiles, now for [V] only.
 *
 * Related to the above, globe_init no longer loads tile images twice if
 * a tileset doesn't have corresponding masks.
 *
 * Added support for POSIX-style pathnames, for Mach-O Carbon (gcc, CW >= 7).
 * We can finally live without Pascal strings to handle files this way.
 *
 * (Mach-O Carbon) Graphics tiles are moved out of the resource fork into
 * bundle-based data fork files.
 *
 * Changed size-related menu code, because they no longer function because
 * some APIs have been changed to return Unicode in some cases.
 *
 * Changed the transparency code again, this time using Ron Anderson's code,
 * which makes more sound assumption about background colour and is more
 * efficient.
 *
 * The old asynchronous sound player could try to lock the same handle more
 * than once, load same sound resource already in use, or unlock and release
 * currently playing sound.
 *
 * hook_quit() now releases memory-related resources dynamically allocated by
 * the graphics and sound code.
 *
 * Important Resources in the resource file:
 *
 *   FREF 130 = ANGBAND_CREATOR / 'APPL' (application)
 *   FREF 129 = ANGBAND_CREATOR / 'SAVE' (save file)
 *   FREF 130 = ANGBAND_CREATOR / 'TEXT' (bone file, generic text file)
 *   FREF 131 = ANGBAND_CREATOR / 'DATA' (binary image file, score file)
 *
 *   DLOG 128 = "About Angband..."
 *
 *   ALRT 128 = unused (?)
 *   ALRT 129 = "Warning..."
 *
 *   DITL 128 = body for DLOG 128
 *   DITL 129 = body for ALRT 129
 *   DITL 130 = body for ALRT 130
 *
 *   ICON 128 = "warning" icon
 *
 *   MBAR 128 = array of MENU id's (128, 129, 130, 131, 132, 133, 134)
 *   MENU 128 = apple (about, -, ...)
 *   MENU 129 = File (new, open, close, save, -, score, quit)
 *     (If SAVEFILE_SCREEN is defined)
 *   MENU 129 = File (close, save, -, score, quit)
 *   MENU 130 = Edit (undo, -, cut, copy, paste, clear)
 *   MENU 131 = Font (bold, wide, -)
 *   MENU 132 = Size ()
 *   MENU 133 = Windows ()
 *   MENU 134 = Special (Sound, Graphics, TileWidth, TileHeight, -, Fiddle,
 *                       Wizard)
 *              Graphics have following submenu attached:
 *   MENU 144 = Graphics (None, 8x8, 16x16, 32x32, enlarge tiles)
 *              TileWidth and TileHeight submenus are filled in by this program.
 *   MENU 145 = TileWidth ()
 *   MENU 146 = TileHeight ()
 *
 *   On CFM(PEF) Carbon only:
 *   PICT 1001 = Graphics tile set (8x8)
 *   PICT 1002 = Graphics tile set (16x16 images)
 *   PICT 1004 = Graphics tile set (32x32)
 *
 *   Mach-O Carbon now uses data fork resources:
 *   8x8.png   = Graphics tile set (8x8)
 *   16x16.png = Graphics tile set (16x16 images)
 *   32x32.png = Graphics tile set (32x32)
 *   These files should go into the Resources subdirectory of an application
 *   bundle.
 *
 *   STR# 128 = "Please select the "lib" folder"
 *
 *   plst 0   can be empty, but required for single binary Carbon apps on OS X
 *            Isn't necessary for Mach-O Carbon.
 *
 *
 * File name patterns:
 *   all 'APEX' files have a filename of the form "*:apex:*" (?)
 *   all 'BONE' files have a filename of the form "*:bone:*" (?)
 *   all 'DATA' files have a filename of the form "*:data:*"
 *   all 'SAVE' files have a filename of the form "*:save:*"
 *   all 'USER' files have a filename of the form "*:user:*" (?)
 *
 * Perhaps we should attempt to set the "_ftype" flag inside this file,
 * to avoid nasty file type information being spread all through the
 * rest of the code.  (?)  This might require adding hooks into the
 * "fd_open()" and "my_fopen()" functions in "util.c".  XXX XXX XXX
 *
 *
 * Reasons for each header file:
 *
 *   angband.h = Angband header file
 *
 *   Types.h = (included anyway)
 *   Gestalt.h = gestalt code
 *   QuickDraw.h = (included anyway)
 *   OSUtils.h = (included anyway)
 *   Files.h = file code
 *   Fonts.h = font code
 *   Menus.h = menu code
 *   Dialogs.h = dialog code
 *   Windows.h = (included anyway)
 *   Palettes.h = palette code
 *   ToolUtils.h = HiWord() / LoWord()
 *   Events.h = event code
 *   Resources.h = resource code
 *   Controls.h = button code
 *   SegLoad.h = ExitToShell(), AppFile, etc
 *   Memory.h = NewPtr(), etc
 *   QDOffscreen.h = GWorld code
 *   Sound.h = Sound code
 *   Navigation.h = save file / lib locating dialogues
 *   CFPreferences.h = Preferences
 *   CFNumber.h = read/write short values from/to preferences
 */

/*
 * Yet another main-xxx.c for Carbon (pelpel) - revision 11d
 *
 * Since I'm using CodeWarrior, the traditional header files are
 * #include'd below.
 *
 * I also compiled Angband 3.0.2 successfully with OS X's gcc.
 * Please follow these instructions if you are interested.
 *
 * ---(developer CD gcc + makefile porting notes, for Angband 3.0.2)-------
 * 1. Compiling the binary
 *
 * If you try this on OS X + gcc, please use makefile.std, replacing
 * main.c and main.o with main-crb.c and main-crb.o, removing all main-xxx.c
 * and main-xxx.o from SRCS and OBJS, and, and use these settings:
 *
 * COPTS = -Wall -O1 -g -fpascal-strings
 * INCLUDES =
 * DEFINES = -DMACH_O_CARBON -DANGBAND30X
 * LIBS = -framework CoreFoundation -framework QuickTime -framework Carbon
 *
 * -DANGBAND30X only affects main-crb.c. This is because I'm also compiling
 * a couple of variants, and this arrangement makes my life easier.
 *
 * Never, ever #define MACINTOSH.  It'll wreck havoc in system interface
 * (mostly because of totally different pathname convention).
 *
 * You might wish to disable some SET_UID features for various reasons:
 * to have user folder within the lib folder, savefile names etc.
 *
 * For the best compatibility with the Classic ports and my PEF Carbon
 * ports, my_fopen, fd_make and fd_open [in util.c] should call
 *   (void)fsetfileinfo(buf, _fcreator, _ftype);
 * when a file is successfully opened.  Or you'll see odd icons for some files
 * in the lib folder.  In order to do so, extern.h should contain these lines,
 * within #ifdef MACH_O_CARBON:
 *   extern int fsetfileinfo(char *path, u32b fcreator, u32b ftype);
 *   extern u32b _fcreator;
 *   extern u32b _ftype;
 * And enable the four FILE_TYPE macros in h-config.h for defined(MACH_O_CARBON)
 * in addition to defined(MACINTOSH) && !defined(applec), i.e.
 *  #if defined(MACINTOSH) && !defined(applec) || defined(MACH_O_CARBON)
 *
 * This is a very good way to spot bugs in use of these macros, btw.
 *
 * 2. Installation
 *
 * The "angband" binary must be arranged this way for it to work:
 *
 * lib/ <- the lib folder
 * Angband (OS X).app/
 *   Contents/
 *     MacOS/
 *       angband <- the binary you've just compiled
 *     Info.plist <- to be explained below
 *     Resources/
 *       Angband.icns
 *       Data.icns
 *       Edit.icns
 *       Save.icns
 *       8x8.png <- 8x8 tiles
 *       16x16.png <- 16x16 tiles
 *       angband.rsrc <- see below
 *
 * 3. Preparing Info.plist
 *
 * Info.plist is an XML file describing some attributes of an application,
 * and this is appropriate for Angband:
 *
 * 
 * 
 *   
 *     CFBundleNameAngband
 *     CFBundleDisplayNameAngband (OS X)
 *     CFBundleExecutableangband
 *     CFBundlePackageTypeAPPL
 *     CFBundleSignatureA271
 *     CFBundleVersion3.0.2
 *     CFBundleShortVersionString3.0.2
 *     CFBundleIconFileAngband
 *     CFBundleIdentifiernet.thangorodrim.Angband
 *     CFBundleInfoDictionaryVersion6.0
 *     CFBundleDocumentTypes
 *       
 *         
 *           CFBundleTypeExtentions*
 *           CFBundleTypeIconFileSave
 *           CFBundleTypeNameAngband saved game
 *           CFBundleTypeOSTypesSAVE
 *           CFBundleTypeRoleEditor
 *         
 *         
 *           CFBundleTypeExtentions*
 *           CFBundleTypeIconFileEdit
 *           CFBundleTypeNameAngband game data
 *           CFBundleTypeOSTypesTEXT
 *           CFBundleTypeRoleEditor
 *         
 *         
 *           CFBundleTypeExtentionsraw
 *           CFBundleTypeIconFileData
 *           CFBundleTypeNameAngband game data
 *           CFBundleTypeOSTypesDATA
 *           CFBundleTypeRoleEditor
 *         
 * 	
 *   
 * 
 *
 * 4. Menu, diaglogue and gfx resources
 *
 * The binary assumes angband.rsrc should be in the traditional resource
 * mangager format.  Please run this command to create it from its textual
 * description:
 *
 * Rez -i /Developer/Headers/FlatCarbon -d MACH_O -o angband.rsrc Angband.r
 *
 * The command is in /Developer/Tools.  You might wish to include it in your
 * PATH.
 *
 * It's better to comment out the definitions of BNDL and plst resources
 * before you do that.  I think you can DeRez the resulting tome.rsrc and
 * feed it to the Interface Builder to produce a set of compatible .nib files,
 * but this file also needs to be updated to understand .nib...  On the other
 * hand, I really don't like to hardcode UI definitions in C.
 *
 * Graphics resources are moved out of the resource fork and become ordinary
 * PNG files.  Make sure to set its resolution to 72 dpi (<- VERY important)
 * while keeping vertical and horizontal scaling factor to 100% (<- VERY
 * important), when you convert tiles in any formats to PNG.  This means
 * that the real size of an image must shrink or grow when you change it's dpi.
 *
 * Sound resources are a bit more complicated.
 * The easiest way is:
 * 1) Grab recent Mac Angband binary.
 * 2) Run this command:
 *   DeRez -only 'snd ' (Angband binary) > sound.r
 * 3) And specify sound.r files in addition to Angband.r when you run Rez.
 *
 * ---(end of OS X + gcc porting note)--------------------------------------
 *
 * Code adapted from Peter Ammon's work on 2.8.3 and some modifications
 * are made when Apple's Carbon Porting Guide says they are absolutely
 * necessary. Other arbirary changes are mostly because of my hatred
 * of deep nestings and indentations. The code for controlling graphics modes
 * have been thoroughly revised simply because I didn't like it (^ ^;).
 * A bonus of this is that graphics settings can be loaded from Preferences
 * quite easily.
 *
 * I also took Ron Anderson's (minimising the use of local-global coordinate
 * conversions). Some might say his QuickTime multimedia is the most
 * significant achievement... Play your favourite CD instead, if you really
 * miss that (^ ^;) I might consider incorporating it if it makes use of
 * event notification.
 *
 * I replaced some old API calls with new (OS 8.x--) ones, especially
 * when I felt Apple is strongly against their continued usage.
 *
 * Similarly, USE_SFL_CODE should be always active, so I removed ifdef's
 * just to prevent accidents, as well as to make the code a bit cleaner.
 *
 * On the contrary, I deliberately left traditional resource interfaces.
 * Whatever Apple might say, I abhor file name extentions. And keeping two
 * different sets of resources for Classic and Carbon is just too much for
 * a personal project XXX
 *
 * Because Carbon forbids the use of 68K code, ANGBAND_LITE_MAC sections
 * are removed.
 *
 * Because the default font-size combination causes redraw artefact problem
 * (some characters, even in monospace fonts, have negative left bearings),
 * I introduced rather crude hack to clip all character drawings within
 * their bounding rects. If you don't like this, please comment out the line
 * #define CLIP_HACK
 * below.
 *
 * The check for return values of AEProcessAppleEvent is removed,
 * because it results in annoying dialogues on OS X, also because
 * Apple says it isn't usually necessary.
 *
 * Because the always_pict code is *so* slow, I changed the graphics
 * mode selection a bit to use higher_pict when a user chooses a fixed
 * width font and doesn't changes tile width / height.
 *
 * Added support for David Gervais' 32x32 tiles.
 *
 * Replaced transparency effect code by Ron Anderson's.
 *
 * Added support for gcc & make compilation. They come free with OS X
 * (on the developer CD).  This means that it can be compiled as a bundle.
 *
 * For Mach-O Carbon binary, moved graphics tiles out of the
 * resource fork and made them plain PNG files, to be stored in the application
 * bundle's "Resources" subdirectory.
 *
 * For Mach-O Carbon binary, provided a compile-time option (USE_QT_SOUND) to
 * move sound effect samples out of the resource fork and use *.wav files in
 * the bundle's "Resources" subdirectory. The "*" part must match the names in
 * angband_sound_name (variable.c) exactly. This doesn't hurt performance
 * a lot in [V] (it's got ~25 sound events), but problematic in [Z]-based
 * ones (they have somewhere around 70 sound events).
 *
 * You still can use the resource file that comes with the ext-mac archive
 * on the Angband FTP server, with these additions:
 * - MENUs 131--134 and 144--146, as described above
 * - MBAR 128: just a array of 128 through 134
 * - plst 0 : can be empty, although Apple recommends us to fill it in.
 * - STR# 128 : something like "Please select your lib folder"
 *
 * Since this involves considerable amount of work, I attached
 * a plain text resource definition (= Rez format) .
 * I heavily commented on the file, hoping it could be easily adapted
 * to future versions of Angband as well as variants.
 * I omitted sound effects and graphic tiles to make it reasonably small.
 * Please copy them from any recent Mac binaries - you can use, say ZAngband
 * ones for Vanilla or [V]-based variants quite safely. T.o.M.E. uses fairly
 * extended 16x16 tileset and it is maintained actively. IIRC Thangorodrim
 * compile page has an intruction explaining how to convert tiles for
 * use on the Mac... It can be tricky, depending on your choice of
 * graphics utility. Remember setting resolution to 72 pixels per inch,
 * while keeping vertical/horizontal scale factor to 100% and dump the
 * result as a PICT from resource.
 *
 * To build Carbonised Angband with CodeWarrior, copy your PPC project
 * and
 * - replace main-mac.c in the project with this file (in the link order tab)
 * - remove InterfaceLib and MathLib
 * - add CarbonLib (found in Carbon SDK or CW's UniversalInterfaces) --
 *   if you have compiler/linker errors, you'll need Carbon SDK 1.1 or greater
 * - replace MSL C.PPC.Lib with MSL C.Carbon.Lib (both found in
 *   MSL:MSL_C:MSL_MacOS:Lib:PPC)
 * - leave MSL RuntimePPC.Lib as it is
 * - don't forget to update resource file, as described above
 * - as in Classic targets, you may have to include  and
 *   . The most convinient place for them is the first
 *   #ifdef MACINTOSH in h-system.h
 * - check variant dependent ifdef's explained below, and add
 *   appropriate one(s) in your A-mac-h.pch.
 */


/*
 * Force Carbon-compatible APIs
 */
#ifndef MACH_O_CARBON

/* Can be CodeWarrior or MPW */
# define TARGET_API_MAC_CARBON 1

#else

/*
* Must be Mach-O Carbon target with OS X gcc.
* No need to set TARGET_API_MAC_CARBON to 1 here, but I assume it should
* be able to make efficient use of BSD functions, hence:
*/
# define USE_MALLOC
/* Not yet */
/* # define USE_NIB */

#endif /* !MACH_O_CARBON */


#include "angband.h"

#if defined(MACINTOSH) || defined(MACH_O_CARBON)

#ifdef PRIVATE_USER_PATH

/*
 * Check and create if needed the directory dirpath
 */
bool private_check_user_directory(cptr dirpath)
{
	/* Is this used anywhere else in *bands? */
	struct stat stat_buf;

	int ret;

	/* See if it already exists */
	ret = stat(dirpath, &stat_buf);

	/* It does */
	if (ret == 0)
	{
		/* Now we see if it's a directory */
		if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE);

		/*
		 * Something prevents us from create a directory with
		 * the same pathname
		 */
		return (FALSE);
	}

	/* No - this maybe the first time. Try to create a directory */
	else
	{
		/* Create the ~/.ToME directory */
		ret = mkdir(dirpath, 0700);

		/* An error occured */
		if (ret == -1) return (FALSE);

		/* Success */
		return (TRUE);
	}
}

/*
 * Check existence of ".ToME/" directory in the user's
 * home directory or try to create it if it doesn't exist.
 * Returns FALSE if all the attempts fail.
 */
static bool check_create_user_dir(void)
{
	char dirpath[1024];
	char versionpath[1024];
	char savepath[1024];
#ifdef PRIVATE_USER_PATH_DATA
	char datapath[1024];
#endif
#ifdef PRIVATE_USER_PATH_APEX
	char apexpath[1024];
#endif

	/* Get an absolute path from the filename */
	path_parse(dirpath, 1024, PRIVATE_USER_PATH);
	strcpy(versionpath, dirpath);
	strcat(versionpath, USER_PATH_VERSION);
	strcpy(savepath, versionpath);
	strcat(savepath, "/save");
#ifdef PRIVATE_USER_PATH_DATA
	strcpy(datapath, versionpath);
	strcat(datapath, "/data");
#endif
#ifdef PRIVATE_USER_PATH_APEX
	strcpy(apexpath, versionpath);
	strcat(apexpath, "/apex");
#endif

	return /* don't forget, the dirpath muts come first */
	       private_check_user_directory(dirpath) &&
	       private_check_user_directory(versionpath) &&
#ifdef PRIVATE_USER_PATH_DATA
	       private_check_user_directory(datapath) &&
#endif
#ifdef PRIVATE_USER_PATH_APEX
	       private_check_user_directory(apexpath) &&
#endif
	       private_check_user_directory(savepath);
}

#endif /* PRIVATE_USER_PATH */


/*
 * Variant-dependent features:
 *
 * #define ALLOW_BIG_SCREEN (V, Ey, O, T.o.M.E., and Z.  Dr's big screen needs
 * more work.  New S one is too idiosyncratic...)
 * #define ANG281_RESET_VISUALS (Cth, Gum, T.o.M.E., Z)
 * #define SAVEFILE_SCREEN (T.o.M.E.)
 * #define ZANG_AUTO_SAVE (O and Z)
 * #define HAS_SCORE_MENU (V and T.o.M.E.)
 * #define ANGBAND_CREATOR four letter code for your variant, if any.
 * or use the default one.
 *
 * For [Z], you also have to say -- #define inkey_flag (p_ptr->inkey_flag)
 * but before that, please, please consider using main-mac-carbon.c in [Z],
 * that has some interesting features.
 */

/* Some porting examples */
#ifdef ANGBAND30X
# define USE_DOUBLE_TILES
# define ALLOW_BIG_SCREEN
# define HAS_SCORE_MENU
# define NEW_ZVIRT_HOOKS
/* I can't ditch this, yet, because there are many variants */
# define USE_TRANSPARENCY
#endif /* ANGBAND30X */

# define USE_DOUBLE_TILES
# define SAVEFILE_SCREEN
# define ANG281_RESET_VISUALS
# define ALLOW_BIG_SCREEN
# define HAS_SCORE_MENU
# define ANGBAND_CREATOR 'PrnA'

/* Default creator signature */
#ifndef ANGBAND_CREATOR
# define ANGBAND_CREATOR 'A271'
#endif


/*
 * Use rewritten asynchronous sound player
 */
#define USE_ASYNC_SOUND


/*
 * A rather crude fix to reduce amount of redraw artefacts.
 * Some fixed width fonts (i.e. Monaco) has characters with negative
 * left bearings, so Term_wipe_mac or overwriting cannot completely
 * erase them. This could be introduced to Classic Mac OS ports too,
 * but since I've never heard any complaints and I don't like to
 * make 68K ports even slower, I won't do so there.
 */
#define CLIP_HACK /* */

/*
 * To cope with pref file related problems.  It no longer has to be acculate,
 * because preferences are stored in plist.
 */
#define PREF_VER_MAJOR VERSION_MAJOR
#define PREF_VER_MINOR VERSION_MINOR
#define PREF_VER_PATCH VERSION_PATCH
#define PREF_VER_EXTRA VERSION_EXTRA


/*
 * In OS X + gcc, use ,  and
 *  for ALL of these, including the Apple
 * Event ones.   is used by the tile loading code.
 */
#ifdef MACH_O_CARBON

#include 
#include 
#include 
#include 

#else /* MACH_O_CARBON */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#endif /* MACH_O_CARBON */

/* MacOSX == Unix == Good */
#ifdef USE_MACOSX
#include 
#include 
#include 
#include 
#endif


/*
 * Use "malloc()" instead of "NewPtr()"
 */
/* #define USE_MALLOC */


/*
 * Information about each of the 256 available colors
 */
static RGBColor color_info[256];


#ifdef MACH_O_CARBON

/*
 * Creator signature and file type - Didn't I say that I abhor file name
 * extentions?  Names and metadata are entirely different set of notions.
 */
OSType _fcreator;
OSType _ftype;

#endif /* MACH_O_CARBON */


/*
 * Forward declare
 */
typedef struct term_data term_data;

/*
 * Extra "term" data
 */
struct term_data
{
	term *t;

	Rect r;

	WindowPtr w;


	short padding;

	short pixelDepth;

	GWorldPtr theGWorld; 	/* not used ... */

	GDHandle theGDH;

	GDHandle mainSWGDH; 	/* not used ... */

	Str15 title;

	s16b oops;

	s16b keys;

	s16b last;

	s16b mapped;

	s16b rows;
	s16b cols;

	s16b font_id;
	s16b font_size;
	s16b font_face;
	s16b font_mono;

	s16b font_o_x;
	s16b font_o_y;
	s16b font_wid;
	s16b font_hgt;

	s16b tile_o_x;
	s16b tile_o_y;
	s16b tile_wid;
	s16b tile_hgt;

	s16b size_wid;
	s16b size_hgt;

	s16b size_ow1;
	s16b size_oh1;
	s16b size_ow2;
	s16b size_oh2;
};




/*
 * Forward declare -- see below
 */
static bool CheckEvents(bool wait);


#ifndef MACH_O_CARBON

/*
 * Hack -- location of the main directory
 */
static short app_vol;
static long app_dir;

#endif /* !MACH_O_CARBON */


/*
 * Delay handling of double-clicked savefiles
 */
Boolean open_when_ready = FALSE;

/*
 * Delay handling of pre-emptive "quit" event
 */
Boolean quit_when_ready = FALSE;


/*
 * Aqua automatically supplies the Quit menu.
 */
static Boolean is_aqua = FALSE;

/*
 * Version of Mac OS - for version specific bug workarounds (; ;)
 */
static long mac_os_version;


/*
 * Hack -- game in progress
 */
static int game_in_progress = 0;


/*
 * Only do "SetPort()" when needed
 */
static WindowPtr active = NULL;


/*
 * Maximum number of terms
 */
#define MAX_TERM_DATA 8


/*
 * An array of term_data's
 */
static term_data data[MAX_TERM_DATA];


/*
 * Note when "open"/"new" become valid
 */
static bool initialized = FALSE;



/*
 * Convert a C string to a pascal string in place
 *
 * This function may be defined elsewhere, but since it is so
 * small, it is not worth finding the proper function name for
 * all the different platforms.
 */
static void ctopstr(StringPtr src)
{
	int i;
	byte len;

	/* Hack -- pointer */
	char *s = (char*)(src);

	len = strlen(s);

	/* Hack -- convert the string */
	for (i = len; i > 1; i--) s[i] = s[i - 1];

	/* Hack -- terminate the string */
	s[0] = len;
}


#ifdef MACH_O_CARBON

/* Carbon File Manager utilities by pelpel */

/*
 * (Carbon)
 * Convert a pathname to a corresponding FSSpec.
 * Returns noErr on success.
 */
static OSErr path_to_spec(const char *path, FSSpec *spec)
{
	OSErr err;
	FSRef ref;

	/* Convert pathname to FSRef ... */
	err = FSPathMakeRef(path, &ref, NULL);
	if (err != noErr) return (err);

	/* ... then FSRef to FSSpec */
	err = FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);

	/* Inform caller of success or failure */
	return (err);
}


/*
 * (Carbon)
 * Convert a FSSpec to a corresponding pathname.
 * Returns noErr on success.
 */
static OSErr spec_to_path(const FSSpec *spec, char *buf, size_t size)
{
	OSErr err;
	FSRef ref;

	/* Convert FSSpec to FSRef ... */
	err = FSpMakeFSRef(spec, &ref);
	if (err != noErr) return (err);

	/* ... then FSRef to pathname */
	err = FSRefMakePath(&ref, buf, size);

	/* Inform caller of success or failure */
	return (err);
}


/*
 * (Carbon) [via path_to_spec]
 * Set creator and filetype of a file specified by POSIX-style pathname.
 * Returns 0 on success, -1 in case of errors.
 */
int fsetfileinfo(char *pathname, OSType fcreator, OSType ftype)
{
	OSErr err;
	FSSpec spec;
	FInfo info;

	/* Convert pathname to FSSpec */
	if (path_to_spec(pathname, &spec) != noErr) return ( -1);

	/* Obtain current finder info of the file */
	if (FSpGetFInfo(&spec, &info) != noErr) return ( -1);

	/* Overwrite creator and type */
	info.fdCreator = fcreator;
	info.fdType = ftype;
	err = FSpSetFInfo(&spec, &info);

	/* Inform caller of success or failure */
	return ((err == noErr) ? 0 : -1);
}


#else /* MACH_O_CARBON */

/*
* Convert refnum+vrefnum+fname into a full file name
* Store this filename in 'buf' (make sure it is long enough)
* Note that 'fname' looks to be a "pascal" string
*/
static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
{
	DirInfo pb;
	Str255 name;
	int err;
	int i, j;

	char res[1000];

	i = 999;

	res[i] = 0;
	i--;
	for (j = 1; j <= fname[0]; j++)
	{
		res[i - fname[0] + j] = fname[j];
	}
	i -= fname[0];

	pb.ioCompletion = NULL;
	pb.ioNamePtr = name;
	pb.ioVRefNum = vrefnum;
	pb.ioDrParID = refnum;
	pb.ioFDirIndex = -1;

	while (1)
	{
		pb.ioDrDirID = pb.ioDrParID;
		err = PBGetCatInfoSync((CInfoPBPtr) & pb);
		res[i] = ':';
		i--;
		for (j = 1; j <= name[0]; j++)
		{
			res[i - name[0] + j] = name[j];
		}
		i -= name[0];

		if (pb.ioDrDirID == fsRtDirID) break;
	}

	/* Extract the result */
	for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
	buf[j] = 0;
}


/*
* Convert a pascal string in place
*
* This function may be defined elsewhere, but since it is so
* small, it is not worth finding the proper function name for
* all the different platforms.
*/
static void ptocstr(StringPtr src)
{
	int i;

	/* Hack -- pointer */
	char *s = (char*)(src);

	/* Hack -- convert the string */
	for (i = s[0]; i; i--, s++) s[0] = s[1];

	/* Hack -- terminate the string */
	s[0] = '\0';
}


/*
* Utility routines by Steve Linberg
*
* The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
* were taken from the Think Reference section called "Getting a Full Pathname"
* (under the File Manager section).  We need PathNameFromDirID to get the
* full pathname of the opened savefile, making no assumptions about where it
* is.
*
* I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
* nice.
*/
static void pstrcat(StringPtr dst, StringPtr src)
{
	/* copy string in */
	BlockMove(src + 1, dst + *dst + 1, *src);

	/* adjust length byte */
	*dst += *src;
}


/*
* pstrinsert - insert string 'src' at beginning of string 'dst'
*/
static void pstrinsert(StringPtr dst, StringPtr src)
{
	/* make room for new string */
	BlockMove(dst + 1, dst + *src + 1, *dst);

	/* copy new string in */
	BlockMove(src + 1, dst + 1, *src);

	/* adjust length byte */
	*dst += *src;
}


static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
{
	CInfoPBRec block;
	Str255 directoryName;
	OSErr err;

	fullPathName[0] = '\0';

	block.dirInfo.ioDrParID = dirID;
	block.dirInfo.ioNamePtr = directoryName;

	while (1)
	{
		block.dirInfo.ioVRefNum = vRefNum;
		block.dirInfo.ioFDirIndex = -1;
		block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
		err = PBGetCatInfoSync(&block);
		pstrcat(directoryName, (StringPtr)"\p:");
		pstrinsert(fullPathName, directoryName);
		if (block.dirInfo.ioDrDirID == 2) break;
	}
}

#endif /* MACH_O_CARBON */




/*
 * Center a rectangle inside another rectangle
 *
 * Consider using RepositionWindow() whenever possible
 */
static void center_rect(Rect *r, Rect *s)
{
	int centerx = (s->left + s->right) / 2;
	int centery = (2 * s->top + s->bottom) / 3;
	int dx = centerx - (r->right - r->left) / 2 - r->left;
	int dy = centery - (r->bottom - r->top) / 2 - r->top;
	r->left += dx;
	r->right += dx;
	r->top += dy;
	r->bottom += dy;
}


/*
 * Activate a given window, if necessary
 */
static void activate(WindowPtr w)
{
	/* Activate */
	if (active != w)
	{
		/* Activate */
		if (w) SetPort(GetWindowPort(w));

		/* Remember */
		active = w;
	}
}


/*
 * Display a warning message
 */
static void mac_warning(cptr warning)
{
	Str255 text;
	int len, i;

	/* Limit of 250 chars */
	len = strlen(warning);
	if (len > 250) len = 250;

	/* Make a "Pascal" string */
	text[0] = len;
	for (i = 0; i < len; i++) text[i + 1] = warning[i];

	/* Prepare the dialog box values */
	ParamText(text, "\p", "\p", "\p");

	/* Display the Alert, wait for Okay */
	Alert(129, 0L);
}



/*** Some generic functions ***/

/*
 * Hack -- activate a color (0 to 255)
 */
static void term_data_color(term_data *td, int a)
{
	/* Activate the color */
	if (td->last != a)
	{
		/* Activate the color */
		RGBForeColor(&color_info[a]);

		/* Memorize color */
		td->last = a;
	}
}


/*
 * Hack -- Apply and Verify the "font" info
 *
 * This should usually be followed by "term_data_check_size()"
 *
 * XXX XXX To force (re)initialisation of td->tile_wid and td->tile_hgt
 * you have to reset them to zero before this function is called.
 * XXX XXX This is automatic when the program starts because the term_data
 * array is WIPE'd by term_data_hack, but isn't in the other cases, i.e.
 * font, font style and size changes.
 */
static void term_data_check_font(term_data *td)
{
	int i;

	FontInfo info;

	WindowPtr old = active;


	/* Activate */
	activate(td->w);

	/* Instantiate font */
	TextFont(td->font_id);
	TextSize(td->font_size);
	TextFace(td->font_face);

	/* Extract the font info */
	GetFontInfo(&info);

	/* Assume monospaced */
	td->font_mono = TRUE;

	/* Extract the font sizing values XXX XXX XXX */
	td->font_wid = CharWidth('@');  /* info.widMax; */
	td->font_hgt = info.ascent + info.descent;
	td->font_o_x = 0;
	td->font_o_y = info.ascent;

	/* Check important characters */
	for (i = 33; i < 127; i++)
	{
		/* Hack -- notice non-mono-space */
		if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;

		/* Hack -- collect largest width */
		if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
	}

	/* Set default offsets */
	td->tile_o_x = td->font_o_x;
	td->tile_o_y = td->font_o_y;

	/* Set default tile size */
	if (td->tile_wid == 0) td->tile_wid = td->font_wid;
	if (td->tile_hgt == 0) td->tile_hgt = td->font_hgt;

	/* Re-activate the old window */
	activate(old);
}


/*
 * Hack -- Apply and Verify the "size" info
 */
static void term_data_check_size(term_data *td)
{
	if (td == &data[0])
	{
#ifndef ALLOW_BIG_SCREEN

		/* Forbid resizing of the Angband window */
		td->cols = 80;
		td->rows = 24;

#else

		/* Enforce minimal size */
		if (td->cols < 80) td->cols = 80;
		if (td->rows < 24) td->rows = 24;

#endif /* !ALLOW_BIG_SCREEN */
	}

	/* Information windows can be much smaller */
	else
	{
		if (td->cols < 1) td->cols = 1;
		if (td->rows < 1) td->rows = 1;
	}

	/* Enforce maximal sizes */
	if (td->cols > 255) td->cols = 255;
	if (td->rows > 255) td->rows = 255;

	/* Minimal tile size */
	if (td->tile_wid < td->font_wid) td->tile_wid = td->font_wid;
	if (td->tile_hgt < td->font_hgt) td->tile_hgt = td->font_hgt;

	/* Default tile offsets */
	td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
	td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;

	/* Minimal tile offsets */
	if (td->tile_o_x < 0) td->tile_o_x = 0;
	if (td->tile_o_y < 0) td->tile_o_y = 0;

	/* Apply font offsets */
	td->tile_o_x += td->font_o_x;
	td->tile_o_y += td->font_o_y;

	/* Calculate full window size */
	td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
	td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;

	{
		BitMap tScreen;

		/* Get current screen */
		(void)GetQDGlobalsScreenBits(&tScreen);

		/* Verify the top */
		if (td->r.top > tScreen.bounds.bottom - td->size_hgt)
		{
			td->r.top = tScreen.bounds.bottom - td->size_hgt;
		}

		/* Verify the top */
		if (td->r.top < tScreen.bounds.top + GetMBarHeight())
		{
			td->r.top = tScreen.bounds.top + GetMBarHeight();
		}

		/* Verify the left */
		if (td->r.left > tScreen.bounds.right - td->size_wid)
		{
			td->r.left = tScreen.bounds.right - td->size_wid;
		}

		/* Verify the left */
		if (td->r.left < tScreen.bounds.left)
		{
			td->r.left = tScreen.bounds.left;
		}
	}

	/* Calculate bottom right corner */
	td->r.right = td->r.left + td->size_wid;
	td->r.bottom = td->r.top + td->size_hgt;

	/* Assume no graphics */
	td->t->higher_pict = FALSE;
	td->t->always_pict = FALSE;


	/* Handle graphics */
	if (use_graphics)
	{
		/* Use higher pict whenever possible */
		if (td->font_mono) td->t->higher_pict = TRUE;

		/* Use always_pict only when necessary */
		else td->t->always_pict = TRUE;
	}

	/* Fake mono-space */
	if (!td->font_mono ||
	                (td->font_wid != td->tile_wid) ||
	                (td->font_hgt != td->tile_hgt))
	{
		/*
		 * Handle fake monospace
		 *
		 * pelpel: This is SLOW. Couldn't we use CharExtra
		 * and SpaceExtra for monospaced fonts?
		 */
		if (td->t->higher_pict) td->t->higher_pict = FALSE;
		td->t->always_pict = TRUE;
	}
}


/*
 * Hack -- resize a term_data
 *
 * This should normally be followed by "term_data_redraw()"
 */
static void term_data_resize(term_data *td)
{
	/*
	 * Actually resize the window
	 *
	 * ResizeWindow is the preferred API call, but it cannot
	 * be used here.
	 */
	SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
}



/*
 * Hack -- redraw a term_data
 *
 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
 */
static void term_data_redraw(term_data *td)
{
	term *old = Term;
	Rect tRect;

	/* Activate the term */
	Term_activate(td->t);

	/* Redraw the contents */
	Term_redraw();

	/* Flush the output */
	Term_fresh();

	/* Restore the old term */
	Term_activate(old);

	/* No need to redraw */
	ValidWindowRect(td->w, GetPortBounds(GetWindowPort(td->w), &tRect));
}


/*
 * Graphics support
 */

/* Set by Term_xtra_mac_react */
#ifdef MACH_O_CARBON
static CFStringRef pict_id; 		/* PICT id of image tiles */
#else
static int pict_id; 		/* PICT id of image tiles */
#endif /* MACH_O_CARBON */

static int graf_width; 	/* Width of a tile in pixels */
static int graf_height; 	/* Height of a tile in pixels */

/* Calculated by PICT loading code */
static int pict_cols; 	/* Number of columns in tiles */
static int pict_rows; 	/* Number of rows in tiles */

/* Available graphics modes */
#define GRAF_MODE_NONE	0	/* plain ASCII */
#define GRAF_MODE_8X8	1	/* 8x8 tiles */
#define GRAF_MODE_16X16	2	/* 16x16 tiles */
#define GRAF_MODE_32X32	3	/* 32x32 tiles */

static int graf_mode = GRAF_MODE_NONE; 		/* current graphics mode */
static int graf_mode_req = GRAF_MODE_NONE; 	/* requested graphics mode */

#define TR_NONE	0	/* No transparency */
#define TR_OVER 1	/* Overwriting with transparent black pixels */
static int transparency_mode = TR_NONE; 	/* types of transparency effect */


/*
 * Forward Declare
 */
typedef struct FrameRec FrameRec;

/*
 * Frame
 *
 *	- GWorld for the frame image
 *	- Handle to pix map (saved for unlocking/locking)
 *	- Pointer to color pix map (valid only while locked)
 */
struct FrameRec
{
	GWorldPtr framePort;
	PixMapHandle framePixHndl;
	PixMapPtr framePix;
};


/*
 * The global picture data
 */
static FrameRec *frameP = NULL;


/*
 * Lock a frame
 */
static void BenSWLockFrame(FrameRec *srcFrameP)
{
	PixMapHandle pixMapH;

	pixMapH = GetGWorldPixMap(srcFrameP->framePort);
	(void)LockPixels(pixMapH);
	HLockHi((Handle)pixMapH);
	srcFrameP->framePixHndl = pixMapH;
	srcFrameP->framePix = (PixMapPtr)(*(Handle)pixMapH);
}


/*
 * Unlock a frame
 */
static void BenSWUnlockFrame(FrameRec *srcFrameP)
{
	if (srcFrameP->framePort != NULL)
	{
		HUnlock((Handle)srcFrameP->framePixHndl);
		UnlockPixels(srcFrameP->framePixHndl);
	}

	srcFrameP->framePix = NULL;
}



#ifdef MACH_O_CARBON

/* Moving graphics resources into data fork -- pelpel */

/*
 * (Carbon, Bundle)
 * Given base and type names of a resource, find a file in the
 * current application bundle and return its FSSpec in the third argument.
 * Returns true on success, false otherwise.
 * e.g. get_resource_spec(CFSTR("8x8"), CFSTR("png"), &spec);
 */
static Boolean get_resource_spec(
        CFStringRef base_name, CFStringRef type_name, FSSpec *spec)
{
	CFURLRef res_url;
	FSRef ref;

	/* Find the tile resource specified in the current bundle */
	res_url = CFBundleCopyResourceURL(
	                  CFBundleGetMainBundle(), base_name, type_name, NULL);

	/* Oops */
	if (res_url == NULL) return (false);

	/* Convert CFURL to FSRef */
	(void)CFURLGetFSRef(res_url, &ref);

	/* Convert FSRef to FSSpec */
	(void)FSGetCatalogInfo(&ref, kFSCatInfoNone, NULL, NULL, spec, NULL);

	/* Free allocated CF data */
	CFRelease(res_url);

	/* Success */
	return (true);
}


/*
 * (QuickTime)
 * Create a off-screen GWorld from contents of a file specified by a FSSpec.
 *
 * Globals referenced: data[0], graf_height, graf_width
 * Globals updated: pict_rows, pict_cols.
 */
static OSErr create_gworld_from_spec(
        GWorldPtr *tile_gw, FSSpec *tile_spec)
{
	OSErr err;
	GraphicsImportComponent gi;
	GWorldPtr gw, tmp_gw;
	GDHandle gdh, tmp_gdh;
	Rect r;
	SInt16 depth;

	/* See if QuickTime understands the file format */
	err = GetGraphicsImporterForFile(tile_spec, &gi);

	/* Oops */
	if (err != noErr) return (err);

	/* Get depth */
	depth = data[0].pixelDepth;

	/* Get GDH */
	gdh = data[0].theGDH;

	/* Retrieve the rect of the image */
	err = GraphicsImportGetNaturalBounds(gi, &r);

	/* Adjust it, so that the upper left corner becomes (0, 0) */
	OffsetRect(&r, -r.left, -r.top);

	/* Calculate and set numbers of rows and columns */
	pict_rows = r.bottom / graf_height;
	pict_cols = r.right / graf_width;

	/* Create a GWorld */
	err = NewGWorld(&gw, depth, &r, NULL, gdh, noNewDevice);

	/* Oops */
	if (err != noErr) return (err);

	/* Save the pointer to the GWorld */
	*tile_gw = gw;

	/* Save the current GWorld */
	GetGWorld(&tmp_gw, &tmp_gdh);

	/* Activate the newly created GWorld */
	(void)GraphicsImportSetGWorld(gi, gw, NULL);

	/* Prevent pixmap from moving while drawing */
	(void)LockPixels(GetGWorldPixMap(gw));

	/* Clear the pixels */
	EraseRect(&r);

	/* Draw the image into it */
	(void)GraphicsImportDraw(gi);

	/* Release the lock*/
	UnlockPixels(GetGWorldPixMap(gw));

	/* Restore GWorld */
	SetGWorld(tmp_gw, tmp_gdh);

	/* Close the image importer */
	CloseComponent(gi);

	/* Success */
	return (noErr);
}

#else /* MACH_O_CARBON */

static OSErr BenSWCreateGWorldFromPict(
        GWorldPtr *pictGWorld, PicHandle pictH)
{
	OSErr err;
	GWorldPtr saveGWorld;
	GDHandle saveGDevice;
	GWorldPtr tempGWorld;
	Rect pictRect;
	short depth;
	GDHandle theGDH;

	tempGWorld = NULL;

	/* Reset */
	*pictGWorld = NULL;

	/* Get depth */
	depth = data[0].pixelDepth;

	/* Get GDH */
	theGDH = data[0].theGDH;

	/* Obtain size rectangle */
	pictRect = (**pictH).picFrame;
	OffsetRect(&pictRect, -pictRect.left, -pictRect.top);

	/* Calculate and set numbers of rows and columns */
	pict_rows = pictRect.bottom / graf_height;
	pict_cols = pictRect.right / graf_width;

	/* Create a GWorld */
	err = NewGWorld(&tempGWorld, depth, &pictRect, nil, theGDH, noNewDevice);

	/* Oops */
	if (err != noErr) return (err);

	/* Save pointer */
	*pictGWorld = tempGWorld;

	/* Save GWorld */
	GetGWorld(&saveGWorld, &saveGDevice);

	/* Activate */
	SetGWorld(tempGWorld, nil);

	/* Dump the pict into the GWorld */
	(void)LockPixels(GetGWorldPixMap(tempGWorld));
	EraseRect(&pictRect);
	DrawPicture(pictH, &pictRect);
	UnlockPixels(GetGWorldPixMap(tempGWorld));

	/* Restore GWorld */
	SetGWorld(saveGWorld, saveGDevice);

	/* Success */
	return (0);
}

#endif /* MACH_O_CARBON */


/*
 * Init the global "frameP"
 */
static errr globe_init(void)
{
	OSErr err;

	GWorldPtr tempPictGWorldP;

#ifdef MACH_O_CARBON
	FSSpec pict_spec;
#else
	PicHandle newPictH;
#endif /* MACH_O_CARBON */


	/* Use window XXX XXX XXX */
	SetPort(GetWindowPort(data[0].w));


#ifdef MACH_O_CARBON

	/* Get the tile resources */
	if (!get_resource_spec(pict_id, CFSTR("png"), &pict_spec)) return ( -1);

	/* Create GWorld */
	err = create_gworld_from_spec(&tempPictGWorldP, &pict_spec);

#else /* MACH_O_CARBON */

	/* Get the pict resource */
	if ((newPictH = GetPicture(pict_id)) == 0) return ( -1);

	/* Create GWorld */
	err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);

	/* Release resource */
	ReleaseResource((Handle)newPictH);

#endif /* MACH_O_CARBON */

	/* Error */
	if (err != noErr) return (err);

	/* Create the frame */
	frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));

	/* Analyze result */
	if (frameP == NULL) return ( -1);

	/* Save GWorld */
	frameP->framePort = tempPictGWorldP;

	/* Lock it */
	BenSWLockFrame(frameP);

	/* Success */
	return (noErr);
}


/*
 * Nuke the global "frameP"
 */
static errr globe_nuke(void)
{
	/* Dispose */
	if (frameP)
	{
		/* Unlock */
		BenSWUnlockFrame(frameP);

		/* Dispose of the GWorld */
		DisposeGWorld(frameP->framePort);

		/* Dispose of the memory */
		DisposePtr((Ptr)frameP);

		/* Forget */
		frameP = NULL;
	}

	/* Flush events */
	FlushEvents(everyEvent, 0);

	/* Success */
	return (0);
}


#ifdef USE_ASYNC_SOUND

/*
 * Asynchronous sound player - completely revised (beta)
 */
#if defined(USE_QT_SOUND) && !defined(MACH_O_CARBON)
# undef USE_QT_SOUND
#endif /* USE_QT_SOUND && !MACH_O_CARBON */

/*
 * How many sound channels will be pooled
 *
 * Was: 20, but I don't think we need 20 sound effects playing
 * simultaneously :) -- pelpel
 */
#define MAX_CHANNELS		8

/*
 * A pool of sound channels
 */
static SndChannelPtr channels[MAX_CHANNELS];

/*
 * Status of the channel pool
 */
static Boolean channel_initialised = FALSE;

/*
 * Data handles containing sound samples
 */
static SndListHandle samples[SOUND_MAX];

/*
 * Reference counts of sound samples
 */
static SInt16 sample_refs[SOUND_MAX];

#define SOUND_VOLUME_MIN	0	/* Default minimum sound volume */
#define SOUND_VOLUME_MAX	255	/* Default maximum sound volume */
#define VOLUME_MIN			0	/* Minimum sound volume in % */
#define VOLUME_MAX			100	/* Maximum sound volume in % */
#define VOLUME_INC			5	/* Increment sound volume in % */

/*
 * I'm just too lazy to write a panel for this XXX XXX
 */
static int sound_volume = SOUND_VOLUME_MAX;


#ifdef USE_QT_SOUND

/*
 * QuickTime sound, by Ron Anderson
 *
 * I didn't choose to use Windows-style .ini files (Ron wrote a parser
 * for it, but...), nor did I use lib/xtra directory, hoping someone
 * would code plist-based configuration code in the future -- pelpel
 */

/*
 * (QuickTime)
 * Load sound effects from data-fork resources.  They are wav files
 * with the same names as angband_sound_name[] (variable.c)
 *
 * Globals referenced: angband_sound_name[]
 * Globals updated: samples[] (they can be *huge*)
 */
static void load_sounds(void)
{
	OSErr err;
	int i;

	/* Start QuickTime */
	err = EnterMovies();

	/* Error */
	if (err != noErr) return;

	/*
	 * This loop may take a while depending on the count and size of samples
	 * to load.
	 *
	 * We should use a progress dialog for this.
	 */
	for (i = 1; i < SOUND_MAX; i++)
	{
		/* Apple APIs always give me headacke :( */
		CFStringRef name;
		FSSpec spec;
		SInt16 file_id;
		SInt16 res_id;
		Str255 movie_name;
		Movie movie;
		Track track;
		Handle h;
		Boolean res;

		/* Allocate CFString with the name of sound event to be processed */
		name = CFStringCreateWithCString(NULL, angband_sound_name[i],
		                                 kTextEncodingUS_ASCII);

		/* Error */
		if (name == NULL) continue;

		/* Find sound sample resource with the same name */
		res = get_resource_spec(name, CFSTR("wav"), &spec);

		/* Free the reference to CFString */
		CFRelease(name);

		/* Error */
		if (!res) continue;

		/* Open the sound file */
		err = OpenMovieFile(&spec, &file_id, fsRdPerm);

		/* Error */
		if (err != noErr) continue;

		/* Create Movie from the file */
		err = NewMovieFromFile(&movie, file_id, &res_id, movie_name,
		                       newMovieActive, NULL);

		/* Error */
		if (err != noErr) goto close_file;

		/* Get the first track of the movie */
		track = GetMovieIndTrackType(movie, 1, AudioMediaCharacteristic,
		                             movieTrackCharacteristic | movieTrackEnabledOnly );

		/* Error */
		if (track == NULL) goto close_movie;

		/* Allocate a handle to store sample */
		h = NewHandle(0);

		/* Error */
		if (h == NULL) goto close_track;

		/* Dump the sample into the handle */
		err = PutMovieIntoTypedHandle(movie, track, soundListRsrc, h, 0,
		                              GetTrackDuration(track), 0L, NULL);

		/* Success */
		if (err == noErr)
		{
			/* Store the handle in the sample list */
			samples[i] = (SndListHandle)h;
		}

		/* Failure */
		else
		{
			/* Free unused handle */
			DisposeHandle(h);
		}

		/* Free the track */
close_track:
		DisposeMovieTrack(track);

		/* Free the movie */
close_movie:
		DisposeMovie(movie);

		/* Close the movie file */
close_file:
		CloseMovieFile(file_id);
	}

	/* Stop QuickTime */
	ExitMovies();
}

#else /* USE_QT_SOUND */

/*
* Return a handle of 'snd ' resource given Angband sound event number,
* or NULL if it isn't found.
*
* Globals referenced: angband_sound_name[] (variable.c)
*/
static SndListHandle find_sound(int num)
{
Str255 sound;

/* Get the proper sound name */
strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]);
sound[0] = strlen((char*)sound + 1);

/* Obtain resource XXX XXX XXX */
return ((SndListHandle)GetNamedResource('snd ', sound));
}

#endif /* USE_QT_SOUND */


/*
 * Clean up sound support - to be called when the game exits.
 *
 * Globals referenced: channels[], samples[], sample_refs[].
 */
static void cleanup_sound(void)
{
	int i;

	/* No need to clean it up */
	if (!channel_initialised) return;

	/* Dispose channels */
	for (i = 0; i < MAX_CHANNELS; i++)
	{
		/* Drain sound commands and free the channel */
		SndDisposeChannel(channels[i], TRUE);
	}

	/* Free sound data */
	for (i = 1; i < SOUND_MAX; i++)
	{
		/* Still locked */
		if ((sample_refs[i] > 0) && (samples[i] != NULL))
		{
			/* Unlock it */
			HUnlock((Handle)samples[i]);
		}

#ifndef USE_QT_SOUND

		/* Release it */
		if (samples[i]) ReleaseResource((Handle)samples[i]);

#else
/* Free handle */
		if (samples[i]) DisposeHandle((Handle)samples[i]);

#endif /* !USE_QT_SOUND */
	}
}


/*
 * Play sound effects asynchronously -- pelpel
 *
 * I don't believe those who first started using the previous implementations
 * imagined this is *much* more complicated as it may seem.  Anyway,
 * introduced round-robin scheduling of channels and made it much more
 * paranoid about HLock/HUnlock.
 *
 * XXX XXX de-refcounting, HUnlock and ReleaseResource should be done
 * using channel's callback procedures, which set global flags, and
 * a procedure hooked into CheckEvents does housekeeping.  On the other
 * hand, this lazy reclaiming strategy keeps things simple (no interrupt
 * time code) and provides a sort of cache for sound data.
 *
 * Globals referenced: channel_initialised, channels[], samples[],
 *   sample_refs[].
 * Globals updated: channel_initialised, channels[], sample_refs[].
 *   Only in !USE_QT_SOUND, samples[].
 */
static void play_sound(int num, int vol)
{
	OSErr err;
	int i;
	int prev_num;
	SndListHandle h;
	SndChannelPtr chan;
	SCStatus status;

	static int next_chan;
	static SInt16 channel_occupants[MAX_CHANNELS];
	static SndCommand volume_cmd, quiet_cmd;


	/* Initialise sound channels */
	if (!channel_initialised)
	{
		for (i = 0; i < MAX_CHANNELS; i++)
		{
			/* Paranoia - Clear occupant table */
			/* channel_occupants[i] = 0; */

			/* Create sound channel for all sounds to play from */
			err = SndNewChannel(&channels[i], sampledSynth, initMono, NULL);

			/* Error */
			if (err != noErr)
			{
				/* Free channels */
				while (--i >= 0)
				{
					SndDisposeChannel(channels[i], TRUE);
				}

				/* Notify error */
				plog("Cannot initialise sound channels!");

				/* Cancel request */
				use_sound = arg_sound = FALSE;

				/* Failure */
				return;
			}
		}

		/* First channel to use */
		next_chan = 0;

		/* Prepare volume command */
		volume_cmd.cmd = volumeCmd;
		volume_cmd.param1 = 0;
		volume_cmd.param2 = 0;

		/* Prepare quiet command */
		quiet_cmd.cmd = quietCmd;
		quiet_cmd.param1 = 0;
		quiet_cmd.param2 = 0;

		/* Initialisation complete */
		channel_initialised = TRUE;
	}

	/* Paranoia */
	if ((num <= 0) || (num >= SOUND_MAX)) return;

	/* Prepare volume command */
	volume_cmd.param2 = (SInt16)((vol << 4) | vol);

	/* Channel to use (round robin) */
	chan = channels[next_chan];

	/* See if the resource is already in use */
	if (sample_refs[num] > 0)
	{
		/* Resource in use */
		h = samples[num];

		/* Increase the refcount */
		sample_refs[num]++;
	}

	/* Sound is not currently in use */
	else
	{
		/* Get handle for the sound */
#ifdef USE_QT_SOUND
		h = samples[num];
#else
		h = find_sound(num);
#endif /* USE_QT_SOUND */

		/* Sample not available */
		if (h == NULL) return;

#ifndef USE_QT_SOUND

		/* Load resource */
		LoadResource((Handle)h);

		/* Remember it */
		samples[num] = h;

#endif /* !USE_QT_SOUND */

		/* Lock the handle */
		HLock((Handle)h);

		/* Initialise refcount */
		sample_refs[num] = 1;
	}

	/* Poll the channel */
	err = SndChannelStatus(chan, sizeof(SCStatus), &status);

	/* It isn't available */
	if ((err != noErr) || status.scChannelBusy)
	{
		/* Shut it down */
		SndDoImmediate(chan, &quiet_cmd);
	}

	/* Previously played sound on this channel */
	prev_num = channel_occupants[next_chan];

	/* Process previously played sound */
	if (prev_num != 0)
	{
		/* Decrease refcount */
		sample_refs[prev_num]--;

		/* We can free it now */
		if (sample_refs[prev_num] <= 0)
		{
			/* Unlock */
			HUnlock((Handle)samples[prev_num]);

#ifndef USE_QT_SOUND

			/* Release */
			ReleaseResource((Handle)samples[prev_num]);

			/* Forget handle */
			samples[prev_num] = NULL;

#endif /* !USE_QT_SOUND */

			/* Paranoia */
			sample_refs[prev_num] = 0;
		}
	}

	/* Remember this sound as the current occupant of the channel */
	channel_occupants[next_chan] = num;

	/* Set up volume for channel */
	SndDoImmediate(chan, &volume_cmd);

	/* Play new sound asynchronously */
	SndPlay(chan, h, TRUE);

	/* Schedule next channel (round robin) */
	next_chan++;
	if (next_chan >= MAX_CHANNELS) next_chan = 0;
}

#endif /* USE_ASYNC_SOUND */




/*** Support for the "z-term.c" package ***/


/*
 * Initialize a new Term
 *
 * Note also the "window type" called "noGrowDocProc", which might be more
 * appropriate for the main "screen" window.
 *
 * Note the use of "srcCopy" mode for optimized screen writes.
 */
static void Term_init_mac(term *t)
{
	term_data *td = (term_data*)(t->data);
	WindowAttributes wattrs;
	OSStatus err;

	static RGBColor black = {0x0000, 0x0000, 0x0000};
	static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};

#ifndef ALLOW_BIG_SCREEN

	/* Every window has close and collapse boxes */
	wattrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute;

	/* Information windows are resizable */
	if (td != &data[0]) wattrs |= kWindowResizableAttribute;

#else

	/* Big screen - every window has close, collapse and resize boxes */
	wattrs = kWindowCloseBoxAttribute |
	         kWindowCollapseBoxAttribute |
	         kWindowResizableAttribute;

#endif /* !ALLOW_BIG_SCREEN */

	/* Make the window  */
	err = CreateNewWindow(
	              kDocumentWindowClass,
	              wattrs,
	              &td->r,
	              &td->w);

	/*
	 * XXX XXX Although the original main-mac.c doesn't perform error
	 * checking, it should be done here.
	 */

	/* Set window title */
	SetWTitle(td->w, td->title);

	/* Activate the window */
	activate(td->w);

	/* Erase behind words */
	TextMode(srcCopy);

	/* Apply and Verify */
	term_data_check_font(td);
	term_data_check_size(td);

	/* Resize the window */
	term_data_resize(td);


	/* Prepare the colors (real colors) */
	RGBBackColor(&black);
	RGBForeColor(&white);

	/* Block */
	{
		Rect globalRect;
		GDHandle mainGDH;
		GDHandle currentGDH;
		GWorldPtr windowGWorld;
		PixMapHandle basePixMap;

		/* Obtain the global rect */
		GetWindowBounds((WindowRef)td->w, kWindowContentRgn, &globalRect);

		/* Obtain the proper GDH */
		mainGDH = GetMaxDevice(&globalRect);

		/* Extract GWorld and GDH */
		GetGWorld(&windowGWorld, ¤tGDH);

		/* Obtain base pixmap */
		basePixMap = (**mainGDH).gdPMap;

		/* Save pixel depth */
		td->pixelDepth = (**basePixMap).pixelSize;

		/* Save Window GWorld - unused */
		td->theGWorld = windowGWorld;

		/* Save Window GDH */
		td->theGDH = currentGDH;

		/* Save main GDH - unused */
		td->mainSWGDH = mainGDH;
	}

	{
		Rect portRect;

		/* Get current Rect */
		GetPortBounds(GetWindowPort(td->w), &portRect);

		/* Clip to the window */
		ClipRect(&portRect);

		/* Erase the window */
		EraseRect(&portRect);

		/* Invalidate the window */
		InvalWindowRect(td->w, &portRect);
	}

	/*
	 * A certain release of OS X fails to display windows at proper
	 * locations (_ _#)
	 */
	if ((mac_os_version >= 0x1000) && (mac_os_version < 0x1010))
	{
		/* Hack - Make sure the window is displayed at (r.left,r.top) */
		MoveWindow(td->w, td->r.left, td->r.top, 1);
	}

	/* Display the window if needed */
	if (td->mapped)
	{
		TransitionWindow(td->w,
		                 kWindowZoomTransitionEffect, kWindowShowTransitionAction, NULL);
	}

	/* Hack -- set "mapped" flag */
	t->mapped_flag = td->mapped;

	/* Forget color */
	td->last = -1;
}



/*
 * Nuke an old Term
 */
static void Term_nuke_mac(term *t)
{
	/* XXX */
}



/*
 * Unused
 */
static errr Term_user_mac(int n)
{
	/* Success */
	return (0);
}



/*
 * React to changes
 */
static errr Term_xtra_mac_react(void)
{
	term_data *td = (term_data*)(Term->data);

	int i;


	/* Reset color */
	td->last = -1;

	/* Update colors */
	for (i = 0; i < 256; i++)
	{
		u16b rv, gv, bv;

		/* Extract the R,G,B data */
		rv = angband_color_table[i][1];
		gv = angband_color_table[i][2];
		bv = angband_color_table[i][3];

		/* Save the actual color */
		color_info[i].red = (rv | (rv << 8));
		color_info[i].green = (gv | (gv << 8));
		color_info[i].blue = (bv | (bv << 8));
	}


	/* Handle sound */
	if (use_sound != arg_sound)
	{
		/* Apply request */
		use_sound = arg_sound;
	}


	/* Handle graphics */
	if (graf_mode_req != graf_mode)
	{
		/* dispose old GWorld's if present */
		globe_nuke();

		/*
		 * Setup parameters according to request
		 *
		 * In [Z], you have to set use_graphics and arg_graphics to
		 * GRAPHICS_NONE, GRAPHICS_ORIGINAL or GRAPHICS_ADAM_BOLT, and
		 * comment ANGBAND_GRAF out.
		 */
		switch (graf_mode_req)
		{
			/* ASCII - no graphics whatsoever */
		case GRAF_MODE_NONE:
			{
				use_graphics = arg_graphics = FALSE;
				transparency_mode = TR_NONE;
				break;
			}

			/*
			 * 8x8 tiles (PICT id 1001)
			 * no transparency effect
			 * "old" graphics definitions
			 */
		case GRAF_MODE_8X8:
			{
				use_graphics = arg_graphics = TRUE;
				ANGBAND_GRAF = "old";
				transparency_mode = TR_NONE;
#ifdef MACH_O_CARBON
				pict_id = CFSTR("8x8");
#else
				pict_id = 1001;
#endif /* MACH_O_CARBON */
				graf_width = graf_height = 8;
				break;
			}

			/*
			 * 16x16 tiles (images: PICT id 1002, masks: PICT id 1003)
			 * with transparency effect
			 * "new" graphics definitions
			 */
		case GRAF_MODE_16X16:
			{
				use_graphics = arg_graphics = TRUE;
				ANGBAND_GRAF = "new";
				transparency_mode = TR_OVER;
#ifdef MACH_O_CARBON
				pict_id = CFSTR("16x16");
#else
				pict_id = 1002;
#endif /* MACH_O_CARBON */
				graf_width = graf_height = 16;
				break;
			}

			/*
			 * 32x32 tiles (images: PICT id 1004)
			 * with transparency effect
			 * "david" graphics definitions
			 * Vanilla-specific
			 */
		case GRAF_MODE_32X32:
			{
				use_graphics = arg_graphics = TRUE;
				ANGBAND_GRAF = "david";
				transparency_mode = TR_OVER;
#ifdef MACH_O_CARBON
				pict_id = CFSTR("32x32");
#else
				pict_id = 1004;
#endif /* MACH_O_CARBON */
				graf_width = graf_height = 32;
				break;
			}
		}

		/* load tiles and setup GWorlds if tiles are requested */
		if ((graf_mode_req != GRAF_MODE_NONE) && (globe_init() != 0))
		{
			/* Oops */
			plog("Cannot initialize graphics!");

			/* reject request */
			graf_mode_req = GRAF_MODE_NONE;

			/* reset graphics flags */
			use_graphics = arg_graphics = FALSE;

			/* reset transparency mode */
			transparency_mode = TR_NONE;
		}

		/* update current graphics mode */
		graf_mode = graf_mode_req;

		/* Apply and Verify */
		term_data_check_size(td);

		/* Resize the window */
		term_data_resize(td);

		/* Reset visuals */
#ifndef ANG281_RESET_VISUALS
		reset_visuals(TRUE);
#else
		reset_visuals();
#endif /* !ANG281_RESET_VISUALS */
	}

	/* Success */
	return (0);
}


/*
 * Do a "special thing"
 */
static errr Term_xtra_mac(int n, int v)
{
	term_data *td = (term_data*)(Term->data);

	Rect r;

	/* Analyze */
	switch (n)
	{
		/* Make a noise */
	case TERM_XTRA_NOISE:
		{
			/* Make a noise */
			SysBeep(1);

			/* Success */
			return (0);
		}

		/* Make a sound */
	case TERM_XTRA_SOUND:
		{
#ifndef USE_ASYNC_SOUND

			/*
			 * This may not be your choice, but much safer and much less
			 * resource hungry.  Existing implementations can quite easily
			 * crash, by starting asynchronous playing and immediately
			 * unlocking and releasing the sound data just started playing...
			 * -- pelpel
			 */
			Handle handle;
			Str255 sound;

			/* Get the proper sound name */
			strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[v]);
			sound[0] = strlen((char*)sound + 1);

			/* Obtain resource XXX XXX XXX */
			handle = GetNamedResource('snd ', sound);

			/* Oops -- it is a failure, but we return 0 anyway */
			if (handle == NULL) return (0);

			/* Load and Lock */
			LoadResource(handle);
			HLock(handle);

			/* Play sound (wait for completion) */
			SndPlay(NULL, (SndListHandle)handle, FALSE);

			/* Unlock and release */
			HUnlock(handle);
			ReleaseResource(handle);

#else /* !USE_ASYNC_SOUND */

			/* Play sound */
			play_sound(v, sound_volume);

#endif /* !USE_ASYNC_SOUND */

			/* Success */
			return (0);
		}

		/* Process random events */
	case TERM_XTRA_BORED:
		{
			/* Process an event */
			(void)CheckEvents(FALSE);

			/* Success */
			return (0);
		}

		/* Process pending events */
	case TERM_XTRA_EVENT:
		{
			/* Process an event */
			(void)CheckEvents(v);

			/* Success */
			return (0);
		}

		/* Flush all pending events (if any) */
	case TERM_XTRA_FLUSH:
		{
			/* Hack -- flush all events */
			while (CheckEvents(FALSE)) /* loop */;

			/* Success */
			return (0);
		}

		/* Hack -- Change the "soft level" */
	case TERM_XTRA_LEVEL:
		{
			/* Activate if requested */
			if (v) activate(td->w);

			/* Success */
			return (0);
		}

		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		{
			Rect portRect;

			/* Get current Rect */
			GetPortBounds(GetWindowPort(td->w), &portRect);

			/* No clipping XXX XXX XXX */
			ClipRect(&portRect);

			/* Erase the window */
			EraseRect(&portRect);

			/* Set the color */
			term_data_color(td, TERM_WHITE);

			/* Frame the window in white */
			MoveTo(0, 0);
			LineTo(0, td->size_hgt - 1);
			LineTo(td->size_wid - 1, td->size_hgt - 1);
			LineTo(td->size_wid - 1, 0);

			/* Clip to the new size */
			r.left = portRect.left + td->size_ow1;
			r.top = portRect.top + td->size_oh1;
			r.right = portRect.right - td->size_ow2;
			r.bottom = portRect.bottom - td->size_oh2;
			ClipRect(&r);

			/* Success */
			return (0);
		}

		/* React to changes */
	case TERM_XTRA_REACT:
		{
			/* React to changes */
			return (Term_xtra_mac_react());
		}

		/* Delay (milliseconds) */
	case TERM_XTRA_DELAY:
		{
			/*
			 * WaitNextEvent relinquishes CPU as well as
			 * induces a screen refresh on OS X
			 */

			/* If needed */
			if (v > 0)
			{
				EventRecord tmp;
				UInt32 ticks;

				/* Convert millisecs to ticks */
				ticks = (v * 60L) / 1000;

				/*
				 * Hack? - Put the programme into sleep.
				 * No events match ~everyEvent, so nothing
				 * should be lost in Angband's event queue.
				 * Even if ticks are 0, it's worth calling for
				 * the above mentioned reasons.
				 */
				WaitNextEvent((EventMask)~everyEvent, &tmp, ticks, nil);
			}

			/* Success */
			return (0);
		}

		/* Rename main window */
	case TERM_XTRA_RENAME_MAIN_WIN:
		{
			char *s = strdup(angband_term_name[0]);

			ctopstr((StringPtr)s);
			SetWTitle(data[0].w, (StringPtr)s);

			free(s);
			return (0);
		}

/* MacOSX == Unix == Good */
#ifdef USE_MACOSX
		/* Get Delay of some milliseconds */
	case TERM_XTRA_GET_DELAY:
		{
			int ret;
			struct timeval tv;

			ret = gettimeofday(&tv, NULL);
			Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);

			return ret;
		}

		/* Subdirectory scan */
	case TERM_XTRA_SCANSUBDIR:
		{
			DIR *directory;
			struct dirent *entry;

			scansubdir_max = 0;

			directory = opendir(scansubdir_dir);
			if (!directory)
				return 1;

			while ((entry = readdir(directory)))
			{
				char file[PATH_MAX + NAME_MAX + 2];
				struct stat filedata;

				file[PATH_MAX + NAME_MAX] = 0;
				strncpy(file, scansubdir_dir, PATH_MAX);
				strncat(file, "/", 2);
				strncat(file, entry->d_name, NAME_MAX);
				if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(entry->d_name);
					++scansubdir_max;
				}
			}

			closedir(directory);
			return 0;
		}
#endif
	}

	/* Oops */
	return (1);
}



/*
 * Low level graphics (Assumes valid input).
 * Draw a "cursor" at (x,y), using a "yellow box".
 * We are allowed to use "Term_what()" to determine
 * the current screen contents (for inverting, etc).
 */
static errr Term_curs_mac(int x, int y)
{
	Rect r;

	term_data *td = (term_data*)(Term->data);

	/* Set the color */
	term_data_color(td, TERM_YELLOW);

	/* Frame the grid */
	r.left = x * td->tile_wid + td->size_ow1;
	r.right = r.left + td->tile_wid;
	r.top = y * td->tile_hgt + td->size_oh1;
	r.bottom = r.top + td->tile_hgt;

#ifdef USE_DOUBLE_TILES

	/* Mogami's bigtile patch */

	/* Adjust it if double width tiles are requested */
	if (use_bigtile &&
	                (x + 1 < Term->wid) &&
	                (Term->old->a[y][x + 1] == 255))
	{
		r.right += td->tile_wid;
	}

#endif /* USE_DOUBLE_TILES */

	FrameRect(&r);

	/* Success */
	return (0);
}


/*
 * Low level graphics (Assumes valid input)
 *
 * Erase "n" characters starting at (x,y)
 */
static errr Term_wipe_mac(int x, int y, int n)
{
	Rect r;

	term_data *td = (term_data*)(Term->data);


	/* Erase the block of characters */
	r.left = x * td->tile_wid + td->size_ow1;
	r.right = r.left + n * td->tile_wid;
	r.top = y * td->tile_hgt + td->size_oh1;
	r.bottom = r.top + td->tile_hgt;
	EraseRect(&r);

	/* Success */
	return (0);
}


/*
 * Low level graphics.  Assumes valid input.
 *
 * Draw several ("n") chars, with an attr, at a given location.
 */
static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
{
	int xp, yp;

#ifdef CLIP_HACK
	Rect r;
#endif /* CLIP_HACK */

	term_data *td = (term_data*)(Term->data);


	/* Set the color */
	term_data_color(td, a);

#ifdef CLIP_HACK
	/* Hack - only draw within the bounding rect */
	r.left = x * td->tile_wid + td->size_ow1;
	r.right = r.left + n * td->tile_wid;
	r.top = y * td->tile_hgt + td->size_oh1;
	r.bottom = r.top + td->tile_hgt;
	ClipRect(&r);

	/* Hack - clear the content of the bounding rect */
	EraseRect(&r);
#endif /* CLIP_HACK */

	/* Starting pixel */
	xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
	yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;

	/* Move to the correct location */
	MoveTo(xp, yp);

	/* Draw the character */
	if (n == 1) DrawChar(*cp);

	/* Draw the string */
	else DrawText(cp, 0, n);

#ifdef CLIP_HACK
	/* Obtain current window's rect */
	GetPortBounds(GetWindowPort(td->w), &r);

	/* Clip to the window again */
	ClipRect(&r);
#endif /* CLIP_HACK */

	/* Success */
	return (0);
}


/*
 * Low level graphics (Assumes valid input)
 *
 * Erase "n" characters starting at (x,y)
 */
#ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp,
                          const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
#else /* USE_TRANSPARENCY */
static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp)
#endif /* USE_TRANSPARENCY */
{
	int i;
	Rect dst_r;
	GrafPtr port;
	PixMapHandle pixmap_h;

#ifdef CLIP_HACK
	Rect portRect;
#endif /* CLIP_HACK */

	term_data *td = (term_data*)(Term->data);

	static RGBColor black = {0x0000, 0x0000, 0x0000};
	static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};


#ifdef CLIP_HACK
	/* Remember current window's rect */
	GetPortBounds(GetWindowPort(td->w), &portRect);
#endif /* CLIP_HACK */

	/* Destination rectangle */
	dst_r.left = x * td->tile_wid + td->size_ow1;
#ifndef USE_DOUBLE_TILES
	dst_r.right = dst_r.left + td->tile_wid;
#endif /* !USE_DOUBLE_TILES */
	dst_r.top = y * td->tile_hgt + td->size_oh1;
	dst_r.bottom = dst_r.top + td->tile_hgt;

	/* Scan the input */
	for (i = 0; i < n; i++)
	{
		bool done = FALSE;

		byte a = *ap++;
		char c = *cp++;

#ifdef USE_TRANSPARENCY
		byte ta = *tap++;
		char tc = *tcp++;
# ifdef USE_EGO_GRAPHICS
		byte ea = *eap++;
		char ec = *ecp++;
		bool has_overlay = (ea && ec);
# endif  /* USE_EGO_GRAPHICS */
#endif


#ifdef USE_DOUBLE_TILES

		/* Hack -- a filler for double-width tile */
		if (use_bigtile && (a == 255))
		{
			/* Advance */
			dst_r.left += td->tile_wid;

			/* Ignore */
			continue;
		}

		/* Prepare right side of rectagle now */
		dst_r.right = dst_r.left + td->tile_wid;

#endif /* USE_DOUBLE_TILES */

		/* Graphics -- if Available and Needed */
		if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80))
		{
			int col, row;
			Rect src_r;
#ifdef USE_TRANSPARENCY
			int t_col, t_row;
			Rect terrain_r;
# ifdef USE_EGO_GRAPHICS
			int e_col, e_row;
			Rect ego_r;
# endif  /* USE_EGO_GRAPHICS */
#endif /* USE_TRANSPARENCY */

			/* Row and Col */
			row = ((byte)a & 0x7F) % pict_rows;
			col = ((byte)c & 0x7F) % pict_cols;

			/* Source rectangle */
			src_r.left = col * graf_width;
			src_r.top = row * graf_height;
			src_r.right = src_r.left + graf_width;
			src_r.bottom = src_r.top + graf_height;

#ifdef USE_TRANSPARENCY
			/* Row and Col */
			t_row = ((byte)ta & 0x7F) % pict_rows;
			t_col = ((byte)tc & 0x7F) % pict_cols;

			/* Source rectangle */
			terrain_r.left = t_col * graf_width;
			terrain_r.top = t_row * graf_height;
			terrain_r.right = terrain_r.left + graf_width;
			terrain_r.bottom = terrain_r.top + graf_height;

# ifdef USE_EGO_GRAPHICS

			/* If there's an overlay */
			if (has_overlay)
			{
				/* Row and Col */
				e_row = ((byte)ea & 0x7F) % pict_rows;
				e_col = ((byte)ec & 0x7F) % pict_cols;

				/* Source rectangle */
				ego_r.left = e_col * graf_width;
				ego_r.top = e_row * graf_height;
				ego_r.right = ego_r.left + graf_width;
				ego_r.bottom = ego_r.top + graf_height;
			}

# endif  /* USE_EGO_GRAPHICS */

#endif /* USE_TRANSPARENCY */

			/* Hardwire CopyBits */
			RGBBackColor(&white);
			RGBForeColor(&black);

#ifdef USE_DOUBLE_TILES

			/* Double width tiles */
			if (use_bigtile) dst_r.right += td->tile_wid;

#endif /* USE_DOUBLE_TILES */

			/*
			 * OS X requires locking and unlocking of window port
			 * when we draw directly to its pixmap.
			 * The Lock/Unlock protocol is described in the Carbon
			 * Porting Guide.
			 */

			/* Obtain current window's graphic port */
			port = GetWindowPort(td->w);

			/* Lock pixels, so we can use handle safely */
			LockPortBits(port);

			/* Get Pixmap handle */
			pixmap_h = GetPortPixMap(port);

#ifdef USE_TRANSPARENCY

			/* Transparency effect */
			switch (transparency_mode)
			{
				/* No transparency effects */
			case TR_NONE:
			default:
				{
					/* Draw the picture */
					CopyBits((BitMap*)frameP->framePix,
					         (BitMap*)*pixmap_h,
					         &src_r, &dst_r, srcCopy, NULL);

					break;
				}

				/* Overwriting with transparent black pixels */
			case TR_OVER:
				{
					/* Draw the terrain */
					CopyBits((BitMap*)frameP->framePix,
					         (BitMap*)*pixmap_h,
					         &terrain_r, &dst_r, srcCopy, NULL);

					/* Make black pixels transparent */
					RGBBackColor(&black);

					/* Draw mon/obj if there's one */
					if ((row != t_row) || (col != t_col))
						CopyBits((BitMap*)frameP->framePix,
						         (BitMap*)*pixmap_h,
						         &src_r, &dst_r, transparent, NULL);

# ifdef USE_EGO_GRAPHICS

					/* Draw overlay if there's one */
					if (has_overlay)
					{
						CopyBits((BitMap*)frameP->framePix,
						         (BitMap*)*pixmap_h,
						         &ego_r, &dst_r, transparent, NULL);
					}

# endif  /* USE_EGO_GRAPHICS */

					break;
				}
			}

#else /* USE_TRANSPARENCY */

			/* Draw the picture */
			CopyBits((BitMap*)frameP->framePix,
			         (BitMap*)*pixmap_h,
			         &src_r, &dst_r, srcCopy, NULL);

#endif /* USE_TRANSPARENCY */

			/* Release the lock and dispose the PixMap handle */
			UnlockPortBits(port);

			/* Restore colors */
			RGBBackColor(&black);
			RGBForeColor(&white);

			/* Forget color */
			td->last = -1;

			/* Done */
			done = TRUE;
		}

		/* Normal */
		if (!done)
		{
			int xp, yp;

#ifdef CLIP_HACK
			/* Hack - avoid writing outside of dst_r */
			ClipRect(&dst_r);
			/* Some characters do not match dst_r, therefore we have to... */
#endif /* CLIP_HACK */

			/* Erase */
			EraseRect(&dst_r);

			/* Set the color */
			term_data_color(td, a);

			/* Starting pixel */
			xp = dst_r.left + td->tile_o_x;
			yp = dst_r.top + td->tile_o_y;

			/* Move to the correct location */
			MoveTo(xp, yp);

			/* Draw the character */
			DrawChar(c);

#ifdef CLIP_HACK
			/* Clip to the window - inefficient (; ;) XXX XXX */
			ClipRect(&portRect);
#endif /* CLIP_HACK */
		}

		/* Advance */
		dst_r.left += td->tile_wid;
#ifndef USE_DOUBLE_TILES
		dst_r.right += td->tile_wid;
#endif /* !USE_DOUBLE_TILES */
	}

	/* Success */
	return (0);
}





/*
 * Create and initialize window number "i"
 */
static void term_data_link(int i)
{
	term *old = Term;

	term_data *td = &data[i];

	/* Only once */
	if (td->t) return;

	/* Require mapped */
	if (!td->mapped) return;

	/* Allocate */
	MAKE(td->t, term);

	/* Initialize the term */
	term_init(td->t, td->cols, td->rows, td->keys);

	/* Use a "software" cursor */
	td->t->soft_cursor = TRUE;

	/* Erase with "white space" */
	td->t->attr_blank = TERM_WHITE;
	td->t->char_blank = ' ';

	/* Prepare the init/nuke hooks */
	td->t->init_hook = Term_init_mac;
	td->t->nuke_hook = Term_nuke_mac;

	/* Prepare the function hooks */
	td->t->user_hook = Term_user_mac;
	td->t->xtra_hook = Term_xtra_mac;
	td->t->wipe_hook = Term_wipe_mac;
	td->t->curs_hook = Term_curs_mac;
	td->t->text_hook = Term_text_mac;
	td->t->pict_hook = Term_pict_mac;

#if 0

	/* Doesn't make big difference? */
	td->t->never_bored = TRUE;

#endif

	/* Link the local structure */
	td->t->data = (void *)(td);

	/* Activate it */
	Term_activate(td->t);

	/* Global pointer */
	angband_term[i] = td->t;

	/* Activate old */
	Term_activate(old);
}




#ifdef MACH_O_CARBON

/*
 * (Carbon, Bundle)
 * Return a POSIX pathname of the lib directory, or NULL if it can't be
 * located.  Caller must supply a buffer along with its size in bytes,
 * where returned pathname will be stored.
 * I prefer use of goto's to several nested if's, if they involve error
 * handling.  Sorry if you are offended by their presence.  Modern
 * languages have neater constructs for this kind of jobs -- pelpel
 */
static char *locate_lib(char *buf, size_t size)
{
	CFURLRef main_url = NULL;
	CFStringRef main_str = NULL;
	char *p;
	char *res = NULL;

	/* Obtain the URL of the main bundle */
	main_url = CFBundleCopyBundleURL(CFBundleGetMainBundle());

	/* Oops */
	if (main_url == NULL) goto ret;

	/* Convert it to POSIX pathname */
	main_str = CFURLCopyFileSystemPath(main_url, kCFURLPOSIXPathStyle);

	/* Oops */
	if (main_str == NULL) goto ret;

	/* Convert it again from darn unisomething encoding to ASCII */
	if (CFStringGetCString(main_str, buf, size, kTextEncodingUS_ASCII) == FALSE)
		goto ret;

	/*
	 * Paranoia - bounds check
	 */
	if (strlen(buf) + 25 + 1 > size) goto ret;

	/* Location of the data */
	strcat(buf, "/Contents/Resources/");

	/* Set result */
	res = buf;

ret:

	/* Release objects allocated and implicitly retained by the program */
	if (main_str) CFRelease(main_str);
	if (main_url) CFRelease(main_url);

	/* pathname of the lib folder or NULL */
	return (res);
}


#else /* MACH_O_CARBON */

/*
* Set the "current working directory" (also known as the "default"
* volume/directory) to the location of the current application.
*
* Original code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
*
* Completely rewritten to use Carbon Process Manager.  It retrieves the
* volume and direcotry of the current application and simply stores it
* in the (static) global variables app_vol and app_dir, but doesn't
* mess with the "current working directory", because it has long been
* an obsolete (and arcane!) feature.
*/
static void SetupAppDir(void)
{
	OSErr err;
	ProcessSerialNumber curPSN;
	ProcessInfoRec procInfo;
	FSSpec cwdSpec;

	/* Initialise PSN info for the current process */
	curPSN.highLongOfPSN = 0;
	curPSN.lowLongOfPSN = kCurrentProcess;

	/* Fill in mandatory fields */
	procInfo.processInfoLength = sizeof(ProcessInfoRec);
	procInfo.processName = nil;
	procInfo.processAppSpec = &cwdSpec;

	/* Obtain current process information */
	err = GetProcessInformation(&curPSN, &procInfo);

	/* Oops */
	if (err != noErr)
	{
		mac_warning("Unable to get process information");

		/* Quit without writing anything */
		ExitToShell();
	}

	/* Extract and save the Vol and Dir */
	app_vol = cwdSpec.vRefNum;
	app_dir = cwdSpec.parID;
}

#endif /* MACH_O_CARBON */




/*
 * Using Core Foundation's Preferences services -- pelpel
 *
 * Requires OS 8.6 or greater with CarbonLib 1.1 or greater. Or OS X,
 * of course.
 *
 * Without this, we can support older versions of OS 8 as well
 * (with CarbonLib 1.0.4).
 *
 * Frequent allocation/deallocation of small chunks of data is
 * far from my liking, but since this is only called at the
 * beginning and the end of a session, I hope this hardly matters.
 */


/*
 * Store "value" as the value for preferences item name
 * pointed by key
 */
static void save_pref_short(const char *key, short value)
{
	CFStringRef cf_key;
	CFNumberRef cf_value;

	/* allocate and initialise the key */
	cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII);

	/* allocate and initialise the value */
	cf_value = CFNumberCreate(NULL, kCFNumberShortType, &value);

	if ((cf_key != NULL) && (cf_value != NULL))
	{
		/* Store the key-value pair in the applications preferences */
		CFPreferencesSetAppValue(
		        cf_key,
		        cf_value,
		        kCFPreferencesCurrentApplication);
	}

	/*
	 * Free CF data - the reverse order is a vain attempt to
	 * minimise memory fragmentation.
	 */
	if (cf_value) CFRelease(cf_value);
	if (cf_key) CFRelease(cf_key);
}


/*
 * Load preference value for key, returns TRUE if it succeeds with
 * vptr updated appropriately, FALSE otherwise.
 */
static bool query_load_pref_short(const char *key, short *vptr)
{
	CFStringRef cf_key;
	CFNumberRef cf_value;

	/* allocate and initialise the key */
	cf_key = CFStringCreateWithCString(NULL, key, kTextEncodingUS_ASCII);

	/* Oops */
	if (cf_key == NULL) return (FALSE);

	/* Retrieve value for the key */
	cf_value = CFPreferencesCopyAppValue(
	                   cf_key,
	                   kCFPreferencesCurrentApplication);

	/* Value not found */
	if (cf_value == NULL)
	{
		CFRelease(cf_key);
		return (FALSE);
	}

	/* Convert the value to short */
	CFNumberGetValue(
	        cf_value,
	        kCFNumberShortType,
	        vptr);

	/* Free CF data */
	CFRelease(cf_value);
	CFRelease(cf_key);

	/* Success */
	return (TRUE);
}


/*
 * Update short data pointed by vptr only if preferences
 * value for key is located.
 */
static void load_pref_short(const char *key, short *vptr)
{
	short tmp;

	if (query_load_pref_short(key, &tmp)) *vptr = tmp;
	return;
}


/*
 * Save preferences to preferences file for current host+current user+
 * current application.
 */
static void cf_save_prefs()
{
	int i;

	/* Version stamp */
	save_pref_short("version.major", PREF_VER_MAJOR);
	save_pref_short("version.minor", PREF_VER_MINOR);
	save_pref_short("version.patch", PREF_VER_PATCH);
	save_pref_short("version.extra", PREF_VER_EXTRA);

	/* Gfx settings */
	save_pref_short("arg.arg_sound", arg_sound);
	save_pref_short("arg.graf_mode", graf_mode);
#ifdef USE_DOUBLE_TILES
	save_pref_short("arg.big_tile", use_bigtile);
#endif /* USE_DOUBLE_TILES */

	/* Windows */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		term_data *td = &data[i];

		save_pref_short(format("term%d.font_mono", i), td->font_mono); 
		save_pref_short(format("term%d.font_o_x", i), td->font_o_x);
		save_pref_short(format("term%d.font_o_y", i), td->font_o_y);
		save_pref_short(format("term%d.font_wid", i), td->font_wid);
		save_pref_short(format("term%d.font_hgt", i), td->font_hgt);
		save_pref_short(format("term%d.tile_o_x", i), td->tile_o_x);
		save_pref_short(format("term%d.tile_o_y", i), td->tile_o_y);
		save_pref_short(format("term%d.right", i), td->r.right);
		save_pref_short(format("term%d.bottom", i), td->r.bottom);
		save_pref_short(format("term%d.ow1", i), td->size_ow1);
		save_pref_short(format("term%d.oh1", i), td->size_oh1);
		save_pref_short(format("term%d.ow2", i), td->size_ow2);
		save_pref_short(format("term%d.oh2", i), td->size_oh2);

		save_pref_short(format("term%d.mapped", i), td->mapped);

		save_pref_short(format("term%d.font_id", i), td->font_id);
		save_pref_short(format("term%d.font_size", i), td->font_size);
		save_pref_short(format("term%d.font_face", i), td->font_face);

		save_pref_short(format("term%d.tile_wid", i), td->tile_wid);
		save_pref_short(format("term%d.tile_hgt", i), td->tile_hgt);

		save_pref_short(format("term%d.cols", i), td->cols);
		save_pref_short(format("term%d.rows", i), td->rows);
		save_pref_short(format("term%d.left", i), td->r.left);
		save_pref_short(format("term%d.top", i), td->r.top);
	}

	/*
	 * Make sure preferences are persistent
	 */
	CFPreferencesAppSynchronize(
	        kCFPreferencesCurrentApplication);
}


/*
 * Load preferences from preferences file for current host+current user+
 * current application.
 */
static void cf_load_prefs()
{
	bool ok;
	short pref_major, pref_minor, pref_patch, pref_extra;
	int i;

	/* Assume nothing is wrong, yet */
	ok = TRUE;

	/* Load version information */
	ok &= query_load_pref_short("version.major", &pref_major);
	ok &= query_load_pref_short("version.minor", &pref_minor);
	ok &= query_load_pref_short("version.patch", &pref_patch);
	ok &= query_load_pref_short("version.extra", &pref_extra);

	/* Any of the above failed */
	if (!ok)
	{
		/* This may be the first run */
		mac_warning("Preferences are not found.");

		/* Ignore the rest */
		return;
	}

#if 0

	/* Check version */
	if ((pref_major != PREF_VER_MAJOR) ||
	                (pref_minor != PREF_VER_MINOR) ||
	                (pref_patch != PREF_VER_PATCH) ||
	                (pref_extra != PREF_VER_EXTRA))
	{
		/* Message */
		mac_warning(
		        format("Ignoring %d.%d.%d.%d preferences.",
		               pref_major, pref_minor, pref_patch, pref_extra));

		/* Ignore */
		return;
	}

#endif

	/* Gfx settings */
	{
		short pref_tmp;

		/* sound */
		if (query_load_pref_short("arg.arg_sound", &pref_tmp))
			arg_sound = pref_tmp;

		/* graphics */
		if (query_load_pref_short("arg.graf_mode", &pref_tmp))
			graf_mode_req = pref_tmp;

#ifdef USE_DOUBLE_TILES

		/* double-width tiles */
		if (query_load_pref_short("arg.big_tile", &pref_tmp))
		{
			use_bigtile = pref_tmp;
		}

#endif /* USE_DOUBLE_TILES */

	}

	/* Windows */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		term_data *td = &data[i];

		load_pref_short(format("term%d.mapped", i), &td->mapped);

		load_pref_short(format("term%d.font_id", i), &td->font_id);
		load_pref_short(format("term%d.font_size", i), &td->font_size);
		load_pref_short(format("term%d.font_face", i), &td->font_face);

		load_pref_short(format("term%d.tile_wid", i), &td->tile_wid);
		load_pref_short(format("term%d.tile_hgt", i), &td->tile_hgt);

		load_pref_short(format("term%d.cols", i), &td->cols);
		load_pref_short(format("term%d.rows", i), &td->rows);
		load_pref_short(format("term%d.left", i), &td->r.left);
		load_pref_short(format("term%d.top", i), &td->r.top);

		load_pref_short(format("term%d.font_mono", i), &td->font_mono); 
		load_pref_short(format("term%d.font_o_x", i), &td->font_o_x);
		load_pref_short(format("term%d.font_o_y", i), &td->font_o_y);
		load_pref_short(format("term%d.font_wid", i), &td->font_wid);
		load_pref_short(format("term%d.font_hgt", i), &td->font_hgt);
		load_pref_short(format("term%d.tile_o_x", i), &td->tile_o_x);
		load_pref_short(format("term%d.tile_o_y", i), &td->tile_o_y);
		load_pref_short(format("term%d.right", i), &td->r.right);
		load_pref_short(format("term%d.bottom", i), &td->r.bottom);
		load_pref_short(format("term%d.ow1", i), &td->size_ow1);
		load_pref_short(format("term%d.oh1", i), &td->size_oh1);
		load_pref_short(format("term%d.ow2", i), &td->size_ow2);
		load_pref_short(format("term%d.oh2", i), &td->size_oh2);
	}
}




/*
 * Hack -- default data for a window
 */
static void term_data_hack(term_data *td)
{
	short fid;

	/* Default to Monaco font */
	GetFNum("\pmonaco", &fid);

	/* Wipe it */
	WIPE(td, term_data);

	/* No color */
	td->last = -1;

	/* Default borders */
	td->size_ow1 = 2;
	td->size_ow2 = 2;
	td->size_oh1 = 2;
	td->size_oh2 = 2;

	/* Start hidden */
	td->mapped = FALSE;

	/* Default font */
	td->font_id = fid;

	/* Default font size - was 12 */
	td->font_size = 14;

	/* Default font face */
	td->font_face = 0;

	/* Default size */
	td->rows = 24;
	td->cols = 80;

	/* Default position */
	td->r.left = 10;
	td->r.top = 40;

	/* Minimal keys */
	td->keys = 16;
}


/*
 * Read the preference file, Create the windows.
 *
 * We attempt to use "FindFolder()" to track down the preference file.
 */
static void init_windows(void)
{
	int i, b = 0;

	term_data *td;


	/*** Default values ***/

	/* Initialize (backwards) */
	for (i = MAX_TERM_DATA; i-- > 0; )
	{
		int n;

		cptr s;

		/* Obtain */
		td = &data[i];

		/* Defaults */
		term_data_hack(td);

		/* Obtain title */
		s = angband_term_name[i];

		/* Get length */
		n = strlen(s);

		/* Maximal length */
		if (n > 15) n = 15;

		/* Copy the title */
		strncpy((char*)(td->title) + 1, s, n);

		/* Save the length */
		td->title[0] = n;

		/* Tile the windows */
		td->r.left += (b * 30);
		td->r.top += (b * 30);

		/* Tile */
		b++;
	}


	/*** Load preferences ***/

	cf_load_prefs();


	/*** Instantiate ***/

	/* Main window */
	td = &data[0];

	/* Many keys */
	td->keys = 1024;

	/* Start visible */
	td->mapped = TRUE;

	/* Link (backwards, for stacking order) */
	for (i = MAX_TERM_DATA; i-- > 0; )
	{
		term_data_link(i);
	}

	/* Main window */
	td = &data[0];

	/* Main window */
	Term_activate(td->t);
}


/*
 * Save preferences
 */
static void save_pref_file(void)
{
	cf_save_prefs();
}




#ifndef SAVEFILE_SCREEN

/*
 * Prepare savefile dialogue and set the variable
 * savefile accordingly. Returns true if it succeeds, false (or
 * aborts) otherwise. If all is false, only allow files whose type
 * is 'SAVE'.
 * Originally written by Peter Ammon
 */
static bool select_savefile(bool all)
{
	OSErr err;
	FSSpec theFolderSpec;
	FSSpec savedGameSpec;
	NavDialogOptions dialogOptions;
	NavReplyRecord reply;
	/* Used only when 'all' is true */
	NavTypeList types = {ANGBAND_CREATOR, 1, 1, {'SAVE'}};
	NavTypeListHandle myTypeList;
	AEDesc defaultLocation;

#ifdef MACH_O_CARBON

	/* Find the save folder */
	err = path_to_spec(ANGBAND_DIR_SAVE, &theFolderSpec);

#else

	/* Find :lib:save: folder */
	err = FSMakeFSSpec(
	              app_vol,
	              app_dir,
	              "\p:lib:save:",
	              &theFolderSpec);

#endif

	/* Oops */
	if (err != noErr) quit("Unable to find the folder :lib:save:");

	/* Get default Navigator dialog options */
	err = NavGetDefaultDialogOptions(&dialogOptions);

	/* Clear preview option */
	dialogOptions.dialogOptionFlags &= ~kNavAllowPreviews;

	/* Disable multiple file selection */
	dialogOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles;

	/* Make descriptor for default location */
	err = AECreateDesc(
	              typeFSS,
	              &theFolderSpec,
	              sizeof(FSSpec),
	              &defaultLocation);

	/* Oops */
	if (err != noErr) quit("Unable to allocate descriptor");

	/* We are indifferent to signature and file types */
	if (all)
	{
		myTypeList = (NavTypeListHandle)nil;
	}

	/* Set up type handle */
	else
	{
		err = PtrToHand(&types, (Handle *) & myTypeList, sizeof(NavTypeList));

		/* Oops */
		if (err != noErr) quit("Error in PtrToHand. Try enlarging heap");

	}

	/* Call NavGetFile() with the types list */
	err = NavChooseFile(
	              &defaultLocation,
	              &reply,
	              &dialogOptions,
	              nil,
	              nil,
	              nil,
	              myTypeList,
	              nil);

	/* Free type list */
	DisposeHandle((Handle)myTypeList);

	/* Invalid response -- allow the user to cancel */
	if (!reply.validRecord) return (FALSE);

	/* Retrieve FSSpec from the reply */
	if (err == noErr)
	{
		AEKeyword theKeyword;
		DescType actualType;
		Size actualSize;

		/* Get a pointer to selected file */
		(void)AEGetNthPtr(
		        &reply.selection,
		        1,
		        typeFSS,
		        &theKeyword,
		        &actualType,
		        &savedGameSpec,
		        sizeof(FSSpec),
		        &actualSize);

		/* Dispose NavReplyRecord, resources and descriptors */
		(void)NavDisposeReply(&reply);
	}

	/* Dispose location info */
	AEDisposeDesc(&defaultLocation);

#ifdef MACH_O_CARBON

	/* Convert FSSpec to pathname and store it in variable savefile */
	(void)spec_to_path(&savedGameSpec, savefile, sizeof(savefile));

#else

	/* Convert FSSpec to pathname and store it in variable savefile */
	refnum_to_name(
	        savefile,
	        savedGameSpec.parID,
	        savedGameSpec.vRefNum,
	        (char *)savedGameSpec.name);

#endif

	/* Success */
	return (TRUE);
}


/*
 * Handle menu: "File" + "New"
 */
static void do_menu_file_new(void)
{
	/* Hack */
	HiliteMenu(0);

	/* Game is in progress */
	game_in_progress = 1;

	/* Flush input */
	Term_flush();

	/* Play a game */
	play_game(TRUE);

	/* Hack -- quit */
	quit(NULL);
}


/*
 * Handle menu: "File" + "Open" /  "Import"
 */
static void do_menu_file_open(bool all)
{
	/* Let the player to choose savefile */
	if (!select_savefile(all)) return;

	/* Hack */
	HiliteMenu(0);

	/* Game is in progress */
	game_in_progress = 1;

	/* Flush input */
	flush();

	/* Play a game */
	play_game(FALSE);

	/* Hack -- quit */
	quit(NULL);
}

#endif /* !SAVEFILE_SCREEN */


/*
 * Handle the "open_when_ready" flag
 */
static void handle_open_when_ready(void)
{
	/* Check the flag XXX XXX XXX make a function for this */
	if (open_when_ready && initialized && !game_in_progress)
	{
		/* Forget */
		open_when_ready = FALSE;

		/* Game is in progress */
		game_in_progress = 1;

		/* Wait for it */
		pause_line(23);

		/* Flush input */
		flush();

#ifdef SAVEFILE_SCREEN

		/* User double-clicked savefile; no savefile screen */
		no_begin_screen = TRUE;

#endif /* SAVEFILE_SCREEN */

		/* Play a game */
		play_game(FALSE);

		/* Quit */
		quit(NULL);
	}
}




/*
 * Menus
 *
 * The standard menus are:
 *
 *   Apple (128) =   { About, -, ... }
 *   File (129) =    { New,Open,Import,Close,Save,-,Score,Quit }
 *     (If SAVEFILE_SCREEN is defined, this becomes)
 *   File (129) =    { Close,Save,-,Score,Quit }
 *   Edit (130) =    { Cut, Copy, Paste, Clear }   (?)
 *   Font (131) =    { Bold, Extend, -, Monaco, ..., -, ... }
 *   Size (132) =    { ... }
 *   Window (133) =  { Angband, Term-1/Mirror, Term-2/Recall, Term-3/Choice,
 *                     Term-4, Term-5, Term-6, Term-7 }
 *   Special (134) = { Sound, Graphics, TileWidth, TileHeight, -,
 *                     Fiddle, Wizard }
 */

/* Apple menu */
#define MENU_APPLE	128
#define ITEM_ABOUT	1

/* File menu */
#define MENU_FILE	129
#ifndef SAVEFILE_SCREEN
# define ITEM_NEW	1
# define ITEM_OPEN	2
# define ITEM_IMPORT	3
# define ITEM_CLOSE	4
# define ITEM_SAVE	5
# ifdef HAS_SCORE_MENU
# define ITEM_SCORE 7
# define ITEM_QUIT	8
# else
# define ITEM_QUIT	7
# endif  /* HAS_SCORE_MENU */
#else /* !SAVEFILE_SCREEN - in-game savefile menu */
# define ITEM_CLOSE	1
# define ITEM_SAVE	2
# ifdef HAS_SCORE_MENU
# define ITEM_SCORE 4
# define ITEM_QUIT	5
# else
# define ITEM_QUIT	4
# endif  /* HAS_SCORE_MENU */
#endif /* !SAVEFILE_SCREEN */

/* Edit menu */
#define MENU_EDIT	130
#define ITEM_UNDO	1
#define ITEM_CUT	3
#define ITEM_COPY	4
#define ITEM_PASTE	5
#define ITEM_CLEAR	6

/* Font menu */
#define MENU_FONT	131
#define ITEM_BOLD	1
#define ITEM_WIDE	2

/* Size menu */
#define MENU_SIZE	132

/* Windows menu */
#define MENU_WINDOWS	133

/* Special menu */
#define MENU_SPECIAL	134
#define ITEM_SOUND	1
#define ITEM_GRAPH	2
# define SUBMENU_GRAPH	144
# define ITEM_NONE	1
# define ITEM_8X8	2
# define ITEM_16X16	3
# define ITEM_32X32	4
# define ITEM_BIGTILE 6
#define ITEM_TILEWIDTH 3
# define SUBMENU_TILEWIDTH 145
#define ITEM_TILEHEIGHT 4
# define SUBMENU_TILEHEIGHT 146
#define ITEM_FIDDLE	6
#define ITEM_WIZARD	7


/*
 * I HATE UNICODE!  We've never wanted it.  Some multi-national companies
 * made it up as their internationalisation "solution".  So I won't use
 * any such API's -- pelpel
 */
#define NSIZES 32
static byte menu_size_values[NSIZES];
static byte menu_tilewidth_values[NSIZES];
static byte menu_tileheight_values[NSIZES];

/*
 * Initialize the menus
 *
 * Fixed top level menus are now loaded all at once by GetNewMBar().
 * Although this simplifies the function a bit, we have to make sure
 * that resources have all the expected entries defined XXX XXX
 */
static void init_menubar(void)
{
	int i, n;

	Rect r;

	WindowPtr tmpw;

	MenuRef m;

#ifdef USE_NIB

	/* The new way - loading main menu using Interface Builder services */
	{
		IBNibRef nib;
		OSStatus err;

		/* Create a nib reference to the main nib file */
		err = CreateNibReference(CFSTR("main"), &nib);

		/* Fatal error - missing Main.nib */
		if (err != noErr) quit("Cannot find Main.nib in the bundle!");

		/* Unarchive the menu bar and make it ready to use */
		err = SetMenuBarFromNib(nib, CFSTR("MainMenu"));

		/* Fatal error - couldn't insert menu bar */
		if (err != noErr) quit("Cannot prepare menu bar!");

		/* Dispose of the nib reference because we don't need it any longer */
		DisposeNibReference(nib);
	}

#else /* USE_NIB */

	/* The old way - loading main menu from Resource Manager resource */
	{
		Handle mbar;

		/* Load menubar from resources */
		mbar = GetNewMBar(128);

		/* Whoops! */
		if (mbar == nil) quit("Cannot find menubar('MBAR') id 128!");

		/* Insert them into the current menu list */
		SetMenuBar(mbar);

		/* Free handle */
		DisposeHandle(mbar);
	}

#endif /* USE_NIB */


	/* Apple menu (id 128) - we don't have to do anything */

#ifndef USE_NIB

	/* File menu (id 129) - Aqua provides Quit menu for us */
	if (is_aqua)
	{
		/* Get a handle to the file menu */
		m = GetMenuHandle(MENU_FILE);

		/* Nuke the quit menu since Aqua does that for us */
		DeleteMenuItem(m, ITEM_QUIT);

#ifndef HAS_SCORE_MENU

		/* Hack - because the above leaves a separator as the last item */
		DeleteMenuItem(m, ITEM_QUIT - 1);

#endif /* !HAS_SCORE_MENU */
	}

#endif /* !USE_NIB */


	/* Edit menu (id 130) - we don't have to do anything */


	/*
	 * Font menu (id 131) - append names of mono-spaced fonts
	 * followed by all available ones
	 */
	m = GetMenuHandle(MENU_FONT);

	/* Fake window */
	r.left = r.right = r.top = r.bottom = 0;

	/* Make the fake window so that we can retrieve font info */
	(void)CreateNewWindow(
	        kDocumentWindowClass,
	        kWindowNoAttributes,
	        &r,
	        &tmpw);

	/* Activate the "fake" window */
	SetPort(GetWindowPort(tmpw));

	/* Default mode */
	TextMode(0);

	/* Default size */
	TextSize(12);

	/* Add the fonts to the menu */
	AppendResMenu(m, 'FONT');

	/* Size of menu */
	n = CountMenuItems(m);

	/* Scan the menu */
	for (i = n; i >= 4; i--)
	{
		Str255 tmpName;
		short fontNum;

		/* Acquire the font name */
		GetMenuItemText(m, i, tmpName);

		/* Acquire the font index */
		GetFNum(tmpName, &fontNum);

		/* Apply the font index */
		TextFont(fontNum);

		/* Remove non-mono-spaced fonts */
		if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
		{
			/* Delete the menu item */
			DeleteMenuItem(m, i);
		}
	}

	/* Destroy the fake window */
	DisposeWindow(tmpw);

	/* Add a separator */
	AppendMenu(m, "\p-");

	/* Add the fonts to the menu */
	AppendResMenu(m, 'FONT');


#ifndef USE_NIB

	/* Size menu (id 132) */
	m = GetMenuHandle(MENU_SIZE);

	/* Add some sizes (stagger choices) */
	for (i = 8, n = 1; i <= 32; i += ((i / 16) + 1), n++)
	{
		Str15 buf;

		/* Textual size */
		strnfmt((char*)buf + 1, 15, "%d", i);
		buf[0] = strlen((char*)buf + 1);

		/* Add the item */
		AppendMenu(m, buf);

		/* Remember its value, for we can't be sure it's in ASCII */
		menu_size_values[n] = i;
	}

#endif /* !USE_NIB */


	/* Windows menu (id 133) */
	m = GetMenuHandle(MENU_WINDOWS);

	/* Default choices */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		Str15 buf;

		/* Describe the item */
		strnfmt((char*)buf + 1, 15, "%.15s", angband_term_name[i]);
		buf[0] = strlen((char*)buf + 1);

		/* Add the item */
		AppendMenu(m, buf);

		/* Command-Key shortcuts */
		if (i < 8) SetItemCmd(m, i + 1, I2D(i));
	}


#ifndef USE_NIB

	/* Special menu (id 134) */
	m = GetMenuHandle(MENU_SPECIAL);

	/* Insert Graphics submenu (id 144) */
	{
		MenuHandle submenu;

		/* Get the submenu */
		submenu = GetMenu(SUBMENU_GRAPH);

		/* Insert it */
		SetMenuItemHierarchicalMenu(m, ITEM_GRAPH, submenu);
	}

	/* Insert TileWidth submenu (id 145) */
	{
		MenuHandle submenu;

		/* Get the submenu */
		submenu = GetMenu(SUBMENU_TILEWIDTH);

		/* Add some sizes */
		for (i = 4, n = 1; i <= 32; i++, n++)
		{
			Str15 buf;

			/* Textual size */
			strnfmt((char*)buf + 1, 15, "%d", i);
			buf[0] = strlen((char*)buf + 1);

			/* Append item */
			AppendMenu(submenu, buf);

			/* Remember its value, for we can't be sure it's in ASCII */
			menu_tilewidth_values[n] = i;
		}

		/* Insert it */
		SetMenuItemHierarchicalMenu(m, ITEM_TILEWIDTH, submenu);
	}

	/* Insert TileHeight submenu (id 146) */
	{
		MenuHandle submenu;

		/* Get the submenu */
		submenu = GetMenu(SUBMENU_TILEHEIGHT);


		/* Add some sizes */
		for (i = 4, n = 1; i <= 32; i++, n++)
		{
			Str15 buf;

			/* Textual size */
			strnfmt((char*)buf + 1, 15, "%d", i);
			buf[0] = strlen((char*)buf + 1);

			/* Append item */
			AppendMenu(submenu, buf);

			/* Remember its value, for we can't be sure it's in ASCII */
			menu_tileheight_values[n] = i;
		}

		/* Insert it */
		SetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, submenu);
	}

#endif /* !USE_NIB */

	/* Update the menu bar */
	DrawMenuBar();
}


/*
 * Prepare the menus
 *
 * It is very important that the player not be allowed to "save" the game
 * unless the "inkey_flag" variable is set, indicating that the game is
 * waiting for a new command.  XXX XXX XXX
 */

static void setup_menus(void)
{
	int i, n;

	short value;

	Str255 s;

	MenuHandle m;

	term_data *td = NULL;


	/* Relevant "term_data" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Unused */
		if (!data[i].t) continue;

		/* Notice the matching window */
		if (data[i].w == FrontWindow()) td = &data[i];
	}


	/* File menu */
	m = GetMenuHandle(MENU_FILE);

	/* Get menu size */
	n = CountMenuItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableMenuItem(m, i);
		CheckMenuItem(m, i, FALSE);
	}

#ifndef SAVEFILE_SCREEN

	/* Enable "new"/"open..."/"import..." */
	if (initialized && !game_in_progress)
	{
		EnableMenuItem(m, ITEM_NEW);
		EnableMenuItem(m, ITEM_OPEN);
		EnableMenuItem(m, ITEM_IMPORT);
	}

#endif /* !SAVEFILE_SCREEN */

	/* Enable "close" */
	if (initialized)
	{
		EnableMenuItem(m, ITEM_CLOSE);
	}

	/* Enable "save" */
	if (initialized && character_generated && inkey_flag)
	{
		EnableMenuItem(m, ITEM_SAVE);
	}

#ifdef HAS_SCORE_MENU

	/* Enable "score" */
	if (initialized && character_generated && !character_icky)
	{
		EnableMenuItem(m, ITEM_SCORE);
	}

#endif /* HAS_SCORE_MENU */

	/* Enable "quit" */
	if (!is_aqua)
	{
		if (!initialized || !character_generated || inkey_flag)
		{
			EnableMenuItem(m, ITEM_QUIT);
		}
	}


	/* Edit menu */
	m = GetMenuHandle(MENU_EDIT);

	/* Get menu size */
	n = CountMenuItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableMenuItem(m, i);
		CheckMenuItem(m, i, FALSE);
	}

	/* Enable "edit" options if "needed" */
	if (!td)
	{
		EnableMenuItem(m, ITEM_UNDO);
		EnableMenuItem(m, ITEM_CUT);
		EnableMenuItem(m, ITEM_COPY);
		EnableMenuItem(m, ITEM_PASTE);
		EnableMenuItem(m, ITEM_CLEAR);
	}


	/* Font menu */
	m = GetMenuHandle(MENU_FONT);

	/* Get menu size */
	n = CountMenuItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableMenuItem(m, i);
		CheckMenuItem(m, i, FALSE);
	}

	/* Hack -- look cute XXX XXX */
	/* SetItemStyle(m, ITEM_BOLD, bold); */

	/* Hack -- look cute XXX XXX */
	/* SetItemStyle(m, ITEM_WIDE, extend); */

	/* Active window */
	if (initialized && td)
	{
		/* Enable "bold" */
		EnableMenuItem(m, ITEM_BOLD);

		/* Enable "extend" */
		EnableMenuItem(m, ITEM_WIDE);

		/* Check the appropriate "bold-ness" */
		if (td->font_face & bold) CheckMenuItem(m, ITEM_BOLD, TRUE);

		/* Check the appropriate "wide-ness" */
		if (td->font_face & extend) CheckMenuItem(m, ITEM_WIDE, TRUE);

		/* Analyze fonts */
		for (i = 4; i <= n; i++)
		{
			/* Enable it */
			EnableMenuItem(m, i);

			/* Analyze font */
			GetMenuItemText(m, i, s);
			GetFNum(s, &value);

			/* Check active font */
			if (td->font_id == value) CheckMenuItem(m, i, TRUE);
		}
	}


	/* Size menu */
	m = GetMenuHandle(MENU_SIZE);

	/* Get menu size */
	n = CountMenuItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableMenuItem(m, i);
		CheckMenuItem(m, i, FALSE);
	}

	/* Active window */
	if (initialized && td)
	{
		/* Analyze sizes */
		for (i = 1; i <= n; i++)
		{
			/* Analyze size */
			value = menu_size_values[i];

			/* Enable the "real" sizes */
			if (RealFont(td->font_id, value)) EnableMenuItem(m, i);

			/* Check the current size */
			if (td->font_size == value) CheckMenuItem(m, i, TRUE);
		}
	}


	/* Windows menu */
	m = GetMenuHandle(MENU_WINDOWS);

	/* Get menu size */
	n = CountMenuItems(m);

	/* Check active windows */
	for (i = 1; i <= n; i++)
	{
		/* Check if needed */
		CheckMenuItem(m, i, data[i - 1].mapped);
	}


	/* Special menu */
	m = GetMenuHandle(MENU_SPECIAL);

	/* Get menu size */
	n = CountMenuItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableMenuItem(m, i);
		CheckMenuItem(m, i, FALSE);
	}

	/* Item "arg_sound" */
	EnableMenuItem(m, ITEM_SOUND);
	CheckMenuItem(m, ITEM_SOUND, arg_sound);

	/* Item "Graphics" */
	EnableMenuItem(m, ITEM_GRAPH);
	{
		MenuRef submenu;

		/* Graphics submenu */
		(void)GetMenuItemHierarchicalMenu(m, ITEM_GRAPH, &submenu);

		/* Get menu size */
		n = CountMenuItems(submenu);

		/* Reset menu */
		for (i = 1; i <= n; i++)
		{
			/* Reset */
			DisableMenuItem(submenu, i);
			CheckMenuItem(submenu, i, FALSE);
		}

		/* Item "None" */
		EnableMenuItem(submenu, ITEM_NONE);
		CheckMenuItem(submenu, ITEM_NONE, (graf_mode == GRAF_MODE_NONE));

		/* Item "8x8" */
		EnableMenuItem(submenu, ITEM_8X8);
		CheckMenuItem(submenu, ITEM_8X8, (graf_mode == GRAF_MODE_8X8));

		/* Item "16x16" */
		EnableMenuItem(submenu, ITEM_16X16);
		CheckMenuItem(submenu, ITEM_16X16, (graf_mode == GRAF_MODE_16X16));

		/* Item "32x32" */
		/*EnableMenuItem(submenu, ITEM_32X32);
		CheckMenuItem(submenu, ITEM_32X32, (graf_mode == GRAF_MODE_32X32));*/

#ifdef USE_DOUBLE_TILES

		/* Item "Big tiles" */
		if (inkey_flag) EnableMenuItem(submenu, ITEM_BIGTILE);
		CheckMenuItem(submenu, ITEM_BIGTILE, use_bigtile);

#endif /* USE_DOUBLE_TILES */

	}

	/* Item "TileWidth" */
	EnableMenuItem(m, ITEM_TILEWIDTH);
	{
		MenuRef submenu;

		/* TileWidth submenu */
		(void)GetMenuItemHierarchicalMenu(m, ITEM_TILEWIDTH, &submenu);

		/* Get menu size */
		n = CountMenuItems(submenu);

		/* Reset menu */
		for (i = 1; i <= n; i++)
		{
			/* Reset */
			DisableMenuItem(submenu, i);
			CheckMenuItem(submenu, i, FALSE);
		}

		/* Active window */
		if (initialized && td)
		{
			/* Analyze sizes */
			for (i = 1; i <= n; i++)
			{
				/* Analyze size */
				value = menu_tilewidth_values[i];

				/* Enable */
				if (value >= td->font_wid) EnableMenuItem(submenu, i);

				/* Check the current size */
				if (td->tile_wid == value) CheckMenuItem(submenu, i, TRUE);
			}
		}
	}

	/* Item "TileHeight" */
	EnableMenuItem(m, ITEM_TILEHEIGHT);
	{
		MenuRef submenu;

		/* TileWidth submenu */
		(void)GetMenuItemHierarchicalMenu(m, ITEM_TILEHEIGHT, &submenu);

		/* Get menu size */
		n = CountMenuItems(submenu);

		/* Reset menu */
		for (i = 1; i <= n; i++)
		{
			/* Reset */
			DisableMenuItem(submenu, i);
			CheckMenuItem(submenu, i, FALSE);
		}

		/* Active window */
		if (initialized && td)
		{
			/* Analyze sizes */
			for (i = 1; i <= n; i++)
			{
				/* Analyze size */
				value = menu_tileheight_values[i];

				/* Enable */
				if (value >= td->font_hgt) EnableMenuItem(submenu, i);

				/* Check the current size */
				if (td->tile_hgt == value) CheckMenuItem(submenu, i, TRUE);
			}
		}
	}

	/* Item "arg_fiddle" */
	EnableMenuItem(m, ITEM_FIDDLE);
	CheckMenuItem(m, ITEM_FIDDLE, arg_fiddle);

	/* Item "arg_wizard" */
	EnableMenuItem(m, ITEM_WIZARD);
	CheckMenuItem(m, ITEM_WIZARD, arg_wizard);


	/* TileHeight menu */
	m = GetMenuHandle(SUBMENU_TILEHEIGHT);

	/* Get menu size */
	n = CountMenuItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableMenuItem(m, i);
		CheckMenuItem(m, i, FALSE);
	}
}


/*
 * Process a menu selection (see above)
 *
 * Hack -- assume that invalid menu selections are disabled above,
 * which I have been informed may not be reliable.  XXX XXX XXX
 */
static void menu(long mc)
{
	int i;

	int menuid, selection;

	static unsigned char s[1000];

	short fid;

	term_data *td = NULL;

	WindowPtr old_win;


	/* Analyze the menu command */
	menuid = HiWord(mc);
	selection = LoWord(mc);


	/* Find the window */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Skip dead windows */
		if (!data[i].t) continue;

		/* Notice matches */
		if (data[i].w == FrontWindow()) td = &data[i];
	}


	/* Branch on the menu */
	switch (menuid)
	{
		/* Apple Menu */
	case MENU_APPLE:
		{
			/* About Angband... */
			if (selection == ITEM_ABOUT)
			{
				DialogPtr dialog;
				short item_hit;

				/* Get the about dialogue */
				dialog = GetNewDialog(128, 0, (WindowPtr) - 1);

				/* Move it to the middle of the screen */
				RepositionWindow(
				        GetDialogWindow(dialog),
				        NULL,
				        kWindowCenterOnMainScreen);

				/* Show the dialog */
				TransitionWindow(GetDialogWindow(dialog),
				                 kWindowZoomTransitionEffect,
				                 kWindowShowTransitionAction,
				                 NULL);

				/* Wait for user to click on it */
				ModalDialog(0, &item_hit);

				/* Free the dialogue */
				DisposeDialog(dialog);
				break;
			}

			break;
		}

		/* File Menu */
	case MENU_FILE:
		{
			switch (selection)
			{
#ifndef SAVEFILE_SCREEN

				/* New */
			case ITEM_NEW:
				{
					do_menu_file_new();
					break;
				}

				/* Open... */
			case ITEM_OPEN:
				{
					do_menu_file_open(FALSE);
					break;
				}

				/* Import... */
			case ITEM_IMPORT:
				{
					do_menu_file_open(TRUE);
					break;
				}

#endif /* !SAVEFILE_SCREEN */

				/* Close */
			case ITEM_CLOSE:
				{
					/* No window */
					if (!td) break;

					/* Not Mapped */
					td->mapped = FALSE;

					/* Not Mapped */
					td->t->mapped_flag = FALSE;

					/* Hide the window */
					TransitionWindow(td->w,
					                 kWindowZoomTransitionEffect,
					                 kWindowHideTransitionAction,
					                 NULL);

					break;
				}

				/* Save */
			case ITEM_SAVE:
				{
					/* Hack -- Forget messages */
					msg_flag = FALSE;

					/* Hack -- Save the game */
#ifndef ZANG_AUTO_SAVE
					do_cmd_save_game();
#else
					do_cmd_save_game(FALSE);
#endif /* !ZANG_AUTO_SAVE */

					break;
				}

#ifdef HAS_SCORE_MENU

				/* Show score */
			case ITEM_SCORE:
				{
					char buf[1024];

					/* Paranoia */
					if (!initialized || character_icky ||
					                !game_in_progress || !character_generated)
					{
						/* Can't happen but just in case */
						plog("You may not do that right now.");

						break;
					}

					/* Build the pathname of the score file */
					path_build(buf, sizeof(buf), ANGBAND_DIR_APEX,
					           "scores.raw");

					/* Hack - open the score file for reading */
					highscore_fd = fd_open(buf, O_RDONLY);

					/* Paranoia - No score file */
					if (highscore_fd < 0)
					{
						msg_print("Score file is not available.");

						break;
					}

					/* Mega-Hack - prevent various functions XXX XXX XXX */
					initialized = FALSE;

					/* Save screen */
					screen_save();

					/* Clear screen */
					Term_clear();

					/* Prepare scores */
					if (game_in_progress && character_generated)
					{
						predict_score();
					}

#if 0 /* I don't like this - pelpel */

					/* Mega-Hack - No current player XXX XXX XXX XXX */
					else
					{
						display_scores_aux(0, MAX_HISCORES, -1, NULL);
					}

#endif

					/* Close the high score file */
					(void)fd_close(highscore_fd);

					/* Forget the fd */
					highscore_fd = -1;

					/* Restore screen */
					screen_load();

					/* Hack - Flush it */
					Term_fresh();

					/* Mega-Hack - We are ready again */
					initialized = TRUE;

					/* Done */
					break;
				}

#endif /* HAS_SCORE_MENU */

				/* Quit (with save) */
			case ITEM_QUIT:
				{
					/* Save the game (if necessary) */
					if (game_in_progress && character_generated)
					{
						/* Hack -- Forget messages */
						msg_flag = FALSE;

						/* Save the game */
#ifndef ZANG_AUTO_SAVE
						do_cmd_save_game();
#else
						do_cmd_save_game(FALSE);
#endif /* !ZANG_AUTO_SAVE */
					}

					/* Quit */
					quit(NULL);
					break;
				}
			}
			break;
		}

		/* Edit menu */
	case MENU_EDIT:
		{
			/* Unused */
			break;
		}

		/* Font menu */
	case MENU_FONT:
		{
			/* Require a window */
			if (!td) break;

			/* Memorize old */
			old_win = active;

			/* Activate */
			activate(td->w);

			/* Toggle the "bold" setting */
			if (selection == ITEM_BOLD)
			{
				/* Toggle the setting */
				if (td->font_face & bold)
				{
					td->font_face &= ~bold;
				}
				else
				{
					td->font_face |= bold;
				}

				/* Hack - clear tile size info XXX XXX */
				td->tile_wid = td->tile_hgt = 0;

				/* Apply and Verify */
				term_data_check_font(td);
				term_data_check_size(td);

				/* Resize and Redraw */
				term_data_resize(td);
				term_data_redraw(td);

				break;
			}

			/* Toggle the "wide" setting */
			if (selection == ITEM_WIDE)
			{
				/* Toggle the setting */
				if (td->font_face & extend)
				{
					td->font_face &= ~extend;
				}
				else
				{
					td->font_face |= extend;
				}

				/* Hack - clear tile size info XXX XXX */
				td->tile_wid = td->tile_hgt = 0;

				/* Apply and Verify */
				term_data_check_font(td);
				term_data_check_size(td);

				/* Resize and Redraw */
				term_data_resize(td);
				term_data_redraw(td);

				break;
			}

			/* Get a new font name */
			GetMenuItemText(GetMenuHandle(MENU_FONT), selection, s);
			GetFNum(s, &fid);

			/* Save the new font id */
			td->font_id = fid;

			/* Current size is bad for new font */
			if (!RealFont(td->font_id, td->font_size))
			{
				/* Find similar size */
				for (i = 1; i <= 32; i++)
				{
					/* Adjust smaller */
					if (td->font_size - i >= 8)
					{
						if (RealFont(td->font_id, td->font_size - i))
						{
							td->font_size -= i;
							break;
						}
					}

					/* Adjust larger */
					if (td->font_size + i <= 128)
					{
						if (RealFont(td->font_id, td->font_size + i))
						{
							td->font_size += i;
							break;
						}
					}
				}
			}

			/* Hack - clear tile size info XXX XXX */
			td->tile_wid = td->tile_hgt = 0;

			/* Apply and Verify */
			term_data_check_font(td);
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore the window */
			activate(old_win);

			break;
		}

		/* Size menu */
	case MENU_SIZE:
		{
			if (!td) break;

			/* Save old */
			old_win = active;

			/* Activate */
			activate(td->w);

			td->font_size = menu_size_values[selection];

			/* Hack - clear tile size info XXX XXX */
			td->tile_wid = td->tile_hgt = 0;

			/* Apply and Verify */
			term_data_check_font(td);
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore */
			activate(old_win);

			break;
		}

		/* Window menu */
	case MENU_WINDOWS:
		{
			/* Parse */
			i = selection - 1;

			/* Check legality of choice */
			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			/* Obtain the window */
			td = &data[i];

			/* Mapped */
			td->mapped = TRUE;

			/* Link */
			term_data_link(i);

			/* Mapped (?) */
			td->t->mapped_flag = TRUE;

			/* Show the window */
			TransitionWindow(td->w,
			                 kWindowZoomTransitionEffect,
			                 kWindowShowTransitionAction,
			                 NULL);

			/* Bring to the front */
			SelectWindow(td->w);

			break;
		}

		/* Special menu */
	case MENU_SPECIAL:
		{
			switch (selection)
			{
			case ITEM_SOUND:
				{
					/* Toggle arg_sound */
					arg_sound = !arg_sound;

					/* React to changes */
					Term_xtra(TERM_XTRA_REACT, 0);

					break;
				}

			case ITEM_FIDDLE:
				{
					arg_fiddle = !arg_fiddle;

					break;
				}

			case ITEM_WIZARD:
				{
					arg_wizard = !arg_wizard;

					break;
				}
			}

			break;
		}

		/* Graphics submenu */
	case SUBMENU_GRAPH:
		{
			switch (selection)
			{
			case ITEM_NONE:
				{
					graf_mode_req = GRAF_MODE_NONE;

					break;
				}

			case ITEM_8X8:
				{
					graf_mode_req = GRAF_MODE_8X8;

					break;
				}

			case ITEM_16X16:
				{
					graf_mode_req = GRAF_MODE_16X16;

					break;
				}

			case ITEM_32X32:
				{
					graf_mode_req = GRAF_MODE_32X32;

					break;
				}

#ifdef USE_DOUBLE_TILES

			case ITEM_BIGTILE:
				{
					term *old = Term;
					term_data *td = &data[0];

					/* Toggle "use_bigtile" */
					use_bigtile = !use_bigtile;
					arg_bigtile = use_bigtile;

					/* Activate */
					Term_activate(td->t);

					/* Resize the term */
					Term_resize(td->cols, td->rows);

					/* Activate old */
					Term_activate(old);

					break;
				}

#endif /* USE_DOUBLE_TILES */

			}

			/* Hack -- Force redraw */
			Term_key_push(KTRL('R'));

			break;
		}

		/* TileWidth menu */
	case SUBMENU_TILEWIDTH:
		{
			if (!td) break;

			/* Save old */
			old_win = active;

			/* Activate */
			activate(td->w);

			/* Analyse value */
			td->tile_wid = menu_tilewidth_values[selection];

			/* Apply and Verify */
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore */
			activate(old_win);

			break;
		}

		/* TileHeight menu */
	case SUBMENU_TILEHEIGHT:
		{
			if (!td) break;

			/* Save old */
			old_win = active;

			/* Activate */
			activate(td->w);

			/* Analyse value */
			td->tile_hgt = menu_tileheight_values[selection];

			/* Apply and Verify */
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore */
			activate(old_win);

			break;
		}
	}


	/* Clean the menu */
	HiliteMenu(0);
}


/*
 * Check for extra required parameters -- From "Maarten Hazewinkel"
 */
static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
{
	OSErr aeError;
	DescType returnedType;
	Size actualSize;

	aeError = AEGetAttributePtr(
	                  theAppleEvent, keyMissedKeywordAttr, typeWildCard,
	                  &returnedType, NULL, 0, &actualSize);

	if (aeError == errAEDescNotFound) return (noErr);

	if (aeError == noErr) return (errAEParamMissed);

	return (aeError);
}


/*
 * Apple Event Handler -- Open Application
 */
static OSErr AEH_Start(const AppleEvent *theAppleEvent, AppleEvent *reply,
                       SInt32 handlerRefCon)
{
	return (CheckRequiredAEParams(theAppleEvent));
}


/*
 * Apple Event Handler -- Quit Application
 */
static OSErr AEH_Quit(const AppleEvent *theAppleEvent, AppleEvent *reply,
                      SInt32 handlerRefCon)
{
	/* Quit later */
	quit_when_ready = TRUE;

	/* Check arguments */
	return (CheckRequiredAEParams(theAppleEvent));
}


/*
 * Apple Event Handler -- Print Documents
 */
static OSErr AEH_Print(const AppleEvent *theAppleEvent, AppleEvent *reply,
                       SInt32 handlerRefCon)
{
	return (errAEEventNotHandled);
}


/*
 * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
 *
 * The old method of opening savefiles from the finder does not work
 * on the Power Macintosh, because CountAppFiles and GetAppFiles,
 * used to return information about the selected document files when
 * an application is launched, are part of the Segment Loader, which
 * is not present in the RISC OS due to the new memory architecture.
 *
 * The "correct" way to do this is with AppleEvents.  The following
 * code is modeled on the "Getting Files Selected from the Finder"
 * snippet from Think Reference 2.0.  (The prior sentence could read
 * "shamelessly swiped & hacked")
 */
static OSErr AEH_Open(const AppleEvent *theAppleEvent, AppleEvent* reply,
                      SInt32 handlerRefCon)
{
	FSSpec myFSS;
	AEDescList docList;
	OSErr err;
	Size actualSize;
	AEKeyword keywd;
	DescType returnedType;
	char msg[128];
	FInfo myFileInfo;

	/* Put the direct parameter (a descriptor list) into a docList */
	err = AEGetParamDesc(
	              theAppleEvent, keyDirectObject, typeAEList, &docList);
	if (err) return err;

	/*
	 * We ignore the validity check, because we trust the FInder, and we only
	 * allow one savefile to be opened, so we ignore the depth of the list.
	 */
	err = AEGetNthPtr(
	              &docList, 1L, typeFSS, &keywd, &returnedType,
	              (Ptr) & myFSS, sizeof(myFSS), &actualSize);
	if (err) return err;

	/* Only needed to check savefile type below */
	err = FSpGetFInfo(&myFSS, &myFileInfo);
	if (err)
	{
		strnfmt(msg, 128, "Argh!  FSpGetFInfo failed with code %d", err);
		mac_warning(msg);
		return err;
	}

	/* Ignore non 'SAVE' files */
	if (myFileInfo.fdType != 'SAVE') return noErr;

#ifdef MACH_O_CARBON

	/* Extract a file name */
	(void)spec_to_path(&myFSS, savefile, sizeof(savefile));

#else

	/* XXX XXX XXX Extract a file name */
	PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
	pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);

	/* Convert the string */
	ptocstr((StringPtr)savefile);

#endif /* MACH_O_CARBON */

	/* Delay actual open */
	open_when_ready = TRUE;

	/* Dispose */
	err = AEDisposeDesc(&docList);

	/* Success */
	return noErr;
}


/*
 * Handle quit_when_ready, by Peter Ammon,
 * slightly modified to check inkey_flag.
 */
static void quit_calmly(void)
{
	/* Quit immediately if game's not started */
	if (!game_in_progress || !character_generated) quit(NULL);

	/* Save the game and Quit (if it's safe) */
	if (inkey_flag)
	{
		/* Hack -- Forget messages */
		msg_flag = FALSE;

		/* Save the game */
#ifndef ZANG_AUTO_SAVE
		do_cmd_save_game();
#else
		do_cmd_save_game(FALSE);
#endif /* !ZANG_AUTO_SAVE */

		/* Quit */
		quit(NULL);
	}

	/* Wait until inkey_flag is set */
}


/*
 * Macintosh modifiers (event.modifier & ccc):
 *   cmdKey, optionKey, shiftKey, alphaLock, controlKey
 *
 *
 * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
 *
 * Return:36
 * Delete:51
 *
 * Period:65
 * Star:67
 * Plus:69
 * Clear:71
 * Slash:75
 * Enter:76
 * Minus:78
 * Equal:81
 * 0-7:82-89
 * 8-9:91-92
 *
 * backslash/vertical bar (Japanese keyboard):93
 *
 * F5: 96
 * F6: 97
 * F7: 98
 * F3:99
 * F8:100
 * F10:101
 * F11:103
 * F13:105
 * F14:107
 * F9:109
 * F12:111
 * F15:113
 * Help:114
 * Home:115
 * PgUp:116
 * Del:117
 * F4: 118
 * End:119
 * F2:120
 * PgDn:121
 * F1:122
 * Lt:123
 * Rt:124
 * Dn:125
 * Up:126
 */


/*
 * Check for Events, return TRUE if we process any
 *
 * Now it really waits for events if wait set to true, to prevent
 * undesirable monopoly of CPU. The side-effect is that you cannot do
 * while (CheckEvents(TRUE)); without discretion.
 */
static bool CheckEvents(bool wait)
{
	EventRecord event;

	WindowPtr w;

	Rect r;

	UInt32 sleep_ticks;

	int ch, ck;

	int mc, ms, mo, mx;

	int i;

	term_data *td = NULL;


	/*
	 * With the wait mode blocking for available event / timeout,
	 * the non-wait mode should actually call WaitNextEvent,
	 * because of those event draining loops. Or we had to
	 * implement yet another mode.
	 */

	/* Handles the quit_when_ready flag */
	if (quit_when_ready) quit_calmly();

	/* Blocking call to WaitNextEvent - should use MAX_INT XXX XXX */
	if (wait) sleep_ticks = 0x7FFFFFFFL;

	/* Non-blocking */
	else sleep_ticks = 0L;

	/* Get an event (or null)  */
	WaitNextEvent(everyEvent, &event, sleep_ticks, nil);

	/* Hack -- Nothing is ready yet */
	if (event.what == nullEvent) return (FALSE);


	/* Analyze the event */
	switch (event.what)
	{

#if 0

	case activateEvt:
		{
			w = (WindowPtr)event.message;

			activate(w);

			break;
		}

#endif

	case updateEvt:
		{
			/* Extract the window */
			w = (WindowPtr)event.message;

			/* Find the window */
			for (i = 0; i < MAX_TERM_DATA; i++)
			{
				/* Skip dead windows */
				if (!data[i].t) continue;

				/* Notice matches */
				if (data[i].w == w) td = &data[i];
			}

			/* Hack XXX XXX XXX */
			BeginUpdate(w);
			EndUpdate(w);

			/* Redraw the window */
			if (td) term_data_redraw(td);

			break;
		}

	case keyDown:
	case autoKey:
		{
			/* Extract some modifiers */
			mc = (event.modifiers & controlKey) ? TRUE : FALSE;
			ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
			mo = (event.modifiers & optionKey) ? TRUE : FALSE;
			mx = (event.modifiers & cmdKey) ? TRUE : FALSE;

			/* Keypress: (only "valid" if ck < 96) */
			ch = (event.message & charCodeMask) & 255;

			/* Keycode: see table above */
			ck = ((event.message & keyCodeMask) >> 8) & 255;

			/* Command + "normal key" -> menu action */
			if (mx && (ck < 64))
			{
#ifdef MENU_SHORTCUTS
				/* Hack -- Prepare the menus */
				setup_menus();

				/* Run the Menu-Handler */
				menu(MenuKey(ch));

				/* Turn off the menus */
				HiliteMenu(0);

				/* Done */
				break;
#else
				/* Begin special trigger */
				Term_keypress(31);

				/* Send some modifier keys */
				if (mc) Term_keypress('C');
				if (ms) Term_keypress('S');
				if (mo) Term_keypress('O');
				if (mx) Term_keypress('X');

				/* Enqueue the keypress */
				Term_keypress(ch);

				/* Terminate the trigger */
				Term_keypress(13);
#endif
			}

			/* Hide the mouse pointer */
			ObscureCursor();

			/* Normal key -> simple keypress */
			if ((ck < 64) || (ck == 93))
			{
				/* Enqueue the keypress */
				Term_keypress(ch);
			}

			/* Keypad keys -> trigger plus simple keypress */
			else if (!mc && !ms && !mo && !mx && (ck < 96))
			{
				/* Hack -- "enter" is confused */
				if (ck == 76) ch = '\n';

				/* Begin special trigger */
				Term_keypress(31);

				/* Send the "keypad" modifier */
				Term_keypress('K');

				/* Send the "ascii" keypress */
				Term_keypress(ch);

				/* Terminate the trigger */
				Term_keypress(13);
			}

			/* Bizarre key -> encoded keypress */
			else if (ck <= 127)
			{
				/* Begin special trigger */
				Term_keypress(31);

				/* Send some modifier keys */
				if (mc) Term_keypress('C');
				if (ms) Term_keypress('S');
				if (mo) Term_keypress('O');
				if (mx) Term_keypress('X');

				/* Downshift and encode the keycode */
				Term_keypress(I2D((ck - 64) / 10));
				Term_keypress(I2D((ck - 64) % 10));

				/* Terminate the trigger */
				Term_keypress(13);
			}

			break;
		}

	case mouseDown:
		{
			int code;

			/* Analyze click location */
			code = FindWindow(event.where, &w);

			/* Find the window */
			for (i = 0; i < MAX_TERM_DATA; i++)
			{
				/* Skip dead windows */
				if (!data[i].t) continue;

				/* Notice matches */
				if (data[i].w == w) td = &data[i];
			}

			/* Analyze */
			switch (code)
			{
			case inMenuBar:
				{
					setup_menus();
					menu(MenuSelect(event.where));
					HiliteMenu(0);
					break;
				}

			case inDrag:
				{
					WindowPtr old_win;
					BitMap tBitMap;
					Rect pRect;

					r = GetQDGlobalsScreenBits(&tBitMap)->bounds;
					r.top += 20;  /* GetMBarHeight() XXX XXX XXX */
					InsetRect(&r, 4, 4);
					DragWindow(w, event.where, &r);

					/* Oops */
					if (!td) break;

					/* Save */
					old_win = active;

					/* Activate */
					activate(td->w);

					/* Analyze */
					GetWindowBounds(
					        (WindowRef)td->w,
					        kWindowContentRgn,
					        &pRect);
					td->r.left = pRect.left;
					td->r.top = pRect.top;

					/* Apply and Verify */
					term_data_check_size(td);

					/* Restore */
					activate(old_win);

					break;
				}

			case inGoAway:
				{
					/* Oops */
					if (!td) break;

					/* Track the go-away box */
					if (TrackGoAway(w, event.where))
					{
						/* Not Mapped */
						td->mapped = FALSE;

						/* Not Mapped */
						td->t->mapped_flag = FALSE;

						/* Hide the window */
						TransitionWindow(td->w,
						                 kWindowZoomTransitionEffect,
						                 kWindowHideTransitionAction,
						                 NULL);
					}

					break;
				}

			case inGrow:
				{
					int x, y;

					Rect nr;

					term *old = Term;

					/* Oops */
					if (!td) break;

#ifndef ALLOW_BIG_SCREEN

					/* Minimum and maximum sizes */
					r.left = 20 * td->tile_wid + td->size_ow1;
					r.right = 80 * td->tile_wid + td->size_ow1 + td->size_ow2 + 1;
					r.top = 1 * td->tile_hgt + td->size_oh1;
					r.bottom = 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;

					/* Grow the rectangle */
					if (!ResizeWindow(w, event.where, &r, NULL)) break;
#else

					/* Grow the rectangle */
					if (!ResizeWindow(w, event.where, NULL, NULL)) break;

#endif /* !ALLOW_BIG_SCREEN */


					/* Obtain geometry of resized window */
					GetWindowBounds(w, kWindowContentRgn, &nr);

					/* Extract the new size in pixels */
					y = nr.bottom - nr.top - td->size_oh1 - td->size_oh2;
					x = nr.right - nr.left - td->size_ow1 - td->size_ow2;

					/* Extract a "close" approximation */
					td->rows = y / td->tile_hgt;
					td->cols = x / td->tile_wid;

					/* Apply and Verify */
					term_data_check_size(td);

					/* Activate */
					Term_activate(td->t);

					/* Hack -- Resize the term */
					Term_resize(td->cols, td->rows);

					/* Resize and Redraw */
					term_data_resize(td);
					term_data_redraw(td);

					/* Restore */
					Term_activate(old);

					break;
				}

			case inContent:
				{
					SelectWindow(w);

					break;
				}
			}

			break;
		}

		/* OS Event -- From "Maarten Hazewinkel" */
	case osEvt:
		{
			switch ((event.message >> 24) & 0x000000FF)
			{
			case suspendResumeMessage:

				/* Resuming: activate the front window */
				if (event.message & resumeFlag)
				{
					Cursor tempCursor;
					SetPort(GetWindowPort(FrontWindow()));
					SetCursor(GetQDGlobalsArrow(&tempCursor));
				}

				/* Suspend: deactivate the front window */
				else
				{
					/* Nothing */
				}

				break;
			}

			break;
		}

		/* From "Steve Linberg" and "Maarten Hazewinkel" */
	case kHighLevelEvent:
		{
			/* Process apple events */
			(void)AEProcessAppleEvent(&event);

			/* Handle "quit_when_ready" */
			if (quit_when_ready)
			{
#if 0 /* Doesn't work with Aqua well */
				/* Forget */
				quit_when_ready = FALSE;

				/* Do the menu key */
				menu(MenuKey('q'));
#endif
				/* Turn off the menus */
				HiliteMenu(0);
			}

			/* Handle "open_when_ready" */
			else if (open_when_ready)
			{
				handle_open_when_ready();
			}

			break;
		}

	}


	/* Something happened */
	return (TRUE);
}


/*** Some Hooks for various routines ***/


/*
 * Mega-Hack -- emergency lifeboat
 */
static void *lifeboat = NULL;


/*
 * Hook to "release" memory
 */
#ifdef NEW_ZVIRT_HOOKS /* [V] removed the unused 'size' argument. */
static void *hook_rnfree(void *v)
#else
static void *hook_rnfree(void *v, size_t size)
#endif /* NEW_ZVIRT_HOOKS */
{

#ifdef USE_MALLOC

	/* Alternative method */
	free(v);

#else

	/* Dispose */
	DisposePtr(v);

#endif

	/* Success */
	return (NULL);
}

/*
 * Hook to "allocate" memory
 */
static void *hook_ralloc(size_t size)
{

#ifdef USE_MALLOC

	/* Make a new pointer */
	return (malloc(size));

#else

	/* Make a new pointer */
	return (NewPtr(size));

#endif

}

/*
 * Hook to handle "out of memory" errors
 */
static void *hook_rpanic(size_t size)
{
	/* void *mem = NULL; */

	/* Free the lifeboat */
	if (lifeboat)
	{
		/* Free the lifeboat */
		DisposePtr(lifeboat);

		/* Forget the lifeboat */
		lifeboat = NULL;

		/* Mega-Hack -- Warning */
		mac_warning("Running out of Memory!\rAbort this process now!");

		/* Mega-Hack -- Never leave this function */
		while (TRUE) CheckEvents(TRUE);
	}

	/* Mega-Hack -- Crash */
	return (NULL);
}


/*
 * Hook to tell the user something important
 */
static void hook_plog(cptr str)
{
	/* Warning message */
	mac_warning(str);
}


/*
 * Hook to tell the user something, and then quit
 */
static void hook_quit(cptr str)
{
	/* Warning if needed */
	if (str) mac_warning(str);

#ifdef USE_ASYNC_SOUND

	/* Clean up sound support */
	cleanup_sound();

#endif /* USE_ASYNC_SOUND */

	/* Dispose of graphic tiles */
	if (frameP)
	{
		/* Unlock */
		BenSWUnlockFrame(frameP);

		/* Dispose of the GWorld */
		DisposeGWorld(frameP->framePort);

		/* Dispose of the memory */
		DisposePtr((Ptr)frameP);
	}

	/* Write a preference file */
	save_pref_file();

	/* All done */
	ExitToShell();
}


/*
 * Hook to tell the user something, and then crash
 */
static void hook_core(cptr str)
{
	/* XXX Use the debugger */
	/* DebugStr(str); */

	/* Warning */
	if (str) mac_warning(str);

	/* Warn, then save player */
	mac_warning("Fatal error.\rI will now attempt to save and quit.");

	/* Attempt to save */
	if (!save_player()) mac_warning("Warning -- save failed!");

	/* Quit */
	quit(NULL);
}



/*** Main program ***/


/*
 * Init some stuff
 *
 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
 * "Macintosh Save Bug" by using "absolute" path names, since on
 * System 7 machines anyway, the "current working directory" often
 * "changes" due to background processes, invalidating any "relative"
 * path names.  Note that the Macintosh is limited to 255 character
 * path names, so be careful about deeply embedded directories...
 *
 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
 * "missing lib folder bug" by allowing the user to help find the
 * "lib" folder by hand if the "application folder" code fails...
 *
 *
 * The problem description above no longer applies, but I left it here,
 * modified for Carbon, to allow the game proceeds when a user doesn't
 * placed the Angband binary and the lib folder in the same place for
 * whatever reasons. -- pelpel
 */
static void init_stuff(void)
{
	Rect r;
	BitMap tBitMap;
	Rect screenRect;
	Point topleft;

	char path[1024];

	OSErr err = noErr;
	NavDialogOptions dialogOptions;
	FSSpec theFolderSpec;
	NavReplyRecord theReply;


	/* Fake rectangle */
	r.left = 0;
	r.top = 0;
	r.right = 344;
	r.bottom = 188;

	/* Center it */
	screenRect = GetQDGlobalsScreenBits(&tBitMap)->bounds;
	center_rect(&r, &screenRect);

	/* Extract corner */
	topleft.v = r.top;
	topleft.h = r.left;

	/* Default to the "lib" folder with the application */
#ifdef MACH_O_CARBON
	if (locate_lib(path, sizeof(path)) == NULL) quit(NULL);
#else
	refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));
#endif


	/* Check until done */
	while (1)
	{
		/* Prepare the paths */
		init_file_paths(path);

		/* Build the filename */
		path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt");

		/* Attempt to open and close that file */
		if (0 == fd_close(fd_open(path, O_RDONLY))) break;

		/* Warning */
		plog_fmt("Unable to open the '%s' file.", path);

		/* Warning */
		plog("The Angband 'lib' folder is probably missing or misplaced.");

		/* Ask the user to choose the lib folder */
		err = NavGetDefaultDialogOptions(&dialogOptions);

		/* Paranoia */
		if (err != noErr) quit(NULL);

		/* Set default location option */
		dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;

		/* Clear preview option */
		dialogOptions.dialogOptionFlags &= ~(kNavAllowPreviews);

		/* Forbit selection of multiple files */
		dialogOptions.dialogOptionFlags &= ~(kNavAllowMultipleFiles);

		/* Display location */
		dialogOptions.location = topleft;

#if 0

		/* Load the message for the missing folder from the resource fork */
		/* GetIndString(dialogOptions.message, 128, 1); */

#else

		/* Set the message for the missing folder XXX XXX */
		strcpy(dialogOptions.message + 1, "Please select the \"lib\" folder");
		dialogOptions.message[0] = strlen(dialogOptions.message + 1);

#endif

		/* Wait for the user to choose a folder */
		err = NavChooseFolder(
		              nil, &theReply, &dialogOptions, nil, nil, nil);

		/* Assume the player doesn't want to go on */
		if ((err != noErr) || !theReply.validRecord) quit(NULL);

		/* Retrieve FSSpec from the reply */
		{
			AEKeyword theKeyword;
			DescType actualType;
			Size actualSize;

			/* Get a pointer to selected folder */
			err = AEGetNthPtr(
			              &(theReply.selection), 1, typeFSS, &theKeyword,
			              &actualType, &theFolderSpec, sizeof(FSSpec), &actualSize);

			/* Paranoia */
			if (err != noErr) quit(NULL);
		}

		/* Free navitagor reply */
		err = NavDisposeReply(&theReply);

		/* Paranoia */
		if (err != noErr) quit(NULL);

		/* Extract textual file name for given file */
#ifdef MACH_O_CARBON
		if (spec_to_path(&theFolderSpec, path, sizeof(path)) != noErr)
		{
			quit(NULL);
		}
#else /* MACH_O_CARBON */
refnum_to_name(
		path,
		theFolderSpec.parID,
		theFolderSpec.vRefNum,
		(char *)theFolderSpec.name);
#endif /* MACH_O_CARBON */
	}
}


/*
 * Macintosh Main loop
 */
int main(void)
{
	int i;
	long response;
	OSStatus err;
	EventRecord tempEvent;
	UInt32 numberOfMasters = 10;

	/* Get more Masters -- it is not recommended by Apple, should go away */
	MoreMasterPointers(numberOfMasters);

	/* Check for existence of Carbon */
	err = Gestalt(gestaltCarbonVersion, &response);

	if (err != noErr) quit("This program requires Carbon API");

	/* See if we are running on Aqua */
	err = Gestalt(gestaltMenuMgrAttr, &response);

	/* Cache the result */
	if ((err == noErr) &&
	                (response & gestaltMenuMgrAquaLayoutMask)) is_aqua = TRUE;

	/*
	 * Remember Mac OS version, in case we have to cope with version-specific
	 * problems
	 */
	(void)Gestalt(gestaltSystemVersion, &mac_os_version);


	/* Set up the Macintosh */
	InitCursor();

	/* Flush events */
	FlushEvents(everyEvent, 0);

	/* Flush events some more (?) */
	if (EventAvail(everyEvent, &tempEvent)) FlushEvents(everyEvent, 0);


	/* Install the start event hook (ignore error codes) */
	AEInstallEventHandler(
	        kCoreEventClass,
	        kAEOpenApplication,
	        NewAEEventHandlerUPP(AEH_Start),
	        0L,
	        FALSE);

	/* Install the quit event hook (ignore error codes) */
	AEInstallEventHandler(
	        kCoreEventClass,
	        kAEQuitApplication,
	        NewAEEventHandlerUPP(AEH_Quit),
	        0L,
	        FALSE);

	/* Install the print event hook (ignore error codes) */
	AEInstallEventHandler(
	        kCoreEventClass,
	        kAEPrintDocuments,
	        NewAEEventHandlerUPP(AEH_Print),
	        0L,
	        FALSE);

	/* Install the open event hook (ignore error codes) */
	AEInstallEventHandler(
	        kCoreEventClass,
	        kAEOpenDocuments,
	        NewAEEventHandlerUPP(AEH_Open),
	        0L,
	        FALSE);


#ifndef MACH_O_CARBON

	/* Find the current application */
	SetupAppDir();

#endif /* !MACH_O_CARBON */

	/* Mark ourself as the file creator */
	_fcreator = ANGBAND_CREATOR;

	/* Default to saving a "text" file */
	_ftype = 'TEXT';


	/* Hook in some "z-virt.c" hooks */
	rnfree_aux = hook_rnfree;
	ralloc_aux = hook_ralloc;
	rpanic_aux = hook_rpanic;

	/* Hooks in some "z-util.c" hooks */
	plog_aux = hook_plog;
	quit_aux = hook_quit;
	core_aux = hook_core;


	/* Initialize colors */
	for (i = 0; i < 256; i++)
	{
		u16b rv, gv, bv;

		/* Extract the R,G,B data */
		rv = angband_color_table[i][1];
		gv = angband_color_table[i][2];
		bv = angband_color_table[i][3];

		/* Save the actual color */
		color_info[i].red = (rv | (rv << 8));
		color_info[i].green = (gv | (gv << 8));
		color_info[i].blue = (bv | (bv << 8));
	}


	/* Show the "watch" cursor */
	SetCursor(*(GetCursor(watchCursor)));

	/* Prepare the menubar */
	init_menubar();

	/* Prepare the windows */
	init_windows();

	/* Hack -- process all events */
	while (CheckEvents(FALSE)) /* loop */;

	/* Reset the cursor */
	{
		Cursor tempCursor;

		SetCursor(GetQDGlobalsArrow(&tempCursor));
	}

	/* Mega-Hack -- Allocate a "lifeboat" */
	lifeboat = NewPtr(16384);

#ifdef USE_QT_SOUND

	/* Load sound effect resources */
	load_sounds();

#endif /* USE_QT_SOUND */

	/* Note the "system" */
	ANGBAND_SYS = "mac";

#ifdef PRIVATE_USER_PATH
	if (check_create_user_dir() == FALSE)
		quit("Cannot create directory " PRIVATE_USER_PATH);
#endif

	/* Initialize */
	init_stuff();

	/* Initialize */
	init_angband();


	/* Hack -- process all events */
	while (CheckEvents(FALSE)) /* loop */;


	/* We are now initialized */
	initialized = TRUE;


	/* Handle "open_when_ready" */
	handle_open_when_ready();

#ifndef SAVEFILE_SCREEN

	/* Prompt the user - You may have to change this for some variants */
	prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);

	/* Flush the prompt */
	Term_fresh();

	/* Hack -- Process Events Forever */
	while (TRUE) CheckEvents(TRUE);

#else

	/* Game is in progress */
	game_in_progress = 1;

	/* Wait for keypress */
	pause_line(23);

	/* flush input - Warning: without this, _system_ would hang */
	flush();

	/* Play the game - note the value of the argument */
	play_game(FALSE);

	/* Quit */
	quit(NULL);

	/* Since it's a int function */
	return (0);
#endif /* !SAVEFILE_SCREEN */
}

#endif /* MACINTOSH || MACH_O_CARBON */

tome-235-src/src/main-dmy.c0000644000076400017500000001204211012107763013333 0ustar  dgdg/* File: main-dmy.c */

/*
 * Copyright (c) 1997 Ben Harrison, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */

#ifdef USE_DMY

/*
 * This file helps ToME run on nothing.
 */


#include "angband.h"

#include 
#include 
#include 
#include 
#include 

/* /me pffts Solaris */
#ifndef NAME_MAX
#define	NAME_MAX	_POSIX_NAME_MAX
#endif

/*
 * Information about a term
 */
typedef struct term_data term_data;

struct term_data
{
	term t;                  /* All term info */
};

/* Max number of windows on screen */
#define MAX_TERM_DATA 4

/* Information about our windows */
static term_data data[MAX_TERM_DATA];


/*
 * Hack -- Number of initialized "term" structures
 */
static int active = 0;




/*
 * Suspend/Resume
 */
static errr Term_xtra_dummy_alive(int v)
{
	int x, y;


	/* Suspend */
	if (!v)
	{}

	/* Resume */
	else
	{}

	/* Success */
	return (0);
}



/*
 * Init the "net" system
 */
static void Term_init_dummy(term *t)
{
	term_data *td = (term_data *)(t->data);

	/* Count init's, handle first */
	if (active++ != 0) return;
}


/*
 * Nuke the "net" system
 */
static void Term_nuke_dummy(term *t)
{
	int x, y;
	term_data *td = (term_data *)(t->data);
}




/*
 * Process events (with optional wait)
 */
static errr Term_xtra_dummy_event(int v)
{
	/* Success */
	Term_keypress('\r');
	return (0);
}

/*
 * React to changes
 */
static errr Term_xtra_dummy_react(void)
{
	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_dummy(int n, int v)
{
	term_data *td = (term_data *)(Term->data);
	char buf[2];

	/* Analyze the request */
	switch (n)
	{
		/* Clear screen */
	case TERM_XTRA_CLEAR:
		return (0);

		/* Make a noise */
	case TERM_XTRA_NOISE:
		return (0);

		/* Flush the Curses buffer */
	case TERM_XTRA_FRESH:
		return (0);

		/* Suspend/Resume curses */
	case TERM_XTRA_ALIVE:
		return (Term_xtra_dummy_alive(v));

		/* Process events */
	case TERM_XTRA_EVENT:
		return (Term_xtra_dummy_event(v));

		/* Flush events */
	case TERM_XTRA_FLUSH:
		while (!Term_xtra_dummy_event(FALSE));
		return (0);

		/* Delay */
	case TERM_XTRA_DELAY:
		return (0);

		/* React to events */
	case TERM_XTRA_REACT:
		Term_xtra_dummy_react();
		return (0);

		/* Subdirectory scan */
	case TERM_XTRA_SCANSUBDIR:
		{
			DIR *directory;
			struct dirent *entry;

			scansubdir_max = 0;

			directory = opendir(scansubdir_dir);
			if (!directory)
				return 1;

			while ((entry = readdir(directory)))
			{
				char file[PATH_MAX + NAME_MAX + 2];
				struct stat filedata;

				file[PATH_MAX + NAME_MAX] = 0;
				strncpy(file, scansubdir_dir, PATH_MAX);
				strncat(file, "/", 2);
				strncat(file, entry->d_name, NAME_MAX);
				if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(entry->d_name);
					++scansubdir_max;
				}
			}

			closedir(directory);
			return 0;
		}
	}

	/* Unknown */
	return (1);
}


/*
 * Actually MOVE the hardware cursor
 */
static errr Term_curs_dummy(int x, int y)
{
	term_data *td = (term_data *)(Term->data);

	/* Literally move the cursor */
	// DGDGDGD

	/* Success */
	return (0);
}


/*
 * Erase a grid of space
 * Hack -- try to be "semi-efficient".
 */
static errr Term_wipe_dummy(int x, int y, int n)
{
	/* Success */
	return (0);
}

/*
 * Place some text on the screen using an attribute
 */
static errr Term_text_dummy(int x, int y, int n, byte a, cptr s)
{
	/* Success */
	return (0);
}


/*
 * Create a window for the given "term_data" argument.
 *
 * Assumes legal arguments.
 */
static errr term_data_init_dummy(term_data *td, int rows, int cols)
{
	term *t = &td->t;

	/* Initialize the term */
	term_init(t, cols, rows, 256);

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Set some hooks */
	t->init_hook = Term_init_dummy;
	t->nuke_hook = Term_nuke_dummy;

	/* Set some more hooks */
	t->text_hook = Term_text_dummy;
	t->wipe_hook = Term_wipe_dummy;
	t->curs_hook = Term_curs_dummy;
	t->xtra_hook = Term_xtra_dummy;

	/* Save the data */
	t->data = td;

	/* Activate it */
	Term_activate(t);

	/* Success */
	return (0);
}


static void hook_quit(cptr str)
{
	/* Unused */
	(void)str;
}

/*
 * Prepare "curses" for use by the file "z-term.c"
 *
 * Installs the "hook" functions defined above, and then activates
 * the main screen "term", which clears the screen and such things.
 *
 * Someone should really check the semantics of "initscr()"
 */
errr init_dummy(int argc, char **argv)
{
	int num_term = MAX_TERM_DATA, next_win = 0;

	/* Activate hooks */
	quit_aux = hook_quit;
	core_aux = hook_quit;

	/* Create a term */
	term_data_init_dummy(&data[0], 25, 80);

	/* Remember the term */
	angband_term[0] = &data[0].t;

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

	/* Remember the active screen */
	term_screen = &data[0].t;

	/* Success */
	return (0);
}
#endif
tome-235-src/src/main-dos.c0000644000076400017500000013736111012107763013343 0ustar  dgdg/* File: main-dos.c */

/*
 * Copyright (c) 1997 Ben Harrison, Robert Ruehlmann, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband work with DOS computers.
 *
 * Adapted from "main-ibm.c".
 *
 * Author: Robert Ruehlmann (rr9@angband.org).
 * See "http://thangorodrim.angband.org/".
 *
 * Initial framework (and some code) by Ben Harrison (benh@phial.com).
 *
 * This file requires the (free) DJGPP compiler (based on "gcc").
 * See "http://www.delorie.com/djgpp/".
 *
 * This file uses the (free) "Allegro" library (SVGA graphics library).
 * See "http://www.talula.demon.co.uk/allegro/".
 *
 * To compile this file, use "Makefile.dos", which defines "USE_DOS".
 *
 * See also "main-ibm.c" and "main-win.c".
 *
 *
 * The "lib/user/pref.prf" file contains macro definitions and possible
 * alternative color set definitions.
 *
 * The "lib/user/font.prf" contains attr/char mappings for use with the
 * special fonts in the "lib/xtra/font/" directory.
 *
 * The "lib/user/graf.prf" contains attr/char mappings for use with the
 * special bitmaps in the "lib/xtra/graf/" directory.
 *
 *
 * Both "shift" keys are treated as "identical", and all the modifier keys
 * (control, shift, alt) are ignored when used with "normal" keys, unless
 * they modify the underlying "ascii" value of the key.  You must use the
 * new "user pref files" to be able to interact with the keypad and such.
 *
 * Note that "Term_xtra_dos_react()" allows runtime color, graphics, 
 * screen resolution, and sound modification.
 *
 *
 * The sound code uses *.wav files placed in the "lib/xtra/sound" folder.
 * Every sound-event can have several samples assigned to it and a random
 * one will be played when the event occures. Look at the
 * "lib/xtra/sound/sound.cfg" configuration file for more informations.
 *
 * The background music uses midi-files (and mod files) from the
 * "lib/xtra/music" folder.
 *
 *
 * Comment by Ben Harrison (benh@phial.com):
 *
 * On my Windows NT box, modes "VESA1" and "VESA2B" seem to work, but
 * result in the game running with no visible output.  Mode "VESA2L"
 * clears the screen and then fails silently.  All other modes fail
 * instantly.  To recover from such "invisible" modes, you can try
 * typing escape, plus control-x, plus escape.  XXX XXX XXX
 *
 * Comment by Eric Stevens (tome@eastevens.com):
 *
 * This file has been modified to work with Allegro 4.0.3 that comes with
 * DJGPP 2.0.3. This modification allows ToME to use the .dat font files
 * provided with the Angband release for DOS.
 *
 */

#include "angband.h"


#ifdef USE_DOS

#include 

#ifdef USE_MOD_FILES
#include 
#endif /* USE_MOD_FILES */

#include "load_gif.c"


#include 
#include 
#include 
#include 
#include 

/*
 * ZAngband remapping for race and class in the enhanced bitmap
 */
/* #define PLAYER_REMAP */


/*
 * Index of the first standard Angband color.
 *
 * All colors below this index are defined by
 * the palette of the tiles-bitmap.
 */
#define COLOR_OFFSET 240


/*
 * Maximum number of terminals
 */
#define MAX_TERM_DATA 8


/*
 * Forward declare
 */
typedef struct term_data term_data;


/*
 * Extra "term" data
 */
struct term_data
{
	term t;

	int number;

	int x;
	int y;

	int cols;
	int rows;

	int tile_wid;
	int tile_hgt;

	int font_wid;
	int font_hgt;

	FONT *font;

#ifdef USE_GRAPHICS

	BITMAP *tiles;

#endif /* USE_GRAPHICS */

#ifdef USE_BACKGROUND

	int window_type;

#endif /* USE_BACKGROUND */

};

/*
 * The current screen resolution
 */
static int resolution;

#ifdef USE_BACKGROUND

/*
 * The background images
 */
BITMAP *background[17];

#endif /* USE_BACKGROUND */


/*
 * An array of term_data's
 */
static term_data data[MAX_TERM_DATA];


#ifdef USE_GRAPHICS

/*
 * Are graphics already initialized ?
 */
static bool graphics_initialized = FALSE;

#endif /* USE_GRAPHICS */


/*
 * Small bitmap for the cursor
 */
static BITMAP *cursor;


#ifdef USE_SOUND

/*
 * Is the sound already initialized ?
 */
static bool sound_initialized = FALSE;

# ifdef USE_MOD_FILES
/*
 * Is the mod-file support already initialized ?
 */
static bool mod_file_initialized = FALSE;

# endif  /* USE_MOD_FILES */

/*
 * Volume settings
 */
static int digi_volume;
static int midi_volume;

/*
 * The currently playing song
 */
static MIDI *midi_song = NULL;

# ifdef USE_MOD_FILES

static JGMOD *mod_song = NULL;

# endif  /* USE_MOD_FILES */

static int current_song;

/*
 * The number of available songs
 */
static int song_number;

/*
 * The maximum number of available songs
 */
#define MAX_SONGS 255

static char music_files[MAX_SONGS][16];

/*
 * The maximum number of samples per sound-event
 */
#define SAMPLE_MAX 10

/*
 * An array of sound files
 */
static SAMPLE* samples[SOUND_MAX][SAMPLE_MAX];

/*
 * The number of available samples for every event
 */
static int sample_count[SOUND_MAX];

#endif /* USE_SOUND */


/*
 *  Extra paths
 */
static char xtra_font_dir[1024];
static char xtra_graf_dir[1024];
static char xtra_sound_dir[1024];
static char xtra_music_dir[1024];


/*
 * List of the available videomodes to reduce executable size
 */
 /*
DECLARE_GFX_DRIVER_LIS
(
	GFX_DRIVER_VBEAF
	GFX_DRIVER_VESA2L
	GFX_DRIVER_VESA2B
	GFX_DRIVER_ATI
	GFX_DRIVER_MACH64
	GFX_DRIVER_CIRRUS64
	GFX_DRIVER_CIRRUS54
	GFX_DRIVER_PARADISE
	GFX_DRIVER_S3
	GFX_DRIVER_TRIDENT
	GFX_DRIVER_ET3000
	GFX_DRIVER_ET4000
	GFX_DRIVER_VIDEO7
	GFX_DRIVER_VESA1
)
*/

/*
 * Declare the videomode list
 */
//DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8)


/*
 * Keypress input modifier flags (hard-coded by DOS)
 */
#define K_RSHIFT	0	/* Right shift key down */
#define K_LSHIFT	1	/* Left shift key down */
#define K_CTRL		2	/* Ctrl key down */
#define K_ALT		3	/* Alt key down */
#define K_SCROLL	4	/* Scroll lock on */
#define K_NUM		5	/* Num lock on */
#define K_CAPS		6	/* Caps lock on */
#define K_INSERT	7	/* Insert on */


/*
 * Prototypes
 */
static errr Term_xtra_dos_event(int v);
static void Term_xtra_dos_react(void);
static void Term_xtra_dos_clear(void);
static errr Term_xtra_dos(int n, int v);
static errr Term_user_dos(int n);
static errr Term_curs_dos(int x, int y);
static errr Term_wipe_dos(int x, int y, int n);
static errr Term_text_dos(int x, int y, int n, byte a, const char *cp);
static void Term_init_dos(term *t);
static void Term_nuke_dos(term *t);
static void term_data_link(term_data *td);
static void dos_dump_screen(void);
static void dos_quit_hook(cptr str);
static bool init_windows(void);
errr init_dos(void);
#ifdef USE_SOUND
static bool init_sound(void);
static errr Term_xtra_dos_sound(int v);
static void play_song(void);
#endif /* USE_SOUND */
#ifdef USE_GRAPHICS
static bool init_graphics(void);
# ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp, const byte *eap, const char *ecp);
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp);
# endif  /* USE_EGO_GRAPHICS */
# else /* USE_TRANSPARENCY */
static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp);
# endif  /* USE_TRANSPARENCY */
#endif /* USE_GRAPHICS */


/*
 * Process an event (check for a keypress)
 *
 * The keypress processing code is often the most system dependant part
 * of Angband, since sometimes even the choice of compiler is important.
 *
 * For this file, we divide all keypresses into two categories, first, the
 * "normal" keys, including all keys required to play Angband, and second,
 * the "special" keys, such as keypad keys, function keys, and various keys
 * used in combination with various modifier keys.
 *
 * To simplify this file, we use Angband's "macro processing" ability, in
 * combination with the "lib/user/pref.prf" file, to handle most of the
 * "special" keys, instead of attempting to fully analyze them here.  This
 * file only has to determine when a "special" key has been pressed, and
 * translate it into a simple string which signals the use of a "special"
 * key, the set of modifiers used, if any, and the hardware scan code of
 * the actual key which was pressed.  To simplify life for the user, we
 * treat both "shift" keys as identical modifiers.
 *
 * The final encoding is "^_MMMxSS\r", where "MMM" encodes the modifiers
 * ("C" for control, "S" for shift, "A" for alt, or any ordered combination),
 * and "SS" encodes the keypress (as the two "digit" hexadecimal encoding of
 * the scan code of the key that was pressed), and the "^_" and "x" and "\r"
 * delimit the encoding for recognition by the macro processing code.
 *
 * Some important facts about scan codes follow.  All "normal" keys use
 * scan codes from 1-58.  The "function" keys use 59-68 (and 133-134).
 * The "keypad" keys use 69-83.  Escape uses 1.  Enter uses 28.  Control
 * uses 29.  Left Shift uses 42.  Right Shift uses 54.  PrtScrn uses 55.
 * Alt uses 56.  Space uses 57.  CapsLock uses 58.  NumLock uses 69.
 * ScrollLock uses 70.  The "keypad" keys which use scan codes 71-83
 * are ordered KP7,KP8,KP9,KP-,KP4,KP5,KP6,KP+,KP1,KP2,KP3,INS,DEL.
 *
 * Using "bioskey(0x10)" instead of "bioskey(0)" apparently provides more
 * information, including better access to the keypad keys in combination
 * with various modifiers, but only works on "PC's after 6/1/86", and there
 * is no way to determine if the function is provided on a machine.  I have
 * been told that without it you cannot detect, for example, control-left.
 * The basic scan code + ascii value pairs returned by the keypad follow,
 * with values in parentheses only available to "bioskey(0x10)".
 *
 *         /      *      -      +      1      2      3      4
 * Norm:  352f   372a   4a2d   4e2b   4f00   5000   5100   4b00
 * Shft:  352f   372a   4a2d   4e2b   4f31   5032   5133   4b34
 * Ctrl: (9500) (9600) (8e00) (9000)  7500  (9100)  7600   7300
 *
 *         5      6      7      8      9      0      .     Enter
 * Norm: (4c00)  4d00   4700   4800   4900   5200   5300  (e00d)
 * Shft:  4c35   4d36   4737   4838   4939   5230   532e  (e00d)
 * Ctrl: (8f00)  7400   7700  (8d00)  8400  (9200) (9300) (e00a)
 *
 * See "lib/user/pref-win.prf" for the "standard" macros for various keys.
 *
 * Certain "bizarre" keypad keys (such as "enter") return a "scan code"
 * of "0xE0", and a "usable" ascii value.  These keys should be treated
 * like the normal keys, see below.  XXX XXX XXX Note that these "special"
 * keys could be prefixed with an optional "ctrl-^" which would allow them
 * to be used in macros without hurting their use in normal situations.
 *
 * This function also appears in "main-ibm.c".  XXX XXX XXX
 *
 * Addition for the DOS version: Dump-screen function with the
 * "Ctrl-Print" key saves a bitmap with the screen contents to
 * "lib/user/dump.bmp".
 */
static errr Term_xtra_dos_event(int v)
{
	int i, k, s;

	bool mc = FALSE;
	bool ms = FALSE;
	bool ma = FALSE;

	/* Hack -- Check for a keypress */
	if (!v && !bioskey(1)) return (1);

	/* Wait for a keypress */
	k = bioskey(0x10);

	/* Access the "modifiers" */
	i = bioskey(2);

	/* Extract the "scan code" */
	s = ((k >> 8) & 0xFF);

	/* Extract the "ascii value" */
	k = (k & 0xFF);

	/* Process "normal" keys */
	if ((s <= 58) || (s == 0xE0))
	{
		/* Enqueue it */
		if (k) Term_keypress(k);

		/* Success */
		return (0);
	}

	/* Extract the modifier flags */
	if (i & (1 << K_CTRL)) mc = TRUE;
	if (i & (1 << K_LSHIFT)) ms = TRUE;
	if (i & (1 << K_RSHIFT)) ms = TRUE;
	if (i & (1 << K_ALT)) ma = TRUE;

	/* Dump the screen with "Ctrl-Print" */
	if ((s == 0x72) && mc)
	{
		/* Dump the screen */
		dos_dump_screen();

		/* Success */
		return (0);
	}

	/* Begin a "macro trigger" */
	Term_keypress(31);

	/* Hack -- Send the modifiers */
	if (mc) Term_keypress('C');
	if (ms) Term_keypress('S');
	if (ma) Term_keypress('A');

	/* Introduce the hexidecimal scan code */
	Term_keypress('x');

	/* Encode the hexidecimal scan code */
	Term_keypress(hexsym[s / 16]);
	Term_keypress(hexsym[s % 16]);

	/* End the "macro trigger" */
	Term_keypress(13);

	/* Success */
	return (0);
}


#ifdef SUPPORT_GAMMA

/*
 * When set to TRUE, indicates that we can use gamma_table
 */
static bool gamma_table_ready = FALSE;


/*
 * Build gamma correction table if requested and applicable
 */
static void setup_gamma_table(void)
{
	static u16b old_gamma_val = 0;

	/* (Re)build the table only when gamma value changes */
	if (gamma_val == old_gamma_val) return;

	/* Temporarily inactivate the table */
	gamma_table_ready = FALSE;

	/* Validate gamma_val */
	if ((gamma_val <= 0) || (gamma_val >= 256))
	{
		/* Reset */
		old_gamma_val = gamma_val = 0;

		/* Leave it inactive */
		return;
	}

	/* (Re)build the table */
	build_gamma_table(gamma_val);

	/* Remember gamma_val */
	old_gamma_val = gamma_val;

	/* Activate the table */
	gamma_table_ready = TRUE;
}

#endif /* SUPPORT_GAMMA */


/*
 * React to global changes in the colors, graphics, and sound settings. 
 */
static void Term_xtra_dos_react(void)
{
	int i;

#ifdef USE_SPECIAL_BACKGROUND

	int j;

	term_data *td;

#endif /* USE_SPECIAL_BACKGROUND */


#ifdef SUPPORT_GAMMA

	/* Setup gamma_table */
	setup_gamma_table();

#endif /* SUPPORT_GAMMA */

	/*
	 * Set the Angband colors
	 */
	for (i = 0; i < 16; i++)
	{
		byte rv, gv, bv;
		RGB colour;

		/* Extract desired values */
		rv = angband_color_table[i][1];
		gv = angband_color_table[i][2];
		bv = angband_color_table[i][3];

#ifdef SUPPORT_GAMMA

		/* Hack - Gamma correction */
		if (gamma_table_ready)
		{
			rv = gamma_table[rv];
			gv = gamma_table[gv];
			bv = gamma_table[bv];
		}

#endif /* SUPPORT_GAMMA */

		/* 8 bit to 6 bit conversion */
		colour.r = rv >> 2;
		colour.g = gv >> 2;
		colour.b = bv >> 2;

		set_color(COLOR_OFFSET + i, &colour);
	}

#ifdef USE_GRAPHICS

	/*
	 * Handle "arg_graphics"
	 */
	if (use_graphics != arg_graphics)
	{
		/* Initialize (if needed) */
		if (arg_graphics && !init_graphics())
		{
			/* Warning */
			plog("Cannot initialize graphics!");

			/* Cannot enable */
			arg_graphics = FALSE;
		}

		/* Change setting */
		use_graphics = arg_graphics;
	}

#endif /* USE_GRAPHICS */

#ifdef USE_SOUND

	/*
	 * Handle "arg_sound"
	 */
	if (use_sound != arg_sound)
	{
		/* Clear the old song */
		if (midi_song) destroy_midi(midi_song);
		midi_song = NULL;
#ifdef USE_MOD_FILES
		if (mod_file_initialized)
		{
			stop_mod();
			if (mod_song) destroy_mod(mod_song);
			mod_song = NULL;
		}
#endif /* USE_MOD_FILES */

		/* Initialize (if needed) */
		if (arg_sound && !init_sound())
		{
			/* Warning */
			plog("Cannot initialize sound!");

			/* Cannot enable */
			arg_sound = FALSE;
		}

		/* Change setting */
		use_sound = arg_sound;
	}

#endif /* USE_SOUND */

#ifdef USE_SPECIAL_BACKGROUND

	/*
	 * Initialize the window backgrounds
	 */
	for (i = 0; i < 8; i++)
	{
		td = &data[i];

		/* Window flags */
		for (j = 0; j < 16; j++)
		{
			if (op_ptr->window_flag[i] & (1L << j))
			{
				if (background[j + 1])
				{
					td->window_type = j + 1;
				}
				else
				{
					td->window_type = 0;
				}
			}
		}
	}
#endif /* USE_SPECIAL_BACKGROUND */
}


/*
 * Clear a terminal
 *
 * Fills the terminal area with black color or with
 * the background image
 */
static void Term_xtra_dos_clear(void)
{
	term_data *td = (term_data*)(Term->data);

#ifdef USE_BACKGROUND
	int bgrnd;
#endif /* USE_BACKGROUND */

	int x1, y1;
	int w1, h1;

	/* Location */
	x1 = td->x;
	y1 = td->y;

	/* Size */
	w1 = td->tile_wid * td->cols;
	h1 = td->tile_hgt * td->rows;

#ifdef USE_BACKGROUND

	bgrnd = td->window_type;

	if (background[bgrnd])
	{
		/* Draw the background */
		stretch_blit(background[bgrnd], screen,
		             0, 0, background[bgrnd]->w, background[bgrnd]->h,
		             x1, y1, w1, h1);
	}
	else

#endif /* USE_BACKGROUND */

	{
		/* Draw the Term black */
		rectfill(screen,
		         x1, y1, x1 + w1 - 1, y1 + h1 - 1,
		         COLOR_OFFSET + TERM_DARK);
	}
}


/*
 * Handle a "special request"
 *
 * The given parameters are "valid".
 */
static errr Term_xtra_dos(int n, int v)
{
	/* Analyze the request */
	switch (n)
	{
		/* Make a "bell" noise */
	case TERM_XTRA_NOISE:
		{
			/* Make a bell noise */
			(void)write(1, "\007", 1);

			/* Success */
			return (0);
		}

		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		{
			/* Clear the screen */
			Term_xtra_dos_clear();

			/* Success */
			return (0);
		}

		/* Process events */
	case TERM_XTRA_EVENT:
		{
			irc_poll();

			/* Process one event */
			return (Term_xtra_dos_event(v));
		}

		/* Flush events */
	case TERM_XTRA_FLUSH:
		{
			/* Strip events */
			while (!Term_xtra_dos_event(FALSE));

			/* Success */
			return (0);
		}

		/* Do something useful if bored */
	case TERM_XTRA_BORED:
		{
			irc_poll();

#ifdef USE_SOUND
			/*
			 * Check for end of song and start a new one
			 */
			if (!use_sound) return (0);

#ifdef USE_MOD_FILES
			if (song_number && ((midi_pos == -1) && !is_mod_playing()))
#else /* USE_MOD_FILES */
if (song_number && (midi_pos == -1))
#endif /* USE_MOD_FILES */
			{
				if (song_number > 1)
				{
					/* Get a *new* song at random */
					while (1)
					{
						n = randint(song_number);
						if (n != current_song) break;
					}
					current_song = n;
				}
				else
				{
					/* We only have one song, so loop it */
					current_song = 1;
				}

				/* Play the song */
				play_song();
			}

#endif /* USE_SOUND */

			/* Success */
			return (0);
		}

		/* React to global changes */
	case TERM_XTRA_REACT:
		{
			/* Change the colors */
			Term_xtra_dos_react();

			/* Success */
			return (0);
		}

		/* Delay for some milliseconds */
	case TERM_XTRA_DELAY:
		{
			irc_poll();

			/* Delay if needed */
			if (v > 0) delay(v);

			/* Success */
			return (0);
		}

#ifdef USE_SOUND

		/* Make a sound */
	case TERM_XTRA_SOUND:
		{
			return (Term_xtra_dos_sound(v));
		}

#endif /* USE_SOUND */

		/*
		 * Scans for subdirectories in a directory "scansubdir_dir"
		 * and place teh result in "scansubdir_result/scansubdir_max"
		 */
	case TERM_XTRA_SCANSUBDIR:
		{
			struct ffblk f;
			int done;

			done = findfirst(format("%s\\*", scansubdir_dir), &f, FA_DIREC);

			scansubdir_max = 0;
			while ((!done) && (scansubdir_max < 255))
			{
				if ((f.ff_attrib & FA_DIREC) && (strcmp(f.ff_name, ".")) && (strcmp(f.ff_name, "..")))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(f.ff_name);
					scansubdir_max++;
				}

				done = findnext(&f);
			}

			return 0;
		}

	}

	/* Unknown request */
	return (1);
}


/*
 * Do a "user action" on the current "term"
 */
static errr Term_user_dos(int n)
{
	int k;

	char status[4];

	char section[80];

	/* Interact */
	while (1)
	{
		/* Clear screen */
		Term_clear();

		/* Print date and time of compilation */
		prt(format("Compiled: %s %s\n", __TIME__, __DATE__), 1, 45);

		/* Why are we here */
		prt("DOS options", 2, 0);

		/* Give some choices */
#ifdef USE_SOUND
		prt("(V) Sound Volume", 4, 5);
		prt("(M) Music Volume", 5, 5);
#endif /* USE_SOUND */

#ifdef USE_GRAPHICS

		if (arg_graphics)
		{
			strcpy(status, "On");
		}
		else
		{
			strcpy(status, "Off");
		}
		prt(format("(G) Graphics : %s", status), 7, 5);

#endif /* USE_GRAPHICS */

#ifdef USE_SOUND

		if (arg_sound)
		{
			strcpy(status, "On");
		}
		else
		{
			strcpy(status, "Off");
		}
		prt(format("(S) Sound/Music : %s", status), 8, 5);

#endif /* USE_SOUND */

		prt("(R) Screen resolution", 12, 5);

		prt("(W) Save current options", 14, 5);

		/* Prompt */
		prt("Command: ", 18, 0);

		/* Get command */
		k = inkey();

		/* Exit */
		if (k == ESCAPE) break;

		/* Analyze */
		switch (k)
		{
#ifdef USE_SOUND
			/* Sound Volume */
		case 'V':
		case 'v':
			{
				/* Prompt */
				prt("Command: Sound Volume", 18, 0);

				/* Get a new value */
				while (1)
				{
					prt(format("Current Volume: %d", digi_volume), 22, 0);
					prt("Change Volume (+, - or ESC to accept): ", 20, 0);
					k = inkey();
					if (k == ESCAPE) break;
					switch (k)
					{
					case '+':
						{
							digi_volume++;
							if (digi_volume > 255) digi_volume = 255;
							break;
						}
					case '-':
						{
							digi_volume--;
							if (digi_volume < 0) digi_volume = 0;
							break;
						}
						/* Unknown option */
					default:
						{
							break;
						}
					}
					set_volume(digi_volume, -1);
				}
				break;
			}

			/* Music Volume */
		case 'M':
		case 'm':
			{
				/* Prompt */
				prt("Command: Music Volume", 18, 0);

				/* Get a new value */
				while (1)
				{
					prt(format("Current Volume: %d", midi_volume), 22, 0);
					prt("Change Volume (+, - or ESC to accept): ", 20, 0);
					k = inkey();
					if (k == ESCAPE) break;
					switch (k)
					{
					case '+':
						{
							midi_volume++;
							if (midi_volume > 255) midi_volume = 255;
							break;
						}
					case '-':
						{
							midi_volume--;
							if (midi_volume < 0) midi_volume = 0;
							break;
						}
						/* Unknown option */
					default:
						{
							break;
						}
					}
					set_volume( -1, midi_volume);
				}
				break;
			}

#endif /*USE_SOUND */

#ifdef USE_GRAPHICS

			/* Switch graphics on/off */
		case 'G':
		case 'g':
			{
				/* Toggle "arg_graphics" */
				arg_graphics = !arg_graphics;

				/* React to changes */
				Term_xtra_dos_react();

				/* Reset visuals */
#ifdef ANGBAND_2_8_1
				reset_visuals();
#else /* ANGBAND_2_8_1 */
				reset_visuals(TRUE);
#endif /* ANGBAND_2_8_1 */
				break;
			}

#endif /* USE_GRAPHICS */

#ifdef USE_SOUND

			/* Sound/Music On/Off */
		case 'S':
		case 's':
			{
				/* Toggle "arg_sound" */
				arg_sound = !arg_sound;

				/* React to changes */
				Term_xtra_dos_react();

				break;
			}

#endif /* USE_SOUND */

			/* Screen Resolution */
		case 'R':
		case 'r':
			{
				int h, w, i = 1;
				char *descr;

				/* Clear screen */
				Term_clear();

				/* Prompt */
				prt("Command: Screen Resolution", 1, 0);
				prt("Restart Angband to get the new screenmode.", 3, 0);

				/* Get a list of the available presets */
				while (1)
				{
					/* Section name */
					sprintf(section, "Mode-%d", i);

					/* Get new values or end the list */
					if (!(w = get_config_int(section, "screen_wid", 0)) || (i == 16)) break;
					h = get_config_int(section, "screen_hgt", 0);

					/* Get a extra description of the resolution */
					descr = get_config_string(section, "Description", "");

					/* Print it */
					prt(format("(%d) %d x %d   %s", i, w, h, descr), 4 + i, 0);

					/* Next */
					i++;
				}

				/* Get a new resolution */
				prt(format("Screen Resolution : %d", resolution), 20, 0);
				k = inkey();
				if (k == ESCAPE) break;
				if (isdigit(k)) resolution = D2I(k);

				/* Check for min, max value */
				if ((resolution < 1) || (resolution >= i)) resolution = 1;

				/* Save the resolution */
				set_config_int("Angband", "Resolution", resolution);

				/* Return */
				break;
			}


			/* Save current option */
		case 'W':
		case 'w':
			{
				prt("Saving current options", 18, 0);

#ifdef USE_SOUND
				set_config_int("sound", "digi_volume", digi_volume);
				set_config_int("sound", "midi_volume", midi_volume);
#endif /* USE_SOUND */
				set_config_int("Angband", "Graphics", arg_graphics);
				set_config_int("Angband", "Sound", arg_sound);

				break;
			}

			/* Unknown option */
		default:
			{
				break;
			}
		}

		/* Flush messages */
		msg_print(NULL);
	}

	/* Redraw it */
	Term_key_push(KTRL('R'));

	/* Unknown */
	return (0);
}


/*
 * Move the cursor
 *
 * The given parameters are "valid".
 */
static errr Term_curs_dos(int x, int y)
{
	term_data *td = (term_data*)(Term->data);

	int x1, y1;

	/* Location */
	x1 = x * td->tile_wid + td->x;
	y1 = y * td->tile_hgt + td->y;

	/* Draw the cursor */
	draw_sprite(screen, cursor, x1, y1);

	/* Success */
	return (0);
}


/*
 * Erase a block of the screen
 *
 * The given parameters are "valid".
 */
static errr Term_wipe_dos(int x, int y, int n)
{
	term_data *td = (term_data*)(Term->data);

#ifdef USE_BACKGROUND
	int bgrnd;
#endif /* USE_BACKGROUND */

	int x1, y1;
	int w1, h1;

	/* Location */
	x1 = x * td->tile_wid + td->x;
	y1 = y * td->tile_hgt + td->y;

	/* Size */
	w1 = n * td->tile_wid;
	h1 = td->tile_hgt;

#ifdef USE_BACKGROUND

	bgrnd = td->window_type;

	if (background[bgrnd])
	{
		int source_x = x * background[bgrnd]->w / td->cols;
		int source_y = y * background[bgrnd]->h / td->rows;
		int source_w = n * background[bgrnd]->w / td->cols;
		int source_h = background[bgrnd]->h / td->rows;

		/* Draw the background */
		stretch_blit(background[bgrnd], screen,
		             source_x, source_y, source_w, source_h,
		             x1, y1, w1, h1);
	}
	else

#endif /* USE_BACKGROUND */

	{
		/* Draw a black block */
		rectfill(screen, x1, y1, x1 + w1 - 1, y1 + h1 - 1,
		         COLOR_OFFSET + TERM_DARK);
	}

	/* Success */
	return (0);
}


/*
 * Place some text on the screen using an attribute
 *
 * The given parameters are "valid".  Be careful with "a".
 *
 * The string "cp" has length "n" and is NOT null-terminated.
 */
static errr Term_text_dos(int x, int y, int n, byte a, const char *cp)
{
	term_data *td = (term_data*)(Term->data);

	int i;

	int x1, y1;

	char text[257];

	/* Location */
	x1 = x * td->tile_wid + td->x;
	y1 = y * td->tile_hgt + td->y;

	/* Erase old contents */
	Term_wipe_dos(x, y, n);

#ifdef USE_SPECIAL_BACKGROUND

	/* Show text in black in the message window */
	if (op_ptr->window_flag[td->number] & (PW_MESSAGE)) a = 0;

#endif /* USE_SPECIAL_BACKGROUND */

	/* No stretch needed */
	if (td->font_wid == td->tile_wid)
	{
		/* Copy the string */
		for (i = 0; i < n; ++i) text[i] = cp[i];

		/* Terminate */
		text[i] = '\0';

		/* Dump the text */
		textout(screen, td->font, text, x1, y1,
		        COLOR_OFFSET + (a & 0x0F));
	}

	/* Stretch needed */
	else
	{
		/* Pre-Terminate */
		text[1] = '\0';

		/* Write the chars to the screen */
		for (i = 0; i < n; ++i)
		{
			/* Build a one character string */
			text[0] = cp[i];

			/* Dump some text */
			textout(screen, td->font, text, x1, y1,
			        COLOR_OFFSET + (a & 0x0F));

			/* Advance */
			x1 += td->tile_wid;
		}
	}

	/* Success */
	return (0);
}


#ifdef USE_GRAPHICS

/*
 * Place some attr/char pairs on the screen
 *
 * The given parameters are "valid".
 *
 * To prevent crashes, we must not only remove the high bits of the
 * "ap[i]" and "cp[i]" values, but we must map the resulting value
 * onto the legal bitmap size, which is normally 32x32.  XXX XXX XXX
 */
#ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp, const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
#else /* USE_TRANSPARENCY */
static errr Term_pict_dos(int x, int y, int n, const byte *ap, const char *cp)
#endif /* USE_TRANSPARENCY */
{
	term_data *td = (term_data*)(Term->data);

	int i;

	int w, h;

	int x1, y1;
	int x2, y2;

# ifdef USE_TRANSPARENCY

	int x3, y3;

# ifdef USE_EGO_GRAPHICS

	int x4, y4;
	bool has_overlay;

# endif  /* USE_EGO_GRAPHICS */

# endif  /* USE_TRANSPARENCY */

	/* Size */
	w = td->tile_wid;
	h = td->tile_hgt;

	/* Location (window) */
	x1 = x * w + td->x;
	y1 = y * h + td->y;

	/* Dump the tiles */
	for (i = 0; i < n; i++)
	{
		/* Location (bitmap) */
		x2 = (cp[i] & 0x7F) * w;
		y2 = (ap[i] & 0x7F) * h;

# ifdef USE_TRANSPARENCY
		x3 = (tcp[i] & 0x7F) * w;
		y3 = (tap[i] & 0x7F) * h;

# ifdef EGO_GRAPHICS
		x4 = (ecp[i] & 0x7F) * w;
		y4 = (eap[i] & 0x7F) * h;
		has_overlay = (ecp[i] && eap[i]);

# endif  /* EGO_GRAPHICS */

		/* Blit the tile to the screen */
		blit(td->tiles, screen, x3, y3, x1, y1, w, h);

		/* Blit the tile to the screen */
		masked_blit(td->tiles, screen, x2, y2, x1, y1, w, h);

# ifdef EGO_GRAPHICS

		/* Blit the overlay to the screen */
		if (has_overlay)
			masked_blit(td->tiles, screen, x4, y4, x1, y1, w, h);

# endif  /* EGO_GRAPHICS */

# else /* USE_TRANSPARENCY */

		/* Blit the tile to the screen */
		blit(td->tiles, screen, x2, y2, x1, y1, w, h);

# endif  /* USE_TRANSPARENCY */

		/* Advance (window) */
		x1 += w;
	}

	/* Success */
	return (0);
}

#endif /* USE_GRAPHICS */


/*
 * Init a Term
 */
static void Term_init_dos(term *t)
{
	/* XXX Nothing */
}


/*
 * Nuke a Term
 */
static void Term_nuke_dos(term *t)
{
	term_data *td = (term_data*)(t->data);

	/* Free the terminal font */
	if (td->font) destroy_font(td->font);

#ifdef USE_GRAPHICS

	/* Free the terminal bitmap */
	if (td->tiles) destroy_bitmap(td->tiles);

#endif /* USE_GRAPHICS */
}



/*
 * Instantiate a "term_data" structure
 */
static void term_data_link(term_data *td)
{
	term *t = &td->t;

	/* Initialize the term */
	term_init(t, td->cols, td->rows, 255);

	/* Use a "software" cursor */
	t->soft_cursor = TRUE;

	/* Ignore the "TERM_XTRA_BORED" action */
	t->never_bored = FALSE;

	/* Ignore the "TERM_XTRA_FROSH" action */
	t->never_frosh = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Prepare the init/nuke hooks */
	t->init_hook = Term_init_dos;
	t->nuke_hook = Term_nuke_dos;

	/* Prepare the template hooks */
	t->xtra_hook = Term_xtra_dos;
	t->curs_hook = Term_curs_dos;
	t->wipe_hook = Term_wipe_dos;
	t->user_hook = Term_user_dos;
	t->text_hook = Term_text_dos;

#ifdef USE_GRAPHICS

	/* Prepare the graphics hook */
	t->pict_hook = Term_pict_dos;

	/* Use "Term_pict" for "graphic" data */
	t->higher_pict = TRUE;

#endif /* USE_GRAPHICS */

	/* Remember where we came from */
	t->data = (vptr)(td);
}


/*
 * Shut down visual system, then fall back into standard "quit()"
 */
static void dos_quit_hook(cptr str)
{
	int i;

	/* Destroy sub-windows */
	for (i = MAX_TERM_DATA - 1; i >= 1; i--)
	{
		/* Unused */
		if (!angband_term[i]) continue;

		/* Nuke it */
		term_nuke(angband_term[i]);
	}


	/* Free all resources */
	if (cursor) destroy_bitmap(cursor);

#ifdef USE_BACKGROUND

	/* Free the background bitmaps */
	for (i = 0; i < 17; i++)
	{
		if (background[i]) destroy_bitmap(background[i]);
	}

#endif /* USE_BACKGROUND */


#ifdef USE_SOUND

	if (sound_initialized)
	{
		/* Destroy samples */
		for (i = 1; i < SOUND_MAX; i++)
		{
			int j;

			for (j = 0; j < sample_count[i]; j++)
			{
				if (samples[i][j]) destroy_sample(samples[i][j]);
			}
		}
	}

	/* Clear the old song */
	if (midi_song) destroy_midi(midi_song);
	midi_song = NULL;
# ifdef USE_MOD_FILES
	if (mod_file_initialized)
	{
		stop_mod();
		if (mod_song) destroy_mod(mod_song);
		mod_song = NULL;
	}
# endif  /* USE_MOD_FILES */

#endif /* USE_SOUND */

	/* Shut down Allegro */
	allegro_exit();
}


/*
 * Dump the screen to "lib/user/dump.bmp"
 */
static void dos_dump_screen(void)
{
	/* Bitmap and palette of the screen */
	BITMAP *bmp;
	PALETTE pal;

	/* Filename */
	char filename[1024];

	/* Get bitmap and palette of the screen */
	bmp = create_sub_bitmap(screen, 0, 0, SCREEN_W, SCREEN_H);
	get_palette(pal);

	/* Build the filename for the screen-dump */
	path_build(filename, 1024, ANGBAND_DIR_USER, "dump.bmp");

	/* Save it */
	save_bmp(filename, bmp, pal);

	/* Free up the memory */
	if (bmp) destroy_bitmap(bmp);

	/* Success message */
	msg_print("Screen dump saved.");
	msg_print(NULL);
}


/*
 * GRX font file reader by Mark Wodrich.
 *
 * GRX FNT files consist of the header data (see struct below). If the font
 * is proportional, followed by a table of widths per character (unsigned 
 * shorts). Then, the data for each character follows. 1 bit/pixel is used,
 * with each line of the character stored in contiguous bytes. High bit of
 * first byte is leftmost pixel of line.
 *
 * Note that GRX FNT files can have a variable number of characters, so you
 * must verify that any "necessary" characters exist before using them.
 *
 * The GRX FNT files were developed by ???.
 */


/*
 * Magic value
 */
#define FONTMAGIC	0x19590214L


/*
 * Forward declare
 */
typedef struct FNTfile_header FNTfile_header;


/*
 * .FNT file header
 */
struct FNTfile_header
{
	unsigned long magic;
	unsigned long bmpsize;
	unsigned short width;
	unsigned short height;
	unsigned short minchar;
	unsigned short maxchar;
	unsigned short isfixed;
	unsigned short reserved;
	unsigned short baseline;
	unsigned short undwidth;
	char fname[16];
	char family[16];
};


/*
 * A "bitmap" is simply an array of bytes
 */
typedef byte *GRX_BITMAP;


/*
 * Temporary space to store font bitmap
 */
#define GRX_TMP_SIZE    4096


/*
 * ???
 */
void convert_grx_bitmap(int width, int height, GRX_BITMAP src, GRX_BITMAP dest)
{
	unsigned short x, y, bytes_per_line;
	unsigned char bitpos, bitset;

	bytes_per_line = (width + 7) >> 3;

	for (y = 0; y < height; y++)
	{
		for (x = 0; x < width; x++)
		{
			bitpos = 7 - (x & 7);
			bitset = !!(src[(bytes_per_line * y) + (x >> 3)] & (1 << bitpos));
			dest[y*width + x] = bitset;
		}
	}
}


/*
 * ???
 */
GRX_BITMAP *load_grx_bmps(PACKFILE *f, FNTfile_header *hdr,
                          int numchar, unsigned short *wtable)
{
	int t, width, bmp_size;
	GRX_BITMAP temp;
	GRX_BITMAP *bmp;

	/* alloc array of bitmap pointers */
	bmp = malloc(sizeof(GRX_BITMAP) * numchar);

	/* assume it's fixed width for now */
	width = hdr->width;

	/* temporary working area to store FNT bitmap */
	temp = malloc(GRX_TMP_SIZE);

	for (t = 0; t < numchar; t++)
	{
		/* if prop. get character width */
		if (!hdr->isfixed) width = wtable[t];

		/* work out how many bytes to read */
		bmp_size = ((width + 7) >> 3) * hdr->height;

		/* oops, out of space! */
		if (bmp_size > GRX_TMP_SIZE)
		{
			free(temp);
			for (t--; t >= 0; t--) free(bmp[t]);
			free(bmp);
			return NULL;
		}

		/* alloc space for converted bitmap */
		bmp[t] = malloc(width * hdr->height);

		/* read data */
		pack_fread(temp, bmp_size, f);

		/* convert to 1 byte/pixel */
		convert_grx_bitmap(width, hdr->height, temp, bmp[t]);
	}

	free(temp);
	return bmp;
}


/*
 * ???
 */

FONT* import_grx_font(char *fname)
	{
		return NULL;
	}

//FONT *import_grx_font(char *fname)
//{
//	PACKFILE *f;
//
//	/* GRX font header */
//	FNTfile_header hdr;
//
//	/* number of characters in the font */
//	int numchar;
//
//	/* table of widths for each character */
//	unsigned short *wtable = NULL;
//
//	/* array of font bitmaps */
//	GRX_BITMAP *bmp;
//
//	/* the Allegro font */
//	FONT *font = NULL;
//
//	FONT_PROP *font_prop;
//	int c, c2, start, width;
//
//
//	f = pack_fopen(fname, F_READ);
//
//	if (!f) return NULL;
//
//	/* read the header structure */
//	pack_fread(&hdr, sizeof(hdr), f);
//
//	/* check magic number */
//	if (hdr.magic != FONTMAGIC)
//	{
//		pack_fclose(f);
//		return NULL;
//	}
//
//	numchar = hdr.maxchar - hdr.minchar + 1;
//
//	/* proportional font */
//	if (!hdr.isfixed)
//	{
//		wtable = malloc(sizeof(unsigned short) * numchar);
//		pack_fread(wtable, sizeof(unsigned short) * numchar, f);
//	}
//
//	bmp = load_grx_bmps(f, &hdr, numchar, wtable);
//
//	if (!bmp) goto get_out;
//
//	if (pack_ferror(f)) goto get_out;
//
//	font = malloc(sizeof(FONT));
//	font->height = -1;
//	font->dat.dat_prop = font_prop = malloc(sizeof(FONT_PROP));
//
//	start = 32 - hdr.minchar;
//	width = hdr.width;
//
//	for (c = 0; c < FONT_SIZE; c++)
//	{
//		c2 = c + start;
//
//		if ((c2 >= 0) && (c2 < numchar))
//		{
//			if (!hdr.isfixed) width = wtable[c2];
//
//			font_prop->dat[c] = create_bitmap_ex(8, width, hdr.height);
//			memcpy(font_prop->dat[c]->dat, bmp[c2], width*hdr.height);
//		}
//		else
//		{
//			font_prop->dat[c] = create_bitmap_ex(8, 8, hdr.height);
//			clear(font_prop->dat[c]);
//		}
//	}
//
//get_out:
//
//	pack_fclose(f);
//
//	if (wtable) free(wtable);
//
//	if (bmp)
//	{
//		for (c = 0; c < numchar; c++) free(bmp[c]);
//
//		free(bmp);
//	}
//
//	return font;
//}


/*
 * Initialize the terminal windows
 */
static bool init_windows(void)
{
	int i, num_windows;

	term_data *td;

	char section[80];

	char filename[1024];

	char buf[128];

	/* Section name */
	sprintf(section, "Mode-%d", resolution);

	/* Get number of windows */
	num_windows = get_config_int(section, "num_windows", 1);

	/* Paranoia */
	if (num_windows > 8) num_windows = 8;

	/* Init the terms */
	for (i = 0; i < num_windows; i++)
	{
		td = &data[i];
		WIPE(td, term_data);

		/* Section name */
		sprintf(section, "Term-%d-%d", resolution, i);

		/* Term number */
		td->number = i;

		/* Coordinates of left top corner */
		td->x = get_config_int(section, "x", 0);
		td->y = get_config_int(section, "y", 0);

		/* Rows and cols of term */
		td->rows = get_config_int(section, "rows", 24);
		td->cols = get_config_int(section, "cols", 80);

		/* Tile size */
		td->tile_wid = get_config_int(section, "tile_wid", 8);
		td->tile_hgt = get_config_int(section, "tile_hgt", 13);

		/* Font size */
		td->font_wid = get_config_int(section, "tile_wid", 8);
		td->font_hgt = get_config_int(section, "tile_hgt", 13);

		/* Get font filename */
		strcpy(buf, get_config_string(section, "font_file", "xm8x13.fnt"));

		/* Build the name of the font file */
		path_build(filename, 1024, xtra_font_dir, buf);

		/* Load a "*.fnt" file */
		if (suffix(filename, ".fnt"))
		{
			/* Load the font file */
			if (!(td->font = import_grx_font(filename)))
			{
				quit_fmt("Error reading font file '%s'", filename);
			}
		}

		/* Load a "*.dat" file */
		else if (suffix(filename, ".dat"))
		{
			DATAFILE *fontdata;

			/* Load the font file */
			if (!(fontdata = load_datafile(filename)))
			{
				quit_fmt("Error reading font file '%s'", filename);
			}

			/* Save the font data */
			td->font = fontdata[1].dat;

			/* Unload the font file */
			unload_datafile_object(fontdata);
		}

		/* Oops */
		else
		{
			quit_fmt("Unknown suffix in font file '%s'", filename);
		}

		/* Link the term */
		term_data_link(td);
		angband_term[i] = &td->t;
	}

	/* Success */
	return 0;
}


#ifdef USE_BACKGROUND

/*
 * Initialize the window backgrounds
 */
static void init_background(void)
{
	int i;

	char filename[1024];

	char buf[128];

	PALLETE background_pallete;

	/* Get the backgrounds */
	for (i = 0; i < 16; i++)
	{
		/* Get background filename */
		strcpy(buf, get_config_string("Background", format("Background-%d", i), ""));

		/* Build the filename for the background-bitmap */
		path_build(filename, 1024, xtra_graf_dir, buf);

		/* Try to open the bitmap file */
		background[i] = load_bitmap(filename, background_pallete);
	}

#ifndef USE_SPECIAL_BACKGROUND
	/*
	 * Set the palette for the background
	 */
	if (background[0])
	{
		set_palette_range(background_pallete, 0, COLOR_OFFSET - 1, 0);
	}
#endif /* USE_SPECIAL_BACKGROUND */
}

#endif /* USE_BACKGROUND */


#ifdef USE_GRAPHICS

/*
 * Initialize graphics
 */
static bool init_graphics(void)
{
	char filename[1024];
	char section[80];
	char name_tiles[128];

	/* Large bitmap for the tiles */
	BITMAP *tiles = NULL;
	PALLETE tiles_pallete;

	/* Size of each bitmap tile */
	int bitmap_wid;
	int bitmap_hgt;

	int num_windows;

	if (!graphics_initialized)
	{
		/* Section name */
		sprintf(section, "Mode-%d", resolution);

		/* Get bitmap tile size */
		bitmap_wid = get_config_int(section, "bitmap_wid", 8);
		bitmap_hgt = get_config_int(section, "bitmap_hgt", 8);

		/* Get bitmap filename */
		strcpy(name_tiles, get_config_string(section, "bitmap_file", "8x8.bmp"));

		/* Get number of windows */
		num_windows = get_config_int(section, "num_windows", 1);

		/* Build the name of the bitmap file */
		path_build(filename, 1024, xtra_graf_dir, name_tiles);

		/* Open the bitmap file */
		if ((tiles = load_bitmap(filename, tiles_pallete)) != NULL)
		{
			int i;

			/*
			 * Set the graphics mode to "new" if Adam Bolt's
			 * new 16x16 tiles are used.
			 */
			ANGBAND_GRAF = get_config_string(section, "graf-mode", "old");

			/* Select the bitmap pallete */
			set_palette_range(tiles_pallete, 0, COLOR_OFFSET - 1, 0);

			/* Prepare the graphics */
			for (i = 0; i < num_windows; i++)
			{
				term_data *td;

				int col, row;
				int cols, rows;
				int width, height;
				int src_x, src_y;
				int tgt_x, tgt_y;

				td = &data[i];

				cols = tiles->w / bitmap_wid;
				rows = tiles->h / bitmap_hgt;

				width = td->tile_wid * cols;
				height = td->tile_hgt * rows;

				/* Initialize the tile graphics */
				td->tiles = create_bitmap(width, height);

				for (row = 0; row < rows; ++row)
				{
					src_y = row * bitmap_hgt;
					tgt_y = row * td->tile_hgt;

					for (col = 0; col < cols; ++col)
					{
						src_x = col * bitmap_wid;
						tgt_x = col * td->tile_wid;

						stretch_blit(tiles, td->tiles,
						             src_x, src_y,
						             bitmap_wid, bitmap_hgt,
						             tgt_x, tgt_y,
						             td->tile_wid, td->tile_hgt);
					}
				}
			}

			/* Free the old tiles bitmap */
			if (tiles) destroy_bitmap(tiles);

			graphics_initialized = TRUE;

			/* Success */
			return (TRUE);
		}

		/* Failure */
		return (FALSE);
	}

	/* Success */
	return (TRUE);
}

#endif /* USE_GRAPHICS */

#ifdef USE_SOUND

/*
 * Initialize sound
 * We try to get a list of the available sound-files from "lib/xtra/sound/sound.cfg"
 * and then preload the samples. Every Angband-sound-event can have several samples
 * assigned. Angband will randomly select which is played. This makes it easy to
 * create "sound-packs", just copy wav-files into the "lib/xtra/sound/" folder and
 * add the filenames to "sound.cfg" in the same folder.
 */
static bool init_sound(void)
{
	int i, j, done;

	char section[128];
	char filename[1024];
	char **argv;

	struct ffblk f;

	if (sound_initialized) return (TRUE);

	/* Initialize Allegro sound */
	if (!install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL))
	{
#ifdef USE_MOD_FILES
		/*
		 * Try to enable support for MOD-, and S3M-files
		 * The parameter for install_mod() is the number
		 * of channels reserved for the MOD/S3M-file.
		 */
		if (install_mod(16) > 0) mod_file_initialized = TRUE;
#endif /* USE_MOD_FILES */

		/* Access the new sample */
		path_build(filename, 1024, xtra_sound_dir, "sound.cfg");

		/* Read config info from "lib/xtra/sound/sound.cfg" */
		override_config_file(filename);

		/* Sound section */
		strcpy(section, "Sound");

		/* Prepare the sounds */
		for (i = 1; i < SOUND_MAX + 1; i++)
		{
			/* Get the sample names */
			argv = get_config_argv(section, angband_sound_name[i], &sample_count[i]);

			/* Limit the number of samples */
			if (sample_count[i] > SAMPLE_MAX) sample_count[i] = SAMPLE_MAX;

			for (j = 0; j < sample_count[i]; j++)
			{
				/* Access the new sample */
				path_build(filename, 1024, xtra_sound_dir, argv[j]);

				/* Load the sample */
				samples[i][j] = load_sample(filename);
			}
		}

		/*
		 * Get a list of music files
		 */
#ifdef USE_MOD_FILES
		if (mod_file_initialized)
		{
			done = findfirst(format("%s/*.*", xtra_music_dir), &f, FA_ARCH | FA_RDONLY);
		}
		else
#endif /* USE_MOD_FILES */
			done = findfirst(format("%s/*.mid", xtra_music_dir), &f, FA_ARCH | FA_RDONLY);


		while (!done && (song_number <= MAX_SONGS))
		{
			/* Add music files */
			{
				strcpy(music_files[song_number], f.ff_name);
				song_number++;
			}

			done = findnext(&f);
		}

		/* Use "angdos.cfg" */
		override_config_file("angdos.cfg");

		/* Sound section */
		strcpy(section, "Sound");

		/* Get the volume setting */
		digi_volume = get_config_int(section, "digi_volume", 255);
		midi_volume = get_config_int(section, "midi_volume", 255);

		/* Set the volume */
		set_volume(digi_volume, midi_volume);

		/* Success */
		return (TRUE);
	}

	/* Init failed */
	return (FALSE);
}


/*
 * Make a sound
 */
static errr Term_xtra_dos_sound(int v)
{
	int n;

	/* Sound disabled */
	if (!use_sound) return (1);

	/* Illegal sound */
	if ((v < 0) || (v >= SOUND_MAX)) return (1);

	/* Get a random sample from the available ones */
	n = rand_int(sample_count[v]);

	/* Play the sound, catch errors */
	if (samples[v][n])
	{
		return (play_sample(samples[v][n], 255, 128, 1000, 0) == 0);
	}

	/* Oops */
	return (1);
}


/*
 * Play a song-file
 */
static void play_song(void)
{
	char filename[256];

	/* Clear the old song */
	if (midi_song) destroy_midi(midi_song);
	midi_song = NULL;
#ifdef USE_MOD_FILES
	if (mod_file_initialized)
	{
		stop_mod();
		if (mod_song) destroy_mod(mod_song);
		mod_song = NULL;
	}
#endif /* USE_MOD_FILES */

	/* Access the new song */
	path_build(filename, 1024, xtra_music_dir, music_files[current_song - 1]);

	/* Load and play the new song */
	if ((midi_song = load_midi(filename))) play_midi(midi_song, 0);
#ifdef USE_MOD_FILES
	else if (mod_file_initialized)
	{
		if ((mod_song = load_mod(filename))) play_mod(mod_song, FALSE);
	}
#endif /* USE_MOD_FILES */
}

#endif /* USE_SOUND */


/*
 * Attempt to initialize this file
 *
 * Hack -- we assume that "blank space" should be "white space"
 * (and not "black space" which might make more sense).
 *
 * Note the use of "((x << 2) | (x >> 4))" to "expand" a 6 bit value
 * into an 8 bit value, without losing much precision, by using the 2
 * most significant bits as the least significant bits in the new value.
 *
 * We should attempt to "share" bitmaps (and fonts) between windows
 * with the same "tile" size.  XXX XXX XXX
 */
errr init_dos(void)
{
	term_data *td;

	char section[80];

	int screen_wid;
	int screen_hgt;

	/* Initialize the Allegro library (never fails) */
	(void)allegro_init();

	/* Install timer support for music and sound */
	install_timer();

	/* Enable the gif-loading function */
	register_bitmap_file_type("GIF", load_gif , NULL);

	/* Read config info from filename */
	set_config_file("angdos.cfg");

	/* Main section */
	strcpy(section, "Angband");

	/* Get screen size */
	resolution = get_config_int(section, "Resolution", 1);

	/* Section name */
	sprintf(section, "Mode-%d", resolution);

	/* Get the screen dimensions */
	screen_wid = get_config_int(section, "screen_wid", 640);
	screen_hgt = get_config_int(section, "screen_hgt", 480);

	/* Set the color depth */
	set_color_depth(8);

	/* Auto-detect, and instantiate, the appropriate graphics mode */
	if ((set_gfx_mode(GFX_AUTODETECT, screen_wid, screen_hgt, 0, 0)) < 0)
	{
		/*
		 * Requested graphics mode is not available
		 * We retry with the basic 640x480 mode
		 */
		resolution = 1;

		if ((set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0)) < 0)
		{
			char error_text[1024];

			/* Save the Allegro error description */
			strcpy(error_text, allegro_error);

			/* Shut down Allegro */
			allegro_exit();

			/* Print the error description */
			plog_fmt("Error selecting screen mode: %s", error_text);

			/* Failure */
			return ( -1);
		}
	}

	/* Hook in "z-util.c" hook */
	quit_aux = dos_quit_hook;

	/* Build the "graf" path */
	path_build(xtra_graf_dir, 1024, ANGBAND_DIR_XTRA, "graf");

	/* Build the "font" path */
	path_build(xtra_font_dir, 1024, ANGBAND_DIR_XTRA, "font");

	/* Build the "sound" path */
	path_build(xtra_sound_dir, 1024, ANGBAND_DIR_XTRA, "sound");

	/* Build the "music" path */
	path_build(xtra_music_dir, 1024, ANGBAND_DIR_XTRA, "music");

	/* Initialize the windows */
	init_windows();

#ifdef USE_SOUND

	/* Look for the sound preferences in "angdos.cfg" */
	if (!arg_sound)
	{
		arg_sound = get_config_int("Angband", "Sound", TRUE);
	}

#endif /* USE_SOUND */

#ifdef USE_GRAPHICS

	/* Look for the graphic preferences in "angdos.cfg" */
	if (!arg_graphics)
	{
		arg_graphics = get_config_int("Angband", "Graphics", TRUE);
	}

#endif /* USE_GRAPHICS */

	/* Initialize the "complex" RNG for the midi-shuffle function */
	Rand_quick = FALSE;
	Rand_state_init(time(NULL));

	/* Set the Angband colors/graphics/sound mode */
	Term_xtra_dos_react();

#ifdef USE_BACKGROUND

	/* Initialize the background graphics */
	init_background();

#endif /* USE_BACKGROUND */

	/* Clear the screen */
	clear_to_color(screen, COLOR_OFFSET + TERM_DARK);

	/* Main screen */
	td = &data[0];

	/* Build a cursor bitmap */
	cursor = create_bitmap(td->tile_wid, td->tile_hgt);

	/* Erase the cursor sprite */
	clear(cursor);

	/* Draw the cursor sprite (yellow rectangle) */
	rect(cursor, 0, 0, td->tile_wid - 1, td->tile_hgt - 1,
	     COLOR_OFFSET + TERM_YELLOW);

	/* Activate the main term */
	Term_activate(angband_term[0]);

	/* Place the cursor */
	Term_curs_dos(0, 0);

#ifdef USE_BACKGROUND

	/* Use transparent text */
	text_mode( -1);

#endif /* USE_BACKGROUND */

	/* Success */
	return 0;
}

#endif /* USE_DOS */
tome-235-src/src/main-emx.c0000644000076400017500000007112111012107763013336 0ustar  dgdg/* File: main-emx.c */

/*
 * Copyright (c) 1997 Ben Harrison, Ekkehard Kraemer, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */

/* Purpose: Support for OS/2 EMX Angband */

/* Author: ekraemer@pluto.camelot.de (Ekkehard Kraemer) */

/* Current maintainer: silasd@psyber.com (Silas Dunsmore) */
/* Unless somebody else wants it.... */

#ifdef USE_EMX

/*
 * === Instructions for using Angband 2.7.X with OS/2 ===
 *
 * The patches (file "main-emx.c") to compile Angband 2.7.X under OS/2
 * were written by ekraemer@pluto.camelot.de (Ekkehard Kraemer).
 *
 * TO COMPILE:
 *
 * - untar the archive into /angband (or /games/angband or whatever)
 * - change directory to /angband/src
 * - run "dmake -B -r -f makefile.emx" (not gmake or make)
 *
 * TO INSTALL:
 *
 * - change directory to /angband/src
 * - run "dmake -B -r -f makefile.emx install" (not gmake or make)
 * - copy your old savefile into ./lib/save and your old pref.prf into ./lib/user
 * - start /angband/angband.exe for one single window
 * - start /angband/startwnd.cmd for multiple windows
 *
 * TO REMOVE TEMPORARY FILES:
 *
 * - run 'dmake -B -r -f makefile.emx clean'
 *
 *
 * I use EMX 0.9b, but every EMX compiler since 0.8g or so should work
 * fine. EMX is available at ftp-os2.cdrom.com ("Hobbes"), as is dmake.
 *
 *  dmake:    ftp://ftp-os2.cdrom.com/all/program/dmake38X.zip
 *  EMX:      ftp://ftp-os2.cdrom.com/2_x/unix/emx???/   (most probably)
 *
 * Old savefiles must be renamed to follow the new "savefile" naming
 * conventions.  Either rename the savefile to "PLAYER", or start the
 * program with the "-uName" flag.  See "main.c" for details.  The
 * savefiles are stores in "./lib/save" if you forgot the old names...
 *
 *  Changes
 *  =======
 *
 *  When       By     Version   What
 *  -------------------------------------------------------------------
 *
 *  18.11.95   EK      2.7.8    Added window/pipe code
 *                              Introduced __EMX__CLIENT__ hack
 *
 *  15.12.95   EK      2.7.9    Updated for 2.7.9
 *                     beta     Added third view
 *                              Added number of line support in aclient
 *
 *  25.12.95   EK      2.7.9    Added 'install' target
 *                    non-beta  Updated installation hints
 *                              Uploaded binary to export.andrew.cmu.edu
 *
 *  25.01.96   EK      2.7.9    Updated for 2.7.9v3
 *                      v3      Removed (improved) keyboard hack
 *                              Introduced pref-emx.prf
 *                              Phew... Makefile.emx grows! (patches, export)
 *                              Uploaded binary to export.andrew.cmu.edu
 *
 *  26.01.96   EK               Added files.uue target
 *
 *  22.02.96   EK               Added PM support
 *
 *   2.03.96   EK      2.7.9    Uploaded binaries to export.andrew.cmu.edu
 *                      v4
 *
 *   9.03.96   EK      2.7.9    Adjustable background color (PM)
 *                      v5      Added map window
 
 *  3 Dec 97   SWD      282     Brought key-handling, macros in sync with DOS.
 *                              Hacked on sub-window code -- it compiles, but
 *                              doesn't link.
 *
 * 23 Jan 98   SWD      282     Hacked more on sub-windows.  Now links, with
 *                              warnings.  Seems to work.
 *
 * 01 Nov 98   AGA      2.8.3	Adjusted for 2.8.3 sources, typos corrected
 *
 * 01 Nov 98   AGA	Z214b	Corrections for ZAngband 2.1.4 beta
 *
 */

#include 
#include 
#include 
#include 
#include 
#define INCL_KBD 1
#include 
#include 

#include "angband.h"


/*
 * Maximum windows
 */
#define MAX_TERM_DATA 8


/*
 * Keypress input modifier flags (copied from main-ibm.c)
 *
 * SWD: these could be changed to the definitions in , which are
 *      direct bitmasks instead of shift-counts.
 */
#define K_RSHIFT	0	/* Right shift key down */
#define K_LSHIFT	1	/* Left shift key down */
#define K_CTRL		2	/* Ctrl key down */
#define K_ALT		3	/* Alt key down */
#define K_SCROLL	4	/* Scroll lock on */
#define K_NUM		5	/* Num lock on */
#define K_CAPS		6	/* Caps lock on */
#define K_INSERT	7	/* Insert on */


/*
 * Prototypes!
 */
static errr Term_curs_emx(int x, int y);
static errr Term_wipe_emx(int x, int y, int n);
static errr Term_text_emx(int x, int y, int n, unsigned char a, cptr s);
static void Term_init_emx(term *t);
static void Term_nuke_emx(term *t);

#ifndef EMXPM

/*
 * termPipe* is sometimes cast to term* and vice versa,
 * so "term t;" must be the first line
 */

typedef struct
{
	term t;
	FILE *out;                   /* used by the ..._pipe_emx stuff */
}
termPipe;

/*
 * Communication between server and client
 */

enum
{
	PIP_INIT,
	PIP_NUKE,
	PIP_XTRA,
	PIP_CURS,
	PIP_WIPE,
	PIP_TEXT,
};


/*
 * Current cursor "size"
 */
static int curs_start = 0;
static int curs_end = 0;

/*
 * Angband color conversion table
 *
 * Note that "Light Green"/"Yellow"/"Red" are used for
 * "good"/"fair"/"awful" stats and conditions.
 *
 * But "brown"/"light brown"/"orange" are really only used
 * for "objects" (such as doors and spellbooks), and these
 * values can in fact be re-defined.
 *
 * Future versions of Angband will probably allow the
 * "use" of more that 16 colors, so "extra" entries can be
 * made at the end of this table in preparation.
 */
static int colors[16] =
{
	F_BLACK,                     /* Black */
	F_WHITE | INTENSITY,           /* White */
	F_WHITE,                     /* XXX Gray */
	F_RED | INTENSITY,             /* Orange */
	F_RED,                       /* Red */
	F_GREEN,                     /* Green */
	F_BLUE,                      /* Blue */
	F_BROWN,                     /* Brown */
	F_BLACK | INTENSITY,           /* Dark-grey */
	F_WHITE,                     /* XXX Light gray */
	F_MAGENTA,                   /* Purple */
	F_YELLOW | INTENSITY,          /* Yellow */
	F_RED | INTENSITY,             /* Light Red */
	F_GREEN | INTENSITY,           /* Light Green */
	F_BLUE | INTENSITY,            /* Light Blue */
	F_BROWN | INTENSITY           /* Light brown */
};

/*
 * Display a cursor, on top of a given attr/char
 */
static errr Term_curs_emx(int x, int y)
{
	v_gotoxy(x, y);
	v_ctype(curs_start, curs_end);

	return (0);
}

/*
 * Erase a grid of space (as if spaces were printed)
 */
static errr Term_wipe_emx(int x, int y, int n)
{
	v_gotoxy(x, y);
	v_putn(' ', n);

	return (0);
}

/*
 * Draw some text, wiping behind it first
 */
static errr Term_text_emx(int x, int y, int n, unsigned char a, cptr s)
{
	/* Convert the color and put the text */
	v_attrib(colors[a & 0x0F]);
	v_gotoxy(x, y);
	v_putm(s, n);

	return (0);
}

/*
 * EMX initialization
 */
static void Term_init_emx(term *t)
{
	struct _KBDINFO kbdinfo; 	/* see structure description ?somewhere? */

	v_init();
	v_getctype(&curs_start, &curs_end);
	/* hide cursor (?) XXX XXX XXX */
	v_clear();

	/* the documentation I (SWD) have implies, in passing, that setting */
	/* "binary mode" on the keyboard device will prevent the O/S from */
	/* acting on keys such as ^S (pause) and ^P (printer echo). */

	/* note also that "KbdSetStatus is ignored for a Vio-windowed application." */
	/* so there may well be problems with running this in a window.  Damnit. */

	/* this is kind of a nasty structure, as you can't just flip a bit */
	/* to change binary/ASCII mode, or echo on/off mode... nor can you */
	/* clear the whole thing -- certain bits need to be preserved. */

	KbdGetStatus(&kbdinfo, (HKBD)0);
	kbdinfo.fsMask &= ~ (KEYBOARD_ECHO_ON | 	/* clear lowest four bits */
	                     KEYBOARD_ECHO_OFF | KEYBOARD_BINARY_MODE | KEYBOARD_ASCII_MODE);
	kbdinfo.fsMask |= (KEYBOARD_BINARY_MODE); 	/* set bit two */
	KbdSetStatus(&kbdinfo, (HKBD)0);

#if 1 /* turn off for debug */
	signal(SIGHUP, SIG_IGN);
	signal(SIGINT, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);
	/*  signal(SIGILL,SIG_IGN);  */
	/*  signal(SIGTRAP,SIG_IGN); */
	/*  signal(SIGABRT,SIG_IGN); */
	/*  signal(SIGEMT,SIG_IGN);  */
	/*  signal(SIGFPE,SIG_IGN);  */
	/*  signal(SIGBUS,SIG_IGN);  */
	/*  signal(SIGSEGV,SIG_IGN); */
	/*  signal(SIGSYS,SIG_IGN);  */
	signal(SIGPIPE, SIG_IGN);
	signal(SIGALRM, SIG_IGN);
	/*  signal(SIGTERM,SIG_IGN); */
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGCHLD, SIG_IGN);
	signal(SIGBREAK, SIG_IGN);
#endif

}

/*
 * EMX shutdown
 */
static void Term_nuke_emx(term *t)
{
	/* Move the cursor to bottom of screen */
	v_gotoxy(0, 23);

	/* Restore the cursor (not necessary) */
	v_ctype(curs_start, curs_end);

	/* Set attribute to gray on black */
	v_attrib(F_WHITE);

	/* Clear the screen */
	v_clear();
}


#ifndef __EMX__CLIENT__

/*
 * Oh no, more prototypes!
 */
static errr CheckEvents(int returnImmediately);
static errr Term_xtra_pipe_emx(int n, int v);
static errr Term_curs_pipe_emx(int x, int y);
static errr Term_wipe_pipe_emx(int x, int y, int n);
static errr Term_text_pipe_emx(int x, int y, int n, unsigned char a, cptr s);
static void Term_init_pipe_emx(term *t);
static void Term_nuke_pipe_emx(term *t);
static FILE *initPipe(const char *name);
static void initPipeTerm(termPipe *pipe, const char *name, term **term);

/*
 * Main initialization function
 */
errr init_emx(void);

/*
 * The screens
 */
static termPipe term_screen_aga[MAX_TERM_DATA];


/*
 * Check for events -- called by "Term_scan_emx()"
 *
 * Note -- this is probably NOT the most efficient way
 * to "wait" for a keypress (TERM_XTRA_EVENT).
 *
 *
 * This code was ripped from "main-ibm.c" -- consult it to
 * figure out what's going on.
 *
 * See "main-ibm.c" for more information about "macro encoding".
 *
 *
 * The following documentation was cut&pasted from
 * the OS/2 Programming Reference, PRCP.INF
 * 
-------------------------------------------------------------------------------
 
 
 This call returns a character data record from the keyboard.
 
  KbdCharIn    (CharData, IOWait, KbdHandle)
 
  CharData (PKBDKEYINFO) - output
     Address of the character data structure:
 
     asciicharcode (UCHAR)
	ASCII character code. The scan code received from the keyboard is
	translated to the ASCII character code.
 
     scancode (UCHAR)
	Code received from the keyboard.  The scan code received from the
	keyboard is translated to the ASCII character code.
 
     status (UCHAR)
	State of the keystroke event:
 
	Bit       Description
 
	7-6       00 = Undefined
 
		  01 = Final character, interim character flag off
 
		  10 = Interim character
 
		  11 = Final character, interim character flag on.
 
	5         1 = Immediate conversion requested.
 
	4-2       Reserved.
 
	1         0 = Scan code is a character.
 
		  1 = Scan code is not a character; is an extended key code
		  from the keyboard.
 
	0         1 = Shift status returned without character.
 
     reserved (UCHAR)
	NLS shift status.  Reserved, set to zero.
 
     shiftkeystat (USHORT)
	Shift key status.
 
	Bit       Description
	15        SysReq key down
	14        CapsLock key down
	13        NumLock key down
	12        ScrollLock key down
	11        Right Alt key down
	10        Right Ctrl key down
	9         Left Alt key down
	8         Left Ctrl key down
	7         Insert on
	6         CapsLock on
	5         NumLock on
	4         ScrollLock on
	3         Either Alt key down
	2         Either Ctrl key down
	1         Left Shift key down
	0         Right Shift key down
 
     time (ULONG)
	Time stamp indicating when a key was pressed.  It is specified in
	milliseconds from the time the system was started.
 
  IOWait (USHORT) - input
     Wait if a character is not available.
 
     Value     Definition
     0         Requestor waits for a character if one is not available.
     1         Requestor gets an immediate return if no character is
	       available.
 
  KbdHandle (HKBD) - input
     Default keyboard or the logical keyboard.
 
  rc (USHORT) - return
     Return code descriptions are:
 
     0         NO_ERROR
     375       ERROR_KBD_INVALID_IOWAIT
     439       ERROR_KBD_INVALID_HANDLE
     445       ERROR_KBD_FOCUS_REQUIRED
     447       ERROR_KBD_KEYBOARD_BUSY
     464       ERROR_KBD_DETACHED
     504       ERROR_KBD_EXTENDED_SG
 
  Remarks
 
  On an enhanced keyboard, the secondary enter key returns the normal
  character 0DH and a scan code of E0H.
 
  Double-byte character codes (DBCS) require two function calls to obtain
  the entire code.
 
  If shift report is set with KbdSetStatus, the CharData record returned
  reflects changed shift information only.
 
  Extended ASCII codes are identified with the status byte, bit 1 on and the
  ASCII character code being either 00H or E0H. Both conditions must be
  satisfied for the character to be an extended keystroke.  For extended
  ASCII codes, the scan code byte returned is the second code (extended
  code). Usually the extended ASCII code is the scan code of the primary
  key that was pressed.
 
  A thread in the foreground session that repeatedly polls the keyboard
  with KbdCharIn (with no wait), can prevent all regular priority class
  threads from executing.  If polling must be used and a minimal amount of
  other processing is being performed, the thread should periodically yield to
  the CPU by issuing a DosSleep call for an interval of at least 5
  milliseconds.
 
 
  Family API Considerations
 
  Some options operate differently in the DOS mode than in the OS /2 mode.
  Therefore, the following restrictions apply to KbdCharIn when coding in
  the DOS mode:
 
  o The CharData structure includes everything except the time stamp.
  o Interim character is not supported
  o Status can be 0 or 40H
  o KbdHandle is ignored.
 
 
-------------------------------------------------------------------------------
 
 
   typedef struct _KBDKEYINFO {   / * kbci * /
     UCHAR    chChar;             / * ASCII character code * /
     UCHAR    chScan;             / * Scan Code * /
     UCHAR    fbStatus;           / * State of the character * /
     UCHAR    bNlsShift;          / * Reserved (set to zero) * /
     USHORT   fsState;            / * State of the shift keys * /
     ULONG    time;               / * Time stamp of keystroke (ms since ipl) * /
   }KBDKEYINFO;
 
   #define INCL_KBD
 
   USHORT  rc = KbdCharIn(CharData, IOWait, KbdHandle);
 
   PKBDKEYINFO      CharData;      / * Buffer for data * /
   USHORT           IOWait;        / * Indicate if wait * /
   HKBD             KbdHandle;     / * Keyboard handle * /
 
   USHORT           rc;            / * return code * /
 
 
-------------------------------------------------------------------------------
 *
 */
static errr CheckEvents(int returnImmediately)
{
	int i, k, s;

	bool mc = FALSE;
	bool ms = FALSE;
	bool ma = FALSE;

	/* start OS/2 specific section */

	struct _KBDKEYINFO keyinfo; 	/* see structure description above */

	/* Check (and possibly wait) for a keypress */
	/* see function description above */
	KbdCharIn( &keyinfo, returnImmediately, (HKBD)0 );

#if 0
	printf("AC:%x SC:%x ST:%x R1:%x SH:%x TI:%ld\n", 	/* OS/2 debug */
	       keyinfo.chChar,
	       keyinfo.chScan,
	       keyinfo.fbStatus,
	       keyinfo.bNlsShift,
	       keyinfo.fsState,
	       keyinfo.time );
#endif

	/* If there wasn't a key, leave now. */
	if ((keyinfo.fbStatus & 0xC0) == 0) return (1);


	/* by a set of lucky coincidences, the data maps directly over. */
	k = keyinfo.chChar;
	s = keyinfo.chScan;
	i = (keyinfo.fsState & 0xFF);

	/* end OS/2 specific section */


	/* Process "normal" keys */
	if ( k != 0 && ((s <= 58) || (s == 0xE0)) )	/* Tweak: allow for ALT-keys */
	{
		/* Enqueue it */
		Term_keypress(k);

		/* Success */
		return (0);
	}

	/* Extract the modifier flags */
	if (i & (1 << K_CTRL)) mc = TRUE;
	if (i & (1 << K_LSHIFT)) ms = TRUE;
	if (i & (1 << K_RSHIFT)) ms = TRUE;
	if (i & (1 << K_ALT)) ma = TRUE;


	/* Begin a "macro trigger" */
	Term_keypress(31);

	/* Hack -- Send the modifiers */
	if (mc) Term_keypress('C');
	if (ms) Term_keypress('S');
	if (ma) Term_keypress('A');

	/* Introduce the hexidecimal scan code */
	Term_keypress('x');

	/* Encode the hexidecimal scan code */
	Term_keypress(hexsym[s / 16]);
	Term_keypress(hexsym[s % 16]);

	/* End the "macro trigger" */
	Term_keypress(13);

	/* Success */
	return (0);
}



/*
 * Do a special thing (beep, flush, etc)
 */
static errr Term_xtra_emx(int n, int v)
{
	switch (n)
	{
	case TERM_XTRA_SHAPE:
		if (v)
		{
			v_ctype(curs_start, curs_end);
		}
		else
		{
			v_hidecursor();
		}
		return (0);

	case TERM_XTRA_NOISE:
		DosBeep(440, 50);
		return (0);

	case TERM_XTRA_FLUSH:
		while (!CheckEvents(TRUE));
		return 0;

	case TERM_XTRA_EVENT:

		/* Process an event */
		return (CheckEvents(!v));

		/* Success */
		return (0);

	case TERM_XTRA_CLEAR:
		v_clear();
		return (0);
	}

	return (1);
}

static errr Term_xtra_pipe_emx(int n, int v)
{
	termPipe *tp = (termPipe*)Term;

	switch (n)
	{
	case TERM_XTRA_NOISE:
		DosBeep(440, 50);
		return (0);

	case TERM_XTRA_SHAPE:
		return (0);

	case TERM_XTRA_EVENT:
		return (CheckEvents(FALSE));

	case TERM_XTRA_CLEAR:

		if (!tp->out) return -1;

		fputc(PIP_XTRA, tp->out);
		fwrite(&n, sizeof(n), 1, tp->out);
		fwrite(&v, sizeof(v), 1, tp->out);
		fflush(tp->out);

		return (0);
	}

	return (1);
}

static errr Term_curs_pipe_emx(int x, int y)
{
	termPipe *tp = (termPipe*)Term;

	if (!tp->out) return -1;

	fputc(PIP_CURS, tp->out);
	fwrite(&x, sizeof(x), 1, tp->out);
	fwrite(&y, sizeof(y), 1, tp->out);
	fflush(tp->out);

	return (0);
}


static errr Term_wipe_pipe_emx(int x, int y, int n)
{
	termPipe *tp = (termPipe*)Term;

	if (!tp->out) return -1;

	fputc(PIP_WIPE, tp->out);
	fwrite(&x, sizeof(x), 1, tp->out);
	fwrite(&y, sizeof(y), 1, tp->out);
	fwrite(&n, sizeof(n), 1, tp->out);
	fflush(tp->out);

	return (0);
}


static errr Term_text_pipe_emx(int x, int y, int n, unsigned char a, cptr s)
{
	termPipe *tp = (termPipe*)Term;

	if (!tp->out) return -1;

	fputc(PIP_TEXT, tp->out);
	fwrite(&x, sizeof(x), 1, tp->out);
	fwrite(&y, sizeof(y), 1, tp->out);
	fwrite(&n, sizeof(n), 1, tp->out);
	fwrite(&a, sizeof(a), 1, tp->out);
	fwrite(s, n, 1, tp->out);
	fflush(tp->out);

	return (0);
}


static void Term_init_pipe_emx(term *t)
{
	termPipe *tp = (termPipe*)t;

	if (tp->out)
	{
		fputc(PIP_INIT, tp->out);
		fflush(tp->out);
	}
}


static void Term_nuke_pipe_emx(term *t)
{
	termPipe *tp = (termPipe*)t;

	if (tp->out)
	{
		fputc(PIP_NUKE, tp->out);  /* Terminate client */
		fflush(tp->out);
		fclose(tp->out);          /* Close Pipe */
		tp->out = NULL;             /* Paranoia */
	}
}

static void initPipeTerm(termPipe *pipe, const char *name, term **termTarget)
{
	term *t;

	t = &pipe->t;

	if ((pipe->out = initPipe(name)) != NULL)
	{
		/* Initialize the term */
		term_init(t, 80, 24, 1);

		/* Special hooks */
		t->init_hook = Term_init_pipe_emx;
		t->nuke_hook = Term_nuke_pipe_emx;

		/* Add the hooks */
		t->text_hook = Term_text_pipe_emx;
		t->wipe_hook = Term_wipe_pipe_emx;
		t->curs_hook = Term_curs_pipe_emx;
		t->xtra_hook = Term_xtra_pipe_emx;

		/* Save it */
		*termTarget = t;

		/* Activate it */
		Term_activate(t);
	}
}

/*
 * Prepare "term.c" to use "USE_EMX" built-in video library
 */
errr init_emx(void)
{
	int i;

	term *t;

	/* Initialize the pipe windows */
	for (i = MAX_TERM_DATA - 1; i > 0; --i)
	{
		const char *name = angband_term_name[i];
		initPipeTerm(&term_screen_aga[i], name, &angband_term[i]);
	}

	/* Initialize main window */
	t = &term_screen_aga[0].t;

	/* Initialize the term -- big key buffer */
	term_init(t, 80, 24, 1024);

	/* Special hooks */
	t->init_hook = Term_init_emx;
	t->nuke_hook = Term_nuke_emx;

	/* Add the hooks */
	t->text_hook = Term_text_emx;
	t->wipe_hook = Term_wipe_emx;
	t->curs_hook = Term_curs_emx;
	t->xtra_hook = Term_xtra_emx;

	/* Save it */
	angband_term[0] = t;

	/* Activate it */
	Term_activate(t);

	/* Success */
	return (0);
}

static FILE *initPipe(const char *name)
{
	char buf[256];
	FILE *fi;

	sprintf(buf, "\\pipe\\angband\\%s", name);    /* Name of pipe */
	fi = fopen(buf, "wb");                         /* Look for server */
	return fi;
}

#else /* __EMX__CLIENT__ */

int main(int argc, char **argv)
{
	int c, end = 0, lines = 25;
	int x, y, h, n, v;

	FILE *in = NULL;
	char a;
	char buf[160];
	HPIPE pipe;
	APIRET rc;
	char *target;

	/* Check command line */
	if (argc != 2 && argc != 3)
	{
		printf("Usage: %s Mirror|Recall|Choice|Term-4|...|Term-7 [number of lines]\n"
		       "Start this before angband.exe\n", argv[0]);
		exit(1);
	}

	if (argc == 3) lines = atoi(argv[2]);
	if (lines <= 0) lines = 25;

	printf("Looking for Angband... press ^C to abort\n");

	target = strdup(argv[1]);
	for (c = 0; c < strlen(target); c++) target[c] = tolower(target[c]);

	sprintf(buf, "\\pipe\\angband\\%s", target);

	do
	{
		rc = DosCreateNPipe((PSZ)buf,           /* Create pipe */
		                    &pipe,
		                    NP_ACCESS_INBOUND,
		                    NP_WAIT | NP_TYPE_BYTE | NP_READMODE_BYTE | 1,
		                    1,                  /* No output buffer */
		                    1,                  /* No input buffer */
		                    -1);

		if (rc)                              /* Pipe not created */
		{
			printf("DosCreateNPipe: rc=%ld, pipe=%ld\n", (long)rc, (long)pipe);
			break;
		}

		do
		{
			rc = DosConnectNPipe(pipe);         /* Wait for angband to connect */
			if (!rc) break;
			_sleep2(500);                     /* Sleep for 0.5s  */
		}
		while (_read_kbd(0, 0, 0) == -1);       /* Until key pressed */

		if (rc) break;

		h = _imphandle(pipe);                   /* Register handle with io */
		setmode(h, O_BINARY);                  /* Make it binary */
		in = fdopen(h, "rb");                    /* Register handle with stdio */

	}
	while (0);            /* We don't need no stinking exception handling  */

	if (!in)
	{
		printf("Sorry, the pipe connection to Angband could not be established.\n");
		exit(1);
	}

	printf("Connected.\n");

	sprintf(buf, "mode co80,%d", lines);
	system(buf);

	/* Infinite loop */
	while (!end)
	{
		/* Get command */
		c = fgetc(in);

		switch (c)
		{
		case PIP_XTRA:
			if (!fread(&n, sizeof(x), 1, in) ||
			                !fread(&v, sizeof(y), 1, in))
				abort();

			/* This hack prevents another hack */
			switch (n)
			{
			case TERM_XTRA_CLEAR:
				v_clear();
				break;

			default:
				printf("Sorry, angband.exe and aclient.exe don't fit together.\n");
				exit(1);
			}

			break;

		case PIP_CURS:
			if (!fread(&x, sizeof(x), 1, in) ||
			                !fread(&y, sizeof(y), 1, in))
				abort();
			Term_curs_emx(x, y);
			break;

		case PIP_WIPE:
			if (!fread(&x, sizeof(x), 1, in) ||
			                !fread(&y, sizeof(y), 1, in) ||
			                !fread(&n, sizeof(n), 1, in))
				abort();
			Term_wipe_emx(x, y, n);
			break;

		case PIP_TEXT:
			if (!fread(&x, sizeof(x), 1, in) ||
			                !fread(&y, sizeof(y), 1, in) ||
			                !fread(&n, sizeof(n), 1, in) ||
			                !fread(&a, sizeof(a), 1, in) || (n > 160) ||
			                !fread(buf, n, 1, in))
				abort();
			Term_text_emx(x, y, n, a, buf);
			break;

		case PIP_INIT:
			Term_init_emx(NULL);
			break;

		case PIP_NUKE:
		case EOF:
		default:
			Term_nuke_emx(NULL);
			end = 1;
			break;
		}
	}

	return 0;
}

#endif /* __EMX__CLIENT__ */

#else /* EMXPM */

void emx_endPM(const char *reason);
int emx_options(char **ANGBAND_DIR_USER,
                char **ANGBAND_DIR_SAVE,
                char **ANGBAND_DIR_INFO,
                char *arg_force_roguelike,
                char *arg_force_original,
                char *arg_fiddle,
                char *arg_wizard,
                char player_name[32]);

void emx_init_window(void **instance, void *main_instance, int n);

errr emx_curs(void *instance, int x, int y);
errr emx_wipe(void *instance, int x, int y, int n);
errr emx_text(void *instance, int x, int y, int n, unsigned char a, cptr s);
void emx_init(void *instance);
void emx_nuke(void *instance);
int emx_read_kbd(void *instance, int wait);
void emx_clear(void *instance);
void emx_hidecursor(void *instance);
void emx_showcursor(void *instance);

/*
* termWindow* is sometimes cast to term* and vice versa,
* so "term t;" must be the first line
*/

typedef struct
{
	term t;
	void *instance;                           /* Pointer to window */
}
termWindow;

/*
* Display a cursor, on top of a given attr/char
*/
static errr Term_curs_emx(int x, int y)
{
	return emx_curs(((termWindow*)Term)->instance, x, y);
}

/*
* Erase a grid of space (as if spaces were printed)
*/
static errr Term_wipe_emx(int x, int y, int n)
{
	return emx_wipe(((termWindow*)Term)->instance, x, y, n);
}

/*
* Draw some text, wiping behind it first
*/
static errr Term_text_emx(int x, int y, int n, unsigned char a, cptr s)
{
	return emx_text(((termWindow*)Term)->instance, x, y, n, a, s);
}

/*
* EMX initialization
*/
static void Term_init_emx(term *t)
{
	return emx_init(((termWindow*)t)->instance);
}

/*
* EMX shutdown
*/
static void Term_nuke_emx(term *t)
{}

/*
* Oh no, more prototypes!
*/
static errr CheckEvents(int returnImmediately);

/*
* Main initialization function
*/
errr init_emx(void);

/*
* The screens
*/
static termWindow term_screen_aga[MAX_TERM_DATA];

/*
* Check for events -- called by "Term_scan_emx()"
*/
static errr CheckEvents(int returnImmediately)
{
	/* Get key - Macro triggers are generated by emx_read_kbd() */
	int k = emx_read_kbd(((termWindow*)Term)->instance, returnImmediately ? 0 : 1);

	/* Nothing ready */
	if (k < 0) return (1);

	/* Enqueue the key */
	Term_keypress(k);

	/* Success */
	return (0);
}

/*
* Do a special thing (beep, flush, etc)
*/
static errr Term_xtra_emx(int n, int v)
{
	void *instance = ((termWindow*)Term)->instance;

	switch (n)
	{
	case TERM_XTRA_SHAPE:
		if (v)
		{
			emx_showcursor(instance);
		}
		else
		{
			emx_hidecursor(instance);
		}
		return (0);

	case TERM_XTRA_NOISE:
		DosBeep(440, 50);
		return (0);

	case TERM_XTRA_FLUSH:
		while (!CheckEvents(TRUE));
		return 0;

	case TERM_XTRA_EVENT:
		return (CheckEvents(!v));

	case TERM_XTRA_CLEAR:
		emx_clear(instance);
		return (0);

	case TERM_XTRA_DELAY:
		if (v > 0) _sleep2(v);
		return (0);
	}

	return (1);
}

void emx_init_term(termWindow *t, void *main_instance, term **angTerm, int n)
{
	term *te = (term*)t;

	/* Initialize window */
	emx_init_window(&t->instance, main_instance, n);

	*angTerm = te;

	/* Initialize the term -- big key buffer */
	term_init(te, 80, 24, 1024);

	/* Special hooks */
	te->init_hook = Term_init_emx;
	te->nuke_hook = Term_nuke_emx;

	/* Add the hooks */
	te->text_hook = Term_text_emx;
	te->wipe_hook = Term_wipe_emx;
	te->curs_hook = Term_curs_emx;
	te->xtra_hook = Term_xtra_emx;
}

/*
* Prepare "term.c" to use "USE_EMX" built-in faked video library
*/
errr init_emx(void)
{
	int i;

	/* Initialize the windows */
	emx_init_term(&term_screen_aga[0], NULL, &angband_term[0], 0);

	for (i = 1; i < MAX_TERM_DATA; ++i)
	{
		emx_init_term(&term_screen_aga[i], term_screen_aga[0].instance, &angband_term[i], i);
	}

	/* Activate main window */
	Term_activate(angband_term[0]);

	/* Success */
	return (0);
}

static void init_stuff(void)
{
	char path[1024];
	cptr tail;

	/* Get the environment variable */
	tail = getenv("ANGBAND_PATH");

	/* Use the angband_path, or a default */
	strcpy(path, tail ? tail : DEFAULT_PATH);

	/* Hack -- Add a path separator (only if needed) */
	if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);

	/* Initialize */
	init_file_paths(path);
}

static void quit_hook(cptr s)
{
	int i;

	for (i = MAX_TERM_DATA - 1; i >= 0; --i)
	{
		/* Shut down the term windows */
		if (angband_term[i])
		{
			term_nuke(angband_term[i]);
			emx_nuke(((termWindow*)angband_term[i])->instance);
		}
	}

	/* Shut down window system - doesn't return */
	emx_endPM(s);
}


void angbandThread(void *arg)
{
	bool new_game = FALSE;

	int show_score = 0;

	char player_name_aga[32];

	/* Save the "program name" */
	argv0 = (char*)arg;

	/* Use the "main-emx.c" support */
	init_emx();
	ANGBAND_SYS = "ibm";

	/* Get the file paths */
	init_stuff();

	if (!emx_options((char**)&ANGBAND_DIR_USER,
	                 (char**)&ANGBAND_DIR_SAVE,
	                 (char**)&ANGBAND_DIR_INFO,
	                 &arg_force_roguelike,
	                 &arg_force_original,
	                 &arg_fiddle,
	                 &arg_wizard,
	                 player_name_aga)) quit(NULL);

	/* XXX XXX XXX (?) */
	strcpy(player_name, player_name_aga);

	/* Process the player name */
	process_player_name(TRUE);

	/* Tell "quit()" to call "Term_nuke()" */
	quit_aux = quit_hook;

	/* If requested, display scores and quit */
	if (show_score > 0) display_scores(0, show_score);

	/* Catch nasty signals */
	signals_init();

	/* Initialize */
	init_angband();

	/* Wait for response */
	pause_line(23);

	/* Play the game */
	play_game(new_game);

	/* Quit */
	quit(NULL);
}

#endif /* EMXPM */

#endif /* USE_EMX */

/*
 * Local Variables:
 * comment-column: 45
 * End:
 *
 */

tome-235-src/src/main-gcu.c0000644000076400017500000005576111012107763013337 0ustar  dgdg/* File: main-gcu.c */

/*
 * Copyright (c) 1997 Ben Harrison, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband run on Unix/Curses machines.
 *
 *
 * To use this file, you must define "USE_GCU" in the Makefile.
 *
 *
 * Note that this file is not "intended" to support non-Unix machines,
 * nor is it intended to support VMS or other bizarre setups.
 *
 * Also, this package assumes that the underlying "curses" handles both
 * the "nonl()" and "cbreak()" commands correctly, see the "OPTION" below.
 *
 * This code should work with most versions of "curses" or "ncurses",
 * and the "main-ncu.c" file (and USE_NCU define) are no longer used.
 *
 * See also "USE_CAP" and "main-cap.c" for code that bypasses "curses"
 * and uses the "termcap" information directly, or even bypasses the
 * "termcap" information and sends direct vt100 escape sequences.
 *
 * This file provides up to 4 term windows.
 *
 * This file will attempt to redefine the screen colors to conform to
 * standard Angband colors.  It will only do so if the terminal type
 * indicates that it can do so.  See the page:
 *
 *     http://www.umr.edu/~keldon/ang-patch/ncurses_color.html
 *
 * for information on this.
 *
 * Consider the use of "savetty()" and "resetty()".  XXX XXX XXX
 */


#include "angband.h"


#ifdef USE_GCU

#include 

/*
 * Hack -- play games with "bool" and "term"
 */
#undef bool

/* Avoid 'struct term' name conflict with  (via ) on AIX */
#define term System_term

/*
 * Include the proper "header" file
 */
#ifdef USE_NCURSES
# include 
#else
# include 
#endif

#undef term

/*
 * Try redefining the colors at startup.
 */
#define REDEFINE_COLORS


/*
 * Hack -- try to guess which systems use what commands
 * Hack -- allow one of the "USE_Txxxxx" flags to be pre-set.
 * Mega-Hack -- try to guess when "POSIX" is available.
 * If the user defines two of these, we will probably crash.
 */
#if !defined(USE_TPOSIX)
# if !defined(USE_TERMIO) && !defined(USE_TCHARS)
# if defined(_POSIX_VERSION)
# define USE_TPOSIX
# else
# if defined(USG) || defined(linux) || defined(SOLARIS)
# define USE_TERMIO
# else
# define USE_TCHARS
# endif
# endif
# endif
#endif

/*
 * Hack -- Amiga uses "fake curses" and cannot do any of this stuff
 */
#if defined(AMIGA)
# undef USE_TPOSIX
# undef USE_TERMIO
# undef USE_TCHARS
#endif




/*
 * POSIX stuff
 */
#ifdef USE_TPOSIX
# include 
# include 
#endif

/*
 * One version needs these files
 */
#ifdef USE_TERMIO
# include 
# include 
#endif

/*
 * The other needs these files
 */
#ifdef USE_TCHARS
# include 
# include 
# include 
# include 
#endif

#include 
#include 
#include 
#include 

/* /me pffts Solaris */
#ifndef NAME_MAX
#define	NAME_MAX	_POSIX_NAME_MAX
#endif



/*
 * XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
 *
 * They should both work due to the "(i != 1)" test below.
 */
#ifndef O_NDELAY
# define O_NDELAY O_NONBLOCK
#endif


/*
 * OPTION: some machines lack "cbreak()"
 * On these machines, we use an older definition
 */
/* #define cbreak() crmode() */


/*
 * OPTION: some machines cannot handle "nonl()" and "nl()"
 * On these machines, we can simply ignore those commands.
 */
/* #define nonl() */
/* #define nl() */


/*
 * Save the "normal" and "angband" terminal settings
 */

#ifdef USE_TPOSIX

static struct termios norm_termios;

static struct termios game_termios;

#endif

#ifdef USE_TERMIO

static struct termio norm_termio;

static struct termio game_termio;

#endif

#ifdef USE_TCHARS

static struct ltchars norm_special_chars;
static struct sgttyb norm_ttyb;
static struct tchars norm_tchars;
static int norm_local_chars;

static struct ltchars game_special_chars;
static struct sgttyb game_ttyb;
static struct tchars game_tchars;
static int game_local_chars;

#endif

/*
 * Information about a term
 */
typedef struct term_data term_data;

struct term_data
{
	term t;                  /* All term info */

	WINDOW *win;             /* Pointer to the curses window */
};

/* Max number of windows on screen */
#define MAX_TERM_DATA 4

/* Information about our windows */
static term_data data[MAX_TERM_DATA];


/*
 * Hack -- Number of initialized "term" structures
 */
static int active = 0;


#ifdef A_COLOR

/*
 * Hack -- define "A_BRIGHT" to be "A_BOLD", because on many
 * machines, "A_BRIGHT" produces ugly "inverse" video.
 */
#ifndef A_BRIGHT
# define A_BRIGHT A_BOLD
#endif

/*
 * Software flag -- we are allowed to use color
 */
static int can_use_color = FALSE;

/*
 * Software flag -- we are allowed to change the colors
 */
static int can_fix_color = FALSE;

/*
 * Simple Angband to Curses color conversion table
 */
static int colortable[16];

#endif



/*
 * Place the "keymap" into its "normal" state
 */
static void keymap_norm(void)
{

#ifdef USE_TPOSIX

	/* restore the saved values of the special chars */
	(void)tcsetattr(0, TCSAFLUSH, &norm_termios);

#endif

#ifdef USE_TERMIO

	/* restore the saved values of the special chars */
	(void)ioctl(0, TCSETA, (char *)&norm_termio);

#endif

#ifdef USE_TCHARS

	/* restore the saved values of the special chars */
	(void)ioctl(0, TIOCSLTC, (char *)&norm_special_chars);
	(void)ioctl(0, TIOCSETP, (char *)&norm_ttyb);
	(void)ioctl(0, TIOCSETC, (char *)&norm_tchars);
	(void)ioctl(0, TIOCLSET, (char *)&norm_local_chars);

#endif

}


/*
 * Place the "keymap" into the "game" state
 */
static void keymap_game(void)
{

#ifdef USE_TPOSIX

	/* restore the saved values of the special chars */
	(void)tcsetattr(0, TCSAFLUSH, &game_termios);

#endif

#ifdef USE_TERMIO

	/* restore the saved values of the special chars */
	(void)ioctl(0, TCSETA, (char *)&game_termio);

#endif

#ifdef USE_TCHARS

	/* restore the saved values of the special chars */
	(void)ioctl(0, TIOCSLTC, (char *)&game_special_chars);
	(void)ioctl(0, TIOCSETP, (char *)&game_ttyb);
	(void)ioctl(0, TIOCSETC, (char *)&game_tchars);
	(void)ioctl(0, TIOCLSET, (char *)&game_local_chars);

#endif

}


/*
 * Save the normal keymap
 */
static void keymap_norm_prepare(void)
{

#ifdef USE_TPOSIX

	/* Get the normal keymap */
	tcgetattr(0, &norm_termios);

#endif

#ifdef USE_TERMIO

	/* Get the normal keymap */
	(void)ioctl(0, TCGETA, (char *)&norm_termio);

#endif

#ifdef USE_TCHARS

	/* Get the normal keymap */
	(void)ioctl(0, TIOCGETP, (char *)&norm_ttyb);
	(void)ioctl(0, TIOCGLTC, (char *)&norm_special_chars);
	(void)ioctl(0, TIOCGETC, (char *)&norm_tchars);
	(void)ioctl(0, TIOCLGET, (char *)&norm_local_chars);

#endif

}


/*
 * Save the keymaps (normal and game)
 */
static void keymap_game_prepare(void)
{

#ifdef USE_TPOSIX

	/* Acquire the current mapping */
	tcgetattr(0, &game_termios);

	/* Force "Ctrl-C" to interupt */
	game_termios.c_cc[VINTR] = (char)3;

	/* Force "Ctrl-Z" to suspend */
	game_termios.c_cc[VSUSP] = (char)26;

	/* Hack -- Leave "VSTART/VSTOP" alone */

	/* Disable the standard control characters */
	game_termios.c_cc[VQUIT] = (char) - 1;
	game_termios.c_cc[VERASE] = (char) - 1;
	game_termios.c_cc[VKILL] = (char) - 1;
	game_termios.c_cc[VEOF] = (char) - 1;
	game_termios.c_cc[VEOL] = (char) - 1;

	/* Normally, block until a character is read */
	game_termios.c_cc[VMIN] = 1;
	game_termios.c_cc[VTIME] = 0;

#endif

#ifdef USE_TERMIO

	/* Acquire the current mapping */
	(void)ioctl(0, TCGETA, (char *)&game_termio);

	/* Force "Ctrl-C" to interupt */
	game_termio.c_cc[VINTR] = (char)3;

	/* Force "Ctrl-Z" to suspend */
	game_termio.c_cc[VSUSP] = (char)26;

	/* Hack -- Leave "VSTART/VSTOP" alone */

	/* Disable the standard control characters */
	game_termio.c_cc[VQUIT] = (char) - 1;
	game_termio.c_cc[VERASE] = (char) - 1;
	game_termio.c_cc[VKILL] = (char) - 1;
	game_termio.c_cc[VEOF] = (char) - 1;
	game_termio.c_cc[VEOL] = (char) - 1;

#if 0
	/* Disable the non-posix control characters */
	game_termio.c_cc[VEOL2] = (char) - 1;
	game_termio.c_cc[VSWTCH] = (char) - 1;
	game_termio.c_cc[VDSUSP] = (char) - 1;
	game_termio.c_cc[VREPRINT] = (char) - 1;
	game_termio.c_cc[VDISCARD] = (char) - 1;
	game_termio.c_cc[VWERASE] = (char) - 1;
	game_termio.c_cc[VLNEXT] = (char) - 1;
	game_termio.c_cc[VSTATUS] = (char) - 1;
#endif

	/* Normally, block until a character is read */
	game_termio.c_cc[VMIN] = 1;
	game_termio.c_cc[VTIME] = 0;

#endif

#ifdef USE_TCHARS

	/* Get the default game characters */
	(void)ioctl(0, TIOCGETP, (char *)&game_ttyb);
	(void)ioctl(0, TIOCGLTC, (char *)&game_special_chars);
	(void)ioctl(0, TIOCGETC, (char *)&game_tchars);
	(void)ioctl(0, TIOCLGET, (char *)&game_local_chars);

	/* Force suspend (^Z) */
	game_special_chars.t_suspc = (char)26;

	/* Cancel some things */
	game_special_chars.t_dsuspc = (char) - 1;
	game_special_chars.t_rprntc = (char) - 1;
	game_special_chars.t_flushc = (char) - 1;
	game_special_chars.t_werasc = (char) - 1;
	game_special_chars.t_lnextc = (char) - 1;

	/* Force interupt (^C) */
	game_tchars.t_intrc = (char)3;

	/* Force start/stop (^Q, ^S) */
	game_tchars.t_startc = (char)17;
	game_tchars.t_stopc = (char)19;

	/* Cancel some things */
	game_tchars.t_quitc = (char) - 1;
	game_tchars.t_eofc = (char) - 1;
	game_tchars.t_brkc = (char) - 1;

#endif

}




/*
 * Suspend/Resume
 */
static errr Term_xtra_gcu_alive(int v)
{
	int x, y;


	/* Suspend */
	if (!v)
	{
		/* Go to normal keymap mode */
		keymap_norm();

		/* Restore modes */
		nocbreak();
		echo();
		nl();

		/* Hack -- make sure the cursor is visible */
		Term_xtra(TERM_XTRA_SHAPE, 1);

		/* Flush the curses buffer */
		(void)refresh();

		/* Get current cursor position */
		getyx(curscr, y, x);

		/* Move the cursor to bottom right corner */
		mvcur(y, x, LINES - 1, 0);

		/* Exit curses */
		endwin();

		/* Flush the output */
		(void)fflush(stdout);
	}

	/* Resume */
	else
	{
		/* Refresh */
		/* (void)touchwin(curscr); */
		/* (void)wrefresh(curscr); */

		/* Restore the settings */
		cbreak();
		noecho();
		nonl();

		/* Go to angband keymap mode */
		keymap_game();
	}

	/* Success */
	return (0);
}


#if 0

#ifdef USE_NCURSES
const char help_gcu[] = "NCurses, for terminal console, subopts -b(ig screen)";
#else /* USE_NCURSES */
const char help_gcu[] = "Curses, for terminal console, subopts -b(ig screen)";
#endif /* USE_NCURSES */

#endif


/*
 * Init the "curses" system
 */
static void Term_init_gcu(term *t)
{
	term_data *td = (term_data *)(t->data);

	/* Count init's, handle first */
	if (active++ != 0) return;

	/* Erase the window */
	(void)wclear(td->win);

	/* Reset the cursor */
	(void)wmove(td->win, 0, 0);

	/* Flush changes */
	(void)wrefresh(td->win);

	/* Game keymap */
	keymap_game();
}


/*
 * Nuke the "curses" system
 */
static void Term_nuke_gcu(term *t)
{
	int x, y;
	term_data *td = (term_data *)(t->data);

	/* Delete this window */
	delwin(td->win);

	/* Count nuke's, handle last */
	if (--active != 0) return;

	/* Hack -- make sure the cursor is visible */
	Term_xtra(TERM_XTRA_SHAPE, 1);

#ifdef A_COLOR
	/* Reset colors to defaults */
	start_color();
#endif

	/* Get current cursor position */
	getyx(curscr, y, x);

	/* Move the cursor to bottom right corner */
	mvcur(y, x, LINES - 1, 0);

	/* Flush the curses buffer */
	(void)refresh();

	/* Exit curses */
	endwin();

	/* Flush the output */
	(void)fflush(stdout);

	/* Normal keymap */
	keymap_norm();
}




#ifdef USE_GETCH

/*
 * Process events, with optional wait
 */
static errr Term_xtra_gcu_event(int v)
{
	int i, k;

	/* Wait */
	if (v)
	{
		/* Paranoia -- Wait for it */
		nodelay(stdscr, FALSE);

		/* Get a keypress */
		i = getch();

		/* Mega-Hack -- allow graceful "suspend" */
		for (k = 0; (k < 10) && (i == ERR); k++) i = getch();

		/* Broken input is special */
		if (i == ERR) exit_game_panic();
		if (i == EOF) exit_game_panic();
	}

	/* Do not wait */
	else
	{
		/* Do not wait for it */
		nodelay(stdscr, TRUE);

		/* Check for keypresses */
		i = getch();

		/* Wait for it next time */
		nodelay(stdscr, FALSE);

		/* None ready */
		if (i == ERR) return (1);
		if (i == EOF) return (1);
	}

	/* Enqueue the keypress */
	Term_keypress(i);

	/* Success */
	return (0);
}

#else	/* USE_GETCH */

/*
* Process events (with optional wait)
*/
static errr Term_xtra_gcu_event(int v)
{
	int i, k;

	char buf[2];

	/* Wait */
	if (v)
	{
		/* Wait for one byte */
		i = read(0, buf, 1);

		/* Hack -- Handle bizarre "errors" */
		if ((i <= 0) && (errno != EINTR)) exit_game_panic();
	}

	/* Do not wait */
	else
	{
		/* Get the current flags for stdin */
		k = fcntl(0, F_GETFL, 0);

		/* Oops */
		if (k < 0) return (1);

		/* Tell stdin not to block */
		if (fcntl(0, F_SETFL, k | O_NDELAY) < 0) return (1);

		/* Read one byte, if possible */
		i = read(0, buf, 1);

		/* Replace the flags for stdin */
		if (fcntl(0, F_SETFL, k)) return (1);
	}

	/* Ignore "invalid" keys */
	if ((i != 1) || (!buf[0])) return (1);

	/* Enqueue the keypress */
	Term_keypress(buf[0]);

	/* Success */
	return (0);
}

#endif	/* USE_GETCH */

/*
 * React to changes
 */
static errr Term_xtra_gcu_react(void)
{

#ifdef A_COLOR

	int i;

	/* Cannot handle color redefinition */
	if (!can_fix_color) return (0);

	/* Set the colors */
	for (i = 0; i < 16; i++)
	{
		/* Set one color (note scaling) */
		init_color(i,
		           angband_color_table[i][1] * 1000 / 255,
		           angband_color_table[i][2] * 1000 / 255,
		           angband_color_table[i][3] * 1000 / 255);
	}

#endif

	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_gcu(int n, int v)
{
	term_data *td = (term_data *)(Term->data);

	/* Analyze the request */
	switch (n)
	{
		/* Clear screen */
	case TERM_XTRA_CLEAR:
		touchwin(td->win);
		(void)wclear(td->win);
		return (0);

		/* Make a noise */
	case TERM_XTRA_NOISE:
		(void)write(1, "\007", 1);
		return (0);

		/* Flush the Curses buffer */
	case TERM_XTRA_FRESH:
		(void)wrefresh(td->win);
		return (0);

#ifdef USE_CURS_SET

		/* Change the cursor visibility */
	case TERM_XTRA_SHAPE:
		curs_set(v);
		return (0);

#endif

		/* Suspend/Resume curses */
	case TERM_XTRA_ALIVE:
		return (Term_xtra_gcu_alive(v));

		/* Process events */
	case TERM_XTRA_EVENT:
		return (Term_xtra_gcu_event(v));

		/* Flush events */
	case TERM_XTRA_FLUSH:
		while (!Term_xtra_gcu_event(FALSE));
		return (0);

		/* Delay */
	case TERM_XTRA_DELAY:
		usleep(1000 * v);
		return (0);

		/* Get Delay of some milliseconds */
	case TERM_XTRA_GET_DELAY:
		{
			int ret;
			struct timeval tv;

			ret = gettimeofday(&tv, NULL);
			Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);

			return ret;
		}

		/* Subdirectory scan */
	case TERM_XTRA_SCANSUBDIR:
		{
			DIR *directory;
			struct dirent *entry;

			scansubdir_max = 0;

			directory = opendir(scansubdir_dir);
			if (!directory)
				return 1;

			while ((entry = readdir(directory)))
			{
				char file[PATH_MAX + NAME_MAX + 2];
				struct stat filedata;

				file[PATH_MAX + NAME_MAX] = 0;
				strncpy(file, scansubdir_dir, PATH_MAX);
				strncat(file, "/", 2);
				strncat(file, entry->d_name, NAME_MAX);
				if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(entry->d_name);
					++scansubdir_max;
				}
			}
		}

		/* React to events */
	case TERM_XTRA_REACT:
		Term_xtra_gcu_react();
		return (0);
	}

	/* Unknown */
	return (1);
}


/*
 * Actually MOVE the hardware cursor
 */
static errr Term_curs_gcu(int x, int y)
{
	term_data *td = (term_data *)(Term->data);

	/* Literally move the cursor */
	wmove(td->win, y, x);

	/* Success */
	return (0);
}


/*
 * Erase a grid of space
 * Hack -- try to be "semi-efficient".
 */
static errr Term_wipe_gcu(int x, int y, int n)
{
	term_data *td = (term_data *)(Term->data);

	/* Place cursor */
	wmove(td->win, y, x);

	/* Clear to end of line */
	if (x + n >= td->t.wid)
	{
		wclrtoeol(td->win);
	}

	/* Clear some characters */
	else
	{
		while (n-- > 0) waddch(td->win, ' ');
	}

	/* Success */
	return (0);
}


/*
 * Place some text on the screen using an attribute
 */
static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
{
	term_data *td = (term_data *)(Term->data);

	int i, pic;

#ifdef A_COLOR
	/* Set the color */
	if (can_use_color) wattrset(td->win, colortable[a & 0x0F]);
#endif

	/* Move the cursor */
	wmove(td->win, y, x);

	/* Draw each character */
	for (i = 0; i < n; i++)
	{
#ifdef USE_GRAPHICS
		/* Special character */
		if (use_graphics && (s[i] & 0x80))
		{
			/* Determine picture to use */
			switch (s[i] & 0x7F)
			{

#ifdef ACS_CKBOARD
				/* Wall */
			case '#':
				pic = ACS_CKBOARD;
				break;
#endif /* ACS_CKBOARD */

#ifdef ACS_BOARD
				/* Mineral vein */
			case '%':
				pic = ACS_BOARD;
				break;
#endif /* ACS_BOARD */

				/* XXX */
			default:
				pic = '?';
				break;
			}

			/* Draw the picture */
			waddch(td->win, pic);

			/* Next character */
			continue;
		}
#endif

		/* Draw a normal character */
		waddch(td->win, (byte)s[i]);
	}

	/* Success */
	return (0);
}


/*
 * Create a window for the given "term_data" argument.
 *
 * Assumes legal arguments.
 */
static errr term_data_init_gcu(term_data *td, int rows, int cols, int y, int x)
{
	term *t = &td->t;

	/* Create new window */
	td->win = newwin(rows, cols, y, x);

	/* Check for failure */
	if (!td->win)
	{
		/* Error */
		quit("Failed to setup curses window.");
	}

	/* Initialize the term */
	term_init(t, cols, rows, 256);

	/* Avoid bottom right corner */
	t->icky_corner = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Set some hooks */
	t->init_hook = Term_init_gcu;
	t->nuke_hook = Term_nuke_gcu;

	/* Set some more hooks */
	t->text_hook = Term_text_gcu;
	t->wipe_hook = Term_wipe_gcu;
	t->curs_hook = Term_curs_gcu;
	t->xtra_hook = Term_xtra_gcu;

	/* Save the data */
	t->data = td;

	/* Activate it */
	Term_activate(t);

	/* Success */
	return (0);
}


static void hook_quit(cptr str)
{
	/* Unused */
	(void)str;

	/* Exit curses */
	endwin();
}


/*
 * Prepare "curses" for use by the file "z-term.c"
 *
 * Installs the "hook" functions defined above, and then activates
 * the main screen "term", which clears the screen and such things.
 *
 * Someone should really check the semantics of "initscr()"
 */
errr init_gcu(int argc, char **argv)
{
	int i;

	int num_term = MAX_TERM_DATA, next_win = 0;

	bool use_big_screen = FALSE;


	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-b"))
		{
			use_big_screen = TRUE;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}


	/* Extract the normal keymap */
	keymap_norm_prepare();


#if defined(USG)
	/* Initialize for USG Unix */
	if (initscr() == NULL) return ( -1);
#else
/* Initialize for other systems */
	if (initscr() == (WINDOW*)ERR) return ( -1);
#endif

	/* Activate hooks */
	quit_aux = hook_quit;
	core_aux = hook_quit;

	/* Require standard size screen */
	if ((LINES < 24) || (COLS < 80))
	{
		quit("Angband needs at least an 80x24 'curses' screen");
	}


#ifdef USE_GRAPHICS

	/* Set graphics flag */
	use_graphics = arg_graphics;

#endif

#ifdef A_COLOR

	/*** Init the Color-pairs and set up a translation table ***/

	/* Do we have color, and enough color, available? */
	can_use_color = ((start_color() != ERR) && has_colors() &&
	                 (COLORS >= 8) && (COLOR_PAIRS >= 8));

#ifdef REDEFINE_COLORS

	/* Can we change colors? */
	can_fix_color = (can_use_color && can_change_color() &&
	                 (COLORS >= 16) && (COLOR_PAIRS > 8));

#endif

	/* Attempt to use customized colors */
	if (can_fix_color)
	{
		/* Prepare the color pairs */
		for (i = 1; i <= 8; i++)
		{
			/* Reset the color */
			if (init_pair(i, i - 1, 0) == ERR)
			{
				quit("Color pair init failed");
			}

			/* Set up the colormap */
			colortable[i - 1] = (COLOR_PAIR(i) | A_NORMAL);
			colortable[i + 7] = (COLOR_PAIR(i) | A_BRIGHT);
		}

		/* Take account of "gamma correction" XXX XXX XXX */

		/* Prepare the "Angband Colors" */
		Term_xtra_gcu_react();
	}

	/* Attempt to use colors */
	else if (can_use_color)
	{
		/* Color-pair 0 is *always* WHITE on BLACK */

		/* Prepare the color pairs */
		init_pair(1, COLOR_RED, COLOR_BLACK);
		init_pair(2, COLOR_GREEN, COLOR_BLACK);
		init_pair(3, COLOR_YELLOW, COLOR_BLACK);
		init_pair(4, COLOR_BLUE, COLOR_BLACK);
		init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
		init_pair(6, COLOR_CYAN, COLOR_BLACK);
		init_pair(7, COLOR_BLACK, COLOR_BLACK);

		/* Prepare the "Angband Colors" -- Bright white is too bright */
		colortable[0] = (COLOR_PAIR(7) | A_NORMAL); 	/* Black */
		colortable[1] = (COLOR_PAIR(0) | A_NORMAL); 	/* White */
		colortable[2] = (COLOR_PAIR(6) | A_NORMAL); 	/* Grey XXX */
		colortable[3] = (COLOR_PAIR(1) | A_BRIGHT); 	/* Orange XXX */
		colortable[4] = (COLOR_PAIR(1) | A_NORMAL); 	/* Red */
		colortable[5] = (COLOR_PAIR(2) | A_NORMAL); 	/* Green */
		colortable[6] = (COLOR_PAIR(4) | A_NORMAL); 	/* Blue */
		colortable[7] = (COLOR_PAIR(3) | A_NORMAL); 	/* Umber */
		colortable[8] = (COLOR_PAIR(7) | A_BRIGHT); 	/* Dark-grey XXX */
		colortable[9] = (COLOR_PAIR(6) | A_BRIGHT); 	/* Light-grey XXX */
		colortable[10] = (COLOR_PAIR(5) | A_NORMAL); 	/* Purple */
		colortable[11] = (COLOR_PAIR(3) | A_BRIGHT); 	/* Yellow */
		colortable[12] = (COLOR_PAIR(5) | A_BRIGHT); 	/* Light Red XXX */
		colortable[13] = (COLOR_PAIR(2) | A_BRIGHT); 	/* Light Green */
		colortable[14] = (COLOR_PAIR(4) | A_BRIGHT); 	/* Light Blue */
		colortable[15] = (COLOR_PAIR(3) | A_NORMAL); 	/* Light Umber XXX */
	}

#endif


	/*** Low level preparation ***/

#ifdef USE_GETCH

	/* Paranoia -- Assume no waiting */
	nodelay(stdscr, FALSE);

#endif

	/* Prepare */
	cbreak();
	noecho();
	nonl();

	/* Extract the game keymap */
	keymap_game_prepare();


	/*** Now prepare the term(s) ***/

	/* Big screen -- one big term */
	if (use_big_screen)
	{
		/* Create a term */
		term_data_init_gcu(&data[0], LINES, COLS, 0, 0);

		/* Remember the term */
		angband_term[0] = &data[0].t;
	}

	/* No big screen -- create as many term windows as possible */
	else
	{
		/* Create several terms */
		for (i = 0; i < num_term; i++)
		{
			int rows, cols, y, x;

			/* Decide on size and position */
			switch (i)
			{
				/* Upper left */
			case 0:
				{
					rows = 24;
					cols = 80;
					y = x = 0;
					break;
				}

				/* Lower left */
			case 1:
				{
					rows = LINES - 25;
					cols = 80;
					y = 25;
					x = 0;
					break;
				}

				/* Upper right */
			case 2:
				{
					rows = 24;
					cols = COLS - 81;
					y = 0;
					x = 81;
					break;
				}

				/* Lower right */
			case 3:
				{
					rows = LINES - 25;
					cols = COLS - 81;
					y = 25;
					x = 81;
					break;
				}

				/* XXX */
			default:
				{
					rows = cols = y = x = 0;
					break;
				}
			}

			/* Skip non-existant windows */
			if (rows <= 0 || cols <= 0) continue;

			/* Create a term */
			term_data_init_gcu(&data[next_win], rows, cols, y, x);

			/* Remember the term */
			angband_term[next_win] = &data[next_win].t;

			/* One more window */
			next_win++;
		}
	}

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

	/* Remember the active screen */
	term_screen = &data[0].t;

	/* Success */
	return (0);
}


#endif /* USE_GCU */


tome-235-src/src/q_spider.c0000644000076400017500000000512611012107763013433 0ustar  dgdg#undef cquest
#define cquest (quest[QUEST_SPIDER])

bool quest_spider_gen_hook(char *fmt)
{
	int x, y;
	int xstart = 2;
	int ystart = 2;

	if (p_ptr->inside_quest != QUEST_SPIDER) return FALSE;

	/* Start with perm walls */
	for (y = 0; y < cur_hgt; y++)
	{
		for (x = 0; x < cur_wid; x++)
		{
			cave_set_feat(y, x, FEAT_PERM_SOLID);
		}
	}
	dun_level = quest[p_ptr->inside_quest].level;

	/* Set the correct monster hook */
	set_mon_num_hook();

	/* Prepare allocation table */
	get_mon_num_prep();

	init_flags = INIT_CREATE_DUNGEON;
	process_dungeon_file_full = TRUE;
	process_dungeon_file(NULL, "spiders.map", &ystart, &xstart, cur_hgt, cur_wid, TRUE);
	process_dungeon_file_full = FALSE;

	return TRUE;
}
bool quest_spider_death_hook(char *fmt)
{
	int i, mcnt = 0;

	if (p_ptr->inside_quest != QUEST_SPIDER) return FALSE;

	for (i = m_max - 1; i >= 1; i--)
	{
		/* Access the monster */
		monster_type *m_ptr = &m_list[i];

		/* Ignore "dead" monsters */
		if (!m_ptr->r_idx) continue;

		if (m_ptr->status <= MSTATUS_ENEMY) mcnt++;
	}

	if (mcnt <= 1)
	{
		cmsg_print(TERM_YELLOW, "The forest is now safer, thanks to you.");

		/* Yavanna LOVES saving forests */
		GOD(GOD_YAVANNA)
		{
			cmsg_print(TERM_L_GREEN, "You feel the gentle touch of Yavanna, as she smiles at you.");
			inc_piety(GOD_YAVANNA, 6000);
		}

		cquest.status = QUEST_STATUS_COMPLETED;
		del_hook(HOOK_MONSTER_DEATH, quest_spider_death_hook);
		process_hooks_restart = TRUE;
		return (FALSE);
	}

	return (FALSE);
}
bool quest_spider_finish_hook(char *fmt)
{
	object_type forge, *q_ptr;
	s32b q_idx;

	q_idx = get_next_arg(fmt);

	if (q_idx != QUEST_SPIDER) return FALSE;

	c_put_str(TERM_YELLOW, "All of us praise your mighty deed in driving back the", 8, 0);
	c_put_str(TERM_YELLOW, "menace. Take this as a reward.", 9, 0);

	q_ptr = &forge;
	object_prep(q_ptr, lookup_kind(TV_POTION, SV_POTION_AUGMENTATION));
	q_ptr->number = 1;
	q_ptr->found = OBJ_FOUND_REWARD;
	object_aware(q_ptr);
	object_known(q_ptr);
	q_ptr->ident |= IDENT_STOREB;
	(void)inven_carry(q_ptr, FALSE);

	/* Continue the plot */
	*(quest[q_idx].plot) = QUEST_POISON;
	quest[*(quest[q_idx].plot)].init(*(quest[q_idx].plot));

	del_hook(HOOK_QUEST_FINISH, quest_spider_finish_hook);
	process_hooks_restart = TRUE;

	return TRUE;
}
bool quest_spider_init_hook(int q_idx)
{
	if ((cquest.status >= QUEST_STATUS_TAKEN) && (cquest.status < QUEST_STATUS_FINISHED))
	{
		add_hook(HOOK_MONSTER_DEATH, quest_spider_death_hook, "spider_death");
		add_hook(HOOK_GEN_QUEST, quest_spider_gen_hook, "spider_gen");
		add_hook(HOOK_QUEST_FINISH, quest_spider_finish_hook, "spider_finish");
	}
	return (FALSE);
}
tome-235-src/src/main-gtk.c0000644000076400017500000032576111012107763013346 0ustar  dgdg/* File: main-gtk.c */

/*
 * Copyright (c) 2000-2001 Robert Ruehlmann,
 * Steven Fuerst, Uwe Siems, "pelpel", et al.
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */

/*
 * Robert Ruehlmann wrote the original Gtk port. Since an initial work is
 * much harder than enhancements, his effort worth more credits than
 * others.
 *
 * Steven Fuerst implemented colour-depth independent X server support,
 * graphics, resizing and big screen support for ZAngband as well as
 * fast image rescaling that is included here.
 *
 * Uwe Siems wrote smooth tiles rescaling code (on by default).
 * Try this with 8x8 tiles. They *will* look different.
 *
 * "pelpel" wrote another colour-depth independent X support
 * using GdkRGB, added several hooks and callbacks for various
 * reasons, wrote no-backing store mode (off by default),
 * added GtkItemFactory based menu system, introduced
 * USE_GRAPHICS code bloat (^ ^;), added comments (I have
 * a strange habit of writing comments while I code...)
 * and reorganised the file a bit.
 */

#include "angband.h"


/*
 * Activate variant-specific features
 *
 * Angband 2.9.3 and close variants don't require any.
 *
 * Angband 2.9.4 alpha and later removed the short-lived
 * can_save flag, so please #define can_save TRUE, or remove
 * all the references to it. They also changed long-lived
 * z-virt macro names. Find C_FREE/C_KILL and replace them
 * with FREE/KILL, which takes one pointer parameter.
 *
 * [Z]-based variants (Gum and Cth, for example) usually need
 * ANG293_COMPAT, ANG291_COMPAT and ANG281_RESET_VISUALS.
 *
 * [O] needs ANG293_COMPAT and ZANG_SAVE_GAME.
 *
 * ZAngband has its own enhanced main-gtk.c as mentioned above, and
 * you *should* use it :-)
 *
 * ANG291_COMPAT does not include Angband 2.9.x's gamma correction code.
 * If you like to use SUPPORT_GAMMA, copy the code bracketed
 * inside of #ifdef SUPPORT_GAMMA in util.c of Angband 2.9.1 or greater.
 */
#define TOME

#ifdef TOME
# define ANG293_COMPAT	/* Requires V2.9.3 compatibility code */
# define ANG291_COMPAT	/* Requires V2.9.1 compatibility code */
# define ANG281_RESET_VISUALS	/* The old style reset_visuals() */
# define INTERACTIVE_GAMMA	/* Supports interactive gamma correction */
# define SAVEFILE_SCREEN	/* New/Open integrated into the game */
# define USE_DOUBLE_TILES	/* Mogami's bigtile patch */
#endif /* TOME */

/*
 * Some examples
 */
#ifdef ANGBAND300
# define can_save TRUE	/* Mimick the short-lived flag */
# define C_FREE(P, N, T)	FREE(P)	/* Emulate the long-lived macro */
# define USE_TRANSPARENCY	/* Because it's default now */
#endif /* ANGBAND300 */

#ifdef GUMBAND
# define ANG293_COMPAT	/* Requires V2.9.3 compatibility code */
# define ANG291_COMPAT	/* Requires V2.9.1 compatibility code */
# define ANG281_RESET_VISUALS	/* The old style reset_visuals() */
# define OLD_SAVEFILE_CODE /* See also SAVEFILE_MUTABLE in files.c */
# define NO_REDRAW_SECTION	/* Doesn't have Term_redraw_section() */
#endif /* GUMBAND */

#ifdef OANGBAND
# define ANG293_COMPAT	/* Requires V2.9.3 compatibility code */
# define ZANG_SAVE_GAME	/* do_cmd_save_game with auto_save parameter */
#endif /* OANGBAND */


#ifdef USE_GTK

/* Force ANSI standard */
/* #define __STRICT_ANSI__ */

/* No GCC-specific includes */
/* #undef __GNUC__ */

#include 
#include 
#include 
#include 
#include 
#include 

/* /me pffts Solaris */
#ifndef NAME_MAX
#define	NAME_MAX	_POSIX_NAME_MAX
#endif


/*
 * Include some helpful X11 code.
 */
#ifndef ANG293_COMPAT
# include "maid-x11.h"
#endif /* !ANG293_COMPAT */


/*
 * Number of pixels inserted between the menu bar and the main screen
 */
#define NO_PADDING 0


/*
 * Largest possible number of terminal windows supported by the game
 */
#define MAX_TERM_DATA 8


/*
 * Extra data to associate with each "window"
 *
 * Each "window" is represented by a "term_data" structure, which
 * contains a "term" structure, which contains a pointer (t->data)
 * back to the term_data structure.
 */

#ifdef USE_GRAPHICS

/*
 * Since GdkRGB doesn't provide us some useful functions...
 */
typedef struct GdkRGBImage GdkRGBImage;

struct GdkRGBImage
{
	gint width;
	gint height;
	gint ref_count;
	guchar *image;
};

#endif /* USE_GRAPHICS */


/*
 * This structure holds everything you need to manipulate terminals
 */
typedef struct term_data term_data;

struct term_data
{
	term t;

	GtkWidget *window;
	GtkWidget *drawing_area;
	GdkPixmap *backing_store;
	GdkFont *font;
	GdkGC *gc;

	bool shown;
	byte last_attr;

	int font_wid;
	int font_hgt;

	int rows;
	int cols;

#ifdef USE_GRAPHICS

	int tile_wid;
	int tile_hgt;

	GdkRGBImage *tiles;
# ifdef USE_TRANSPARENCY
	guint32 bg_pixel;
	GdkRGBImage *trans_buf;
# endif  /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */

	cptr name;
};


/*
 * Where to draw when we call Gdk drawing primitives
 */
# define TERM_DATA_DRAWABLE(td) \
((td)->backing_store ? (td)->backing_store : (td)->drawing_area->window)

# define TERM_DATA_REFRESH(td, x, y, wid, hgt) \
if ((td)->backing_store) gdk_draw_pixmap( \
(td)->drawing_area->window, \
(td)->gc, \
(td)->backing_store, \
(x) * (td)->font_wid, \
(y) * (td)->font_hgt, \
(x) * (td)->font_wid, \
(y) * (td)->font_hgt, \
(wid) * (td)->font_wid, \
(hgt) * (td)->font_hgt)


#if 0

/* Compile time option version */

# ifdef USE_BACKING_STORE

# define TERM_DATA_DRAWABLE(td) (td)->backing_store

# define TERM_DATA_REFRESH(td, x, y, wid, hgt) \
gdk_draw_pixmap( \
(td)->drawing_area->window, \
(td)->gc, \
(td)->backing_store, \
(x) * (td)->font_wid, \
(y) * (td)->font_hgt, \
(x) * (td)->font_wid, \
(y) * (td)->font_hgt, \
(wid) * (td)->font_wid, \
(hgt) * (td)->font_hgt)

# else /* USE_BACKING_STORE */

# define TERM_DATA_DRAWABLE(td) (td)->drawing_area->window
# define TERM_DATA_REFRESH(td, x, y, wid, hgt)

# endif  /* USE_BACKING_STORE */

#endif /* 0 */


/*
 * An array of "term_data" structures, one for each "sub-window"
 */
static term_data data[MAX_TERM_DATA];

/*
 * Number of active terms
 */
static int num_term = 1;


/*
 * RGB values of the sixteen Angband colours
 */
static guint32 angband_colours[16];


/*
 * Set to TRUE when a game is in progress
 */
static bool game_in_progress = FALSE;


/*
 * This is in some cases used for double buffering as well as
 * a backing store, speeding things up under client-server
 * configurations, while turning this off *might* work better
 * with the MIT Shm extention which is usually active if you run
 * Angband locally, because it reduces amount of memory-to-memory copy.
 */
static bool use_backing_store = TRUE;




/**** Vanilla compatibility functions ****/

#ifdef ANG293_COMPAT

/*
 * Look up some environment variables to find font name for each window.
 */
static cptr get_default_font(int term)
{
	char buf[64];
	cptr font_name;

	/* Window specific font name */
	strnfmt(buf, 64, "ANGBAND_X11_FONT_%s", angband_term_name[term]);

	/* Check environment for that font */
	font_name = getenv(buf);

	/* Window specific font name */
	strnfmt(buf, 64, "ANGBAND_X11_FONT_%d", term);

	/* Check environment for that font */
	if (!font_name) font_name = getenv(buf);

	/* Check environment for "base" font */
	if (!font_name) font_name = getenv("ANGBAND_X11_FONT");

	/* No environment variables, use default font */
	if (!font_name) font_name = DEFAULT_X11_FONT_SCREEN;

	return (font_name);
}


# ifndef SAVEFILE_SCREEN

/*
 * In [V]2.9.3, this frees all dynamically allocated memory
 */
static void cleanup_angband(void)
{
	/* XXX XXX XXX */
}

# endif  /* !SAVEFILE_SCREEN */

/*
 * New global flag to indicate if it's safe to save now
 */
#define can_save TRUE

#endif /* ANG293_COMPAT */


#ifdef ANG291_COMPAT

/*
 * The standard game uses this to implement lighting effects
 * for 16x16 tiles in cave.c...
 *
 * Because of the way it is implemented in X11 ports,
 * we can set this to TRUE even if we are using the 8x8 tileset.
 */
static bool use_transparency = TRUE;

#endif /* ANG291_COMPAT */




/**** Low level routines - memory allocation ****/

/*
 * Hook to "release" memory
 */
#ifdef ANGBAND300
static vptr hook_rnfree(vptr v)
#else
static vptr hook_rnfree(vptr v, huge size)
#endif /* ANGBAND300 */
{
	/* Dispose */
	g_free(v);

	/* Success */
	return (NULL);
}


/*
 * Hook to "allocate" memory
 */
static vptr hook_ralloc(huge size)
{
	/* Make a new pointer */
	return (g_malloc(size));
}



/**** Low level routines - colours and graphics ****/

#ifdef SUPPORT_GAMMA

/*
 * When set to TRUE, indicates that we can use gamma_table
 */
static bool gamma_table_ready = FALSE;


# ifdef INTERACTIVE_GAMMA

/*
 * Initialise the gamma-correction table for current gamma_val
 * - interactive version
 */
static void setup_gamma_table(void)
{
	static u16b old_gamma_val = 0;

	/* Don't have to rebuild the table */
	if (gamma_val == old_gamma_val) return;

	/* Temporarily inactivate the table */
	gamma_table_ready = FALSE;

	/* Validate gamma_val */
	if ((gamma_val <= 0) || (gamma_val >= 256))
	{
		/* Reset */
		old_gamma_val = gamma_val = 0;

		/* Leave it inactive */
		return;
	}

	/* (Re)build the gamma table */
	build_gamma_table(gamma_val);

	/* Remember the gamma value used */
	old_gamma_val = gamma_val;

	/* Activate the table */
	gamma_table_ready = TRUE;
}

# else /* INTERACTIVE_GAMMA */

/*
 * Initialise the gamma-correction table if environment variable
 * ANGBAND_X11_GAMMA is set and contains a meaningful value
 *
 * Restored for cross-variant compatibility
 */
static void setup_gamma_table(void)
{
	cptr tmp;
	int gamma_val;


	/* The table's already set up */
	if (gamma_table_ready) return;

	/*
	 * XXX XXX It's documented nowhere, but ANGBAND_X11_GAMMA is
	 * 256 * (1 / gamma), rounded to integer. A recommended value
	 * is 183, which is an approximation of the Macintosh hardware
	 * gamma of 1.4.
	 *
	 *   gamma	ANGBAND_X11_GAMMA
	 *   -----	-----------------
	 *   1.2	213
	 *   1.25	205
	 *   1.3	197
	 *   1.35	190
	 *   1.4	183
	 *   1.45	177
	 *   1.5	171
	 *   1.6	160
	 *   1.7	151
	 *   ...
	 *
	 * XXX XXX The environment variable, or better,
	 * the interact with colours command should allow users
	 * to specify gamma values (or gamma value * 100).
	 */
	tmp = getenv("ANGBAND_X11_GAMMA");

	/* Nothing to do */
	if (tmp == NULL) return;

	/* Extract the value */
	gamma_val = atoi(tmp);

	/*
	 * Only need to build the table if gamma exists and set to
	 * a meaningful value.
	 *
	 * XXX It may be a good idea to prevent use of very high gamma values,
	 * say, greater than 2.5, which is gamma of normal CRT display IIRC.
	 */
	if ((gamma_val <= 0) || (gamma_val >= 256)) return;

	/* Build the gamma correction table */
	build_gamma_table(gamma_val);

	/* The table is properly set up */
	gamma_table_ready = TRUE;
}

# endif  /* INTERACTIVE_GAMMA */

#endif /* SUPPORT_GAMMA */


/*
 * Remeber RGB values for sixteen Angband colours, in a format
 * that is convinient for GdkRGB GC functions.
 *
 * XXX XXX Duplication of maid-x11.c is far from the Angband
 * ideal of code cleanliness, but the whole point of using GdkRGB
 * is to let it handle colour allocation which it does in a very
 * clever fashion. Ditto for the tile scaling code and the BMP loader
 * below.
 */
static void init_colours(void)
{
	int i;


#ifdef SUPPORT_GAMMA

	/* (Re)build gamma table if necessary */
	setup_gamma_table();

#endif /* SUPPORT_GAMMA */

	/* Process each colour */
	for (i = 0; i < 16; i++)
	{
		u32b red, green, blue;

		/* Retrieve RGB values from the game */
		red = angband_color_table[i][1];
		green = angband_color_table[i][2];
		blue = angband_color_table[i][3];

#ifdef SUPPORT_GAMMA

		/* Hack -- Gamma Correction */
		if (gamma_table_ready)
		{
			red = gamma_table[red];
			green = gamma_table[green];
			blue = gamma_table[blue];
		}

#endif /* SUPPORT_GAMMA */

		/* Remember a GdkRGB value, that is 0xRRGGBB */
		angband_colours[i] = (red << 16) | (green << 8) | blue;
	}
}


/*
 * Set foreground colour of window td to attr, only when it is necessary
 */
static void term_data_set_fg(term_data *td, byte attr)
{
	/* We can use the current gc */
	if (td->last_attr == attr) return;

	/* Activate the colour */
	gdk_rgb_gc_set_foreground(td->gc, angband_colours[attr]);

	/* Remember it */
	td->last_attr = attr;
}


#ifdef USE_GRAPHICS

/*
 * Graphics mode selector - current setting and requested value
 */
#define GRAF_MODE_NONE	0
#define GRAF_MODE_OLD	1
#define GRAF_MODE_NEW	2

static int graf_mode = GRAF_MODE_NONE;
static int graf_mode_request = GRAF_MODE_NONE;

/*
 * Use smooth rescaling?
 */
static bool smooth_rescaling = TRUE;
static bool smooth_rescaling_request = TRUE;

/*
 * Dithering
 */
static GdkRgbDither dith_mode = GDK_RGB_DITHER_NORMAL;

/*
 * Need to reload and resize tiles when fonts are changed.
 */
static bool resize_request = FALSE;

/*
 * Numbers of columns and rows in current tileset
 * calculated and set by the tile loading code in graf_init()
 * and used by Term_pict_gtk()
 */
static int tile_rows;
static int tile_cols;


/*
 * Directory name(s)
 */
static cptr ANGBAND_DIR_XTRA_GRAF;


/*
 * Be nice to old graphics hardwares -- using GdkRGB.
 *
 * We don't have colour allocation failure any longer this way,
 * even with 8bpp X servers. Gimp *does* work with 8bpp, why not Angband?
 *
 * Initialisation (before any widgets are created)
 *	gdk_rgb_init();
 *	gtk_widget_set_default_colormap (gdk_rgb_get_cmap());
 *	gtk_widget_set_default_visual (gdk_rgb_get_visual());
 *
 * Setting fg/bg colours
 *	void gdk_rgb_gc_set_foreground(GdkGC *gc, guint32 rgb);
 *	void gdk_rgb_gc_set_background(GdkGC *gc, guint32 rgb);
 * where rgb is 0xRRGGBB.
 *
 * Drawing rgb images
 *	void gdk_draw_rgb_image(
 *		GdkDrawable *drawable,
 *		GdkGC *gc,
 *		gint x, gint y,
 *		gint width, gint height,
 *		GdkRgbDither dith,
 *		guchar *rgb_buf,
 *		gint rowstride);
 *
 * dith:
 *	GDK_RGB_DITHER_NORMAL : dither if 8bpp or below
 *	GDK_RGB_DITHER_MAX : dither if 16bpp or below.
 *
 * for 0 <= i < width and 0 <= j < height,
 * the pixel (x + i, y + j) is colored with
 *  red value rgb_buf[j * rowstride + i * 3],
 *  green value rgb_buf[j * rowstride + i * 3 + 1], and
 *  blue value rgb_buf[j * rowstride + i * 3 + 2].
 */

/*
 * gdk_image compatibility functions - should be part of gdk, IMHO.
 */

/*
 * Create GdkRGBImage of width * height and return pointer
 * to it. Returns NULL on failure
 */
static GdkRGBImage *gdk_rgb_image_new(
        gint width,
        gint height)
{
	GdkRGBImage *result;

	/* Allocate a struct */
	result = g_new(GdkRGBImage, 1);

	/* Oops */
	if (result == NULL) return (NULL);

	/* Allocate buffer */
	result->image = g_new0(guchar, width * height * 3);

	/* Oops */
	if (result->image == NULL)
	{
		g_free(result);
		return (NULL);
	}

	/* Initialise size fields */
	result->width = width;
	result->height = height;

	/* Initialise reference count */
	result->ref_count = 1;

	/* Success */
	return (result);
}

/*
 * Free a GdkRGBImage
 */
static void gdk_rgb_image_destroy(
        GdkRGBImage *im)
{
	/* Paranoia */
	if (im == NULL) return;

	/* Free the RGB buffer */
	g_free(im->image);

	/* Free the structure */
	g_free(im);
}


#if 0

/*
 * Unref a GdkRGBImage
 */
static void gdk_rgb_image_unref(
        GdkRGBImage *im)
{
	/* Paranoia */
	g_return_if_fail(im != NULL);

	/* Decrease reference count by 1 */
	im->ref_count--;

	/* Free if nobody's using it */
	if (im->ref_count <= 0) gdk_rgb_image_destroy(im);
}


/*
 * Reference a GdkRGBImage
 */
static void gdk_rgb_image_ref(
        GdkRGBImage *im)
{
	/* Paranoia */
	g_return_if_fail(im != NULL);

	/* Increase reference count by 1 */
	im->ref_count++;
}

#endif /* 0 */


/*
 * Write RGB pixel of the format 0xRRGGBB to (x, y) in GdkRGBImage
 */
static void gdk_rgb_image_put_pixel(
        GdkRGBImage *im,
        gint x,
        gint y,
        guint32 pixel)
{
	guchar *rgbp;

	/* Paranoia */
	g_return_if_fail(im != NULL);

	/* Paranoia */
	if ((x < 0) || (x >= im->width)) return;

	/* Paranoia */
	if ((y < 0) || (y >= im->height)) return;

	/* Access RGB data */
	rgbp = &im->image[(y * im->width * 3) + (x * 3)];

	/* Red */
	*rgbp++ = (pixel >> 16) & 0xFF;
	/* Green */
	*rgbp++ = (pixel >> 8) & 0xFF;
	/* Blue */
	*rgbp = pixel & 0xFF;
}


/*
 * Returns RGB pixel (0xRRGGBB) at (x, y) in GdkRGBImage
 */
static guint32 gdk_rgb_image_get_pixel(
        GdkRGBImage *im,
        gint x,
        gint y)
{
	guchar *rgbp;

	/* Paranoia */
	if (im == NULL) return (0);

	/* Paranoia - returns black */
	if ((x < 0) || (x >= im->width)) return (0);

	/* Paranoia */
	if ((y < 0) || (y >= im->height)) return (0);

	/* Access RGB data */
	rgbp = &im->image[(y * im->width * 3) + (x * 3)];

	/* Return result */
	return ((rgbp[0] << 16) | (rgbp[1] << 8) | (rgbp[2]));
}


/*
 * Since gdk_draw_rgb_image is a bit harder to use than it's
 * GdkImage counterpart, I wrote a grue function that takes
 * exactly the same parameters as gdk_draw_image, with
 * the GdkImage parameter replaced with GdkRGBImage.
 */
static void gdk_draw_rgb_image_2(
        GdkDrawable *drawable,
        GdkGC *gc,
        GdkRGBImage *image,
        gint xsrc,
        gint ysrc,
        gint xdest,
        gint ydest,
        gint width,
        gint height)
{
	/* Paranoia */
	g_return_if_fail(drawable != NULL);
	g_return_if_fail(image != NULL);

	/* Paranoia */
	if (xsrc < 0 || (xsrc + width - 1) >= image->width) return;
	if (ysrc < 0 || (ysrc + height - 1) >= image->height) return;

	/* Draw the image at (xdest, ydest), with dithering if bpp <= 8/16 */
	gdk_draw_rgb_image(
	        drawable,
	        gc,
	        xdest,
	        ydest,
	        width,
	        height,
	        dith_mode,
	        &image->image[(ysrc * image->width * 3) + (xsrc * 3)],
	        image->width * 3);
}


/*
 * Code for smooth icon rescaling from Uwe Siems, Jan 2000
 *
 * XXX XXX Duplication of maid-x11.c, again. It doesn't do any colour
 * allocation, either.
 */

/*
 * to save ourselves some labour, define a maximum expected icon width here:
 */
#define MAX_ICON_WIDTH 32


/*
 * Each pixel is kept in this structure during smooth rescaling
 * calculations, to make things a bit easier
 */
typedef struct rgb_type rgb_type;

struct rgb_type
{
	guint32 red;
	guint32 green;
	guint32 blue;
};

/*
 * Because there are many occurences of this, and because
 * it's logical to do so...
 */
#define pixel_to_rgb(pix, rgb_buf) \
(rgb_buf)->red   = ((pix) >> 16) & 0xFF; \
(rgb_buf)->green = ((pix) >> 8)  & 0xFF; \
(rgb_buf)->blue  = (pix) & 0xFF


/*
 * get_scaled_row reads a scan from the given GdkRGBImage, scales it smoothly
 * and returns the red, green and blue values in arrays.
 * The values in this arrays must be divided by a certain value that is
 * calculated in scale_icon.
 * x, y is the position, iw is the input width and ow the output width
 * scan must be sufficiently sized
 */
static void get_scaled_row(
        GdkRGBImage *im,
        int x,
        int y,
        int iw,
        int ow,
        rgb_type *scan)
{
	int xi, si, sifrac, ci, cifrac, add_whole, add_frac;
	guint32 pix;
	rgb_type prev;
	rgb_type next;
	bool get_next_pix;

	/* Unscaled */
	if (iw == ow)
	{
		for (xi = 0; xi < ow; xi++)
		{
			pix = gdk_rgb_image_get_pixel(im, x + xi, y);
			pixel_to_rgb(pix, &scan[xi]);
		}
	}

	/* Scaling by subsampling (grow) */
	else if (iw < ow)
	{
		iw--;
		ow--;

		/* read first pixel: */
		pix = gdk_rgb_image_get_pixel(im, x, y);
		pixel_to_rgb(pix, &next);
		prev = next;

		/* si and sifrac give the subsampling position: */
		si = x;
		sifrac = 0;

		/* get_next_pix tells us, that we need the next pixel */
		get_next_pix = TRUE;

		for (xi = 0; xi <= ow; xi++)
		{
			if (get_next_pix)
			{
				prev = next;
				if (xi < ow)
				{
					/* only get next pixel if in same icon */
					pix = gdk_rgb_image_get_pixel(im, si + 1, y);
					pixel_to_rgb(pix, &next);
				}
			}

			/* calculate subsampled color values: */
			/* division by ow occurs in scale_icon */
			scan[xi].red = prev.red * (ow - sifrac) + next.red * sifrac;
			scan[xi].green = prev.green * (ow - sifrac) + next.green * sifrac;
			scan[xi].blue = prev.blue * (ow - sifrac) + next.blue * sifrac;

			/* advance sampling position: */
			sifrac += iw;
			if (sifrac >= ow)
			{
				si++;
				sifrac -= ow;
				get_next_pix = TRUE;
			}
			else
			{
				get_next_pix = FALSE;
			}

		}
	}

	/* Scaling by averaging (shrink) */
	else
	{
		/* width of an output pixel in input pixels: */
		add_whole = iw / ow;
		add_frac = iw % ow;

		/* start position of the first output pixel: */
		si = x;
		sifrac = 0;

		/* get first input pixel: */
		pix = gdk_rgb_image_get_pixel(im, x, y);
		pixel_to_rgb(pix, &next);

		for (xi = 0; xi < ow; xi++)
		{
			/* find endpoint of the current output pixel: */
			ci = si + add_whole;
			cifrac = sifrac + add_frac;
			if (cifrac >= ow)
			{
				ci++;
				cifrac -= ow;
			}

			/* take fraction of current input pixel (starting segment): */
			scan[xi].red = next.red * (ow - sifrac);
			scan[xi].green = next.green * (ow - sifrac);
			scan[xi].blue = next.blue * (ow - sifrac);
			si++;

			/* add values for whole pixels: */
			while (si < ci)
			{
				rgb_type tmp_rgb;

				pix = gdk_rgb_image_get_pixel(im, si, y);
				pixel_to_rgb(pix, &tmp_rgb);
				scan[xi].red += tmp_rgb.red * ow;
				scan[xi].green += tmp_rgb.green * ow;
				scan[xi].blue += tmp_rgb.blue * ow;
				si++;
			}

			/* add fraction of current input pixel (ending segment): */
			if (xi < ow - 1)
			{
				/* only get next pixel if still in icon: */
				pix = gdk_rgb_image_get_pixel(im, si, y);
				pixel_to_rgb(pix, &next);
			}

			sifrac = cifrac;
			if (sifrac > 0)
			{
				scan[xi].red += next.red * sifrac;
				scan[xi].green += next.green * sifrac;
				scan[xi].blue += next.blue * sifrac;
			}
		}
	}
}


/*
 * put_rgb_scan takes arrays for red, green and blue and writes pixel values
 * according to this values in the GdkRGBImage-structure. w is the number of
 * pixels to write and div is the value by which all red/green/blue values
 * are divided first.
 */
static void put_rgb_scan(
        GdkRGBImage *im,
        int x,
        int y,
        int w,
        int div,
        rgb_type *scan)
{
	int xi;
	guint32 pix;
	guint32 adj = div / 2;

	for (xi = 0; xi < w; xi++)
	{
		byte r, g, b;

		/* un-factor the RGB values */
		r = (scan[xi].red + adj) / div;
		g = (scan[xi].green + adj) / div;
		b = (scan[xi].blue + adj) / div;

#ifdef SUPPORT_GAMMA

		/* Apply gamma correction if requested and available */
		if (gamma_table_ready)
		{
			r = gamma_table[r];
			g = gamma_table[g];
			b = gamma_table[b];
		}

#endif /* SUPPORT_GAMMA */

		/* Make a (virtual) 24-bit pixel */
		pix = (r << 16) | (g << 8) | (b);

		/* Draw it into image */
		gdk_rgb_image_put_pixel(im, x + xi, y, pix);
	}
}


/*
 * scale_icon transfers an area from GdkRGBImage im_in, locate (x1,y1) to
 * im_out, locate (x2, y2). Source size is (ix, iy) and destination size
 * is (ox, oy).
 *
 * It does this by getting icon scan line from get_scaled_scan and handling
 * them the same way as pixels are handled in get_scaled_scan.
 * This even allows icons to be scaled differently in horizontal and
 * vertical directions (eg. shrink horizontal, grow vertical).
 */
static void scale_icon(
        GdkRGBImage *im_in,
        GdkRGBImage *im_out,
        int x1,
        int y1,
        int x2,
        int y2,
        int ix,
        int iy,
        int ox,
        int oy)
{
	int div;
	int xi, yi, si, sifrac, ci, cifrac, add_whole, add_frac;

	/* buffers for pixel rows: */
	rgb_type prev[MAX_ICON_WIDTH];
	rgb_type next[MAX_ICON_WIDTH];
	rgb_type temp[MAX_ICON_WIDTH];

	bool get_next_row;

	/* get divider value for the horizontal scaling: */
	if (ix == ox)
		div = 1;
	else if (ix < ox)
		div = ox - 1;
	else
		div = ix;

	/* no scaling needed vertically: */
	if (iy == oy)
	{
		for (yi = 0; yi < oy; yi++)
		{
			get_scaled_row(im_in, x1, y1 + yi, ix, ox, temp);
			put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp);
		}
	}

	/* scaling by subsampling (grow): */
	else if (iy < oy)
	{
		iy--;
		oy--;
		div *= oy;

		/* get first row: */
		get_scaled_row(im_in, x1, y1, ix, ox, next);

		/* si and sifrac give the subsampling position: */
		si = y1;
		sifrac = 0;

		/* get_next_row tells us, that we need the next row */
		get_next_row = TRUE;
		for (yi = 0; yi <= oy; yi++)
		{
			if (get_next_row)
			{
				for (xi = 0; xi < ox; xi++)
				{
					prev[xi] = next[xi];
				}
				if (yi < oy)
				{
					/* only get next row if in same icon */
					get_scaled_row(im_in, x1, si + 1, ix, ox, next);
				}
			}

			/* calculate subsampled color values: */
			/* division by oy occurs in put_rgb_scan */
			for (xi = 0; xi < ox; xi++)
			{
				temp[xi].red = (prev[xi].red * (oy - sifrac) +
				                next[xi].red * sifrac);
				temp[xi].green = (prev[xi].green * (oy - sifrac) +
				                  next[xi].green * sifrac);
				temp[xi].blue = (prev[xi].blue * (oy - sifrac) +
				                 next[xi].blue * sifrac);
			}

			/* write row to output image: */
			put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp);

			/* advance sampling position: */
			sifrac += iy;
			if (sifrac >= oy)
			{
				si++;
				sifrac -= oy;
				get_next_row = TRUE;
			}
			else
			{
				get_next_row = FALSE;
			}

		}
	}

	/* scaling by averaging (shrink) */
	else
	{
		div *= iy;

		/* height of a output row in input rows: */
		add_whole = iy / oy;
		add_frac = iy % oy;

		/* start position of the first output row: */
		si = y1;
		sifrac = 0;

		/* get first input row: */
		get_scaled_row(im_in, x1, y1, ix, ox, next);
		for (yi = 0; yi < oy; yi++)
		{
			/* find endpoint of the current output row: */
			ci = si + add_whole;
			cifrac = sifrac + add_frac;
			if (cifrac >= oy)
			{
				ci++;
				cifrac -= oy;
			}

			/* take fraction of current input row (starting segment): */
			for (xi = 0; xi < ox; xi++)
			{
				temp[xi].red = next[xi].red * (oy - sifrac);
				temp[xi].green = next[xi].green * (oy - sifrac);
				temp[xi].blue = next[xi].blue * (oy - sifrac);
			}
			si++;

			/* add values for whole pixels: */
			while (si < ci)
			{
				get_scaled_row(im_in, x1, si, ix, ox, next);
				for (xi = 0; xi < ox; xi++)
				{
					temp[xi].red += next[xi].red * oy;
					temp[xi].green += next[xi].green * oy;
					temp[xi].blue += next[xi].blue * oy;
				}
				si++;
			}

			/* add fraction of current input row (ending segment): */
			if (yi < oy - 1)
			{
				/* only get next row if still in icon: */
				get_scaled_row(im_in, x1, si, ix, ox, next);
			}
			sifrac = cifrac;
			for (xi = 0; xi < ox; xi++)
			{
				temp[xi].red += next[xi].red * sifrac;
				temp[xi].green += next[xi].green * sifrac;
				temp[xi].blue += next[xi].blue * sifrac;
			}

			/* write row to output image: */
			put_rgb_scan(im_out, x2, y2 + yi, ox, div, temp);
		}
	}
}


/*
 * Rescale icons using sort of anti-aliasing technique.
 */
static GdkRGBImage *resize_tiles_smooth(
        GdkRGBImage *im,
        int ix,
        int iy,
        int ox,
        int oy)
{
	int width1, height1, width2, height2;
	int x1, x2, y1, y2;

	GdkRGBImage *tmp;

	/* Original size */
	width1 = im->width;
	height1 = im->height;

	/* Rescaled size */
	width2 = ox * width1 / ix;
	height2 = oy * height1 / iy;

	/* Allocate GdkRGBImage for resized tiles */
	tmp = gdk_rgb_image_new(width2, height2);

	/* Oops */
	if (tmp == NULL) return (NULL);

	/* Scale each icon */
	for (y1 = 0, y2 = 0; (y1 < height1) && (y2 < height2); y1 += iy, y2 += oy)
	{
		for (x1 = 0, x2 = 0; (x1 < width1) && (x2 < width2); x1 += ix, x2 += ox)
		{
			scale_icon(im, tmp, x1, y1, x2, y2,
			           ix, iy, ox, oy);
		}
	}

	return tmp;
}


/*
 * Steven Fuerst's tile resizing code
 * Taken from Z because I think the algorithm is cool.
 */

/* 24-bit version - GdkRGB uses 24 bit RGB data internally */
static void copy_pixels(
        int wid,
        int y,
        int offset,
        int *xoffsets,
        GdkRGBImage *old_image,
        GdkRGBImage *new_image)
{
	int i;

	/* Get source and destination */
	byte *src = &old_image->image[offset * old_image->width * 3];
	byte *dst = &new_image->image[y * new_image->width * 3];

	/* Copy to the image */
	for (i = 0; i < wid; i++)
	{
#ifdef SUPPORT_GAMMA

		if (gamma_table_ready)
		{
			*dst++ = gamma_table[src[3 * xoffsets[i]]];
			*dst++ = gamma_table[src[3 * xoffsets[i] + 1]];
			*dst++ = gamma_table[src[3 * xoffsets[i] + 2]];

			continue;
		}

#endif /* SUPPORT_GAMMA */

		*dst++ = src[3 * xoffsets[i]];
		*dst++ = src[3 * xoffsets[i] + 1];
		*dst++ = src[3 * xoffsets[i] + 2];
	}
}


#if 0

/* 32-bit version: it might be useful in the future */
static void copy_pixels(
        int wid,
        int y,
        int offset,
        int *xoffsets,
        GdkRGBImage *old_image,
        GdkRGBImage *new_image)
{
	int i;

	/* Get source and destination */
	byte *src = &old_image->image[offset * old_image->width * 4];
	byte *dst = &new_image->image[y * new_image->width * 4];

	/* Copy to the image */
	for (i = 0; i < wid; i++)
	{
		*dst++ = src[4 * xoffsets[i]];
		*dst++ = src[4 * xoffsets[i] + 1];
		*dst++ = src[4 * xoffsets[i] + 2];
		*dst++ = src[4 * xoffsets[i] + 3];
	}
}

#endif


/*
 * Resize ix * iy pixel tiles in old to ox * oy pixels
 * and return a new GdkRGBImage containing the resized tiles
 */
static GdkRGBImage *resize_tiles_fast(
        GdkRGBImage *old_image,
        int ix,
        int iy,
        int ox,
        int oy)
{
	GdkRGBImage *new_image;

	int old_wid, old_hgt;

	int new_wid, new_hgt;

	int add, remainder, rem_tot, offset;

	int *xoffsets;

	int i;


	/* Get the size of the old image */
	old_wid = old_image->width;
	old_hgt = old_image->height;

	/* Calculate the size of the new image */
	new_wid = (old_wid / ix) * ox;
	new_hgt = (old_hgt / iy) * oy;

	/* Allocate a GdkRGBImage to store resized tiles */
	new_image = gdk_rgb_image_new(new_wid, new_hgt);

	/* Paranoia */
	if (new_image == NULL) return (NULL);

	/* now begins the cool part of SF's code */

	/*
	 * Calculate an offsets table, so the transformation
	 * is faster.  This is much like the Bresenham algorithm
	 */

	/* Set up x offset table */
	C_MAKE(xoffsets, new_wid, int);

	/* Initialize line parameters */
	add = old_wid / new_wid;
	remainder = old_wid % new_wid;

	/* Start at left */
	offset = 0;

	/* Half-tile offset so 'line' is centered correctly */
	rem_tot = new_wid / 2;

	for (i = 0; i < new_wid; i++)
	{
		/* Store into the table */
		xoffsets[i] = offset;

		/* Move to next entry */
		offset += add;

		/* Take care of fractional part */
		rem_tot += remainder;
		if (rem_tot >= new_wid)
		{
			rem_tot -= new_wid;
			offset++;
		}
	}

	/* Scan each row */

	/* Initialize line parameters */
	add = old_hgt / new_hgt;
	remainder = old_hgt % new_hgt;

	/* Start at left */
	offset = 0;

	/* Half-tile offset so 'line' is centered correctly */
	rem_tot = new_hgt / 2;

	for (i = 0; i < new_hgt; i++)
	{
		/* Copy pixels to new image */
		copy_pixels(new_wid, i, offset, xoffsets, old_image, new_image);

		/* Move to next entry */
		offset += add;

		/* Take care of fractional part */
		rem_tot += remainder;
		if (rem_tot >= new_hgt)
		{
			rem_tot -= new_hgt;
			offset++;
		}
	}

	/* Free offset table */
	C_FREE(xoffsets, new_wid, int);

	return (new_image);
}


/*
 * Resize an image of ix * iy pixels and return a newly allocated
 * image of ox * oy pixels.
 */
static GdkRGBImage *resize_tiles(
        GdkRGBImage *im,
        int ix,
        int iy,
        int ox,
        int oy)
{
	GdkRGBImage *result;

	/*
	 * I hope we can always use this with GdkRGB, which uses a 5x5x5
	 * colour cube (125 colours) by default, and resort to dithering
	 * when it can't find good match there or expand the cube, so it
	 * works with 8bpp X servers.
	 */
	if (smooth_rescaling_request && (ix != ox || iy != oy))
	{
		result = resize_tiles_smooth(im, ix, iy, ox, oy);
	}

	/*
	 * Unless smoothing is requested by user, we use the fast
	 * resizing code.
	 */
	else
	{
		result = resize_tiles_fast(im, ix, iy, ox, oy);
	}

	/* Return rescaled tiles, or NULL */
	return (result);
}


/*
 * Tile loaders - XPM and BMP
 */

/*
 * A helper function for the XPM loader
 *
 * Read next string delimited by double quotes from
 * the input stream. Return TRUE on success, FALSE
 * if it finds EOF or buffer overflow.
 *
 * I never mean this to be generic, so its EOF and buffer
 * overflow behaviour is terribly stupid -- there are no
 * provisions for recovery.
 *
 * CAVEAT: treatment of backslash is not compatible with the standard
 * C usage XXX XXX XXX XXX
 */
static bool read_str(char *buf, u32b len, FILE *f)
{
	int c;

	/* Paranoia - Buffer too small */
	if (len <= 0) return (FALSE);

	/* Find " */
	while ((c = getc(f)) != '"')
	{
		/* Premature EOF */
		if (c == EOF) return (FALSE);
	}

	while (1)
	{
		/* Read next char */
		c = getc(f);

		/* Premature EOF */
		if (c == EOF) return (FALSE);

		/* Terminating " */
		if (c == '"') break;

		/* Escape */
		if (c == '\\')
		{
			/* Use next char */
			c = getc(f);

			/* Premature EOF */
			if (c == EOF) return (FALSE);
		}

		/* Store character in the buffer */
		*buf++ = c;

		/* Decrement count */
		len--;

		/* Buffer full - we have to place a NULL at the end */
		if (len <= 0) return (FALSE);
	}

	/* Make a C string if there's room left */
	if (len > 0) *buf = '\0';

	/* Success */
	return (TRUE);
}


/*
 * Remember pixel symbol to RGB colour mappings
 */

/*
 * I've forgot the formula, but I remember prime number yields
 * good results
 */
#define HASH_SIZE 19

typedef struct pal_type pal_type;

struct pal_type
{
	u32b str;
	u32b rgb;
	pal_type *next;
};


/*
 * A simple, slow and stupid XPM loader
 */
static GdkRGBImage *load_xpm(cptr filename)
{
	FILE *f;
	GdkRGBImage *img = NULL;
	int width, height, colours, chars;
	int i, j, k;
	bool ret;
	pal_type *pal = NULL;
	pal_type *head[HASH_SIZE];
	u32b buflen = 0;
	char *lin = NULL;
	char buf[1024];

	/* Build path to the XPM file */
	path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, filename);

	/* Open it */
	f = my_fopen(buf, "r");

	/* Oops */
	if (f == NULL) return (NULL);

	/* Read header */
	ret = read_str(buf, 1024, f);

	/* Oops */
	if (!ret)
	{
		/* Notify error */
		plog("Cannot find XPM header");

		/* Failure */
		goto oops;
	}

	/* Parse header */
	if (4 != sscanf(buf, "%d %d %d %d", &width, &height, &colours, &chars))
	{
		/* Notify error */
		plog("Bad XPM header");

		/* Failure */
		goto oops;
	}

	/*
	 * Paranoia - the code can handle upto four letters per pixel,
	 * but such large number of colours certainly requires a smarter
	 * symbol-to-colour mapping algorithm...
	 */
	if ((width <= 0) || (height <= 0) || (colours <= 0) || (chars <= 0) ||
	                (chars > 2))
	{
		/* Notify error */
		plog("Invalid width/height/depth");

		/* Failure */
		goto oops;
	}

	/* Allocate palette */
	C_MAKE(pal, colours, pal_type);

	/* Initialise hash table */
	for (i = 0; i < HASH_SIZE; i++) head[i] = NULL;

	/* Parse palette */
	for (i = 0; i < colours; i++)
	{
		u32b tmp;
		int h_idx;

		/* Read next string */
		ret = read_str(buf, 1024, f);

		/* Check I/O result */
		if (!ret)
		{
			/* Notify error */
			plog("EOF in palette");

			/* Failure */
			goto oops;
		}

		/* Clear symbol code */
		tmp = 0;

		/* Encode pixel symbol */
		for (j = 0; j < chars; j++)
		{
			tmp = (tmp << 8) | (buf[j] & 0xFF);
		}

		/* Remember it */
		pal[i].str = tmp;

		/* Skip spaces */
		while ((buf[j] == ' ') || (buf[j] == '\t')) j++;

		/* Verify 'c' */
		if (buf[j] != 'c')
		{
			/* Notify error */
			plog("No 'c' in palette definition");

			/* Failure */
			goto oops;
		}

		/* Advance cursor */
		j++;

		/* Skip spaces */
		while ((buf[j] == ' ') || (buf[j] == '\t')) j++;

		/* Hack - Assume 'None' */
		if (buf[j] == 'N')
		{
			/* Angband always uses black background */
			pal[i].rgb = 0x000000;
		}

		/* Read colour */
		else if ((1 != sscanf(&buf[j], "#%06lX", &tmp)) &&
		                (1 != sscanf(&buf[j], "#%06lx", &tmp)))
		{
			/* Notify error */
			plog("Badly formatted colour");

			/* Failure */
			goto oops;
		}

		/* Remember it */
		pal[i].rgb = tmp;

		/* Store it in hash table as well */
		h_idx = pal[i].str % HASH_SIZE;

		/* Link the entry */
		pal[i].next = head[h_idx];
		head[h_idx] = &pal[i];
	}

	/* Allocate image */
	img = gdk_rgb_image_new(width, height);

	/* Oops */
	if (img == NULL)
	{
		/* Notify error */
		plog("Cannot allocate image");

		/* Failure */
		goto oops;
	}

	/* Calculate buffer length */
	buflen = width * chars + 1;

	/* Allocate line buffer */
	C_MAKE(lin, buflen, char);

	/* For each row */
	for (i = 0; i < height; i++)
	{
		/* Read a row of image data */
		ret = read_str(lin, buflen, f);

		/* Oops */
		if (!ret)
		{
			/* Notify error */
			plog("EOF in middle of image data");

			/* Failure */
			goto oops;
		}

		/* For each column */
		for (j = 0; j < width; j++)
		{
			u32b tmp;
			pal_type *h_ptr;

			/* Clear encoded pixel */
			tmp = 0;

			/* Encode pixel symbol */
			for (k = 0; k < chars; k++)
			{
				tmp = (tmp << 8) | (lin[j * chars + k] & 0xFF);
			}

			/* Find colour */
			for (h_ptr = head[tmp % HASH_SIZE];
			                h_ptr != NULL;
			                h_ptr = h_ptr->next)
			{
				/* Found a match */
				if (h_ptr->str == tmp) break;
			}

			/* No match found */
			if (h_ptr == NULL)
			{
				/* Notify error */
				plog("Invalid pixel symbol");

				/* Failure */
				goto oops;
			}

			/* Draw it */
			gdk_rgb_image_put_pixel(
			        img,
			        j,
			        i,
			        h_ptr->rgb);
		}
	}

	/* Close file */
	my_fclose(f);

	/* Free line buffer */
	C_FREE(lin, buflen, char);

	/* Free palette */
	C_FREE(pal, colours, pal_type);

	/* Return result */
	return (img);

oops:

	/* Close file */
	my_fclose(f);

	/* Free image */
	if (img) gdk_rgb_image_destroy(img);

	/* Free line buffer */
	if (lin) C_FREE(lin, buflen, char);

	/* Free palette */
	if (pal) C_FREE(pal, colours, pal_type);

	/* Failure */
	return (NULL);
}


/*
 * A BMP loader, yet another duplication of maid-x11.c functions.
 *
 * Another duplication, again because of different image format and
 * avoidance of colour allocation.
 *
 * XXX XXX XXX XXX Should avoid using a propriatary and closed format.
 * Since it's much bigger than gif that was used before, why don't
 * we switch to XPM?  NetHack does.  Well, NH has always been much
 * closer to the GNU/Un*x camp and it's GPL'ed quite early...
 *
 * The names and naming convention are worse than the worst I've ever
 * seen, so I deliberately changed them to fit well with the rest of
 * the code. Or are they what xx calls them? If it's the case, there's
 * no reason to follow *their* words.
 */

/*
 * BMP file header
 */
typedef struct bmp_file_type bmp_file_type;

struct bmp_file_type
{
	u16b type;
	u32b size;
	u16b reserved1;
	u16b reserved2;
	u32b offset;
};


/*
 * BMP file information fields
 */
typedef struct bmp_info_type bmp_info_type;

struct bmp_info_type
{
	u32b size;
	u32b width;
	u32b height;
	u16b planes;
	u16b bit_count;
	u32b compression;
	u32b size_image;
	u32b x_pels_per_meter;
	u32b y_pels_per_meter;
	u32b colors_used;
	u32b color_importand;
};

/*
 * "RGBQUAD" type.
 */
typedef struct rgb_quad_type rgb_quad_type;

struct rgb_quad_type
{
	unsigned char b, g, r;
	unsigned char filler;
};


/*** Helper functions for system independent file loading. ***/

static byte get_byte(FILE *fff)
{
	/* Get a character, and return it */
	return (getc(fff) & 0xFF);
}

static void rd_byte(FILE *fff, byte *ip)
{
	*ip = get_byte(fff);
}

static void rd_u16b(FILE *fff, u16b *ip)
{
	(*ip) = get_byte(fff);
	(*ip) |= ((u16b)(get_byte(fff)) << 8);
}

static void rd_u32b(FILE *fff, u32b *ip)
{
	(*ip) = get_byte(fff);
	(*ip) |= ((u32b)(get_byte(fff)) << 8);
	(*ip) |= ((u32b)(get_byte(fff)) << 16);
	(*ip) |= ((u32b)(get_byte(fff)) << 24);
}


/*
 * Read a BMP file (a certain trademark nuked)
 *
 * This function replaces the old ReadRaw and RemapColors functions.
 *
 * Assumes that the bitmap has a size such that no padding is needed in
 * various places.  Currently only handles bitmaps with 3 to 256 colors.
 */
GdkRGBImage *load_bmp(cptr filename)
{
	FILE *f;

	char path[1024];

	bmp_file_type file_hdr;
	bmp_info_type info_hdr;

	GdkRGBImage *result = NULL;

	int ncol;

	int i;

	u32b x, y;

	guint32 colour_pixels[256];


	/* Build the path to the bmp file */
	path_build(path, 1024, ANGBAND_DIR_XTRA_GRAF, filename);

	/* Open the BMP file */
	f = fopen(path, "r");

	/* No such file */
	if (f == NULL)
	{
		return (NULL);
	}

	/* Read the "bmp_file_type" */
	rd_u16b(f, &file_hdr.type);
	rd_u32b(f, &file_hdr.size);
	rd_u16b(f, &file_hdr.reserved1);
	rd_u16b(f, &file_hdr.reserved2);
	rd_u32b(f, &file_hdr.offset);

	/* Read the "bmp_info_type" */
	rd_u32b(f, &info_hdr.size);
	rd_u32b(f, &info_hdr.width);
	rd_u32b(f, &info_hdr.height);
	rd_u16b(f, &info_hdr.planes);
	rd_u16b(f, &info_hdr.bit_count);
	rd_u32b(f, &info_hdr.compression);
	rd_u32b(f, &info_hdr.size_image);
	rd_u32b(f, &info_hdr.x_pels_per_meter);
	rd_u32b(f, &info_hdr.y_pels_per_meter);
	rd_u32b(f, &info_hdr.colors_used);
	rd_u32b(f, &info_hdr.color_importand);

	/* Verify the header */
	if (feof(f) ||
	                (file_hdr.type != 19778) ||
	                (info_hdr.size != 40))
	{
		plog(format("Incorrect BMP file format %s", filename));
		fclose(f);
		return (NULL);
	}

	/*
	 * The two headers above occupy 54 bytes total
	 * The "offset" field says where the data starts
	 * The "colors_used" field does not seem to be reliable
	 */

	/* Compute number of colors recorded */
	ncol = (file_hdr.offset - 54) / 4;

	for (i = 0; i < ncol; i++)
	{
		rgb_quad_type clr;

		/* Read an "rgb_quad_type" */
		rd_byte(f, &clr.b);
		rd_byte(f, &clr.g);
		rd_byte(f, &clr.r);
		rd_byte(f, &clr.filler);

		/* Remember the pixel */
		colour_pixels[i] = (clr.r << 16) | (clr.g << 8) | (clr.b);
	}

	/* Allocate GdkRGBImage large enough to store the image */
	result = gdk_rgb_image_new(info_hdr.width, info_hdr.height);

	/* Failure */
	if (result == NULL)
	{
		fclose(f);
		return (NULL);
	}

	for (y = 0; y < info_hdr.height; y++)
	{
		u32b y2 = info_hdr.height - y - 1;

		for (x = 0; x < info_hdr.width; x++)
		{
			int ch = getc(f);

			/* Verify not at end of file XXX XXX */
			if (feof(f))
			{
				plog(format("Unexpected end of file in %s", filename));
				gdk_rgb_image_destroy(result);
				fclose(f);
				return (NULL);
			}

			if (info_hdr.bit_count == 24)
			{
				int c3, c2 = getc(f);

				/* Verify not at end of file XXX XXX */
				if (feof(f))
				{
					plog(format("Unexpected end of file in %s", filename));
					gdk_rgb_image_destroy(result);
					fclose(f);
					return (NULL);
				}

				c3 = getc(f);

				/* Verify not at end of file XXX XXX */
				if (feof(f))
				{
					plog(format("Unexpected end of file in %s", filename));
					gdk_rgb_image_destroy(result);
					fclose(f);
					return (NULL);
				}

				/* Draw the pixel */
				gdk_rgb_image_put_pixel(
				        result,
				        x,
				        y2,
				        (ch << 16) | (c2 << 8) | (c3));
			}
			else if (info_hdr.bit_count == 8)
			{
				gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch]);
			}
			else if (info_hdr.bit_count == 4)
			{
				gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch / 16]);
				x++;
				gdk_rgb_image_put_pixel(result, x, y2, colour_pixels[ch % 16]);
			}
			else
			{
				/* Technically 1 bit is legal too */
				plog(format("Illegal bit count %d in %s",
				            info_hdr.bit_count, filename));
				gdk_rgb_image_destroy(result);
				fclose(f);
				return (NULL);
			}
		}
	}

	fclose(f);

	return result;
}


/*
 * Try to load an XPM file, or a BMP file if it fails
 *
 * Choice of file format may better be made yet another option XXX
 */
static GdkRGBImage *load_tiles(cptr basename)
{
	char buf[32];
	GdkRGBImage *img;

	/* build xpm file name */
	strnfmt(buf, 32, "%s.xpm", basename);

	/* Try to load it */
	img = load_xpm(buf);

	/* OK */
	if (img) return (img);

	/* Try again for a bmp file */
	strnfmt(buf, 32, "%s.bmp", basename);

	/* Try loading it */
	img = load_bmp(buf);

	/* Return result, success or failure */
	return (img);
}


/*
 * Free all tiles and graphics buffers associated with windows
 *
 * This is conspirator of graf_init() below, sharing its inefficiency
 */
static void graf_nuke()
{
	int i;

	term_data *td;


	/* Nuke all terms */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Access term_data structure */
		td = &data[i];

		/* Disable graphics */
		td->t.higher_pict = FALSE;

		/* Free previously allocated tiles */
		if (td->tiles) gdk_rgb_image_destroy(td->tiles);

		/* Forget pointer */
		td->tiles = NULL;

# ifdef USE_TRANSPARENCY

		/* Free previously allocated transparency buffer */
		if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf);

		/* Forget stale pointer */
		td->trans_buf = NULL;

# endif  /* USE_TRANSPARENCY */

	}
}


/*
 * Load tiles, scale them to current font size, and store a pointer
 * to them in a term_data structure for each term.
 *
 * XXX XXX XXX This is a terribly stupid quick hack.
 *
 * XXX XXX XXX Windows using the same font should share resized tiles
 */
static bool graf_init(
        cptr filename,
        int tile_wid,
        int tile_hgt)
{
	term_data *td;

	bool result;

	GdkRGBImage *raw_tiles, *scaled_tiles;

# ifdef USE_TRANSPARENCY
	GdkRGBImage *buffer;
# endif  /* USE_TRANSPARENCY */

	int i;


	/* Paranoia */
	if (filename == NULL) return (FALSE);

	/* Load tiles */
	raw_tiles = load_tiles(filename);

	/* Oops */
	if (raw_tiles == NULL)
	{
		/* Clean up */
		graf_nuke();

		/* Failure */
		return (FALSE);
	}

	/* Calculate and remember numbers of rows and columns */
	tile_rows = raw_tiles->height / tile_hgt;
	tile_cols = raw_tiles->width / tile_wid;

	/* Be optimistic */
	result = TRUE;


	/*
	 * (Re-)init each term
	 * XXX It might help speeding this up to avoid doing so if a window
	 * doesn't need graphics (e.g. inventory/equipment and message recall).
	 */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Access term_data */
		td = &data[i];

		/* Shouldn't waste anything for unused terms */
		if (!td->shown) continue;

		/* Enable graphics */
		td->t.higher_pict = TRUE;

		/* See if we need rescaled tiles XXX */
		if ((td->tiles == NULL) ||
		                (td->tiles->width != td->tile_wid * tile_cols) ||
		                (td->tiles->height != td->tile_hgt * tile_rows))
		{
			/* Free old tiles if present */
			if (td->tiles) gdk_rgb_image_destroy(td->tiles);

			/* Forget pointer */
			td->tiles = NULL;

			/* Scale the tiles to current font bounding rect */
			scaled_tiles = resize_tiles(
			                       raw_tiles,
			                       tile_wid, tile_hgt,
			                       td->tile_wid, td->tile_hgt);

			/* Oops */
			if (scaled_tiles == NULL)
			{
				/* Failure */
				result = FALSE;

				break;
			}

			/* Store it */
			td->tiles = scaled_tiles;
		}

# ifdef USE_TRANSPARENCY

		/* See if we have to (re)allocate a new buffer XXX */
		if ((td->trans_buf == NULL) ||
		                (td->trans_buf->width != td->tile_wid) ||
		                (td->trans_buf->height != td->tile_hgt))
		{
			/* Free old buffer if present */
			if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf);

			/* Forget pointer */
			td->trans_buf = NULL;

			/* Allocate a new buffer */
			buffer = gdk_rgb_image_new(td->tile_wid, td->tile_hgt);

			/* Oops */
			if (buffer == NULL)
			{
				/* Failure */
				result = FALSE;

				break;
			}

			/* Store it */
			td->trans_buf = buffer;
		}

		/*
		 * Giga-Hack - assume top left corner of 0x86/0x80 should be
		 * in the background colour XXX XXX XXX XXX
		 */
		td->bg_pixel = gdk_rgb_image_get_pixel(
		                       raw_tiles,
		                       0,
		                       tile_hgt * 6);

# endif  /* USE_TRANSPARENCY */

	}


	/* Alas, we need to free wasted images */
	if (result == FALSE) graf_nuke();

	/* We don't need the raw image any longer */
	gdk_rgb_image_destroy(raw_tiles);

	/* Report success or failure */
	return (result);
}


/*
 * React to various changes in graphics mode settings
 *
 * It is *not* a requirement for tiles to have same pixel width and height.
 * The program can work with any conbinations of graf_wid and graf_hgt
 * (oops, they must be representable by u16b), as long as they are lesser
 * or equal to 32 if you use smooth rescaling.
 */
static void init_graphics(void)
{
	cptr tile_name;

	u16b graf_wid = 0, graf_hgt = 0;


	/* No graphics requests are made - Can't this be simpler? XXX XXX */
	if ((graf_mode_request == graf_mode) &&
	                (smooth_rescaling_request == smooth_rescaling) &&
	                !resize_request) return;

	/* Prevent further unsolicited reaction */
	resize_request = FALSE;


	/* Dispose unusable old tiles - awkward... XXX XXX */
	if ((graf_mode_request == GRAF_MODE_NONE) ||
	                (graf_mode_request != graf_mode) ||
	                (smooth_rescaling_request != smooth_rescaling)) graf_nuke();


	/* Setup parameters according to request */
	switch (graf_mode_request)
	{
		/* ASCII - no graphics whatsoever */
	default:
	case GRAF_MODE_NONE:
		{
			tile_name = NULL;
			use_graphics = arg_graphics = FALSE;

			break;
		}

		/*
		 * 8x8 tiles originally collected for the Amiga port
		 * from several contributers by Lars Haugseth, converted
		 * to 256 colours and expanded by the Z devteam
		 *
		 * Use the "old" tile assignments
		 *
		 * Dawnmist is working on it for ToME
		 */
	case GRAF_MODE_OLD:
		{
			tile_name = "8x8";
			graf_wid = graf_hgt = 8;
			ANGBAND_GRAF = "old";
			use_graphics = arg_graphics = TRUE;

			break;
		}

		/*
		 * Adam Bolt's 16x16 tiles
		 * "new" tile assignments
		 * It is updated for ToME by Andreas Koch
		 */
	case GRAF_MODE_NEW:
		{
			tile_name = "16x16";
			graf_wid = graf_hgt = 16;
			ANGBAND_GRAF = "new";
			use_graphics = arg_graphics = TRUE;

			break;
		}
	}


	/* load tiles and set them up if tiles are requested */
	if ((graf_mode_request != GRAF_MODE_NONE) &&
	                !graf_init(tile_name, graf_wid, graf_hgt))
	{
		/* Oops */
		plog("Cannot initialize graphics");

		/* reject requests */
		graf_mode_request = GRAF_MODE_NONE;
		smooth_rescaling_request = smooth_rescaling;

		/* reset graphics flags */
		use_graphics = arg_graphics = FALSE;
	}

	/* Update current graphics mode */
	graf_mode = graf_mode_request;
	smooth_rescaling = smooth_rescaling_request;

	/* Reset visuals */
#ifndef ANG281_RESET_VISUALS
	reset_visuals(TRUE);
#else
	reset_visuals();
#endif /* !ANG281_RESET_VISUALS */
}

#endif /* USE_GRAPHICS */




/**** Term package support routines ****/


/*
 * Free data used by a term
 */
static void Term_nuke_gtk(term *t)
{
	term_data *td = t->data;


	/* Free name */
	if (td->name) string_free(td->name);

	/* Forget it */
	td->name = NULL;

	/* Free font */
	if (td->font) gdk_font_unref(td->font);

	/* Forget it */
	td->font = NULL;

	/* Free backing store */
	if (td->backing_store) gdk_pixmap_unref(td->backing_store);

	/* Forget it too */
	td->backing_store = NULL;

#ifdef USE_GRAPHICS

	/* Free tiles */
	if (td->tiles) gdk_rgb_image_destroy(td->tiles);

	/* Forget pointer */
	td->tiles = NULL;

# ifdef USE_TRANSPARENCY

	/* Free transparency buffer */
	if (td->trans_buf) gdk_rgb_image_destroy(td->trans_buf);

	/* Amnesia */
	td->trans_buf = NULL;

# endif  /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */
}


/*
 * Erase the whole term.
 */
static errr Term_clear_gtk(void)
{
	term_data *td = (term_data*)(Term->data);


	/* Don't draw to hidden windows */
	if (!td->shown) return (0);

	/* Paranoia */
	g_assert(td->drawing_area->window != 0);

	/* Clear the area */
	gdk_draw_rectangle(
	        TERM_DATA_DRAWABLE(td),
	        td->drawing_area->style->black_gc,
	        1,
	        0,
	        0,
	        td->cols * td->font_wid,
	        td->rows * td->font_hgt);

	/* Copy image from backing store if present */
	TERM_DATA_REFRESH(td, 0, 0, td->cols, td->rows);

	/* Success */
	return (0);
}


/*
 * Erase some characters.
 */
static errr Term_wipe_gtk(int x, int y, int n)
{
	term_data *td = (term_data*)(Term->data);


	/* Don't draw to hidden windows */
	if (!td->shown) return (0);

	/* Paranoia */
	g_assert(td->drawing_area->window != 0);

	/* Fill the area with the background colour */
	gdk_draw_rectangle(
	        TERM_DATA_DRAWABLE(td),
	        td->drawing_area->style->black_gc,
	        TRUE,
	        x * td->font_wid,
	        y * td->font_hgt,
	        n * td->font_wid,
	        td->font_hgt);

	/* Copy image from backing store if present */
	TERM_DATA_REFRESH(td, x, y, n, 1);

	/* Success */
	return (0);
}


/*
 * Draw some textual characters.
 */
static errr Term_text_gtk(int x, int y, int n, byte a, cptr s)
{
	term_data *td = (term_data*)(Term->data);


	/* Don't draw to hidden windows */
	if (!td->shown) return (0);

	/* Paranoia */
	g_assert(td->drawing_area->window != 0);

	/* Set foreground colour */
	term_data_set_fg(td, a);

	/* Clear the line */
	Term_wipe_gtk(x, y, n);

	/* Draw the text to the window */
	gdk_draw_text(
	        TERM_DATA_DRAWABLE(td),
	        td->font,
	        td->gc,
	        x * td->font_wid,
	        td->font->ascent + y * td->font_hgt,
	        s,
	        n);

	/* Copy image from backing store if present */
	TERM_DATA_REFRESH(td, x, y, n, 1);

	/* Success */
	return (0);
}


/*
 * Draw software cursor at (x, y)
 */
static errr Term_curs_gtk(int x, int y)
{
	term_data *td = (term_data*)(Term->data);
	int cells = 1;


	/* Don't draw to hidden windows */
	if (!td->shown) return (0);

	/* Paranoia */
	g_assert(td->drawing_area->window != 0);

	/* Set foreground colour */
	term_data_set_fg(td, TERM_YELLOW);

#ifdef USE_DOUBLE_TILES

	/* Mogami's bigtile patch */

	/* Adjust it if wide tiles are requested */
	if (use_bigtile &&
	                (x + 1 < Term->wid) &&
	                (Term->old->a[y][x + 1] == 255))
	{
		cells = 2;
	}

#endif /* USE_DOUBLE_TILES */

	/* Draw the software cursor */
	gdk_draw_rectangle(
	        TERM_DATA_DRAWABLE(td),
	        td->gc,
	        FALSE,
	        x * td->font_wid,
	        y * td->font_hgt,
	        td->font_wid * cells - 1,
	        td->font_hgt - 1);

	/* Copy image from backing store if present */
	TERM_DATA_REFRESH(td, x, y, cells, 1);

	/* Success */
	return (0);
}


#ifdef USE_GRAPHICS

# ifdef USE_TRANSPARENCY

/*
 * XXX XXX Low level graphics helper
 * Draw a tile at (s_x, s_y) over one at (t_x, t_y) and store the
 * result in td->trans_buf
 *
 * XXX XXX Even if CPU's are faster than necessary these days,
 * this should be made inline. Or better, there should be an API
 * to take advantage of graphics hardware. They almost always have
 * assortment of builtin bitblt's...
 */
static void overlay_tiles_2(
        term_data *td,
        int s_x, int s_y,
        int t_x, int t_y)
{
	guint32 pix;
	int x, y;


	/* Process each row */
	for (y = 0; y < td->tile_hgt; y++)
	{
		/* Process each column */
		for (x = 0; x < td->tile_wid; x++)
		{
			/* Get an overlay pixel */
			pix = gdk_rgb_image_get_pixel(td->tiles, s_x + x, s_y + y);

			/* If it's in background color, use terrain instead */
			if (pix == td->bg_pixel)
				pix = gdk_rgb_image_get_pixel(td->tiles, t_x + x, t_y + y);

			/* Store the result in trans_buf */
			gdk_rgb_image_put_pixel(td->trans_buf, x, y, pix);
		}
	}
}


# ifdef USE_EGO_GRAPHICS

/*
 * XXX XXX Low level graphics helper
 * Draw a tile at (e_x, e_y) over one at (s_x, s_y) over another one
 * at (t_x, t_y) and store the result in td->trans_buf
 *
 * XXX XXX The same comment applies as that for the above...
 */
static void overlay_tiles_3(
        term_data *td,
        int e_x, int e_y,
        int s_x, int s_y,
        int t_x, int t_y)
{
	guint32 pix;
	int x, y;


	/* Process each row */
	for (y = 0; y < td->tile_hgt; y++)
	{
		/* Process each column */
		for (x = 0; x < td->tile_wid; x++)
		{
			/* Get an overlay pixel */
			pix = gdk_rgb_image_get_pixel(td->tiles, e_x + x, e_y + y);

			/*
			 * If it's background colour, try to use one from
			 * the second layer
			 */
			if (pix == td->bg_pixel)
				pix = gdk_rgb_image_get_pixel(td->tiles, s_x + x, s_y + y);

			/*
			 * If it's background colour again, fall back to
			 * the terrain layer
			 */
			if (pix == td->bg_pixel)
				pix = gdk_rgb_image_get_pixel(td->tiles, t_x + x, t_y + y);

			/* Store the pixel in trans_buf */
			gdk_rgb_image_put_pixel(td->trans_buf, x, y, pix);
		}
	}
}

# endif  /* USE_EGO_GRAPHICS */

# endif  /* USE_TRANSPARENCY */


/*
 * Low level graphics (Assumes valid input)
 *
 * Draw "n" tiles/characters starting at (x,y)
 */
# ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_gtk(
        int x, int y, int n,
        const byte *ap, const char *cp,
        const byte *tap, const char *tcp,
        const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_gtk(
        int x, int y, int n,
        const byte *ap, const char *cp,
        const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
# else /* USE_TRANSPARENCY */
static errr Term_pict_gtk(
        int x, int y, int n,
        const byte *ap, const char *cp)
# endif  /* USE_TRANSPARENCY */
{
	term_data *td = (term_data*)(Term->data);

	int i;

	int d_x, d_y;

# ifdef USE_DOUBLE_TILES

	/* Hack - remember real number of columns affected XXX XXX XXX */
	int cols;

# endif  /* USE_DOUBLE_TILES */


	/* Don't draw to hidden windows */
	if (!td->shown) return (0);

	/* Paranoia */
	g_assert(td->drawing_area->window != 0);

	/* Top left corner of the destination rect */
	d_x = x * td->font_wid;
	d_y = y * td->font_hgt;


# ifdef USE_DOUBLE_TILES

	/* Reset column counter */
	cols = 0;

# endif  /* USE_DOUBLE_TILES */

	/* Scan the input */
	for (i = 0; i < n; i++)
	{
		byte a;
		char c;
		int s_x, s_y;

# ifdef USE_TRANSPARENCY

		byte ta;
		char tc;
		int t_x, t_y;

# ifdef USE_EGO_GRAPHICS

		byte ea;
		char ec;
		int e_x = 0, e_y = 0;
		bool has_overlay;

# endif  /* USE_EGO_GRAPHICS */

# endif  /* USE_TRANSPARENCY */


		/* Grid attr/char */
		a = *ap++;
		c = *cp++;

# ifdef USE_TRANSPARENCY

		/* Terrain attr/char */
		ta = *tap++;
		tc = *tcp++;

# ifdef USE_EGO_GRAPHICS

		/* Overlay attr/char */
		ea = *eap++;
		ec = *ecp++;
		has_overlay = (ea && ec);

# endif  /* USE_EGO_GRAPHICS */

# endif  /* USE_TRANSPARENCY */

		/* Row and Col */
		s_y = (((byte)a & 0x7F) % tile_rows) * td->tile_hgt;
		s_x = (((byte)c & 0x7F) % tile_cols) * td->tile_wid;

# ifdef USE_TRANSPARENCY

		/* Terrain Row and Col */
		t_y = (((byte)ta & 0x7F) % tile_rows) * td->tile_hgt;
		t_x = (((byte)tc & 0x7F) % tile_cols) * td->tile_wid;

# ifdef USE_EGO_GRAPHICS

		/* Overlay Row and Col */
		if (has_overlay)
		{
			e_y = (((byte)ea & 0x7F) % tile_rows) * td->tile_hgt;
			e_x = (((byte)ec & 0x7F) % tile_cols) * td->tile_wid;
		}

# endif  /* USE_EGO_GRAPHICS */


# ifdef USE_DOUBLE_TILES

		/* Mogami's bigtile patch */

		/* Hack -- a filler for wide tile */
		if (use_bigtile && (a == 255))
		{
			/* Advance */
			d_x += td->font_wid;

			/* Ignore */
			continue;
		}

# endif  /* USE_DOUBLE_TILES */

		/* Optimise the common case: terrain == obj/mons */
		if (!use_transparency ||
		                ((s_x == t_x) && (s_y == t_y)))
		{

# ifdef USE_EGO_GRAPHICS

			/* The simplest possible case - no overlay */
			if (!has_overlay)
			{
				/* Draw the tile */
				gdk_draw_rgb_image_2(
				        TERM_DATA_DRAWABLE(td), td->gc, td->tiles,
				        s_x, s_y,
				        d_x, d_y,
				        td->tile_wid, td->tile_hgt);
			}

			/* We have to draw overlay... */
			else
			{
				/* Overlay */
				overlay_tiles_2(td, e_x, e_y, s_x, s_y);

				/* And draw the result */
				gdk_draw_rgb_image_2(
				        TERM_DATA_DRAWABLE(td), td->gc, td->trans_buf,
				        0, 0,
				        d_x, d_y,
				        td->tile_wid, td->tile_hgt);

				/* Hack -- Prevent potential display problem */
				gdk_flush();
			}

# else /* USE_EGO_GRAPHICS */

			/* Draw the tile */
			gdk_draw_rgb_image_2(
			        TERM_DATA_DRAWABLE(td), td->gc, td->tiles,
			        s_x, s_y,
			        d_x, d_y,
			        td->tile_wid, td->tile_hgt);

# endif  /* USE_EGO_GRAPHICS */

		}

		/*
		 * Since there's no masking bitblt in X,
		 * we have to do that manually...
		 */
		else
		{

# ifndef USE_EGO_GRAPHICS

			/* Draw mon/PC/obj over terrain */
			overlay_tiles_2(td, s_x, s_y, t_x, t_y);

# else /* !USE_EGO_GRAPHICS */

			/* No overlay */
			if (!has_overlay)
			{
				/* Build terrain + masked overlay image */
				overlay_tiles_2(td, s_x, s_y, t_x, t_y);
			}

			/* With overlay */
			else
			{
				/* Ego over mon/PC over terrain */
				overlay_tiles_3(td, e_x, e_y, s_x, s_y,
				                t_x, t_y);
			}

# endif  /* !USE_EGO_GRAPHICS */

			/* Draw it */
			gdk_draw_rgb_image_2(
			        TERM_DATA_DRAWABLE(td), td->gc, td->trans_buf,
			        0, 0,
			        d_x, d_y,
			        td->tile_wid, td->tile_hgt);

			/* Hack -- Prevent potential display problem */
			gdk_flush();
		}

# else /* USE_TRANSPARENCY */

		/* Draw the tile */
		gdk_draw_rgb_image_2(
		        TERM_DATA_DRAWABLE(td), td->gc, td->tiles,
		        s_x, s_y,
		        d_x, d_y,
		        td->tile_wid, td->tile_hgt);

# endif  /* USE_TRANSPARENCY */

		/*
		 * Advance x-coordinate - wide font fillers are taken care of
		 * before entering the tile drawing code.
		 */
		d_x += td->font_wid;

# ifdef USE_DOUBLE_TILES

		/* Add up *real* number of columns updated XXX XXX XXX */
		cols += use_bigtile ? 2 : 1;

# endif  /* USE_DOUBLE_TILES */
	}

# ifndef USE_DOUBLE_TILES

	/* Copy image from backing store if present */
	TERM_DATA_REFRESH(td, x, y, n, 1);

# else

	/* Copy image from backing store if present */
	TERM_DATA_REFRESH(td, x, y, cols, 1);

# endif  /* USE_DOUBLE_TILES */

	/* Success */
	return (0);
}

#endif /* USE_GRAPHICS */


/*
 * Process an event, if there's none block when wait is set true,
 * return immediately otherwise.
 */
static void CheckEvent(bool wait)
{
	/* Process an event */
	(void)gtk_main_iteration_do(wait);
}


/*
 * Process all pending events (without blocking)
 */
static void DrainEvents(void)
{
	while (gtk_events_pending())
		gtk_main_iteration();
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_gtk(int n, int v)
{
	/* Handle a subset of the legal requests */
	switch (n)
	{
		/* Make a noise */
	case TERM_XTRA_NOISE:
		{
			/* Beep */
			gdk_beep();

			/* Success */
			return (0);
		}

		/* Flush the output */
	case TERM_XTRA_FRESH:
		{
			/* Flush pending X requests - almost always no-op */
			gdk_flush();

			/* Success */
			return (0);
		}

		/* Process random events */
	case TERM_XTRA_BORED:
		{
			/* Process a pending event if there's one */
			CheckEvent(FALSE);

			/* Success */
			return (0);
		}

		/* Process Events */
	case TERM_XTRA_EVENT:
		{
			/* Process an event */
			CheckEvent(v);

			/* Success */
			return (0);
		}

		/* Flush the events */
	case TERM_XTRA_FLUSH:
		{
			/* Process all pending events */
			DrainEvents();

			/* Success */
			return (0);
		}

		/* Handle change in the "level" */
	case TERM_XTRA_LEVEL:
		return (0);

		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		return (Term_clear_gtk());

		/* Delay for some milliseconds */
	case TERM_XTRA_DELAY:
		{
			/* sleep for v milliseconds */
			usleep(v * 1000);

			/* Done */
			return (0);
		}

		/* Get Delay of some milliseconds */
	case TERM_XTRA_GET_DELAY:
		{
			int ret;
			struct timeval tv;

			ret = gettimeofday(&tv, NULL);
			Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);

			return ret;
		}

		/* Subdirectory scan */
	case TERM_XTRA_SCANSUBDIR:
		{
			DIR *directory;
			struct dirent *entry;

			scansubdir_max = 0;

			directory = opendir(scansubdir_dir);
			if (!directory) return (1);

			while ((entry = readdir(directory)) != NULL)
			{
				char file[PATH_MAX + NAME_MAX + 2];
				struct stat filedata;

				file[PATH_MAX + NAME_MAX] = 0;
				strncpy(file, scansubdir_dir, PATH_MAX);
				strncat(file, "/", 2);
				strncat(file, entry->d_name, NAME_MAX);
				if ((stat(file, &filedata) == 0) && S_ISDIR(filedata.st_mode))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] =
					        string_make(entry->d_name);
					++scansubdir_max;
				}
			}
		}

		/* Rename main window */
	case TERM_XTRA_RENAME_MAIN_WIN: gtk_window_set_title(GTK_WINDOW(data[0].window), angband_term_name[0]); return (0);

		/* React to changes */
	case TERM_XTRA_REACT:
		{
			/* (re-)init colours */
			init_colours();

#ifdef USE_GRAPHICS

			/* Initialise graphics */
			init_graphics();

#endif /* USE_GRAPHICS */

			/* Success */
			return (0);
		}
	}

	/* Unknown */
	return (1);
}




/**** Event handlers ****/


/*
 * Operation overkill
 * Verify term size info - just because the other windowing ports have this
 */
static void term_data_check_size(term_data *td)
{
	/* Enforce minimum window size */
	if (td == &data[0])
	{
		if (td->cols < 80) td->cols = 80;
		if (td->rows < 24) td->rows = 24;
	}
	else
	{
		if (td->cols < 1) td->cols = 1;
		if (td->rows < 1) td->rows = 1;
	}

	/* Paranoia - Enforce maximum size allowed by the term package */
	if (td->cols > 255) td->cols = 255;
	if (td->rows > 255) td->rows = 255;
}


/*
 * Enforce these size constraints within Gtk/Gdk
 * These increments are nice, because you can see numbers of rows/cols
 * while you resize a term.
 */
static void term_data_set_geometry_hints(term_data *td)
{
	GdkGeometry geometry;

	/* Resizing is character size oriented */
	geometry.width_inc = td->font_wid;
	geometry.height_inc = td->font_hgt;

	/* Enforce minimum size - the main window */
	if (td == &data[0])
	{
		geometry.min_width = 80 * td->font_wid;
		geometry.min_height = 24 * td->font_hgt;
	}

	/* Subwindows can be much smaller */
	else
	{
		geometry.min_width = 1 * td->font_wid;
		geometry.min_height = 1 * td->font_hgt;
	}

	/* Enforce term package's hard limit */
	geometry.max_width = 255 * td->font_wid;
	geometry.max_height = 255 * td->font_hgt;

	/* This affects geometry display while we resize a term */
	geometry.base_width = 0;
	geometry.base_height = 0;

	/* Give the window a new set of resizing hints */
	gtk_window_set_geometry_hints(GTK_WINDOW(td->window),
	                              td->drawing_area, &geometry,
	                              GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE
	                              | GDK_HINT_BASE_SIZE | GDK_HINT_RESIZE_INC);
}


/*
 * (Re)allocate a backing store for the window
 */
static void term_data_set_backing_store(term_data *td)
{
	/* Paranoia */
	if (!GTK_WIDGET_REALIZED(td->drawing_area)) return;

	/* Free old one if we cannot use it any longer */
	if (td->backing_store)
	{
		int wid, hgt;

		/* Retrive the size of the old backing store */
		gdk_window_get_size(td->backing_store, &wid, &hgt);

		/* Continue using it if it's the same with desired size */
		if (use_backing_store &&
		                (td->cols * td->font_wid == wid) &&
		                (td->rows * td->font_hgt == hgt)) return;

		/* Free it */
		gdk_pixmap_unref(td->backing_store);

		/* Forget the pointer */
		td->backing_store = NULL;
	}

	/* See user preference */
	if (use_backing_store)
	{
		/* Allocate new backing store */
		td->backing_store = gdk_pixmap_new(
		                            td->drawing_area->window,
		                            td->cols * td->font_wid,
		                            td->rows * td->font_hgt,
		                            -1);

		/* Oops - but we can do without it */
		g_return_if_fail(td->backing_store != NULL);

		/* Clear the backing store */
		gdk_draw_rectangle(
		        td->backing_store,
		        td->drawing_area->style->black_gc,
		        TRUE,
		        0,
		        0,
		        td->cols * td->font_wid,
		        td->rows * td->font_hgt);
	}
}


/*
 * Save game only when it's safe to do so
 */
static void save_game_gtk(void)
{
	/* We have nothing to save, yet */
	if (!game_in_progress || !character_generated) return;

	/* It isn't safe to save game now */
	if (!inkey_flag || !can_save)
	{
		plog("You may not save right now.");
		return;
	}

	/* Hack -- Forget messages */
	msg_flag = FALSE;

	/* Save the game */
#ifdef ZANG_SAVE_GAME
	/* Also for OAngband - the parameter tells if it's autosave */
	do_cmd_save_game(FALSE);
#else
/* Everything else */
	do_cmd_save_game();
#endif /* ZANG_SAVE_GAME */
}


/*
 * Display message in a modal dialog
 */
static void gtk_message(cptr msg)
{
	GtkWidget *dialog, *label, *ok_button;

	/* Create the widgets */
	dialog = gtk_dialog_new();
	g_assert(dialog != NULL);

	label = gtk_label_new(msg);
	g_assert(label != NULL);

	ok_button = gtk_button_new_with_label("OK");
	g_assert(ok_button != NULL);

	/* Ensure that the dialogue box is destroyed when OK is clicked */
	gtk_signal_connect_object(
	        GTK_OBJECT(ok_button),
	        "clicked",
	        GTK_SIGNAL_FUNC(gtk_widget_destroy),
	        (gpointer)dialog);
	gtk_container_add(
	        GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
	        ok_button);

	/* Add the label, and show the dialog */
	gtk_container_add(
	        GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
	        label);

	/* And make it modal */
	gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);

	/* Show the dialog */
	gtk_widget_show_all(dialog);
}


/*
 * Hook to tell the user something important
 */
static void hook_plog(cptr str)
{
	/* Warning message */
	gtk_message(str);
}


/*
 * Process File-Quit menu command
 */
static void quit_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	/* Save current game */
	save_game_gtk();

	/* It's done */
	quit(NULL);
}


/*
 * Process File-Save menu command
 */
static void save_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	/* Save current game */
	save_game_gtk();
}


/*
 * Handle destruction of the Angband window
 */
static void destroy_main_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	/* This allows for cheating, but... */
	quit(NULL);
}


/*
 * Handle destruction of Subwindows
 */
static void destroy_sub_event_handler(
        GtkWidget *window,
        gpointer user_data)
{
	/* Hide the window */
	gtk_widget_hide_all(window);
}


#ifndef SAVEFILE_SCREEN

/*
 * Process File-New menu command
 */
static void new_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	if (game_in_progress)
	{
		plog("You can't start a new game while you're still playing!");
		return;
	}

	/* The game is in progress */
	game_in_progress = TRUE;

	/* Flush input */
	Term_flush();

	/* Play game */
	play_game(TRUE);

	/* Houseclearing */
	cleanup_angband();

	/* Done */
	quit(NULL);
}

#endif /* !SAVEFILE_SCREEN */


/*
 * Load fond specified by an XLFD fontname and
 * set up related term_data members
 */
static void load_font(term_data *td, cptr fontname)
{
	GdkFont *old = td->font;

	/* Load font */
	td->font = gdk_font_load(fontname);

	if (td->font)
	{
		/* Free the old font */
		if (old) gdk_font_unref(old);
	}
	else
	{
		/* Oops, but we can still use the old one */
		td->font = old;
	}

	/* Calculate the size of the font XXX */
	td->font_wid = gdk_char_width(td->font, '@');
	td->font_hgt = td->font->ascent + td->font->descent;

#ifndef USE_DOUBLE_TILES

	/* Use the current font size for tiles as well */
	td->tile_wid = td->font_wid;
	td->tile_hgt = td->font_hgt;

#else /* !USE_DOUBLE_TILES */

	/* Calculate the size of tiles */
	if (use_bigtile && (td == &data[0])) td->tile_wid = td->font_wid * 2;
	else td->tile_wid = td->font_wid;
	td->tile_hgt = td->font_hgt;

#endif /* !USE_DOUBLE_TILES */
}


/*
 * React to OK button press in font selection dialogue
 */
static void font_ok_callback(
        GtkWidget *widget,
        GtkWidget *font_selector)
{
	gchar *fontname;
	term_data *td;

	td = gtk_object_get_data(GTK_OBJECT(font_selector), "term_data");

	g_assert(td != NULL);

	/* Retrieve font name from player's selection */
	fontname = gtk_font_selection_dialog_get_font_name(
	                   GTK_FONT_SELECTION_DIALOG(font_selector));

	/* Leave unless selection was valid */
	if (fontname == NULL) return;

	/* Load font and update font size info */
	load_font(td, fontname);

	/* Hack - Hide the window - finally found the trick... */
	gtk_widget_hide_all(td->window);

	/* Resizes the drawing area */
	gtk_drawing_area_size(
	        GTK_DRAWING_AREA(td->drawing_area),
	        td->cols * td->font_wid,
	        td->rows * td->font_hgt);

	/* Update the geometry hints for the window */
	term_data_set_geometry_hints(td);

	/* Reallocate the backing store */
	term_data_set_backing_store(td);

	/* Hack - Show the window */
	gtk_widget_show_all(td->window);

#ifdef USE_GRAPHICS

	/* We have to resize tiles when we are in graphics mode */
	resize_request = TRUE;

#endif /* USE_GRAPHICS */

	/* Hack - force redraw */
	Term_key_push(KTRL('R'));
}


/*
 * Process Options-Font-* menu command
 */
static void change_font_event_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	GtkWidget *font_selector;

	gchar *spacings[] = { "c", "m", NULL };

	font_selector = gtk_font_selection_dialog_new("Select font");

	gtk_object_set_data(
	        GTK_OBJECT(font_selector),
	        "term_data",
	        user_data);

	/* Filter to show only fixed-width fonts */
	gtk_font_selection_dialog_set_filter(
	        GTK_FONT_SELECTION_DIALOG(font_selector),
	        GTK_FONT_FILTER_BASE,
	        GTK_FONT_ALL,
	        NULL,
	        NULL,
	        NULL,
	        NULL,
	        spacings,
	        NULL);

	gtk_signal_connect(
	        GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font_selector)->ok_button),
	        "clicked",
	        font_ok_callback,
	        (gpointer)font_selector);

	/*
	 * Ensure that the dialog box is destroyed when the user clicks
	 * a button.
	 */
	gtk_signal_connect_object(
	        GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font_selector)->ok_button),
	        "clicked",
	        GTK_SIGNAL_FUNC(gtk_widget_destroy),
	        (gpointer)font_selector);

	gtk_signal_connect_object(
	        GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font_selector)->cancel_button),
	        "clicked",
	        GTK_SIGNAL_FUNC(gtk_widget_destroy),
	        (gpointer)font_selector);

	gtk_widget_show(GTK_WIDGET(font_selector));
}


/*
 * Process Terms-* menu command - hide/show terminal window
 */
static void term_event_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	term_data *td = (term_data *)user_data;

	/* We don't mess with the Angband window */
	if (td == &data[0]) return;

	/* It's shown */
	if (td->shown)
	{
		/* Hide the window */
		gtk_widget_hide_all(td->window);
	}

	/* It's hidden */
	else
	{
		/* Show the window */
		gtk_widget_show_all(td->window);
	}
}


/*
 * Toggles the boolean value of use_backing_store and
 * setup / remove backing store for each term
 */
static void change_backing_store_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	int i;

	/* Toggle the backing store mode */
	use_backing_store = !use_backing_store;

	/* Reset terms */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		term_data_set_backing_store(&data[i]);
	}
}


#ifdef USE_GRAPHICS

/*
 * Set graf_mode_request according to user selection,
 * and let Term_xtra react to the change.
 */
static void change_graf_mode_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	/* Set request according to user selection */
	graf_mode_request = (int)user_data;

	/*
	 * Hack - force redraw
	 * This induces a call to Term_xtra(TERM_XTRA_REACT, 0) as well
	 */
	Term_key_push(KTRL('R'));
}


/*
 * Set dither_mode according to user selection
 */
static void change_dith_mode_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	/* Set request according to user selection */
	dith_mode = (int)user_data;

	/*
	 * Hack - force redraw
	 */
	Term_key_push(KTRL('R'));
}


/*
 * Toggles the graphics tile scaling mode (Fast/Smooth)
 */
static void change_smooth_mode_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	/* (Try to) toggle the smooth rescaling mode */
	smooth_rescaling_request = !smooth_rescaling;

	/*
	 * Hack - force redraw
	 * This induces a call to Term_xtra(TERM_XTRA_REACT, 0) as well
	 */
	Term_key_push(KTRL('R'));
}


# ifdef USE_DOUBLE_TILES

static void change_wide_tile_mode_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	term *old = Term;
	term_data *td = &data[0];

	/* Toggle "use_bigtile" */
	use_bigtile = !use_bigtile;

#ifdef TOME
	/* T.o.M.E. requires this as well */
	arg_bigtile = use_bigtile;
#endif /* TOME */

	/* Double the width of tiles (only for the main window) */
	if (use_bigtile)
	{
		td->tile_wid = td->font_wid * 2;
	}

	/* Use the width of current font */
	else
	{
		td->tile_wid = td->font_wid;
	}

	/* Need to resize the tiles */
	resize_request = TRUE;

	/* Activate the main window */
	Term_activate(&td->t);

	/* Resize the term */
	Term_resize(td->cols, td->rows);

	/* Activate the old term */
	Term_activate(old);

	/* Hack - force redraw XXX ??? XXX */
	Term_key_push(KTRL('R'));
}

# endif  /* USE_DOUBLE_TILES */


# ifdef USE_TRANSPARENCY

/*
 * Toggles the boolean value of use_transparency
 */
static void change_trans_mode_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	/* Toggle the transparency mode */
	use_transparency = !use_transparency;

	/* Hack - force redraw */
	Term_key_push(KTRL('R'));
}

# endif  /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */


#ifndef SAVEFILE_SCREEN

/*
 * Caution: Modal or not, callbacks are called by gtk_main(),
 * so this is the right place to start a game.
 */
static void file_ok_callback(
        GtkWidget *widget,
        GtkWidget *file_selector)
{
	strcpy(savefile,
	       gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_selector)));

	gtk_widget_destroy(file_selector);

	/* game is in progress */
	game_in_progress = TRUE;

	/* Flush input */
	Term_flush();

	/* Play game */
	play_game(FALSE);

	/* Free memory allocated by game */
	cleanup_angband();

	/* Done */
	quit(NULL);
}


/*
 * Process File-Open menu command
 */
static void open_event_handler(
        GtkButton *was_clicked,
        gpointer user_data)
{
	GtkWidget *file_selector;
	char buf[1024];


	if (game_in_progress)
	{
		plog("You can't open a new game while you're still playing!");
		return;
	}

	/* Prepare the savefile path */
	path_build(buf, 1024, ANGBAND_DIR_SAVE, "*");

	file_selector = gtk_file_selection_new("Select a savefile");
	gtk_file_selection_set_filename(
	        GTK_FILE_SELECTION(file_selector),
	        buf);
	gtk_signal_connect(
	        GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
	        "clicked",
	        file_ok_callback,
	        (gpointer)file_selector);

	/*
	 * Ensure that the dialog box is destroyed when the user
	 * clicks a button.
	 */
	gtk_signal_connect_object(
	        GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->ok_button),
	        "clicked",
	        GTK_SIGNAL_FUNC(gtk_widget_destroy),
	        (gpointer)file_selector);

	gtk_signal_connect_object(
	        GTK_OBJECT(GTK_FILE_SELECTION(file_selector)->cancel_button),
	        "clicked",
	        GTK_SIGNAL_FUNC(gtk_widget_destroy),
	        (gpointer)file_selector);

	gtk_window_set_modal(GTK_WINDOW(file_selector), TRUE);
	gtk_widget_show(GTK_WIDGET(file_selector));
}

#endif /* !SAVEFILE_SCREEN */


/*
 * React to "delete" signal sent to Window widgets
 */
static gboolean delete_event_handler(
        GtkWidget *widget,
        GdkEvent *event,
        gpointer user_data)
{
	/* Save game if possible */
	save_game_gtk();

	/* Don't prevent closure */
	return (FALSE);
}


/*
 * Convert keypress events to ASCII codes and enqueue them
 * for game
 */
static gboolean keypress_event_handler(
        GtkWidget *widget,
        GdkEventKey *event,
        gpointer user_data)
{
	int i, mc, ms, mo, mx;

	char msg[128];


	/* Extract four "modifier flags" */
	mc = (event->state & GDK_CONTROL_MASK) ? TRUE : FALSE;
	ms = (event->state & GDK_SHIFT_MASK) ? TRUE : FALSE;
	mo = (event->state & GDK_MOD1_MASK) ? TRUE : FALSE;
	mx = (event->state & GDK_MOD3_MASK) ? TRUE : FALSE;

	/*
	 * Hack XXX
	 * Parse shifted numeric (keypad) keys specially.
	 */
	if ((event->state == GDK_SHIFT_MASK)
	                && (event->keyval >= GDK_KP_0) && (event->keyval <= GDK_KP_9))
	{
		/* Build the macro trigger string */
		strnfmt(msg, 128, "%cS_%X%c", 31, event->keyval, 13);

		/* Enqueue the "macro trigger" string */
		for (i = 0; msg[i]; i++) Term_keypress(msg[i]);

		/* Hack -- auto-define macros as needed */
		if (event->length && (macro_find_exact(msg) < 0))
		{
			/* Create a macro */
			macro_add(msg, event->string);
		}

		return (TRUE);
	}

	/* Normal keys with no modifiers */
	if (event->length && !mo && !mx)
	{
		/* Enqueue the normal key(s) */
		for (i = 0; i < event->length; i++) Term_keypress(event->string[i]);

		/* All done */
		return (TRUE);
	}

	/* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
	switch ((uint) event->keyval)
	{
	case GDK_Escape:
		{
			Term_keypress(ESCAPE);
			return (TRUE);
		}

	case GDK_Return:
		{
			Term_keypress('\r');
			return (TRUE);
		}

	case GDK_Tab:
		{
			Term_keypress('\t');
			return (TRUE);
		}

	case GDK_Delete:
	case GDK_BackSpace:
		{
			Term_keypress('\010');
			return (TRUE);
		}

	case GDK_Shift_L:
	case GDK_Shift_R:
	case GDK_Control_L:
	case GDK_Control_R:
	case GDK_Caps_Lock:
	case GDK_Shift_Lock:
	case GDK_Meta_L:
	case GDK_Meta_R:
	case GDK_Alt_L:
	case GDK_Alt_R:
	case GDK_Super_L:
	case GDK_Super_R:
	case GDK_Hyper_L:
	case GDK_Hyper_R:
		{
			/* Hack - do nothing to control characters */
			return (TRUE);
		}
	}

	/* Build the macro trigger string */
	strnfmt(msg, 128, "%c%s%s%s%s_%X%c", 31,
	        mc ? "N" : "", ms ? "S" : "",
	        mo ? "O" : "", mx ? "M" : "",
	        event->keyval, 13);

	/* Enqueue the "macro trigger" string */
	for (i = 0; msg[i]; i++) Term_keypress(msg[i]);

	/* Hack -- auto-define macros as needed */
	if (event->length && (macro_find_exact(msg) < 0))
	{
		/* Create a macro */
		macro_add(msg, event->string);
	}

	return (TRUE);
}


/*
 * Widget customisation (for drawing area) - "realize" signal
 *
 * In this program, called when window containing the drawing
 * area is shown first time.
 */
static void realize_event_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	term_data *td = (term_data *)user_data;

	/* Create graphic context */
	td->gc = gdk_gc_new(td->drawing_area->window);

	/* Set foreground and background colours - isn't bg used at all? */
	gdk_rgb_gc_set_background(td->gc, 0x000000);
	gdk_rgb_gc_set_foreground(td->gc, angband_colours[TERM_WHITE]);

	/* No last foreground colour, yet */
	td->last_attr = -1;

	/* Allocate the backing store */
	term_data_set_backing_store(td);

	/* Clear the window */
	gdk_draw_rectangle(
	        widget->window,
	        widget->style->black_gc,
	        TRUE,
	        0,
	        0,
	        td->cols * td->font_wid,
	        td->rows * td->font_hgt);
}


/*
 * Widget customisation (for drawing area) - "show" signal
 */
static void show_event_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	term_data *td = (term_data *)user_data;

	/* Set the shown flag */
	td->shown = TRUE;
}


/*
 * Widget customisation (for drawing area) - "hide" signal
 */
static void hide_event_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	term_data *td = (term_data *)user_data;

	/* Set the shown flag */
	td->shown = FALSE;
}


/*
 * Widget customisation (for drawing area)- handle size allocation requests
 */
static void size_allocate_event_handler(
        GtkWidget *widget,
        GtkAllocation *allocation,
        gpointer user_data)
{
	term_data *td = user_data;
	int old_rows, old_cols;
	term *old = Term;

	/* Paranoia */
	g_return_if_fail(widget != NULL);
	g_return_if_fail(allocation != NULL);
	g_return_if_fail(td != NULL);

	/* Remember old values */
	old_cols = td->cols;
	old_rows = td->rows;

	/* Update numbers of rows and columns */
	td->cols = (allocation->width + td->font_wid - 1) / td->font_wid;
	td->rows = (allocation->height + td->font_hgt - 1) / td->font_hgt;

	/* Overkill - Validate them */
	term_data_check_size(td);

	/* Adjust size request and set it */
	allocation->width = td->cols * td->font_wid;
	allocation->height = td->rows * td->font_hgt;
	widget->allocation = *allocation;

	/* Widget is realized, so we do some drawing works */
	if (GTK_WIDGET_REALIZED(widget))
	{
		/* Reallocate the backing store */
		term_data_set_backing_store(td);

		/* Actually handles resizing in Gtk */
		gdk_window_move_resize(
		        widget->window,
		        allocation->x,
		        allocation->y,
		        allocation->width,
		        allocation->height);

		/* And in the term package */
		Term_activate(&td->t);

		/* Resize if necessary */
		if ((td->cols != old_cols) || (td->rows != old_rows))
			(void)Term_resize(td->cols, td->rows);

		/* Redraw its content */
		Term_redraw();

		/* Refresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}
}


/*
 * Update exposed area in a window (for drawing area)
 */
static gboolean expose_event_handler(
        GtkWidget *widget,
        GdkEventExpose *event,
        gpointer user_data)
{
	term_data *td = user_data;

	term *old = Term;

#ifndef NO_REDRAW_SECTION

	int x1, x2, y1, y2;

#endif /* !NO_REDRAW_SECTION */


	/* Paranoia */
	if (td == NULL) return (TRUE);

	/* The window has a backing store */
	if (td->backing_store)
	{
		/* Simply restore the exposed area from the backing store */
		gdk_draw_pixmap(
		        td->drawing_area->window,
		        td->gc,
		        td->backing_store,
		        event->area.x,
		        event->area.y,
		        event->area.x,
		        event->area.y,
		        event->area.width,
		        event->area.height);
	}

	/* No backing store - use the game's code to redraw the area */
	else
	{

		/* Activate the relevant term */
		Term_activate(&td->t);

# ifdef NO_REDRAW_SECTION

		/* K.I.S.S. version */

		/* Redraw */
		Term_redraw();

# else /* NO_REDRAW_SECTION */

		/*
		 * Complex version - The above is enough, but since we have
		 * Term_redraw_section... This might help if we had a graphics
		 * mode.
		 */

		/* Convert coordinate in pixels to character cells */
		x1 = event->area.x / td->font_wid;
		x2 = (event->area.x + event->area.width) / td->font_wid;
		y1 = event->area.y / td->font_hgt;
		y2 = (event->area.y + event->area.height) / td->font_hgt;

		/*
		 * No paranoia - boundary checking is done in
		 * Term_redraw_section
		 */

		/* Redraw the area */
		Term_redraw_section(x1, y1, x2, y2);

# endif  /* NO_REDRAW_SECTION */

		/* Refresh */
		Term_fresh();

		/* Restore */
		Term_activate(old);
	}

	/* We've processed the event ourselves */
	return (TRUE);
}




/**** Initialisation ****/

/*
 * Initialise a term_data struct
 */
static errr term_data_init(term_data *td, int i)
{
	term *t = &td->t;
	char *p;

	td->cols = 80;
	td->rows = 24;

	/* Initialize the term */
	term_init(t, td->cols, td->rows, 1024);

	/* Store the name of the term */
	td->name = string_make(angband_term_name[i]);

	/* Instance names should start with a lowercase letter XXX */
	for (p = (char *)td->name; *p; p++) *p = tolower(*p);

	/* Use a "soft" cursor */
	t->soft_cursor = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	t->xtra_hook = Term_xtra_gtk;
	t->text_hook = Term_text_gtk;
	t->wipe_hook = Term_wipe_gtk;
	t->curs_hook = Term_curs_gtk;
#ifdef USE_GRAPHICS
	t->pict_hook = Term_pict_gtk;
#endif /* USE_GRAPHICS */
	t->nuke_hook = Term_nuke_gtk;

	/* Save the data */
	t->data = td;

	/* Activate (important) */
	Term_activate(t);

	/* Success */
	return (0);
}


/*
 * Neater menu code with GtkItemFactory.
 *
 * Menu bar of the Angband window
 *
 * Entry format: Path, Accelerator, Callback, Callback arg, type
 * where type is one of:
 *  - simple item, alias NULL
 *  - has submenu
 *  - as you read it
 *  - has a check mark
 *  - is a toggle
 */
static GtkItemFactoryEntry main_menu_items[] =
{
	/* "File" menu */
	{ "/File", NULL,
	  NULL, 0, ""
	},
#ifndef SAVEFILE_SCREEN
	{ "/File/New", "N",
	  new_event_handler, 0, NULL },
	{ "/File/Open", "O",
	  open_event_handler, 0, NULL },
	{ "/File/sep1", NULL,
	  NULL, 0, "" },
#endif /* !SAVEFILE_SCREEN */
	{ "/File/Save", "S",
	  save_event_handler, 0, NULL },
	{ "/File/Quit", "Q",
	  quit_event_handler, 0, NULL },

	/* "Terms" menu */
	{ "/Terms", NULL,
	  NULL, 0, "" },
	/* XXX XXX XXX NULL's are replaced by the program */
	{ NULL, "0",
	  term_event_handler, (guint)&data[0], "" },
	{ NULL, "1",
	  term_event_handler, (guint)&data[1], "" },
	{ NULL, "2",
	  term_event_handler, (guint)&data[2], "" },
	{ NULL, "3",
	  term_event_handler, (guint)&data[3], "" },
	{ NULL, "4",
	  term_event_handler, (guint)&data[4], "" },
	{ NULL, "5",
	  term_event_handler, (guint)&data[5], "" },
	{ NULL, "6",
	  term_event_handler, (guint)&data[6], "" },
	{ NULL, "7",
	  term_event_handler, (guint)&data[7], "" },

	/* "Options" menu */
	{ "/Options", NULL,
	  NULL, 0, "" },

	/* "Font" submenu */
	{ "/Options/Font", NULL,
	  NULL, 0, "" },
	/* XXX XXX XXX Again, NULL's are filled by the program */
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[0], NULL },
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[1], NULL },
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[2], NULL },
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[3], NULL },
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[4], NULL },
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[5], NULL },
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[6], NULL },
	{ NULL, NULL,
	  change_font_event_handler, (guint)&data[7], NULL },

#ifdef USE_GRAPHICS

	/* "Graphics" submenu */
	{ "/Options/Graphics", NULL,
	  NULL, 0, "" },
	{ "/Options/Graphics/None", NULL,
	  change_graf_mode_event_handler, GRAF_MODE_NONE, "" },
	{ "/Options/Graphics/Old", NULL,
	  change_graf_mode_event_handler, GRAF_MODE_OLD, "" },
	{ "/Options/Graphics/New", NULL,
	  change_graf_mode_event_handler, GRAF_MODE_NEW, "" },
# ifdef USE_DOUBLE_TILES
	{ "/Options/Graphics/sep3", NULL,
	  NULL, 0, "" },
	{ "/Options/Graphics/Wide tiles", NULL,
	  change_wide_tile_mode_event_handler, 0, "" },
# endif  /* USE_DOUBLE_TILES */
	{ "/Options/Graphics/sep1", NULL,
	  NULL, 0, "" },
	{ "/Options/Graphics/Dither if <= 8bpp", NULL,
	  change_dith_mode_event_handler, GDK_RGB_DITHER_NORMAL, "" },
	{ "/Options/Graphics/Dither if <= 16bpp", NULL,
	  change_dith_mode_event_handler, GDK_RGB_DITHER_MAX, "" },
	{ "/Options/Graphics/sep2", NULL,
	  NULL, 0, "" },
	{ "/Options/Graphics/Smoothing", NULL,
	  change_smooth_mode_event_handler, 0, "" },
# ifdef USE_TRANSPARENCY
	{ "/Options/Graphics/Transparency", NULL,
	  change_trans_mode_event_handler, 0, "" },
# endif  /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */

	/* "Misc" submenu */
	{ "/Options/Misc", NULL,
	  NULL, 0, "" },
	{ "/Options/Misc/Backing store", NULL,
	  change_backing_store_event_handler, 0, "" },
};


/*
 * XXX XXX Fill those NULL's in the menu definition with
 * angband_term_name[] strings
 */
static void setup_menu_paths(void)
{
	int i;
	int nmenu_items = sizeof(main_menu_items) / sizeof(main_menu_items[0]);
	GtkItemFactoryEntry *term_entry, *font_entry;
	char buf[64];

	/* Find the "Terms" menu */
	for (i = 0; i < nmenu_items; i++)
	{
		/* Skip NULLs */
		if (main_menu_items[i].path == NULL) continue;

		/* Find a match */
		if (streq(main_menu_items[i].path, "/Terms")) break;
	}
	g_assert(i < (nmenu_items - MAX_TERM_DATA));

	/* Remember the location */
	term_entry = &main_menu_items[i + 1];

	/* Find "Font" menu */
	for (i = 0; i < nmenu_items; i++)
	{
		/* Skip NULLs */
		if (main_menu_items[i].path == NULL) continue;

		/* Find a match */
		if (streq(main_menu_items[i].path, "/Options/Font")) break;
	}
	g_assert(i < (nmenu_items - MAX_TERM_DATA));

	/* Remember the location */
	font_entry = &main_menu_items[i + 1];

	/* For each terminal */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* XXX XXX Build the real path name to the entry */
		strnfmt(buf, 64, "/Terms/%s", angband_term_name[i]);

		/* XXX XXX Store it in the menu definition */
		(cptr)term_entry[i].path = string_make(buf);

		/* XXX XXX Build the real path name to the entry */
		strnfmt(buf, 64, "/Options/Font/%s", angband_term_name[i]);

		/* XXX XXX Store it in the menu definition */
		(cptr)font_entry[i].path = string_make(buf);
	}
}


/*
 * XXX XXX Free strings allocated by setup_menu_paths()
 */
static void free_menu_paths(void)
{
	int i;
	int nmenu_items = sizeof(main_menu_items) / sizeof(main_menu_items[0]);
	GtkItemFactoryEntry *term_entry, *font_entry;

	/* Find the "Terms" menu */
	for (i = 0; i < nmenu_items; i++)
	{
		/* Skip NULLs */
		if (main_menu_items[i].path == NULL) continue;

		/* Find a match */
		if (streq(main_menu_items[i].path, "/Terms")) break;
	}
	g_assert(i < (nmenu_items - MAX_TERM_DATA));

	/* Remember the location */
	term_entry = &main_menu_items[i + 1];

	/* Find "Font" menu */
	for (i = 0; i < nmenu_items; i++)
	{
		/* Skip NULLs */
		if (main_menu_items[i].path == NULL) continue;

		/* Find a match */
		if (streq(main_menu_items[i].path, "/Options/Font")) break;
	}
	g_assert(i < (nmenu_items - MAX_TERM_DATA));

	/* Remember the location */
	font_entry = &main_menu_items[i + 1];

	/* For each terminal */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* XXX XXX Free Term menu path */
		if (term_entry[i].path) string_free((cptr)term_entry[i].path);

		/* XXX XXX Free Font menu path */
		if (font_entry[i].path) string_free((cptr)font_entry[i].path);
	}
}


/*
 * Find widget corresponding to path name
 * return NULL on error
 */
static GtkWidget *get_widget_from_path(cptr path)
{
	GtkItemFactory *item_factory;
	GtkWidget *widget;

	/* Paranoia */
	if (path == NULL) return (NULL);

	/* Look up item factory */
	item_factory = gtk_item_factory_from_path(path);

	/* Oops */
	if (item_factory == NULL) return (NULL);

	/* Look up widget */
	widget = gtk_item_factory_get_widget(item_factory, path);

	/* Return result */
	return (widget);
}


/*
 * Enable/disable a menu item
 */
void enable_menu_item(cptr path, bool enabled)
{
	GtkWidget *widget;

	/* Access menu item widget */
	widget = get_widget_from_path(path);

	/* Paranoia */
	g_assert(widget != NULL);
	g_assert(GTK_IS_MENU_ITEM(widget));

	/*
	 * In Gtk's terminology, enabled is sensitive
	 * and disabled insensitive
	 */
	gtk_widget_set_sensitive(widget, enabled);
}


/*
 * Check/uncheck a menu item. The item should be of the GtkCheckMenuItem type
 */
void check_menu_item(cptr path, bool checked)
{
	GtkWidget *widget;

	/* Access menu item widget */
	widget = get_widget_from_path(path);

	/* Paranoia */
	g_assert(widget != NULL);
	g_assert(GTK_IS_CHECK_MENU_ITEM(widget));

	/*
	 * Put/remove check mark
	 *
	 * Mega-Hack -- The function supposed to be used here,
	 * gtk_check_menu_item_set_active(), emits an "activate" signal
	 * to the GtkMenuItem class of the widget, as if the menu item
	 * were selected by user, thereby causing bizarre behaviour.
	 * XXX XXX XXX
	 */
	GTK_CHECK_MENU_ITEM(widget)->active = checked;
}


/*
 * Update the "File" menu
 */
static void file_menu_update_handler(
        GtkWidget *widget,
        gpointer user_data)
{
#ifndef SAVEFILE_SCREEN
	bool game_start_ok;
#endif /* !SAVEFILE_SCREEN */
	bool save_ok, quit_ok;

#ifndef SAVEFILE_SCREEN

	/* Can we start a game now? */
	game_start_ok = !game_in_progress;

#endif /* !SAVEFILE_SCREEN */

	/* Cave we save/quit now? */
	if (!character_generated || !game_in_progress)
	{
		save_ok = FALSE;
		quit_ok = TRUE;
	}
	else
	{
		if (inkey_flag && can_save) save_ok = quit_ok = TRUE;
		else save_ok = quit_ok = FALSE;
	}

	/* Enable / disable menu items according to those conditions */
#ifndef SAVEFILE_SCREEN
	enable_menu_item("/File/New", game_start_ok);
	enable_menu_item("/File/Open", game_start_ok);
#endif /* !SAVEFILE_SCREEN */
	enable_menu_item("/File/Save", save_ok);
	enable_menu_item("/File/Quit", quit_ok);
}


/*
 * Update the "Terms" menu
 */
static void term_menu_update_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	int i;
	char buf[64];

	/* For each term */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Build the path name */
		strnfmt(buf, 64, "/Terms/%s", angband_term_name[i]);

		/* Update the check mark on the item */
		check_menu_item(buf, data[i].shown);
	}
}


/*
 * Update the "Font" submenu
 */
static void font_menu_update_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	int i;
	char buf[64];

	/* For each term */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Build the path name */
		strnfmt(buf, 64, "/Options/Font/%s", angband_term_name[i]);

		/* Enable selection if the term is shown */
		enable_menu_item(buf, data[i].shown);
	}
}


/*
 * Update the "Misc" submenu
 */
static void misc_menu_update_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	/* Update an item */
	check_menu_item(
	        "/Options/Misc/Backing store",
	        use_backing_store);
}


#ifdef USE_GRAPHICS

/*
 * Update the "Graphics" submenu
 */
static void graf_menu_update_handler(
        GtkWidget *widget,
        gpointer user_data)
{
	/* Update menu items */
	check_menu_item(
	        "/Options/Graphics/None",
	        (graf_mode == GRAF_MODE_NONE));
	check_menu_item(
	        "/Options/Graphics/Old",
	        (graf_mode == GRAF_MODE_OLD));
	check_menu_item(
	        "/Options/Graphics/New",
	        (graf_mode == GRAF_MODE_NEW));

#ifdef USE_DOUBLE_TILES

	check_menu_item(
	        "/Options/Graphics/Wide tiles",
	        use_bigtile);

#endif /* USE_DOUBLE_TILES */

	check_menu_item(
	        "/Options/Graphics/Dither if <= 8bpp",
	        (dith_mode == GDK_RGB_DITHER_NORMAL));
	check_menu_item(
	        "/Options/Graphics/Dither if <= 16bpp",
	        (dith_mode == GDK_RGB_DITHER_MAX));

	check_menu_item(
	        "/Options/Graphics/Smoothing",
	        smooth_rescaling);

# ifdef USE_TRANSPARENCY

	check_menu_item(
	        "/Options/Graphics/Transparency",
	        use_transparency);

# endif  /* USE_TRANSPARENCY */
}

#endif /* USE_GRAPHICS */


/*
 * Construct a menu hierarchy using GtkItemFactory, setting up
 * callbacks and accelerators along the way, and return
 * a GtkMenuBar widget.
 */
GtkWidget *get_main_menu(term_data *td)
{
	GtkItemFactory *item_factory;
	GtkAccelGroup *accel_group;
	gint nmenu_items = sizeof(main_menu_items) / sizeof(main_menu_items[0]);


	/* XXX XXX Setup path names in the "Terms" and "Font" menus */
	setup_menu_paths();

	/* Allocate an accelerator group */
	accel_group = gtk_accel_group_new();
	g_assert(accel_group != NULL);

	/* Initialise the item factory */
	item_factory = gtk_item_factory_new(
	                       GTK_TYPE_MENU_BAR,
	                       "",
	                       accel_group);
	g_assert(item_factory != NULL);

	/* Generate the menu items */
	gtk_item_factory_create_items(
	        item_factory,
	        nmenu_items,
	        main_menu_items,
	        NULL);

	/* Attach the new accelerator group to the window */
	gtk_window_add_accel_group(
	        GTK_WINDOW(td->window),
	        accel_group);

	/* Return the actual menu bar created */
	return (gtk_item_factory_get_widget(item_factory, ""));
}


/*
 * Install callbacks to update menus
 */
static void add_menu_update_callbacks()
{
	GtkWidget *widget;

	/* Access the "File" menu */
	widget = get_widget_from_path("/File");

	/* Paranoia */
	g_assert(widget != NULL);
	g_assert(GTK_IS_MENU(widget));

	/* Assign callback */
	gtk_signal_connect(
	        GTK_OBJECT(widget),
	        "show",
	        GTK_SIGNAL_FUNC(file_menu_update_handler),
	        NULL);

	/* Access the "Terms" menu */
	widget = get_widget_from_path("/Terms");

	/* Paranoia */
	g_assert(widget != NULL);
	g_assert(GTK_IS_MENU(widget));

	/* Assign callback */
	gtk_signal_connect(
	        GTK_OBJECT(widget),
	        "show",
	        GTK_SIGNAL_FUNC(term_menu_update_handler),
	        NULL);

	/* Access the "Font" menu */
	widget = get_widget_from_path("/Options/Font");

	/* Paranoia */
	g_assert(widget != NULL);
	g_assert(GTK_IS_MENU(widget));

	/* Assign callback */
	gtk_signal_connect(
	        GTK_OBJECT(widget),
	        "show",
	        GTK_SIGNAL_FUNC(font_menu_update_handler),
	        NULL);

	/* Access the "Misc" menu */
	widget = get_widget_from_path("/Options/Misc");

	/* Paranoia */
	g_assert(widget != NULL);
	g_assert(GTK_IS_MENU(widget));

	/* Assign callback */
	gtk_signal_connect(
	        GTK_OBJECT(widget),
	        "show",
	        GTK_SIGNAL_FUNC(misc_menu_update_handler),
	        NULL);

#ifdef USE_GRAPHICS

	/* Access Graphics menu */
	widget = get_widget_from_path("/Options/Graphics");

	/* Paranoia */
	g_assert(widget != NULL);
	g_assert(GTK_IS_MENU(widget));

	/* Assign callback */
	gtk_signal_connect(
	        GTK_OBJECT(widget),
	        "show",
	        GTK_SIGNAL_FUNC(graf_menu_update_handler),
	        NULL);

#endif /* USE_GRAPHICS */
}


/*
 * Create Gtk widgets for a terminal window and set up callbacks
 */
static void init_gtk_window(term_data *td, int i)
{
	GtkWidget *menu_bar = NULL, *box;
	cptr font;

	bool main_window = (i == 0) ? TRUE : FALSE;


	/* Create window */
	td->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	/* Set title */
	gtk_window_set_title(GTK_WINDOW(td->window), td->name);


	/* Get default font for this term */
	font = get_default_font(i);

	/* Load font and initialise related term_data fields */
	load_font(td, font);


	/* Create drawing area */
	td->drawing_area = gtk_drawing_area_new();

	/* Set the size of the drawing area */
	gtk_drawing_area_size(
	        GTK_DRAWING_AREA(td->drawing_area),
	        td->cols * td->font_wid,
	        td->rows * td->font_hgt);

	/* Set geometry hints */
	term_data_set_geometry_hints(td);


	/* Install window event handlers */
	gtk_signal_connect(
	        GTK_OBJECT(td->window),
	        "delete_event",
	        GTK_SIGNAL_FUNC(delete_event_handler),
	        NULL);
	gtk_signal_connect(
	        GTK_OBJECT(td->window),
	        "key_press_event",
	        GTK_SIGNAL_FUNC(keypress_event_handler),
	        NULL);

	/* Destroying the Angband window terminates the game */
	if (main_window)
	{
		gtk_signal_connect(
		        GTK_OBJECT(td->window),
		        "destroy_event",
		        GTK_SIGNAL_FUNC(destroy_main_event_handler),
		        NULL);
	}

	/* The other windows are just hidden */
	else
	{
		gtk_signal_connect(
		        GTK_OBJECT(td->window),
		        "destroy_event",
		        GTK_SIGNAL_FUNC(destroy_sub_event_handler),
		        td);
	}


	/* Install drawing area event handlers */
	gtk_signal_connect(
	        GTK_OBJECT(td->drawing_area),
	        "realize",
	        GTK_SIGNAL_FUNC(realize_event_handler),
	        (gpointer)td);
	gtk_signal_connect(
	        GTK_OBJECT(td->drawing_area),
	        "show",
	        GTK_SIGNAL_FUNC(show_event_handler),
	        (gpointer)td);
	gtk_signal_connect(
	        GTK_OBJECT(td->drawing_area),
	        "hide",
	        GTK_SIGNAL_FUNC(hide_event_handler),
	        (gpointer)td);
	gtk_signal_connect(
	        GTK_OBJECT(td->drawing_area),
	        "size_allocate",
	        GTK_SIGNAL_FUNC(size_allocate_event_handler),
	        (gpointer)td);
	gtk_signal_connect(
	        GTK_OBJECT(td->drawing_area),
	        "expose_event",
	        GTK_SIGNAL_FUNC(expose_event_handler),
	        (gpointer)td);


	/* Create menu */
	if (main_window)
	{
		/* Build the main menu bar */
		menu_bar = get_main_menu(td);
		g_assert(menu_bar != NULL);

		/* Since it's tedious to scatter the menu update code around */
		add_menu_update_callbacks();
	}


	/* Pack the menu bar together with the main window */
	/* For vertical placement of the menu bar and the drawing area */
	box = gtk_vbox_new(FALSE, 0);

	/* Let the window widget own it */
	gtk_container_add(GTK_CONTAINER(td->window), box);

	/* The main window has a menu bar */
	if (main_window)
		gtk_box_pack_start(
		        GTK_BOX(box),
		        menu_bar,
		        FALSE,
		        FALSE,
		        NO_PADDING);

	/* And place the drawing area just beneath it */
	gtk_box_pack_start_defaults(GTK_BOX(box), td->drawing_area);


	/* Show the widgets - use of td->shown is a dirty hack XXX XXX */
	if (td->shown) gtk_widget_show_all(td->window);
}


/*
 * To be hooked into quit(). See z-util.c
 */
static void hook_quit(cptr str)
{
	/* Free menu paths dynamically allocated */
	free_menu_paths();

# ifdef USE_GRAPHICS

	/* Free pathname string */
	if (ANGBAND_DIR_XTRA_GRAF) string_free(ANGBAND_DIR_XTRA_GRAF);

# endif  /* USE_GRAPHICS */

	/* Terminate the program */
	gtk_exit(0);
}


#ifdef ANGBAND300

/*
 * Help message for this port
 */
const char help_gtk[] =
	"GTK for X11, subopts -n\n"
	"           -b(acking store off)\n"
#ifdef USE_GRAPHICS
	"           -g(raphics) -o(ld graphics) -s(moothscaling off) \n"
	"           -t(ransparency on)\n"
# ifdef USE_DOUBLE_TILES
	"           -w(ide tiles)\n"
# endif  /* USE_DOUBLE_TILES */
#endif /* USE_GRAPHICS */
	"           and standard GTK options";

#endif /* ANGBAND300 */


/*
 * Initialization function
 */
errr init_gtk(int argc, char **argv)
{
	int i;


	/* Initialize the environment */
	gtk_init(&argc, &argv);

	/* Activate hooks - Use gtk/glib interface throughout */
	ralloc_aux = hook_ralloc;
	rnfree_aux = hook_rnfree;
	quit_aux = hook_quit;
	core_aux = hook_quit;

	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		/* Number of terminals displayed at start up */
		if (prefix(argv[i], "-n"))
		{
			num_term = atoi(&argv[i][2]);
			if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
			else if (num_term < 1) num_term = 1;
			continue;
		}

		/* Disable use of pixmaps as backing store */
		if (streq(argv[i], "-b"))
		{
			use_backing_store = FALSE;
			continue;
		}

#ifdef USE_GRAPHICS

		/* Requests "old" graphics */
		if (streq(argv[i], "-o"))
		{
			graf_mode_request = GRAF_MODE_OLD;
			continue;
		}

		/* Requests "new" graphics */
		if (streq(argv[i], "-g"))
		{
			graf_mode_request = GRAF_MODE_NEW;
			continue;
		}

# ifdef USE_DOUBLE_TILES

		/* Requests wide tile mode */
		if (streq(argv[i], "-w"))
		{
			use_bigtile = TRUE;
# ifdef TOME
			/* T.o.M.E. uses older version of the patch */
			arg_bigtile = TRUE;
# endif  /* TOME */
			continue;
		}

# endif  /* USE_DOUBLE_TILES */


		/* Enable transparency effect */
		if (streq(argv[i], "-t"))
		{
			use_transparency = TRUE;
			continue;
		}

		/* Disable smooth rescaling of tiles */
		if (streq(argv[i], "-s"))
		{
			smooth_rescaling_request = FALSE;
			continue;
		}

#endif /* USE_GRAPHICS */

		/* None of the above */
		plog_fmt("Ignoring option: %s", argv[i]);
	}

#ifdef USE_GRAPHICS

	{
		char path[1024];

		/* Build the "graf" path */
		path_build(path, 1024, ANGBAND_DIR_XTRA, "graf");

		/* Allocate the path */
		ANGBAND_DIR_XTRA_GRAF = string_make(path);
	}

#endif /* USE_GRAPHICS */

	/* Initialise colours */
	gdk_rgb_init();
	gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
	gtk_widget_set_default_visual(gdk_rgb_get_visual());
	init_colours();

	/*
	 * Initialise the windows backwards, so that
	 * the Angband window comes in front
	 */
	for (i = MAX_TERM_DATA - 1; i >= 0; i--)
	{
		term_data *td = &data[i];

		/* Initialize the term_data */
		term_data_init(td, i);

		/* Hack - Set the shown flag, meaning "to be shown" XXX XXX */
		if (i < num_term) td->shown = TRUE;
		else td->shown = FALSE;

		/* Save global entry */
		angband_term[i] = Term;

		/* Init the window */
		init_gtk_window(td, i);
	}

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

#ifndef SAVEFILE_SCREEN

	/* Set the system suffix */
	ANGBAND_SYS = "gtk";

	/* Catch nasty signals */
	signals_init();

	/* Initialize */
	init_angband();

#ifndef OLD_SAVEFILE_CODE

	/* Hack - because this port has New/Open menus XXX */
	savefile[0] = '\0';

#endif /* !OLD_SAVEFILE_CODE */

	/* Prompt the user */
	prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 17);
	Term_fresh();

	/* Activate more hook */
	plog_aux = hook_plog;


	/* Processing loop */
	gtk_main();


	/* Free allocated memory */
	cleanup_angband();

	/* Stop now */
	quit(NULL);

#else /* !SAVEFILE_SCREEN */

	/* Activate more hook */
	plog_aux = hook_plog;

	/* It's too early to set this, but cannot do so elsewhere XXX XXX */
	game_in_progress = TRUE;

#endif /* !SAVEFILE_SCREEN */

	/* Success */
	return (0);
}

#endif /* USE_GTK */
tome-235-src/src/main-ibm.c0000644000076400017500000010054011012107763013312 0ustar  dgdg/* File: main-ibm.c */

/*
 * Copyright (c) 1997 Ben Harrison, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */

/* Purpose: Visual Display Support for "term.c", for the IBM */

/*
 * Original code by "Billy Tanksley (wtanksle@ucsd.edu)"
 * Use "Makefile.ibm" to compile Angband using this file.
 *
 * Support for DJGPP v2 by "Scott Egashira (egashira@u.washington.edu)"
 *
 * Extensive modifications by "Ben Harrison (benh@phial.com)",
 * including "collation" of the Watcom C/C++ and DOS-286 patches.
 *
 * Watcom C/C++ changes by "David Boeren (akemi@netcom.com)"
 * Use "Makefile.wat" to compile this file with Watcom C/C++, and
 * be sure to define "USE_IBM" and "USE_WAT".
 *
 * DOS-286 (conio.h) changes by (Roland Jay Roberts (jay@map.com)
 * Use "Makefile.286" (not ready) to compile this file for DOS-286,
 * and be sure to define "USE_IBM", "USE_WAT", and "USE_286".  Also,
 * depending on your compiler, you may need to define "USE_CONIO".
 *
 * True color palette support by "Mike Marcelais (michmarc@microsoft.com)",
 * with interface to the "color_table" array by Ben Harrison.
 *
 * Both "shift" keys are treated as "identical", and all the modifier keys
 * (control, shift, alt) are ignored when used with "normal" keys, unless
 * they modify the underlying "ascii" value of the key.  You must use the
 * new "user pref files" to be able to interact with the keypad and such.
 *
 * The "lib/user/pref-ibm.prf" file contains macro definitions and possible
 * alternative color set definitions.  The "lib/user/font-ibm.prf" contains
 * attr/char mappings for walls and floors and such.
 *
 * Note the "Term_user_ibm()" function hook, which could allow the user
 * to interact with the "main-ibm.c" visual system.  Currently this hook
 * is unused, but, for example, it could allow the user to toggle "sound"
 * or "graphics" modes, or to select the number of screen rows, with the
 * extra screen rows being used for the mirror window.
 */


#include "angband.h"


#ifdef USE_IBM


/*
 * Use a "virtual" screen to "buffer" screen writes.
 */
#define USE_VIRTUAL

#ifdef USE_DOSSOCK
#include 
#include 
#include 
#include 
#endif

#include 
#include 
#include 

#ifdef USE_WAT

# include 

# ifdef USE_CONIO
# else /* USE_CONIO */

# include 

# define bioskey(C)	_bios_keybrd(C)

# endif  /* USE_CONIO */

# ifndef USE_286
# define int86(a, b, c)	int386(a, b, c)
# endif 

# define inportb(x)	inp(x)
# define outportb(x, y)	outp(x, y)

#else /* USE_WAT */

# if __DJGPP__ > 1

# include 
# include 

# else /* __DJGPP__ > 1 */
# ifdef __DJGPP__
# error "Upgrade to version 2.0 of DJGPP"
# endif  /* __DJGPP__ */
# endif  /* __DJGPP__ > 1 */

#endif /* USE_WAT */


#ifdef USE_CONIO

# include 

/*
 * Hack -- write directly to video card
 */
extern int directvideo = 1;

/*
 * Hack -- no virtual screen
 */
# undef USE_VIRTUAL

#endif /* USE_CONIO */


/*
 * Keypress input modifier flags (hard-coded by DOS)
 */
#define K_RSHIFT	0	/* Right shift key down */
#define K_LSHIFT	1	/* Left shift key down */
#define K_CTRL		2	/* Ctrl key down */
#define K_ALT		3	/* Alt key down */
#define K_SCROLL	4	/* Scroll lock on */
#define K_NUM		5	/* Num lock on */
#define K_CAPS		6	/* Caps lock on */
#define K_INSERT	7	/* Insert on */


/*
 * Foreground color bits (hard-coded by DOS)
 */
#define VID_BLACK	0x00
#define VID_BLUE	0x01
#define VID_GREEN	0x02
#define VID_CYAN	0x03
#define VID_RED		0x04
#define VID_MAGENTA	0x05
#define VID_YELLOW	0x06
#define VID_WHITE	0x07

/*
 * Bright text (hard-coded by DOS)
 */
#define VID_BRIGHT	0x08

/*
 * Background color bits (hard-coded by DOS)
 */
#define VUD_BLACK	0x00
#define VUD_BLUE	0x10
#define VUD_GREEN	0x20
#define VUD_CYAN	0x30
#define VUD_RED		0x40
#define VUD_MAGENTA	0x50
#define VUD_YELLOW	0x60
#define VUD_WHITE	0x70

/*
 * Blinking text (hard-coded by DOS)
 */
#define VUD_BRIGHT	0x80


/*
 * Screen Size
 */
static int rows = 25;
static int cols = 80;


/*
 * Physical Screen
 */
#ifdef USE_286
# define PhysicalScreen ((byte *)MK_FP(0xB800, 0x0000))
#else
# define PhysicalScreen ((byte *)(0xB800 << 4))
#endif


#ifdef USE_VIRTUAL

/*
 * Virtual Screen Contents
 */
static byte *VirtualScreen;

#else

/*
* Physical screen access
*/
#define VirtualScreen PhysicalScreen

#endif


/*
 * Hack -- the cursor "visibility"
 */
static int saved_cur_v;
static int saved_cur_high;
static int saved_cur_low;


#ifdef USE_CONIO
#else /* USE_CONIO */

/*
* This array is used for "wiping" the screen
*/
static byte wiper[160];

#endif /* USE_CONIO */


/*
 * The main screen (currently the only screen)
 */
static term term_screen_body;


/*
 * Choose between the "complex" and "simple" color methods
 */
static byte use_color_complex = FALSE;


/*
 * The "complex" color set
 */
static long ibm_color_complex[16];


/*
 * The "simple" color set
 *
 * This table is used by the "color" code to instantiate the "approximate"
 * Angband colors using the only colors available on crappy monitors.
 *
 * The entries below are taken from the "color bits" defined above.
 *
 * Note that values from 16 to 255 are extremely ugly.
 *
 * The values below came from various sources, if you do not like them,
 * get a better monitor, or edit "pref-ibm.prf" to use different codes.
 *
 * Note that many of the choices below suck, but so do crappy monitors.
 */
static byte ibm_color_simple[16] =
{
	VID_BLACK, 			/* Dark */
	VID_WHITE, 			/* White */
	VID_CYAN, 			/* Slate XXX */
	VID_RED | VID_BRIGHT, 	/* Orange XXX */
	VID_RED, 			/* Red */
	VID_GREEN, 			/* Green */
	VID_BLUE, 			/* Blue */
	VID_YELLOW, 			/* Umber XXX */
	VID_BLACK | VID_BRIGHT, 	/* Light Dark */
	VID_CYAN | VID_BRIGHT, 	/* Light Slate XXX */
	VID_MAGENTA, 		/* Violet */
	VID_YELLOW | VID_BRIGHT, 	/* Yellow */
	VID_MAGENTA | VID_BRIGHT, 	/* Light Red XXX */
	VID_GREEN | VID_BRIGHT, 	/* Light Green */
	VID_BLUE | VID_BRIGHT, 	/* Light Blue */
	VID_YELLOW			/* Light Umber XXX */
};



/*
 * Activate the "ibm_color_complex" palette information.
 *
 * Code by Mike Marcelais, with help from "The programmer's guide
 * to the EGA and VGA video cards" [Farraro].
 *
 * On VGA cards, colors go through a double-indirection when looking
 * up the `real' color when in 16 color mode.  The color value in the
 * attribute is looked up in the EGA color registers.  Then that value
 * is looked up in the VGA color registers.  Then the color is displayed.
 * This is done for compatability.  However, the EGA registers are
 * initialized by default to 0..5, 14, 7, 38..3F and not 0..F which means
 * that unless these are reset, the VGA setpalette function will not
 * update the correct palette register!
 *
 * DJGPP's GrSetColor() does _not_ set the EGA palette list, only the
 * VGA color list.
 *
 * Note that the "traditional" method, using "int86(0x10)", is very slow
 * when called in protected mode, so we use a faster method using video
 * ports instead.
 *
 * On Watcom machines, we could simply use the special "_remapallpalette()"
 * function, which not only sets both palette lists (see below) but also
 * checks for legality of the monitor mode, but, if we are doing bitmapped
 * graphics, that function forgets to set the EGA registers for some reason.
 */
static void activate_color_complex(void)
{
	int i;
	printf("%c%c%c%c", 8, 8, 8, 8);

#if 1

	/* Edit the EGA palette */
	inportb(0x3da);

	/* Edit the colors */
	for (i = 0; i < 16; i++)
	{
		/* Set color "i" */
		outportb(0x3c0, i);

		/* To value "i" */
		outportb(0x3c0, i);
	}

	/* Use that EGA palette */
	outportb(0x3c0, 0x20);

	/* Edit VGA palette, starting at color zero */
	outportb(0x3c8, 0);

	/* Send the colors */
	for (i = 0; i < 16; i++)
	{
		/* Send the red, green, blue components */
		outportb(0x3c9, ((ibm_color_complex[i]) & 0xFF));
		outportb(0x3c9, ((ibm_color_complex[i] >> 8) & 0xFF));
		outportb(0x3c9, ((ibm_color_complex[i] >> 16) & 0xFF));
	}

#else /* 1 */

	/* Set the colors */
	for (i = 0; i < 16; i++)
	{
		union REGS r;

		/* Set EGA color */
		r.h.ah = 0x10;
		r.h.al = 0x00;

		/* Set color "i" */
		r.h.bl = i;

		/* To value "i" */
		r.h.bh = i;

		/* Do it */
		int86(0x10, &r, &r);

		/* Set VGA color */
		r.h.ah = 0x10;
		r.h.al = 0x10;

		/* Set color "i" */
		r.h.bh = 0x00;
		r.h.bl = i;

		/* Use this "green" value */
		r.h.ch = ((ibm_color_complex[i] >> 8) & 0xFF);

		/* Use this "blue" value */
		r.h.cl = ((ibm_color_complex[i] >> 16) & 0xFF);

		/* Use this "red" value */
		r.h.dh = ((ibm_color_complex[i]) & 0xFF);

		/* Do it */
		int86(0x10, &r, &r);
	}

#endif /* 1 */

}


#ifdef SUPPORT_GAMMA

/*
 * When set to TRUE, indicates that we can use gamma_table
 */
static bool gamma_table_ready = FALSE;


/*
 * Build gamma correction table if requested and applicable
 */
static void setup_gamma_table(void)
{
	static u16b old_gamma_val = 0;

	/* (Re)build the table only when gamma value changes */
	if (gamma_val == old_gamma_val) return;

	/* Temporarily inactivate the table */
	gamma_table_ready = FALSE;

	/* Validate gamma_val */
	if ((gamma_val <= 0) || (gamma_val >= 256))
	{
		/* Reset */
		old_gamma_val = gamma_val = 0;

		/* Leave it inactive */
		return;
	}

	/* (Re)build the table */
	build_gamma_table(gamma_val);

	/* Remember gamma_val */
	old_gamma_val = gamma_val;

	/* Activate the table */
	gamma_table_ready = TRUE;
}

#endif /* SUPPORT_GAMMA */


/*
 * Note the use of "(x >> 2)" to convert an 8 bit value to a 6 bit value
 * without losing much precision.
 */
static int Term_xtra_ibm_react(void)
{
	int i;

	/* Complex method */
	if (use_color_complex)
	{
		long rv, gv, bv, code;

		bool change = FALSE;

#ifdef SUPPORT_GAMMA

		/* Build gamma_table */
		setup_gamma_table();

#endif /* SUPPORT_GAMMA */

		/* Save the default colors */
		for (i = 0; i < 16; i++)
		{
			/* Extract desired values */
			rv = angband_color_table[i][1];
			gv = angband_color_table[i][2];
			bv = angband_color_table[i][3];

#ifdef SUPPORT_GAMMA

			/* Hack - Gamma correction */
			if (gamma_table_ready)
			{
				rv = gamma_table[rv];
				gv = gamma_table[gv];
				bv = gamma_table[bv];
			}

#endif /* SUPPORT_GAMMA */

			/* 8 bit to 6 bit conversion */
			rv = rv >> 2;
			gv = gv >> 2;
			bv = bv >> 2;

			/* Extract a full color code */
			code = ((rv) | (gv << 8) | (bv << 16));

			/* Activate changes */
			if (ibm_color_complex[i] != code)
			{
				/* Note the change */
				change = TRUE;

				/* Apply the desired color */
				ibm_color_complex[i] = code;
			}
		}

		/* Activate the palette if needed */
		if (change) activate_color_complex();
	}

	/* Simple method */
	else
	{
		/* Save the default colors */
		for (i = 0; i < 16; i++)
		{
			/* Simply accept the desired colors */
			ibm_color_simple[i] = angband_color_table[i][0];
		}
	}

	/* Success */
	return (0);
}



/*
 * Hack -- set the cursor "visibility"
 */
static void curs_set(int v)
{
	/* If needed */
	if (saved_cur_v != v)
	{
		union REGS r;

		/* Set cursor */
		r.h.ah = 1;

		/* Visible */
		if (v)
		{
			/* Use the saved values */
			r.h.ch = saved_cur_high;
			r.h.cl = saved_cur_low;
		}

		/* Invisible */
		else
		{
			/* Make it invisible */
			r.h.ch = 0x20;
			r.h.cl = 0x00;
		}

		/* Make the call */
		int86(0x10, &r, &r);

		/* Save the cursor state */
		saved_cur_v = v;
	}
}



/*
 * Process an event (check for a keypress)
 *
 * The keypress processing code is often the most system dependant part
 * of Angband, since sometimes even the choice of compiler is important.
 *
 * For the IBM, we divide all keypresses into two categories, first, the
 * "normal" keys, including all keys required to play Angband, and second,
 * the "special" keys, such as keypad keys, function keys, and various keys
 * used in combination with various modifier keys.
 *
 * To simplify this file, we use Angband's "macro processing" ability, in
 * combination with a specialized "pref-ibm.prf" file, to handle most of the
 * "special" keys, instead of attempting to fully analyze them here.  This
 * file only has to determine when a "special" key has been pressed, and
 * translate it into a simple string which signals the use of a "special"
 * key, the set of modifiers used, if any, and the hardware scan code of
 * the actual key which was pressed.  To simplify life for the user, we
 * treat both "shift" keys as identical modifiers.
 *
 * The final encoding is "^_MMMxSS\r", where "MMM" encodes the modifiers
 * ("C" for control, "S" for shift, "A" for alt, or any ordered combination),
 * and "SS" encodes the keypress (as the two "digit" hexadecimal encoding of
 * the scan code of the key that was pressed), and the "^_" and "x" and "\r"
 * delimit the encoding for recognition by the macro processing code.
 *
 * Some important facts about scan codes follow.  All "normal" keys use
 * scan codes from 1-58.  The "function" keys use 59-68 (and 133-134).
 * The "keypad" keys use 69-83.  Escape uses 1.  Enter uses 28.  Control
 * uses 29.  Left Shift uses 42.  Right Shift uses 54.  PrtScrn uses 55.
 * Alt uses 56.  Space uses 57.  CapsLock uses 58.  NumLock uses 69.
 * ScrollLock uses 70.  The "keypad" keys which use scan codes 71-83
 * are ordered KP7,KP8,KP9,KP-,KP4,KP5,KP6,KP+,KP1,KP2,KP3,INS,DEL.
 *
 * Using "bioskey(0x10)" instead of "bioskey(0)" apparently provides more
 * information, including better access to the keypad keys in combination
 * with various modifiers, but only works on "PC's after 6/1/86", and there
 * is no way to determine if the function is provided on a machine.  I have
 * been told that without it you cannot detect, for example, control-left.
 * The basic scan code + ascii value pairs returned by the keypad follow,
 * with values in parentheses only available to "bioskey(0x10)".
 *
 *         /      *      -      +      1      2      3      4
 * Norm:  352f   372a   4a2d   4e2b   4f00   5000   5100   4b00
 * Shft:  352f   372a   4a2d   4e2b   4f31   5032   5133   4b34
 * Ctrl: (9500) (9600) (8e00) (9000)  7500  (9100)  7600   7300
 *
 *         5      6      7      8      9      0      .     Enter
 * Norm: (4c00)  4d00   4700   4800   4900   5200   5300  (e00d)
 * Shft:  4c35   4d36   4737   4838   4939   5230   532e  (e00d)
 * Ctrl: (8f00)  7400   7700  (8d00)  8400  (9200) (9300) (e00a)
 *
 * See "pref-ibm.prf" for the "standard" macros for various keys.
 *
 * Certain "bizarre" keypad keys (such as "enter") return a "scan code"
 * of "0xE0", and a "usable" ascii value.  These keys should be treated
 * like the normal keys, see below.  XXX XXX XXX Note that these "special"
 * keys could be prefixed with an optional "ctrl-^" which would allow them
 * to be used in macros without hurting their use in normal situations.
 */
static errr Term_xtra_ibm_event(int v)
{
	int i, k, s;

	bool mc = FALSE;
	bool ms = FALSE;
	bool ma = FALSE;


	/* Hack -- Check for a keypress */
	if (!v && !bioskey(1)) return (1);

	/* Wait for a keypress */
	k = bioskey(0x10);

	/* Access the "modifiers" */
	i = bioskey(2);

	/* Extract the "scan code" */
	s = ((k >> 8) & 0xFF);

	/* Extract the "ascii value" */
	k = (k & 0xFF);

	/* Process "normal" keys */
	if ((s <= 58) || (s == 0xE0))
	{
		/* Enqueue it */
		if (k) Term_keypress(k);

		/* Success */
		return (0);
	}

	/* Extract the modifier flags */
	if (i & (1 << K_CTRL)) mc = TRUE;
	if (i & (1 << K_LSHIFT)) ms = TRUE;
	if (i & (1 << K_RSHIFT)) ms = TRUE;
	if (i & (1 << K_ALT)) ma = TRUE;


	/* Begin a "macro trigger" */
	Term_keypress(31);

	/* Hack -- Send the modifiers */
	if (mc) Term_keypress('C');
	if (ms) Term_keypress('S');
	if (ma) Term_keypress('A');

	/* Introduce the hexidecimal scan code */
	Term_keypress('x');

	/* Encode the hexidecimal scan code */
	Term_keypress(hexsym[s / 16]);
	Term_keypress(hexsym[s % 16]);

	/* End the "macro trigger" */
	Term_keypress(13);

	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 *
 * The given parameters are "valid".
 */
static errr Term_xtra_ibm(int n, int v)
{
	int i;

	/* Analyze the request */
	switch (n)
	{
		/* Make a "bell" noise */
	case TERM_XTRA_NOISE:
		{
			/* Make a bell noise */
			(void)write(1, "\007", 1);

			/* Success */
			return (0);
		}

		/* Set the cursor shape */
	case TERM_XTRA_SHAPE:
		{
			/* Set cursor shape */
			curs_set(v);

			/* Success */
			return (0);
		}

		/* Flush one line of output */
	case TERM_XTRA_FROSH:
		{

#ifdef USE_VIRTUAL

# ifdef USE_WAT

			/* Copy the virtual screen to the physical screen */
			memcpy(PhysicalScreen + (v*160), VirtualScreen + (v*160), 160);

# else /* USE_WAT */

			/* Apply the virtual screen to the physical screen */
			ScreenUpdateLine(VirtualScreen + ((v*cols) << 1), v);

# endif  /* USE_WAT */

#endif /* USE_VIRTUAL */

			/* Success */
			return (0);
		}

		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		{

#ifdef USE_CONIO

			/* Clear the screen */
			clrscr();

#else /* USE_CONIO */

			/* Clear each line (virtual or physical) */
			for (i = 0; i < rows; i++)
			{
				/* Clear the line */
				memcpy((VirtualScreen + ((i*cols) << 1)), wiper, (cols << 1));
			}

# ifdef USE_VIRTUAL

# ifdef USE_WAT

			/* Copy the virtual screen to the physical screen */
			memcpy(PhysicalScreen, VirtualScreen, 25*80*2);

# else /* USE_WAT */

			/* Erase the physical screen */
			ScreenClear();

# endif  /* USE_WAT */

# endif  /* USE_VIRTUAL */

#endif /* USE_CONIO */

			/* Success */
			return (0);
		}

		/* Process events */
	case TERM_XTRA_EVENT:
		{
			irc_poll();

			/* Process one event */
			return (Term_xtra_ibm_event(v));
		}

		/* Flush events */
	case TERM_XTRA_FLUSH:
		{
			/* Strip events */
			while (!Term_xtra_ibm_event(FALSE)) /* loop */;

			/* Success */
			return (0);
		}

		/* React to global changes */
	case TERM_XTRA_REACT:
		{
			/* React to "color_table" changes */
			return (Term_xtra_ibm_react());
		}

		/* Delay for some milliseconds */
	case TERM_XTRA_DELAY:
		{
			/* Delay if needed */
			if (v > 0) delay(v);

			/* Success */
			return (0);
		}

		/*
		 * Scans for subdirectories in a directory "scansubdir_dir"
		 * and place teh result in "scansubdir_result/scansubdir_max"
		 */
	case TERM_XTRA_SCANSUBDIR:
		{
			struct ffblk f;
			int done;

			done = findfirst(format("%s\\*", scansubdir_dir), &f, FA_DIREC);

			scansubdir_max = 0;
			while ((!done) && (scansubdir_max < 255))
			{
				if ((f.ff_attrib & FA_DIREC) && (strcmp(f.ff_name, ".")) && (strcmp(f.ff_name, "..")))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(f.ff_name);
					scansubdir_max++;
				}

				done = findnext(&f);
			}

			return 0;
		}
	}

	/* Unknown request */
	return (1);
}



/*
 * Move the cursor
 *
 * The given parameters are "valid".
 */
static errr Term_curs_ibm(int x, int y)
{

#ifdef USE_WAT

# ifdef USE_CONIO

	/* Place the cursor */
	gotoxy(x + 1, y + 1);

# else /* USE_CONIO */

	union REGS r;

	r.h.ah = 2;
	r.h.bh = 0;
	r.h.dl = x;
	r.h.dh = y;

	/* Place the cursor */
	int86(0x10, &r, &r);

# endif  /* USE_CONIO */

#else /* USE_WAT */

	/* Move the cursor */
	ScreenSetCursor(y, x);

#endif /* USE_WAT */

	/* Success */
	return (0);
}


/*
 * Erase a block of the screen
 *
 * The given parameters are "valid".
 */
static errr Term_wipe_ibm(int x, int y, int n)
{

#ifdef USE_CONIO

	/* Wipe the region */
	window(x + 1, y + 1, x + n, y + 1);
	clrscr();
	window(1, 1, cols, rows);

#else /* USE_CONIO */

	/* Wipe part of the virtual (or physical) screen */
	memcpy(VirtualScreen + ((cols*y + x) << 1), wiper, n << 1);

#endif /* USE_CONIO */

	/* Success */
	return (0);
}


/*
 * Place some text on the screen using an attribute
 *
 * The given parameters are "valid".  Be careful with "a".
 *
 * The string "cp" has length "n" and is NOT null-terminated.
 */
static errr Term_text_ibm(int x, int y, int n, byte a, const char *cp)
{
	register int i;
	register byte attr;
	register byte *dest;


	/* Handle "complex" color */
	if (use_color_complex)
	{
		/* Extract a color index */
		attr = (a & 0x0F);
	}

	/* Handle "simple" color */
	else
	{
		/* Extract a color value */
		attr = ibm_color_simple[a & 0x0F];
	}

#ifdef USE_CONIO

	/* Place the cursor */
	gotoxy(x + 1, y + 1);

	/* Set the attribute */
	textattr(attr);

	/* Dump the text */
	for (i = 0; i < n; i++) putch(cp[i]);

#else /* USE_CONIO */

	/* Access the virtual (or physical) screen */
	dest = VirtualScreen + (((cols * y) + x) << 1);

	/* Save the data */
	for (i = 0; i < n; i++)
	{
		/* Apply */
		*dest++ = cp[i];
		*dest++ = attr;
	}

#endif /* USE_CONIO */

	/* Success */
	return (0);
}


/*
 * Place some attr/char pairs on the screen
 *
 * The given parameters are "valid".
 */
#ifdef USE_TRANSPARENCY
static errr Term_pict_ibm(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
#else /* USE_TRANSPARENCY */
static errr Term_pict_ibm(int x, int y, int n, const byte *ap, const char *cp)
#endif /* USE_TRANSPARENCY */
{
	register int i;
	register byte attr;
	register byte *dest;


#ifdef USE_CONIO

	/* Place the cursor */
	gotoxy(x + 1, y + 1);

	/* Dump the text */
	for (i = 0; i < n; i++)
	{
		/* Handle "complex" color */
		if (use_color_complex)
		{
			/* Extract a color index */
			attr = (ap[i] & 0x0F);
		}

		/* Handle "simple" color */
		else
		{
			/* Extract a color value */
			attr = ibm_color_simple[ap[i] & 0x0F];
		}

		/* Set the attribute */
		textattr(attr);

		/* Dump the char */
		putch(cp[i]);
	}

#else /* USE_CONIO */

	/* Access the virtual (or physical) screen */
	dest = VirtualScreen + (((cols * y) + x) << 1);

	/* Save the data */
	for (i = 0; i < n; i++)
	{
		/* Handle "complex" color */
		if (use_color_complex)
		{
			/* Extract a color index */
			attr = (ap[i] & 0x0F);
		}

		/* Handle "simple" color */
		else
		{
			/* Extract a color value */
			attr = ibm_color_simple[ap[i] & 0x0F];
		}

		/* Apply */
		*dest++ = cp[i];
		*dest++ = attr;
	}

#endif /* USE_CONIO */

	/* Success */
	return (0);
}


/*
 * Init a Term
 */
static void Term_init_ibm(term *t)
{
	/* XXX Nothing */
}


/*
 * Nuke a Term
 */
static void Term_nuke_ibm(term *t)
{

#ifdef USE_WAT

	/* Nothing */

#else /* USE_WAT */

	union REGS r;

#endif /* USE_WAT */

	/* Move the cursor to the bottom of the screen */
	Term_curs_ibm(0, rows - 1);

#ifdef USE_WAT

	/* Restore the original video mode */
	_setvideomode(_DEFAULTMODE);

#else /* USE_WAT */

	/* Restore the original video mode */
	r.h.ah = 0x00;
	r.h.al = 0x03;
	int86(0x10, &r, &r);

#endif /* USE_WAT */

	/* Make the cursor visible */
	curs_set(1);
}



#ifdef USE_GRAPHICS

#ifdef USE_286

/*
 * In 286 mode we don't need to worry about translating from a 32bit
 * pointer to a 16 bit pointer so we just call the interrupt function
 *
 * Note the use of "intr()" instead of "int86()" so we can pass
 * segment registers.
 */
void enable_graphic_font(void *font)
{
	union REGPACK regs =
		        {0};

	regs.h.ah = 0x11;            /* Text font function */
	regs.h.bh = 0x10;            /* Size of a character -- 16 bytes */
	regs.h.cl = 0xFF;            /* Last character in font */
	regs.x.es = FP_SEG(font);    /* Pointer to font */
	regs.x.bp = FP_OFF(font);
	intr(0x10, ®s);
}

#else /* USE_286 */

#ifdef USE_WAT

/*
* This structure is used by the DMPI function to hold registers when
* doing a real mode interrupt call.  (Stolen from the DJGPP 
                                      * header file).
*/

typedef union
{
	struct
	{
		unsigned long edi;
		unsigned long esi;
		unsigned long ebp;
		unsigned long res;
		unsigned long ebx;
		unsigned long edx;
		unsigned long ecx;
		unsigned long eax;
	}
	d;
	struct
	{
		unsigned short di, di_hi;
		unsigned short si, si_hi;
		unsigned short bp, bp_hi;
		unsigned short res, res_hi;
		unsigned short bx, bx_hi;
		unsigned short dx, dx_hi;
		unsigned short cx, cx_hi;
		unsigned short ax, ax_hi;
		unsigned short flags;
		unsigned short es;
		unsigned short ds;
		unsigned short fs;
		unsigned short gs;
		unsigned short ip;
		unsigned short cs;
		unsigned short sp;
		unsigned short ss;
	}
	x;
	struct
	{
		unsigned char edi[4];
		unsigned char esi[4];
		unsigned char ebp[4];
		unsigned char res[4];
		unsigned char bl, bh, ebx_b2, ebx_b3;
		unsigned char dl, dh, edx_b2, edx_b3;
		unsigned char cl, ch, ecx_b2, ecx_b3;
		unsigned char al, ah, eax_b2, eax_b3;
	}
	h;
} __dpmi_regs;

unsigned __dpmi_allocate_dos_memory(int size, unsigned *selector)
{
	union REGPACK regs =
		        {0};

	regs.w.ax = 0x100;    /* DPMI function -- allocate low memory */
	regs.w.bx = size;     /* Number of Paragraphs to allocate */
	intr(0x31, ®s);     /* DPMI interface */

	*selector = regs.w.dx;
	return (regs.w.ax);
}

void __dpmi_free_dos_memory(unsigned sel)
{
	union REGPACK regs =
		        {0};

	regs.w.ax = 0x101;       /* DPMI function -- free low memory */
	regs.x.edx = sel;         /* PM selector for memory block */
	intr(0x31, ®s);        /* DPMI interface */
}

void __dpmi_int(int intno, __dpmi_regs *dblock)
{
	union REGPACK regs =
		        {0};

	regs.w.ax = 0x300;            /* DPMI function -- real mode interrupt */
	regs.h.bl = intno;            /* interrupt 0x10 */
	regs.x.edi = FP_OFF(dblock);   /* Pointer to dblock (offset and segment) */
	regs.x.es = FP_SEG(dblock);
	intr(0x31, ®s);             /* DPMI interface */
}

unsigned short __dpmi_sel = 0x0000;
#define _farsetsel(x) __dpmi_sel=(x)
extern void _farnspokeb(unsigned long offset, unsigned char value);
#pragma aux _farnspokeb = \
"push   fs" \
"mov    fs,__dpmi_sel" \
"mov    fs:[eax],bl" \
"pop    fs" \
parm [eax] [bl]; 

#else /* USE_WAT */

#include 
#include 
#include 

#endif /* USE_WAT */


/*
* Since you cannot send 32bit pointers to a 16bit interrupt handler
* and the video BIOS wants a (16bit) pointer to the font, we have
* to allocate a block of dos memory, copy the font into it, then
* translate a 32bit pointer into a 16bit pointer to that block.
*
* DPMI - Dos Protected Mode Interface provides functions that let
*        us do that.
*/
void enable_graphic_font(const char *font)
{
	__dpmi_regs dblock = {{0}};

	unsigned seg, sel, i;

	/*
	* Allocate a block of memory 4096 bytes big in `low memory' so a real
	* mode interrupt can access it.  Real mode pointer is returned as seg:0
	* Protected mode pointer is sel:0.
	*/
	seg = __dpmi_allocate_dos_memory(256, &sel);

	/* Copy the information into low memory buffer, by copying one byte at
	* a time.  According to the info in , the functions
	* _farsetsel() and _farnspokeb() will optimise away completely
	*/
	_farsetsel(sel);                /* Set the selector to write to */
	for (i = 0; i < 4096; i++)
	{
		_farnspokeb(i, *font++);       /* Copy 1 byte into low (far) memory */
	}

	/*
	* Now we use DPMI as a jumper to call the real mode interrupt.  This
	* is needed because loading `es' while in protected mode with a real
	* mode pointer will cause an Protection Fault and calling the interrupt
	* directly using the protected mode pointer will result in garbage
	* being received by the interrupt routine
	*/
	dblock.d.eax = 0x1100;          /* BIOS function -- set font */
	dblock.d.ebx = 0x1000;          /* bh = size of a letter; bl = 0 (reserved) */
	dblock.d.ecx = 0x00FF;          /* Last character in font */
	dblock.x.es = seg;             /* Pointer to font segment */
	dblock.d.ebp = 0x0000;          /* Pointer to font offset */

	__dpmi_int(0x10, &dblock);

	/* We're done with the low memory, free it */
	__dpmi_free_dos_memory(sel);
}

#endif /* USE_286 */

#endif /* ALLOW_GRAPH */

#ifdef USE_DOSSOCK
void *zsock_connect(char *hos, short port)
{
	struct hostent *host;
	struct sockaddr_in sin;
	int *client;

	MAKE(client, int);
	*client = socket(AF_INET, SOCK_STREAM, 0);

	host = gethostbyname(hos);

	memset(&sin, 0, sizeof sin);
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
	sin.sin_port = htons(port);

	if (connect(*client, (struct sockaddr*)&sin, sizeof sin) == -1)
	{
		/* could not connect to server */
		return NULL;
	}

	return client;
}

bool zsock_can_read(void *client)
{
	struct timeval t;
	fd_set rd;
	int *c = client;

	FD_ZERO(&rd);
	FD_SET(*c, &rd);
	t.tv_sec = 0;
	t.tv_usec = 0;
	select(*c + 1, &rd, NULL, NULL, &t);
	if (FD_ISSET(*c, &rd)) return TRUE;
	else return (FALSE);
}

bool zsock_wait(void *client)
{
	struct timeval t;
	fd_set rd;
	int *c = client;

	t.tv_sec = 30;
	t.tv_usec = 0;

	FD_ZERO(&rd);
	FD_SET(*c, &rd);
	select(*c + 1, &rd, NULL, NULL, &t);
	if (FD_ISSET(*c, &rd)) return TRUE;
	else return (FALSE);
}

void zsock_disconnect(void *client)
{
	close(*(int*)client);
	FREE(client, int);
}

void zsock_send(void *sock, char *str)
{
	send(*(int*)sock, str, strlen(str), 0);
}

void zsock_recv(void *sock, char *str, int len)
{
	char c;
	int l = 0;

	while ((l < len) && zsock_can_read(sock))
	{
		if (!recv(*(int*)sock, &c, 1, 0))
		{
			irc_disconnect();
			break;
		}
		if (c == '\r') continue;
		if (c == '\n') break;
		str[l++] = c;
	}
	str[l] = '\0';
}
#endif


/*
 * Initialize the IBM "visual module"
 *
 * Hack -- we assume that "blank space" should be "white space"
 * (and not "black space" which might make more sense).
 *
 * Note the use of "((x << 2) | (x >> 4))" to "expand" a 6 bit value
 * into an 8 bit value, without losing much precision, by using the 2
 * most significant bits as the least significant bits in the new value.
 */
errr init_ibm(void)
{
	int i;
	int mode;

	term *t = &term_screen_body;

	union REGS r;

	/* Check for "Windows" */
	if (getenv("windir"))
	{
		r.h.ah = 0x16;            /* Windows API Call -- Set device focus */
		r.h.al = 0x8B;            /* Causes Dos boxes to become fullscreen */
		r.h.bh = r.h.bl = 0x00;   /* 0x0000 = current Dos box */
		int86(0x2F, &r, &r);        /* Call the Windows API */
	}

	/* Initialize "color_table" */
	for (i = 0; i < 16; i++)
	{
		long rv, gv, bv;

		/* Extract desired values */
		rv = angband_color_table[i][1] >> 2;
		gv = angband_color_table[i][2] >> 2;
		bv = angband_color_table[i][3] >> 2;

		/* Extract the "complex" codes */
		ibm_color_complex[i] = ((rv) | (gv << 8) | (bv << 16));

		/* Save the "simple" codes */
		angband_color_table[i][0] = ibm_color_simple[i];
	}

#ifdef USE_WAT

	/* Set the video mode */
	if (_setvideomode(_VRES16COLOR))
	{
		mode = 0x13;
	}

	/* Wimpy monitor */
	else
	{
		mode = 0x03;
	}

	/* Force 25 line mode */
	_setvideomode(_TEXTC80);
	_settextrows(25);

#else /* USE_WAT */

	/* Set video mode */
	r.h.ah = 0x00;
	r.h.al = 0x13;  /* VGA only mode */
	int86(0x10, &r, &r);

	/* Get video mode */
	r.h.ah = 0x0F;
	int86(0x10, &r, &r);
	mode = r.h.al;

	/* Set video mode */
	r.h.ah = 0x00;
	r.h.al = 0x03;  /* Color text mode */
	int86(0x10, &r, &r);

#endif /* USE_WAT */

	/* Check video mode */
	if (mode == 0x13)
	{
		/* Remember the mode */
		use_color_complex = TRUE;

		/* Instantiate the color set */
		activate_color_complex();
	}

#ifdef USE_GRAPHICS

	/* Try to activate bitmap graphics */
	if (arg_graphics && use_color_complex)
	{
		FILE *f;

		char buf[4096];

		/* Build the filename */
		path_build(buf, 1024, ANGBAND_DIR_XTRA, "angband.fnt");

		/* Open the file */
		f = fopen(buf, "rb");

		/* Okay */
		if (f)
		{
			/* Load the bitmap data */
			if (fread(buf, 1, 4096, f) != 4096)
			{
				quit("Corrupt 'angband.fnt' file");
			}

			/* Close the file */
			fclose(f);

			/* Enable graphics */
			enable_graphic_font(buf);

			/* Enable colors (again) */
			activate_color_complex();

			/* Use graphics */
			use_graphics = TRUE;
		}
	}

#endif

#ifdef USE_CONIO
#else /* USE_CONIO */

	/* Build a "wiper line" */
	for (i = 0; i < 80; i++)
	{
		/* Space */
		wiper[2*i] = ' ';

		/* Black */
		wiper[2*i + 1] = TERM_WHITE;
	}

#endif /* USE_CONIO */


#ifdef USE_VIRTUAL

	/* Make the virtual screen */
	C_MAKE(VirtualScreen, rows * cols * 2, byte);

#endif /* USE_VIRTUAL */


	/* Erase the screen */
	Term_xtra_ibm(TERM_XTRA_CLEAR, 0);


	/* Place the cursor */
	Term_curs_ibm(0, 0);


	/* Access the "default" cursor info */
	r.h.ah = 3;
	r.h.bh = 0;

	/* Make the call */
	int86(0x10, &r, &r);

	/* Extract the standard cursor info */
	saved_cur_v = 1;
	saved_cur_high = r.h.ch;
	saved_cur_low = r.h.cl;


	/* Initialize the term */
	term_init(t, 80, 24, 256);

#ifdef USE_CONIO
#else /* USE_CONIO */

	/* Always use "Term_pict()" */
	t->always_pict = TRUE;

#endif /* USE_CONIO */

	/* Use "white space" to erase */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Prepare the init/nuke hooks */
	t->init_hook = Term_init_ibm;
	t->nuke_hook = Term_nuke_ibm;

	/* Connect the hooks */
	t->xtra_hook = Term_xtra_ibm;
	t->curs_hook = Term_curs_ibm;
	t->wipe_hook = Term_wipe_ibm;
	t->text_hook = Term_text_ibm;
	t->pict_hook = Term_pict_ibm;

	/* Save it */
	term_screen = t;

	/* Activate it */
	Term_activate(term_screen);

	/* Success */
	return 0;
}


#endif /* USE_IBM */
tome-235-src/src/main-mac.c0000644000076400017500000031526011012107763013312 0ustar  dgdg/* File: main-mac.c */

/*
 * Copyright (c) 1997 Ben Harrison, Keith Randall, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband work with Macintosh computers.
 *
 * To use this file, use an appropriate "Makefile" or "Project File", which
 * should define "MACINTOSH".
 *
 * The official compilation uses the CodeWarrior Pro compiler.
 *
 * If you are never going to use "graphics" (especially if you are not
 * compiling support for graphics anyway) then you can delete the "pict"
 * resource with id "1001" with no dangerous side effects.
 *
 *
 * By default, this file assumes that you will be using a 68020 or better
 * machine, running System 7 and Color Quickdraw.  In fact, the game will
 * refuse to run unless these features are available.  This allows the use
 * of a variety of interesting features such as graphics and sound.
 *
 * To create a version which can be used on 68000 machines, or on machines
 * which are not running System 7 or Color Quickdraw, simply activate the
 * "ANGBAND_LITE_MAC" compilation flag in the proper header file.  This
 * will disable all "modern" features used in this file, including support
 * for multiple sub-windows, color, graphics, and sound.
 *
 * When compiling with the "ANGBAND_LITE_MAC" flag, the "ANGBAND_LITE"
 * flag will be automatically defined, which will disable many of the
 * advanced features of the game itself, reducing the total memory usage.
 *
 *
 * Note that the "preference" file is now a simple text file called
 * "Angband Preferences", which contains a version stamp, so that
 * obsolete preference files can be ignored.  This should probably
 * be replaced with a "structured" preference file of some kind.
 *
 * Note that "init1.c", "init2.c", "load1.c", "load2.c", and "birth.c"
 * should probably be "unloaded" as soon as they are no longer needed,
 * to save space, but I do not know how to do this.  XXX XXX XXX
 *
 * Stange bug -- The first "ClipRect()" call crashes if the user closes
 * all the windows, switches to another application, switches back, and
 * re-opens the main window, for example, using "command-a".  XXX XXX XXX
 *
 *
 * Initial framework (and most code) by Ben Harrison (benh@phial.com).
 *
 * Some code adapted from "MacAngband 2.6.1" by Keith Randall
 *
 * Initial PowerMac port by Maarten Hazewinkel (mmhazewi@cs.ruu.nl).
 *
 * Most "USE_SFL_CODE" code provided by Steve Linberg (slinberg@crocker.com).
 *
 * Most of the graphics code is adapted from an extremely minimal subset of
 * the "Sprite World II" package, an amazing (and free) animation package.
 *
 *
 * Important Resources in the resource file:
 *
 *   FREF 130 = ANGBAND_CREATOR / 'APPL' (application)
 *   FREF 129 = ANGBAND_CREATOR / 'SAVE' (save file)
 *   FREF 130 = ANGBAND_CREATOR / 'TEXT' (bone file, generic text file)
 *   FREF 131 = ANGBAND_CREATOR / 'DATA' (binary image file, score file)
 *
 *   DLOG 128 = "About Angband..."
 *
 *   ALRT 128 = unused (?)
 *   ALRT 129 = "Warning..."
 *   ALRT 130 = "Are you sure you want to quit without saving?"
 *
 *   DITL 128 = body for DLOG 128
 *   DITL 129 = body for ALRT 129
 *   DITL 130 = body for ALRT 130
 *
 *   ICON 128 = "warning" icon
 *
 *   MENU 128 = apple (about, -, ...)
 *   MENU 129 = File (new, open, close, save, -, score, exit, quit)
 *     In T.o.M.E.
 *   MENU 129 = File (close, save, -, score, exit, quit)
 *   MENU 130 = Edit (undo, -, cut, copy, paste, clear)
 *   MENU 131 = Font (bold, wide, -)
 *   MENU 132 = Size ()
 *   MENU 133 = Windows ()
 *   MENU 134 = Special (Sound, Graphics, TileWidth, TileHeight, -, Fiddle, Wizard)
 *              Graphics have following submenu attached:
 *   MENU 144 = Graphics (None, 8x8, 16x16)
 *              TileWidth and TileHeight submenus are filled in by this program
 *   MENU 145 = TileWidth ()
 *   MENU 146 = TileHeight ()
 *
 *   PICT 1001 = Graphics tile set (8x8)
 *   PICT 1002 = Graphics tile set (16x16 images)
 *
 * Note: You can no longer use the exit menu unless you build the programme
 *       with an appropriate compile-time option.
 *
 *
 * File name patterns:
 *   all 'APEX' files have a filename of the form "*:apex:*" (?)
 *   all 'BONE' files have a filename of the form "*:bone:*" (?)
 *   all 'DATA' files have a filename of the form "*:data:*"
 *   all 'SAVE' files have a filename of the form "*:save:*"
 *   all 'USER' files have a filename of the form "*:user:*" (?)
 *
 * Perhaps we should attempt to set the "_ftype" flag inside this file,
 * to avoid nasty file type information being spread all through the
 * rest of the code.  (?)  This might require adding hooks into the
 * "fd_open()" and "my_fopen()" functions in "util.c".  XXX XXX XXX
 *
 *
 * Reasons for each header file:
 *
 *   angband.h = Angband header file
 *
 *   Types.h = (included anyway)
 *   Gestalt.h = gestalt code
 *   QuickDraw.h = (included anyway)
 *   OSUtils.h = (included anyway)
 *   Files.h = file code
 *   Fonts.h = font code
 *   Menus.h = menu code
 *   Dialogs.h = dialog code
 *   Windows.h = (included anyway)
 *   Palettes.h = palette code
 *   StandardFile.h = file dialog box
 *   DiskInit.h = disk initialization
 *   ToolUtils.h = HiWord() / LoWord()
 *   Desk.h = OpenDeskAcc()
 *   Devices.h = OpenDeskAcc()
 *   Events.h = event code
 *   Resources.h = resource code
 *   Controls.h = button code
 *   SegLoad.h = ExitToShell(), AppFile, etc
 *   Memory.h = SetApplLimit(), NewPtr(), etc
 *   QDOffscreen.h = GWorld code
 *   Sound.h = Sound code
 *
 * For backwards compatibility:
 *   Use GestaltEqu.h instead of Gestalt.h
 *   Add Desk.h to include simply includes Menus.h, Devices.h, Events.h
 */


#include "angband.h"


#ifdef MACINTOSH

/*
 * Variant-dependent features:
 *
 * #define ALLOW_BIG_SCREEN (V, Ey, O, T.o.M.E. and Z.
 *   Dr's big screen needs more work.  New S one needs some thought)
 * #define ANG281_RESET_VISUALS (Cth, Gum, T.o.M.E., Z)
 * #define SAVEFILE_SCREEN (T.o.M.E.)
 * #define USE_DOUBLE_TILES ("bigtile" patch, V and T.o.M.E.
 *   T requires #define TOME in addition to this)
 * #define ZANG_AUTO_SAVE (O and Z)
 * #define HAS_SCORE_MENU (V and T.o.M.E.)
 * #define ANGBAND_PREFERENCES "_your_variant_name_ Preferences"
 * #define ANGBAND_CREATOR four letter code for your variant, if any.
 *  or use the default one.
 *
 * In [Z], please replace inkey_flag with p_ptr->inkey_flag as well.
 */

/* Some porting examples */
#ifdef ANGBAND30X
# define USE_DOUBLE_TILES
# define ALLOW_BIG_SCREEN
# define HAS_SCORE_MENU
# define NEW_ZVIRT_HOOKS
/* I can't ditch this, yet, because there are many variants */
# define USE_TRANSPARENCY
#endif /* ANGBAND30X */

#ifdef TOME
# define USE_DOUBLE_TILES
# define SAVEFILE_SCREEN
# define ANG281_RESET_VISUALS
# define ALLOW_BIG_SCREEN
# define HAS_SCORE_MENU
# define ANGBAND_CREATOR 'PrnA'
# define ANGBAND_PREFERENCES "T.o.M.E. Preferences"
#endif /* TOME */

/* Default creator signature */
# ifndef ANGBAND_CREATOR
# define ANGBAND_CREATOR 'A271'
# endif 

/* Default preferences file name */
# ifndef ANGBAND_PREFERENCES
# define ANGBAND_PREFERENCES "Angband Preferences"
# endif 


/*
 * To cope with pref file related problems
 *
 * Please note that some variants don't set them to "real" version number
 * and uses other defines for that purpose.
 *
 * This is *very* important for Classic ports, because wrong pref file formats
 * can crash the system.
 */
#ifndef PREF_VER_MAJOR
# define PREF_VER_MAJOR VERSION_MAJOR
#endif
#ifndef PREF_VER_MINOR
# define PREF_VER_MINOR VERSION_MINOR
#endif
#ifndef PREF_VER_PATCH
# define PREF_VER_PATCH VERSION_PATCH
#endif
#ifndef PREF_VER_EXTRA
# define PREF_VER_EXTRA VERSION_EXTRA
#endif


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


/*
 * Use "malloc()" instead of "NewPtr()"
 */
/* #define USE_MALLOC */


#if defined(powerc) || defined(__powerc)

/*
 * Disable "LITE" version
 */
# undef ANGBAND_LITE_MAC

#endif


#ifndef ANGBAND_LITE_MAC

/*
 * Activate some special code
 */
# define USE_SFL_CODE

#endif /* ANGBAND_LITE_MAC */



#ifdef USE_SFL_CODE

/*
 * Include the necessary header files
 */
#include 
#include 
#include 

#endif


#ifdef ANGBAND_LITE_MAC

/*
 * Everything in drawn as white on black
 */

#else /* ANGBAND_LITE_MAC */

/*
* Information about each of the 256 available colors
*/
static RGBColor color_info[256];

#endif /* ANGBAND_LITE_MAC */


/*
 * Forward declare
 */
typedef struct term_data term_data;

/*
 * Extra "term" data
 */
struct term_data
{
	term *t;

	Rect r;

	WindowPtr w;

#ifdef ANGBAND_LITE_MAC

	/* Nothing */

#else /* ANGBAND_LITE_MAC */

	short padding;

	short pixelDepth;

	GWorldPtr theGWorld;

	GDHandle theGDH;

	GDHandle mainSWGDH;

#endif /* ANGBAND_LITE_MAC */

	Str15 title;

	s16b oops;

	s16b keys;

	s16b last;

	s16b mapped;

	s16b rows;
	s16b cols;

	s16b font_id;
	s16b font_size;
	s16b font_face;
	s16b font_mono;

	s16b font_o_x;
	s16b font_o_y;
	s16b font_wid;
	s16b font_hgt;

	s16b tile_o_x;
	s16b tile_o_y;
	s16b tile_wid;
	s16b tile_hgt;

	s16b size_wid;
	s16b size_hgt;

	s16b size_ow1;
	s16b size_oh1;
	s16b size_ow2;
	s16b size_oh2;
};




#ifdef MAC_MPW

/*
 * MPW 68K compiler cannot process ToME's variable.c correctly...
 * but support for it is here, for your reference. I have tried
 * this with SC and MrC to compile Vanilla successfully.
 */
QDGlobals qd;

/*
 * File type assigner - declare them in externs.h as well.
 *
 * You still have to call
 *	fsetfileinfo(buf, _fcreator, _ftype);
 * in fd_make() and my_fopen() to assign creator and type
 * to a file.
 */
u32b _ftype;
u32b _fcreator;

/*
 * Since MPW's C library doesn't have stat or fstat, you have to
 * disable CHECK_MODIFICATION_TIME in config.h
 *
 * Another source code change required for MPW compilation is
 * to #define MACINTOSH and #undef __STDC__
 * This can be done conveniently in h-system.h
 *
 * You may have to cast some pointers to non-offending types e.g. (void *).
 * This typically occurs when passing a const pointer to a library
 * function whose prototype doesn't have const in corresponding
 * parameter.
 */

#endif /* MAC_MPW */


/*
 * Forward declare -- see below
 */
static bool CheckEvents(bool wait);


/*
 * Hack -- location of the main directory
 */
static short app_vol;
static long app_dir;


/*
 * Delay handling of double-clicked savefiles
 */
Boolean open_when_ready = FALSE;

/*
 * Delay handling of pre-emptive "quit" event
 */
Boolean quit_when_ready = FALSE;


/*
 * Hack -- game in progress
 */
static int game_in_progress = 0;


/*
 * Only do "SetPort()" when needed
 */
static WindowPtr active = NULL;


/*
 * Maximum number of terms
 */
#define MAX_TERM_DATA 8


/*
 * An array of term_data's
 */
static term_data data[MAX_TERM_DATA];



/*
 * Note when "open"/"new" become valid
 */
static bool initialized = FALSE;



#ifdef ALLOW_NO_SAVE_QUITS

/*
 * CodeWarrior uses Universal Procedure Pointers
 */
static ModalFilterUPP ynfilterUPP;

#endif /* ALLOW_NO_SAVE_QUITS */



#ifdef USE_SFL_CODE

/*
 * Apple Event Hooks
 */
AEEventHandlerUPP AEH_Start_UPP;
AEEventHandlerUPP AEH_Quit_UPP;
AEEventHandlerUPP AEH_Print_UPP;
AEEventHandlerUPP AEH_Open_UPP;

#endif



/*
 * Convert a C string to a pascal string in place
 *
 * This function may be defined elsewhere, but since it is so
 * small, it is not worth finding the proper function name for
 * all the different platforms.
 */
static void ctopstr(StringPtr src)
{
	int i;
	byte len;

	/* Hack -- pointer */
	char *s = (char*)(src);

	len = strlen(s);

	/* Hack -- convert the string */
	for (i = len; i > 1; i--) s[i] = s[i - 1];

	/* Hack -- terminate the string */
	s[0] = len;
}


/*
 * Convert refnum+vrefnum+fname into a full file name
 * Store this filename in 'buf' (make sure it is long enough)
 * Note that 'fname' looks to be a "pascal" string
 */
static void refnum_to_name(char *buf, long refnum, short vrefnum, char *fname)
{
	DirInfo pb;
	Str255 name;
	int err;
	int i, j;

	char res[1000];

	i = 999;

	res[i] = 0;
	i--;
	for (j = 1; j <= fname[0]; j++)
	{
		res[i - fname[0] + j] = fname[j];
	}
	i -= fname[0];

	pb.ioCompletion = NULL;
	pb.ioNamePtr = name;
	pb.ioVRefNum = vrefnum;
	pb.ioDrParID = refnum;
	pb.ioFDirIndex = -1;

	while (1)
	{
		pb.ioDrDirID = pb.ioDrParID;
		err = PBGetCatInfoSync((CInfoPBPtr) & pb);
		res[i] = ':';
		i--;
		for (j = 1; j <= name[0]; j++)
		{
			res[i - name[0] + j] = name[j];
		}
		i -= name[0];

		if (pb.ioDrDirID == fsRtDirID) break;
	}

	/* Extract the result */
	for (j = 0, i++; res[i]; j++, i++) buf[j] = res[i];
	buf[j] = 0;
}


#if 0

/*
 * XXX XXX XXX Allow the system to ask us for a filename
 */
static bool askfor_file(char *buf, int len)
{
	SFReply reply;
	Str255 dflt;
	Point topleft;
	short vrefnum;
	long drefnum, junk;

	/* Default file name */
	strnfmt((char*)dflt + 1, 255, "%s's description", buf);
	dflt[0] = strlen((char*)dflt + 1);

	/* Ask for a file name */
	topleft.h = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) / 2 - 344 / 2;
	topleft.v = (2 * qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) / 3 - 188 / 2;
	SFPutFile(topleft, "\pSelect a filename:", dflt, NULL, &reply);
	/* StandardPutFile("\pSelect a filename:", dflt, &reply); */

	/* Process */
	if (reply.good)
	{
		int fc;

		/* Get info */
		GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);

		/* Extract the name */
		refnum_to_name(buf, drefnum, vrefnum, (char*)reply.fName);

		/* Success */
		return (TRUE);
	}

	/* Failure */
	return (FALSE);
}

#endif



/*
 * Center a rectangle inside another rectangle
 */
static void center_rect(Rect *r, Rect *s)
{
	int centerx = (s->left + s->right) / 2;
	int centery = (2 * s->top + s->bottom) / 3;
	int dx = centerx - (r->right - r->left) / 2 - r->left;
	int dy = centery - (r->bottom - r->top) / 2 - r->top;
	r->left += dx;
	r->right += dx;
	r->top += dy;
	r->bottom += dy;
}


/*
 * Convert a pascal string in place
 *
 * This function may be defined elsewhere, but since it is so
 * small, it is not worth finding the proper function name for
 * all the different platforms.
 */
static void ptocstr(StringPtr src)
{
	int i;

	/* Hack -- pointer */
	char *s = (char*)(src);

	/* Hack -- convert the string */
	for (i = s[0]; i; i--, s++) s[0] = s[1];

	/* Hack -- terminate the string */
	s[0] = '\0';
}


#if defined(USE_SFL_CODE)


/*
 * The following three routines (pstrcat, pstrinsert, and PathNameFromDirID)
 * were taken from the Think Reference section called "Getting a Full Pathname"
 * (under the File Manager section).  We need PathNameFromDirID to get the
 * full pathname of the opened savefile, making no assumptions about where it
 * is.
 *
 * I had to hack PathNameFromDirID a little for MetroWerks, but it's awfully
 * nice.
 */
static void pstrcat(StringPtr dst, StringPtr src)
{
	/* copy string in */
	BlockMove(src + 1, dst + *dst + 1, *src);

	/* adjust length byte */
	*dst += *src;
}

/*
 * pstrinsert - insert string 'src' at beginning of string 'dst'
 */
static void pstrinsert(StringPtr dst, StringPtr src)
{
	/* make room for new string */
	BlockMove(dst + 1, dst + *src + 1, *dst);

	/* copy new string in */
	BlockMove(src + 1, dst + 1, *src);

	/* adjust length byte */
	*dst += *src;
}

static void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
{
	CInfoPBRec block;
	Str255 directoryName;
	OSErr err;

	fullPathName[0] = '\0';

	block.dirInfo.ioDrParID = dirID;
	block.dirInfo.ioNamePtr = directoryName;

	while (1)
	{
		block.dirInfo.ioVRefNum = vRefNum;
		block.dirInfo.ioFDirIndex = -1;
		block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
		err = PBGetCatInfoSync(&block);
		pstrcat(directoryName, (StringPtr)"\p:");
		pstrinsert(fullPathName, directoryName);
		if (block.dirInfo.ioDrDirID == 2) break;
	}
}

#endif



/*
 * Activate a given window, if necessary
 */
static void activate(WindowPtr w)
{
	/* Activate */
	if (active != w)
	{
		/* Activate */
		if (w) SetPort(w);

		/* Remember */
		active = w;
	}
}


/*
 * Display a warning message
 */
static void mac_warning(cptr warning)
{
	Str255 text;
	int len, i;

	/* Limit of 250 chars */
	len = strlen(warning);
	if (len > 250) len = 250;

	/* Make a "Pascal" string */
	text[0] = len;
	for (i = 0; i < len; i++) text[i + 1] = warning[i];

	/* Prepare the dialog box values */
	ParamText(text, "\p", "\p", "\p");

	/* Display the Alert, wait for Okay */
	Alert(129, 0L);
}



/*** Some generic functions ***/


#ifdef ANGBAND_LITE_MAC

/*
 * Hack -- activate a color (0 to 255)
 */
#define term_data_color(TD,A) /* Nothing */

#else /* ANGBAND_LITE_MAC */

/*
* Hack -- activate a color (0 to 255)
*/
static void term_data_color(term_data *td, int a)
{
	/* Activate the color */
	if (td->last != a)
	{
		/* Activate the color */
		RGBForeColor(&color_info[a]);

		/* Memorize color */
		td->last = a;
	}
}

#endif /* ANGBAND_LITE_MAC */


/*
 * Hack -- Apply and Verify the "font" info
 *
 * This should usually be followed by "term_data_check_size()"
 *
 * XXX XXX To force (re)initialisation of td->tile_wid and td->tile_hgt
 * you have to reset them to zero before this function is called.
 * XXX XXX This is automatic when the program starts because the term_data
 * array is WIPE'd by term_data_hack, but isn't in the other cases, i.e.
 * font, font style and size changes.
 */
static void term_data_check_font(term_data *td)
{
	int i;

	FontInfo info;

	WindowPtr old = active;


	/* Activate */
	activate(td->w);

	/* Instantiate font */
	TextFont(td->font_id);
	TextSize(td->font_size);
	TextFace(td->font_face);

	/* Extract the font info */
	GetFontInfo(&info);

	/* Assume monospaced */
	td->font_mono = TRUE;

	/* Extract the font sizing values XXX XXX XXX */
	td->font_wid = CharWidth('@');  /* info.widMax; */
	td->font_hgt = info.ascent + info.descent;
	td->font_o_x = 0;
	td->font_o_y = info.ascent;

	/* Check important characters */
	for (i = 33; i < 127; i++)
	{
		/* Hack -- notice non-mono-space */
		if (td->font_wid != CharWidth(i)) td->font_mono = FALSE;

		/* Hack -- collect largest width */
		if (td->font_wid < CharWidth(i)) td->font_wid = CharWidth(i);
	}

	/* Set default offsets */
	td->tile_o_x = td->font_o_x;
	td->tile_o_y = td->font_o_y;

	/* Set default tile size */
	if (td->tile_wid == 0) td->tile_wid = td->font_wid;
	if (td->tile_hgt == 0) td->tile_hgt = td->font_hgt;

	/* Re-activate the old window */
	activate(old);
}


/*
 * Hack -- Apply and Verify the "size" info
 */
static void term_data_check_size(term_data *td)
{
	/* Minimal window size for the Angband window */
	if (td == &data[0])
	{
#ifdef ALLOW_BIG_SCREEN

		/* Enforce minimal size */
		if (td->cols < 80) td->cols = 80;
		if (td->rows < 24) td->rows = 24;

#else

		/* Enforce the traditional size */
		if (td->cols != 80) td->cols = 80;
		if (td->rows != 24) td->rows = 24;

#endif /* ALLOW_BIG_SCREEN */
	}

	/* Allow small windows for the rest */
	else
	{
		if (td->cols < 1) td->cols = 1;
		if (td->rows < 1) td->rows = 1;
	}

	/* Enforce maximal sizes */
	if (td->cols > 255) td->cols = 255;
	if (td->rows > 255) td->rows = 255;

	/* Minimal tile size */
	if (td->tile_wid < td->font_wid) td->tile_wid = td->font_wid;
	if (td->tile_hgt < td->font_hgt) td->tile_hgt = td->font_hgt;

	/* Default tile offsets */
	td->tile_o_x = (td->tile_wid - td->font_wid) / 2;
	td->tile_o_y = (td->tile_hgt - td->font_hgt) / 2;

	/* Minimal tile offsets */
	if (td->tile_o_x < 0) td->tile_o_x = 0;
	if (td->tile_o_y < 0) td->tile_o_y = 0;

	/* Apply font offsets */
	td->tile_o_x += td->font_o_x;
	td->tile_o_y += td->font_o_y;

	/* Calculate full window size */
	td->size_wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
	td->size_hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;

	/* Verify the top */
	if (td->r.top > qd.screenBits.bounds.bottom - td->size_hgt)
	{
		td->r.top = qd.screenBits.bounds.bottom - td->size_hgt;
	}

	/* Verify the top */
	if (td->r.top < qd.screenBits.bounds.top + 30)
	{
		td->r.top = qd.screenBits.bounds.top + 30;
	}

	/* Verify the left */
	if (td->r.left > qd.screenBits.bounds.right - td->size_wid)
	{
		td->r.left = qd.screenBits.bounds.right - td->size_wid;
	}

	/* Verify the left */
	if (td->r.left < qd.screenBits.bounds.left)
	{
		td->r.left = qd.screenBits.bounds.left;
	}

	/* Calculate bottom right corner */
	td->r.right = td->r.left + td->size_wid;
	td->r.bottom = td->r.top + td->size_hgt;

	/* Assume no graphics */
	td->t->higher_pict = FALSE;
	td->t->always_pict = FALSE;

#ifdef ANGBAND_LITE_MAC

	/* No graphics */

#else /* ANGBAND_LITE_MAC */

	/* Handle graphics */
	if (use_graphics)
	{
		/* Use higher_pict whenever possible */
		if (td->font_mono) td->t->higher_pict = TRUE;

		/* Use always_pict only when necessary */
		else td->t->always_pict = TRUE;
	}

#endif /* ANGBAND_LITE_MAC */

	/* Fake mono-space */
	if (!td->font_mono ||
	                (td->font_wid != td->tile_wid) ||
	                (td->font_hgt != td->tile_hgt))
	{
		/* Handle fake monospace -- this is SLOW */
		if (td->t->higher_pict) td->t->higher_pict = FALSE;
		td->t->always_pict = TRUE;
	}
}


/*
 * Hack -- resize a term_data
 *
 * This should normally be followed by "term_data_resize()"
 */
static void term_data_resize(term_data *td)
{
	/* Actually resize the window */
	SizeWindow(td->w, td->size_wid, td->size_hgt, 0);
}



/*
 * Hack -- redraw a term_data
 *
 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR"
 */
static void term_data_redraw(term_data *td)
{
	term *old = Term;

	/* Activate the term */
	Term_activate(td->t);

	/* Redraw the contents */
	Term_redraw();

	/* Flush the output */
	Term_fresh();

	/* Restore the old term */
	Term_activate(old);

	/* No need to redraw */
	ValidRect(&td->w->portRect);
}




#ifdef ANGBAND_LITE_MAC

/* No graphics */

#else /* ANGBAND_LITE_MAC */


/*
* Graphics support
*/

/* Set by Term_xtra_mac_react */
static int pictID; 		/* PICT id of image tiles */

static int grafWidth; 	/* Width of a tile in pixels */
static int grafHeight; 	/* Height of a tile in pixels */

/* Calculated by PICT loading code */
static int pictCols; 	/* Number of columns in tiles */
static int pictRows; 	/* Number of rows in tiles */

/* Available graphics modes */
#define GRAF_MODE_NONE	0	/* plain ASCII */
#define GRAF_MODE_8X8	1	/* 8x8 tiles, no transparency effect */
#define GRAF_MODE_16X16	2	/* 16x16 tiles, transparency effect */
/* This doesn't work... */
#define GRAF_MODE_32X32	3	/* 32x32 tiles, transparency effect */

static int graf_mode = GRAF_MODE_NONE; 		/* current graphics mode */
static int graf_mode_req = GRAF_MODE_NONE; 	/* requested graphics mode */

#define TR_NONE 0	/* No transparency effect */
#define TR_OVER 1	/* Overwriting with transparent black pixels */
static int transparency_mode = TR_NONE;


/*
* Forward Declare
*/
typedef struct FrameRec FrameRec;

/*
* Frame
*
*	- GWorld for the frame image
*	- Handle to pix map (saved for unlocking/locking)
*	- Pointer to color pix map (valid only while locked)
*/
struct FrameRec
{
	GWorldPtr framePort;
	PixMapHandle framePixHndl;
	PixMapPtr framePix;
};


/*
* The global picture data
*/
static FrameRec *frameP = NULL;


/*
* Lock a frame
*/
static void BenSWLockFrame(FrameRec *srcFrameP)
{
	PixMapHandle pixMapH;

	pixMapH = GetGWorldPixMap(srcFrameP->framePort);
	(void)LockPixels(pixMapH);
	HLockHi((Handle)pixMapH);
	srcFrameP->framePixHndl = pixMapH;
	srcFrameP->framePix = (PixMapPtr)StripAddress(*(Handle)pixMapH);
}


/*
* Unlock a frame
*/
static void BenSWUnlockFrame(FrameRec *srcFrameP)
{
	if (srcFrameP->framePort != NULL)
	{
		HUnlock((Handle)srcFrameP->framePixHndl);
		UnlockPixels(srcFrameP->framePixHndl);
	}

	srcFrameP->framePix = NULL;
}



static OSErr BenSWCreateGWorldFromPict(
        GWorldPtr *pictGWorld, PicHandle pictH)
{
	OSErr err;
	GWorldPtr saveGWorld;
	GDHandle saveGDevice;
	GWorldPtr tempGWorld;
	Rect pictRect;
	short depth;
	GDHandle theGDH;

	tempGWorld = NULL;

	/* Reset */
	*pictGWorld = NULL;

	/* Get depth */
	depth = data[0].pixelDepth;

	/* Get GDH */
	theGDH = data[0].theGDH;

	/* Obtain size rectangle */
	pictRect = (**pictH).picFrame;
	OffsetRect(&pictRect, -pictRect.left, -pictRect.top);

	/* Calculate and set numbers of rows and columns */
	pictRows = pictRect.bottom / grafHeight;
	pictCols = pictRect.right / grafWidth;

	/* Create a GWorld */
	err = NewGWorld(&tempGWorld, depth, &pictRect, nil, theGDH, noNewDevice);

	/* Error */
	if (err != noErr) return (err);

	/* Save pointer */
	*pictGWorld = tempGWorld;

	/* Save GWorld */
	GetGWorld(&saveGWorld, &saveGDevice);

	/* Activate */
	SetGWorld(tempGWorld, nil);

	/* Dump the pict into the GWorld */
	(void)LockPixels(GetGWorldPixMap(tempGWorld));
	EraseRect(&pictRect);
	DrawPicture(pictH, &pictRect);
	UnlockPixels(GetGWorldPixMap(tempGWorld));

	/* Restore GWorld */
	SetGWorld(saveGWorld, saveGDevice);

	/* Success */
	return (0);
}


/*
* Init the global "frameP"
*/
static OSErr globe_init(void)
{
	OSErr err;

	GWorldPtr tempPictGWorldP;

	PicHandle newPictH;


	/* Use window XXX XXX XXX */
	SetPort(data[0].w);


	/* Get the pict resource */
	newPictH = GetPicture(pictID);

	/* Error */
	if (newPictH == NULL) return ( -1);

	/* Create GWorld */
	err = BenSWCreateGWorldFromPict(&tempPictGWorldP, newPictH);

	/* Release resource */
	ReleaseResource((Handle)newPictH);

	/* Error */
	if (err != noErr) return (err);

	/* Create the frame */
	frameP = (FrameRec*)NewPtrClear((Size)sizeof(FrameRec));

	/* Error */
	if (frameP == NULL) return ( -1);

	/* Save GWorld */
	frameP->framePort = tempPictGWorldP;

	/* Lock it */
	BenSWLockFrame(frameP);

	/* Success */
	return (noErr);
}


/*
* Nuke the global "frameP"
*/
static errr globe_nuke(void)
{
	/* Dispose */
	if (frameP)
	{
		/* Unlock */
		BenSWUnlockFrame(frameP);

		/* Dispose of the GWorld */
		DisposeGWorld(frameP->framePort);

		/* Dispose of the memory */
		DisposePtr((Ptr)frameP);

		/* Forget */
		frameP = NULL;
	}

	/* Flush events */
	FlushEvents(everyEvent, 0);

	/* Success */
	return (0);
}


#endif /* ANGBAND_LITE_MAC */




#ifdef USE_ASYNC_SOUND

/*
 * Asynchronous sound player - completely revised (beta)
 */

/*
 * Number of channels in the channel pool
 */
#define MAX_CHANNELS 4

/*
 * A pool of sound channels
 */
static SndChannelPtr channels[MAX_CHANNELS];

/*
 * Status of the channel pool
 */
static Boolean channel_initialised = FALSE;

/*
 * Data handles containing sound samples
 */
static SndListHandle samples[SOUND_MAX];

/*
 * Reference counts of sound samples
 */
static SInt16 sample_refs[SOUND_MAX];

#define SOUND_VOLUME_MIN	0	/* Default minimum sound volume */
#define SOUND_VOLUME_MAX	255	/* Default maximum sound volume */
#define VOLUME_MIN			0	/* Minimum sound volume in % */
#define VOLUME_MAX			100	/* Maximum sound volume in % */
#define VOLUME_INC			5	/* Increment sound volume in % */

/* I'm just too lazy to write a panel for this XXX XXX */
static int sound_volume = SOUND_VOLUME_MAX;

/*
 * Return a handle of 'snd ' resource given Angband sound event number,
 * or NULL if it isn't found.
 *
 * Globals referenced: angband_sound_name[] (variable.c)
 */
static SndListHandle find_sound(int num)
{
	Str255 sound;

	/* Get the proper sound name */
	strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[num]);
	sound[0] = strlen((char*)sound + 1);

	/* Obtain resource XXX XXX XXX */
	return ((SndListHandle)GetNamedResource('snd ', sound));
}


/*
 * Clean up sound support - to be called when the game exits.
 *
 * Globals referenced: channels[], samples[], sample_refs[].
 */
static void cleanup_sound(void)
{
	int i;

	/* No need to clean it up */
	if (!channel_initialised) return;

	/* Dispose channels */
	for (i = 0; i < MAX_CHANNELS; i++)
	{
		/* Drain sound commands and free the channel */
		SndDisposeChannel(channels[i], TRUE);
	}

	/* Free sound data */
	for (i = 1; i < SOUND_MAX; i++)
	{
		/* Still locked */
		if ((sample_refs[i] > 0) && (samples[i] != NULL))
		{
			/* Unlock it */
			HUnlock((Handle)samples[i]);
		}

		/* Release it */
		if (samples[i]) ReleaseResource((Handle)samples[i]);
	}
}


/*
 * Play sound effects asynchronously -- pelpel
 *
 * I don't believe those who first started using the previous implementations
 * imagined this is *much* more complicated as it may seem.  Anyway, 
 * introduced round-robin scheduling of channels and made it much more
 * paranoid about HLock/HUnlock.
 *
 * XXX XXX de-refcounting, HUnlock and ReleaseResource should be done
 * using channel's callback procedures, which set global flags, and
 * a procedure hooked into CheckEvents does housekeeping.  On the other
 * hand, this lazy reclaiming strategy keeps things simple (no interrupt
 * time code) and provides a sort of cache for sound data.
 *
 * Globals referenced: channel_initialised, channels[], samples[],
 *   sample_refs[].
 * Globals updated: ditto.
 */
static void play_sound(int num, int vol)
{
	OSErr err;
	int i;
	int prev_num;
	SndListHandle h;
	SndChannelPtr chan;
	SCStatus status;

	static int next_chan;
	static SInt16 channel_occupants[MAX_CHANNELS];
	static SndCommand volume_cmd, quiet_cmd;


	/* Initialise sound channels */
	if (!channel_initialised)
	{
		for (i = 0; i < MAX_CHANNELS; i++)
		{
			/* Paranoia - Clear occupant table */
			/* channel_occupants[i] = 0; */

			/* Create sound channel for all sounds to play from */
			err = SndNewChannel(&channels[i], sampledSynth, initMono, 0L);

			/* Error */
			if (err != noErr)
			{
				/* Free channels */
				while (--i >= 0)
				{
					SndDisposeChannel(channels[i], TRUE);
				}

				/* Notify error */
				plog("Cannot initialise sound channels!");

				/* Cancel request */
				use_sound = arg_sound = FALSE;

				/* Failure */
				return;
			}
		}

		/* First channel to use */
		next_chan = 0;

		/* Prepare volume command */
		volume_cmd.cmd = volumeCmd;
		volume_cmd.param1 = 0;
		volume_cmd.param2 = 0;

		/* Prepare quiet command */
		quiet_cmd.cmd = quietCmd;
		quiet_cmd.param1 = 0;
		quiet_cmd.param2 = 0;

		/* Initialisation complete */
		channel_initialised = TRUE;
	}

	/* Paranoia */
	if ((num <= 0) || (num >= SOUND_MAX)) return;

	/* Prepare volume command */
	volume_cmd.param2 = (SInt16)((vol << 4) | vol);

	/* Channel to use (round robin) */
	chan = channels[next_chan];

	/* See if the resource is already in use */
	if (sample_refs[num] > 0)
	{
		/* Resource in use */
		h = samples[num];

		/* Increase the refcount */
		sample_refs[num]++;
	}

	/* Sound is not currently in use */
	else
	{
		/* Get handle for the sound */
		h = find_sound(num);

		/* Sample not available */
		if (h == NULL) return;

		/* Load resource */
		LoadResource((Handle)h);

		/* Lock the handle */
		HLock((Handle)h);

		/* Remember it */
		samples[num] = h;

		/* Initialise refcount */
		sample_refs[num] = 1;
	}

	/* Poll the channel */
	err = SndChannelStatus(chan, sizeof(SCStatus), &status);

	/* It isn't available */
	if ((err != noErr) || status.scChannelBusy)
	{
		/* Shut it down */
		SndDoImmediate(chan, &quiet_cmd);
	}

	/* Previously played sound on this channel */
	prev_num = channel_occupants[next_chan];

	/* Process previously played sound */
	if (prev_num != 0)
	{
		/* Decrease refcount */
		sample_refs[prev_num]--;

		/* We can free it now */
		if (sample_refs[prev_num] <= 0)
		{
			/* Unlock */
			HUnlock((Handle)samples[prev_num]);

			/* Release */
			ReleaseResource((Handle)samples[prev_num]);

			/* Forget handle */
			samples[prev_num] = NULL;

			/* Paranoia */
			sample_refs[prev_num] = 0;
		}
	}

	/* Remember this sound as the current occupant of the channel */
	channel_occupants[next_chan] = num;

	/* Set up volume for channel */
	SndDoImmediate(chan, &volume_cmd);

	/* Play new sound asynchronously */
	SndPlay(chan, h, TRUE);

	/* Schedule next channel (round robin) */
	next_chan++;
	if (next_chan >= MAX_CHANNELS) next_chan = 0;
}

#endif /* USE_ASYNC_SOUND */


/*** Support for the "z-term.c" package ***/


/*
 * Initialize a new Term
 *
 * Note also the "window type" called "noGrowDocProc", which might be more
 * appropriate for the main "screen" window.
 *
 * Note the use of "srcCopy" mode for optimized screen writes.
 */
static void Term_init_mac(term *t)
{
	term_data *td = (term_data*)(t->data);

	static RGBColor black = {0x0000, 0x0000, 0x0000};
	static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};

#ifdef ANGBAND_LITE_MAC

	/* Make the window */
	td->w = NewWindow(0, &td->r, td->title, 0, noGrowDocProc, (WindowPtr) - 1, 1, 0L);

#else /* ANGBAND_LITE_MAC */

	/* Make the window */
	td->w = NewCWindow(0, &td->r, td->title, 0, documentProc, (WindowPtr) - 1, 1, 0L);

#endif /* ANGBAND_LITE_MAC */

	/* Activate the window */
	activate(td->w);

	/* Erase behind words */
	TextMode(srcCopy);

	/* Apply and Verify */
	term_data_check_font(td);
	term_data_check_size(td);

	/* Resize the window */
	term_data_resize(td);

#ifdef ANGBAND_LITE_MAC

	/* Prepare the colors (base colors) */
	BackColor(blackColor);
	ForeColor(whiteColor);

#else /* ANGBAND_LITE_MAC */

	/* Prepare the colors (real colors) */
	RGBBackColor(&black);
	RGBForeColor(&white);

	/* Block */
	{
		Rect tempRect;
		Rect globalRect;
		GDHandle mainGDH;
		GDHandle currentGDH;
		GWorldPtr windowGWorld;
		PixMapHandle basePixMap;

		/* Obtain the rect */
		tempRect = td->w->portRect;

		/* Obtain the global rect */
		globalRect = tempRect;
		LocalToGlobal((Point*)&globalRect.top);
		LocalToGlobal((Point*)&globalRect.bottom);

		/* Obtain the proper GDH */
		mainGDH = GetMaxDevice(&globalRect);

		/* Extract GWorld and GDH */
		GetGWorld(&windowGWorld, ¤tGDH);

		/* Obtain base pixmap */
		basePixMap = (**mainGDH).gdPMap;

		/* Save pixel depth */
		td->pixelDepth = (**basePixMap).pixelSize;

		/* Save Window GWorld */
		td->theGWorld = windowGWorld;

		/* Save Window GDH */
		td->theGDH = currentGDH;

		/* Save main GDH */
		td->mainSWGDH = mainGDH;
	}

#endif /* ANGBAND_LITE_MAC */

	/* Clip to the window */
	ClipRect(&td->w->portRect);

	/* Erase the window */
	EraseRect(&td->w->portRect);

	/* Invalidate the window */
	InvalRect(&td->w->portRect);

	/* Display the window if needed */
	if (td->mapped) ShowWindow(td->w);

	/* Hack -- set "mapped" flag */
	t->mapped_flag = td->mapped;

	/* Forget color */
	td->last = -1;
}



/*
 * Nuke an old Term
 */
static void Term_nuke_mac(term *t)
{

#pragma unused (t)

	/* XXX */
}



/*
 * Unused
 */
static errr Term_user_mac(int n)
{

#pragma unused (n)

	/* Success */
	return (0);
}



/*
 * React to changes
 */
static errr Term_xtra_mac_react(void)
{
	term_data *td = (term_data*)(Term->data);

	int i;


#ifdef ANGBAND_LITE_MAC

	/* Nothing */

#else /* ANGBAND_LITE_MAC */

	/* Reset color */
	td->last = -1;

	/* Update colors */
	for (i = 0; i < 256; i++)
	{
		u16b rv, gv, bv;

		/* Extract the R,G,B data */
		rv = angband_color_table[i][1];
		gv = angband_color_table[i][2];
		bv = angband_color_table[i][3];

		/* Save the actual color */
		color_info[i].red = (rv | (rv << 8));
		color_info[i].green = (gv | (gv << 8));
		color_info[i].blue = (bv | (bv << 8));
	}

	/* Handle sound */
	if (use_sound != arg_sound)
	{
		/* Apply request */
		use_sound = arg_sound;
	}

	/* Handle graphics */
	if (graf_mode_req != graf_mode)
	{
		/* dispose old GWorld's if present */
		globe_nuke();

		/* Setup parameters according to request */
		switch (graf_mode_req)
		{
			/* ASCII - no graphics whatsoever */
		case GRAF_MODE_NONE:
			{
#ifndef ZANGBAND
				use_graphics = arg_graphics = FALSE;
#else
use_graphics = arg_graphics = GRAPHICS_NONE;
#endif /* !ZANGBAND */
				transparency_mode = TR_NONE;
				break;
			}

			/*
			* 8x8 tiles (PICT id 1001)
			* no transparency effect
			* "old" graphics definitions
			*/
		case GRAF_MODE_8X8:
			{
#ifndef ZANGBAND
				use_graphics = arg_graphics = TRUE;
				ANGBAND_GRAF = "old";
#else
	use_graphics = arg_graphics = GRAPHICS_ORIGINAL;
#endif /* !ZANGBAND */
				pictID = 1001;
				transparency_mode = TR_NONE;
				grafWidth = grafHeight = 8;
				break;
			}

			/*
			* 16x16 tiles (images: PICT id 1002)
			* with transparency effect
			* "new" graphics definitions
			*/
		case GRAF_MODE_16X16:
			{
#ifndef ZANGBAND
				use_graphics = arg_graphics = TRUE;
				ANGBAND_GRAF = "new";
#else
	use_graphics = arg_graphics = GRAPHICS_ADAM_BOLT;
#endif /* !ZANGBAND */
				pictID = 1002;
				transparency_mode = TR_OVER;
				grafWidth = grafHeight = 16;
				break;
			}

#if 0 /* Good Lord! It doesn't work... Is it too large? */

			/*
			* 32x32 tiles (images: PICT id 1004)
			* no transparency effect
			* "david" graphics definitions
			*/
		case GRAF_MODE_32X32:
			{
				use_graphics = arg_graphics = TRUE;
				ANGBAND_GRAF = "david";
				pictID = 1004;
				transparency_mode = TR_OVER;
				grafWidth = grafHeight = 32;
				break;
			}

#endif /* sigh */
		}

		/* load tiles and setup GWorlds if tiles are requested */
		if ((graf_mode_req != GRAF_MODE_NONE) && (globe_init() != 0))
		{
			/* Oops */
			plog("Cannot initialize graphics!");

			/* reject request */
			graf_mode_req = GRAF_MODE_NONE;

			/* reset graphics flags */
			use_graphics = arg_graphics = FALSE;

			/* reset transparency mode */
			transparency_mode = TR_NONE;
		}

		/* update current graphics mode */
		graf_mode = graf_mode_req;

		/* Apply and Verify */
		term_data_check_size(td);

		/* Resize the window */
		term_data_resize(td);

		/* Reset visuals */
#ifndef ANG281_RESET_VISUALS
		reset_visuals(TRUE);
#else
reset_visuals();
#endif /* !ANG281_RESET_VISUALS */
	}

#endif /* ANGBAND_LITE_MAC */

	/* Success */
	return (0);
}


/*
 * Do a "special thing"
 */
static errr Term_xtra_mac(int n, int v)
{
	term_data *td = (term_data*)(Term->data);

	Rect r;

	/* Analyze */
	switch (n)
	{
		/* Make a noise */
	case TERM_XTRA_NOISE:
		{
			/* Make a noise */
			SysBeep(1);

			/* Success */
			return (0);
		}

#ifdef ANGBAND_LITE_MAC

		/* Nothing */

#else /* ANGBAND_LITE_MAC */

		/* Make a sound */
	case TERM_XTRA_SOUND:
		{
#ifndef USE_ASYNC_SOUND

			/*
			* This may not be your choice, but much safer and much less
			* resource hungry.  Existing implementations can quite easily
			* crash, by starting asynchronous playing and immediately
			* unlocking and releasing the sound data just started playing...
			* -- pelpel
			*/
			Handle handle;
			Str255 sound;

			/* Get the proper sound name */
			strnfmt((char*)sound + 1, 255, "%.16s.wav", angband_sound_name[v]);
			sound[0] = strlen((char*)sound + 1);

			/* Obtain resource XXX XXX XXX */
			handle = GetNamedResource('snd ', sound);

			/* Oops -- it is a failure, but we return 0 anyway */
			if (handle == NULL) return (0);

			/* Load and Lock */
			LoadResource(handle);
			HLock(handle);

			/* Play sound (wait for completion) */
			SndPlay(nil, (SndListHandle)handle, false);

			/* Unlock and release */
			HUnlock(handle);
			ReleaseResource(handle);

#else /* !USE_ASYNC_SOUND */

		/* If you really want async player, please try this one */
		play_sound(v, sound_volume);

#endif /* !USE_ASYNC_SOUND */

			/* Success */
			return (0);
		}

#endif /* ANGBAND_LITE_MAC */

		/* Process random events */
	case TERM_XTRA_BORED:
		{
			/* Process an event */
			(void)CheckEvents(FALSE);

			/* Success */
			return (0);
		}

		/* Process pending events */
	case TERM_XTRA_EVENT:
		{
			/* Process an event */
			(void)CheckEvents(v);

			/* Success */
			return (0);
		}

		/* Flush all pending events (if any) */
	case TERM_XTRA_FLUSH:
		{
			/* Hack -- flush all events */
			while (CheckEvents(TRUE)) /* loop */;

			/* Success */
			return (0);
		}

		/* Hack -- Change the "soft level" */
	case TERM_XTRA_LEVEL:
		{
			/* Activate if requested */
			if (v) activate(td->w);

			/* Success */
			return (0);
		}

		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		{
			/* No clipping XXX XXX XXX */
			ClipRect(&td->w->portRect);

			/* Erase the window */
			EraseRect(&td->w->portRect);

			/* Set the color */
			term_data_color(td, TERM_WHITE);

			/* Frame the window in white */
			MoveTo(0, 0);
			LineTo(0, td->size_hgt - 1);
			LineTo(td->size_wid - 1, td->size_hgt - 1);
			LineTo(td->size_wid - 1, 0);

			/* Clip to the new size */
			r.left = td->w->portRect.left + td->size_ow1;
			r.top = td->w->portRect.top + td->size_oh1;
			r.right = td->w->portRect.right - td->size_ow2;
			r.bottom = td->w->portRect.bottom - td->size_oh2;
			ClipRect(&r);

			/* Success */
			return (0);
		}

		/* React to changes */
	case TERM_XTRA_REACT:
		{
			/* React to changes */
			return (Term_xtra_mac_react());
		}

		/* Delay (milliseconds) */
	case TERM_XTRA_DELAY:
		{
			/* If needed */
			if (v > 0)
			{
				long m = TickCount() + (v * 60L) / 1000;

				/* Wait for it */
				while (TickCount() < m) /* loop */;
			}

			/* Success */
			return (0);
		}

		/* Rename main window */
	case TERM_XTRA_RENAME_MAIN_WIN:
		{
			char *s = strdup(angband_term_name[0]);

			ctopstr((StringPtr)s);
			SetWTitle(data[0].w, (StringPtr)s);

			free(s);
			return (0);
		}
	}

	/* Oops */
	return (1);
}



/*
 * Low level graphics (Assumes valid input).
 * Draw a "cursor" at (x,y), using a "yellow box".
 * We are allowed to use "Term_what()" to determine
 * the current screen contents (for inverting, etc).
 */
static errr Term_curs_mac(int x, int y)
{
	Rect r;

	term_data *td = (term_data*)(Term->data);

	/* Set the color */
	term_data_color(td, TERM_YELLOW);

	/* Frame the grid */
	r.left = x * td->tile_wid + td->size_ow1;
	r.right = r.left + td->tile_wid;
	r.top = y * td->tile_hgt + td->size_oh1;
	r.bottom = r.top + td->tile_hgt;

#ifdef USE_DOUBLE_TILES

	/* Mogami's double width tile patch */
	if (use_bigtile &&
	                (x + 1 < Term->wid) &&
	                (Term->old->a[y][x + 1] == 255))
	{
		r.right += td->tile_wid;
	}

#endif /* USE_DOUBLE_TILES */

	FrameRect(&r);

	/* Success */
	return (0);
}


/*
 * Low level graphics (Assumes valid input)
 *
 * Erase "n" characters starting at (x,y)
 */
static errr Term_wipe_mac(int x, int y, int n)
{
	Rect r;

	term_data *td = (term_data*)(Term->data);

	/* Erase the block of characters */
	r.left = x * td->tile_wid + td->size_ow1;
	r.right = r.left + n * td->tile_wid;
	r.top = y * td->tile_hgt + td->size_oh1;
	r.bottom = r.top + td->tile_hgt;
	EraseRect(&r);

	/* Success */
	return (0);
}


/*
 * Low level graphics.  Assumes valid input.
 *
 * Draw several ("n") chars, with an attr, at a given location.
 */
static errr Term_text_mac(int x, int y, int n, byte a, const char *cp)
{
	int xp, yp;

	term_data *td = (term_data*)(Term->data);

	/* Set the color */
	term_data_color(td, a);

	/* Starting pixel */
	xp = x * td->tile_wid + td->tile_o_x + td->size_ow1;
	yp = y * td->tile_hgt + td->tile_o_y + td->size_oh1;

	/* Move to the correct location */
	MoveTo(xp, yp);

	/* Draw the character */
	if (n == 1) DrawChar(*cp);

	/* Draw the string */
	else DrawText(cp, 0, n);

	/* Success */
	return (0);
}


/*
 * Low level graphics (Assumes valid input)
 *
 * Erase "n" characters starting at (x,y)
 */
#ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp,
                          const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
#else /* USE_TRANSPARENCY */
static errr Term_pict_mac(int x, int y, int n, const byte *ap, const char *cp)
#endif /* USE_TRANSPARENCY */
{
	int i;
	Rect dst_r;
	static RGBColor black = {0x0000, 0x0000, 0x0000};
	static RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
	term_data *td = (term_data*)(Term->data);

	/* Destination rectangle */
	dst_r.left = x * td->tile_wid + td->size_ow1;
#ifndef USE_DOUBLE_TILES
	dst_r.right = dst_r.left + td->tile_wid;
#endif /* !USE_DOUBLE_TILES */
	dst_r.top = y * td->tile_hgt + td->size_oh1;
	dst_r.bottom = dst_r.top + td->tile_hgt;

	/* Scan the input */
	for (i = 0; i < n; i++)
	{
		byte a = *ap++;
		char c = *cp++;

#ifdef USE_TRANSPARENCY
		byte ta = *tap++;
		char tc = *tcp++;
# ifdef USE_EGO_GRAPHICS
		byte ea = *eap++;
		char ec = *ecp++;
		bool has_overlay = (ea && ec);
# endif  /* USE_EGO_GRAPHICS */
#endif /* USE_TRANSPARENCY */

#ifdef USE_DOUBLE_TILES

		/* Second byte of bigtile */
		if (use_bigtile && (a == 255))
		{
			/* Advance */
			dst_r.left += td->tile_wid;

			/* Ignore it */
			continue;
		}

		/* Prepare right side of rectangle */
		dst_r.right = dst_r.left + td->tile_wid;

#endif /* USE_DOUBLE_TILES */

#ifdef ANGBAND_LITE_MAC

		/* Nothing */

#else /* ANGBAND_LITE_MAC */

		/* Graphics -- if Available and Needed */
		if (use_graphics && ((byte)a & 0x80) && ((byte)c & 0x80))
		{
#ifdef USE_TRANSPARENCY
			int t_col, t_row;
			Rect terrain_r;
# ifdef USE_EGO_GRAPHICS
			int e_col, e_row;
			Rect ego_r;
# endif  /* USE_EGO_GRAPHICS */
#endif /* USE_TRANSPARENCY */

			int col, row;
			Rect src_r;

			/* Row and Col */
			row = ((byte)a & 0x7F) % pictRows;
			col = ((byte)c & 0x7F) % pictCols;

			/* Source rectangle */
			src_r.left = col * grafWidth;
			src_r.top = row * grafHeight;
			src_r.right = src_r.left + grafWidth;
			src_r.bottom = src_r.top + grafHeight;

#ifdef USE_TRANSPARENCY

			/* Terrain Row and Col */
			t_row = ((byte)ta & 0x7F) % pictRows;
			t_col = ((byte)tc & 0x7F) % pictCols;

			/* Terrain Source rectangle */
			terrain_r.left = t_col * grafWidth;
			terrain_r.top = t_row * grafHeight;
			terrain_r.right = terrain_r.left + grafWidth;
			terrain_r.bottom = terrain_r.top + grafHeight;

# ifdef USE_EGO_GRAPHICS

			/* If and only if there's overlay */
			if (has_overlay)
			{
				/* Overlay Row and Col */
				e_row = ((byte)ea & 0x7F) % pictRows;
				e_col = ((byte)ec & 0x7F) % pictCols;

				/* Overlay Source rectangle */
				ego_r.left = e_col * grafWidth;
				ego_r.top = e_row * grafHeight;
				ego_r.right = ego_r.left + grafWidth;
				ego_r.bottom = ego_r.top + grafHeight;
			}

# endif  /* USE_EGO_GRAPHICS */

#endif /* USE_TRANSPARENCY */

			/* Hardwire CopyBits */
			RGBBackColor(&white);
			RGBForeColor(&black);

#ifdef USE_DOUBLE_TILES

			/* Double width tiles */
			if (use_bigtile) dst_r.right += td->tile_wid;

#endif /* USE_DOUBLE_TILES */

#ifdef USE_TRANSPARENCY

			/* Transparency effect */
			switch (transparency_mode)
			{
				/* No transparency effect */
			case TR_NONE:
			default:
				{
					/* Draw the picture */
					CopyBits((BitMap*)frameP->framePix,
					         &(td->w->portBits),
					         &src_r, &dst_r, srcCopy, NULL);

					break;
				}

				/* Overwriting with transparent black pixels */
			case TR_OVER:
				{
					/* Draw the terrain */
					CopyBits((BitMap*)frameP->framePix,
					         &(td->w->portBits),
					         &terrain_r, &dst_r, srcCopy, NULL);

					/* Make black pixels transparent */
					RGBBackColor(&black);

					/* Draw mon/obj if there's one */
					if ((row != t_row) || (col != t_col))
						CopyBits((BitMap*)frameP->framePix,
						         &(td->w->portBits),
						         &src_r, &dst_r, transparent, NULL);

# ifdef USE_EGO_GRAPHICS

					/* Draw overlay if there's one */
					if (has_overlay)
						CopyBits((BitMap*)frameP->framePix,
						         &(td->w->portBits),
						         &ego_r, &dst_r, transparent, NULL);

# endif  /* USE_EGO_GRAPHICS */

					break;
				}
			}

#else /* USE_TRANSPARENCY */

/* Draw the picture */
		CopyBits((BitMap*)frameP->framePix,
		         &(td->w->portBits),
		         &src_r, &dst_r, srcCopy, NULL);

#endif /* USE_TRANSPARENCY */

			/* Restore colors */
			RGBBackColor(&black);
			RGBForeColor(&white);

			/* Forget color */
			td->last = -1;
		}

#endif /* ANGBAND_LITE_MAC */

		/* Normal */
		else
		{
			int xp, yp;

			/* Erase */
			EraseRect(&dst_r);

			/* Set the color */
			term_data_color(td, a);

			/* Starting pixel */
			xp = dst_r.left + td->tile_o_x;
			yp = dst_r.top + td->tile_o_y;

			/* Move to the correct location */
			MoveTo(xp, yp);

			/* Draw the character */
			DrawChar(c);
		}

		/* Advance */
		dst_r.left += td->tile_wid;
#ifndef USE_DOUBLE_TILES
		dst_r.right += td->tile_wid;
#endif /* USE_DOUBLE_TILES */
	}

	/* Success */
	return (0);
}





/*
 * Create and initialize window number "i"
 */
static void term_data_link(int i)
{
	term *old = Term;

	term_data *td = &data[i];

	/* Only once */
	if (td->t) return;

	/* Require mapped */
	if (!td->mapped) return;

	/* Allocate */
	MAKE(td->t, term);

	/* Initialize the term */
	term_init(td->t, td->cols, td->rows, td->keys);

	/* Use a "software" cursor */
	td->t->soft_cursor = TRUE;

	/* Erase with "white space" */
	td->t->attr_blank = TERM_WHITE;
	td->t->char_blank = ' ';

	/* Prepare the init/nuke hooks */
	td->t->init_hook = Term_init_mac;
	td->t->nuke_hook = Term_nuke_mac;

	/* Prepare the function hooks */
	td->t->user_hook = Term_user_mac;
	td->t->xtra_hook = Term_xtra_mac;
	td->t->wipe_hook = Term_wipe_mac;
	td->t->curs_hook = Term_curs_mac;
	td->t->text_hook = Term_text_mac;
	td->t->pict_hook = Term_pict_mac;

	/* Link the local structure */
	td->t->data = (void *)(td);

	/* Activate it */
	Term_activate(td->t);

	/* Global pointer */
	angband_term[i] = td->t;

	/* Activate old */
	Term_activate(old);
}




/*
 * Set the "current working directory" (also known as the "default"
 * volume/directory) to the location of the current application.
 *
 * Code by: Maarten Hazewinkel (mmhazewi@cs.ruu.nl)
 *
 * This function does not appear to work correctly with System 6.
 */
static void SetupAppDir(void)
{
	FCBPBRec fcbBlock;
	OSErr err = noErr;
	char errString[100];

	/* Get the location of the Angband executable */
	fcbBlock.ioCompletion = NULL;
	fcbBlock.ioNamePtr = NULL;
	fcbBlock.ioVRefNum = 0;
	fcbBlock.ioRefNum = CurResFile();
	fcbBlock.ioFCBIndx = 0;
	err = PBGetFCBInfoSync(&fcbBlock);
	if (err != noErr)
	{
		strnfmt(errString, 100, "Fatal PBGetFCBInfo Error #%d.\r Exiting.", err);
		mac_warning(errString);
		ExitToShell();
	}

	/* Extract the Vol and Dir */
	app_vol = fcbBlock.ioFCBVRefNum;
	app_dir = fcbBlock.ioFCBParID;

	/* Set the current working directory to that location */
	err = HSetVol(NULL, app_vol, app_dir);
	if (err != noErr)
	{
		strnfmt(errString, 100, "Fatal HSetVol Error #%d.\r Exiting.", err);
		mac_warning(errString);
		ExitToShell();
	}
}




/*
 * Global "preference" file pointer
 */
static FILE *fff;

/*
 * Read a "short" from the file
 */
static int getshort(void)
{
	int x = 0;
	char buf[256];
	if (0 == my_fgets(fff, buf, 256)) x = atoi(buf);
	return (x);
}

/*
 * Dump a "short" to the file
 */
static void putshort(int x)
{
	fprintf(fff, "%d\n", x);
}



/*
 * Write the "preference" data to the current "file"
 */
static void save_prefs(void)
{
	int i;

	term_data *td;


	/*** The current version ***/

	putshort(PREF_VER_MAJOR);
	putshort(PREF_VER_MINOR);
	putshort(PREF_VER_PATCH);
	putshort(PREF_VER_EXTRA);

	/* Gfx settings */
	putshort(arg_sound);
	putshort(graf_mode);
#ifdef USE_DOUBLE_TILES
	putshort(use_bigtile);
#endif /* USE_DOUBLE_TILES */

	/* Dump */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Access */
		td = &data[i];

		putshort(td->mapped);

		putshort(td->font_id);
		putshort(td->font_size);
		putshort(td->font_face);

		putshort(td->tile_wid);
		putshort(td->tile_hgt);

		putshort(td->cols);
		putshort(td->rows);

		putshort(td->r.left);
		putshort(td->r.top);
	}
}


/*
 * Load the preferences from the current "file"
 *
 * XXX XXX XXX Being able to undefine various windows is
 * slightly bizarre, and may cause problems.
 */
static void load_prefs(void)
{
	int i;

	int old_major, old_minor, old_patch, old_extra;

	term_data *td;


	/*** Version information ***/

	/* Preferences version */
	old_major = getshort();
	old_minor = getshort();
	old_patch = getshort();
	old_extra = getshort();

	/* Hack -- Verify or ignore */
	if ((old_major != PREF_VER_MAJOR) ||
	                (old_minor != PREF_VER_MINOR) ||
	                (old_patch != PREF_VER_PATCH) ||
	                (old_extra != PREF_VER_EXTRA))
	{
		/* Message */
		mac_warning("Ignoring old preferences.");

		/* Ignore */
		return;
	}

	/* Gfx mode */
	arg_sound = getshort();
	graf_mode_req = getshort();
#ifdef USE_DOUBLE_TILES
	use_bigtile = getshort();
#endif /* USE_DOUBLE_TILES */

	/* Windows */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Access */
		td = &data[i];

		td->mapped = getshort();

		td->font_id = getshort();
		td->font_size = getshort();
		td->font_face = getshort();

		td->tile_wid = getshort();
		td->tile_hgt = getshort();

		td->cols = getshort();
		td->rows = getshort();

		td->r.left = getshort();
		td->r.top = getshort();

		/* Done */
		if (feof(fff)) break;
	}
}




/*
 * Hack -- default data for a window
 */
static void term_data_hack(term_data *td)
{
	short fid;

	/* Default to Monaco font */
	GetFNum("\pmonaco", &fid);

	/* Wipe it */
	WIPE(td, term_data);

	/* No color */
	td->last = -1;

	/* Default borders */
	td->size_ow1 = 2;
	td->size_ow2 = 2;
	td->size_oh2 = 2;

	/* Start hidden */
	td->mapped = FALSE;

	/* Default font */
	td->font_id = fid;

	/* Default font size */
	td->font_size = 12;

	/* Default font face */
	td->font_face = 0;

	/* Default size */
	td->rows = 24;
	td->cols = 80;

	/* Default position */
	td->r.left = 10;
	td->r.top = 40;

	/* Minimal keys */
	td->keys = 16;
}


/*
 * Read the preference file, Create the windows.
 *
 * We attempt to use "FindFolder()" to track down the preference file,
 * but if this fails, for any reason, we will try the "SysEnvirons()"
 * method, which may work better with System 6.
 */
static void init_windows(void)
{
	int i, b = 0;

	term_data *td;

	bool oops;


	/*** Default values ***/

	/* Initialize (backwards) */
	for (i = MAX_TERM_DATA; i-- > 0; )
	{
		int n;

		cptr s;

		/* Obtain */
		td = &data[i];

		/* Defaults */
		term_data_hack(td);

		/* Obtain title */
		s = angband_term_name[i];

		/* Get length */
		n = strlen(s);

		/* Maximal length */
		if (n > 15) n = 15;

		/* Copy the title */
		strncpy((char*)(td->title) + 1, s, n);

		/* Save the length */
		td->title[0] = n;

		/* Tile the windows */
		td->r.left += (b * 30);
		td->r.top += (b * 30);

		/* Tile */
		b++;
	}


	/*** Load preferences ***/

	/* Assume failure */
	oops = TRUE;

	/* Assume failure */
	fff = NULL;

#ifdef USE_SFL_CODE

	/* Block */
	if (TRUE)
	{
		OSErr	err;
		short vref;
		long dirID;
		char foo[128];

		/* Find the folder */
		err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
		                 &vref, &dirID);

		/* Success */
		if (!err)
		{
			/* Extract a path name */
			PathNameFromDirID(dirID, vref, (StringPtr)foo);

			/* Convert the string */
			ptocstr((StringPtr)foo);

			/* Append the preference file name */
			strcat(foo, ANGBAND_PREFERENCES);

			/* Open the preference file */
			fff = fopen(foo, "r");

			/* Success */
			oops = FALSE;
		}
	}

#endif /* USE_SFL_CODE */

#if 0 /* SysEnvirons? SetVol? I'd say no */

	/* Oops */
	if (oops)
	{
		SysEnvRec env;
		short savev;
		long saved;

		/* Save */
		HGetVol(0, &savev, &saved);

		/* Go to the "system" folder */
		SysEnvirons(curSysEnvVers, &env);
		SetVol(0, env.sysVRefNum);

		/* Open the file */
		fff = fopen(":Preferences:" ANGBAND_PREFERENCES, "r");
		if (!fff) fff = fopen(":" ANGBAND_PREFERENCES, "r");

		/* Restore */
		HSetVol(0, savev, saved);
	}

#endif /* relic */

	/* Load preferences */
	if (fff)
	{
		/* Load a real preference file */
		load_prefs();

		/* Close the file */
		my_fclose(fff);
	}


	/*** Instantiate ***/

	/* Main window */
	td = &data[0];

	/* Many keys */
	td->keys = 1024;

	/* Start visible */
	td->mapped = TRUE;

	/* Link (backwards, for stacking order) */
	for (i = MAX_TERM_DATA; i-- > 0; )
	{
		term_data_link(i);
	}

	/* Main window */
	td = &data[0];

	/* Main window */
	Term_activate(td->t);
}


/*
 * Exit the program
 */
static void save_pref_file(void)
{
	bool oops;


	/* Assume failure */
	oops = TRUE;

	/* Assume failure */
	fff = NULL;

	/* Text file */
	_ftype = 'TEXT';


#ifdef USE_SFL_CODE

	/* Block */
	if (TRUE)
	{
		OSErr	err;
		short vref;
		long dirID;
		char foo[128];

		/* Find the folder */
		err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
		                 &vref, &dirID);

		/* Success */
		if (!err)
		{
			/* Extract a path name */
			PathNameFromDirID(dirID, vref, (StringPtr)foo);

			/* Convert the string */
			ptocstr((StringPtr)foo);

			/* Append the preference file name */
			strcat(foo, ANGBAND_PREFERENCES);

			/* Open the preference file */
			fff = fopen(foo, "w");

			/* Success */
			oops = FALSE;
		}
	}

#endif /* USE_SFL_CODE */

#if 0 /* I don't believe we need SysEnvirons any longer */

	/* Oops */
	if (oops)
	{
		SysEnvRec env;
		short savev;
		long saved;

		/* Save */
		HGetVol(0, &savev, &saved);

		/* Go to "system" folder */
		SysEnvirons(curSysEnvVers, &env);
		SetVol(0, env.sysVRefNum);

		/* Open the preference file */
		fff = fopen(":Preferences:" ANGBAND_PREFERENCES, "w");
		if (!fff) fff = fopen(":" ANGBAND_PREFERENCES, "w");

		/* Restore */
		HSetVol(0, savev, saved);
	}

#endif /* relic */

	/* Save preferences */
	if (fff)
	{
		/* Write the preferences */
		save_prefs();

		/* Close it */
		my_fclose(fff);
	}
}



#ifdef ALLOW_NO_SAVE_QUITS

/*
 * A simple "Yes/No" filter to parse "key press" events in dialog windows
 */
static pascal Boolean ynfilter(DialogPtr dialog, EventRecord *event, short *ip)
{
	/* Parse key press events */
	if (event->what == keyDown)
	{
		int i = 0;
		char c;

		/* Extract the pressed key */
		c = (event->message & charCodeMask);

		/* Accept "no" and  and  */
		if ((c == 'n') || (c == 'N') || (c == 13) || (c == 3)) i = 1;

		/* Accept "yes" */
		else if ((c == 'y') || (c == 'Y')) i = 2;

		/* Handle "yes" or "no" */
		if (i)
		{
			short type;
			ControlHandle control;
			Rect r;

			/* Get the button */
			GetDialogItem(dialog, i, &type, (Handle*)&control, &r);

			/* Blink button for 1/10 second */
			HiliteControl(control, 1);
			Term_xtra_mac(TERM_XTRA_DELAY, 100);
			HiliteControl(control, 0);

			/* Result */
			*ip = i;
			return (1);
		}
	}

	/* Ignore */
	return (0);
}

#endif /* ALLOW_NO_SAVE_QUITS */



#ifndef SAVEFILE_SCREEN

/*
 * Handle menu: "File" + "New"
 */
static void do_menu_file_new(void)
{
	/* Hack */
	HiliteMenu(0);

	/* Game is in progress */
	game_in_progress = 1;

	/* Flush input */
	Term_flush();

	/* Play a game */
	play_game(TRUE);

	/* Hack -- quit */
	quit(NULL);
}

/*
 * Handle menu: "File" + "Open"
 */
static void do_menu_file_open(bool all)
{
	int err;
	short vrefnum;
	long drefnum;
	long junk;
	DirInfo pb;
	SFTypeList types;
	SFReply reply;
	Point topleft;


	/* XXX XXX XXX */

	/* vrefnum = GetSFCurVol(); */
	vrefnum = -*((short*)0x214);

	/* drefnum = GetSFCurDir(); */
	drefnum = *((long*)0x398);

	/* Descend into "lib" folder */
	pb.ioCompletion = NULL;
	pb.ioNamePtr = "\plib";
	pb.ioVRefNum = vrefnum;
	pb.ioDrDirID = drefnum;
	pb.ioFDirIndex = 0;

	/* Check for errors */
	err = PBGetCatInfoSync((CInfoPBPtr) & pb);

	/* Success */
	if ((err == noErr) && (pb.ioFlAttrib & 0x10))
	{
		/* Descend into "lib/save" folder */
		pb.ioCompletion = NULL;
		pb.ioNamePtr = "\psave";
		pb.ioVRefNum = vrefnum;
		pb.ioDrDirID = pb.ioDrDirID;
		pb.ioFDirIndex = 0;

		/* Check for errors */
		err = PBGetCatInfoSync((CInfoPBPtr) & pb);

		/* Success */
		if ((err == noErr) && (pb.ioFlAttrib & 0x10))
		{
			/* SetSFCurDir(pb.ioDrDirID); */
			*((long*)0x398) = pb.ioDrDirID;
		}
	}

	/* Window location */
	topleft.h = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) / 2 - 344 / 2;
	topleft.v = (2 * qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) / 3 - 188 / 2;

	/* Allow "all" files */
	if (all)
	{
		/* Get any file */
		SFGetFile(topleft, "\p", NULL, -1, types, NULL, &reply);
	}

	/* Allow "save" files */
	else
	{
		/* Legal types */
		types[0] = 'SAVE';

		/* Get a file */
		SFGetFile(topleft, "\p", NULL, 1, types, NULL, &reply);
	}

	/* Allow cancel */
	if (!reply.good) return;

	/* Extract textual file name for save file */
	GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
	refnum_to_name(savefile, drefnum, vrefnum, (char*)reply.fName);

	/* Hack */
	HiliteMenu(0);

	/* Game is in progress */
	game_in_progress = 1;

	/* Flush input */
	flush();

	/* Play a game */
	play_game(FALSE);

	/* Hack -- quit */
	quit(NULL);
}

#endif /* !SAVEFILE_SCREEN */


/*
 * Handle the "open_when_ready" flag
 */
static void handle_open_when_ready(void)
{
	/* Check the flag XXX XXX XXX make a function for this */
	if (open_when_ready && initialized && !game_in_progress)
	{
		/* Forget */
		open_when_ready = FALSE;

		/* Game is in progress */
		game_in_progress = 1;

		/* Wait for it */
		pause_line(23);

		/* Flush input */
		flush();

#ifdef SAVEFILE_SCREEN

		/* User double-clicked savefile; no savefile screen */
		no_begin_screen = TRUE;

#endif /* SAVEFILE_SCREEN */

		/* Play a game */
		play_game(FALSE);

		/* Quit */
		quit(NULL);
	}
}



/*
 * The standard menus are:
 *
 *   Apple (128) =   { About, -, ... }
 *   File (129) =    { New,Open,Import,Close,Save,-,Score,Exit,Quit }
 *     In ToME, this becomes
 *   File (129) =    { Close,Save,-,Score,Exit,Quit }
 *   Edit (130) =    { Cut, Copy, Paste, Clear }   (?)
 *   Font (131) =    { Bold, Extend, -, Monaco, ..., -, ... }
 *   Size (132) =    { ... }
 *   Window (133) =  { Angband, Term-1/Mirror, Term-2/Recall, Term-3/Choice,
 *                     Term-4, Term-5, Term-6, Term-7 }
 *   Special (134) = { Sound, Graphics, TileWidth, TileHeight, -,
 *                     Fiddle, Wizard }
 */

/* Apple menu */
#define MENU_APPLE	128
#define ITEM_ABOUT	1

/* File menu */
#define MENU_FILE	129
#ifndef SAVEFILE_SCREEN
# define ITEM_NEW	1
# define ITEM_OPEN	2
# define ITEM_IMPORT	3
# define ITEM_CLOSE	4
# define ITEM_SAVE	5
# ifdef HAS_SCORE_MENU
# define ITEM_SCORE 7
# define ITEM_EXIT	8
# define ITEM_QUIT	9
# else
# define ITEM_EXIT	7
# define ITEM_QUIT	8
# endif  /* HAS_SCORE_MENU */
#else /* !SAVEFILE_SCREEN - in-game savefile menu */
# define ITEM_CLOSE	1
# define ITEM_SAVE	2
# ifdef HAS_SCORE_MENU
# define ITEM_SCORE	4
# define ITEM_EXIT	5
# define ITEM_QUIT	6
# else
# define ITEM_EXIT	4
# define ITEM_QUIT	5
# endif  /* HAS_SCORE_MENU */
#endif /* !SAVEFILE_SCREEN */

/* Edit menu */
#define MENU_EDIT	130
#define ITEM_UNDO	1
#define ITEM_CUT	3
#define ITEM_COPY	4
#define ITEM_PASTE	5
#define ITEM_CLEAR	6

/* Font menu */
#define MENU_FONT	131
#define ITEM_BOLD	1
#define ITEM_WIDE	2

/* Size menu */
#define MENU_SIZE	132

/* Windows menu */
#define MENU_WINDOWS	133

/* Special menu */
#define MENU_SPECIAL	134
#define ITEM_SOUND	1
#define ITEM_GRAPH	2
#define ITEM_TILEWIDTH 3
#define ITEM_TILEHEIGHT 4
#define ITEM_FIDDLE	6
#define ITEM_WIZARD	7

/* Graphics submenu */
#define SUBMENU_GRAPH	144
#define ITEM_NONE	1
#define ITEM_8X8	2
#define ITEM_16X16	3
#define ITEM_BIGTILE    5

/* TileWidth submenu */
#define SUBMENU_TILEWIDTH	145

/* TileHeight submenu */
#define SUBMENU_TILEHEIGHT	146


/*
 * Initialize the menus
 */
static void init_menubar(void)
{
	int i, n;

	Rect r;

	WindowPtr tmpw;

	MenuHandle m;

	Handle mbar;


	/* Load menubar from resources */
	mbar = GetNewMBar(128);

	/* Whoops! */
	if (mbar == nil) quit("Cannot find menubar('MBAR') id 128!");

	/* Insert them into the current menu list */
	SetMenuBar(mbar);

	/* Free handle */
	DisposeHandle(mbar);


	/* Apple menu (id 128) */
	m = GetMenuHandle(MENU_APPLE);

	/* Add the DA's to the "apple" menu */
	AppendResMenu(m, 'DRVR');


	/* File menu (id 129) - we don't have to do anything */


	/* Edit menu (id 130) - we don't have to do anything */


	/*
	 * Font menu (id 131) - append names of mono-spaced fonts
	 * followed by all available ones
	 */
	m = GetMenuHandle(MENU_FONT);

	/* Fake window */
	r.left = r.right = r.top = r.bottom = 0;

	/* Make the fake window so that we can retrive font info */
	tmpw = NewWindow(0, &r, "\p", false, documentProc, 0, 0, 0);

	/* Activate the "fake" window */
	SetPort(tmpw);

	/* Default mode */
	TextMode(0);

	/* Default size */
	TextSize(12);

	/* Add the fonts to the menu */
	AppendResMenu(m, 'FONT');

	/* Size of menu */
	n = CountMItems(m);

	/* Scan the menu */
	for (i = n; i >= 4; i--)
	{
		Str255 tmpName;
		short fontNum;

		/* Acquire the font name */
		GetMenuItemText(m, i, tmpName);

		/* Acquire the font index */
		GetFNum(tmpName, &fontNum);

		/* Apply the font index */
		TextFont(fontNum);

		/* Remove non-mono-spaced fonts */
		if ((CharWidth('i') != CharWidth('W')) || (CharWidth('W') == 0))
		{
			/* Delete the menu item */
			DeleteMenuItem(m, i);
		}
	}

	/* Destroy the old window */
	DisposeWindow(tmpw);

	/* Add a separator */
	AppendMenu(m, "\p-");

	/* Add the fonts to the menu */
	AppendResMenu(m, 'FONT');


	/* Size menu (id 132) */
	m = GetMenuHandle(MENU_SIZE);

	/* Add some sizes (stagger choices) */
	for (i = 8; i <= 32; i += ((i / 16) + 1))
	{
		Str15 buf;

		/* Textual size */
		strnfmt((char*)buf + 1, 15, "%d", i);
		buf[0] = strlen((char*)buf + 1);

		/* Add the item */
		AppendMenu(m, buf);
	}


	/* Windows menu (id 133) */
	m = GetMenuHandle(MENU_WINDOWS);

	/* Default choices */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		Str15 buf;

		/* Describe the item */
		strnfmt((char*)buf + 1, 15, "%.15s", angband_term_name[i]);
		buf[0] = strlen((char*)buf + 1);

		/* Add the item */
		AppendMenu(m, buf);

		/* Command-Key shortcuts */
		if (i < 8) SetItemCmd(m, i + 1, I2D(i));
	}


	/* Special menu (id 134) */

	/* Get graphics (sub)menu (id 144) */
	m = GetMenu(SUBMENU_GRAPH);

	/* Insert it as a submenu */
	InsertMenu(m, hierMenu);


	/* Get TileWidth (sub)menu (id 145) */
	m = GetMenu(SUBMENU_TILEWIDTH);

	/* Add some sizes */
	for (i = 4; i <= 32; i++)
	{
		Str15 buf;

		/* Textual size */
		strnfmt((char*)buf + 1, 15, "%d", i);
		buf[0] = strlen((char*)buf + 1);

		/* Append item */
		AppendMenu(m, buf);
	}

	/* Insert it as a submenu */
	InsertMenu(m, hierMenu);

	/* Get TileHeight (sub)menu (id 146) */
	m = GetMenu(SUBMENU_TILEHEIGHT);

	/* Add some sizes */
	for (i = 4; i <= 32; i++)
	{
		Str15 buf;

		/* Textual size */
		strnfmt((char*)buf + 1, 15, "%d", i);
		buf[0] = strlen((char*)buf + 1);

		/* Append item */
		AppendMenu(m, buf);
	}

	/* Insert it as a submenu */
	InsertMenu(m, hierMenu);


	/* Update the menu bar */
	DrawMenuBar();
}


/*
 * Prepare the menus
 *
 * It is very important that the player not be allowed to "save" the game
 * unless the "inkey_flag" variable is set, indicating that the game is
 * waiting for a new command.  XXX XXX XXX
 */
static void setup_menus(void)
{
	int i, n;

	short value;

	Str255 s;

	MenuHandle m;

	term_data *td = NULL;


	/* Relevant "term_data" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Unused */
		if (!data[i].t) continue;

		/* Notice the matching window */
		if (data[i].w == FrontWindow()) td = &data[i];
	}


	/* File menu */
	m = GetMenuHandle(MENU_FILE);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);
		CheckItem(m, i, FALSE);
	}

#ifndef SAVEFILE_SCREEN

	/* Enable "new"/"open..."/"import..." */
	if (initialized && !game_in_progress)
	{
		EnableItem(m, ITEM_NEW);
		EnableItem(m, ITEM_OPEN);
		EnableItem(m, ITEM_IMPORT);
	}

#endif /* !SAVEFILE_SCREEN */

	/* Enable "close" */
	if (initialized)
	{
		EnableItem(m, ITEM_CLOSE);
	}

	/* Enable "save" */
	if (initialized && character_generated && inkey_flag)
	{
		EnableItem(m, ITEM_SAVE);
	}

#ifdef HAS_SCORE_MENU

	/* Enable "score" */
	if (initialized && character_generated && !character_icky)
	{
		EnableItem(m, ITEM_SCORE);
	}

#endif /* HAS_SCORE_MENU */

#ifdef ALLOW_NO_SAVE_QUITS

	/* Enable "exit" */
	if (TRUE)
	{
		EnableItem(m, ITEM_EXIT);
	}

#endif /* ALLOW_NO_SAVE_QUITS */

	/* Enable "quit" */
	if (!initialized || !character_generated || inkey_flag)
	{
		EnableItem(m, ITEM_QUIT);
	}


	/* Edit menu */
	m = GetMenuHandle(MENU_EDIT);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);
		CheckItem(m, i, FALSE);
	}

	/* Enable "edit" options if "needed" */
	if (!td)
	{
		EnableItem(m, ITEM_UNDO);
		EnableItem(m, ITEM_CUT);
		EnableItem(m, ITEM_COPY);
		EnableItem(m, ITEM_PASTE);
		EnableItem(m, ITEM_CLEAR);
	}


	/* Font menu */
	m = GetMenuHandle(MENU_FONT);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);
		CheckItem(m, i, FALSE);
	}

	/* Hack -- look cute XXX XXX */
	/* SetItemStyle(m, ITEM_BOLD, bold); */

	/* Hack -- look cute XXX XXX */
	/* SetItemStyle(m, ITEM_WIDE, extend); */

	/* Active window */
	if (initialized && td)
	{
		/* Enable "bold" */
		EnableItem(m, ITEM_BOLD);

		/* Enable "extend" */
		EnableItem(m, ITEM_WIDE);

		/* Check the appropriate "bold-ness" */
		if (td->font_face & bold) CheckItem(m, ITEM_BOLD, TRUE);

		/* Check the appropriate "wide-ness" */
		if (td->font_face & extend) CheckItem(m, ITEM_WIDE, TRUE);

		/* Analyze fonts */
		for (i = 4; i <= n; i++)
		{
			/* Enable it */
			EnableItem(m, i);

			/* Analyze font */
			GetMenuItemText(m, i, s);
			GetFNum(s, &value);

			/* Check active font */
			if (td->font_id == value) CheckItem(m, i, TRUE);
		}
	}


	/* Size menu */
	m = GetMenuHandle(MENU_SIZE);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);
		CheckItem(m, i, FALSE);
	}

	/* Active window */
	if (initialized && td)
	{
		/* Analyze sizes */
		for (i = 1; i <= n; i++)
		{
			/* Analyze size */
			GetMenuItemText(m, i, s);
			s[s[0] + 1] = '\0';
			value = atoi((char*)(s + 1));

			/* Enable the "real" sizes */
			if (RealFont(td->font_id, value)) EnableItem(m, i);

			/* Check the current size */
			if (td->font_size == value) CheckItem(m, i, TRUE);
		}
	}


	/* Windows menu */
	m = GetMenuHandle(MENU_WINDOWS);

	/* Get menu size */
	n = CountMItems(m);

	/* Check active windows */
	for (i = 1; i <= n; i++)
	{
		/* Check if needed */
		CheckItem(m, i, data[i - 1].mapped);
	}


	/* Special menu */
	m = GetMenuHandle(MENU_SPECIAL);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);

		/* XXX Oh no, this removes submenu... */
		if ((i != ITEM_GRAPH) &&
		                (i != ITEM_TILEWIDTH) &&
		                (i != ITEM_TILEHEIGHT)) CheckItem(m, i, FALSE);
	}

	/* Item "Sound" */
	EnableItem(m, ITEM_SOUND);
	CheckItem(m, ITEM_SOUND, arg_sound);

	/* Item "Graphics" */
	EnableItem(m, ITEM_GRAPH);

	/* Item "TileWidth" */
	EnableItem(m, ITEM_TILEWIDTH);

	/* Item "TileHeight" */
	EnableItem(m, ITEM_TILEHEIGHT);

	/* Item "Fiddle" */
	EnableItem(m, ITEM_FIDDLE);
	CheckItem(m, ITEM_FIDDLE, arg_fiddle);

	/* Item "Wizard" */
	EnableItem(m, ITEM_WIZARD);
	CheckItem(m, ITEM_WIZARD, arg_wizard);

	/* Graphics submenu */
	m = GetMenuHandle(SUBMENU_GRAPH);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);
		CheckItem(m, i, FALSE);
	}

	/* Item "None" */
	EnableItem(m, ITEM_NONE);
	CheckItem(m, ITEM_NONE, (graf_mode == GRAF_MODE_NONE));

	/* Item "8x8" */
	EnableItem(m, ITEM_8X8);
	CheckItem(m, ITEM_8X8, (graf_mode == GRAF_MODE_8X8));

	/* Item "16x16" */
	EnableItem(m, ITEM_16X16);
	CheckItem(m, ITEM_16X16, (graf_mode == GRAF_MODE_16X16));

#ifdef USE_DOUBLE_TILES

	/* Item "Bigtile" */
	if (inkey_flag) EnableItem(m, ITEM_BIGTILE);
	CheckItem(m, ITEM_BIGTILE, use_bigtile);

#endif /* USE_DOUBLE_TILES */


	/* TIleWidth submenu */
	m = GetMenuHandle(SUBMENU_TILEWIDTH);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);
		CheckItem(m, i, FALSE);
	}

	/* Active window */
	if (initialized && td)
	{
		/* Analyze sizes */
		for (i = 1; i <= n; i++)
		{
			/* Analyze size */
			GetMenuItemText(m, i, s);
			s[s[0] + 1] = '\0';
			value = atoi((char*)(s + 1));

			/* Enable */
			if (value >= td->font_wid) EnableItem(m, i);

			/* Check the current size */
			if (td->tile_wid == value) CheckItem(m, i, TRUE);
		}
	}


	/* TileHeight submenu */
	m = GetMenuHandle(SUBMENU_TILEHEIGHT);

	/* Get menu size */
	n = CountMItems(m);

	/* Reset menu */
	for (i = 1; i <= n; i++)
	{
		/* Reset */
		DisableItem(m, i);
		CheckItem(m, i, FALSE);
	}

	/* Active window */
	if (initialized && td)
	{
		/* Analyze sizes */
		for (i = 1; i <= n; i++)
		{
			/* Analyze size */
			GetMenuItemText(m, i, s);
			s[s[0] + 1] = '\0';
			value = atoi((char*)(s + 1));

			/* Enable */
			if (value >= td->font_hgt) EnableItem(m, i);

			/* Check the current size */
			if (td->tile_hgt == value) CheckItem(m, i, TRUE);
		}
	}
}


/*
 * Process a menu selection (see above)
 *
 * Hack -- assume that invalid menu selections are disabled above,
 * which I have been informed may not be reliable.  XXX XXX XXX
 */
static void menu(long mc)
{
	int i;

	int menuid, selection;

	static unsigned char s[1000];

	short fid;

	term_data *td = NULL;

	WindowPtr old_win;


	/* Analyze the menu command */
	menuid = HiWord(mc);
	selection = LoWord(mc);


	/* Find the window */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		/* Skip dead windows */
		if (!data[i].t) continue;

		/* Notice matches */
		if (data[i].w == FrontWindow()) td = &data[i];
	}


	/* Branch on the menu */
	switch (menuid)
	{
		/* Apple Menu */
	case MENU_APPLE:
		{
			/* About Angband... */
			if (selection == ITEM_ABOUT)
			{
				DialogPtr dialog;
				Rect r;
				short item_hit;

				dialog = GetNewDialog(128, 0, (WindowPtr) - 1);

				r = dialog->portRect;
				center_rect(&r, &qd.screenBits.bounds);
				MoveWindow(dialog, r.left, r.top, 1);
				ShowWindow(dialog);
				ModalDialog(0, &item_hit);
				DisposeDialog(dialog);
				break;
			}

			/* Desk accessory */
			GetMenuItemText(GetMenuHandle(MENU_APPLE), selection, s);
			OpenDeskAcc(s);
			break;
		}


		/* File Menu */
	case MENU_FILE:
		{
			switch (selection)
			{
#ifndef SAVEFILE_SCREEN

				/* New */
			case ITEM_NEW:
				{
					do_menu_file_new();
					break;
				}

				/* Open... */
			case ITEM_OPEN:
				{
					do_menu_file_open(FALSE);
					break;
				}

				/* Import... */
			case ITEM_IMPORT:
				{
					do_menu_file_open(TRUE);
					break;
				}

#endif /* !SAVEFILE_SCREEN */

				/* Close */
			case ITEM_CLOSE:
				{
					/* No window */
					if (!td) break;

					/* Not Mapped */
					td->mapped = FALSE;

					/* Not Mapped */
					td->t->mapped_flag = FALSE;

					/* Hide the window */
					HideWindow(td->w);

					break;
				}

				/* Save */
			case ITEM_SAVE:
				{
					/* Hack -- Forget messages */
					msg_flag = FALSE;

					/* Hack -- Save the game */
#ifndef ZANG_AUTO_SAVE
					do_cmd_save_game();
#else
do_cmd_save_game(FALSE);
#endif /* !ZANG_AUTO_SAVE */

					break;
				}

#ifdef HAS_SCORE_MENU

				/* Show score */
			case ITEM_SCORE:
				{
					char buf[1024];

					/* Paranoia */
					if (!initialized || character_icky ||
					                !game_in_progress || !character_generated)
					{
						/* Can't happen but just in case */
						plog("You may not do that right now.");

						break;
					}

					/* Build the pathname of the score file */
					path_build(buf, sizeof(buf), ANGBAND_DIR_APEX,
					           "scores.raw");

					/* Hack - open the score file for reading */
					highscore_fd = fd_open(buf, O_RDONLY);

					/* Paranoia - No score file */
					if (highscore_fd < 0)
					{
						msg_print("Score file is not available.");

						break;
					}

					/* Mega-Hack - prevent various functions XXX XXX XXX */
					initialized = FALSE;

					/* Save screen */
					screen_save();

					/* Clear screen */
					Term_clear();

					/* Prepare scores */
					if (game_in_progress && character_generated)
					{
						predict_score();
					}

#if 0 /* I don't like this - pelpel */

					/* Mega-Hack - No current player XXX XXX XXX XXX */
					else
					{
						display_scores_aux(0, MAX_HISCORES, -1, NULL);
					}

#endif

					/* Close the high score file */
					(void)fd_close(highscore_fd);

					/* Forget the fd */
					highscore_fd = -1;

					/* Restore screen */
					screen_load();

					/* Hack - Flush it */
					Term_fresh();

					/* Mega-Hack - We are ready again */
					initialized = TRUE;

					/* Done */
					break;
				}

#endif /* HAS_SCORE_MENU */

#ifdef ALLOW_NO_SAVE_QUITS

				/* Exit (without save) */
			case ITEM_EXIT:
				{
					/* Allow user to cancel "dangerous" exit */
					if (game_in_progress && character_generated)
					{
						AlertTHndl alert;
						short item_hit;

						/* Get the "alert" info */
						alert = (AlertTHndl)GetResource('ALRT', 130);

						/* Center the "alert" rectangle */
						center_rect(&(*alert)->boundsRect,
						            &qd.screenBits.bounds);

						/* Display the Alert, get "No" or "Yes" */
						item_hit = Alert(130, ynfilterUPP);

						/* Require "yes" button */
						if (item_hit != 2) break;
					}

					/* Quit */
					quit(NULL);
					break;
				}

#endif /* ALLOW_NO_SAVE_QUITS */

				/* Quit (with save) */
			case ITEM_QUIT:
				{
					/* Save the game (if necessary) */
					if (game_in_progress && character_generated)
					{
						/* Hack -- Forget messages */
						msg_flag = FALSE;

						/* Save the game */
#ifndef ZANG_AUTO_SAVE
						do_cmd_save_game();
#else
						do_cmd_save_game(FALSE);
#endif /* !ZANG_AUTO_SAVE */
					}

					/* Quit */
					quit(NULL);
					break;
				}
			}

			break;
		}


		/* Edit menu */
	case MENU_EDIT:
		{
			/* Unused */
			break;
		}


		/* Font menu */
	case MENU_FONT:
		{
			/* Require a window */
			if (!td) break;

			/* Memorize old */
			old_win = active;

			/* Activate */
			activate(td->w);

			/* Toggle the "bold" setting */
			if (selection == ITEM_BOLD)
			{
				/* Toggle the setting */
				if (td->font_face & bold)
				{
					td->font_face &= ~bold;
				}
				else
				{
					td->font_face |= bold;
				}

				/* Hack - clear tile size info XXX XXX */
				td->tile_wid = td->tile_hgt = 0;

				/* Apply and Verify */
				term_data_check_font(td);
				term_data_check_size(td);

				/* Resize and Redraw */
				term_data_resize(td);
				term_data_redraw(td);

				break;
			}

			/* Toggle the "wide" setting */
			if (selection == ITEM_WIDE)
			{
				/* Toggle the setting */
				if (td->font_face & extend)
				{
					td->font_face &= ~extend;
				}
				else
				{
					td->font_face |= extend;
				}

				/* Hack - clear tile size info XXX XXX */
				td->tile_wid = td->tile_hgt = 0;

				/* Apply and Verify */
				term_data_check_font(td);
				term_data_check_size(td);

				/* Resize and Redraw */
				term_data_resize(td);
				term_data_redraw(td);

				break;
			}

			/* Get a new font name */
			GetMenuItemText(GetMenuHandle(MENU_FONT), selection, s);
			GetFNum(s, &fid);

			/* Save the new font id */
			td->font_id = fid;

			/* Current size is bad for new font */
			if (!RealFont(td->font_id, td->font_size))
			{
				/* Find similar size */
				for (i = 1; i <= 32; i++)
				{
					/* Adjust smaller */
					if (td->font_size - i >= 8)
					{
						if (RealFont(td->font_id, td->font_size - i))
						{
							td->font_size -= i;
							break;
						}
					}

					/* Adjust larger */
					if (td->font_size + i <= 128)
					{
						if (RealFont(td->font_id, td->font_size + i))
						{
							td->font_size += i;
							break;
						}
					}
				}
			}

			/* Hack - clear tile size info XXX XXX */
			td->tile_wid = td->tile_hgt = 0;

			/* Apply and Verify */
			term_data_check_font(td);
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore the window */
			activate(old_win);

			break;
		}

		/* Size menu */
	case MENU_SIZE:
		{
			if (!td) break;

			/* Save old */
			old_win = active;

			/* Activate */
			activate(td->w);

			GetMenuItemText(GetMenuHandle(MENU_SIZE), selection, s);
			s[s[0] + 1] = 0;
			td->font_size = atoi((char*)(s + 1));

			/* Hack - clear tile size info XXX XXX */
			td->tile_wid = td->tile_hgt = 0;

			/* Apply and Verify */
			term_data_check_font(td);
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore */
			activate(old_win);

			break;
		}

		/* Window menu */
	case MENU_WINDOWS:
		{
			/* Parse */
			i = selection - 1;

			/* Check legality of choice */
			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			/* Obtain the window */
			td = &data[i];

			/* Mapped */
			td->mapped = TRUE;

			/* Link */
			term_data_link(i);

			/* Mapped (?) */
			td->t->mapped_flag = TRUE;

			/* Show the window */
			ShowWindow(td->w);

			/* Bring to the front */
			SelectWindow(td->w);

			break;
		}

		/* Special menu */
	case MENU_SPECIAL:
		{
			switch (selection)
			{
			case ITEM_SOUND:
				{
					/* Toggle arg_sound */
					arg_sound = !arg_sound;

					/* React to changes */
					Term_xtra(TERM_XTRA_REACT, 0);

					break;
				}

			case ITEM_FIDDLE:
				{
					arg_fiddle = !arg_fiddle;
					break;
				}

			case ITEM_WIZARD:
				{
					arg_wizard = !arg_wizard;
					break;
				}
			}

			break;
		}


		/* Graphics submenu */
	case SUBMENU_GRAPH:
		{
			switch (selection)
			{
			case ITEM_NONE:
				{
					graf_mode_req = GRAF_MODE_NONE;

					break;
				}

			case ITEM_8X8:
				{
					graf_mode_req = GRAF_MODE_8X8;

					break;
				}

			case ITEM_16X16:
				{
					graf_mode_req = GRAF_MODE_16X16;

					break;
				}

#ifdef USE_DOUBLE_TILES

			case ITEM_BIGTILE:
				{
					term *old = Term;
					term_data *td = &data[0];

					/* Toggle "arg_bigtile" */
					use_bigtile = !use_bigtile;
# ifdef TOME
					arg_bigtile = use_bigtile;
# endif  /* TOME */

					/* Activate */
					Term_activate(td->t);

					/* Resize the term */
					Term_resize(td->cols, td->rows);

					/* Activate old */
					Term_activate(old);

					break;
				}

#endif /* USE_DOUBLE_TILES */

			}

			/* Hack -- Force redraw */
			Term_key_push(KTRL('R'));

			break;
		}


		/* TileWidth submenu */
	case SUBMENU_TILEWIDTH:
		{
			if (!td) break;

			/* Save old */
			old_win = active;

			/* Activate */
			activate(td->w);

			GetMenuItemText(GetMenuHandle(SUBMENU_TILEWIDTH), selection, s);
			s[s[0] + 1] = 0;
			td->tile_wid = atoi((char*)(s + 1));

			/* Apply and Verify */
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore */
			activate(old_win);

			break;
		}


		/* TileHeight submenu */
	case SUBMENU_TILEHEIGHT:
		{
			if (!td) break;

			/* Save old */
			old_win = active;

			/* Activate */
			activate(td->w);

			GetMenuItemText(GetMenuHandle(SUBMENU_TILEHEIGHT), selection, s);
			s[s[0] + 1] = 0;
			td->tile_hgt = atoi((char*)(s + 1));

			/* Apply and Verify */
			term_data_check_size(td);

			/* Resize and Redraw */
			term_data_resize(td);
			term_data_redraw(td);

			/* Restore */
			activate(old_win);

			break;
		}
	}


	/* Clean the menu */
	HiliteMenu(0);
}


#ifdef USE_SFL_CODE


/*
 * Check for extra required parameters -- From "Maarten Hazewinkel"
 */
static OSErr CheckRequiredAEParams(const AppleEvent *theAppleEvent)
{
	OSErr aeError;
	DescType returnedType;
	Size actualSize;

	aeError = AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard,
	                            &returnedType, NULL, 0, &actualSize);

	if (aeError == errAEDescNotFound) return (noErr);

	if (aeError == noErr) return (errAEParamMissed);

	return (aeError);
}


/*
 * Apple Event Handler -- Open Application
 */
static OSErr AEH_Start(const AppleEvent *theAppleEvent,
                       AppleEvent *reply, long handlerRefCon)
{
#pragma unused(reply, handlerRefCon)

	return (CheckRequiredAEParams(theAppleEvent));
}


/*
 * Apple Event Handler -- Quit Application
 */
static OSErr AEH_Quit(const AppleEvent *theAppleEvent,
                      AppleEvent *reply, long handlerRefCon)
{
#pragma unused(reply, handlerRefCon)

	/* Quit later */
	quit_when_ready = TRUE;

	/* Check arguments */
	return (CheckRequiredAEParams(theAppleEvent));
}


/*
 * Apple Event Handler -- Print Documents
 */
static OSErr AEH_Print(const AppleEvent *theAppleEvent,
                       AppleEvent *reply, long handlerRefCon)
{
#pragma unused(theAppleEvent, reply, handlerRefCon)

	return (errAEEventNotHandled);
}


/*
 * Apple Event Handler by Steve Linberg (slinberg@crocker.com).
 *
 * The old method of opening savefiles from the finder does not work
 * on the Power Macintosh, because CountAppFiles and GetAppFiles,
 * used to return information about the selected document files when
 * an application is launched, are part of the Segment Loader, which
 * is not present in the RISC OS due to the new memory architecture.
 *
 * The "correct" way to do this is with AppleEvents.  The following
 * code is modeled on the "Getting Files Selected from the Finder"
 * snippet from Think Reference 2.0.  (The prior sentence could read
 * "shamelessly swiped & hacked")
 */
static OSErr AEH_Open(AppleEvent *theAppleEvent,
                      AppleEvent* reply, long handlerRefCon)
{
#pragma unused(reply, handlerRefCon)

	FSSpec myFSS;
	AEDescList docList;
	OSErr err;
	Size actualSize;
	AEKeyword keywd;
	DescType returnedType;
	char msg[128];
	FInfo myFileInfo;

	/* Put the direct parameter (a descriptor list) into a docList */
	err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList);
	if (err) return err;

	/*
	 * We ignore the validity check, because we trust the FInder, and we only
	 * allow one savefile to be opened, so we ignore the depth of the list.
	 */

	err = AEGetNthPtr(&docList, 1L, typeFSS, &keywd,
	                  &returnedType, (Ptr) & myFSS, sizeof(myFSS), &actualSize);
	if (err) return err;

	/* Only needed to check savefile type below */
	err = FSpGetFInfo(&myFSS, &myFileInfo);
	if (err)
	{
		strnfmt(msg, 128, "Argh!  FSpGetFInfo failed with code %d", err);
		mac_warning(msg);
		return err;
	}

	/* Ignore non 'SAVE' files */
	if (myFileInfo.fdType != 'SAVE') return noErr;

	/* XXX XXX XXX Extract a file name */
	PathNameFromDirID(myFSS.parID, myFSS.vRefNum, (StringPtr)savefile);
	pstrcat((StringPtr)savefile, (StringPtr)&myFSS.name);

	/* Convert the string */
	ptocstr((StringPtr)savefile);

	/* Delay actual open */
	open_when_ready = TRUE;

	/* Dispose */
	err = AEDisposeDesc(&docList);

	/* Success */
	return noErr;
}


#endif



/*
 * Macintosh modifiers (event.modifier & ccc):
 *   cmdKey, optionKey, shiftKey, alphaLock, controlKey
 *
 *
 * Macintosh Keycodes (0-63 normal, 64-95 keypad, 96-127 extra):
 *
 * Return:36
 * Delete:51
 *
 * Period:65
 * Star:67
 * Plus:69
 * Clear:71
 * Slash:75
 * Enter:76
 * Minus:78
 * Equal:81
 * 0-7:82-89
 * 8-9:91-92
 *
 * backslash/vertical bar (Japanese keyboard):93
 *
 * F5: 96
 * F6: 97
 * F7: 98
 * F3:99
 * F8:100
 * F10:101
 * F11:103
 * F13:105
 * F14:107
 * F9:109
 * F12:111
 * F15:113
 * Help:114
 * Home:115
 * PgUp:116
 * Del:117
 * F4: 118
 * End:119
 * F2:120
 * PgDn:121
 * F1:122
 * Lt:123
 * Rt:124
 * Dn:125
 * Up:126
 */


/*
 * Optimize non-blocking calls to "CheckEvents()"
 * Idea from "Maarten Hazewinkel "
 */
#define EVENT_TICKS 6


/*
 * Check for Events, return TRUE if we process any
 *
 * Hack -- Handle AppleEvents if appropriate (ignore result code).
 */
static bool CheckEvents(bool wait)
{
	EventRecord event;

	WindowPtr w;

	Rect r;

	long newsize;

	int ch, ck;

	int mc, ms, mo, mx;

	int i;

	term_data *td = NULL;

	UInt32 curTicks;

	static UInt32 lastTicks = 0L;


	/* Access the clock */
	curTicks = TickCount();

	/* Hack -- Allow efficient checking for non-pending events */
	if (!wait && (curTicks < lastTicks + EVENT_TICKS)) return (FALSE);

	/* Timestamp last check */
	lastTicks = curTicks;

	/* Let the "system" run */
	SystemTask();

	/* Get an event (or null) */
	WaitNextEvent(everyEvent, &event, 0L, nil);

	/* Hack -- Nothing is ready yet */
	if (event.what == nullEvent) return (FALSE);


	/* Analyze the event */
	switch (event.what)
	{

#if 0

	case activateEvt:
		{
			w = (WindowPtr)event.message;

			activate(w);

			break;
		}

#endif

	case updateEvt:
		{
			/* Extract the window */
			w = (WindowPtr)event.message;

			/* Find the window */
			for (i = 0; i < MAX_TERM_DATA; i++)
			{
				/* Skip dead windows */
				if (!data[i].t) continue;

				/* Notice matches */
				if (data[i].w == w) td = &data[i];
			}

			/* Hack XXX XXX XXX */
			BeginUpdate(w);
			EndUpdate(w);

			/* Redraw the window */
			if (td) term_data_redraw(td);

			break;
		}

	case keyDown:
	case autoKey:
		{
			/* Extract some modifiers */
			mc = (event.modifiers & controlKey) ? TRUE : FALSE;
			ms = (event.modifiers & shiftKey) ? TRUE : FALSE;
			mo = (event.modifiers & optionKey) ? TRUE : FALSE;
			mx = (event.modifiers & cmdKey) ? TRUE : FALSE;

			/* Keypress: (only "valid" if ck < 96) */
			ch = (event.message & charCodeMask) & 255;

			/* Keycode: see table above */
			ck = ((event.message & keyCodeMask) >> 8) & 255;

			/* Command + "normal key" -> menu action */
			if (mx && (ck < 64))
			{
				/* Hack -- Prepare the menus */
				setup_menus();

				/* Mega-Hack -- allow easy exit if nothing to save */
				/* if (!character_generated && (ch=='Q' || ch=='q')) ch = 'e'; */

				/* Run the Menu-Handler */
				menu(MenuKey(ch));

				/* Turn off the menus */
				HiliteMenu(0);

				/* Done */
				break;
			}


			/* Hide the mouse pointer */
			ObscureCursor();

			/* Normal key -> simple keypress */
			if ((ck < 64) || (ck == 93))
			{
				/* Enqueue the keypress */
				Term_keypress(ch);
			}

			/* Keypad keys -> trigger plus simple keypress */
			else if (!mc && !ms && !mo && !mx && (ck < 96))
			{
				/* Hack -- "enter" is confused */
				if (ck == 76) ch = '\n';

				/* Begin special trigger */
				Term_keypress(31);

				/* Send the "keypad" modifier */
				Term_keypress('K');

				/* Send the "ascii" keypress */
				Term_keypress(ch);

				/* Terminate the trigger */
				Term_keypress(13);
			}

			/* Bizarre key -> encoded keypress */
			else if (ck <= 127)
			{
				/* Begin special trigger */
				Term_keypress(31);

				/* Send some modifier keys */
				if (mc) Term_keypress('C');
				if (ms) Term_keypress('S');
				if (mo) Term_keypress('O');
				if (mx) Term_keypress('X');

				/* Downshift and encode the keycode */
				Term_keypress(I2D((ck - 64) / 10));
				Term_keypress(I2D((ck - 64) % 10));

				/* Terminate the trigger */
				Term_keypress(13);
			}

			break;
		}

	case mouseDown:
		{
			int code;

			/* Analyze click location */
			code = FindWindow(event.where, &w);

			/* Find the window */
			for (i = 0; i < MAX_TERM_DATA; i++)
			{
				/* Skip dead windows */
				if (!data[i].t) continue;

				/* Notice matches */
				if (data[i].w == w) td = &data[i];
			}

			/* Analyze */
			switch (code)
			{
			case inMenuBar:
				{
					setup_menus();
					menu(MenuSelect(event.where));
					HiliteMenu(0);
					break;
				}

			case inSysWindow:
				{
					SystemClick(&event, w);
					break;
				}

			case inDrag:
				{
					Point p;

					WindowPtr old_win;

					r = qd.screenBits.bounds;
					r.top += 20;  /* GetMBarHeight() XXX XXX XXX */
					InsetRect(&r, 4, 4);
					DragWindow(w, event.where, &r);

					/* Oops */
					if (!td) break;

					/* Save */
					old_win = active;

					/* Activate */
					activate(td->w);

					/* Analyze */
					p.h = td->w->portRect.left;
					p.v = td->w->portRect.top;
					LocalToGlobal(&p);
					td->r.left = p.h;
					td->r.top = p.v;

					/* Restore */
					activate(old_win);

					/* Apply and Verify */
					term_data_check_size(td);

					break;
				}

			case inGoAway:
				{
					/* Oops */
					if (!td) break;

					/* Track the go-away box */
					if (TrackGoAway(w, event.where))
					{
						/* Not Mapped */
						td->mapped = FALSE;

						/* Not Mapped */
						td->t->mapped_flag = FALSE;

						/* Hide the window */
						HideWindow(td->w);
					}

					break;
				}

			case inGrow:
				{
					int x, y;

					term *old = Term;

					/* Oops */
					if (!td) break;

#ifndef ALLOW_BIG_SCREEN

					/* Fake rectangle */
					r.left = 20 * td->tile_wid + td->size_ow1;
					r.right = 80 * td->tile_wid + td->size_ow1 + td->size_ow2 + 1;
					r.top = 1 * td->tile_hgt + td->size_oh1;
					r.bottom = 24 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;

#else /* ALLOW_BIG_SCREEN */

					/* Fake rectangle */
					r.left = 20 * td->tile_wid + td->size_ow1;
					r.right = qd.screenBits.bounds.right;
					r.top = 1 * td->tile_hgt + td->size_oh1;
					r.bottom = qd.screenBits.bounds.bottom;

#endif /* ALLOW_BIG_SCREEN */

					/* Grow the rectangle */
					newsize = GrowWindow(w, event.where, &r);

					/* Handle abort */
					if (!newsize) break;

					/* Extract the new size in pixels */
					y = HiWord(newsize) - td->size_oh1 - td->size_oh2;
					x = LoWord(newsize) - td->size_ow1 - td->size_ow2;

					/* Extract a "close" approximation */
					td->rows = y / td->tile_hgt;
					td->cols = x / td->tile_wid;

					/* Apply and Verify */
					term_data_check_size(td);

					/* Activate */
					Term_activate(td->t);

					/* Hack -- Resize the term */
					Term_resize(td->cols, td->rows);

					/* Resize and Redraw */
					term_data_resize(td);
					term_data_redraw(td);

					/* Restore */
					Term_activate(old);

					break;
				}

			case inContent:
				{
					SelectWindow(w);

					break;
				}
			}

			break;
		}

		/* Disk Event -- From "Maarten Hazewinkel" */
	case diskEvt:
		{
			/* check for error when mounting the disk */
			if (HiWord(event.message) != noErr)
			{
				Point p =
				        {120, 120};

				DILoad();
				DIBadMount(p, event.message);
				DIUnload();
			}

			break;
		}

		/* OS Event -- From "Maarten Hazewinkel" */
	case osEvt:
		{
			switch ((event.message >> 24) & 0x000000FF)
			{
			case suspendResumeMessage:

				/* Resuming: activate the front window */
				if (event.message & resumeFlag)
				{
					SetPort(FrontWindow());
					SetCursor(&qd.arrow);
				}

				/* Suspend: deactivate the front window */
				else
				{
					/* Nothing */
				}

				break;
			}

			break;
		}

#ifdef USE_SFL_CODE

		/* From "Steve Linberg" and "Maarten Hazewinkel" */
	case kHighLevelEvent:
		{
			/* Process apple events */
			if (AEProcessAppleEvent(&event) != noErr)
			{
				plog("Error in Apple Event Handler!");
			}

			/* Handle "quit_when_ready" */
			if (quit_when_ready)
			{
				/* Forget */
				quit_when_ready = FALSE;

				/* Do the menu key */
				menu(MenuKey('q'));

				/* Turn off the menus */
				HiliteMenu(0);
			}

			/* Handle "open_when_ready" */
			handle_open_when_ready();

			break;
		}

#endif

	}


	/* Something happened */
	return (TRUE);
}




/*** Some Hooks for various routines ***/


/*
 * Mega-Hack -- emergency lifeboat
 */
static void *lifeboat = NULL;


/*
 * Hook to "release" memory
 */
#ifdef NEW_ZVIRT_HOOKS /* [V] removed the unused 'size' argument. */
static void *hook_rnfree(void *v)
#else
static void *hook_rnfree(void *v, size_t size)
#endif /* NEW_ZVIRT_HOOKS */
{

#ifndef NEW_ZVIRT_HOOKS /* Oh, no. */
#pragma unused (size)
#endif

#ifdef USE_MALLOC

	/* Alternative method */
	free(v);

#else

	/* Dispose */
	DisposePtr(v);

#endif

	/* Success */
	return (NULL);
}

/*
 * Hook to "allocate" memory
 */
static void *hook_ralloc(size_t size)
{

#ifdef USE_MALLOC

	/* Make a new pointer */
	return (malloc(size));

#else

	/* Make a new pointer */
	return (NewPtr(size));

#endif

}

/*
 * Hook to handle "out of memory" errors
 */
static void *hook_rpanic(size_t size)
{

#pragma unused (size)

	/* void *mem = NULL; */

	/* Free the lifeboat */
	if (lifeboat)
	{
		/* Free the lifeboat */
		DisposePtr(lifeboat);

		/* Forget the lifeboat */
		lifeboat = NULL;

		/* Mega-Hack -- Warning */
		mac_warning("Running out of Memory!\rAbort this process now!");

		/* Mega-Hack -- Never leave this function */
		while (TRUE) CheckEvents(TRUE);
	}

	/* Mega-Hack -- Crash */
	return (NULL);
}


/*
 * Hook to tell the user something important
 */
static void hook_plog(cptr str)
{
	/* Warning message */
	mac_warning(str);
}


/*
 * Hook to tell the user something, and then quit
 */
static void hook_quit(cptr str)
{
	/* Warning if needed */
	if (str) mac_warning(str);

#ifdef USE_ASYNC_SOUND

	/* Cleanup sound player */
	cleanup_sound();

#endif /* USE_ASYNC_SOUND */

	/* Dispose of graphic tiles */
	if (frameP)
	{
		/* Unlock */
		BenSWUnlockFrame(frameP);

		/* Dispose of the GWorld */
		DisposeGWorld(frameP->framePort);

		/* Dispose of the memory */
		DisposePtr((Ptr)frameP);
	}

	/* Write a preference file */
	save_pref_file();

	/* All done */
	ExitToShell();
}


/*
 * Hook to tell the user something, and then crash
 */
static void hook_core(cptr str)
{
	/* XXX Use the debugger */
	/* DebugStr(str); */

	/* Warning */
	if (str) mac_warning(str);

	/* Warn, then save player */
	mac_warning("Fatal error.\rI will now attempt to save and quit.");

	/* Attempt to save */
	if (!save_player()) mac_warning("Warning -- save failed!");

	/* Quit */
	quit(NULL);
}



/*** Main program ***/


/*
 * Init some stuff
 *
 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
 * "Macintosh Save Bug" by using "absolute" path names, since on
 * System 7 machines anyway, the "current working directory" often
 * "changes" due to background processes, invalidating any "relative"
 * path names.  Note that the Macintosh is limited to 255 character
 * path names, so be careful about deeply embedded directories...
 *
 * XXX XXX XXX Hack -- This function attempts to "fix" the nasty
 * "missing lib folder bug" by allowing the user to help find the
 * "lib" folder by hand if the "application folder" code fails...
 */
static void init_stuff(void)
{
	int i;

	short vrefnum;
	long drefnum;
	long junk;

	SFTypeList types;
	SFReply reply;

	Rect r;
	Point topleft;

	char path[1024];


	/* Fake rectangle */
	r.left = 0;
	r.top = 0;
	r.right = 344;
	r.bottom = 188;

	/* Center it */
	center_rect(&r, &qd.screenBits.bounds);

	/* Extract corner */
	topleft.v = r.top;
	topleft.h = r.left;


	/* Default to the "lib" folder with the application */
	refnum_to_name(path, app_dir, app_vol, (char*)("\plib:"));


	/* Check until done */
	while (1)
	{
		/* Prepare the paths */
		init_file_paths(path);

		/* Build the filename */
		path_build(path, 1024, ANGBAND_DIR_FILE, "news.txt");

		/* Attempt to open and close that file */
		if (0 == fd_close(fd_open(path, O_RDONLY))) break;

		/* Warning */
		plog_fmt("Unable to open the '%s' file.", path);

		/* Warning */
		plog("The Angband 'lib' folder is probably missing or misplaced.");

		/* Warning */
		plog("Please 'open' any file in any sub-folder of the 'lib' folder.");

		/* Allow "text" files */
		types[0] = 'TEXT';

		/* Allow "save" files */
		types[1] = 'SAVE';

		/* Allow "data" files */
		types[2] = 'DATA';

		/* Get any file */
		SFGetFile(topleft, "\p", NULL, 3, types, NULL, &reply);

		/* Allow cancel */
		if (!reply.good) quit(NULL);

		/* Extract textual file name for given file */
		GetWDInfo(reply.vRefNum, &vrefnum, &drefnum, &junk);
		refnum_to_name(path, drefnum, vrefnum, (char*)reply.fName);

		/* Hack -- Remove the "filename" */
		i = strlen(path) - 1;
		while ((i > 0) && (path[i] != ':')) i--;
		if (path[i] == ':') path[i + 1] = '\0';

		/* Hack -- allow "lib" folders */
		if (suffix(path, "lib:")) continue;

		/* Hack -- Remove the "sub-folder" */
		i = i - 1;
		while ((i > 1) && (path[i] != ':')) i--;
		if (path[i] == ':') path[i + 1] = '\0';
	}
}


/*
 * Macintosh Main loop
 */
int main(void)
{
	int i;

	EventRecord tempEvent;
	int numberOfMasters = 10;

	/* Increase stack space by 64K */
	SetApplLimit(GetApplLimit() - 65536L);

	/* Stretch out the heap to full size */
	MaxApplZone();

	/* Get more Masters */
	while (numberOfMasters--) MoreMasters();

	/* Set up the Macintosh */
	InitGraf(&qd.thePort);
	InitFonts();
	InitWindows();
	InitMenus();
	/* TEInit(); */
	InitDialogs(NULL);
	InitCursor();

	/* Flush events */
	FlushEvents(everyEvent, 0);

	/* Flush events some more (?) */
	if (EventAvail(everyEvent, &tempEvent)) FlushEvents(everyEvent, 0);


#ifdef ANGBAND_LITE_MAC

	/* Nothing */

#else /* ANGBAND_LITE_MAC */

# if defined(powerc) || defined(__powerc)

	/* Assume System 7 */

	/* Assume Color Quickdraw */

# else

	/* Block */
	if (TRUE)
	{
		OSErr err;
		long versionNumber;

		/* Check the Gestalt */
		err = Gestalt(gestaltSystemVersion, &versionNumber);

		/* Check the version */
		if ((err != noErr) || (versionNumber < 0x0700))
		{
			quit("You must have System 7 to use this program.");
		}
	}

	/* Block */
	if (TRUE)
	{
		SysEnvRec env;

		/* Check the environs */
		if (SysEnvirons(1, &env) != noErr)
		{
			quit("The SysEnvirons call failed!");
		}

		/* Check for System Seven Stuff */
		if (env.systemVersion < 0x0700)
		{
			quit("You must have System 7 to use this program.");
		}

		/* Check for Color Quickdraw */
		if (!env.hasColorQD)
		{
			quit("You must have Color Quickdraw to use this program.");
		}
	}

# endif 

#endif /* ANGBAND_LITE_MAC */


#ifdef USE_SFL_CODE

	/* Obtain a "Universal Procedure Pointer" */
	AEH_Start_UPP = NewAEEventHandlerProc(AEH_Start);

	/* Install the hook (ignore error codes) */
	AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, AEH_Start_UPP,
	                      0L, FALSE);

	/* Obtain a "Universal Procedure Pointer" */
	AEH_Quit_UPP = NewAEEventHandlerProc(AEH_Quit);

	/* Install the hook (ignore error codes) */
	AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, AEH_Quit_UPP,
	                      0L, FALSE);

	/* Obtain a "Universal Procedure Pointer" */
	AEH_Print_UPP = NewAEEventHandlerProc(AEH_Print);

	/* Install the hook (ignore error codes) */
	AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, AEH_Print_UPP,
	                      0L, FALSE);

	/* Obtain a "Universal Procedure Pointer" */
	AEH_Open_UPP = NewAEEventHandlerProc(AEH_Open);

	/* Install the hook (ignore error codes) */
	AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, AEH_Open_UPP,
	                      0L, FALSE);

#endif


	/* Find the current application */
	SetupAppDir();


	/* Mark ourself as the file creator */
	_fcreator = ANGBAND_CREATOR;

	/* Default to saving a "text" file */
	_ftype = 'TEXT';


#if defined(ALLOW_NO_SAVE_QUITS) && defined(__MWERKS__)

	/* Obtian a "Universal Procedure Pointer" */
	ynfilterUPP = NewModalFilterProc(ynfilter);

#endif /* ALLOW_NO_SAVE_QUITS && __MWERKS__ */


	/* Hook in some "z-virt.c" hooks */
	rnfree_aux = hook_rnfree;
	ralloc_aux = hook_ralloc;
	rpanic_aux = hook_rpanic;

	/* Hooks in some "z-util.c" hooks */
	plog_aux = hook_plog;
	quit_aux = hook_quit;
	core_aux = hook_core;


	/* Initialize colors */
	for (i = 0; i < 256; i++)
	{
		u16b rv, gv, bv;

		/* Extract the R,G,B data */
		rv = angband_color_table[i][1];
		gv = angband_color_table[i][2];
		bv = angband_color_table[i][3];

		/* Save the actual color */
		color_info[i].red = (rv | (rv << 8));
		color_info[i].green = (gv | (gv << 8));
		color_info[i].blue = (bv | (bv << 8));
	}


	/* Show the "watch" cursor */
	SetCursor(*(GetCursor(watchCursor)));

	/* Prepare the menubar */
	init_menubar();

	/* Prepare the windows */
	init_windows();

	/* Hack -- process all events */
	while (CheckEvents(TRUE)) /* loop */;

	/* Reset the cursor */
	SetCursor(&qd.arrow);


	/* Mega-Hack -- Allocate a "lifeboat" */
	lifeboat = NewPtr(16384);

	/* Note the "system" */
	ANGBAND_SYS = "mac";


	/* Initialize */
	init_stuff();

	/* Initialize */
	init_angband();


	/* Hack -- process all events */
	while (CheckEvents(TRUE)) /* loop */;


	/* We are now initialized */
	initialized = TRUE;


	/* Handle "open_when_ready" */
	handle_open_when_ready();

#ifndef SAVEFILE_SCREEN

	/* Prompt the user */
	/* In [Z], it's currently prtf(17, 23, ); */
	prt("[Choose 'New' or 'Open' from the 'File' menu]", 23, 15);

	/* Flush the prompt */
	Term_fresh();

	/* Hack -- Process Events Forever */
	while (TRUE) CheckEvents(TRUE);

#else

	/* Game is in progress */
	game_in_progress = 1;

	/* Wait for keypress */
	pause_line(23);

	/* flush input - Warning: without this, _system_ would hang */
	flush();

	/* Play the game - note the value of the argument */
	play_game(FALSE);

	/* Quit */
	quit(NULL);

#endif /* !SAVEFILE_SCREEN */
}

#endif /* MACINTOSH */
tome-235-src/src/main-lsl.c0000644000076400017500000002655111012107763013346 0ustar  dgdg/*
 * File: main-lsl.c
 * Purpose: Support for Linux-SVGALIB Angband
 * Original Author: Jon Taylor (taylorj@gaia.ecs.csus.edu)
 * Update by: Dennis Payne (dulsi@identicalsoftware.com)
 * Version: 1.4.0, 12/05/99
 *
 * Large amounts of code rewritten by Steven Fuerst. 20/04/2001
 *
 * It now uses a hacked-up version of the X11 bmp-loading code.
 * (Preparing to use 256 colour 16x16 mode)
 */

#include "angband.h"

#ifdef USE_LSL

/* Standard C header files */
#include 
#include 

/* SVGAlib header files */
#include 
#include 
#include 
#include 

#define COLOR_OFFSET 240

/* Hack - Define font/graphics cell width and height */
#define CHAR_W 8
#define CHAR_H 13

/* Global palette */
static byte *pal = NULL;

#ifdef USE_GRAPHICS

/*
 * The Win32 "BITMAPFILEHEADER" type.
 */
typedef struct BITMAPFILEHEADER
{
	u16b bfType;
	u32b bfSize;
	u16b bfReserved1;
	u16b bfReserved2;
	u32b bfOffBits;
}
BITMAPFILEHEADER;


/*
 * The Win32 "BITMAPINFOHEADER" type.
 */
typedef struct BITMAPINFOHEADER
{
	u32b biSize;
	u32b biWidth;
	u32b biHeight;
	u16b biPlanes;
	u16b biBitCount;
	u32b biCompresion;
	u32b biSizeImage;
	u32b biXPelsPerMeter;
	u32b biYPelsPerMeter;
	u32b biClrUsed;
	u32b biClrImportand;
}
BITMAPINFOHEADER;

/*
 * The Win32 "RGBQUAD" type.
 */
typedef struct RGBQUAD
{
	unsigned char b, g, r;
	unsigned char filler;
}
RGBQUAD;


/*** Helper functions for system independent file loading. ***/

static byte get_byte(FILE *fff)
{
	/* Get a character, and return it */
	return (getc(fff) & 0xFF);
}

static void rd_byte(FILE *fff, byte *ip)
{
	*ip = get_byte(fff);
}

static void rd_u16b(FILE *fff, u16b *ip)
{
	(*ip) = get_byte(fff);
	(*ip) |= ((u16b)(get_byte(fff)) << 8);
}

static void rd_u32b(FILE *fff, u32b *ip)
{
	(*ip) = get_byte(fff);
	(*ip) |= ((u32b)(get_byte(fff)) << 8);
	(*ip) |= ((u32b)(get_byte(fff)) << 16);
	(*ip) |= ((u32b)(get_byte(fff)) << 24);
}


/*
 * Read a Win32 BMP file.
 *
 * Assumes that the bitmap has a size such that no padding is needed in
 * various places.  Currently only handles bitmaps with 3 to 256 colors.
 */
static byte *ReadBMP(char *Name, int *bw, int *bh)
{
	FILE *f;

	BITMAPFILEHEADER fileheader;
	BITMAPINFOHEADER infoheader;

	byte *Data;

	int ncol;

	int total;

	int i;

	u16b x, y;

	/* Open the BMP file */
	f = fopen(Name, "r");

	/* No such file */
	if (!f)
	{
		quit ("No bitmap to load!");
	}

	/* Read the "BITMAPFILEHEADER" */
	rd_u16b(f, &(fileheader.bfType));
	rd_u32b(f, &(fileheader.bfSize));
	rd_u16b(f, &(fileheader.bfReserved1));
	rd_u16b(f, &(fileheader.bfReserved2));
	rd_u32b(f, &(fileheader.bfOffBits));

	/* Read the "BITMAPINFOHEADER" */
	rd_u32b(f, &(infoheader.biSize));
	rd_u32b(f, &(infoheader.biWidth));
	rd_u32b(f, &(infoheader.biHeight));
	rd_u16b(f, &(infoheader.biPlanes));
	rd_u16b(f, &(infoheader.biBitCount));
	rd_u32b(f, &(infoheader.biCompresion));
	rd_u32b(f, &(infoheader.biSizeImage));
	rd_u32b(f, &(infoheader.biXPelsPerMeter));
	rd_u32b(f, &(infoheader.biYPelsPerMeter));
	rd_u32b(f, &(infoheader.biClrUsed));
	rd_u32b(f, &(infoheader.biClrImportand));

	/* Verify the header */
	if (feof(f) ||
	                (fileheader.bfType != 19778) ||
	                (infoheader.biSize != 40))
	{
		quit_fmt("Incorrect BMP file format %s", Name);
	}

	/* The two headers above occupy 54 bytes total */
	/* The "bfOffBits" field says where the data starts */
	/* The "biClrUsed" field does not seem to be reliable */
	/* Compute number of colors recorded */
	ncol = (fileheader.bfOffBits - 54) / 4;

	for (i = 0; i < ncol; i++)
	{
		RGBQUAD clrg;

		/* Read an "RGBQUAD" */
		rd_byte(f, &(clrg.b));
		rd_byte(f, &(clrg.g));
		rd_byte(f, &(clrg.r));
		rd_byte(f, &(clrg.filler));

		/* Analyze the color */
		pal[i * 3] = clrg.b;
		pal[i * 3 + 1] = clrg.g;
		pal[i * 3 + 2] = clrg.r;
	}

	/* Look for illegal bitdepths. */
	if ((infoheader.biBitCount == 1) || (infoheader.biBitCount == 24))
	{
		quit_fmt("Illegal biBitCount %d in %s",
		         infoheader.biBitCount, Name);
	}

	/* Determine total bytes needed for image */
	total = infoheader.biWidth * (infoheader.biHeight + 2);

	/* Allocate image memory */
	C_MAKE(Data, total, byte);

	for (y = 0; y < infoheader.biHeight; y++)
	{
		int y2 = infoheader.biHeight - y - 1;

		for (x = 0; x < infoheader.biWidth; x++)
		{
			int ch = getc(f);

			/* Verify not at end of file XXX XXX */
			if (feof(f)) quit_fmt("Unexpected end of file in %s", Name);

			if (infoheader.biBitCount == 8)
			{
				Data[x + y2 * infoheader.biWidth] = ch;
			}
			else if (infoheader.biBitCount == 4)
			{
				Data[x + y2 * infoheader.biWidth] = ch / 16;
				x++;
				Data[x + y2 * infoheader.biWidth] = ch % 16;
			}
		}
	}

	fclose(f);

	/* Save the size for later */
	*bw = infoheader.biWidth;
	*bh = infoheader.biHeight;

	return (Data);
}

#endif /* USE_GRAPHICS */


/* The main "term" structure */
static term term_screen_body;

/* The visible and virtual screens */
GraphicsContext *screen;
GraphicsContext *buffer;

/* The font data */
static void *font;

/* Initialize the screen font */
static void initfont(void)
{
	gzFile fontfile;
	void *temp;
	long junk;

	if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psf.gz", "r")))
	{
		/* Try uncompressed */
		if (!(fontfile = gzopen("/usr/lib/kbd/consolefonts/lat1-12.psf", "r")))
		{
			printf ("Error: could not open font file.  Aborting....\n");
			exit(1);
		}
	}

	/* Junk the 4-byte header */
	gzread(fontfile, &junk, 4);

	/* Initialize font */

	/*
	 * Read in 13 bytes per character, and there are 256 characters
	 * in the font.  This means we need to load 13x256 = 3328 bytes.
	 */
	C_MAKE(temp, 256 * 13, byte);
	gzread(fontfile, temp, 256 * 13);

	/*
	 * I don't understand this code - SF
	 * (Is it converting from 8x13 -> 8x12?) 
	 *
	 * I assume 15 is a colour...
	 */
	font = malloc(256 * 8 * 12 * BYTESPERPIXEL);
	gl_expandfont(8, 12, 15, temp, font);
	gl_setfont(8, 12, font);

	/* Cleanup */
	C_FREE(temp, 256 * 13, byte);
	gzclose(fontfile);
}

/* Initialize palette values for colors 0-15 */
static void setpal(void)
{
	int i;
	gl_setpalette(pal);
	for (i = 0; i < 16; i++)
	{
		gl_setpalettecolor(COLOR_OFFSET + i,
		                   angband_color_table[i][1] >> 2,
		                   angband_color_table[i][2] >> 2,
		                   angband_color_table[i][3] >> 2);
	}
}

/*
 * Check for "events"
 * If block, then busy-loop waiting for event, else check once and exit.
 */
static errr CheckEvents(int block)
{
	int k = 0;

	if (block)
	{
		k = vga_getkey();
		if (k < 1) return (1);
	}
	else
	{
		k = vga_getch();
	}

	Term_keypress(k);
	return (0);
}


/*
 * Low-level graphics routine (assumes valid input)
 * Do a "special thing"
 */
static errr term_xtra_svgalib(int n, int v)
{
	switch (n)
	{
	case TERM_XTRA_EVENT:
		{
			/* Process some pending events */
			if (v) return (CheckEvents (FALSE));
			while (!CheckEvents (TRUE));
			return 0;
		}

	case TERM_XTRA_FLUSH:
		{
			/* Flush all pending events */
			/* Should discard all key presses but unimplemented */
			return 0;
		}

	case TERM_XTRA_CLEAR:
		{
			/* Clear the entire window */
			gl_fillbox (0, 0, 80 * CHAR_W, 25 * CHAR_H, 0);
			return 0;
		}

	case TERM_XTRA_DELAY:
		{
			/* Delay for some milliseconds */
			usleep(1000 * v);
			return 0;
		}
	}
	return 1;
}

/*
 * Low-level graphics routine (assumes valid input)
 * Draws a "cursor" at (x,y)
 */
static errr term_curs_svgalib(int x, int y)
{
	gl_fillbox(x * CHAR_W, y * CHAR_H, CHAR_W, CHAR_H, 15);
	return (0);
}

/*
 * Low-level graphics routine (assumes valid input)
 * Erases a rectangular block of characters from (x,y) to (x+w,y+h)
 */
static errr term_wipe_svgalib(int x, int y, int n)
{
	gl_fillbox(x * CHAR_W, y * CHAR_H, n * CHAR_W, CHAR_H, 0);
	return (0);
}

/*
 * Low-level graphics routine (assumes valid input)
 * Draw n chars at location (x,y) with value s and attribute a
 */
static errr term_text_svgalib(int x, int y, int n, byte a, cptr s)
{
	/* Clear the area */
	term_wipe_svgalib(x, y, n);

	/* Draw the coloured text */
	gl_colorfont(8, 12, COLOR_OFFSET + (a & 0x0F), font);
	gl_writen(x * CHAR_W, y * CHAR_H, n, (char *) s);
	return (0);
}

/*
 * Low-level graphics routine (assumes valid input)
 * Draw n chars at location (x,y) with value s and attribute a
 */

#ifdef USE_GRAPHICS

# ifdef USE_TRANSPARENCY
static errr term_pict_svgalib(int x, int y, int n,
                              const byte *ap, const char *cp, const byte *tap, const char *tcp)
# else /* USE_TRANSPARENCY */
static errr term_pict_svgalib(int x, int y, int n,
                              const byte *ap, const char *cp)
# endif  /* USE_TRANSPARENCY */
{
	int i;
	int x2, y2;


# ifdef USE_TRANSPARENCY
	/* Hack - Ignore unused transparency data for now */
	(void) tap;
	(void) tcp;
# endif  /* USE_TRANSPARENCY */

	for (i = 0; i < n; i++)
	{
		x2 = (cp[i] & 0x7F) * CHAR_W;
		y2 = (ap[i] & 0x7F) * CHAR_H;

		gl_copyboxfromcontext(buffer, x2, y2, CHAR_W, CHAR_H,
		                      (x + i) * CHAR_W, y * CHAR_H);
	}
	return (0);
}

static void term_load_bitmap(void)
{
	char path[1024];

	byte *temp = NULL;

	int bw, bh;

	/* Build the "graf" path */
	path_build(path, 1024, ANGBAND_DIR_XTRA, "graf");

	sprintf (path, "%s/8x13.bmp", path);

	/* See if the file exists */
	if (fd_close(fd_open(path, O_RDONLY)))
	{
		printf ("Unable to load bitmap data file %s, bailing out....\n", path);
		exit ( -1);
	}

	temp = ReadBMP(path, &bw, &bh);

	/* Blit bitmap into buffer */
	gl_putbox(0, 0, bw, bh, temp);

	FREE(temp, byte);

	return;
}

#endif /* USE_GRAPHICS */

/*
 * Term hook
 * Initialize a new term
 */
static void term_init_svgalib(term *t)
{
	int vgamode;

	/* Only one term */
	(void) t;

	vga_init();

	/* The palette is 256x3 bytes big (RGB). */
	C_MAKE(pal, 768, byte);

#ifdef USE_GRAPHICS

	/* Hardwire this mode in for now */
	vgamode = G1024x768x256;

	/* Set up the bitmap buffer context */
	gl_setcontextvgavirtual(vgamode);
	buffer = gl_allocatecontext();
	gl_getcontext(buffer);

	/* Load bitmap into virtual screen */
	term_load_bitmap();

#endif /* USE_GRAPHICS */

	/* Hardwire this mode in for now */
	vgamode = G640x480x256;

	/* Set up the physical screen context */
	if (vga_setmode(vgamode) < 0)
	{
		quit("Graphics mode not available!");
	}

	gl_setcontextvga(vgamode);
	screen = gl_allocatecontext();
	gl_getcontext(screen);

	/* Is this needed? */
	gl_enablepageflipping(screen);

	/* Set up palette colors */
	setpal();

	/* Load the character font data */
	initfont();

	/* Color 0 isn't transparent */
	gl_setwritemode(WRITEMODE_OVERWRITE);
}

/*
 * Term hook
 * Nuke an old term
 */
static void term_nuke_svgalib(term *t)
{
	/* Only one term */
	(void) t;

	vga_setmode(TEXT);
}

/*
 * Hook SVGAlib routines into term.c
 */
errr init_lsl(void)
{
	term *t = &term_screen_body;

#ifdef USE_GRAPHICS

	if (arg_graphics)
	{
		use_graphics = TRUE;
	}

#endif /* USE_GRAPHICS */

	/* Initialize the term */
	term_init(t, 80, 24, 1024);

	/* The cursor is done via software and needs erasing */
	t->soft_cursor = TRUE;

	t->attr_blank = TERM_DARK;
	t->char_blank = ' ';

	/* Add hooks */
	t->init_hook = term_init_svgalib;
	t->nuke_hook = term_nuke_svgalib;
	t->text_hook = term_text_svgalib;

#ifdef USE_GRAPHICS

	if (use_graphics)
	{
		t->pict_hook = term_pict_svgalib;
		t->higher_pict = TRUE;
	}

#endif /* USE_GRAPHICS */

	t->wipe_hook = term_wipe_svgalib;
	t->curs_hook = term_curs_svgalib;
	t->xtra_hook = term_xtra_svgalib;

	/* Save the term */
	term_screen = t;

	/* Activate it */
	Term_activate(term_screen);

	return (0);
}

#endif /* USE_LSL */
tome-235-src/src/main-net.c0000644000076400017500000002014011012107763013326 0ustar  dgdg/* File: main-gcu.c */

/*
 * Copyright (c) 1997 Ben Harrison, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband run on Unix/Curses machines.
 *
 *
 * To use this file, you must define "USE_NET" in the Makefile.
 *
 *
 * Note that this file is not "intended" to support non-Unix machines,
 * nor is it intended to support VMS or other bizarre setups.
 *
 * Also, this package assumes that the underlying "curses" handles both
 * the "nonl()" and "cbreak()" commands correctly, see the "OPTION" below.
 *
 * This code should work with most versions of "curses" or "ncurses",
 * and the "main-ncu.c" file (and USE_NCU define) are no longer used.
 *
 * See also "USE_CAP" and "main-cap.c" for code that bypasses "curses"
 * and uses the "termcap" information directly, or even bypasses the
 * "termcap" information and sends direct vt100 escape sequences.
 *
 * This file provides up to 4 term windows.
 *
 * This file will attempt to redefine the screen colors to conform to
 * standard Angband colors.  It will only do so if the terminal type
 * indicates that it can do so.  See the page:
 *
 *     http://www.umr.edu/~keldon/ang-patch/ncurses_color.html
 *
 * for information on this.
 *
 * Consider the use of "savetty()" and "resetty()".  XXX XXX XXX
 */


#include "angband.h"


#ifdef USE_NET

/* The server connection */
ip_connection net_serv_connection_forge;
ip_connection *net_serv_connection = &net_serv_connection_forge;

/* The client connection */
ip_connection net_connection_forge;
ip_connection *net_connection = &net_connection_forge;

#define PACKET_STOP             255
#define PACKET_TEXT             254
#define PACKET_CLEAR            253

/*
 * Information about a term
 */
typedef struct term_data term_data;

struct term_data
{
	term t;                  /* All term info */
};

/* Max number of windows on screen */
#define MAX_TERM_DATA 4

/* Information about our windows */
static term_data data[MAX_TERM_DATA];


/*
 * Hack -- Number of initialized "term" structures
 */
static int active = 0;




/*
 * Suspend/Resume
 */
static errr Term_xtra_net_alive(int v)
{
	int x, y;


	/* Suspend */
	if (!v)
	{}

	/* Resume */
	else
	{}

	/* Success */
	return (0);
}



/*
 * Init the "net" system
 */
static void Term_init_net(term *t)
{
	term_data *td = (term_data *)(t->data);

	/* Count init's, handle first */
	if (active++ != 0) return;
}


/*
 * Nuke the "net" system
 */
static void Term_nuke_net(term *t)
{
	int x, y;
	term_data *td = (term_data *)(t->data);
}




/*
 * Process events (with optional wait)
 */
static errr Term_xtra_net_event(int v)
{
	int i, k;

	char buf[2];

	/* Wait */
	if (v)
	{
		/* Wait for one byte */
		i = zsock.read_simple(net_connection, buf, 1);
#if 1
		/* Hack -- Handle bizarre "errors" */
		//                if (!i) exit_game_panic();
		if (!i) return 1;
#else
		/* Try again(must be a new connection) */
		while (!i)
			i = zsock.read_simple(net_connection, buf, 1);
#endif
	}

	/* Do not wait */
	else
	{
		/* Read one byte, if possible */
		if (zsock.can_read(net_connection))
			zsock.read_simple(net_connection, buf, 1);
	}

	/* Ignore "invalid" keys */
	if (!buf[0]) return (1);

	/* Enqueue the keypress */
	Term_keypress(buf[0]);

	/* Success */
	return (0);
}

/*
 * React to changes
 */
static errr Term_xtra_net_react(void)
{

#ifdef A_COLOR

	int i;

	/* Cannot handle color redefinition */
	if (!can_fix_color) return (0);

	/* Set the colors */
	for (i = 0; i < 16; i++)
	{
		/* Set one color (note scaling) */
		init_color(i,
		           angband_color_table[i][1] * 1000 / 255,
		           angband_color_table[i][2] * 1000 / 255,
		           angband_color_table[i][3] * 1000 / 255);
	}

#endif

	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_net(int n, int v)
{
	term_data *td = (term_data *)(Term->data);
	char buf[2];

	/* Analyze the request */
	switch (n)
	{
		/* Clear screen */
	case TERM_XTRA_CLEAR:
		buf[0] = PACKET_CLEAR;
		buf[1] = '\0';
		zsock.write_simple(net_connection, buf);
		return (0);

		/* Make a noise */
	case TERM_XTRA_NOISE:
		return (0);

		/* Flush the Curses buffer */
	case TERM_XTRA_FRESH:
		return (0);

		/* Suspend/Resume curses */
	case TERM_XTRA_ALIVE:
		return (Term_xtra_net_alive(v));

		/* Process events */
	case TERM_XTRA_EVENT:
		return (Term_xtra_net_event(v));

		/* Flush events */
	case TERM_XTRA_FLUSH:
		while (!Term_xtra_net_event(FALSE));
		return (0);

		/* Delay */
	case TERM_XTRA_DELAY:
		usleep(1000 * v);
		return (0);

		/* Get Delay of some milliseconds */
	case TERM_XTRA_GET_DELAY:
		{
			int ret;
			struct timeval tv;

			ret = gettimeofday(&tv, NULL);
			Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);

			return ret;
		}

		/* React to events */
	case TERM_XTRA_REACT:
		Term_xtra_net_react();
		return (0);
	}

	/* Unknown */
	return (1);
}


/*
 * Actually MOVE the hardware cursor
 */
static errr Term_curs_net(int x, int y)
{
	term_data *td = (term_data *)(Term->data);

	/* Literally move the cursor */
	// DGDGDGD

	/* Success */
	return (0);
}


/*
 * Erase a grid of space
 * Hack -- try to be "semi-efficient".
 */
static errr Term_wipe_net(int x, int y, int n)
{
	char buf[2];

	term_data *td = (term_data *)(Term->data);

	buf[0] = PACKET_CLEAR;
	buf[1] = '\0';
	zsock.write_simple(net_connection, buf);

	/* Success */
	return (0);
}

/*
 * Place some text on the screen using an attribute
 */
static errr Term_text_net(int x, int y, int n, byte a, cptr s)
{
	term_data *td = (term_data *)(Term->data);
	char buf[5];

	buf[0] = PACKET_TEXT;
	buf[1] = y + 1;
	buf[2] = x + 1;
	buf[3] = a + 1;
	buf[4] = '\0';

	zsock.write_simple(net_connection, buf);
	zsock.write_simple(net_connection, s);

	buf[0] = PACKET_STOP;
	buf[1] = '\0';
	zsock.write_simple(net_connection, buf);

	/* Success */
	return (0);
}


/*
 * Create a window for the given "term_data" argument.
 *
 * Assumes legal arguments.
 */
static errr term_data_init_net(term_data *td, int rows, int cols)
{
	term *t = &td->t;

	/* Initialize the term */
	term_init(t, cols, rows, 256);

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Set some hooks */
	t->init_hook = Term_init_net;
	t->nuke_hook = Term_nuke_net;

	/* Set some more hooks */
	t->text_hook = Term_text_net;
	t->wipe_hook = Term_wipe_net;
	t->curs_hook = Term_curs_net;
	t->xtra_hook = Term_xtra_net;

	/* Save the data */
	t->data = td;

	/* Activate it */
	Term_activate(t);

	/* Success */
	return (0);
}


static void hook_quit(cptr str)
{
	/* Unused */
	(void)str;
}

static void net_lost_connection_hook(ip_connection *conn)
{
	printf("Lost connection ! ARGGGG\nAccepting a new one...\n");
	zsock.accept(net_serv_connection, net_connection);
	zsock.set_lose_connection(net_connection, net_lost_connection_hook);
	printf("...accepted\n");
}

/*
 * Prepare "curses" for use by the file "z-term.c"
 *
 * Installs the "hook" functions defined above, and then activates
 * the main screen "term", which clears the screen and such things.
 *
 * Someone should really check the semantics of "initscr()"
 */
errr init_net(int argc, char **argv)
{
	int i;

	int num_term = MAX_TERM_DATA, next_win = 0;
	int port = 6666;

	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-P"))
		{
			port = atoi(argv[i + 1]);
			i++;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}

	/* Activate hooks */
	quit_aux = hook_quit;
	core_aux = hook_quit;

	/* Create a term */
	term_data_init_net(&data[0], 25, 80);

	/* Remember the term */
	angband_term[0] = &data[0].t;

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

	/* Remember the active screen */
	term_screen = &data[0].t;

	/* Initialize the server and wait for thhe client */
	zsock.setup(net_serv_connection, "127.0.0.1", port, ZSOCK_TYPE_TCP, TRUE);
	zsock.open(net_serv_connection);

	printf("Accepting...\n");
	zsock.accept(net_serv_connection, net_connection);
	zsock.set_lose_connection(net_connection, net_lost_connection_hook);
	printf("...accepted\n");

	/* Success */
	return (0);
}


#endif /* USE_NET */
tome-235-src/src/main-x11.c0000644000076400017500000017510311012107763013163 0ustar  dgdg/* File: main-x11.c */

/*
 * Copyright (c) 1997 Ben Harrison, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband work with UNIX/X11 computers.
 *
 * To use this file, compile with "USE_X11" defined, and link against all
 * the various "X11" libraries which may be needed.
 *
 * See also "main-xaw.c".
 *
 * Part of this file provides a user interface package composed of several
 * pseudo-objects, including "metadpy" (a display), "infowin" (a window),
 * "infoclr" (a color), and "infofnt" (a font).  Actually, the package was
 * originally much more interesting, but it was bastardized to keep this
 * file simple.
 *
 * The rest of this file is an implementation of "main-xxx.c" for X11.
 *
 * Most of this file is by Ben Harrison (benh@phial.com).
 */

/*
 * The following shell script can be used to launch Angband, assuming that
 * it was extracted into "~/Angband", and compiled using "USE_X11", on a
 * Linux machine, with a 1280x1024 screen, using 6 windows (with the given
 * characteristics), with gamma correction of 1.8 -> (1 / 1.8) * 256 = 142,
 * and without graphics (add "-g" for graphics).  Just copy this comment
 * into a file, remove the leading " * " characters (and the head/tail of
 * this comment), and make the file executable.
 *
 *
 * #!/bin/csh
 *
 * # Describe attempt
 * echo "Launching angband..."
 * sleep 2
 *
 * # Main window
 * setenv ANGBAND_X11_FONT_0 10x20
 * setenv ANGBAND_X11_AT_X_0 5
 * setenv ANGBAND_X11_AT_Y_0 510
 *
 * # Message window
 * setenv ANGBAND_X11_FONT_1 8x13
 * setenv ANGBAND_X11_AT_X_1 5
 * setenv ANGBAND_X11_AT_Y_1 22
 * setenv ANGBAND_X11_ROWS_1 35
 *
 * # Inventory window
 * setenv ANGBAND_X11_FONT_2 8x13
 * setenv ANGBAND_X11_AT_X_2 635
 * setenv ANGBAND_X11_AT_Y_2 182
 * setenv ANGBAND_X11_ROWS_3 23
 *
 * # Equipment window
 * setenv ANGBAND_X11_FONT_3 8x13
 * setenv ANGBAND_X11_AT_X_3 635
 * setenv ANGBAND_X11_AT_Y_3 22
 * setenv ANGBAND_X11_ROWS_3 12
 *
 * # Monster recall window
 * setenv ANGBAND_X11_FONT_4 6x13
 * setenv ANGBAND_X11_AT_X_4 817
 * setenv ANGBAND_X11_AT_Y_4 847
 * setenv ANGBAND_X11_COLS_4 76
 * setenv ANGBAND_X11_ROWS_4 11
 *
 * # Object recall window
 * setenv ANGBAND_X11_FONT_5 6x13
 * setenv ANGBAND_X11_AT_X_5 817
 * setenv ANGBAND_X11_AT_Y_5 520
 * setenv ANGBAND_X11_COLS_5 76
 * setenv ANGBAND_X11_ROWS_5 24
 *
 * # The build directory
 * cd ~/Angband
 *
 * # Gamma correction
 * setenv ANGBAND_X11_GAMMA 142
 *
 * # Launch Angband
 * ./src/angband -mx11 -- -n6 &
 *
 */

#include "angband.h"

#ifdef USE_X11

#ifndef __MAKEDEPEND__
#include 
#include 
#include 
#include 
#include 
#endif /* __MAKEDEPEND__ */

#include 
#include 
#include 
#include 
#include 

#include 

/* /me pffts Solaris */
#ifndef NAME_MAX
#define	NAME_MAX	_POSIX_NAME_MAX
#endif

/*
 * Include some helpful X11 code.
 */
#include "maid-x11.c"

/*
 * Hack -- avoid some compiler warnings
 */
#define IGNORE_UNUSED_FUNCTIONS


/*
 * Notes on Colors:
 *
 *   1) On a monochrome (or "fake-monochrome") display, all colors
 *   will be "cast" to "fg," except for the bg color, which is,
 *   obviously, cast to "bg".  Thus, one can ignore this setting.
 *
 *   2) Because of the inner functioning of the color allocation
 *   routines, colors may be specified as (a) a typical color name,
 *   (b) a hexidecimal color specification (preceded by a pound sign),
 *   or (c) by strings such as "fg", "bg", "zg".
 *
 *   3) Due to the workings of the init routines, many colors
 *   may also be dealt with by their actual pixel values.  Note that
 *   the pixel with all bits set is "zg = (1<depth)-1", which
 *   is not necessarily either black or white.
 */



/**** Generic Types ****/


/*
 * An X11 pixell specifier
 */
typedef unsigned long Pixell;

/*
 * The structures defined below
 */
typedef struct metadpy metadpy;
typedef struct infowin infowin;
typedef struct infoclr infoclr;
typedef struct infofnt infofnt;


/*
 * A structure summarizing a given Display.
 *
 *	- The Display itself
 *	- The default Screen for the display
 *	- The virtual root (usually just the root)
 *	- The default colormap (from a macro)
 *
 *	- The "name" of the display
 *
 *	- The socket to listen to for events
 *
 *	- The width of the display screen (from a macro)
 *	- The height of the display screen (from a macro)
 *	- The bit depth of the display screen (from a macro)
 *
 *	- The black Pixell (from a macro)
 *	- The white Pixell (from a macro)
 *
 *	- The background Pixell (default: black)
 *	- The foreground Pixell (default: white)
 *	- The maximal Pixell (Equals: ((2 ^ depth)-1), is usually ugly)
 *
 *	- Bit Flag: Force all colors to black and white (default: !color)
 *	- Bit Flag: Allow the use of color (default: depth > 1)
 *	- Bit Flag: We created 'dpy', and so should nuke it when done.
 */
struct metadpy
{
	Display *dpy;
	Screen *screen;
	Window root;
	Colormap cmap;

	char *name;

	int fd;

	uint width;
	uint height;
	uint depth;

	Pixell black;
	Pixell white;

	Pixell bg;
	Pixell fg;
	Pixell zg;

uint mono:
	1;
uint color:
	1;
uint nuke:
	1;
};



/*
 * A Structure summarizing Window Information.
 *
 * I assume that a window is at most 30000 pixels on a side.
 * I assume that the root windw is also at most 30000 square.
 *
 *	- The Window
 *	- The current Input Event Mask
 *
 *	- The location of the window
 *	- The width, height of the window
 *	- The border width of this window
 *
 *	- Byte: 1st Extra byte
 *
 *	- Bit Flag: This window is currently Mapped
 *	- Bit Flag: This window needs to be redrawn
 *	- Bit Flag: This window has been resized
 *
 *	- Bit Flag: We should nuke 'win' when done with it
 *
 *	- Bit Flag: 1st extra flag
 *	- Bit Flag: 2nd extra flag
 *	- Bit Flag: 3rd extra flag
 *	- Bit Flag: 4th extra flag
 */
struct infowin
{
	Window win;
	long mask;

	s16b ox, oy;

	s16b x, y;
	s16b w, h;
	u16b b;

	byte byte1;

uint mapped:
	1;
uint redraw:
	1;
uint resize:
	1;

uint nuke:
	1;

uint flag1:
	1;
uint flag2:
	1;
uint flag3:
	1;
uint flag4:
	1;
};






/*
 * A Structure summarizing Operation+Color Information
 *
 *	- The actual GC corresponding to this info
 *
 *	- The Foreground Pixell Value
 *	- The Background Pixell Value
 *
 *	- Num (0-15): The operation code (As in Clear, Xor, etc)
 *	- Bit Flag: The GC is in stipple mode
 *	- Bit Flag: Destroy 'gc' at Nuke time.
 */
struct infoclr
{
	GC gc;

	Pixell fg;
	Pixell bg;

uint code:
	4;
uint stip:
	1;
uint nuke:
	1;
};



/*
 * A Structure to Hold Font Information
 *
 *	- The 'XFontStruct*' (yields the 'Font')
 *
 *	- The font name
 *
 *	- The default character width
 *	- The default character height
 *	- The default character ascent
 *
 *	- Byte: Pixel offset used during fake mono
 *
 *	- Flag: Force monospacing via 'wid'
 *	- Flag: Nuke info when done
 */
struct infofnt
{
	XFontStruct *info;

	cptr name;

	s16b wid;
	s16b twid;
	s16b hgt;
	s16b asc;

	byte off;

uint mono:
	1;
uint nuke:
	1;
};




/**** Generic Macros ****/



/* Set current metadpy (Metadpy) to 'M' */
#define Metadpy_set(M) \
Metadpy = M


/* Initialize 'M' using Display 'D' */
#define Metadpy_init_dpy(D) \
Metadpy_init_2(D,cNULL)

/* Initialize 'M' using a Display named 'N' */
#define Metadpy_init_name(N) \
Metadpy_init_2((Display*)(NULL),N)

/* Initialize 'M' using the standard Display */
#define Metadpy_init() \
Metadpy_init_name("")


/* Init an infowin by giving father as an (info_win*) (or NULL), and data */
#define Infowin_init_dad(D,X,Y,W,H,B,FG,BG) \
Infowin_init_data(((D) ? ((D)->win) : (Window)(None)), \
X,Y,W,H,B,FG,BG)


/* Init a top level infowin by pos,size,bord,Colors */
#define Infowin_init_top(X,Y,W,H,B,FG,BG) \
Infowin_init_data(None,X,Y,W,H,B,FG,BG)


/* Request a new standard window by giving Dad infowin and X,Y,W,H */
#define Infowin_init_std(D,X,Y,W,H,B) \
Infowin_init_dad(D,X,Y,W,H,B,Metadpy->fg,Metadpy->bg)


/* Set the current Infowin */
#define Infowin_set(I) \
(Infowin = (I))


/* Set the current Infoclr */
#define Infoclr_set(C) \
(Infoclr = (C))


#define Infoclr_init_ppo(F,B,O,M) \
Infoclr_init_data(F,B,O,M)

#define Infoclr_init_cco(F,B,O,M) \
Infoclr_init_ppo(Infoclr_Pixell(F),Infoclr_Pixell(B),O,M)

#define Infoclr_init_ppn(F,B,O,M) \
Infoclr_init_ppo(F,B,Infoclr_Opcode(O),M)

#define Infoclr_init_ccn(F,B,O,M) \
Infoclr_init_cco(F,B,Infoclr_Opcode(O),M)


/* Set the current infofnt */
#define Infofnt_set(I) \
(Infofnt = (I))


/* Errr: Expose Infowin */
#define Infowin_expose() \
(!(Infowin->redraw = 1))

/* Errr: Unxpose Infowin */
#define Infowin_unexpose() \
(Infowin->redraw = 0)



/**** Generic Globals ****/


/*
 * The "default" values
 */
static metadpy metadpy_default;


/*
 * The "current" variables
 */
static metadpy *Metadpy = &metadpy_default;
static infowin *Infowin = (infowin*)(NULL);
static infoclr *Infoclr = (infoclr*)(NULL);
static infofnt *Infofnt = (infofnt*)(NULL);


/**** Generic code ****/

/*
 * Simple routine to save the state of the game when the display connection
 * is broken. Remember, you cannot do anything in this function that will
 * generate X protocol requests.
 */
int x_io_error_handler(Display *d)
{
	/* We have nothing to save */
	if (!character_generated) return 0;

	save_dungeon();
	save_player();

	return 0;
}

/*
 * Calculate how much space there is in the key queue for the current term.
 */
int Term_queue_space(void)
{
	/* Find the gap if the tail is before the head. */
	int space = Term->key_tail - Term->key_head;

	/* Otherwise, add in the extra for looping. */
	if (space <= 0) space = Term->key_size - space;

	/* The last space is never used as that would be interpreted as leaving
	 * no pending keypresses. */
	return space -1;
}


/*
 * Add a series of keypresses to the "queue".
 *
 * Return any errors generated by Term_keypress() in doing so, or SUCCESS
 * if there are none.
 *
 * Catch the "out of space" error before anything is printed.
 *
 * NB: The keys added here will be interpreted by any macros or keymaps.
 */
errr type_string(char *str, uint len)
{
	char *s;

	term *old = Term;

	/* Paranoia - no string. */
	if (!str) return 5;

	/* Hack - calculate the string length here if none given. */
	if (!len) len = strlen(str);

	/* Activate the main window, as all pastes go there. */
	Term_activate(term_screen);

	/* Not enough space for the string. */
	if (Term_queue_space() <= (int)len)
		return 7;

	for (s = str; s < str + len; s++)
	{
		errr err = Term_keypress(*s);

		/* Catch errors other than "str[i] == 0", which is ignored. */
		if (err && err != -1) return err;
	}

	/* Activate the original window. */
	Term_activate(old);

	return 0;
}


/*
 * Init the current metadpy, with various initialization stuff.
 *
 * Inputs:
 *	dpy:  The Display* to use (if NULL, create it)
 *	name: The name of the Display (if NULL, the current)
 *
 * Notes:
 *	If 'name' is NULL, but 'dpy' is set, extract name from dpy
 *	If 'dpy' is NULL, then Create the named Display
 *	If 'name' is NULL, and so is 'dpy', use current Display
 *
 * Return -1 if no Display given, and none can be opened.
 */
static errr Metadpy_init_2(Display *dpy, cptr name)
{
	metadpy *m = Metadpy;

	/*** Open the display if needed ***/

	/* If no Display given, attempt to Create one */
	if (!dpy)
	{
		/* Attempt to open the display */
		dpy = XOpenDisplay(name);

		/* Failure */
		if (!dpy) return ( -1);

		/* We will have to nuke it when done */
		m->nuke = 1;
	}

	/* Since the Display was given, use it */
	else
	{
		/* We will not have to nuke it when done */
		m->nuke = 0;
	}

	XSetIOErrorHandler(x_io_error_handler);

	/*** Save some information ***/

	/* Save the Display itself */
	m->dpy = dpy;

	/* Get the Screen and Virtual Root Window */
	m->screen = DefaultScreenOfDisplay(dpy);
	m->root = RootWindowOfScreen(m->screen);

	/* Get the default colormap */
	m->cmap = DefaultColormapOfScreen(m->screen);

	/* Extract the true name of the display */
	m->name = DisplayString(dpy);

	/* Extract the fd */
	m->fd = ConnectionNumber(Metadpy->dpy);

	/* Save the Size and Depth of the screen */
	m->width = WidthOfScreen(m->screen);
	m->height = HeightOfScreen(m->screen);
	m->depth = DefaultDepthOfScreen(m->screen);

	/* Save the Standard Colors */
	m->black = BlackPixelOfScreen(m->screen);
	m->white = WhitePixelOfScreen(m->screen);

	/*** Make some clever Guesses ***/

	/* Guess at the desired 'fg' and 'bg' Pixell's */
	m->bg = m->black;
	m->fg = m->white;

	/* Calculate the Maximum allowed Pixel value.  */
	m->zg = (1 << m->depth) - 1;

	/* Save various default Flag Settings */
	m->color = ((m->depth > 1) ? 1 : 0);
	m->mono = ((m->color) ? 0 : 1);

	/* Return "success" */
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Nuke the current metadpy
 */
static errr Metadpy_nuke(void)
{
	metadpy *m = Metadpy;


	/* If required, Free the Display */
	if (m->nuke)
	{
		/* Close the Display */
		XCloseDisplay(m->dpy);

		/* Forget the Display */
		m->dpy = (Display*)(NULL);

		/* Do not nuke it again */
		m->nuke = 0;
	}

	/* Return Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * General Flush/ Sync/ Discard routine
 */
static errr Metadpy_update(int flush, int sync, int discard)
{
	/* Flush if desired */
	if (flush) XFlush(Metadpy->dpy);

	/* Sync if desired, using 'discard' */
	if (sync) XSync(Metadpy->dpy, discard);

	/* Success */
	return (0);
}


/*
 * Make a simple beep
 */
static errr Metadpy_do_beep(void)
{
	/* Make a simple beep */
	XBell(Metadpy->dpy, 100);

	return (0);
}



/*
 * Set the name (in the title bar) of Infowin
 */
static errr Infowin_set_name(cptr name)
{
	Status st;
	XTextProperty tp;
	char buf[128];
	char *bp = buf;
	strcpy(buf, name);
	st = XStringListToTextProperty(&bp, 1, &tp);
	if (st) XSetWMName(Metadpy->dpy, Infowin->win, &tp);
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Set the icon name of Infowin
 */
static errr Infowin_set_icon_name(cptr name)
{
	Status st;
	XTextProperty tp;
	char buf[128];
	char *bp = buf;
	strcpy(buf, name);
	st = XStringListToTextProperty(&bp, 1, &tp);
	if (st) XSetWMIconName(Metadpy->dpy, Infowin->win, &tp);
	return (0);
}


/*
 * Nuke Infowin
 */
static errr Infowin_nuke(void)
{
	infowin *iwin = Infowin;

	/* Nuke if requested */
	if (iwin->nuke)
	{
		/* Destory the old window */
		XDestroyWindow(Metadpy->dpy, iwin->win);
	}

	/* Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Prepare a new 'infowin'.
 */
static errr Infowin_prepare(Window xid)
{
	infowin *iwin = Infowin;

	Window tmp_win;
	XWindowAttributes xwa;
	int x, y;
	unsigned int w, h, b, d;

	/* Assign stuff */
	iwin->win = xid;

	/* Check For Error XXX Extract some ACTUAL data from 'xid' */
	XGetGeometry(Metadpy->dpy, xid, &tmp_win, &x, &y, &w, &h, &b, &d);

	/* Apply the above info */
	iwin->x = x;
	iwin->y = y;
	iwin->w = w;
	iwin->h = h;
	iwin->b = b;

	/* Check Error XXX Extract some more ACTUAL data */
	XGetWindowAttributes(Metadpy->dpy, xid, &xwa);

	/* Apply the above info */
	iwin->mask = xwa.your_event_mask;
	iwin->mapped = ((xwa.map_state == IsUnmapped) ? 0 : 1);

	/* And assume that we are exposed */
	iwin->redraw = 1;

	/* Success */
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Initialize a new 'infowin'.
 */
static errr Infowin_init_real(Window xid)
{
	/* Wipe it clean */
	(void)WIPE(Infowin, infowin);

	/* Start out non-nukable */
	Infowin->nuke = 0;

	/* Attempt to Prepare ourself */
	return (Infowin_prepare(xid));
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Init an infowin by giving some data.
 *
 * Inputs:
 *	dad: The Window that should own this Window (if any)
 *	x,y: The position of this Window
 *	w,h: The size of this Window
 *	b,d: The border width and pixel depth
 *
 * Notes:
 *	If 'dad == None' assume 'dad == root'
 */
static errr Infowin_init_data(Window dad, int x, int y, int w, int h,
                              int b, Pixell fg, Pixell bg)
{
	Window xid;

	/* Wipe it clean */
	(void)WIPE(Infowin, infowin);


	/*** Error Check XXX ***/


	/*** Create the Window 'xid' from data ***/

	/* What happened here?  XXX XXX XXX */

	/* If no parent given, depend on root */
	if (dad == None)

		/* #ifdef USE_GRAPHICS

				xid = XCreateWindow(Metadpy->dpy, Metadpy->root, x, y, w, h, b, 8, InputOutput, CopyFromParent, 0, 0);

			else
		*/

		/* #else */

		dad = Metadpy->root;

	/* #endif */

	/* Create the Window XXX Error Check */
	xid = XCreateSimpleWindow(Metadpy->dpy, dad, x, y, w, h, b, fg, bg);

	/* Start out selecting No events */
	XSelectInput(Metadpy->dpy, xid, 0L);


	/*** Prepare the new infowin ***/

	/* Mark it as nukable */
	Infowin->nuke = 1;

	/* Attempt to Initialize the infowin */
	return (Infowin_prepare(xid));
}



/*
 * Modify the event mask of an Infowin
 */
static errr Infowin_set_mask(long mask)
{
	/* Save the new setting */
	Infowin->mask = mask;

	/* Execute the Mapping */
	XSelectInput(Metadpy->dpy, Infowin->win, Infowin->mask);

	/* Success */
	return (0);
}


/*
 * Request that Infowin be mapped
 */
static errr Infowin_map(void)
{
	/* Execute the Mapping */
	XMapWindow(Metadpy->dpy, Infowin->win);

	/* Success */
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Request that Infowin be unmapped
 */
static errr Infowin_unmap(void)
{
	/* Execute the Un-Mapping */
	XUnmapWindow(Metadpy->dpy, Infowin->win);

	/* Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Request that Infowin be raised
 */
static errr Infowin_raise(void)
{
	/* Raise towards visibility */
	XRaiseWindow(Metadpy->dpy, Infowin->win);

	/* Success */
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Request that Infowin be lowered
 */
static errr Infowin_lower(void)
{
	/* Lower towards invisibility */
	XLowerWindow(Metadpy->dpy, Infowin->win);

	/* Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Request that Infowin be moved to a new location
 */
static errr Infowin_impell(int x, int y)
{
	/* Execute the request */
	XMoveWindow(Metadpy->dpy, Infowin->win, x, y);

	/* Success */
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Move and Resize an infowin
 */
static errr Infowin_locate(int x, int y, int w, int h)
{
	/* Execute the request */
	XMoveResizeWindow(Metadpy->dpy, Infowin->win, x, y, w, h);

	/* Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Visually clear Infowin
 */
static errr Infowin_wipe(void)
{
	/* Execute the request */
	XClearWindow(Metadpy->dpy, Infowin->win);

	/* Success */
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Visually Paint Infowin with the current color
 */
static errr Infowin_fill(void)
{
	/* Execute the request */
	XFillRectangle(Metadpy->dpy, Infowin->win, Infoclr->gc,
	               0, 0, Infowin->w, Infowin->h);

	/* Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * A NULL terminated pair list of legal "operation names"
 *
 * Pairs of values, first is texttual name, second is the string
 * holding the decimal value that the operation corresponds to.
 */
static cptr opcode_pairs[] =
{
	"cpy", "3",
	"xor", "6",
	"and", "1",
	"ior", "7",
	"nor", "8",
	"inv", "10",
	"clr", "0",
	"set", "15",

	"src", "3",
	"dst", "5",

	"+andReverse", "2",
	"+andInverted", "4",
	"+noop", "5",
	"+equiv", "9",
	"+orReverse", "11",
	"+copyInverted", "12",
	"+orInverted", "13",
	"+nand", "14",
	NULL
};


/*
 * Parse a word into an operation "code"
 *
 * Inputs:
 *	str: A string, hopefully representing an Operation
 *
 * Output:
 *	0-15: if 'str' is a valid Operation
 *	-1:   if 'str' could not be parsed
 */
static int Infoclr_Opcode(cptr str)
{
	register int i;

	/* Scan through all legal operation names */
	for (i = 0; opcode_pairs[i*2]; ++i)
	{
		/* Is this the right oprname? */
		if (streq(opcode_pairs[i*2], str))
		{
			/* Convert the second element in the pair into a Code */
			return (atoi(opcode_pairs[i*2 + 1]));
		}
	}

	/* The code was not found, return -1 */
	return ( -1);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Request a Pixell by name.  Note: uses 'Metadpy'.
 *
 * Inputs:
 *      name: The name of the color to try to load (see below)
 *
 * Output:
 *	The Pixell value that metched the given name
 *	'Metadpy->fg' if the name was unparseable
 *
 * Valid forms for 'name':
 *	'fg', 'bg', 'zg', '' and '#'
 */
static Pixell Infoclr_Pixell(cptr name)
{
	XColor scrn;

	/* Attempt to Parse the name */
	if (name && name[0])
	{
		/* The 'bg' color is available */
		if (streq(name, "bg")) return (Metadpy->bg);

		/* The 'fg' color is available */
		if (streq(name, "fg")) return (Metadpy->fg);

		/* The 'zg' color is available */
		if (streq(name, "zg")) return (Metadpy->zg);

		/* The 'white' color is available */
		if (streq(name, "white")) return (Metadpy->white);

		/* The 'black' color is available */
		if (streq(name, "black")) return (Metadpy->black);

		/* Attempt to parse 'name' into 'scrn' */
		if (!(XParseColor(Metadpy->dpy, Metadpy->cmap, name, &scrn)))
		{
			plog_fmt("Warning: Couldn't parse color '%s'\n", name);
		}

		/* Attempt to Allocate the Parsed color */
		if (!(XAllocColor(Metadpy->dpy, Metadpy->cmap, &scrn)))
		{
			plog_fmt("Warning: Couldn't allocate color '%s'\n", name);
		}

		/* The Pixel was Allocated correctly */
		else return (scrn.pixel);
	}

	/* Warn about the Default being Used */
	plog_fmt("Warning: Using 'fg' for unknown color '%s'\n", name);

	/* Default to the 'Foreground' color */
	return (Metadpy->fg);
}


/*
 * Initialize a new 'infoclr' with a real GC.
 */
static errr Infoclr_init_1(GC gc)
{
	infoclr *iclr = Infoclr;

	/* Wipe the iclr clean */
	(void)WIPE(iclr, infoclr);

	/* Assign the GC */
	iclr->gc = gc;

	/* Success */
	return (0);
}


/*
 * Nuke an old 'infoclr'.
 */
static errr Infoclr_nuke(void)
{
	infoclr *iclr = Infoclr;

	/* Deal with 'GC' */
	if (iclr->nuke)
	{
		/* Free the GC */
		XFreeGC(Metadpy->dpy, iclr->gc);
	}

	/* Forget the current */
	Infoclr = (infoclr*)(NULL);

	/* Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Initialize an infoclr with some data
 *
 * Inputs:
 *	fg:   The Pixell for the requested Foreground (see above)
 *	bg:   The Pixell for the requested Background (see above)
 *	op:   The Opcode for the requested Operation (see above)
 *	stip: The stipple mode
 */
static errr Infoclr_init_data(Pixell fg, Pixell bg, int op, int stip)
{
	infoclr *iclr = Infoclr;

	GC gc;
	XGCValues gcv;
	unsigned long gc_mask;



	/*** Simple error checking of opr and clr ***/

	/* Check the 'Pixells' for realism */
	if (bg > Metadpy->zg) return ( -1);
	if (fg > Metadpy->zg) return ( -1);

	/* Check the data for trueness */
	if ((op < 0) || (op > 15)) return ( -1);


	/*** Create the requested 'GC' ***/

	/* Assign the proper GC function */
	gcv.function = op;

	/* Assign the proper GC background */
	gcv.background = bg;

	/* Assign the proper GC foreground */
	gcv.foreground = fg;

	/* Hack -- Handle XOR (xor is code 6) by hacking bg and fg */
	if (op == 6) gcv.background = 0;
	if (op == 6) gcv.foreground = (bg ^ fg);

	/* Assign the proper GC Fill Style */
	gcv.fill_style = (stip ? FillStippled : FillSolid);

	/* Turn off 'Give exposure events for pixmap copying' */
	gcv.graphics_exposures = False;

	/* Set up the GC mask */
	gc_mask = (GCFunction | GCBackground | GCForeground |
	           GCFillStyle | GCGraphicsExposures);

	/* Create the GC detailed above */
	gc = XCreateGC(Metadpy->dpy, Metadpy->root, gc_mask, &gcv);


	/*** Initialize ***/

	/* Wipe the iclr clean */
	(void)WIPE(iclr, infoclr);

	/* Assign the GC */
	iclr->gc = gc;

	/* Nuke it when done */
	iclr->nuke = 1;

	/* Assign the parms */
	iclr->fg = fg;
	iclr->bg = bg;
	iclr->code = op;
	iclr->stip = stip ? 1 : 0;

	/* Success */
	return (0);
}



/*
 * Change the 'fg' for an infoclr
 *
 * Inputs:
 *	fg:   The Pixell for the requested Foreground (see above)
 */
static errr Infoclr_change_fg(Pixell fg)
{
	infoclr *iclr = Infoclr;


	/*** Simple error checking of opr and clr ***/

	/* Check the 'Pixells' for realism */
	if (fg > Metadpy->zg) return ( -1);


	/*** Change ***/

	/* Change */
	XSetForeground(Metadpy->dpy, iclr->gc, fg);

	/* Success */
	return (0);
}



#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Nuke an old 'infofnt'.
 */
static errr Infofnt_nuke(void)
{
	infofnt *ifnt = Infofnt;

	/* Deal with 'name' */
	if (ifnt->name)
	{
		/* Free the name */
		string_free(ifnt->name);
	}

	/* Nuke info if needed */
	if (ifnt->nuke)
	{
		/* Free the font */
		XFreeFont(Metadpy->dpy, ifnt->info);
	}

	/* Success */
	return (0);
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Prepare a new 'infofnt'
 */
static errr Infofnt_prepare(XFontStruct *info)
{
	infofnt *ifnt = Infofnt;

	XCharStruct *cs;

	/* Assign the struct */
	ifnt->info = info;

	/* Jump into the max bouonds thing */
	cs = &(info->max_bounds);

	/* Extract default sizing info */
	ifnt->asc = info->ascent;
	ifnt->hgt = info->ascent + info->descent;
	ifnt->wid = cs->width;
	if (use_bigtile)
		ifnt->twid = 2 * ifnt->wid;
	else
		ifnt->twid = ifnt->wid;


#ifdef OBSOLETE_SIZING_METHOD
	/* Extract default sizing info */
	ifnt->asc = cs->ascent;
	ifnt->hgt = (cs->ascent + cs->descent);
	ifnt->wid = cs->width;
#endif

	/* Success */
	return (0);
}


#ifndef IGNORE_UNUSED_FUNCTIONS

/*
 * Initialize a new 'infofnt'.
 */
static errr Infofnt_init_real(XFontStruct *info)
{
	/* Wipe the thing */
	(void)WIPE(Infofnt, infofnt);

	/* No nuking */
	Infofnt->nuke = 0;

	/* Attempt to prepare it */
	return (Infofnt_prepare(info));
}

#endif /* IGNORE_UNUSED_FUNCTIONS */


/*
 * Init an infofnt by its Name
 *
 * Inputs:
 *	name: The name of the requested Font
 */
static errr Infofnt_init_data(cptr name)
{
	XFontStruct *info;


	/*** Load the info Fresh, using the name ***/

	/* If the name is not given, report an error */
	if (!name) return ( -1);

	/* Attempt to load the font */
	info = XLoadQueryFont(Metadpy->dpy, name);

	/* The load failed, try to recover */
	if (!info) return ( -1);


	/*** Init the font ***/

	/* Wipe the thing */
	(void)WIPE(Infofnt, infofnt);

	/* Attempt to prepare it */
	if (Infofnt_prepare(info))
	{
		/* Free the font */
		XFreeFont(Metadpy->dpy, info);

		/* Fail */
		return ( -1);
	}

	/* Save a copy of the font name */
	Infofnt->name = string_make(name);

	/* Mark it as nukable */
	Infofnt->nuke = 1;

	/* Success */
	return (0);
}


/*
 * Standard Text
 */
static errr Infofnt_text_std(int x, int y, cptr str, int len)
{
	int i;


	/*** Do a brief info analysis ***/

	/* Do nothing if the string is null */
	if (!str || !*str) return ( -1);

	/* Get the length of the string */
	if (len < 0) len = strlen(str);


	/*** Decide where to place the string, vertically ***/

	/* Ignore Vertical Justifications */
	y = (y * Infofnt->hgt) + Infofnt->asc + Infowin->oy;


	/*** Decide where to place the string, horizontally ***/

	/* Line up with x at left edge of column 'x' */
	x = (x * Infofnt->wid) + Infowin->ox;


	/*** Actually draw 'str' onto the infowin ***/

	/* Be sure the correct font is ready */
	XSetFont(Metadpy->dpy, Infoclr->gc, Infofnt->info->fid);


	/*** Handle the fake mono we can enforce on fonts ***/

	/* Monotize the font */
	if (Infofnt->mono)
	{
		/* Do each character */
		for (i = 0; i < len; ++i)
		{
			/* Note that the Infoclr is set up to contain the Infofnt */
			XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
			                 x + i * Infofnt->wid + Infofnt->off, y, str + i, 1);
		}
	}

	/* Assume monoospaced font */
	else
	{
		/* Note that the Infoclr is set up to contain the Infofnt */
		XDrawImageString(Metadpy->dpy, Infowin->win, Infoclr->gc,
		                 x, y, str, len);
	}


	/* Success */
	return (0);
}


/*
 * Painting where text would be
 */
static errr Infofnt_text_non(int x, int y, cptr str, int len)
{
	int w, h;


	/*** Find the width ***/

	/* Negative length is a flag to count the characters in str */
	if (len < 0) len = strlen(str);

	/* The total width will be 'len' chars * standard width */
	w = len * Infofnt->wid;


	/*** Find the X dimensions ***/

	/* Line up with x at left edge of column 'x' */
	x = x * Infofnt->wid + Infowin->ox;


	/*** Find other dimensions ***/

	/* Simply do 'Infofnt->hgt' (a single row) high */
	h = Infofnt->hgt;

	/* Simply do "at top" in row 'y' */
	y = y * h + Infowin->oy;


	/*** Actually 'paint' the area ***/

	/* Just do a Fill Rectangle */
	XFillRectangle(Metadpy->dpy, Infowin->win, Infoclr->gc, x, y, w, h);

	/* Success */
	return (0);
}



/*************************************************************************/


/*
 * Angband specific code follows... (ANGBAND)
 */


/*
 * Hack -- cursor color
 */
static infoclr *xor;

/*
 * Actual color table
 */
static infoclr *clr[256];

/*
 * Color info (unused, red, green, blue).
 */
static byte color_table[256][4];

/*
 * Forward declare
 */
typedef struct term_data term_data;

/*
 * A structure for each "term"
 */
struct term_data
{
	term t;

	infofnt *fnt;

	infowin *win;

#ifdef USE_GRAPHICS

	XImage *tiles;

#ifdef USE_TRANSPARENCY

	/* Tempory storage for overlaying tiles. */
	XImage *TmpImage;

#endif

#endif

};


/*
 * The number of term data structures
 */
#define MAX_TERM_DATA 8

/*
 * The array of term data structures
 */
static term_data data[MAX_TERM_DATA];

/* Use short names for the most commonly used elements of various structures. */
#define DPY (Metadpy->dpy)
#define WIN (Infowin->win)

/*
 * Simply push a set of co-ordinates around.
 */
typedef struct co_ord co_ord;
struct co_ord
{
	int x;
	int y;
};

/*
 * A special structure to store information about the text currently
 * selected.
 */
typedef struct x11_selection_type x11_selection_type;
struct x11_selection_type
{
	bool select;  /* The selection is currently in use. */
	bool drawn;  /* The selection is currently displayed. */
	term *t;  /* The window where the selection is found. */
	co_ord init;  /* The starting co-ordinates. */
	co_ord cur;  /* The end co-ordinates (the current ones if still copying). */
	co_ord old;  /* The previous end co-ordinates. */
	Time time;  /* The time at which the selection was finalised. */
};

static x11_selection_type s_ptr[1];



/*
 * Process a keypress event
 *
 * Also appears in "main-xaw.c".
 */
static void react_keypress(XKeyEvent *xev)
{
	int i, n, mc, ms, mo, mx;

	uint ks1;

	XKeyEvent *ev = (XKeyEvent*)(xev);

	KeySym ks;

	char buf[128];
	char msg[128];


	/* Check for "normal" keypresses */
	n = XLookupString(ev, buf, 125, &ks, NULL);

	/* Terminate */
	buf[n] = '\0';


	/* Hack -- Ignore "modifier keys" */
	if (IsModifierKey(ks)) return;


	/* Hack -- convert into an unsigned int */
	ks1 = (uint)(ks);

	/* Extract four "modifier flags" */
	mc = (ev->state & ControlMask) ? TRUE : FALSE;
	ms = (ev->state & ShiftMask) ? TRUE : FALSE;
	mo = (ev->state & Mod1Mask) ? TRUE : FALSE;
	mx = (ev->state & Mod2Mask) ? TRUE : FALSE;


	/* Normal keys with no modifiers */
	if (n && !mo && !mx && !IsSpecialKey(ks))
	{
		/* Enqueue the normal key(s) */
		for (i = 0; buf[i]; i++) Term_keypress(buf[i]);

		/* All done */
		return;
	}


	/* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
	switch (ks1)
	{
	case XK_Escape:
		{
			Term_keypress(ESCAPE);
			return;
		}

	case XK_Return:
		{
			Term_keypress('\r');
			return;
		}

	case XK_Tab:
		{
			Term_keypress('\t');
			return;
		}

	case XK_Delete:
	case XK_BackSpace:
		{
			Term_keypress('\010');
			return;
		}
	}


	/* Hack -- Use the KeySym */
	if (ks)
	{
		sprintf(msg, "%c%s%s%s%s_%lX%c", 31,
		        mc ? "N" : "", ms ? "S" : "",
		        mo ? "O" : "", mx ? "M" : "",
		        (unsigned long)(ks), 13);
	}

	/* Hack -- Use the Keycode */
	else
	{
		sprintf(msg, "%c%s%s%s%sK_%X%c", 31,
		        mc ? "N" : "", ms ? "S" : "",
		        mo ? "O" : "", mx ? "M" : "",
		        ev->keycode, 13);
	}

	/* Enqueue the "macro trigger" string */
	for (i = 0; msg[i]; i++) Term_keypress(msg[i]);


	/* Hack -- auto-define macros as needed */
	if (n && (macro_find_exact(msg) < 0))
	{
		/* Create a macro */
		macro_add(msg, buf);
	}
}


/*
 * Find the square a particular pixel is part of.
 */
static void pixel_to_square(int * const x, int * const y,
                            const int ox, const int oy)
{
	(*x) = (ox - Infowin->ox) / Infofnt->wid;
	(*y) = (oy - Infowin->oy) / Infofnt->hgt;
}

/*
 * Find the pixel at the top-left corner of a square.
 */
static void square_to_pixel(int * const x, int * const y,
                            const int ox, const int oy)
{
	(*x) = ox * Infofnt->wid + Infowin->ox;
	(*y) = oy * Infofnt->hgt + Infowin->oy;
}

/*
 * Convert co-ordinates from starting corner/opposite corner to minimum/maximum.
 */
static void sort_co_ord(co_ord *min, co_ord *max,
                        const co_ord *b, const co_ord *a)
{
	min->x = MIN(a->x, b->x);
	min->y = MIN(a->y, b->y);
	max->x = MAX(a->x, b->x);
	max->y = MAX(a->y, b->y);
}

/*
 * Remove the selection by redrawing it.
 */
static void mark_selection_clear(int x1, int y1, int x2, int y2)
{
	Term_redraw_section(x1, y1, x2, y2);
}

/*
 * Select an area by drawing a grey box around it.
 * NB. These two functions can cause flicker as the selection is modified,
 * as the game redraws the entire marked section.
 */
static void mark_selection_mark(int x1, int y1, int x2, int y2)
{
	square_to_pixel(&x1, &y1, x1, y1);
	square_to_pixel(&x2, &y2, x2, y2);
	XDrawRectangle(Metadpy->dpy, Infowin->win, clr[2]->gc, x1, y1,
	               x2 - x1 + Infofnt->wid - 1, y2 - y1 + Infofnt->hgt - 1);
}

/*
 * Mark a selection by drawing boxes around it (for now).
 */
static void mark_selection(void)
{
	co_ord min, max;
	term *old = Term;
	bool draw = s_ptr->select;
	bool clear = s_ptr->drawn;

	/* Open the correct term if necessary. */
	if (s_ptr->t != old) Term_activate(s_ptr->t);

	if (clear)
	{
		sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->old);
		mark_selection_clear(min.x, min.y, max.x, max.y);
	}
	if (draw)
	{
		sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->cur);
		mark_selection_mark(min.x, min.y, max.x, max.y);
	}

	/* Finish on the current term. */
	if (s_ptr->t != old) Term_activate(old);

	s_ptr->old.x = s_ptr->cur.x;
	s_ptr->old.y = s_ptr->cur.y;
	s_ptr->drawn = s_ptr->select;
}

/*
 * Forget a selection for one reason or another.
 */
static void copy_x11_release(void)
{
	/* Deselect the current selection. */
	s_ptr->select = FALSE;

	/* Remove its graphical represesntation. */
	mark_selection();
}

/*
 * Start to select some text on the screen.
 */
static void copy_x11_start(int x, int y)
{
	if (s_ptr->select) copy_x11_release();

	/* Remember where the selection started. */
	s_ptr->t = Term;
	s_ptr->init.x = s_ptr->cur.x = s_ptr->old.x = x;
	s_ptr->init.y = s_ptr->cur.y = s_ptr->old.y = y;
}

/*
 * Respond to movement of the mouse when selecting text.
 */
static void copy_x11_cont(int x, int y, unsigned int buttons)
{
	/* Use the nearest square within bounds if the mouse is outside. */
	x = MIN(MAX(x, 0), Term->wid - 1);
	y = MIN(MAX(y, 0), Term->hgt - 1);

	/* The left mouse button isn't pressed. */
	if (~buttons & Button1Mask) return;

	/* Not a selection in this window. */
	if (s_ptr->t != Term) return;

	/* Not enough movement. */
	if (x == s_ptr->old.x && y == s_ptr->old.y && s_ptr->select) return;

	/* Something is being selected. */
	s_ptr->select = TRUE;

	/* Track the selection. */
	s_ptr->cur.x = x;
	s_ptr->cur.y = y;

	/* Hack - display it inefficiently. */
	mark_selection();
}

/*
 * Respond to release of the left mouse button by putting the selected text in
 * the primary buffer.
 */
static void copy_x11_end(const Time time)
{
	/* No selection. */
	if (!s_ptr->select) return;

	/* Not a selection in this window. */
	if (s_ptr->t != Term) return;

	/* Remember when the selection was finalised. */
	s_ptr->time = time;

	/* Acquire the primary selection. */
	XSetSelectionOwner(Metadpy->dpy, XA_PRIMARY, Infowin->win, time);
	if (XGetSelectionOwner(Metadpy->dpy, XA_PRIMARY) != Infowin->win)
	{
		/* Failed to acquire the selection, so forget it. */
		bell();
		s_ptr->select = FALSE;
		mark_selection();
	}
}

/*
 * Send a message to request that the PRIMARY buffer be sent here.
 */
static void paste_x11_request(const Time time)
{
	XEvent event[1];
	XSelectionRequestEvent *ptr = &(event->xselectionrequest);

	/* Set various things. */
	ptr->type = SelectionRequest;
	ptr->display = Metadpy->dpy;
	ptr->owner = XGetSelectionOwner(Metadpy->dpy, XA_PRIMARY);
	ptr->requestor = Infowin->win;
	ptr->selection = XA_PRIMARY;
	ptr->target = XA_STRING;
	ptr->property = XA_STRING;  /* Unused */
	ptr->time = time;

	/* Check the owner. */
	if (ptr->owner == None)
	{
		/* No selection. */
		bell();
		return;
	}

	/* Send the SelectionRequest event. */
	XSendEvent(Metadpy->dpy, ptr->owner, False, NoEventMask, event);
}

/*
 * Add a character to a string in preparation for sending it to another
 * client as a STRING.
 * This doesn't change anything, as clients tend not to have difficulty in
 * receiving this format (although the standard specifies a restricted set).
 * Strings do not have a colour.
 */
static int add_char_string(char *buf, byte a, char c)
{
	*buf = c;
	return 1;
}

/*
 * Send some text requested by another X client.
 */
static void paste_x11_send(XSelectionRequestEvent *rq)
{
	XEvent event;
	XSelectionEvent *ptr = &(event.xselection);
	int (*add)(char *, byte, char) = 0;

	/* Set the event parameters. */
	ptr->type = SelectionNotify;
	ptr->property = rq->property;
	ptr->display = rq->display;
	ptr->requestor = rq->requestor;
	ptr->selection = rq->selection;
	ptr->target = rq->target;
	ptr->time = rq->time;

	/* Determine the correct "add a character" function.
	 * As Term->wid is at most 255, these can add up to 4 characters of
	 * output per character of input without problem.
	 * The mechanism will need to change if much more than this is needed.
	 */
	switch (rq->target)
	{
	case XA_STRING:
		add = add_char_string;
		break;
	default:
		goto error;
	}

	/* Reply to a known target received recently with data. */
	if (rq->time >= s_ptr->time && add)
	{
		char buf[1024];
		co_ord max, min;
		int x, y, l;
		byte a;
		char c;

		/* Work out which way around to paste. */
		sort_co_ord(&min, &max, &s_ptr->init, &s_ptr->cur);

		/* Paranoia. */
		if (XGetSelectionOwner(DPY, XA_PRIMARY) != WIN)
		{
			bell();
			goto error;
		}

		/* Delete the old value of the property. */
		XDeleteProperty(DPY, rq->requestor, rq->property);

		for (y = 0; y < Term->hgt; y++)
		{
			if (y < min.y) continue;
			if (y > max.y) break;

			for (x = l = 0; x < Term->wid; x++)
			{
				if (x < min.x) continue;
				if (x > max.x) break;

				/* Find the character. */
				Term_what(x, y, &a, &c);

				/* Add it. */
				l += (*add)(buf + l, a, c);
			}

			/* Terminate all but the last line in an appropriate way. */
			if (y != max.y) l += (*add)(buf + l, TERM_WHITE, '\n');

			/* Send the (non-empty) string. */
			XChangeProperty(DPY, rq->requestor, rq->property, rq->target, 8,
			                PropModeAppend, (unsigned char*)buf, l);
		}
	}
	else
	{
		/* Respond to all bad requests with property None. */
error:
		ptr->property = None;
	}

	/* Send whatever event we're left with. */
	XSendEvent(DPY, rq->requestor, FALSE, NoEventMask, &event);
}

extern errr type_string(char *str, uint len);

/*
 * Add the contents of the PRIMARY buffer to the input queue.
 *
 * Hack - This doesn't use the "time" of the event, and so accepts anything a
 * client tries to send it.
 */
static void paste_x11_accept(const XSelectionEvent *ptr)
{
	long offset;
	unsigned long left;

	/* Failure. */
	if (ptr->property == None)
	{
		bell();
		return;
	}

	if (ptr->selection != XA_PRIMARY)
	{
		bell();
		return;
	}
	if (ptr->target != XA_STRING)
	{
		bell();
		return;
	}

	for (offset = 0; ; offset += left)
	{
		errr err;

		/* A pointer for the pasted information. */
		unsigned char *data;

		Atom type;
		int fmt;
		unsigned long nitems;

		/* Set data to the string, and catch errors. */
		if (XGetWindowProperty(Metadpy->dpy, Infowin->win, XA_STRING, offset,
		                       32767, TRUE, XA_STRING, &type, &fmt, &nitems, &left, &data)
		                != Success) break;

		/* Paste the text. */
		err = type_string((char*)data, (uint)nitems);

		/* Free the data pasted. */
		XFree(data);

		/* No room. */
		if (err == 7)
		{
			bell();
			break;
		}
		/* Paranoia? - strange errors. */
		else if (err)
		{
			break;
		}

		/* Pasted everything. */
		if (!left) return;
	}

	/* An error has occurred, so free the last bit of data before returning. */
	XFree(data);
}

/*
 * Handle various events conditional on presses of a mouse button.
 */
static void handle_button(Time time, int x, int y, int button,
                          bool press)
{
	/* The co-ordinates are only used in Angband format. */
	pixel_to_square(&x, &y, x, y);

	if (press && button == 1) copy_x11_start(x, y);
	if (!press && button == 1) copy_x11_end(time);
	if (!press && button == 2) paste_x11_request(time);
}


/*
 * Process events
 */
static errr CheckEvent(bool wait)
{
	term_data *old_td = (term_data*)(Term->data);

	XEvent xev_body, *xev = &xev_body;

	term_data *td = NULL;
	infowin *iwin = NULL;

	int i;


	/* Do not wait unless requested */
	if (!wait && !XPending(Metadpy->dpy)) return (1);

	/* Hack - redraw the selection, if needed.
	* This doesn't actually check that one of its squares was drawn to,
	* only that this may have happened.
	*/
	if (s_ptr->select && !s_ptr->drawn) mark_selection();

	/* Load the Event */
	XNextEvent(Metadpy->dpy, xev);


	/* Notice new keymaps */
	if (xev->type == MappingNotify)
	{
		XRefreshKeyboardMapping(&xev->xmapping);
		return 0;
	}


	/* Scan the windows */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		if (xev->xany.window == data[i].win->win)
		{
			td = &data[i];
			iwin = td->win;
			break;
		}
	}

	/* Unknown window */
	if (!td || !iwin) return (0);


	/* Hack -- activate the Term */
	Term_activate(&td->t);

	/* Hack -- activate the window */
	Infowin_set(iwin);


	/* Switch on the Type */
	switch (xev->type)
	{

	case ButtonPress:
	case ButtonRelease:
		{
			bool press = (xev->type == ButtonPress);

			/* Where is the mouse */
			int x = xev->xbutton.x;
			int y = xev->xbutton.y;

			int z;

			/* Which button is involved */
			if (xev->xbutton.button == Button1) z = 1;
			else if (xev->xbutton.button == Button2) z = 2;
			else if (xev->xbutton.button == Button3) z = 3;
			else if (xev->xbutton.button == Button4) z = 4;
			else if (xev->xbutton.button == Button5) z = 5;
			else z = 0;

			/* Where is the mouse */
			x = xev->xbutton.x;
			y = xev->xbutton.y;

			/* XXX Handle */
			handle_button(xev->xbutton.time, x, y, z, press);

			break;
		}

	case EnterNotify:
	case LeaveNotify:
		{
			/* Where is the mouse */
			/* XXX Handle */

			break;
		}

	case MotionNotify:
		{
			int x = xev->xmotion.x;
			int y = xev->xmotion.y;
			unsigned int z = xev->xmotion.state;

			/* Convert to co-ordinates Angband understands. */
			pixel_to_square(&x, &y, x, y);

			/* Alter the selection if appropriate. */
			copy_x11_cont(x, y, z);

			/* XXX Handle */

			break;
		}

	case SelectionNotify:
		{
			paste_x11_accept(&(xev->xselection));
			break;
		}

	case SelectionRequest:
		{
			paste_x11_send(&(xev->xselectionrequest));
			break;
		}

	case SelectionClear:
		{
			s_ptr->select = FALSE;
			mark_selection();
			break;
		}

	case KeyRelease:
		{
			/* Nothing */
			break;
		}

	case KeyPress:
		{
			/* Hack -- use "old" term */
			Term_activate(&old_td->t);

			/* Process the key */
			react_keypress(&(xev->xkey));

			break;
		}

	case Expose:
		{
			/* Ignore "extra" exposes */
			if (xev->xexpose.count) break;

			/* Clear the window */
			Infowin_wipe();

			/* Redraw */
			Term_redraw();

			break;
		}

	case MapNotify:
		{
			Infowin->mapped = 1;
			Term->mapped_flag = TRUE;
			break;
		}

	case UnmapNotify:
		{
			Infowin->mapped = 0;
			Term->mapped_flag = FALSE;
			break;
		}

		/* Move and/or Resize */
	case ConfigureNotify:
		{
			int cols, rows, wid, hgt;

			int ox = Infowin->ox;
			int oy = Infowin->oy;

			/* Save the new Window Parms */
			Infowin->x = xev->xconfigure.x;
			Infowin->y = xev->xconfigure.y;
			Infowin->w = xev->xconfigure.width;
			Infowin->h = xev->xconfigure.height;

			/* Determine "proper" number of rows/cols */
			cols = ((Infowin->w - (ox + ox)) / td->fnt->wid);
			rows = ((Infowin->h - (oy + oy)) / td->fnt->hgt);

			/* Hack -- minimal size */
			if (td == &data[0])
			{
				if (cols < 80) cols = 80;
				if (rows < 24) rows = 24;
			}

			else
			{
				if (cols < 1) cols = 1;
				if (rows < 1) rows = 1;
			}

			/* Paranoia */
			if (cols > 255) cols = 255;
			if (rows > 255) rows = 255;

			/* Desired size of window */
			wid = cols * td->fnt->wid + (ox + ox);
			hgt = rows * td->fnt->hgt + (oy + oy);

			/* Resize the Term (if needed) */
			Term_resize(cols, rows);
			break;
		}
	}


	/* Hack -- Activate the old term */
	Term_activate(&old_td->t);

	/* Hack -- Activate the proper window */
	Infowin_set(old_td->win);


	/* Success */
	return (0);
}


/*
 * Handle "activation" of a term
 */
static errr Term_xtra_x11_level(int v)
{
	term_data *td = (term_data*)(Term->data);

	/* Handle "activate" */
	if (v)
	{
		/* Activate the window */
		Infowin_set(td->win);

		/* Activate the font */
		Infofnt_set(td->fnt);
	}

	/* Success */
	return (0);
}


/*
 * React to changes
 */
static errr Term_xtra_x11_react(void)
{
	int i;

	if (Metadpy->color)
	{
		/* Check the colors */
		for (i = 0; i < 256; i++)
		{
			if ((color_table[i][0] != angband_color_table[i][0]) ||
			                (color_table[i][1] != angband_color_table[i][1]) ||
			                (color_table[i][2] != angband_color_table[i][2]) ||
			                (color_table[i][3] != angband_color_table[i][3]))
			{
				Pixell pixel;

				/* Save new values */
				color_table[i][0] = angband_color_table[i][0];
				color_table[i][1] = angband_color_table[i][1];
				color_table[i][2] = angband_color_table[i][2];
				color_table[i][3] = angband_color_table[i][3];

				/* Create pixel */
				pixel = create_pixel(Metadpy->dpy,
				                     color_table[i][1],
				                     color_table[i][2],
				                     color_table[i][3]);

				/* Change the foreground */
				Infoclr_set(clr[i]);
				Infoclr_change_fg(pixel);
			}
		}
	}

	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_x11(int n, int v)
{
	/* Handle a subset of the legal requests */
	switch (n)
	{
		/* Make a noise */
	case TERM_XTRA_NOISE:
		Metadpy_do_beep(); return (0);

		/* Flush the output XXX XXX */
	case TERM_XTRA_FRESH: Metadpy_update(1, 0, 0); return (0);

		/* Process random events XXX */
	case TERM_XTRA_BORED:
		{
			irc_poll();

			return (CheckEvent(0));
		}

		/* Process Events XXX */
	case TERM_XTRA_EVENT:
		{
			irc_poll();

			return (CheckEvent(v));
		}

		/* Flush the events XXX */
	case TERM_XTRA_FLUSH: while (!CheckEvent(FALSE)); return (0);

		/* Handle change in the "level" */
	case TERM_XTRA_LEVEL: return (Term_xtra_x11_level(v));

		/* Clear the screen, and redraw any selection later. */
	case TERM_XTRA_CLEAR: Infowin_wipe(); s_ptr->drawn = FALSE; return (0);

		/* Delay for some milliseconds */
	case TERM_XTRA_DELAY:
		irc_poll();

		usleep(1000 * v);
		return (0);

		/* Get Delay of some milliseconds */
	case TERM_XTRA_GET_DELAY:
		{
			int ret;
			struct timeval tv;

			ret = gettimeofday(&tv, NULL);
			Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);

			return ret;
		}

		/* Subdirectory scan */
	case TERM_XTRA_SCANSUBDIR:
		{
			DIR *directory;
			struct dirent *entry;

			scansubdir_max = 0;

			directory = opendir(scansubdir_dir);
			if (!directory)
				return 1;

			while ((entry = readdir(directory)))
			{
				char file[PATH_MAX + NAME_MAX + 2];
				struct stat filedata;

				file[PATH_MAX + NAME_MAX] = 0;
				strncpy(file, scansubdir_dir, PATH_MAX);
				strncat(file, "/", 2);
				strncat(file, entry->d_name, NAME_MAX);
				if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(entry->d_name);
					++scansubdir_max;
				}
			}

			closedir(directory);
			return 0;
		}

		/* React to changes */
	case TERM_XTRA_REACT: return (Term_xtra_x11_react());

		/* Rename main window */
	case TERM_XTRA_RENAME_MAIN_WIN: Infowin_set_name(angband_term_name[0]); return (0);
	}

	/* Unknown */
	return (1);
}


/*
 * Draw the cursor as an inverted rectangle.
 *
 * Consider a rectangular outline like "main-mac.c".  XXX XXX
 */
static errr Term_curs_x11(int x, int y)
{
	/* Draw the cursor */
	Infoclr_set(xor);

	if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x + 1] == 255)
		Infofnt_text_non(x, y, "  ", 2);
	else
		/* Hilite the cursor character */
		Infofnt_text_non(x, y, " ", 1);

	/* Redraw the selection if any, as it may have been obscured. (later) */
	s_ptr->drawn = FALSE;

	/* Success */
	return (0);
}


/*
 * Erase some characters.
 */
static errr Term_wipe_x11(int x, int y, int n)
{
	/* Erase (use black) */
	Infoclr_set(clr[TERM_DARK]);

	/* Mega-Hack -- Erase some space */
	Infofnt_text_non(x, y, "", n);

	/* Redraw the selection if any, as it may have been obscured. (later) */
	s_ptr->drawn = FALSE;

	/* Success */
	return (0);
}


/*
 * Draw some textual characters.
 */
static errr Term_text_x11(int x, int y, int n, byte a, cptr s)
{
	/* Draw the text */
	Infoclr_set(clr[a]);

	/* Draw the text */
	Infofnt_text_std(x, y, s, n);

	/* Success */
	return (0);
}


#ifdef USE_GRAPHICS

/*
 * Draw some graphical characters.
 */
# ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp, const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
# else /* USE_TRANSPARENCY */
static errr Term_pict_x11(int x, int y, int n, const byte *ap, const char *cp)
# endif  /* USE_TRANSPARENCY */
{
	int i, x1, y1;

	byte a;
	char c;


#ifdef USE_TRANSPARENCY
	byte ta;
	char tc;
	int x2, y2;

# ifdef USE_EGO_GRAPHICS
	byte ea;
	char ec;
	int x3, y3;
	bool has_overlay;
# endif  /* USE_EGO_GRAPHICS */

	int k, l;

	unsigned long pixel, blank;
#endif /* USE_TRANSPARENCY */

	term_data *td = (term_data*)(Term->data);

	y *= Infofnt->hgt;
	x *= Infofnt->wid;

	/* Add in affect of window boundaries */
	y += Infowin->oy;
	x += Infowin->ox;

	for (i = 0; i < n; ++i, x += td->fnt->wid)
	{
		a = *ap++;
		c = *cp++;

		/* For extra speed - cache these values */
		x1 = (c & 0x7F) * td->fnt->twid;
		y1 = (a & 0x7F) * td->fnt->hgt;

#ifdef USE_TRANSPARENCY

		ta = *tap++;
		tc = *tcp++;

		/* For extra speed - cache these values */
		x2 = (tc & 0x7F) * td->fnt->twid;
		y2 = (ta & 0x7F) * td->fnt->hgt;

# ifdef USE_EGO_GRAPHICS

		ea = *eap++;
		ec = *ecp++;
		has_overlay = (ea && ec);

		/* For extra speed - cache these values too */
		x3 = (ec & 0x7F) * td->fnt->twid;
		y3 = (ea & 0x7F) * td->fnt->hgt;

# endif  /* USE_EGO_GRAPHICS */

		/* Optimise the common case */
		if ((x1 == x2) && (y1 == y2))
		{
# ifndef USE_EGO_GRAPHICS

			/* Draw object / terrain */
			XPutImage(Metadpy->dpy, td->win->win,
			          clr[0]->gc,
			          td->tiles,
			          x1, y1,
			          x, y,
			          td->fnt->twid, td->fnt->hgt);
# else /* !USE_EGO_GRAPHICS */

			/* Draw object / terrain */
			if (!has_overlay)
			{
				XPutImage(Metadpy->dpy, td->win->win,
				          clr[0]->gc,
				          td->tiles,
				          x1, y1,
				          x, y,
				          td->fnt->twid, td->fnt->hgt);
			}

			/* There's a terrain overlay */
			else
			{
				/* Mega Hack^2 - assume the top left corner is "black" */
				blank = XGetPixel(td->tiles, 0, td->fnt->hgt * 6);
				for (k = 0; k < td->fnt->twid; k++)
				{
					for (l = 0; l < td->fnt->hgt; l++)
					{
						/* If mask set in overlay... */
						if ((pixel = XGetPixel(td->tiles, x3 + k, y3 + l)) == blank)
						{
							/* Output from the terrain */
							pixel = XGetPixel(td->tiles, x1 + k, y1 + l);
						}

						/* Store into the temp storage. */
						XPutPixel(td->TmpImage, k, l, pixel);
					}
				}

				/* Draw to screen */
				XPutImage(Metadpy->dpy, td->win->win,
				          clr[0]->gc,
				          td->TmpImage,
				          0, 0, x, y,
				          td->fnt->twid, td->fnt->hgt);
			}

# endif  /* !USE_EGO_GRAPHICS */

		}
		else
		{

			/* Mega Hack^2 - assume the top left corner is "black" */
			blank = XGetPixel(td->tiles, 0, td->fnt->hgt * 6);

# ifndef USE_EGO_GRAPHICS

			for (k = 0; k < td->fnt->twid; k++)
			{
				for (l = 0; l < td->fnt->hgt; l++)
				{
					/* If mask set... */
					if ((pixel = XGetPixel(td->tiles, x1 + k, y1 + l)) == blank)
					{
						/* Output from the terrain */
						pixel = XGetPixel(td->tiles, x2 + k, y2 + l);
					}

					/* Store into the temp storage. */
					XPutPixel(td->TmpImage, k, l, pixel);
				}
			}

# else /* !USE_EGO_GRAPHICS */

			for (k = 0; k < td->fnt->twid; k++)
			{
				for (l = 0; l < td->fnt->hgt; l++)
				{
					/* Overlay */
					if (has_overlay)
					{
						pixel = XGetPixel(td->tiles, x3 + k, y3 + l);
					}

					/* Hack -- No overlay */
					else
					{
						pixel = blank;
					}

					/* If it's blank... */
					if (pixel == blank)
					{
						/* Look at mon/obj */
						pixel = XGetPixel(td->tiles, x1 + k, y1 + l);
					}

					/* If it's blank too, use terrain */
					if (pixel == blank)
					{
						pixel = XGetPixel(td->tiles, x2 + k, y2 + l);
					}

					/* Store into the temp storage. */
					XPutPixel(td->TmpImage, k, l, pixel);
				}
			}

# endif  /* !USE_EGO_GRAPHICS */


			/* Draw to screen */
			XPutImage(Metadpy->dpy, td->win->win,
			          clr[0]->gc,
			          td->TmpImage,
			          0, 0, x, y,
			          td->fnt->twid, td->fnt->hgt);
		}

#else /* USE_TRANSPARENCY */

/* Draw object / terrain */
		XPutImage(Metadpy->dpy, td->win->win,
		          clr[0]->gc,
		          td->tiles,
		          x1, y1,
		          x, y,
		          td->fnt->twid, td->fnt->hgt);

#endif /* USE_TRANSPARENCY */
		x += td->fnt->wid;
	}

	/* Redraw the selection if any, as it may have been obscured. (later) */
	s_ptr->drawn = FALSE;

	/* Success */
	return (0);
}

#endif /* USE_GRAPHICS */



/*
 * Initialize a term_data
 */
static errr term_data_init(term_data *td, int i)
{
	term *t = &td->t;

	cptr name = angband_term_name[i];

	cptr font;

	int x = 0;
	int y = 0;

	int cols = 80;
	int rows = 24;

	int ox = 1;
	int oy = 1;

	int wid, hgt, num;

	char buf[80];

	cptr str;

	int val;

	XClassHint *ch;

	char res_name[20];
	char res_class[20];

	XSizeHints *sh;


	/* Window specific font name */
	sprintf(buf, "ANGBAND_X11_FONT_%d", i);

	/* Check environment for that font */
	font = getenv(buf);

	/* Check environment for "base" font */
	if (!font) font = getenv("ANGBAND_X11_FONT");

	/* No environment variables, use default font */
	if (!font)
	{
		switch (i)
		{
		case 0:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		case 1:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		case 2:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		case 3:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		case 4:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		case 5:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		case 6:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		case 7:
			{
				font = DEFAULT_X11_FONT;
			}
			break;
		default:
			{
				font = DEFAULT_X11_FONT;
			}
		}
	}

	/* Window specific location (x) */
	sprintf(buf, "ANGBAND_X11_AT_X_%d", i);
	str = getenv(buf);
	x = (str != NULL) ? atoi(str) : -1;

	/* Window specific location (y) */
	sprintf(buf, "ANGBAND_X11_AT_Y_%d", i);
	str = getenv(buf);
	y = (str != NULL) ? atoi(str) : -1;


	/* Window specific cols */
	sprintf(buf, "ANGBAND_X11_COLS_%d", i);
	str = getenv(buf);
	val = (str != NULL) ? atoi(str) : -1;
	if (val > 0) cols = val;

	/* Window specific rows */
	sprintf(buf, "ANGBAND_X11_ROWS_%d", i);
	str = getenv(buf);
	val = (str != NULL) ? atoi(str) : -1;
	if (val > 0) rows = val;


	/* Window specific inner border offset (ox) */
	sprintf(buf, "ANGBAND_X11_IBOX_%d", i);
	str = getenv(buf);
	val = (str != NULL) ? atoi(str) : -1;
	if (val > 0) ox = val;

	/* Window specific inner border offset (oy) */
	sprintf(buf, "ANGBAND_X11_IBOY_%d", i);
	str = getenv(buf);
	val = (str != NULL) ? atoi(str) : -1;
	if (val > 0) oy = val;


	/* Prepare the standard font */
	MAKE(td->fnt, infofnt);
	Infofnt_set(td->fnt);
	Infofnt_init_data(font);

	/* Hack -- key buffer size */
	num = (i == 0 ? 1024 : 16);

	/* Assume full size windows */
	wid = cols * td->fnt->wid + (ox + ox);
	hgt = rows * td->fnt->hgt + (oy + oy);

	/* Create a top-window */
	MAKE(td->win, infowin);
	Infowin_set(td->win);
	Infowin_init_top(x, y, wid, hgt, 0,
	                 Metadpy->fg, Metadpy->bg);

	/* Ask for certain events */
	Infowin_set_mask(ExposureMask | StructureNotifyMask | KeyPressMask |
	                 PointerMotionMask | ButtonPressMask | ButtonReleaseMask);

	/* Set the window name */
	Infowin_set_name(name);

	/* Save the inner border */
	Infowin->ox = ox;
	Infowin->oy = oy;

	/* Make Class Hints */
	ch = XAllocClassHint();

	if (ch == NULL) quit("XAllocClassHint failed");

	strcpy(res_name, name);
	res_name[0] = FORCELOWER(res_name[0]);
	ch->res_name = res_name;

	strcpy(res_class, "Angband");
	ch->res_class = res_class;

	XSetClassHint(Metadpy->dpy, Infowin->win, ch);

	/* Make Size Hints */
	sh = XAllocSizeHints();

	/* Oops */
	if (sh == NULL) quit("XAllocSizeHints failed");

	/* Fixed window size */
	if (i == 0)
	{
		/* Main window: 80x24 -- 255x255 */
		sh->flags = PMinSize | PMaxSize;
		sh->min_width = 80 * td->fnt->wid + (ox + ox);
		sh->min_height = 24 * td->fnt->hgt + (oy + oy);
		sh->max_width = 255 * td->fnt->wid + (ox + ox);
		sh->max_height = 255 * td->fnt->hgt + (oy + oy);
	}

	/* Variable window size */
	else
	{
		/* Subwindows: 1x1 -- 255x255 */
		sh->flags = PMinSize | PMaxSize;
		sh->min_width = td->fnt->wid + (ox + ox);
		sh->min_height = td->fnt->hgt + (oy + oy);
		sh->max_width = 255 * td->fnt->wid + (ox + ox);
		sh->max_height = 255 * td->fnt->hgt + (oy + oy);
	}

	/* Resize increment */
	sh->flags |= PResizeInc;
	sh->width_inc = td->fnt->wid;
	sh->height_inc = td->fnt->hgt;

	/* Base window size */
	sh->flags |= PBaseSize;
	sh->base_width = (ox + ox);
	sh->base_height = (oy + oy);

	/* Use the size hints */
	XSetWMNormalHints(Metadpy->dpy, Infowin->win, sh);

	/* Map the window */
	Infowin_map();


	/* Move the window to requested location */
	if ((x >= 0) && (y >= 0)) Infowin_impell(x, y);


	/* Initialize the term */
	term_init(t, cols, rows, num);

	/* Use a "soft" cursor */
	t->soft_cursor = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Hooks */
	t->xtra_hook = Term_xtra_x11;
	t->curs_hook = Term_curs_x11;
	t->wipe_hook = Term_wipe_x11;
	t->text_hook = Term_text_x11;

	/* Save the data */
	t->data = td;

	/* Activate (important) */
	Term_activate(t);

	/* Success */
	return (0);
}


/*
 * Initialization function for an "X11" module to Angband
 */
errr init_x11(int argc, char *argv[])
{
	int i;

	cptr dpy_name = "";

	int num_term = 1;

#ifdef USE_GRAPHICS

	char filename[1024];

	int pict_wid = 0;
	int pict_hgt = 0;
	bool force_old_graphics = FALSE;

#ifdef USE_TRANSPARENCY

	char *TmpData;
#endif /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */


	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-d"))
		{
			dpy_name = &argv[i][2];
			continue;
		}

#ifdef USE_GRAPHICS

		if (prefix(argv[i], "-s"))
		{
			smoothRescaling = FALSE;
			continue;
		}

		if (prefix(argv[i], "-o"))
		{
			force_old_graphics = TRUE;
			continue;
		}

		if (prefix(argv[i], "-b"))
		{
			arg_bigtile = use_bigtile = TRUE;
			continue;
		}

#endif /* USE_GRAPHICS */

		if (prefix(argv[i], "-n"))
		{
			num_term = atoi(&argv[i][2]);
			if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
			else if (num_term < 1) num_term = 1;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}


	/* Init the Metadpy if possible */
	if (Metadpy_init_name(dpy_name)) return ( -1);


	/* Prepare cursor color */
	MAKE(xor, infoclr);
	Infoclr_set(xor);
	Infoclr_init_ppn(Metadpy->fg, Metadpy->bg, "xor", 0);


	/* Prepare normal colors */
	for (i = 0; i < 256; ++i)
	{
		Pixell pixel;

		MAKE(clr[i], infoclr);

		Infoclr_set(clr[i]);

		/* Acquire Angband colors */
		color_table[i][0] = angband_color_table[i][0];
		color_table[i][1] = angband_color_table[i][1];
		color_table[i][2] = angband_color_table[i][2];
		color_table[i][3] = angband_color_table[i][3];

		/* Default to monochrome */
		pixel = ((i == 0) ? Metadpy->bg : Metadpy->fg);

		/* Handle color */
		if (Metadpy->color)
		{
			/* Create pixel */
			pixel = create_pixel(Metadpy->dpy,
			                     color_table[i][1],
			                     color_table[i][2],
			                     color_table[i][3]);
		}

		/* Initialize the color */
		Infoclr_init_ppn(pixel, Metadpy->bg, "cpy", 0);
	}


	/* Initialize the windows */
	for (i = 0; i < num_term; i++)
	{
		term_data *td = &data[i];

		/* Initialize the term_data */
		term_data_init(td, i);

		/* Save global entry */
		angband_term[i] = Term;
	}

	/* Raise the "Angband" window */
	Infowin_set(data[0].win);
	Infowin_raise();

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);


#ifdef USE_GRAPHICS

	/* Try graphics */
	if (arg_graphics)
	{
		/* Try the "16x16.bmp" file */
		path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");

		/* Use the "16x16.bmp" file if it exists */
		if (!force_old_graphics &&
		                (0 == fd_close(fd_open(filename, O_RDONLY))))
		{
			/* Use graphics */
			use_graphics = TRUE;

			pict_wid = pict_hgt = 16;

			ANGBAND_GRAF = "new";
		}
		else
		{
			/* Try the "8x8.bmp" file */
			path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");

			/* Use the "8x8.bmp" file if it exists */
			if (0 == fd_close(fd_open(filename, O_RDONLY)))
			{
				/* Use graphics */
				use_graphics = TRUE;

				pict_wid = pict_hgt = 8;

				ANGBAND_GRAF = "old";
			}
		}
	}

	/* Load graphics */
	if (use_graphics)
	{
		Display *dpy = Metadpy->dpy;

		XImage *tiles_raw;

		/* Load the graphical tiles */
		tiles_raw = ReadBMP(dpy, filename);

		/* Initialize the windows */
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];

			term *t = &td->t;

			/* Graphics hook */
			t->pict_hook = Term_pict_x11;

			/* Use graphics sometimes */
			t->higher_pict = TRUE;

			/* Resize tiles */
			td->tiles =
			        ResizeImage(dpy, tiles_raw,
			                    pict_wid, pict_hgt,
			                    td->fnt->twid, td->fnt->hgt);
		}

#ifdef USE_TRANSPARENCY
		/* Initialize the transparency masks */
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];
			int ii, jj;
			int depth = DefaultDepth(dpy, DefaultScreen(dpy));
			Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
			int total;


			/* Determine total bytes needed for image */
			ii = 1;
			jj = (depth - 1) >> 2;
			while (jj >>= 1) ii <<= 1;
			total = td->fnt->twid * td->fnt->hgt * ii;


			TmpData = (char *)malloc(total);

			td->TmpImage = XCreateImage(dpy, visual, depth,
			                            ZPixmap, 0, TmpData,
			                            td->fnt->twid, td->fnt->hgt, 8, 0);

		}
#endif /* USE_TRANSPARENCY */


		/* Free tiles_raw? XXX XXX */
	}

#endif /* USE_GRAPHICS */


	/* Success */
	return (0);
}

#endif /* USE_X11 */

tome-235-src/src/main-sdl.c0000644000076400017500000022110611012107763013327 0ustar  dgdg/* Copyright (C) 2003-2004 Neil Stevens 
 // Copyright (C) 2004 Ethan Stump 
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // in the Software without restriction, including without limitation the rights
 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 // copies of the Software, and to permit persons to whom the Software is
 // furnished to do so, subject to the following conditions:
 //
 // The above copyright notice and this permission notice shall be included in
 // all copies or substantial portions of the Software.
 //
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 // THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 // Except as contained in this notice, the name(s) of the author(s) shall not be
 // used in advertising or otherwise to promote the sale, use or other dealings
 // in this Software without prior written authorization from the author(s).
 */

#ifdef USE_SDL

#include "angband.h"
#include 
#include 
#include 

#include 

#ifdef USE_ISO
/*
 * Simugraph system (Hj. Malthaner)
 */
#include "iso/simsys.h"
#include "iso/simgraph.h"
#include "iso/world_adaptor.h"
#include "iso/world_view.h"
/*
 * Simugraph specific routines
 * by Hj. Malthaner
 */
#include "iso/hackdef.h"

/*
 * Text place marker function protype (Hj. Malthaner)
 */
static void set_spots(int x, int y, int n, bool v);

/**
 * we need to track spots with text to avoid overdrawing text with images
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
bool spots[80][24];

/**
 * mouse coordinates for Simugraph engine 
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int mx, my;

/*
 * Hajo: this flags need to be set when opening windows
 */

static int tex_width;
static int tex_height;
static int tex_xoff;
static int tex_yoff;

static unsigned int tab16[1 << 16];

/**
 * this is used if we need to fake an 8 bit array
 * @author Hj. Malthaner
 */
static unsigned short * data8;

// buffers to store char code/attr for graphics
unsigned char **iso_ap;
unsigned char **iso_cp;
unsigned char **iso_atp;
unsigned char **iso_ctp;
unsigned char **iso_aep;
unsigned char **iso_cep;

#endif /* USE_ISO */

/*************************************************
 GLOBAL SDL-ToME PROPERTIES
 *************************************************/
 
/* Default window properties - used if none are available
from other places*/
#define DEF_SCREEN_WIDTH  800
#define DEF_SCREEN_HEIGHT 600
#define DEF_SCREEN_BPP     16

/*Main window properties that may be loaded at runtime from
a preference file or environmental variables. However,
default values (defined above) can be used. */
static int arg_width = DEF_SCREEN_WIDTH;
static int arg_height = DEF_SCREEN_HEIGHT;
static int arg_bpp = DEF_SCREEN_BPP;

/**************/

/* Default font properties - used unless otherwise changed.
These properties are the size and also default font to load. */
#define DEF_FONT_SIZE 14
#define DEF_FONT_FILE "VeraMono.ttf"

/* The font properties that may perhaps be changed at runtime,
due to environmental variables, preference files, or in-program
commands.*/
static int arg_font_size = DEF_FONT_SIZE;
static char arg_font_name[64] = DEF_FONT_FILE;

/**************/

/* Graphics setting - signifies what graphics to use. Valid ints
are available with given defines */

/* No graphics - use only colored text */
#define NO_GRAPHICS		0
/* "Old" graphics - use 8x8.bmp to extract graphics tiles */
#define GRAPHICS_8x8	8
/* "New" graphics - use 16x16.bmp as tiles and apply mask.bmp for transparency*/
#define GRAPHICS_16x16	16

static int arg_graphics_type = NO_GRAPHICS;


/**************/

/* The number of term_data structures to set aside mem for */
#define MAX_CONSOLE_COUNT 8

/* The number of consoles that are actually being used.
This number could be changed via preference files, environmental
variables, command-line arguments, or possibly even in-game
keypresses or menu-selections. */
static int arg_console_count = 1;

/* When rendering multiple terminals, each is drawn with a
surrounding border. This value controls the width of this
border */
#define BORDER_THICKNESS 1

/**************/

/* some miscellaneous settings which have not been dealt
with yet */
static bool arg_double_width = FALSE;

/* flag signifying whether the game is in full screen */
static bool arg_full_screen = FALSE;

/* a flag to show whether window properties have been
set or not... if so, the properties can be dumped
upon quit*/
static bool window_properties_set = FALSE;

/*************************************************
 GLOBAL SDL-ToME VARIABLES
 *************************************************/

/* the main screen to draw to */
static SDL_Surface *screen;

/* the video settings for the system */
static SDL_VideoInfo *videoInfo;

/* a flag to suspend updating of the screen;
this is in place so that when a large area is being
redrawn -- like when doing a Term_redraw() or when
redoing the entire screen -- all of the changes
can be stored up before doing an update. This
should cut down on screen flicker */
static bool suspendUpdate = FALSE;

/* some helper surfaces that are used for rendering 
characters */
static SDL_Surface *worksurf;
static SDL_Surface *crayon;

/* the cursor surface */
static SDL_Surface *cursor = NULL;

/* the array of pre-rendered characters
(see loadAndRenderFont() below) */
SDL_Surface *text[128];

/* the actual TTF_Font used (XXX should get rid of this)*/
TTF_Font *font=0;

/* the width and height of the uniformly-sized pre-rendered
characters */
int t_width = 0, t_height = 0;


/*************************************************
 COLOR SETUP
 *************************************************/
 
/* Simple black, mapped using the format of the main screen */
int screen_black;

/* The color to use for the cursor */
static int cursor_color = 0;
/* default cursor color is a semi-transparent yellow */
#define DEF_CURSOR_COLOR	255,255,0,128

/* The array of colors, mapped to the format of the crayon surface,
since this is ultimately the surface that color is begin applied to */
static int color_data[16];

/* The following macro is for color defining...
 Note that the color is fully opaque... */
#define COLOR(r,g,b) \
	SDL_MapRGBA(crayon->format,r,g,b,SDL_ALPHA_OPAQUE)

/*These color macros will setup the colors to use, but must be called after
 the SDL video has been set. That way SDL can correct for any funky video
 setttings. */

#define BLACK			COLOR(  0,  0,  0)	/* 0*/
#define WHITE			COLOR(255,255,255)	/* 1*/
#define MID_GREY		COLOR(128,128,128)	/* 2*/
#define BRIGHT_ORANGE	COLOR(255,128,  0)	/* 3*/
#define RED				COLOR(192,  0,  0)	/* 4*/
#define GREEN			COLOR(  0,128, 64)	/* 5*/
#define BRIGHT_BLUE		COLOR(  0,  0,255)	/* 6*/
#define DARK_ORANGE		COLOR(128, 64,  0)	/* 7*/
#define DARK_GREY		COLOR( 64, 64, 64)	/* 8*/
#define BRIGHT_GREY		COLOR(192,192,192)	/* 9*/
#define PURPLE			COLOR(255,  0,255)	/*10*/
#define YELLOW			COLOR(255,255,  0)	/*11*/
#define BRIGHT_RED		COLOR(255,  0,  0)	/*12*/
#define BRIGHT_GREEN	COLOR(  0,255,  0)	/*13*/
#define AQUAMARINE		COLOR(  0,255,255)	/*14*/
#define BROWN			COLOR(192,128, 64)	/*15*/

/*************************************************
 TERMINAL DATA STRUCTURE SETUP
 *************************************************/

/* Forward declare */
typedef struct _term_data term_data;

/* A structure for each "term" */
struct _term_data
{
	term t;					/* the term structure, defined in z-term.h */
	cptr name;				/* name of this term sub-window */

	uint rows, cols;		/* row/column count */
	SDL_Rect rect;			/* the bounding rectangle for the entire box;
								includes border and empty space as well */
							/* this rectangle is in screen coordinates */

	int border_thick;		/* thickness of border to draw around window */
	int border_color;		/* current color of the border */	
	uint cushion_x_top, cushion_x_bot, cushion_y_top, cushion_y_bot;
							/* empty space cushion between border and tiles */
	
	uint tile_width;		/* the width of each tile (graphic or otherwise)*/
	uint tile_height;		/* the height of each tile (graphic or otherwise)*/

	SDL_Surface	*surf;		/* the surface that graphics for this screen are
								rendered to before blitting to main screen */	
	int black,white,purple;	/* basic colors keyed to this terminal's surface */

#ifdef USE_GRAPHICS
#ifdef USE_TRANSPARENCY
#endif
#endif
};

/* The array of term data structures */
static term_data data[MAX_CONSOLE_COUNT];

/* Ordered array of pointers to term data structures, placed in order of
priority: lowest is on top of all others, the higher the index, the further
back into the screen that it is drawn */
static term_data *term_order[MAX_CONSOLE_COUNT];

/*************************************************
 FILE-SPECIFIC MACROS
 *************************************************/

/* Debug macros! */
#define DB(str) \
	printf("main-sdl: %s\n",str);

/* Prints out the RGBA values of a given color */
#define TYPECOLOR32(color) 	printf("  R:%d\tG:%d\tB:%d\tA:%d\t\n",\
	color>>24,(color&0x00ff0000)>>16,\
	(color&0x0000ff00)>>8,(color&0x000000ff))

#define TYPECOLOR16(color) 	printf("  R:%d\tG:%d\tB:%d\tA:%d\t\n",\
	(color&0xf000)>>12,(color&0x0f00)>>8,\
	(color&0x00f0)>>4,(color&0x000f))

/* SDL Surface locking and unlocking */
#define SDL_LOCK(surf) \
	if (SDL_MUSTLOCK(surf) ){ \
		if (SDL_LockSurface(surf) < 0) { \
			printf("Can't lock the screen: %s\n", SDL_GetError()); \
			exit(1); \
		} \
	}

#define SDL_UNLOCK(surf) \
	if (SDL_MUSTLOCK(surf) ){ \
		SDL_UnlockSurface(surf); \
	}

/* Wrapped SDL_UpdateRects function, to take into
account the fact that updates may be suspended by
the suspendUpdate flag... this macro should be used
whenever a rect needs updated */
#define SDL_UPDATE(rect) \
	if (!suspendUpdate) \
		SDL_UpdateRects(screen,1,&rect)

/* A complete screen redraw macro */
#define SDL_REDRAW_SCREEN \
	SDL_UpdateRect(screen,0,0,arg_width,arg_height)
	
/*************************************************
 QUITTING
 *************************************************/

/* function prototype */
void dumpWindowSettings(void);
	
/* SDL Quitting function... declare a few functions first.*/
void killFontAndAlphabet(void);
static void sdl_quit(cptr string)
{
	printf("sdl_quit called.\n");
	printf("message: %s\n",string);
	/* Need to take care of font and rendered characters */
	killFontAndAlphabet();
	if (TTF_WasInit())
		TTF_Quit();
	/* Then exit SDL */
	SDL_Quit();
	
	/* Dump the window properties, if available */
	if (window_properties_set)
		dumpWindowSettings();
	
	/* And now for the default quit behavior */
	quit_aux = 0;
	quit(string);
}

/*************************************************
 FONT SUPPORT FUNCTIONS
 *************************************************/

/* function prototype for creating surfaces */
SDL_Surface *createSurface(int width, int height);

/* killFontAndAlphabet will effectively de-initialize the font system;
it does this by closing the font and destroying any pre-rendered
text in memory */
void killFontAndAlphabet(void)
{
	int i;
	/* need to close a font and free all of its corresponding pre-rendered
	surfaces */
	if (font)
	{
		TTF_CloseFont(font);
		font = 0;
	}
	for (i=0;i<128;i++)
	{
		if(text[i])
		{
			SDL_FreeSurface(text[i]);
			text[i] = NULL;
		}
	}
}	

/* loadAndRenderFont is responsible for loading and initializing
a font. First, SDL_ttf calls are made to load and set the style
for the desired font. Next, a character alphabet is rendered and
each character is placed onto a uniformly-sized surface within
the text[] array. Whenever text is needed for displaying on-screen,
this array is referenced and the desired character picture is used. */
void loadAndRenderFont(char *fname, int size)
{
	int minx,maxx,miny,maxy,advance,i,midline = 0;
	char filename[PATH_MAX + 1];
	char fontdir[PATH_MAX + 1];
	SDL_Color base_color = {255,255,255,255};
	SDL_Surface *temp_surf;
	SDL_Rect tgt = {0,0,0,0};


	/* Assuming that the filename is valid,open the font */
	path_build(fontdir, PATH_MAX, ANGBAND_DIR_XTRA, "font");
	path_build(filename, PATH_MAX, fontdir, fname);
	font = TTF_OpenFont(filename,size);
	if (font == NULL)
		sdl_quit("Error loading that font!");
	/* Set the font style to normal */
	TTF_SetFontStyle(font,TTF_STYLE_NORMAL);

	/* Collect some measurements on this font -
	arbitrarily choose the letter 'a' to get width*/
	TTF_GlyphMetrics(font,'a',&minx,&maxx,&miny,&maxy,&advance);
	/* the width of each character tile */
	t_width = advance;
	/* the height of each character tile */
	t_height = TTF_FontHeight(font);
	/* position of the y=0 line in each tile */
	midline = TTF_FontAscent(font);
	
	/* now... render each of the individual characters */
	for (i=0;i<128;i++)
	{
		/* make a pretty blended glyph */
		temp_surf=TTF_RenderGlyph_Blended(font,i,base_color);
		/* and make sure that we got it right! */
		if (temp_surf == NULL)
			sdl_quit("Glyph failed to render!");
		/* get the metrics of this particular glyph so we can position it */
		TTF_GlyphMetrics(font,i,&minx,&maxx,&miny,&maxy,&advance);
		/* copy rendered glyph into text queue, at the right position*/
		tgt.x = minx;
		tgt.y = midline-maxy;
		/* but first... we'll need a surface in the text queue to blit to! */
		text[i] = createSurface(t_width,t_height);
		/* turn OFF src-alpha... results in brute
		 copy of the RGBA contents of surf */
		SDL_SetAlpha(temp_surf,0,0);
		SDL_BlitSurface(temp_surf,NULL,text[i],&tgt);
		/* turn OFF src-alpha since we'll be using worksurf for blitting */
		SDL_SetAlpha(text[i],0,0);
		/* kill the surface to patch up memory leaks */
		SDL_FreeSurface(temp_surf);
	}
}

#ifdef USE_ISO
/*************************************************
 ISO SUPPORT FUNCTIONS
 *************************************************/
/**
 * inits operating system stuff
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_os_init(int n, int *parameter)
{
	// Hajo:
	// unused in isov-x11
	return TRUE;
}


/**
 * opens graphics device/context/window of size w*h
 * @param w width
 * @param h height
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_os_open(int w, int h)
{
	const int left = 13;

/*	tex_width = (data[0].fd->dw * (data[0].t.wid - left + 2) + 3) & 0xFFFC;
	tex_height = data[0].fd->dh * (data[0].t.hgt - 2);

	tex_xoff = data[0].fd->dw * left;
	tex_yoff = data[0].fd->dh * 1 + 1; 
*/

	//tex_width = (data[0].size_w - (left - 2) * (data[0].size_w / data[0].cols) + 3) & 0xFFFC;
	// this is too big (but works :-))
	tex_width = data[0].size_w & 0xfffc;
	tex_height = (data[0].size_h / data[0].rows) * (data[0].rows-2);

	tex_xoff = (tex_width / data[0].cols) * left;
	tex_yoff = (tex_height / data[0].rows) * 1 + 1;
	
	return TRUE;
}


/**
 * closes operating system stuff
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_os_close()
{
	// Hajo:
	// unused in isov-x11
	return TRUE;
}


/**
 * retrieve display width
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_get_width()
{
	return data[0].size_w;
}


/**
 * retrieve display height
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
int dr_get_height()
{
	return data[0].size_h;
}


/**
 * this is used if we need to fake an 8 bit array
 * @author Hj. Malthaner
 */
static unsigned short * data8;


/**
 * creates a (maybe virtual) array of graphics data
 * @author Hj. Malthaner
 */
unsigned short * dr_textur_init()
{
	int i;

	printf("isov-sdl::dr_textur_init()\n");
	printf(" width  = %d\n", data[0].size_w);
	printf(" height = %d\n", data[0].size_h);

	for (i = 0; i < (1 << 16); i++)
	{
		// FIXME!!!
		// must consider color bits, or breaks in anything else but RGB 555
		unsigned int R;
		unsigned int G;
		unsigned int B;

		// RGB 555
		R = (i & 0x7C00) >> 10;
		G = (i & 0x03E0) >> 5;
		B = (i & 0x001F) >> 0;


		tab16[i] = SDL_MapRGB(screen->format, R << 3, G << 3, B << 3);
	}



	data8 = malloc((data[0].size_w) * (data[0].size_h) * 2);

	printf(" textur = %p\n", data8);

	// fake an 16 bit array and convert data before displaying
	return data8;
}

static void flush_area(int dest_x, int dest_y,
                       int x, int y, int w, int h)
{
	SDL_Surface *face = screen;

	if (SDL_LockSurface(face) == 0)
	{
		int i, j;
		const int bpp = screen->format->BytesPerPixel;

		for (j = 0; j < h; j++)
		{
			unsigned short * p = data8 + (y + j) * tex_width + x;
			unsigned char * row = face->pixels + (dest_y + j) * face->pitch + dest_x * bpp;


			for (i = 0; i < w; i++)
			{
				*((unsigned short*)row) = tab16[ *p++ ];
				row += bpp;
			}
		}
		SDL_UnlockSurface(face);
	}
}

/**
 * displays the array of graphics data
 * @author Hj. Malthaner
 */
void dr_textur(int xp, int yp, int w, int h)
{
	int y;

	// clipping unten
	if (yp + h > tex_height)
	{
		h = tex_height - yp;
	}

	/* debug spots
	for(y=0; y<24; y++) {
	int x;

	for(x=0; x<80; x++) {
	 if(spots[x][y]) {
	printf("X");
	 } else {
	printf(".");
	 }
}
	printf("\n");
}
	*/

	for (y = 0; y < SCREEN_HGT; y++)
	{
		const int left = 13;
		const int y1 = y + 1;
		int x = 0;

		yp = data[0].size_h / data[0].rows * y;

		spots[79][y1] = FALSE;

		do
		{
			int n = 0;
			while (x + n + left < 80 && !spots[x + n + left][y1])
			{
				n++;
			}

			xp = data[0].size_w / data[0].cols * x;


			flush_area(tex_xoff + xp, tex_yoff + yp,
			           xp, yp,
			           data[0].size_w / data[0].cols*(n),
				   data[0].size_h / data[0].rows);

			x += n;

			while (x + left < 80 && spots[x + left][y1])
			{
				x++;
			}
		}
		while (x + left < 80);
	}
}


/**
 * use this method to flush graphics pipeline (undrawn stuff) onscreen.
 * @author Hj. Malthaner
 */
void dr_flush()
{
	// Iso-view for angband needs no sync.
	// XSync(md,FALSE);
}


/**
 * set colormap entries
 * @author Hj. Malthaner
 */
void dr_setRGB8multi(int first, int count, unsigned char * data)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * display/hide mouse pointer
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void show_pointer(int yesno)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * move mouse pointer
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void move_pointer(int x, int y)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * update softpointer position
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void ex_ord_update_mx_my()
{
	// Hajo:
	// unused in isov-x11
}


/**
 * get events from the system
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void GetEvents()
{
	// Hajo:
	// unused in isov-x11
}


/**
 * get events from the system without waiting
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
void GetEventsNoWait()
{
	// Hajo:
	// unused in isov-x11
}


/**
 * @returns time since progrma start in milliseconds
 * @author Hj. Malthaner
 */
long long dr_time(void)
{
	// Hajo:
	// unused in isov-x11
	return 0;
}


/**
 * sleeps some microseconds
 * @author Hj. Malthaner
 */
void dr_sleep(unsigned long usec)
{
	// Hajo:
	// unused in isov-x11
}


/**
 * loads a sample
 * @return a handle for that sample or -1 on failure
 * @author Hj. Malthaner
 */
int dr_load_sample(const char *filename)
{
	// Hajo:
	// unused in isov-x11
	return TRUE;
}


/**
 * plays a sample
 * @param key the key for the sample to be played
 * @author Hj. Malthaner
 */
void dr_play_sample(int key, int volume)
{
	// Hajo:
	// unused in isov-x11
}

static unsigned char ** halloc(int w, int h)
{
	unsigned char **field = (unsigned char **)malloc(sizeof(unsigned char *) * h);
	int i;

	for (i = 0; i < h; i++)
	{
		field[i] = (unsigned char *)malloc(sizeof(unsigned char) * w);
		memset(field[i], 32 , w);
	}

	return field;
}

/**
 * spot array access procedure. Mark text output spots
 * @author Hj. Malthaner (hansjoerg.malthaner@gmx.de)
 */
static void set_spots(const int x, const int y, const int n, const bool v)
{
	int i;

	for (i = x; i < x + n; i++)
	{
		spots[i][y] = v;
	}
}


/***********************************************/
#endif /* USE_ISO */

/***********************************************/

/*** Function hooks needed by "Term" ***/

static void Term_init_sdl(term *t)
{
	term_data *td = (term_data*)(t->data);
	DB("Term_init_sdl");
	/* XXX XXX XXX */
}

static void Term_nuke_sdl(term *t)
{
	term_data *td = (term_data*)(t->data);
	DB("Term_nuke_sdl");
	/* XXX XXX XXX */
}

static errr Term_user_sdl(int n)
{
	term_data *td = (term_data*)(Term->data);
	DB("Term_user_sdl");
	/* XXX XXX XXX */

	/* Unknown */
	return (1);
}

/* KEYPRESS_STRING repeatedly sends characters to the terminal
XXX - should implement routine from maim-sdl.c, it's sooo much
cleaner */
#define KEYPRESS_STRING(str) \
strcpy(buf,str); \
n = buf; \
while (*n != '\0') { \
	Term_keypress((int)(*(n++))); \
}

/* function prototype */
void manipulationMode(void);
void redrawAllTerminals(void);
/* This is the main event handling routine that will be called
whenever an event is pulled off of the queue (in Term_xtra_sdl())*/
void handleEvent(SDL_Event *event)
{
	static char buf[24];	/* a buffer used when passing key names */
	char *n;				/* and a pointer to manipulate this buffer */

	switch( event->type )
	{
	case SDL_KEYDOWN:
		{
			/* handle key presses */

			/* I'm reading that as long as the upper 9 bits of the unicode
			 * value are zero, then the lower 7 bits are direct ASCII characters.
			 * Furthermore, it seems that all basic keys return non-zero values
			 * for the lower 7 bits, but function keys and other various things
			 * return 0000000 for the lower 7 bits.
			 * Basically, if the lower 7 bits are zero, do something special
			 *  (like start a macro), but otherwise just pass along the ASCII
			 * code!
			 */
			byte ascii_part = event->key.keysym.unicode & 0x00ff;

			/* gimme the key name */
			printf("Key is: %s\n",SDL_GetKeyName(event->key.keysym.sym));

			/* allow for full screen toggling! */
			if ((event->key.keysym.sym == SDLK_RETURN) && \
				(SDL_GetModState() & KMOD_ALT))
			{
				SDL_WM_ToggleFullScreen(screen);
				/* toggle the internal full screen flag */
				arg_full_screen = (arg_full_screen ? FALSE : TRUE);
			}

			/* entry into window manipulation mode */
			if ((event->key.keysym.sym == SDLK_RETURN) && \
				(SDL_GetModState() & KMOD_CTRL))
			{
				DB("Manipulation mode!");
				manipulationMode();
			}

#ifdef USE_ISO
			/* toggle tile size */
			if (event->key.keysym.sym == SDLK_SCROLLOCK) 
			{
			    switch (display_get_tile_size())
			    {
				case 32:
				    display_select_tile_size(0);
				    break;
				case 64:
				    display_select_tile_size(1);
				    break;
				default:
				    display_select_tile_size(0);
				    break;
			    }
			    reset_visuals();
			    strcpy(buf, "graf-iso.prf");
			    process_pref_file(buf);
			    refresh_display();
			    SDL_UpdateRect(screen, 0, 0, data[0].size_w, data[0].size_h);
			}
			
			/* cycle grid type none/objects+monsters only/full */
			if ((event->key.keysym.sym == '#') && \
				(SDL_GetModState() & KMOD_ALT))
			{
			    set_grid(get_grid()+1);
			    refresh_display();
			}

#endif
			
			/*printf("ascii_part: %d\n",ascii_part);*/
			if (ascii_part)
			{
				/* We have now determined that the ASCII part is not '0', so
				 we can safely pass along the ASCII value! */
				Term_keypress(ascii_part);
			}
			else
			{
				/* We want to ignore keypresses that are simply the modifier
				keys*/
				if (!( (event->key.keysym.sym == SDLK_RSHIFT) |
					(event->key.keysym.sym == SDLK_LSHIFT) |
					(event->key.keysym.sym == SDLK_RALT) |
					(event->key.keysym.sym == SDLK_LALT) |
					(event->key.keysym.sym == SDLK_RCTRL) |
					(event->key.keysym.sym == SDLK_LCTRL) ))
				{

					/* now build a macro string using the modifiers together
					with the key that was just pressed*/

					/* As for the formatting...
					 * We pass the key press and modifiers as follows:
					 * \[ctrl-alt-shift-"key name"]
					 * following the previously established convention...
					 *
					 * All of the things that happen are defined in pref-sdl.prf
					 */
					
					KEYPRESS_STRING("\[");	/*Output the first part... */
					/* See if a control key is down */
					if (event->key.keysym.mod & KMOD_CTRL)
					{
						KEYPRESS_STRING("ctrl-");
					}
					/* See if an alt key is down */
					if (event->key.keysym.mod & KMOD_ALT)
					{
						KEYPRESS_STRING("alt-");
					}
					/* See if a shift key is down */
					if (event->key.keysym.mod & KMOD_SHIFT)
					{
						KEYPRESS_STRING("shift-");
					}

					/* Add in the name of whatever key was pressed */
					KEYPRESS_STRING(SDL_GetKeyName(event->key.keysym.sym));

					/* and end it... */
					KEYPRESS_STRING("]");
				}
			}
			break;
		}
	case SDL_QUIT:
		{
			/* handle quit requests */
			DB("Emergency Blit");
			redrawAllTerminals();
			/*sdl_quit("Quitting!\n");*/
			break;
		}
	default:
		{
			break;
		}
	}
}

/* declare the screen clearing function used below */
void eraseTerminal();
void drawTermStuff(term_data *td, SDL_Rect *rect);
static errr Term_xtra_sdl(int n, int v)
{
	static SDL_Event event;
	term_data *td;


	/* Analyze */
	switch (n)
	{
	case TERM_XTRA_EVENT:
		{
			if (v)
			{
				/* Perform event checking with blocking */
				SDL_WaitEvent( &event );
				handleEvent( &event );
			} else {
				/* Perform event checking without blocking */
				if (SDL_PollEvent(&event)){
					/* We found an event! */
					handleEvent(&event);
				}
			}
			return(0);
		}

	case TERM_XTRA_FLUSH:
		{
			/* Keep doing events until the queue is empty! */
			while (SDL_PollEvent(&event))
			{
				handleEvent(&event);
			}
			return (0);
		}

	case TERM_XTRA_CLEAR:
		{
			/* Clear the terminal */
			DB("TERM_XTRA_CLEAR");
			suspendUpdate = TRUE;
			eraseTerminal();
			return (0);
		}

	case TERM_XTRA_SHAPE:
		{
			/*
			 * Set the cursor visibility XXX XXX XXX
			 *
			 * This action should change the visibility of the cursor,
			 * if possible, to the requested value (0=off, 1=on)
			 *
			 * This action is optional, but can improve both the
			 * efficiency (and attractiveness) of the program.
			 */

			return (0);
		}

	case TERM_XTRA_FROSH:
		{
			/*
			 * Flush a row of output XXX XXX XXX
			 *
			 * This action should make sure that row "v" of the "output"
			 * to the window will actually appear on the window.
			 *
			 * This action is optional, assuming that "Term_text_xxx()"
			 * (and similar functions) draw directly to the screen, or
			 * that the "TERM_XTRA_FRESH" entry below takes care of any
			 * necessary flushing issues.
			 */

			return (1);
		}

	case TERM_XTRA_FRESH:
		{
			/*
			 * Flush output XXX XXX XXX
			 *
			 * This action should make sure that all "output" to the
			 * window will actually appear on the window.
			 *
			 * This action is optional, assuming that "Term_text_xxx()"
			 * (and similar functions) draw directly to the screen, or
			 * that the "TERM_XTRA_FROSH" entry above takes care of any
			 * necessary flushing issues.
			 */

#ifdef USE_ISO
	 		// Hajo:
			// refresh the graphical view

			refresh_display();
			SDL_UpdateRect(screen, 0, 0, data[0].size_w, data[0].size_h);
//			SDL_UpdateRect(td->face, 0, 0, 80*td->w, 24*td->h);
#else /* regular SDL */
			/* If terminal display has been held for any reason,
			then update the whole thing now!*/			
			DB("TERM_XTRA_FRESH");
			if (suspendUpdate)
			{
				DB("  update WAS suspended... updating now");
				td = (term_data*)(Term->data);
				suspendUpdate = FALSE;				
				drawTermStuff(td,NULL);
			}
#endif /* USE_ISO */			
			return (0);
		}

	case TERM_XTRA_NOISE:
		{
			/*
			 * Make a noise XXX XXX XXX
			 *
			 * This action should produce a "beep" noise.
			 *
			 * This action is optional, but convenient.
			 */

			return (1);
		}

	case TERM_XTRA_SOUND:
		{
			/*
			 * Make a sound XXX XXX XXX
			 *
			 * This action should produce sound number "v", where the
			 * "name" of that sound is "sound_names[v]".  This method
			 * is still under construction.
			 *
			 * This action is optional, and not very important.
			 */

			return (1);
		}

	case TERM_XTRA_BORED:
		{
			/* Perform event checking without blocking */
			if (SDL_PollEvent(&event)){
				/* We found an event! */
				handleEvent(&event);
			}
			return(0);
		}

	case TERM_XTRA_REACT:
		{
			/*
			 * React to global changes XXX XXX XXX
			 *
			 * For example, this action can be used to react to
			 * changes in the global "color_table[256][4]" array.
			 *
			 * This action is optional, but can be very useful for
			 * handling "color changes" and the "arg_sound" and/or
			 * "arg_graphics" options.
			 */
#ifdef USE_ISO
	    	strcpy(buf, "graf-iso.prf");
			process_pref_file(buf);
#endif /* USE_ISO */
			return (1);
		}

	case TERM_XTRA_ALIVE:
		{
			/*
			 * Change the "hard" level XXX XXX XXX
			 *
			 * This action is used if the program changes "aliveness"
			 * by being either "suspended" (v=0) or "resumed" (v=1)
			 * This action is optional, unless the computer uses the
			 * same "physical screen" for multiple programs, in which
			 * case this action should clean up to let other programs
			 * use the screen, or resume from such a cleaned up state.
			 *
			 * This action is currently only used by "main-gcu.c",
			 * on UNIX machines, to allow proper "suspending".
			 */

			return (1);
		}

	case TERM_XTRA_LEVEL:
		{
			/*
			 * Change the "soft" level XXX XXX XXX
			 *
			 * This action is used when the term window changes "activation"
			 * either by becoming "inactive" (v=0) or "active" (v=1)
			 *
			 * This action can be used to do things like activate the proper
			 * font / drawing mode for the newly active term window.  This
			 * action should NOT change which window has the "focus", which
			 * window is "raised", or anything like that.
			 *
			 * This action is optional if all the other things which depend
			 * on what term is active handle activation themself, or if only
			 * one "term_data" structure is supported by this file.
			 */

			return (1);
		}

	case TERM_XTRA_DELAY:
		{
			/*
			 * Delay for some milliseconds XXX XXX XXX
			 *
			 * This action is useful for proper "timing" of certain
			 * visual effects, such as breath attacks.
			 *
			 * This action is optional, but may be required by this file,
			 * especially if special "macro sequences" must be supported.
			 */

			/* I think that this command is system independent... */
			/*sleep(v/1000);*/
			/* main-x11 uses usleep(1000*v); */
			/* main-win uses Sleep(v); */
			return (1);
		}

	case TERM_XTRA_GET_DELAY:
		{
			/*
			 * Get Delay of some milliseconds XXX XXX XXX
			 * place the result in Term_xtra_long
			 *
			 * This action is useful for proper "timing" of certain
			 * visual effects, such as recording cmovies.
			 *
			 * This action is optional, but cmovies wont perform
			 * good without it
			 */

			return (1);
		}
	}

	/* Unknown or Unhandled action */
	return (1);
}

/*************************************************
 GRAPHICS ROUTINES
 *************************************************/

/* wrapper routine for creating an RGB surface with given height and
 width that corresponds to desired color depth and respects the system
 pixel format */
SDL_Surface *createSurface(int width, int height)
{
	SDL_Surface *surf;
	int surface_type;
	
	if (videoInfo->hw_available)
		surface_type = SDL_HWSURFACE;
	else
		surface_type = SDL_SWSURFACE;
	
	/* XXX need to make RGBA masks correspond to system pixel format! */
	switch (arg_bpp)
	{
		case 8:
		{
			/* I really don't know if 8 bpp is even possible, but here it is */
			surf = SDL_CreateRGBSurface(surface_type,width,\
				height,8,0xc0,0x30,0x0c,0x03);
			break;
		}
		case 16:
		{
			surf = SDL_CreateRGBSurface(surface_type,width,\
				height,16,0xf000,0x0f00,0x00f0,0x000f);
			break;
		}
		case 24:
		{
			surf = SDL_CreateRGBSurface(surface_type,width,\
				height,24,0xfc0000,0x03f000,0x000fc0,0x000030);
			break;
		}
		case 32:
		{
			surf = SDL_CreateRGBSurface(surface_type,width,\
				height,32,0xff000000,0x00ff0000,0x0000ff00,0x000000ff);
			break;
		}
		default:
		{
			surf = NULL;
			break;
		}
	}
	
	if (surf == NULL)
		sdl_quit("Bad Surface Creation!");
	
	return surf;
}

/* Take a rectangle in terminal coordinates and then transform it into
screen coordinates; td is the term_data that this rect belongs to */
void term_to_screen(SDL_Rect *termrect, term_data *td)
{
	termrect->x += td->rect.x;
	termrect->y += td->rect.y;
}

/* Do the opposite, take a rectangle in screen coordinates and transform 
it into the terminal coordinates of the given term_data */
void screen_to_term(SDL_Rect *scrrect, term_data *td)
{
	scrrect->x -= td->rect.x;
	scrrect->y -= td->rect.y;
}

/* A macro that determines if the 'top' rectangle completely occludes the
'bottom' rectangle */
#define BLOCKS(top,bottom) \
( (top.x <= bottom.x) & ((top.x+top.w)>=(bottom.x+bottom.w)) & \
 (top.y <= bottom.y) & ((top.y+top.h)>=(bottom.y+bottom.h)) )

#define INTERSECT(r1,r2) \
!( ( (r1.x > (r2.x+r2.w)) | (r2.x > (r1.x+r1.w)) ) & \
  ( (r1.y > (r2.y+r2.h)) | (r2.y > (r1.y+r1.h)) ) )

/* A function to calculate the intersection of two rectangles. Takes base
rectangle and then updates it to include only the rectangles that intersect 
with the test rectangle. If there is an intersection, the function returns
TRUE and base now contains the intersecting rectangle. If there is no
intersection, then the function returns FALSE */
bool intersectRects(SDL_Rect *base, SDL_Rect *test)
{
	if (INTERSECT((*base),(*test)))
	{
		/* Scoot the x-coordinates for the left side*/
		if ( test->x > base->x )
		{
			base->w -= test->x - base->x;
			base->x = test->x;
		}
		/* Scoot the x-coordinates for the right side*/		
		if ( (test->x + test->w) < (base->x + base->w) )
		{
			base->w = test->x + test->w - base->x;
		}
		/* Scoot the upper y-coordinates */
		if ( test->y > base->y )
		{
			base->h -= test->y - base->y;
			base->y = test->y;
		}
		/* Scoot the lower y-coordinates */		
		if ( (test->y + test->h) < (base->y + base->h) )
		{
			base->h = test->y + test->h - base->y;
		}
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

/* A function to calculate the join of two rectangles; the first argument is
changed to the joined rectangle */
SDL_Rect joinRects(SDL_Rect *r1, SDL_Rect *r2)
{
	SDL_Rect out = {0,0,0,0};
	
	if ( (r1 != NULL) & (r2 != NULL) )
	{
		/* Lower x-coordinate */
		if ( r2->x < r1->x )
			out.x = r2->x;
		else
			out.x = r1->x;
		/* Upper x-coordinate */
		if ( (r2->x+r2->w) > (r1->x+r1->w) )
			out.w = (r2->x+r2->w) - out.x;
		else
			out.w = (r1->x+r1->w) - out.x;
		/* Lower y-coordinate */
		if ( r2->y < r1->y )
			out.y = r2->y;
		else
			out.y = r1->y;
		if ( (r2->y+r2->h) > (r1->y+r1->h) )
			out.h = (r2->y+r2->h) - out.y;
		else
			out.h = (r1->y+r1->h) - out.y;
	}
	return out;
}
			
/* Given a term_data (and its associated screen) and a rectangle in terminal
coordinates (with NULL signifying to take the whole terminal surface), blit
graphics from the term_data surface to the screen, using the term_data's rect
to indicate how terminal coordinates transform into screen coordinates.
This is complicated, however, by the possibility that the indicated area may be
occluded by overlaying terminals. In this case, if the target area is
completely occluded, nothing will be done. If partially occluded, it will be
drawn, but occluding terminals will then re-blit to re-cover the area. */
void drawTermStuff(term_data *td, SDL_Rect *rect)
{
	int n = 0, i;
	bool block = FALSE, cover = FALSE;
	SDL_Rect spot, isect_term, isect_scr;

	/* first of all, if updating is suspended, do nothing! */
	if (!suspendUpdate)
	{
		/* find out which number in the ordered stack of screens that this
		terminal is */
		while ((term_order[n] != td) & (n < MAX_CONSOLE_COUNT))
		{
			n++;
		}
		if (n == MAX_CONSOLE_COUNT)
			printf("Could not find terminal in display list...\n");
		/* now loop through and see if any terminals completely occlude 
		the desired spot; if num=0, note that this will be skipped */
		if (rect == NULL)
		{
			/* Grab the whole terminal screen */
			spot.x = 0;	spot.y = 0;
			spot.w = td->surf->w; spot.h = td->surf->h;
		}
		else
		{
			/* Just copy the given area */
			spot.x = rect->x; spot.y = rect->y;
			spot.w = rect->w; spot.h = rect->h;
		}
		term_to_screen(&spot,td);
		i = n;
		while (i--)
		{
			if (BLOCKS(term_order[i]->rect,spot))
			{
				/* Higher terminal completely occludes this spot */
				block = TRUE;
				DB("  Blocks!");
			}
			else if (INTERSECT(term_order[i]->rect,spot))
			{
				/* Partial occlusion */
				cover = TRUE;
				DB("  Covers!");
			}
		}
		/* If any of the higher terminals blocked, then don't do
		anything */
		if (!block)
		{
			/*printf("Blitting to %d %d %d %d\n",spot.x,spot.y,spot.w,spot.h);*/
			/* First of all, draw the graphics */
			SDL_BlitSurface(td->surf,rect,screen,&spot);
			if (cover)
			{
				printf("covering...");
				/* There are covering terminals, so go through and blit all
				partially occluding ones */
				while (n--)
				{
					/* copy spot to find the intersect */
					isect_scr.x = spot.x; isect_scr.y = spot.y;
					isect_scr.w = spot.w; isect_scr.h = spot.h;
					if (intersectRects(&isect_scr,&(term_order[n]->rect)))
					{
						/* this terminal intersects... re-blit */
						/* first, convert to term coordinates */
						isect_term.x = isect_scr.x; isect_term.y = isect_scr.y;
						isect_term.w = isect_scr.w; isect_term.h = isect_scr.h;						
						screen_to_term(&isect_term,term_order[n]);
						/* blit from term coordinates to screen coordinates */
						SDL_BlitSurface(term_order[n]->surf,&isect_term,\
							screen,&isect_scr);
					}
				}
			}
			/* Now update what was drawn */
			DB("Update");
			SDL_UpdateRects(screen,1,&spot);
		}
	}
}
		
/* utility routine for creating and setting the color of the cursor;
it could be useful for setting a new cursor color if desired.
Could later be expanded to do other stuff with the cursor,
like a hollow rectangle a la main-win.c or even a graphic */
void createCursor(byte r, byte g, byte b, byte a)
{
	/* free the cursor if it exists */
	if (cursor != NULL)
		SDL_FreeSurface(cursor);

	/* and create it anew! (or the first time) */
	cursor = createSurface(t_width,t_height);
	
	/* be sure to use alpha channel when blitting! */
	SDL_SetAlpha(cursor,SDL_SRCALPHA,0);
	
	/* just set the color for now - drawing rectangles
	needs surface locking for some setups */
	cursor_color = SDL_MapRGBA(cursor->format,r,g,b,a);
	SDL_LOCK(cursor);
	SDL_FillRect(cursor,NULL,cursor_color);
	SDL_UNLOCK(cursor);
}

/* Cursor Display routine - just blits the global cursor
surface onto the correct location */
static errr Term_curs_sdl(int x, int y)
{
#ifdef USE_ISO
	highlite_spot(x, y);
#else /* regular SDL */
	term_data *td = (term_data*)(Term->data);
	static SDL_Rect base;

	/* calculate the position to place the cursor */
	base.x = td->surf->clip_rect.x + x*t_width;
	base.y = td->surf->clip_rect.y + y*t_height;
	base.w = t_width;
	base.h = t_height;
	
	/* blit the cursor over top of the given spot;
	note that surface should not be locked
	(see note in Term_text_sdl() below) */
	SDL_BlitSurface(cursor,NULL,td->surf,&base);

	/* Now draw to the main screen */
	drawTermStuff(td,&base);
#endif	/* USE_ISO */
	/* Success */
	return (0);
}

/* routine for wiping terminal locations - simply draws
a black rectangle over the offending spots! */
static errr Term_wipe_sdl(int x, int y, int n)
{
	static SDL_Rect base;
	term_data *td = (term_data*)(Term->data);

	/* calculate boundaries of the area to clear */
	base.x = td->surf->clip_rect.x + x*t_width;
	base.y = td->surf->clip_rect.y + y*t_height;
	base.w = n*t_width;
	base.h = t_height;

	SDL_LOCK(td->surf);
	
	/* blank the screen area */
	SDL_FillRect(td->surf, &base, td->black);

	SDL_UNLOCK(td->surf);

	/* And... UPDATE the rectangle we just wrote to! */
	drawTermStuff(td,&base);

	/* Success */
	return (0);
}
	
/* Perform a full clear of active terminal; redraw the borders.*/
void eraseTerminal(void)
{
	static SDL_Rect base;
	term_data *td = (term_data*)(Term->data);

	/* temporarily remove clipping rectangle */
	SDL_SetClipRect(td->surf,NULL);

	SDL_LOCK(td->surf);	
	/* flood terminal with border color */
	SDL_FillRect(td->surf,NULL,td->border_color);
	
	/* get smaller rectangle to hollow out window */
	base.x = td->border_thick;
	base.y = td->border_thick;
	base.w = td->rect.w - 2*td->border_thick;
	base.h = td->rect.h - 2*td->border_thick;
	
	/* hollow out terminal */
	SDL_FillRect(td->surf,&base,td->black);

	SDL_UNLOCK(screen);
	
	/* reset clipping rectangle */
	base.x += td->cushion_x_top;
	base.y += td->cushion_y_top;
	base.w -= td->cushion_x_top + td->cushion_x_bot;
	base.h -= td->cushion_y_top + td->cushion_y_bot;
	SDL_SetClipRect(td->surf,&base);
	printf("Clip rect: %d %d %d %d\n",base.x,base.y,base.w,base.h);
	/* And... UPDATE the whole thing */
	drawTermStuff(td,NULL);
	
}

/*
 * Draw some text on the screen
 *
 * This function should actually display an array of characters
 * starting at the given location, using the given "attribute",
 * and using the given string of characters, which contains
 * exactly "n" characters and which is NOT null-terminated.
 *
 * You may assume "valid" input if the window is properly sized.
 *
 * You must be sure that the string, when written, erases anything
 * (including any visual cursor) that used to be where the text is
 * drawn.  On many machines this happens automatically, on others,
 * you must first call "Term_wipe_xxx()" to clear the area.
 *
 * In color environments, you should activate the color contained
 * in "color_data[a & 0x0F]", if needed, before drawing anything.
 *
 * You may ignore the "attribute" if you are only supporting a
 * monochrome environment, since this routine is normally never
 * called to display "black" (invisible) text, including the
 * default "spaces", and all other colors should be drawn in
 * the "normal" color in a monochrome environment.
 *
 * Note that if you have changed the "attr_blank" to something
 * which is not black, then this function must be able to draw
 * the resulting "blank" correctly.
 *
 * Note that this function must correctly handle "black" text if
 * the "always_text" flag is set, if this flag is not set, all the
 * "black" text will be handled by the "Term_wipe_xxx()" hook.
 */
static errr Term_text_sdl(int x, int y, int n, byte a, const char *cp)
{
#ifdef USE_ISO
	if (a < 16)
	{
		set_spots(x, y, n, TRUE);
	}
	else
	{
		set_spots(x, y, n, FALSE);
	}
#else
	term_data *td = (term_data*)(Term->data);
	static SDL_Rect base;
	SDL_Rect base_back;
	int i = n;
	char old = 0;

	/* calculate place to clear off and draw to */
	base.x = td->surf->clip_rect.x + x*td->tile_width;
	base.y = td->surf->clip_rect.y + y*td->tile_height;
	base.w = n*td->tile_width;
	base.h = td->tile_height;

	base_back = base;

	SDL_LOCK(screen);

	/* blank the drawing area */
	SDL_FillRect(td->surf, &base, td->black);

	SDL_UNLOCK(screen);

	/* Note that SDL docs specify that SDL_BlitSurface should not be called
	 on locked surfaces... since the character printing routine below revolves
	 around blitting, the surface has been unlocked first*/

	/* loop through the input string, drawing characters */
	i = n;
	old = 0;
	while (i--)
	{
		/* Output the character... */
		/* If character has not changed, then just blit the old surface into
		 the new location to save effort*/
		if (*cp == old)
		{
			/* the desired character/color combo is already on the work surf */
			/* just blit it! */
			SDL_BlitSurface(worksurf,NULL,td->surf,&base);
		} else {
			/* copy the desired character onto working surface */
			SDL_BlitSurface(text[*cp],NULL,worksurf,NULL);
			/* color our crayon surface with the desired color */
			SDL_FillRect(crayon,NULL,color_data[a&0x0f]);
			/* apply the color to the character on the working surface */
			SDL_BlitSurface(crayon,NULL,worksurf,NULL);
			/* and blit it onto our screen! */
			SDL_BlitSurface(worksurf,NULL,td->surf,&base);
		}
		/* Move to the next position */
		base.x += t_width;
		/* Store the old character */
		old = *cp;
		/* Increment the character pointer */
		cp++;
	}

	/* And update */
	drawTermStuff(td,&base_back);

#endif /* USE_ISO */	
	/* Success */
	return (0);
}

/*
 * Draw some attr/char pairs on the screen
 *
 * This routine should display the given "n" attr/char pairs at
 * the given location (x,y).  This function is only used if one
 * of the flags "always_pict" or "higher_pict" is defined.
 *
 * You must be sure that the attr/char pairs, when displayed, will
 * erase anything (including any visual cursor) that used to be at
 * the given location.  On many machines this is automatic, but on
 * others, you must first call "Term_wipe_xxx(x, y, 1)".
 *
 * With the "higher_pict" flag, this function can be used to allow
 * the display of "pseudo-graphic" pictures, for example, by using
 * the attr/char pair as an encoded index into a pixmap of special
 * "pictures".
 *
 * With the "always_pict" flag, this function can be used to force
 * every attr/char pair to be drawn by this function, which can be
 * very useful if this file can optimize its own display calls.
 *
 * This function is often associated with the "arg_graphics" flag.
 *
 * This function is only used if one of the "higher_pict" and/or
 * "always_pict" flags are set.
 */
#ifndef USE_ISO
static errr Term_pict_sdl(int x, int y, int n, const byte *ap, const char *cp)
{
	term_data *td = (term_data*)(Term->data);
	DB("Term_pict_sdl");
	/* XXX XXX XXX */
	
#else
// for ISO-view we need USE_TRANSPARENCY and USE_EGO_GRAPHICS defined
static errr Term_pict_sdl(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp, const byte *eap, const char *ecp)
{
	/* Hajo: memorize output */
	memcpy(&iso_ap[y][x], ap, n);
	memcpy(&iso_cp[y][x], cp, n);
	memcpy(&iso_atp[y][x], tap, n);
	memcpy(&iso_ctp[y][x], tcp, n);
	memcpy(&iso_aep[y][x], eap, n);
	memcpy(&iso_cep[y][x], ecp, n);

	// here is no text
	set_spots(x, y, n, FALSE);

#endif /* USE_ISO */
	/* Success */
	return (0);
}

/*************************************************
 SPECIAL TERMINAL WINDOW MANIPULATION ROUTINES
 *************************************************/

/* macro for bounding a value between two given values */
#define BOUND(val,low,high) \
if (val < low) \
{ \
	val = low; \
} \
else if (val > high) \
{ \
	val = high; \
}

/* two macros to get the adjusted maximums for window
positions... eg the screen width minus the width of the
window is the maximum x-position that the window can
be set at. */
#define MAX_X(td) \
( arg_width - td->rect.w )

#define MAX_Y(td) \
( arg_height - td->rect.h )

/* another two macros that give maximum window widths
based on screen size and current window position together
width tile widths/heights */
#define MAX_WIDTH(td) \
( (int)floorf((arg_width - td->rect.x - 2*td->border_thick - \
	td->cushion_x_bot - td->cushion_x_top )/td->tile_width))

#define MAX_HEIGHT(td) \
( (int)floorf((arg_height - td->rect.y - 2*td->border_thick - \
	td->cushion_y_bot - td->cushion_y_top )/td->tile_height))

/* update the width and height of given term's rectangle by simply
multiplying the tile count by tile size and adding in cushions and
borders */
#define UPDATE_SIZE(td) \
	td->rect.w = (td->cols)*td->tile_width + td->cushion_x_top \
		+ td->cushion_x_bot + 2*td->border_thick; \
	td->rect.h = (td->rows)*td->tile_height + td->cushion_y_top \
		+ td->cushion_y_bot + 2*td->border_thick

void recompose(void);

/* Resize the active terminal with new width and height.
Note that his involves a complicated sequence of events...
Details to follow below! */
void resizeTerminal(int width, int height)
{
	term_data *td = (term_data*)(Term->data);
	
	/* First of all, bound the input width and height to satisfy
	these conditions:
	- The main ToME window should be at least 80 cols, 24 rows
	- no part of each window should be drawn off screen....
	  I'm including borders in this restriction!
	But no bounds checking needs to take place if the input width
	and height are unchanged....
	*/

	if (td == &data[0])
	{
		/* The active terminal is the main ToME window...
		don't let the width get below 80, don't let the heights below
		24, and don't let it leak off of the edge! */
		if (width != td->cols)
		{
			BOUND(width,80,MAX_WIDTH(td));
		}
		if (height != td->rows)
		{
			BOUND(height,24,MAX_HEIGHT(td));
		}
	}
	else
	{
		/* This is not the main window... just make sure it
		doesn't shrink to nothing or go past the edge */
		if (width != td->cols)
		{
			BOUND(width,1,MAX_WIDTH(td));
		}
		if (height != td->rows)
		{
			BOUND(height,1,MAX_HEIGHT(td));
		}
	}
	
	/* Okay, now make sure that something has ACTUALLY changed 
	before doing anything */
	if ((width != td->cols) || (height != td->rows))
	{
		
		/* Now, ask zterm to please resize the term structure! */
		Term_resize(width,height);

		/* Reactivate, since Term_resize seems to activate the
		main window again...*/
		Term_activate(&td->t);
		
		/* It might not have resized completely to the new
		size we wanted (some windows have size limits it seems,
		like the message window). So, update our structure with
		the size that were actually obtained.*/
		td->cols = Term->wid;
		td->rows = Term->hgt;
		
		/* And recalculate the sizes */
		UPDATE_SIZE(td);		
		
		/* Create a new surface that can hold the updated size */
		SDL_FreeSurface(td->surf);
		td->surf = createSurface(td->rect.w,td->rect.h);

		/* Now we should be in business for a complete redraw! */
		Term_redraw();
		
		/* Re-blit everything so it looks good */
		recompose();
		
		/* That's it! */
	}
}

/* Move the terminal around... a much simpler action that involves
just changing the pos_x/pos_y values and redrawing!*/
void moveTerminal(int x, int y)
{
	term_data *td = (term_data*)(Term->data);
	
	/* Now, the window is being shifted about... much simpler
	situation to handle! But of course, the window must not
	drift too far or else parts will be hanging off the screen
	and may lead to errors - bound the input positions to
	prevent this unfortunate situation... do nothing if the
	input is no different than the current */
	if (x != td->rect.x)
	{
		BOUND(x,0,MAX_X(td));
	}
	if (y != td->rect.y)
	{
		BOUND(y,0,MAX_Y(td));
	}
	
	/* Okay, now make sure that something changed before doing
	anything */
	if ((x != td->rect.x) || (y != td->rect.y))
	{
		/* Now update OUR structure */
		td->rect.x = x;
		td->rect.y = y;
		
		/* Then do a reblit to see the results */
		recompose();
		
		/* That's it! */
	}
}

/* Routine to bring a given term_data to the top of the drawing stack */
void bringToTop(int current)
{
	term_data *td;
	term_data *tc;
	int n = 0;
	int i;
	
	/* Get the pointer to the desired term_data from the data structure */
	td = &data[current];
	
	printf("Current stack: \n");
	for (i=0;isurf,NULL,screen,&(term_order[i]->rect));
	}
	
	/* Update everything */
	SDL_REDRAW_SCREEN;
}

/* This utility routine will completely blank the screen and
then cycle through all terminals, performing a Term_redraw()
on each and every term that is being used (according to
arg_term_count that is). The terminals will be redrawn
last-to-first, so that the main is over top of everything */
void redrawAllTerminals(void)
{
	int i = arg_console_count;
	DB("Total redraw");
	/* do a complete screen wipe */
	SDL_LOCK(screen);
	SDL_FillRect(screen,NULL,screen_black);
	SDL_UNLOCK(screen);

	while (i--)
	{
		/* Re-order the terminals */
		term_order[i] = &data[i];
	}
	
	i = arg_console_count;
	/* cycle down through each terminal */
	while (i--)
	{
		/* Activate this terminal */
		Term_activate(&(data[i].t));
		
		/* Make its border white since manipulation mode is over */
		data[i].border_color = data[i].white;

		/* And redraw it */
		Term_redraw();
	}
	/* Loop will end on i=0 ! */

	printf("Current stack: \n");
	for (i=0;iborder_color = td->purple;
	
	/* and do a complete redraw */
	DB("Term_redraw");
	Term_redraw();
	
	/* Now keep looping until Esc has been pressed. */
	while (!done)
	{
		/* Get the keypress event */
		SDL_WaitEvent(&event);
		/* Make sure that it is a keypress */
		if (event.type == SDL_KEYDOWN)
		{
			/* Act on the keypress! */
			switch (event.key.keysym.sym)
			{
				case SDLK_ESCAPE:
				{
					/* Escape has been pressed, so we're done!*/
					done = TRUE;
					break;
				}
				case SDLK_SPACE:
				{
					/* Space has been pressed: toggle move mode */
					moveMode = ( moveMode ? FALSE : TRUE );
					break;
				}
				case SDLK_RETURN:
				{
					/* Return... cycle the terminals!
					update the current_term appropriately*/
					current_term = cycleTerminal(current_term);
					
					/* Get the new term_data */
					td = &data[current_term];
					
					break;
				}
				case SDLK_RIGHT:
				case SDLK_LEFT:
				case SDLK_DOWN:
				case SDLK_UP:
				{
					/* Increase either the x-position or column
					width - multiply according to modifiers */
					value = 1;
					if (SDL_GetModState() & KMOD_SHIFT)
					{
						/* shift is down... a muliplier of 5 */
						value *= 5;
					}
					if (SDL_GetModState() & KMOD_CTRL)
					{
						/* control is down... multiply by 10 */
						value *= 10;
					}
					
					/* Now, behavior depends on which key was pressed
					and whether we are in moveMode resize mode... */
					
					/* First, set the delta_x/y based on key */
					if (event.key.keysym.sym == SDLK_RIGHT)
					{
						delta_x = 1;
						delta_y = 0;
					}
					if (event.key.keysym.sym == SDLK_LEFT)
					{
						delta_x = -1;
						delta_y = 0;
					}
					if (event.key.keysym.sym == SDLK_DOWN)
					{
						delta_x = 0;
						delta_y = 1;
					}
					if (event.key.keysym.sym == SDLK_UP)
					{
						delta_x = 0;
						delta_y = -1;
					}
					
					/* Now either moveTerminal() or 
					resizeTerminal() based on value of
					moveMode! */
					if (moveMode)
					{
						moveTerminal(td->rect.x + value*delta_x,\
							td->rect.y + value*delta_y);
					}
					else
					{
						resizeTerminal(td->cols + value*delta_x,\
							td->rows + value*delta_y);
					}
					break;
				}
				default:
				{
					break;
				}
			}
		}
		else if (event.type == SDL_MOUSEBUTTONDOWN)
		{
			/* Store the coordinates where the button was pressed */
			mouse_x = event.button.x;
			mouse_y = event.button.y;
		}
		else if (event.type == SDL_MOUSEMOTION)
		{
			/* Mouse is moving... maybe move or resize the window, based
			on the state of the mouse buttons */
			
			/* To keep the motion quick, temporarily ignore all mouse motion
			events until window moving is complete */
			SDL_EventState(SDL_MOUSEMOTION,SDL_IGNORE);
			
			if(event.motion.state & SDL_BUTTON(1))
			{
				/* the left mouse button is down, move the window,
				do a differential based on where the button was pressed */
				moveTerminal(td->rect.x + (event.motion.x - mouse_x), \
					td->rect.y + (event.motion.y - mouse_y));
				/* save the most current mouse location */
				SDL_GetMouseState(&mouse_x,&mouse_y);
			}
			
			if(event.motion.state & SDL_BUTTON(3))
			{
				/* the right mouse button is down, so resize the window;
				do a differential, but divide the number by the tile sizes */
				
				/* see if at least one whole tile width/height has been
				reached */
				int delta_cols, delta_rows;
				delta_cols = (int)floorf(\
					(float)(event.motion.x - mouse_x)/td->tile_width);
				delta_rows = (int)floorf(\
					(float)(event.motion.y - mouse_y)/td->tile_height);
				if ( delta_cols || delta_rows )
				{
					/* something changed, so update */
					resizeTerminal(td->cols + delta_cols, \
						td->rows + delta_rows);
					/* save the most current mouse location */
					SDL_GetMouseState(&mouse_x,&mouse_y);
				}
			}
			
			/* Deal with mouse motion again */
			SDL_EventState(SDL_MOUSEMOTION,SDL_ENABLE);
			
		}
	}
	/* Perform the last redraw to take all changes
	into account */
	redrawAllTerminals();
}

/*************************************************
 INITIALIZATION ROUTINES
 *************************************************/

static errr term_data_init(term_data *td, int i)
{
	term *t = &(td->t);
	char env_var[80];
	cptr val;

	
	/***** load position, size information */
	
	int cols, rows, x, y;	
	
	/* grab the column and row counts from
	environmental variables for now */
	sprintf(env_var,"TOME_NUM_COLS_%d",i);
	val = getenv(env_var);
	/* make sure it is valid */
	if (val != NULL)
	{
		cols = atoi(val);
		/* now make sure that the main window will
		have at least 80x24 */
		if (td == &data[0])
		{
			/* can't really pick an upper bound without
			knowing what the position is... oh well. */
			BOUND(cols,80,255);
		}
	}
	else
	{
		/* no environmental variable... have to guess
		something. If it's the main window, choose
		the minimum. */
		if (td == &data[0])
			cols = 80;
		else
			cols = 5;
	}
	/* do the rows */
	sprintf(env_var,"TOME_NUM_ROWS_%d",i);
	val = getenv(env_var);
	/* make sure it is valid */
	if (val != NULL)
	{
		rows = atoi(val);
		/* now make sure that the main window will
		have at least 80x24 */
		if (td == &data[0])
		{
			/* can't really pick an upper bound without
			knowing what the position is... oh well. */
			BOUND(rows,24,128);
		}
	}
	else
	{
		/* no environmental variable... have to guess
		something. If it's the main window, choose
		the minimum. */
		if (td == &data[0])
			rows = 24;
		else
			rows = 3;
	}
	/* store these values in the term_data structure */
	td->rows = rows;
	td->cols = cols;
	
	/* the position will be loaded from environmental
	variables as well - for the time being*/
	/* x-location */
	sprintf(env_var,"TOME_X_POS_%d",i);
	val = getenv(env_var);
	/* make sure it is valid */
	if (val != NULL)
	{
		x = atoi(val);
		/* now do intelligent position checking */
		BOUND(x,0,MAX_X(td));
	}
	else
	{
		/* no variable, choose something */
		x = 20*i;
	}
	/* y-location */
	sprintf(env_var,"TOME_Y_POS_%d",i);
	val = getenv(env_var);
	/* make sure it is valid */
	if (val != NULL)
	{
		y = atoi(val);
		/* position checking again */
		BOUND(y,0,MAX_Y(td));
	}
	else
	{
		/* no variable */
		y = 20*i;
	}
	/* and store these values into the structure */
	td->rect.x = x;
	td->rect.y = y;
	
	/*********** term structure initializing */
	
	/* Initialize the term 
	 gets: pointer to address, number of columns, number of rows, number
	   of keypresses to queue up (guess 24?)*/
	term_init(t, cols, rows, 24);

	/* Use a "soft" cursor */
	t->soft_cursor = TRUE;

	/* Picture routine flags */
	t->always_pict = FALSE;
	t->higher_pict = FALSE;
	t->always_text = FALSE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Hooks */
	t->xtra_hook = Term_xtra_sdl;
	t->curs_hook = Term_curs_sdl;
	t->wipe_hook = Term_wipe_sdl;
	t->text_hook = Term_text_sdl;
#ifdef USE_ISO
	t->pict_hook = Term_pict_sdl;
#endif /* USE_ISO */

	/* Save the data */
	t->data = td;

	/* Activate (important) */
	Term_activate(t);

	/************* finish term_data intializing */
	
	/* name of this term window */
	td->name = angband_term_name[i];

	/* For now, all font is the same size... use global t_width/height */
	td->tile_width = t_width;
	td->tile_height = t_height;

	td->cushion_x_top = 1;
	td->cushion_x_bot = 1;
	td->cushion_y_top = 1;
	td->cushion_y_bot = 1;
	
	/* Now calculate the total width and height*/
	UPDATE_SIZE(td);

	/* Create a surface to draw to */
	td->surf = createSurface(td->rect.w,td->rect.h);
	SDL_SetAlpha(td->surf,0,0);

	/* Key some colors to this surface */
	td->black  = SDL_MapRGB(td->surf->format,  0,  0,  0);
	td->white  = SDL_MapRGB(td->surf->format,255,255,255);
	td->purple = SDL_MapRGB(td->surf->format,255,  0,255);	
		
	/* Turn on a border, thickness specified by BORDER_THICKNESS */
	td->border_thick = BORDER_THICKNESS;

	/* make the default terminal border color to be white */
	td->border_color = td->white;


	printf("Init-int term: %d\n",i);
#ifdef USE_GRAPHICS
#ifdef USE_TRANSPARENCY
#endif
#endif

	/* Success */
	return (0);
}

/* dumpWindowSettings is responsible for exporting all current
values of the window positions, etc. to the screen, so that 
the user can see what the final values were after tweaking */
void dumpWindowSettings(void)
{
	char name[80];
	char value[8];
	int i;
	
	DB("Dumping settings");
	printf("---------------------------\n");
	/* cycle through each available terminal */
	for (i=0; ikillFontAndAlphabet() doesn't try to free
	SDL_Surfaces that don't exist ! */
	memset(text,0,sizeof(text));
	
	/* Also, clear out the term order array */
	memset(term_order,0,sizeof(term_order));

	/* initialize SDL */
	if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
	{
		sdl_quit("Video initialization failed!");
	}
	DB("SDL Initialized!");

	/* get video info, to be used for determining if hardware acceleration is
	 available, pixel format, etc.... */
	videoInfo = SDL_GetVideoInfo();
	
	/* Environment calls to retrieve specific settings...
	Note that these can be overridden by the command-line
	arguments that are handled below */
	if(getenv("TOME_CONSOLE_COUNT"))
		arg_console_count = atoi(getenv("TOME_CONSOLE_COUNT"));
	if(getenv("TOME_SCREEN_WIDTH"))
		arg_width = atoi(getenv("TOME_SCREEN_WIDTH"));
	if(getenv("TOME_SCREEN_HEIGHT"))
		arg_height = atoi(getenv("TOME_SCREEN_HEIGHT"));
	if(getenv("TOME_SCREEN_BPP"))
		arg_bpp = atoi(getenv("TOME_SCREEN_BPP"));
	if(getenv("TOME_FONT_SIZE"))
		arg_font_size = atoi(getenv("TOME_FONT_SIZE"));
	
	/* Argument handling routine;
	the argv pointer is already pointing at the '--'
	argument, so just start from there, parsing each
	option as it comes along */
	for (i=1; i < argc ; i++)
	{
		/* Set the number of consoles to handle
		(ie the number of windows) */
		if (0 == strcmp(argv[i], "-n"))
		{
			if (++i == argc)
			{
				printf("Argument missing for option -n\n");
				return -1;
			}
			
			arg_console_count = atoi(argv[i]);
			if (arg_console_count <= 0 || \
				arg_console_count > MAX_CONSOLE_COUNT)
			{
				printf("Invalid console count given.\n");
				arg_console_count = 1;
			}
		}
		/* Set the SDL window/screen width in pixels */
		else if (0 == strcmp(argv[i], "-w"))
	 	{
			if (++i == argc)
			{
				printf("Argument missing for option -w\n");
				return -1;
			}
			
			arg_width = atoi(argv[i]);
		}
		/* Set the SDL window/screen height in pixels */
		else if (0 == strcmp(argv[i], "-h"))
		{
			if (++i == argc)
			{
				printf("Argument missing for option -h\n");
				return -1;
			}
		
			arg_height = atoi(argv[i]);
		}
		/* Set the SDL window/screen color depth
		(in bits per pixel -- only 8,16,32 are okay) */
		else if (0 == strcmp(argv[i], "-bpp"))
		{
			if (++i == argc)
			{
				printf("Argument missing for option -bpp\n");
				return -1;
			}
			
			arg_bpp = atoi(argv[i]);
			if ( (arg_bpp != 8) && (arg_bpp != 16) \
				&& (arg_bpp != 24) && (arg_bpp != 32) )
			{
				printf("Invalid color depth. Must be either 8, 16, or 32 bpp!\n");
				return -1;
			}
		}
		/* see if new graphics are requested...*/
		else if (0 == strcmp(argv[i], "-g"))
		{
			printf("New graphics (16x16) enabled!\n");
			arg_graphics_type = GRAPHICS_16x16;
		}
		/* see if old graphics are requested...*/
		else if (0 == strcmp(argv[i], "-o"))
		{
			printf("Old graphics (8x8) enabled!\n");
			arg_graphics_type = GRAPHICS_8x8;
		}
		
		/* see if double width tiles are requested */
		else if (0 == strcmp(argv[i], "-b"))
		{
			/* do nothing for now */
			/* arg_double_width = TRUE; */
		}
		/* switch into full-screen at startup */
		else if (0 == strcmp(argv[i], "-fs"))
		{
			DB("Full-screen enabled!");
			arg_full_screen = TRUE;
		}
		/* change the font size */
		else if (0 == strcmp(argv[i], "-s"))
		{
			if (++i == argc)
			{
				printf("Argument missing for option -s\n");
				printf("Please specify font size!\n");
				return -1;
			}
			
			arg_font_size = atoi(argv[i]);
		}
		/* change the font to use */
		else if (0 == strcmp(argv[i], "-f"))
		{
			/* Can we please not be so MS Windows-specific?  One of the main goals
			   of SDL in ToME was to be more portable.  These file name hacks are
			   only the idiom of that one OS, though. -- Neil */
			DB("Getting font name");
			if (++i == argc)
			{
				printf("Argument missing for option -f\n");
				printf("Please specify a true-type font found in /lib/xtra/font!\n");
				return -1;
			}
			
			/* tokenize the font name so that no .ttf extension
			is required */
			strcpy(arg_font_name,\
				strtok(argv[i],&file_sep));
			
			/* and append the extension */
			strcat(arg_font_name,".ttf");

			/* print a little debug message, so
			user sees what font was actually selected */
			printf("\tUsing font: %s\n",arg_font_name);
			
			/* maybe check to see if file is even
			existant in /lib/xtra/font */
		}
		
	} /* end argument handling */

	/* Make sure that the engine will shutdown SDL properly*/
	quit_aux = sdl_quit;

	/* Use the ToME logo and set the window name */
	filename[PATH_MAX] = 0;
	path_build(filename, PATH_MAX, ANGBAND_DIR_XTRA, "graf/icon.png");
	SDL_WM_SetIcon(IMG_Load(filename), 0);
	SDL_WM_SetCaption("ToME", "tome");

	/* SDL video settings, dependent on whether hardware is available */
	if (videoInfo->hw_available)
		videoFlags = SDL_HWSURFACE;
	else
		videoFlags = SDL_SWSURFACE;

	/* now set the video mode that has been configured */
	screen = SDL_SetVideoMode( arg_width, arg_height, arg_bpp, videoFlags );

	/* Verify there is a surface */
	if ( !screen )
	{
		DB("No screen!");
		sdl_quit("Failed to set SDL Surface.");
	}

	DB("Video Mode Set!");
	
	/* now switch into full screen if asked for */
	if (arg_full_screen)
		SDL_WM_ToggleFullScreen(screen);
	
	DB("SDL Window Created!");

	/* Now ready the fonts! */

	DB("initializing SDL_ttf");
	if(TTF_Init()==-1) {
		printf("TTF_Init: %s\n", TTF_GetError());
		sdl_quit("Bah");
	}

	DB("loading font...");

	/* load and render the font */
	loadAndRenderFont(arg_font_name,arg_font_size);

	/* Graphics! ----
	If graphics are selected, then load graphical tiles! */
	if (arg_graphics_type != NO_GRAPHICS)
	{
		/* load graphics tiles */
	}
	
	/* Initialize the working surface and crayon surface used for rendering
	 text in different colors. */

	worksurf = createSurface(t_width,t_height);
	crayon = createSurface(t_width,t_height);
	
	/* The working surface will blit using alpha values... */
	SDL_SetAlpha(worksurf,SDL_SRCALPHA,0);

	/* Set up the colors using the great little color macros! */
	color_data[0]  = BLACK;
	color_data[1]  = WHITE;
	color_data[2]  = MID_GREY;
	color_data[3]  = BRIGHT_ORANGE;
	color_data[4]  = RED;
	color_data[5]  = GREEN;
	color_data[6]  = BRIGHT_BLUE;
	color_data[7]  = DARK_ORANGE;
	color_data[8]  = DARK_GREY;
	color_data[9]  = BRIGHT_GREY;
	color_data[10] = PURPLE;
	color_data[11] = YELLOW;
	color_data[12] = BRIGHT_RED;
	color_data[13] = BRIGHT_GREEN;
	color_data[14] = AQUAMARINE;
	color_data[15] = BROWN;

	/* And setup the cursor, using the default color...
	XXX - in the future, this should (and will) be loaded from prefs */
	createCursor(DEF_CURSOR_COLOR);

	/* Initialize the windows, or whatever that means in this case.
	Do this in reverse order so that the main window is on top.*/
	suspendUpdate = TRUE;	/* draw everything at the end */
	i = arg_console_count;
	while (i--)
	{
		term_data *td = &data[i];

		/* Initialize the term_data */
		term_data_init(td, i);

		/* Save global entry */
		angband_term[i] = Term;
		
		/* Add into term_order */
		term_order[i] = td;
		
	}
	
	/* And setup the basic screen colors -- these are keyed to the format of
	the main terminal surface */
	screen_black  = SDL_MapRGB(screen->format,  0,  0,  0);

	suspendUpdate = FALSE; /* now draw everything */
	redrawAllTerminals();
	/*SDL_REDRAW_SCREEN;*/
	
	/* now that the windows have been set, their settings can
	be dumped upon quit! */
	window_properties_set = TRUE;

	/* Enable UNICODE keysyms - needed for current eventHandling routine */
	SDL_EnableUNICODE(1);
	
	/* Enable key repeat! */
	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);

	#ifdef USE_ISO
	DB("Isometric view uses always graphics mode.\n");
	use_graphics = TRUE;

	
	/* Hajo: allocate memory for output data */
	/* These arrays are read by the iso-view and written from this file */
	iso_cp = halloc(data[0].t.wid, data[0].t.hgt);
	iso_ap = halloc(data[0].t.wid, data[0].t.hgt);
	iso_ctp = halloc(data[0].t.wid, data[0].t.hgt);
	iso_atp = halloc(data[0].t.wid, data[0].t.hgt);
	iso_cep = halloc(data[0].t.wid, data[0].t.hgt);
	iso_aep = halloc(data[0].t.wid, data[0].t.hgt);

	// Hmm, no ANGBAND_SYS in old iso-code
	// if I change this I don't have to load the *.prf manually?
	// 
	// seems not to work for the following:	
	/* Hajo: set mode */
	ANGBAND_GRAF = "iso";

	/* Hajo: init view */
	init_adaptor();
	
	center_player = TRUE;
#endif /* USE_ISO */

#ifdef USE_ISO
	// Juergen: HACK, but this all is just for testing ...
	data[0].t.higher_pict = TRUE;
#endif

	/* main-sdl initialized! */
	return 0;
}

#endif
tome-235-src/src/main-ros.c0000644000076400017500000055733711012107763013372 0ustar  dgdg/*
 * File: main-ros.c
 *
 * Abstract: Support for RISC OS versions of Angband, including support
 * for multitasking and dynamic areas.
 *
 * Authors: Musus Umbra, Andrew Sidwell, Ben Harrison, and others.
 *
 * Licences: Angband licence.
 */

#ifdef __riscos

#include "angband.h"

/*
 * Purpose: Support for RISC OS Angband 2.9.x onwards (and variants)
 *
 * NB: This code is still under continuous development - if you want to use
 * it for your own compilation/variant, please contact me so that I can
 * keep you up to date and give you support :)
 *
 * Prerequisites to compiling:
 *
 * DeskLib 2.30 or later  (earlier versions may be OK though)
 *
 * An ANSI C compiler (tested with Acorn's C/C++ and GCC, but should be OK
 *                     with any decent compiler)
 *
 * My binary distribution (for the templates and other bits)
 *
 * Note:
 *   The following symbols are *required* and *must* be defined properly.
 */

/*
 * VARIANT & VERSION
 *   These two get variant and version data from Angband itself; older
 *   variants may not have these defined and will have to be altered.
 */
#define VARIANT		"ToME"
#define VERSION		"2.2.2"

/*
 * PORTVERSION
 *   This is the port version; it appears in the infobox.
 */
#define PORTVERSION	"1.29-dev (2003-08-06)"

/*
 * RISCOS_VARIANT
 *  This must match the entry in the !Variant Obey file, and it must only
 *  contain characters that are valid as part of a RISC OS path variable.
 *  [eg. "Yin-Yangband" is not okay, "EyAngband" is.]
 */
#define RISCOS_VARIANT	"ToME"

/*
 * AUTHORS
 *  For the info box. [eg. "Ben Harrison"]
 */
#define AUTHORS		"DarkGod & co."

/*
 * PORTERS
 *  For the info box. [eg. "Musus Umbra"]
 */
#define PORTERS		"A. Sidwell"

/*
 * ICONNAME
 *  Iconbar icon sprite name eg. "!angband".  Note that this must be a valid
 *  sprite name; it may need modifying for long variant names.
 */
#define ICONNAME	"!"RISCOS_VARIANT

/*
 * PDEADCHK
 *   This should expand to an expression that is true if the player is dead.
 *   [eg. (p_ptr->is_dead) for Angband or (!alive || dead) for some Zangbands]
 */

#define PDEADCHK	(!alive)

/*
 * The following symbols control the (optional) file-cache:
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * NB: Variants that don't repeatedly read any files whilst running
 * (eg. vanilla, sang, etc) should NOT define USE_FILECACHE, etc. as
 * it causes a non-negligable amount of code to be compiled in.
 *
 * NB: The file-cache functions require that some code in files.c is modified
 * to use the cached_* functions.  This should be utterly trivial.
 *
 * NB: The returned handle from cached_fopen() is almost certainly *NOT*
 * a |FILE*| (although it may be if the cache cannot accomodate the file).
 *
 * Therefore, you *MUST* ensure that any file opened with cached_fopen()
 * is only ever accessed via cached_fgets() and cached_fclose().
 *
 * Failure to do so will result in, ahem, unpleasantness.  Extreme
 * unpleasantness.  "Him fall down, go boom."
 *
 * This /may/ change in the near future (ie. to apply caching in a
 * transparent manner), so do keep a backup of files.c (and any other files
 * you modify).  You always keep backups anyway, don't you?  Don't you?!
 */

/*
 * USE_FILECACHE
 *   if defined then some caching functions will be compiled for use by the
 *   various get_rnd_line(), etc. in files.c.  This could be used in a
 *   variety of places that read data repeatedly, but it's up to you to
 *   implement it then.
 */

/* #define USE_FILECACHE */

/*
 * SMART_FILECACHE
 *   This causes lines beginning with '#' (and blank lines) to be discarded
 *   when caching files.  This should help Zangband 2.2.5+ but could cause
 *   trouble for other variants.  If defined, then smart file caching will be
 *   on by default.
 */

/* #define SMART_FILECACHE */

/*
 * ABBR_FILECACHE
 *   ABBR_FILECACHE causes data read into file-cache to be compressed (using a
 *   simple set of abbreviations) by default.  This can be overridden using a
 *   command line option.  If this symbol is not defined then no compression
 *   code will be compiled and the user option will be ignored/unavailable.
 */

/* #define ABBR_FILECACHE */

/*
 * Note:
 *   The following symbols control debugging information.
 */

/*
 * FE_DEBUG_INFO
 *  If defined, some functions will be compiled to display some info. on the
 *  state of the front-end (accessible) from the '!' user menu.
 *
 *  NB: For actual releases you should NOT define this symbol since it causes
 *  a non-negligable amount of code/data to be sucked in.
 */
/* #define FE_DEBUG_INFO */

/*
 * USE_DA
 *  If defined, it enables the use of dynamic areas (these are still only
 *  used when the !Variant file allows it).  It is likely that this option
 *  will eventually be removed altogether as there is no major advantege
 *  to using DAs over just using the Wimpslot.
 */
#define USE_DA


/* Constants, etc. ---------------------------------------------------------*/

/* Deal with any weird file-caching symbols */
#ifndef USE_FILECACHE
# undef ABBR_FILECACHE
# undef SMART_FILECACHE
#endif

/* Maximum terminals */
#define MAX_TERM_DATA 8

/* Menu entry numbers */
#define IBAR_MENU_INFO			0
#define IBAR_MENU_SAVE			1
#define IBAR_MENU_FULLSCREEN	2
#define IBAR_MENU_GAMMA			3
#define IBAR_MENU_SOUND			4
#define IBAR_MENU_WINDOWS		5
#define IBAR_MENU_SAVECHOICES	6
#define IBAR_MENU_QUIT			7

#define TERM_MENU_INFO			0
#define TERM_MENU_SAVE			1
#define TERM_MENU_FONT			2
#define TERM_MENU_WINDOWS		3

/* Icon numbers */
#define SND_VOL_SLIDER			0
#define SND_VOL_DOWN			1
#define SND_VOL_UP				2
#define SND_ENABLE				3

#define GAMMA_ICN				0
#define GAMMA_DOWN				1
#define GAMMA_UP				2

#define SAVE_ICON				2
#define SAVE_PATH				1
#define SAVE_OK					0
#define SAVE_CANCEL				3

/* Position and size of the colours strip in the gamma window */
#define GC_XOFF 20
#define GC_YOFF -14
#define GC_WIDTH 512
#define GC_HEIGHT 72

/* Maximum and minimum allowed volume levels */
#define SOUND_VOL_MIN			16
#define SOUND_VOL_MAX			176

/*--------------------------------------------------------------------------*/


#undef rename
#undef remove

#include "Desklib:Event.h"
#include "Desklib:EventMsg.h"
#include "Desklib:Template.h"
#include "Desklib:Window.h"
#include "Desklib:Handler.h"
#include "Desklib:Screen.h"
#include "Desklib:Menu.h"
#include "Desklib:Msgs.h"
#include "Desklib:Icon.h"
#include "Desklib:Resource.h"
#include "Desklib:SWI.h"
#include "Desklib:Time.h"
#include "Desklib:Sound.h"
#include "Desklib:KeyCodes.h"
#include "Desklib:Kbd.h"
#include "Desklib:GFX.h"
#include "Desklib:ColourTran.h"
#include "Desklib:Error.h"
#include "Desklib:Coord.h"
#include "Desklib:Slider.h"
#include "Desklib:Hourglass.h"
#include "Desklib:Save.h"
#include "Desklib:Sprite.h"
#include "Desklib:KernelSWIs.h"
#include "DeskLib:Filing.h"    

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*--------------------------------------------------------------------------*/

/*
 | We use the hourglass around calls to Wimp_Poll in an attempt to stop
 | users thinking that the game has 'hung'.
 | Kamband/Zangband and the Borg in particular can have quite long delays at
 | times.
 */
#define Start_Hourglass \
	{ if ( use_glass && !glass_on ) { glass_on=1; Hourglass_Start(50); } }
#define Stop_Hourglass \
	{ if ( glass_on ) { glass_on=0; Hourglass_Off(); } }


/*--------------------------------------------------------------------------*/
/* Types																	*/
/*--------------------------------------------------------------------------*/

/*
 | A ZapRedraw block
 */
typedef struct
{
	union
	{
		unsigned int value;
		struct
		{
			unsigned int vdu:1;
			unsigned int double_height:1;
			unsigned int extension:1;
			unsigned int padding:29;
		}
		bits;
	}
	r_flags;

	int r_minx;	/* min x of redraw in pixels from LHS, incl */
	int r_miny;	/* min y of redraw in pixels from top, incl */
	int r_maxx;	/* max x of redraw in pixels from LHS, excl */
	int r_maxy;	/* max y of redraw in pixels from top, excl */

	void *r_screen;	/* DSA: address of screen to write to (0=>read) */
	int r_bpl;	/* DSA: bytes per raster line */

	int r_bpp;	/* log base 2 of bits per pixel */
	int r_charw;	/* width of a character in pixels */
	int r_charh;	/* height of a character in pixels */
	void *r_caddr;	/* DSA: ->character cache | VDU: ->font name */
	int r_cbpl;	/* DSA: #bytes/character line | VDU: x OS offset */
	int r_cbpc;	/* DSA: #bytes/character | VDU: y OS offset */

	int r_linesp;	/* line spacing (pixels) */

	void *r_data;	/* -> text to display */
	int r_scrollx;	/* see Redraw dox */
	int r_scrolly;	/* see Redraw dox */

	void *r_palette;	/* -> palette lookup table */
	int r_for;	/* foreground colour at start of line */
	int r_bac;	/* background colour at start of line */

	void *r_workarea;	/* -> word aligned workspace */

	int r_magx;	/* log2 x OS coords per pixel */
	int r_magy;	/* log2 y OS coords per pixel */

	int r_xsize;	/* width of screen in pixels */
	int r_ysize;	/* height of screen in pixels */

	int r_mode;	/* current screen mode */
}
ZapRedrawBlock;


/*
 | We cache font data using an array of 'font handles' (since there is a
 | known maximum no. of fonts required).
 | This is what a font 'handle' looks like:
 */
typedef struct
{
	char *name;	/* font name */
	int usage;	/* usage count */
	int w, h;	/* width, height */
	int f, l;	/* first and last character defined */
	void *bpp_1;	/* source bitmap */
	void *bpp_n;	/* bitmap for the current screen mode */
}
ZapFont;

/*
 | A struct to hold all the data relevant to a term window
 */
typedef struct
{
	term t;	/* The Term itself */
	window_handle w;	/* Window handle */
	ZapFont *font;	/* Font */
	wimp_box changed_box;	/* Area out of date */
	struct
	{
	wimp_point pos;	/* Cursor position */
	BOOL visible;	/* visibility flag */
	}
	cursor;
	char name[12];	/* Name to give menus opened from the term */
	int def_open;	/* Open by default? */
	wimp_box def_pos;	/* default position */
	wimp_point def_scroll;	/* default scroll offset */
	int unopened;	/* Has this window not been opened yet? */
}
term_data;



/*--------------------------------------------------------------------------*/
/* ZapRedraw SWI numbers													*/
/*--------------------------------------------------------------------------*/

#define SWI_ZapRedraw_ 0x48480
#define SWI_ZapRedraw_RedrawArea (SWI_ZapRedraw_ + 0x00)
#define SWI_ZapRedraw_GetPaletteEntry (SWI_ZapRedraw_ + 0x01)
#define SWI_ZapRedraw_RedrawRaster (SWI_ZapRedraw_ + 0x02)
#define SWI_ZapRedraw_ConvertBitmap (SWI_ZapRedraw_ + 0x03)
#define SWI_ZapRedraw_PrepareDataLine (SWI_ZapRedraw_ + 0x04)
#define SWI_ZapRedraw_AddCursor (SWI_ZapRedraw_ + 0x05)
#define SWI_ZapRedraw_FindCharacter (SWI_ZapRedraw_ + 0x06)
#define SWI_ZapRedraw_MoveBytes (SWI_ZapRedraw_ + 0x07)
#define SWI_ZapRedraw_CachedCharSize (SWI_ZapRedraw_ + 0x08)
#define SWI_ZapRedraw_ConvBitmapChar (SWI_ZapRedraw_ + 0x09)
#define SWI_ZapRedraw_CreatePalette (SWI_ZapRedraw_ + 0x0a)
#define SWI_ZapRedraw_InsertChar (SWI_ZapRedraw_ + 0x0b)
#define SWI_ZapRedraw_ReadSystemChars (SWI_ZapRedraw_ + 0x0c)
#define SWI_ZapRedraw_ReverseBitmaps (SWI_ZapRedraw_ + 0x0d)
#define SWI_ZapRedraw_ReadVduVars (SWI_ZapRedraw_ + 0x0e)
#define SWI_ZapRedraw_GetRectangle (SWI_ZapRedraw_ + 0x0f)
#define SWI_ZapRedraw_AddVduBitmaps (SWI_ZapRedraw_ + 0x10)
#define SWI_ZapRedraw_CacheFontChars (SWI_ZapRedraw_ + 0x11)
#define SWI_ZapRedraw_SpriteSize (SWI_ZapRedraw_ + 0x12)
#define SWI_ZapRedraw_RedrawWindow (SWI_ZapRedraw_ + 0x13)


/*
 | Other SWI numbers that aren't defined in DeskLib's SWI.h:
 */
#define SWI_OS_ScreenMode 0x65
#define SWI_OS_DynamicArea 0x66
#define SWI_ColourTrans_ReturnColourNumber 0x40744
#define SWI_Wimp_ReportError 0x400df
#define SWI_PlayIt_Volume 0x4d146



/*--------------------------------------------------------------------------*
 | File scope variables													 |
 *--------------------------------------------------------------------------*/
static int ftype = 0xffd;	/* hack so saved games get the right type */
static int filehandle[16];	/* we keep track of open files with this */
static int openfiles = 0;	/* how many files are currently open */

/*
 | Paths we use...
 */
static char resource_path[260] = "";	/* Path pointng to "!Angband.Lib." */
static char scrap_path[260] = "";	/* Path to create scrap files on */
static char choices_file[3][260] =
{ "", "", "" };	/* Choices paths (read/write, mirror, read) */
static char alarm_file[2][260] =
{ "", "" };	/* Alarm choices paths (read/write, mirror, read) */
/*
 | So we can use something more meaningful later...
 | NB: Mirror is only meaningful for Choices and we don't
 | even reserve space for alarm_file[CHFILE_MIRROR].
 */
#define CHFILE_WRITE 0
#define CHFILE_READ 1
#define CHFILE_MIRROR 2

/*
 | Other 'globals':
 */
static int initialised = 0;	/* Used to determine whether to try to save */
static int game_in_progress = 0;	/* if Quit (or core() is called),  etc. */

static byte a_palette[256][4];	/* a copy of the raw Angband palette */
static unsigned int palette[256];	/* palette as gamma'd bbggrrxx words */
static unsigned int zpalette[256];	/* And our version for ZapRedraw */
static double gamma = 1.0;	/* assume gamma of 1.0 if unspecified */

static int enable_sound = 0;	/* enable sound FX */
static int sound_volume = 127;	/* Full volume */
static int force_mono = 0;	/* force monochrome */
static int start_fullscreen = 0;	/* start up full screen (added in 1.18) */
static int hack_flush = 0;	/* Should TERM_XTRA_FLUSH wait for all keys to be released? */
static int flush_scrap = 1;	/* Should any scrapfiles (incl. filecache) be deleted at exit? */
static int max_file_cache_size = 64 << 10;
static unsigned int vfiletype;
static int allow_iclear_hack = 0;	/* Allow the hideously evil Iclear workaround thing */
static int alarm_type = 0;	/* is there an alarm set? */
static int alarm_h = 0, alarm_m = 0;	/* alarm time (midnight) */
static char alarm_message[80] = "Time for bed!";	/* the message to give */
static int alarm_disp = 0;	/* is the alarm being displayed? */
static int alarm_beep = 0;	/* should be beep? */
static const char *alarm_types[] =
{ "Off", "On (one-shot)", "On (repeating)", "On (one-shot)" };
static unsigned int alarm_lastcheck = 0;


/* A little macro to save some typing later: */
#define COLOUR_CHANGED(x) \
	( (angband_color_table[x][1]!=a_palette[x][1]) || \
	  (angband_color_table[x][2]!=a_palette[x][2]) || \
	  (angband_color_table[x][3]!=a_palette[x][3]) )

static int got_caret = 0;	/* Do we own the caret? */
static int key_pressed = 0;	/* 'Key has been pressed' Flag */
static int use_glass = 1;	/* use the hourglass between WimpPolls? */
static int glass_on = 1;	/* is the hourglass on? */
static int user_menu_active = FALSE;	/* set to TRUE when the user menu is active */

/* Font system variables */
static ZapFont fonts[MAX_TERM_DATA + 1];	/* The +1 is for the system font */

/* The system font is always font 0 */
#define SYSTEM_FONT (&(fonts[0]))

/* Term system variables */
static term_data data[MAX_TERM_DATA];	/* One per term */

#ifndef FULLSCREEN_ONLY
static char r_data[24 * (80 * 5 + 4) + 25 * 4];	/* buffer for ZapRedraw data */

/* Wimp variables */
static icon_handle ibar_icon;	/* Iconbar icon handle */
static window_handle info_box;	/* handle of the info window */
static window_handle gamma_win;	/* gamma correction window */
static window_handle sound_win;	/* sound options window */
static window_handle save_box;	/* The savebox */
static menu_ptr ibar_menu;	/* Iconbar menu */
static menu_ptr term_menu;	/* Term window menu */
static menu_ptr wind_menu;	/* windows (sub) menu */
static menu_ptr font_menu;	/* Font (sub)menu */

static save_saveblock *saveblk = NULL;	/* For the save box */

/* List of Wimp messages we want to be given */
static int message_list[] =
{
	message_MODECHANGE,
	message_PALETTECHANGE,

	/* For the savebox */
	message_MENUWARN,
	message_DATASAVEACK,

	message_PREQUIT,
	0
};


static term_data *menu_term;	/* term the last menu was opened for */

#endif /* FULLSCREEN_ONLY */

static ZapRedrawBlock zrb;	/* a redraw block */

/* Cursor colour */
#define CURSOR_COLOUR	255		/* Cursor's Angband colour */
#define CURSOR_RGB		0x00ffff00	/* if undefined, use bbggrrxx */

static int cursor_rgb = -1;	/* colour to use for cursor */

static int fullscreen_mode = 0;	/* screen mode in use */
static int old_screenmode = 0;	/* Mode we started out in */
static int *fullscreen_font = 0;	/* font data for fullscreen use */
static int *fullscreen_base = 0;	/* base address of screen */
static int fullscreen_height;	/* height of the fullscreen font */
static int fullscreen_topline;	/* raster offset of fullscreen */

#define KEYPRESS_QUIT    0x1cc	/* F12 gets back to the desktop */
#define TERM_TOPLINE_HR  32		/* vertical pixel offset in mode 27 */
#define TERM_TOPLINE_LR  16		/* vertical pixel offset in mode 12 */
#define TIME_LINE        26		/* Line to display the clock on */

/* text to display at the bottom left of the fullscreen display */
static const char *fs_quit_key_text = "Press f12 to return to the desktop";
static const char *alarm_cancel_text = "(Press ^Escape to cancel the alarm)";

/* Debugging flags, etc. */
static int log_g_malloc = 0;	/* Log calls to ralloc, etc */
static int show_sound_alloc = 0;	/* Log sound mappings, etc */

/* Activate file caching? */
#ifdef USE_FILECACHE
static int use_filecache = TRUE;
#else
static int use_filecache = FALSE;
#endif

/* Cripple some things to save memory */
static int minimise_memory = 0;

/* Forward declarations of some of the Full Screen Mode stuff */
static void enter_fullscreen_mode(void);
static void leave_fullscreen_mode(void);
static void set_keys(int claim);

/* Forwards declarations of the sound stuff */
static void initialise_sound(void);
static void play_sound(int event);

/* Forward declarations of Term hooks, etc. */ 
static void Term_init_acn(term *t);   
static errr Term_user_acn(int n);
           
#ifndef FULLSCREEN_ONLY
static errr Term_curs_acn(int x, int y);
static errr Term_text_acn(int x, int y, int n, byte a, cptr s);
static errr Term_xtra_acn(int n, int v);  
static errr Term_wipe_acn(int x, int y, int n);
static errr Term_xtra_acn_check(void);
static errr Term_xtra_acn_event(void);
static errr Term_xtra_acn_react(void);  
#endif /* FULLSCREEN_ONLY */

static errr Term_curs_acnFS(int x, int y);  
static errr Term_text_acnFS(int x, int y, int n, byte a, cptr s); 
static errr Term_xtra_acnFS(int n, int v);  
static errr Term_wipe_acnFS(int x, int y, int n);  
static errr Term_xtra_acn_checkFS(void);
static errr Term_xtra_acn_clearFS(void);  
static errr Term_xtra_acn_eventFS(void);    
static errr Term_xtra_acn_reactFS(int force);

#ifdef USE_DA
/* Forward declarations of the memory stuff */
static void init_memory(int, int);
#endif

/* Forward declarations of the alarm stuff */
static void check_alarm(void);
#ifndef FULLSCREEN_ONLY
static void trigger_alarm_desktop(void);
#endif /* FULLSCREEN_ONLY */
static void ack_alarm(void);
static void write_alarm_choices(void);
static void read_alarm_choices(void);


/* This just shows some debugging info (if enabled with FE_DEBUG_INFO) */
static void show_debug_info(void);



/* File-caching functions (if enabled at compile time) */
#ifdef USE_FILECACHE
FILE *cached_fopen(char *name, char *mode);
errr cached_fclose(FILE *fch);
errr cached_fgets(FILE *fch, char *buffer, int max_len);
#endif

/*
 | These functions act as malloc/free, but (if possible) using memory
 | in the 'Game' Dynamic Area created by init_memory()
 | We attach these functions to the ralloc_aux and rnfree_aux hooks
 | that z-virt.c provides.
 */     
#ifdef USE_DA
static vptr g_malloc(huge size);
static vptr g_free(vptr blk, huge);
#else  
  #define g_malloc(size) malloc(size);
  #define g_free(block, size) free(block);
#endif

/*
 | These functions act as malloc/free, but (if possible) using memory
 | in the 'Fonts' Dynamic Area created by init_memory()
 */
#ifdef USE_DA
static void* f_malloc(size_t size);
static void f_free(void *blk);
#else
  #define f_malloc(size) malloc(size);
  #define f_free(block) free(block);
#endif

/*
 | These two functions perpetrate great evil to stop IClear from mucking
 | with the cursor keys in fullscreen mode.
 */
static void iclear_hack(void);
static void remove_iclear_hack(void);

/*
 | We use this to locate the choices file(s)...
 */
static char *find_choices(int write);
static char *find_choices_mirror(void);
static char *find_alarmfile(int write);



/*
 | This function is supplied as a wrapper to the save_player function.
 |
 | Its purpose is to change the filename that the game will be saved with
 | the leafname "!!PANIC!!" so that panic saves that break the savefile
 | won't overwrite the original savefile.
 |
 | To get this to work, you'll need to ammend files.c and change the call
 | to save_player in the panic save function(s) (search for "panic save")
 | to a call to save_player_panic_acn.  You can declare a prototype for
 | the function if you like.
 */

extern int save_player_panic_acn(void)
{
	char *e, *l;

	/* Find the final / in the savefile name */
	for (l = e = savefile; *e; e++)
		if (*e == '/')
		{
			l = e + 1;
		}

	/* Write over the current leaf with the special panic one */
	strcpy(l, "!!PANIC!!");

	/* save the game */
	return save_player();
}


/*--------------------------------------------------------------------------*/
/* Error reporting, etc.													*/
/*--------------------------------------------------------------------------*/


/* Tell the user something important */
static void plog_hook(cptr str)
{
	Msgs_Report(1, "err.plog", str);
}

/* Tell the user something, then quit */
static void quit_hook(cptr str)
{
	/* str may be null */
	if (str) Msgs_Report(1, "err.quit", str);
	exit(0);
}

/* Tell the user something then crash ;) */
static void core_hook(cptr str)
{
	Msgs_Report(1, "err.core", str);

	if (game_in_progress && character_generated)
		save_player_panic_acn();

	quit(NULL);
}

static void debug(const char *fmt, ...)
{
	va_list ap;
	char buffer[260];
	va_start(ap, fmt);
	vsprintf(buffer, fmt, ap);
	va_end(ap);
	plog(buffer);
}



/*
static void oserror_handler( int sig )
{
	core(_kernel_last_oserror()->errmess);
}
*/


/*--------------------------------------------------------------------------*/
/* File handling															*/
/*--------------------------------------------------------------------------*/

static int myFile_Open(const char *name, int mode)
{
	int handle;
	if (SWI(2, 1, SWI_OS_Find, mode, name, /**/ &handle))
		return 0;
	return handle;
}

static int myFile_Size(const char *name)
{
	int size, type;
	if (SWI(2, 5, SWI_OS_File, 17, name, /**/ &type, 0, 0, 0, &size))
		return -2;
	return type ? size : -1;
}

static os_error *myFile_Close(const int handle)
{
	return SWI(2, 0, SWI_OS_Find, 0, handle);
}

static os_error *myFile_Seek(const int handle, const int offset)
{
	return SWI(3, 0, SWI_OS_Args, 1, handle, offset);
}

static int myFile_WriteBytes(const int handle, const void *buf, const int n)
{
	int ntf;
	if (SWI(4, 4, SWI_OS_GBPB, 2, handle, buf, n, /**/ NULL, NULL, NULL, &ntf))
		return n;
	return ntf;
}

static int myFile_ReadBytes(const int handle, void *buf, const int n)
{
	int ntf;
	if (SWI(4, 4, SWI_OS_GBPB, 4, handle, buf, n, /**/ NULL, NULL, NULL, &ntf))
		return n;
	return ntf;
}

static os_error *myFile_SetType(const char *n, const int type)
{
	return SWI(3, 0, SWI_OS_File, 18, n, type);
}


static int myFile_Extent(const int handle)
{
	int ext;
	if (SWI(2, 3, SWI_OS_Args, 2, handle, /**/ NULL, NULL, &ext))
		return -1;
	return ext;
}


/*
 | Determine if one file is newer than another.
 |
 | The filenames should be specified in RISC OS style.
 |
 | Returns -1 if 'a' is newer than 'b'.
 */
static int file_is_newer(const char *a, const char *b)
{
	os_error *e;
	struct
	{
	unsigned int msw;
	unsigned int lsw;
	}
	a_time;
	struct
	{
	unsigned int msw;
	unsigned int lsw;
	}
	b_time;
	int a_type, b_type;

	/* Get the datestamp of the 'a' file */
	e = SWI(2, 4, SWI_OS_File,
			/* In */
			17, (int)a,
			/* Out */
			&a_type,			/* object type */
			NULL, &(a_time.msw),	/* Load Addr */
			&(a_time.lsw)		/* Exec Addr */
		);
	if (e)
	{
		core(e->errmess);
	}


	/* Get the datestamp of the 'b' file */
	e = SWI(2, 4, SWI_OS_File,
			/* In */
			17, (int)b,
			/* Out */
			&b_type,			/* object type */
			NULL, &(b_time.msw),	/* Load Addr */
			&(b_time.lsw)		/* Exec Addr */
		);
	if (e)
	{
		core(e->errmess);
	}

	/* If 'b' doesn't exist then 'b' is OOD. */
	if (!b_type)
	{
		return -1;
	}
	/* If 'a' doesn't exist then 'b' isn't OOD. (?) */
	if (!a_type)
	{
		return 0;
	}

	/* Compare the timestamps (assume that the files are typed) */
	if ((a_time.msw & 0xff) >= (b_time.msw & 0xff))
		if ((a_time.lsw) > (b_time.lsw))
			return -1;			/* OOD */
	return 0;					/* Not OOD */
}


/*
 | As fprintf, but outout to all files (if their handles are non zero).
 | NB: void type.
 */
static void f2printf(FILE *a, FILE *b, const char *fmt, ...)
{
	va_list ap;
	char buffer[2048];
	va_start(ap, fmt);
	vsprintf(buffer, fmt, ap);
	va_end(ap);
	if (a)
	{
		fprintf(a, buffer);
	}
	if (b)
	{
		fprintf(b, buffer);
	}
	va_end(ap);
}




/*--------------------------------------------------------------------------*/
/* Clean up (ie. close files, etc). 										*/
/*--------------------------------------------------------------------------*/

static void final_acn(void)
{
	int i;

	for (i = 0; i < openfiles; i++)
		myFile_Close(filehandle[i]);

	if (fullscreen_mode)
	{
		/* Restore the screen mode */
		Wimp_SetMode(old_screenmode);

		/* Restore the various soft keys */
		set_keys(FALSE);

		/*
		   | Hack: Early WIMP versions do the "Press SPACE" thing, or something
		   | odd.  It's bloody annoying, whatever it is...
		 */
		if (event_wimpversion < 300)
			Wimp_CommandWindow(-1);
	}

	if (flush_scrap && *scrap_path)
	{
		char tmp[512];
		strcpy(tmp, scrap_path);
		tmp[strlen(tmp) - 1] = 0;	/* Remove trailing dot */
		SWI(4, 0, SWI_OS_FSControl, 27, tmp, 0, 1);	/* ie. "*Wipe  r~c~v~f" */
	}

#ifdef FULLSCREEN_ONLY
	Wimp_CommandWindow(-1);
#endif /* FULLSCREEN_ONLY */

	Stop_Hourglass;
}


/*--------------------------------------------------------------------------*
 | Various UNIX-like support funtions									   |
 *--------------------------------------------------------------------------*/

/*
 | Hack: determine whether filenames should be truncated to 10 chars or not.
 |
 | Needed since RO2 (and RO3 with Truncate configured off) will return
 | errors instead of automatically truncating long filenames.
 */
static int truncate_names(void)
{
	int r1, r2;

	/* First, check the OS version */
	OS_Byte(osbyte_READOSIDENTIFIER, 0x00, 0xff, &r1, &r2);

	/* Assume that we need to truncate if running under RO2 */
	if (r1 == 0xa1 || r1 == 0xa2)
		return TRUE;

	/* Okay, so we've got RO3 (or later), so check the CMOS RAM */
	OS_Byte(osbyte_READCMOSRAM, 28, 0, &r1, &r2);

	/* Bit 0 of byte 28 is the Truncate flag */
	return !(r2 & 1);
}


/*
 | The PathName translation is now done by two separate functions:
 | unixify_name() and riscosify_name().
 |
 | This is done because only the UNIX=>RISCOS translation should
 | ever affect the length of the leafname (ie. by truncating it to
 | 10 chars if necessary).
 |
 | Note that the two functions are identical but for the truncation
 | check so all that's really been done is that translate_name() now
 | takes an extra argument: 'trunc' that controls whether truncation
 | is applied, and riscosify and unixify just call translate_name().
 */
static char *translate_name(const char *path, int trunc)
{
	static char buf[260];
	char c, *p;

	/* Copy 'path' into 'buf', swapping dots and slashes */
	p = buf;					/* Output position */
	do
	{
		c = *path++;
		if (c == '/')
			c = '.';
		else if (c == '.')
			c = '/';
		*p++ = c;
	}
	while (c);					/* Terminator /is/ copied */

	/*
	   | When saving a game, the old game is renamed as
	   | "SavedGame.old", the new one is saved as "SavedGame.new",
	   | "SavedGame.old" is deleted, "SavedGame.new" is renamed
	   | as "SavedGame". This will go wrong on a Filecore based filing
	   | system if the saved game has a leafname > 8 chars.
	 */

	if ((p = strstr(buf, "/old")) == NULL)
	{
		p = strstr(buf, "/new");
	}
	if (!p)
	{
		ftype = 0xffd;
	}
	else
	{
		char *q = strrchr(buf, '.');
		if (q)
			if (p - q > 6)
			{
				memmove(q + 6, p, 5);
			}
		ftype = vfiletype;
	}

	/*
	   | Hack: Do we need to truncate the leafname?
	 */
	if (trunc)
	{
		if (truncate_names())
		{
			char *a, *b;
			/*
			   | Assume that only the leafname needs attention
			   | (this should be true for any variant)
			 */
			for (a = b = buf; *a; a++)
				if (*a == '.')
					b = a + 1;
			/*
			   | Now b points to the start of the leafname.
			   | If the leafname is >10 chars, write over the 10th with a
			   | terminator.
			 */
			if (strlen(b) > 10)
			{
				b[10] = 0;
			};
		}
	}

	return buf;
}


extern char *riscosify_name(const char *path)
{
	return translate_name(path, TRUE);
}

static char *unixify_name(const char *path)
{
	return translate_name(path, FALSE);
}


/*--------------------------------------------------------------------------*/


/* Open a file [as fopen()] but translate the requested filename first */

FILE *my_fopen(const char *f, const char *m)
{
	FILE *fp;
	char *n = riscosify_name(f);	/* translate for RO */

	/* Try to open the file */
	fp = fopen(n, m);

	/* If it succeded and the file was opened for binary output
	   | then set the type according to the 'ftype' hack.
	   | NB: This will fail on some filing systems.
	 */

	if (fp && strstr(m, "wb"))
	{
		myFile_SetType(n, ftype);
	}

	return fp;
}




/* Close a file, a la fclose() */

errr my_fclose(FILE *fp)
{
	/* Close the file, return 1 for an error, 0 otherwise */
	return fclose(fp) ? 1 : 0;
}


/* Open/Create a file */

int fd_make(cptr file, int mode)
{
	char *real_path;
	int handle;

	/* Translate the filename into a RISCOS one */
	real_path = riscosify_name(file);

	/* Try to OPENOUT the file (no path, error if dir or not found) */
	handle = myFile_Open(real_path, 0x8f);

	/* Check for failure */
	if (!handle)
	{
		return -1;
	}

	/* Try to set the filetype according to the ftype hack */
	myFile_SetType(real_path, ftype);

	/* We keep track of up to 16 open files at any given time */
	if (openfiles < 16)
		filehandle[openfiles++] = handle;
                                                                                
	return (handle);
}


/* Delete a file [as remove()] */
errr fd_kill(cptr file)
{
	return remove(riscosify_name(file)) ? 1 : 0;
}


/* Rename a file [as rename()] */
errr fd_move(cptr old, cptr new)
{
	char new_[260];
	strcpy(new_, riscosify_name(new));
	return rename(riscosify_name(old), new_) ? 1 : 0;
}

/* Open a file */
int fd_open(cptr path, int flags)
{
	int handle = 0;
	char *real_path = riscosify_name(path);

	switch (flags & 0x0f)
	{
		case O_RDONLY:			/* Read only */
			handle = myFile_Open(real_path, 0x4f);
			break;
		case O_WRONLY:			/* Write only */
		case O_RDWR:			/* Read/Write */
			handle = myFile_Open(real_path, 0xcf);
	}

	/* Check for failure */
	if (!handle)
	{
		return (-1);
	}

	/* Keep track of upto 16 open files... */
	if (openfiles < 16)
		filehandle[openfiles++] = handle;

	return (handle);
}


/* Close a file opened with fd_make or fd_open */
errr fd_close(int handle)
{
	int i;

	if (handle <= 0)
	{
		return -1;
	}							/* Illegal handle */

	/* Try to close the file */
	if (myFile_Close(handle))
	{
		return 1;
	}

	/* Mark the file as closed in our array of file handles */
	openfiles--;
	/* Find the entry in the array (if it exists) */
	for (i = 0; i < 16; i++)
		if (filehandle[i] == handle)
		{
			break;
		}
	/* Shuffle the remaining entries down */
	for (; i < openfiles; i++)
		filehandle[i] = filehandle[i + 1];

	return 0;					/* Sucess */
}



/* Read some bytes from a file */
errr fd_read(int handle, char *buf, huge nbytes)
{
	int unread;

	if (handle <= 0)
	{
		return -1;
	}							/* Illegal handle */
	unread = myFile_ReadBytes(handle, buf, (int)nbytes);

	return unread ? 1 : 0;
}


/* Write some bytes to a file */
errr fd_write(int handle, const char *buf, huge nbytes)
{
	int unwritten;

	if (handle <= 0)
	{
		return -1;
	}							/* Illegal handle */
	unwritten = myFile_WriteBytes(handle, (const void *)buf, (int)nbytes);

	return unwritten ? 1 : 0;
}


/* Seek in a file */
errr fd_seek(int handle, huge offset)
{
	os_error *e;

	if (handle <= 0)
	{
		return -1;
	}							/* Illegal handle */
	e = myFile_Seek(handle, (int)offset);

	return e ? 1 : 0;
}


/* RISC OS provides no file locking facilities, so: */
errr fd_lock(int handle, int what)
{
	return 0;
}


/* Get a temporary filename */
errr path_temp(char *buf, int max)
{

	/*
	   | New in 1.25 - use the scrap path we decided on earlier, or
	   | fall back on tmpnam() if that fails for some reason.
	 */
	if (*scrap_path)
	{
		time_t t;
		int m;
		char tmp[512];

		time(&t);
		for (m = 0; m < 80; m++)
		{
			sprintf(tmp, "%s0x%08x", scrap_path, (int)t + m);
			if (myFile_Size(tmp) == -1)
			{
				break;
			}
		}

		if (m < 80)
		{
			strncpy(buf, unixify_name(tmp), max);
			return 0;
		}
	}

	strncpy(buf, unixify_name(tmpnam(NULL)), max);
	return 0;
}



/*
 * Create a new path by appending a file (or directory) to a path
 *
 * This requires no special processing on simple machines, except
 * for verifying the size of the filename, but note the ability to
 * bypass the given "path" with certain special file-names.
 *
 * Note that the "file" may actually be a "sub-path", including
 * a path and a file.
 *
 * Note that this function yields a path which must be "parsed"
 * using the "parse" function above.
 */
errr path_build(char *buf, int max, cptr path, cptr file)
{
	/* Special file */
	if (file[0] == '~')
	{
		/* Use the file itself */
		strnfmt(buf, max, "%s", file);
	}

	/* Absolute file, on "normal" systems */
	else if (prefix(file, PATH_SEP) && !streq(PATH_SEP, ""))
	{
		/* Use the file itself */
		strnfmt(buf, max, "%s", file);
	}

	/* No path given */
	else if (!path[0])
	{
		/* Use the file itself */
		strnfmt(buf, max, "%s", file);
	}

	/* Path and File */
	else
	{
		/* Build the new path */
		strnfmt(buf, max, "%s%s%s", path, PATH_SEP, file);
	}

	/* Success */
	return (0);
}



/*--------------------------------------------------------------------------*/





/*--------------------------------------------------------------------------*/
/* Font Functions															*/
/*--------------------------------------------------------------------------*/

/*
 | Cache the system font as fonts[0]
 | Returns 1 for sucess or 0 for failure.
 | NB: The n_bpp data is *not* cached, just the 1bpp data and font info.
 | Also, the usage is never affected.
 */
static int cache_system_font(void)
{
	ZapFont *sys = SYSTEM_FONT;
	ZapRedrawBlock zrb;
	char work_area[16];
	int i;

	/* Cache the system font (as fonts[0]) */
	if (sys->bpp_1)
	{
		f_free(sys->bpp_1);
		sys->bpp_1 = 0;
	}
	sys->bpp_1 = f_malloc(8 * 256);	/* 2K */
	if (!sys->bpp_1)
	{
		return 0;
	}

	/* Mung so that undefined characters show up as inverted ?s */
	work_area[3] = '?';
	SWI(2, 0, SWI_OS_Word, 10, work_area + 3);
	for (i = 4; i < 12; i++)
		work_area[i] ^= 255;	/* invert colours */
	SWI(4, 0, SWI_ZapRedraw_ReverseBitmaps, 0, work_area + 4, work_area + 4, 8);
	for (i = 0; i < 0x20; i++)
		memcpy(((char *)sys->bpp_1) + i * 8, work_area + 4, 8);

	/* Read the system font */
	zrb.r_workarea = work_area;
	SWI(2, 0, SWI_ZapRedraw_ReadSystemChars, sys->bpp_1, &zrb);

	/* Set up some little bits of info */
	sys->name = (char *) "";
	sys->w = sys->h = 8;
	sys->f = 0;
	sys->l = 255;

	return 1;
}



/*
 | Prepare the font system
 */
static void initialise_fonts(void)
{
	/* Initialise the array */
	memset(fonts, 0, sizeof(fonts));	/* Clear to zeroes */

	/* Cache the system font */
	cache_system_font();
	fonts[0].usage = 0;			/* No users */
}


#ifndef FULLSCREEN_ONLY
/*
 | Find a font (by name) in the array.
 | Returns 0 if the font isn't loaded, or a ZapFont* for it if it is.
 */
static ZapFont *find_font_by_name(char *name)
{
	int i;
	for (i = 0; i <= MAX_TERM_DATA; i++)
		if (fonts[i].name)
			if (!strcmp(fonts[i].name, name))
				return &(fonts[i]);
	return NULL;
}

/*
 | Find a free slot in the fonts array
 */
static ZapFont *find_free_font(void)
{
	int i;
	for (i = 1; i <= MAX_TERM_DATA; i++)
		if (!fonts[i].name)
		{
			return &(fonts[i]);
		}
	return NULL;
}



/*
 | Load a font from disc and set up the header info, etc.
 | NB: doesn't cache the nbpp data, just the 1bpp data.
 | (Sets usage to 1)
 | Returns NULL if failed.
 */
static ZapFont *load_font(char *name, ZapFont *f)
{
	int handle, extent;
	char path[260];
	struct
	{
		char id[8];
		int w, h, f, l, r1, r2;
	}
	header;
	char *font_path;
	char *t;
	char *real_name = name;	/* need to preserve this */

	/*
	   | 1.10 - the first element of the name determines the path to load
	   | the font from.
	 */

	/* The font paths start $ */
	t = path + sprintf(path, "%s$", RISCOS_VARIANT);

	/* Copy the path specifier and move 'name' past it */
	for (; *name != '.'; *t++ = *name++) ;

	/* After this, the name now points to the font name proper */
	name++;

	/* Append the end of the path name */
	strcpy(t, "$FontPath");

	/* Get the path setting */
	font_path = getenv(path);
	if (!font_path || !*font_path)
		strcpy(path, "null:$.");
	else
	{
		strcpy(path, font_path);
		for (t = path; *t > ' '; t++)
			;
		if (t[-1] != '.' && t[-1] != ':')
		{
			*t++ = '.';
		}
		*t = 0;
	}
	strcat(path, name);


	/* Open the file */
	handle = myFile_Open(path, 0x4f);
	if (!handle)
	{
		return NULL;
	}

	/* Read the header */
	if (myFile_ReadBytes(handle, &header, sizeof(header)))
	{
		myFile_Close(handle);
		return NULL;
	}

	/* Check that it's a zapfont */
	if (strncmp(header.id, "ZapFont\r", 8))
	{
		myFile_Close(handle);
		return NULL;
	}

	/* Calculate the size of the 1bpp data */
	extent = myFile_Extent(handle) - sizeof(header);

	/* Allocate the storage for the 1bpp data */
	f->bpp_1 = f_malloc(extent);
	if (!f->bpp_1)
	{
		myFile_Close(handle);
		return NULL;
	}

	/* Load the 1bpp data */
	if (myFile_ReadBytes(handle, f->bpp_1, extent))
	{
		f_free(f->bpp_1);
		f->bpp_1 = 0;
		myFile_Close(handle);
		return NULL;
	}

	/* Close the file and set the header, etc. */
	myFile_Close(handle);
	f->name = f_malloc(strlen(real_name) + 1);
	if (!f->name)
	{
		f_free(f->bpp_1);
		f->bpp_1 = 0;
		return NULL;
	}

	strcpy(f->name, real_name);
	f->w = header.w;
	f->h = header.h;
	f->f = header.f;
	f->l = header.l;
	f->usage = 1;

	return f;
}




/*
 | Cache a font at a suitable number of bpp for the current mode
 | Returns 0 for failure, 1 for sucess.
 | If the call fails then the font's bpp_n entry will be NULL.
 */
static int cache_font_for_mode(ZapFont *f)
{
	ZapRedrawBlock b;
	char work_area[128];
	int size;

	if (!f)
	{
		return 0;
	}
	if (!f->bpp_1)
	{
		return 0;
	}

	b.r_workarea = work_area;
	SWI(2, 0, SWI_ZapRedraw_ReadVduVars, 0, &b);

	b.r_workarea = work_area;	/* Paranoia */
	b.r_charh = f->h;
	b.r_charw = f->w;
	SWI(4, 4, SWI_ZapRedraw_CachedCharSize, b.r_bpp, 0, f->w, f->h,
		NULL, NULL, &(b.r_cbpl), &(b.r_cbpc));

	size = 256 * b.r_cbpc;
	if (f->bpp_n)
	{
		f_free(f->bpp_n);
		f->bpp_n = NULL;
	}
	f->bpp_n = f_malloc(size);
	if (!f->bpp_n)
	{
		return 0;
	}

	b.r_workarea = work_area;	/* Paranoia */
	b.r_caddr = f->bpp_n;
	SWI(5, 0, SWI_ZapRedraw_ConvertBitmap, 0, &b, 0, 255, f->bpp_1);

	return 1;
}



/*
 | Stop using a font.
 | If the font's usage drops to zero then the font data is purged.
 */
static void lose_font(ZapFont *f)
{
	if (--f->usage)
	{
		/*debug("Losing font %s (still cached)",f->name); */
		return;
	}
	/*debug("Losing font %s (no longer in use)",f->name); */
	f_free(f->name);
	f_free(f->bpp_1);
	if (f->bpp_n)
	{
		f_free(f->bpp_n);
	}
	memset(f, 0, sizeof(ZapFont));
}


/*
 | Get a font.
 */
static ZapFont *find_font(char *name)
{
	ZapFont *f;

	/* Check to see if it's already loaded */
	f = find_font_by_name(name);
	if (f)
	{
		/*debug("Find font %s (already cached)",name); */
		f->usage++;
		if (f == SYSTEM_FONT)
		{
			if (!cache_system_font())
				core("Failed to cache system font!");
			if (!cache_font_for_mode(SYSTEM_FONT))
				core("Failed to cache system font!");
		}
		return f;
	}

	/* Ok, now check to see if there's a free slot for it */
	f = find_free_font();
	if (!f)
	{
		return NULL;
	}							/* Oh dear :( */

	/* Load the font */
	/*debug("Find font %s (loading)",name); */
	f = load_font(name, f);
	if (f)
	{
		if (!cache_font_for_mode(f))
			return NULL;
		return f;
	}
	return NULL;
}




/*
 | Cache the n_bpp data for all the active fonts (including system)
 */
static void cache_fonts(void)
{
	int i;
	for (i = 0; i <= MAX_TERM_DATA; i++)
		if (fonts[i].name)
			if (!cache_font_for_mode(&(fonts[i])))
				core("Failed to (re)cache font tables");
}






typedef struct
{
	int load, exec, size, attr, type;
	char name[4];	/* Actual size is unknown */
}
osgbpb10_block;


static char *leafname(char *path)
{
	char *s = path + strlen(path);
	while (--s > path)
		if (*s == '.' || *s == ':')
		{
			return s + 1;
		}
	return path;
}

/*
 | NB: This function is recursive.
 */
static menu_ptr make_zfont_menu(char *dir)
{
	int entries, entry;
	int read, offset;
	unsigned int max_width;
	menu_ptr m;
	menu_item *mi;
	char *temp;
	osgbpb10_block *item_info;
	char buffer[1024];	/* 1Kb buffer */

	/* Count the entries in the directory */
	entries = read = offset = 0;
	while (offset != -1)
	{
		if (SWI(7, 5, SWI_OS_GBPB, 10, dir, buffer, 77, offset, 1024, 0,
				NULL, NULL, NULL, &read, &offset))
		{
			offset = -1;
			read = 0;
		}
		entries += read;
	}

	if (!entries)
	{
		return NULL;
	}

	/* Allocate a big enough area of storage for the number of entries */
	m = f_malloc(sizeof(menu_block) + entries * sizeof(menu_item));
	if (!m)
	{
		return NULL;
	}
	memset(m, 0, sizeof(menu_block) + entries * sizeof(menu_item));

	/* Set up the menu header */
	strncpy(m->title, leafname(dir), 12);
	m->titlefore = 7;
	m->titleback = 2;
	m->workfore = 7;
	m->workback = 0;
	m->height = 44;
	m->gap = 0;
	mi = (menu_item *) (((int)m) + sizeof(menu_block));
	max_width = strlen(m->title);

	entry = 0;

	/* Read the entries */
	read = offset = 0;
	while (offset != -1)
	{
		if (SWI(7, 5, SWI_OS_GBPB, 10, dir, buffer, 77, offset, 1024, 0,
				NULL, NULL, NULL, &read, &offset))
		{
			offset = -1;
			read = 0;
			/*free(m);return NULL; */
		}

		item_info = (osgbpb10_block *) buffer;

		/* Create a menu item for each entry read (if it fits) */
		while (read-- > 0)
		{
			switch (item_info->type)
			{
				case 1:		/* File */
					if ((item_info->load & 0xffffff00) == 0xfffffd00)
					{
						/* Data file */
						mi[entry].submenu.value = -1;
						mi[entry].iconflags.data.text = 1;
						mi[entry].iconflags.data.filled = 1;
						mi[entry].iconflags.data.foreground = 7;
						mi[entry].iconflags.data.background = 0;
						strncpy(mi[entry].icondata.text, item_info->name, 12);
						if (strlen(mi[entry].icondata.text) > max_width)
							max_width = strlen(mi[entry].icondata.text);
						entry++;
					}
					break;
				case 2:		/* Directory */
				case 3:		/* Image */
				{
					menu_ptr sub;
					char new_path[260];
					if (strchr(":.", dir[strlen(dir) - 1]))
						sprintf(new_path, "%s%s", dir, item_info->name);
					else
						sprintf(new_path, "%s.%s", dir, item_info->name);
					sub = make_zfont_menu(new_path);
					if (sub)
					{
						/* Add the submenu */
						mi[entry].submenu.menu = sub;
						mi[entry].iconflags.data.text = 1;
						mi[entry].iconflags.data.filled = 1;
						mi[entry].iconflags.data.foreground = 7;
						mi[entry].iconflags.data.background = 0;
						strncpy(mi[entry].icondata.text, item_info->name, 12);
						if (strlen(mi[entry].icondata.text) > max_width)
							max_width = strlen(mi[entry].icondata.text);
						entry++;
					}
				}
					break;
			}
			temp = ((char *)item_info) + 20;
			while (*temp++) ;
			item_info = (osgbpb10_block *) ((((int)temp) + 3) & ~3);
		}
	}

	if (entry)
	{
		m->width = (max_width + 2) * 16;
		mi[entry - 1].menuflags.data.last = 1;
		/*
		   | We could possibly realloc() the storage to fit the
		   | actual no. of entries read, but this is probably more
		   | trouble than it's worth.
		 */
	}
	else
	{
		/*
		   | No point in returning an empty menu.
		 */
		f_free(m);
		m = NULL;
	}

	return m;
}

#endif /* FULLSCREEN_ONLY */




/*--------------------------------------------------------------------------*/

/*
 | Initialise the palette stuff
 */
static void initialise_palette(void)
{
	memset(a_palette, 0, sizeof(a_palette));
	memset(palette, 0, sizeof(palette));
	memset(zpalette, 0, sizeof(zpalette));
}



#ifndef FULLSCREEN_ONLY

/*
 | Cache the ZapRedraw palette
 */
static void cache_palette(void)
{
	static ZapRedrawBlock b;
	char workspace[128];
	int i;

	static double old_gamma = -1.0;

	/* Idiocy check: */
	if (gamma < 0.01)
	{
		plog("Internal error: Attempt to apply zero gamma - recovering...");
		gamma = 1.00;
	}

	if (gamma != old_gamma)
	{
		memset(a_palette, 0, sizeof(a_palette));
		old_gamma = gamma;
	}

	/* Go through the palette updating any changed values */
	for (i = 0; i < 256; i++)
	{
		if (COLOUR_CHANGED(i))
		{
			int r, g, b;
			r = (int)(255.0 *
					  pow(angband_color_table[i][1] / 255.0, 1.0 / gamma));
			g = (int)(255.0 *
					  pow(angband_color_table[i][2] / 255.0, 1.0 / gamma));
			b = (int)(255.0 *
					  pow(angband_color_table[i][3] / 255.0, 1.0 / gamma));
			palette[i] = (b << 24) | (g << 16) | (r << 8);
			a_palette[i][1] = angband_color_table[i][1];
			a_palette[i][2] = angband_color_table[i][2];
			a_palette[i][3] = angband_color_table[i][3];
		}
	}

	cursor_rgb = palette[CURSOR_COLOUR];

	/* Cache the ZapRedraw palette for it */
	b.r_workarea = workspace;
	if (b.r_mode != screen_mode)
		SWI(2, 0, SWI_ZapRedraw_ReadVduVars, 0, &b);
	SWI(5, 0, SWI_ZapRedraw_CreatePalette, 2, &b, palette, zpalette, 256);
}




/*--------------------------------------------------------------------------*/

/*
 | Functions for dealing with the SaveBox
 */

/*
 | Create the window and claim various handlers for it
 */
static void init_save_window(void)
{
	/* Create the window */
	save_box = Window_Create("save", template_TITLEMIN);

	/* Set the file icon */
	Icon_printf(save_box, SAVE_ICON, "file_%03x", vfiletype);

}
#endif /* FULLSCREEN_ONLY */

/*
 | Hack: can't use Str.h without defining HAS_STRICMP.  Rather than
 | require that the header files are altered we simply provide our
 | own strnicmp() function.
 */
static int my_strnicmp(const char *a, const char *b, int n)
{
	int i;

	n--;

	for (i = 0; i <= n; i++)
	{
		if (tolower((unsigned char)a[i]) != tolower((unsigned char)b[i]))
			return tolower((unsigned char)a[i]) - tolower((unsigned char)b[i]);

		if (a[i] == '\0')
			break;
	}

	return 0;
}

#ifndef FULLSCREEN_ONLY
/*
 | This is the handler called when a 'save' occurrs.
 | All it does is to update the game's own savefile setting and
 | then (if possible) save the character.
 */
static BOOL SaveHnd_FileSave(char *filename, void *ref)
{
	char old_savefile[1024];

	/* Hack: refuse to save if the character is dead */
	if (PDEADCHK)
	{
		Msgs_Report(0, "err.cheat");
		return FALSE;
	}

	/* Hack: disallow saves to * */
	if (!my_strnicmp("", filename, 12))
	{
		Msgs_Report(0, "err.scrap");
		return FALSE;
	}

	/* Preserve the old path, in case something goes wrong... */
	strcpy(old_savefile, savefile);

	/* Set the new path */
	strcpy(savefile, unixify_name(filename));

	/* Try a save (if sensible) */
	if (game_in_progress && character_generated)
	{
		if (!save_player())
		{
			Msgs_Report(0, "err.save", filename);
			strcpy(savefile, old_savefile);
			return FALSE;		/* => failure */
		}
	}

	/* Set the pathname icon */
	Icon_printf(save_box, SAVE_PATH, "%s", riscosify_name(savefile));

	/* Kill the menu */
	Wimp_CreateMenu((menu_block *) - 1, -1, -1);

	return TRUE;				/* => Success */
}



/*
 | Init the handlers for the savebox (eg. as a result of a menuwarning
 | being received for the savebox)
 */

static void init_savehandlers(void)
{
	if (saveblk)
	{
		Save_ReleaseSaveHandlers(saveblk);
		saveblk = 0;
	}

	saveblk = Save_InitSaveWindowHandler(save_box,	/* Window handle */
										 TRUE,	/* it's part of a menu */
										 FALSE,	/* not a window */
										 FALSE,	/* Don't auto release the handlers */
										 SAVE_ICON,	/* The file icon */
										 SAVE_OK,	/* The OK icon */
										 SAVE_CANCEL,	/* The cancel icon */
										 SAVE_PATH,	/* The pathname icon */
										 SaveHnd_FileSave,	/* Handler to "save the file" */
										 NULL,	/* No RAM transfer support */
										 NULL,	/* No 'result handler' */
										 100 << 10,	/* Est. size (irelevant anyway) */
										 vfiletype,	/* filetype (irelevant) */
										 NULL	/* ref */
		);
}


/*
 | Handle a MenuWarning message for the savebox
 */
static BOOL Hnd_SaveWarning(event_pollblock * pb, void *ref)
{
	os_error *e;

	init_savehandlers();

	/* Set the pathname */
	Icon_printf(save_box, SAVE_PATH, "%s", riscosify_name(savefile));

	/* Open the submenu */
	e = Wimp_CreateSubMenu((menu_block *) save_box,
						   pb->data.message.data.menuwarn.openpos.x,
						   pb->data.message.data.menuwarn.openpos.y);

	if (e)
	{
		Msgs_ReportFatal(0, "err.swi", __LINE__, e->errmess);
	}

	return TRUE;
}


/*--------------------------------------------------------------------------*/


/*
 | Initialise the r_data array
 | Mainly we just set up the line offset pointers and make sure that the
 | lines themselves are 'safe' by writing end-of-line codes to them.
 */
static void initialise_r_data(void)
{
	int *lo = (int *)r_data;
	char *ld;
	int j;
	for (j = 0; j < 24; j++)
	{
		lo[j] = 25 * 4 + (80 * 5 + 4) * j;	/* Offset of line */
		ld = r_data + lo[j];
		*ld++ = 0;				/* 0,2 ==     */
		*ld = 2;				/* end of line */
	}
	lo[j] = 0;					/* Terminate line index */
}



/*
 | Create the r_data array for a term
 | This is typically quite fast (1ms or so on a RPC700)
 | so we don't bother caching r_data for each term or using the
 | 'frosh' concept.
 */
static void make_r_data(term_data *t)
{
	char **c = t->t.old->c;	/* char array [24][80] */
	byte **a = t->t.old->a;	/* attr array [24][80] */
	char *o;
	int i, j, cf;

/* New code: */

	o = r_data + 25 * 4;		/* First byte of r_data after line index */

	if (force_mono)
	{
		for (j = 0; j < 24; j++)
		{
			/* Set up the line offset entry */
			((int *)r_data)[j] = o - r_data;

			for (i = 0; i < 80; i++)
				*o++ = a[j][i] != TERM_DARK ? c[j][i] : ' ';
			/* 0,2 => end of line */
			*o++ = 0;
			*o++ = 2;
		}
	}
	else
	{
		for (j = 0; j < 24; j++)
		{
			/* Set up the line offset entry */
			((int *)r_data)[j] = o - r_data;

			/* Each line starts in white */
			cf = TERM_WHITE;

			for (i = 0; i < 80; i++)
			{
				if (a[j][i] != cf)
				{
					/* 0,6 => change FG */
					*o++ = 0;
					*o++ = 6;
					cf = *o++ = a[j][i];
				}
				*o++ = c[j][i];
			}
			/* 0,2 => end of line */
			*o++ = 0;
			*o++ = 2;
		}
	}
}


/*
 | Set up 'zrb' for the current screen mode.
 */
static void set_up_zrb_for_mode(void)
{
	static char work_area[4096];
	zrb.r_workarea = work_area;
	zrb.r_palette = zpalette;
	zrb.r_linesp = 0;
	zrb.r_for = TERM_WHITE;
	zrb.r_bac = 0;
	zrb.r_data = r_data;
	SWI(2, 0, SWI_ZapRedraw_ReadVduVars, 0, &zrb);
}



/*
 | Set up the ZapRedrawBlock ready to redraw term 't'
 | (caches the r_data as part of the process)
 */
static void set_up_zrb(term_data *t)
{
	int fw, fh;

	zrb.r_flags.value = 0;

	/* Set font info up */
	fw = t->font->w;
	fh = t->font->h;
	SWI(4, 4, SWI_ZapRedraw_CachedCharSize, zrb.r_bpp, 0, fw, fh,
		NULL, NULL, &(zrb.r_cbpl), &(zrb.r_cbpc));
	zrb.r_caddr = (void *)(((int)t->font->bpp_n) - (t->font->f * zrb.r_cbpc));

	zrb.r_charw = fw;			/* Character size in pixels */
	zrb.r_charh = fh;

	if (t->font == SYSTEM_FONT)
		zrb.r_flags.bits.double_height = screen_eig.y == 1;
	else
		zrb.r_flags.bits.double_height = 0;

	make_r_data(t);				/* Cache the r_data */
}





static void redraw_window(window_redrawblock * rb, BOOL *more, term_data *t)
{
	int cx, cy, cw, ch;

	/* set GCOL for cursor colour */
	if (t->cursor.visible)
	{
		cw = zrb.r_charw << screen_eig.x;
		ch = -(zrb.r_charh << screen_eig.y);
		if (zrb.r_flags.bits.double_height)
		{
			ch *= 2;
		}
		cx = t->cursor.pos.x * cw;
		cy = t->cursor.pos.y * ch;
		cx += (rb->rect.min.x - rb->scroll.x);
		cy += (rb->rect.max.y - rb->scroll.y);
		cw -= (1 << screen_eig.x);
		ch += (1 << screen_eig.y);
		cy -= (1 << screen_eig.y);
	}

	while (*more)
	{
		SWI(2, 0, SWI_ZapRedraw_GetRectangle, rb, &zrb);
		SWI(2, 0, SWI_ZapRedraw_RedrawArea, NULL, &zrb);
		if (t->cursor.visible)
		{
			ColourTrans_SetGCOL(cursor_rgb, 0, 0);
			GFX_Move(cx, cy);
			GFX_DrawBy(cw, 0);
			GFX_DrawBy(0, ch);
			GFX_DrawBy(-cw, 0);
			GFX_DrawBy(0, -ch);
		}
		Wimp_GetRectangle(rb, more);
	}
}





static BOOL Hnd_Redraw(event_pollblock * pb, void *ref)
{
	term_data *t = (term_data *)ref;
	window_redrawblock rb;
	BOOL more;

	rb.window = t->w;
	Wimp_RedrawWindow(&rb, &more);

	set_up_zrb(t);

	redraw_window(&rb, &more, t);

	return TRUE;
}





static void refresh_window(term_data *t)
{
	window_redrawblock rb;
	BOOL more;
	int fw, fh;

	if ((t->changed_box.min.x >= t->changed_box.max.x) ||
		(t->changed_box.min.y >= t->changed_box.max.y))
		return;

	set_up_zrb(t);

	fw = zrb.r_charw << screen_eig.x;
	fh = -(zrb.r_charh << screen_eig.y);
	if (zrb.r_flags.bits.double_height)
	{
		fh *= 2;
	}

	rb.window = t->w;
	rb.rect.min.x = fw * t->changed_box.min.x;
	rb.rect.max.x = fw * t->changed_box.max.x;

	rb.rect.max.y = fh * t->changed_box.min.y;
	rb.rect.min.y = fh * t->changed_box.max.y;

	Wimp_UpdateWindow(&rb, &more);
	redraw_window(&rb, &more, t);

	t->changed_box.min.x = t->changed_box.min.y = 255;
	t->changed_box.max.x = t->changed_box.max.y = 0;
}



static void refresh_windows(void)
{
	int i;
	window_info info;
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		info.window = data[i].w;
		Wimp_GetWindowInfo(&info);
		if (info.block.flags.data.open)
			refresh_window(&(data[i]));
	}
}


/*
 | Set the size of a window.
 | If the window grows but has no scroll bars then it is re-sized to
 | the new extent.  If it shrinks then it is resized regardless.
 |
 | If the window isn't open then it is opened behind the backwindow,
 | resized and then closed again...  I /did/ have a reason for doing this
 | rather than simply recreating the window at the new size, but for the
 | life of me I can't remember what it was...
 */
static void set_window_size(window_handle w, int width, int height)
{
	window_state ws;
	int reclose;
/*
 *  int cw,ch;
 */

	Wimp_GetWindowState(w, &ws);
	Window_SetExtent(w, 0, -height, width, 0);

	reclose = !ws.flags.data.open;
	if (!(ws.flags.value & (0xf << 27)))
	{
		if (reclose)
		{
			ws.openblock.behind = -3;
			Wimp_OpenWindow(&(ws.openblock));
		}
		/* Removed - caused "pixel creep" :)
		 *  cw = ws.openblock.screenrect.max.x;
		 *  ch = ws.openblock.screenrect.max.y;
		 *  cw -= ws.openblock.screenrect.min.x;
		 *  ch -= ws.openblock.screenrect.min.y;
		 *  ws.openblock.screenrect.min.x -= ((width-cw)/2)-(1<w, fw, fh);
}



















static BOOL Hnd_Caret(event_pollblock * pb, void *ref)
{
	if (ref)
		got_caret = 1;
	else
		got_caret = 0;
	return TRUE;
}




/*
 | Attach a (named) font to the specified term.
 | If 'font' is NULL then the system font is attached.
 | The bpp_n data is calculated if necessary
 | returns:
 |	1 => the font was attached OK
 |	0 => the system font was substituted
 */
static int attach_font_to_term(term_data *t, char *font)
{
	if (t->font != SYSTEM_FONT)
	{
		lose_font(t->font);
	}
	if (font)
	{
		t->font = find_font(font);
	}
	if (!t->font)
	{
		t->font = SYSTEM_FONT;
		if (font)
		{
			Msgs_Report(1, "err.font_l", font);
		}
	}
	else
	{
		if (!t->font->bpp_n)
		{
			lose_font(t->font);
			t->font = SYSTEM_FONT;
			if (font)
			{
				Msgs_Report(1, "err.font_c", font);
			}
		}
	}
	resize_term_for_font(t);
	return !(t->font == SYSTEM_FONT);
}




/*--------------------------------------------------------------------------*/



/*
 | Create a menu of all the (probable!) fonts in the specified location
 | NB: Any file of type 'data' is considered a font.
 |
 | Subdirectories are recursively searched.
 |
 | 1.10 - Uses $FontPaths to get a (space separated) list of paths
 | to search.  For each path name, the menu text will be the name and the
 | path searched will be $$FontPath
 |
 | Eg. (for angband):
 | Angband$FontPaths Zap Angband
 | Angband$Zap$FontPath ZapFonts:
 | Angband$Angband$FontPath Angband:xtra.fonts.
 */
static void make_font_menu(void)
{
	char *t;
	char buffer[260];
	char menu_buffer[260];
	int paths;
	int i;
	unsigned int max_width;
	const char *path[64];	/* pointers to path names */
	menu_item *mi;

	font_menu = NULL;

	/* Get the path (ie. dir) to look under */
	t = getenv(RISCOS_VARIANT "$FontPaths");

	/* Hack: cope if the path isn't set */
	if (!t)
	{
		t = "";
	}

	strcpy(buffer, t);

	/*
	   | Count how many paths there are, build an array of pointers to them
	   | and terminate them in the buffer
	 */
	paths = 1;					/* including the system font fake path '' */
	for (t = buffer; *t; t++)
	{
		if (*t == ' ')
		{
			*t = 0;
		}
		else
		{
			if (t == buffer || !t[-1])
			{
				path[paths] = t;
				paths++;
			}
		}
	}

	/*
	   | Create the menu
	 */
	path[0] = SYSTEM_FONT->name;

	font_menu = f_malloc(sizeof(menu_block) + paths * sizeof(menu_item));
	if (!font_menu)
	{
		core("Out of memory (building font menu)");
	}
	memset(font_menu, 0, sizeof(menu_block) + paths * sizeof(menu_item));

	strncpy(font_menu->title, "Fonts", 12);
	font_menu->titlefore = 7;
	font_menu->titleback = 2;
	font_menu->workfore = 7;
	font_menu->workback = 0;
	font_menu->height = 44;
	font_menu->gap = 0;
	max_width = strlen(font_menu->title);

	mi = (menu_item *) (font_menu + 1);

	for (i = 0; i < paths; i++)
	{
		mi[i].submenu.value = -1;
		mi[i].iconflags.data.text = 1;
		mi[i].iconflags.data.filled = 1;
		mi[i].iconflags.data.foreground = 7;
		mi[i].iconflags.data.background = 0;
		strncpy(mi[i].icondata.text, path[i], 12);
		if (strlen(mi[i].icondata.text) > max_width)
			max_width = strlen(mi[i].icondata.text);
	}
	font_menu->width = (max_width + 2) * 16;
	mi[i - 1].menuflags.data.last = 1;

	/*
	   | Hack: add a dotted line after the system font entry if appropriate
	 */
	if (paths > 1) mi[0].menuflags.data.dotted = 1;

	/*
	   | Iterate over the paths, building the appropriate submenus
	 */
	for (i = 1; i < paths; i++)
	{
		menu_ptr sub_menu = NULL;

		sprintf(menu_buffer, "%s$%s$FontPath", RISCOS_VARIANT, path[i]);
		t = getenv(menu_buffer);
		/* Hack: cope if the path isn't defined */
		if (!t)
		{
			t = "";
		}

		/* Fudge so that the fontpath can be a path, not just a dir. */
		strcpy(menu_buffer, t);
		for (t = menu_buffer; *t > ' '; t++)
			;
		if (t[-1] == '.')
		{
			t--;
		}
		*t = 0;

		/* Build the menu.  Don't bother if the path variable was empty */
		if (*menu_buffer)
			sub_menu = make_zfont_menu(menu_buffer);

		if (!sub_menu)
		{
			mi[i].iconflags.data.shaded = 1;
		}
		else
		{
			mi[i].submenu.menu = sub_menu;
			/* Override the title of the 'root' sub-menu */
			strncpy(sub_menu->title, path[i], 12);
			/* Add the submenu to the main menu */
		}
	}

	return;
}

/* ----------------------------------------------- musus, xxxx-xx-xx ---
 * Create and set up the infobox.
 * --------------------------------------------------------------------- */
static void create_info_box(void)
{
	info_box = Window_Create("info", template_TITLEMIN);
	Icon_printf(info_box, 0, "%s %s", VARIANT, VERSION);
	Icon_SetText(info_box, 2, AUTHORS);
	Icon_SetText(info_box, 3, PORTERS);
	Icon_SetText(info_box, 7, PORTVERSION);

	return;
}

/*
 | Create the various menus
 */
static void init_menus(void)
{
	char buffer1[256];
	char buffer2[32];
	char *o;

	create_info_box();			/* For the Info> entries */
	make_font_menu();			/* Make the fonts menu */

	Msgs_Lookup("menu.ibar:Info|>Save As|Full screen,Gamma correction,Sound,"
				"Windows|Save choices|Quit (& save)", buffer1, 256);
	ibar_menu = Menu_New(VARIANT, buffer1);
	if (!ibar_menu) core("Can't create Iconbar menu!");

	Msgs_Lookup("menu.term:Info|>Save As|Font,Windows", buffer1, 256);
	term_menu = Menu_New(VARIANT, buffer1);
	if (!term_menu) core("Can't create Term menu!");

#ifndef OLD_TERM_MENU
	o = buffer1;
	o += sprintf(buffer1, "%s|", VARIANT);
	o += sprintf(o, "%s,%s,%s|", angband_term_name[1], angband_term_name[2],
				 angband_term_name[3]);
	sprintf(o, "%s,%s,%s,%s", angband_term_name[4], angband_term_name[5],
			angband_term_name[6], angband_term_name[7]);
#else
	Msgs_printf(buffer1, "menu.windows:%s|Term-1 (Mirror),Term-2 (Recall),"
				"Term-3 (Choice)|Term-4,Term-5,Term-6,Term-7", VARIANT);
#endif
	Msgs_Lookup("menu.winT:Windows", buffer2, 32);
	wind_menu = Menu_New(buffer2, buffer1);
	if (!wind_menu)
	{
		core("Can't create Windows menu!");
	}

	/* Now attach the various submenus to where they belong */
	Menu_AddSubMenu(ibar_menu, IBAR_MENU_INFO, (menu_ptr) info_box);
	Menu_AddSubMenu(ibar_menu, IBAR_MENU_GAMMA, (menu_ptr) gamma_win);
	Menu_AddSubMenu(ibar_menu, IBAR_MENU_SOUND, (menu_ptr) sound_win);
	Menu_AddSubMenu(ibar_menu, IBAR_MENU_WINDOWS, (menu_ptr) wind_menu);
	Menu_AddSubMenu(term_menu, TERM_MENU_INFO, (menu_ptr) info_box);
	Menu_AddSubMenu(term_menu, TERM_MENU_WINDOWS, wind_menu);

	/* Add the savebox */
	Menu_Warn(ibar_menu, IBAR_MENU_SAVE, TRUE, Hnd_SaveWarning, NULL);
	Menu_Warn(term_menu, TERM_MENU_SAVE, TRUE, Hnd_SaveWarning, NULL);

	if (font_menu)
		/* add the submenu */
		Menu_AddSubMenu(term_menu, TERM_MENU_FONT, font_menu);
	else
		/* If the font menu is buggered, shade its entry */
		/* unticked, shaded */
		Menu_SetFlags(term_menu, TERM_MENU_FONT, FALSE, TRUE);
}




static void grab_caret(void)
{
	caret_block cb;
	cb.window = data[0].w;
	cb.icon = -1;
	cb.height = 1 << 25;		/* Invisible */
	Wimp_SetCaretPosition(&cb);
}




/*
 | (Recursively) clear all ticks from the specified menu
 */
static void clear_all_menu_ticks(menu_ptr mp)
{
	menu_item *mi = (menu_item *) (mp + 1);

	do
	{
		if (mi->menuflags.data.ticked)
			mi->menuflags.data.ticked = 0;
		if (mi->submenu.value != -1)
			clear_all_menu_ticks(mi->submenu.menu);
		mi++;
	}
	while (mi[-1].menuflags.data.last != 1);
}






/*
 | Set the font menu's ticks to match the specifed font name.
 |
 | fm is the (sub) menu to scan down (recursing into it's submenus (if any))
 | fn is the font name to match
 | prefix is the menu text to be prepended to the menu entries due to
 | previous menus (eg. "08x16" will cause fn="08x16.fred" to match menu
 | entry "fred".
 |
 | NB: recursive.
 |
 */

static void set_font_menu_ticks(menu_ptr fm, char *fn, const char *prefix)
{
	char buffer[260];
	char *b_leaf;	/* -> menu 'leaf' text in buffer */
	int pl;	/* prefix string length */
	menu_item *mi = (menu_item *) (fm + 1);

	strcpy(buffer, prefix);
	pl = strlen(buffer);
	b_leaf = buffer + pl;

	do
	{
		/* Check for (substring) match */
		strncpy(b_leaf, mi->icondata.text, 12);

		/* Is it a sub-menu? */
		if (mi->submenu.value == -1)
		{
			/* No - must be an exact match */
			mi->menuflags.data.ticked = !strcmp(buffer, fn);
		}
		else
		{
			/* Yes - must be a partial match (with a dot on :) */
			strcat(b_leaf, ".");
			mi->menuflags.data.ticked =
				!strncmp(buffer, fn, pl + strlen(b_leaf));
			if (mi->menuflags.data.ticked)
				set_font_menu_ticks(mi->submenu.menu, fn, buffer);
			else
				clear_all_menu_ticks(mi->submenu.menu);
		}

		/* Next item */
		mi++;
	}
	while (mi[-1].menuflags.data.last != 1);	/* Until finished */
}











/*
 | Set ticks, etc. in the term_menu to reflect the current state of the
 | term 't'
 */
static void set_up_term_menu(term_data *t)
{
	int i;
	menu_ptr mp;
	menu_item *mi;
	window_state ws;

	/* First of all, set up menu title to be the term's title */
	strncpy(term_menu->title, t->name, 12);

	/* Now set the ticks in the Windows> submenu (cuz it's easy) */
	mp = wind_menu;				/* Windows submenu */
	mi = (menu_item *) (mp + 1);	/* First entry */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		Wimp_GetWindowState(data[i].w, &ws);
		mi[i].menuflags.data.ticked = ws.flags.data.open;
	}

	/*
	   | Now, the tricky bit:  find out which font is selected in this
	   | term and tick it in the menu.  Untick all the rest.
	 */
	set_font_menu_ticks(font_menu, t->font->name, "");

	/* Shade the 'Save>' entry if saving isn't possible (yet) */
	if (game_in_progress && character_generated)
		Menu_SetFlags(term_menu, TERM_MENU_SAVE, 0, PDEADCHK);
	else
		Menu_SetFlags(term_menu, TERM_MENU_SAVE, 0, TRUE);

}



/*
 | Generic 'click' handler for windows - turns a drag on the window
 | into a move-window style drag.
 */
static BOOL Hnd_Click(event_pollblock * pb, void *ref)
{
	if (pb->data.mouse.button.data.dragselect ||
		pb->data.mouse.button.data.dragadjust)
	{
		drag_block b;
		b.window = pb->data.mouse.window;
		b.screenrect.min.x = b.screenrect.min.y = 0;
		b.screenrect.max.x = screen_size.x;
		b.screenrect.max.y = screen_size.y;
		b.type = drag_MOVEWINDOW;
		Wimp_DragBox(&b);
	}

	return TRUE;
}



/*
 | Handle a click on a Term window.
 */
static BOOL Hnd_TermClick(event_pollblock * pb, void *ref)
{
	term_data *t = (term_data *)ref;

	if (pb->data.mouse.button.data.menu)
	{
		menu_term = t;
		set_up_term_menu(t);
		Menu_Show(term_menu, pb->data.mouse.pos.x - 32,
				  pb->data.mouse.pos.y + 32);
	}
	else
	{
		grab_caret();
		Hnd_Click(pb, ref);
	}

	return TRUE;
}

#endif /* FULLSCREEN_ONLY */



static void mark_ood(term_data *t, int minx, int miny, int maxx, int maxy)
{
	if (t->changed_box.min.x > minx)
		t->changed_box.min.x = minx;
	if (t->changed_box.max.x < maxx)
		t->changed_box.max.x = maxx;
	if (t->changed_box.min.y > miny)
		t->changed_box.min.y = miny;
	if (t->changed_box.max.y < maxy)
		t->changed_box.max.y = maxy;
}


#ifndef FULLSCREEN_ONLY

/* Check for an event (ie. key press) */
static errr Term_xtra_acn_check(void)
{
	static int last_poll = 0;
	unsigned int curr_time;
	int bh, bl;

	/*
	   | Only poll the wimp if there's something in the keyboard buffer
	   | or every 10cs.  This is presumably so that we process as many
	   | keypresses as possible before any other application gets a go.
	 */

	/* Check the kbd buffer */
	SWI(3, 3, SWI_OS_Byte, 128, 255, 0, /**/ NULL, &bl, &bh);
	bl = (bl & 0xff) + (bh << 8);

	/* Check how long it is since we last polled */
	curr_time = Time_Monotonic();

	if ((bl > 0 && got_caret) || ((curr_time - last_poll) > 9))
	{
		last_poll = curr_time;
		Stop_Hourglass;
		Event_Poll();
		Start_Hourglass;
	}

	/*
	   | This allows the user to interrupt the borg.
	 */
	if (key_pressed) return key_pressed = 0;

	return 1;
}


/*
 | Wait for an event (ie. keypress)
 | Note that we idle poll once a second to allow us to implement the
 | alarm system.
 */
static errr Term_xtra_acn_event(void)
{
	Stop_Hourglass;

	while (!key_pressed && !fullscreen_font)
	{
		Event_PollIdle(100);
	}
	Start_Hourglass;

	return key_pressed = 0;
}



/* React to changes (eg. palette change) */
static errr Term_xtra_acn_react(void)
{
	int c;

	cache_palette();

	/* Mark the entirety of each window as out of date */
	for (c = 0; c < MAX_TERM_DATA; c++)
		mark_ood(&data[c], 0, 0, 80, 24);

	/* Force a redraw of the windows */
	refresh_windows();

	/* Success */
	return 0;
}



/* Do various things to a term */
static errr Term_xtra_acn(int n, int v)
{
	term_data *t = (term_data *)Term;

	switch (n)
	{
		case TERM_XTRA_CLEAR:	/* Clear the Term */
			/*for ( i=0; ihgt; i++ )
			   t->froshed[i] = 1; */
			mark_ood(t, 0, 0, Term->wid, Term->hgt);
			/*refresh_window( t ); - NB: Term isn't actually cleared yet! */
			/* Success */
			return 0;

		case TERM_XTRA_EVENT:	/* Wait/check for an event */
			if (v)
				return Term_xtra_acn_event();
			else
				return Term_xtra_acn_check();

		case TERM_XTRA_BORED:	/* Bored */
			return Term_xtra_acn_check();

		case TERM_XTRA_FLUSH:	/* Flush input */
			if (got_caret)
			{
				/* 1.21 - Hack: wait until no keys are pressed */
				if (hack_flush)
					for (v = 0; v != 0xff;)
						SWI(1, 2, SWI_OS_Byte, 122, 0, &v);
				SWI(3, 0, SWI_OS_Byte, 21, 0, 0);	/* Flush Kbd buffer */
			}
			return 0;

		case TERM_XTRA_FRESH:	/* Flush output */
			refresh_window(t);
			return 0;

		case TERM_XTRA_FROSH:	/* Ensure line 'v' is plotted */
			/* Doesn't do anything */
			return 0;

		case TERM_XTRA_SHAPE:	/* Set cursor visibility */
			t->cursor.visible = v ? TRUE : FALSE;
			mark_ood(t, t->cursor.pos.x, t->cursor.pos.y,
					 t->cursor.pos.x + 1, t->cursor.pos.y + 1);
			refresh_window(t);	/* needed? */
			return 0;

		case TERM_XTRA_NOISE:	/* Make a beep */
			Sound_SysBeep();
			return 0;

		case TERM_XTRA_REACT:	/* React to, eg. palette changes */
			return Term_xtra_acn_react();

		case TERM_XTRA_DELAY:	/* Delay for 'v' ms */
			if (v > 0)
			{
				unsigned int start = Time_Monotonic();
				v = (v + 5) / 10;	/* Round to nearest cs */
				GFX_Wait();
				while ((Time_Monotonic() - start) < v)
					;
			}
			return 0;

		case TERM_XTRA_SOUND:	/* Play a sound :) */
			if (enable_sound)
			{
				play_sound(v);
			}
			return 0;
			
		/* Subdirectory scan */
		case TERM_XTRA_SCANSUBDIR:
		{
		    filing_dirdata directory;
		    filing_direntry *entry;

			scansubdir_max = 0;

			if (Filing_OpenDir(riscosify_name(scansubdir_dir), &directory, sizeof(filing_direntry), readdirtype_DIRENTRY) != NULL)
			{
			  Error_Report(0, "Couldn't open directory \"%s\"", riscosify_name(scansubdir_dir));
			  return 0;
			}

			while ((entry = Filing_ReadDir(&directory)) != NULL)
			{
				if (entry->objtype == filing_DIRECTORY)
				{    
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(entry->name);
					++scansubdir_max;
				}
			}

			Filing_CloseDir(&directory);

			return 0;
		}

		/* Return current "time" in milliseconds */
		case TERM_XTRA_GET_DELAY:
				{
			Term_xtra_long = Time_Monotonic() * 100;

			return 0;
				}

		/* Rename main window */
		case TERM_XTRA_RENAME_MAIN_WIN:
		{
			Window_SetTitle(data[0].w, angband_term_name[0]);
			return 0;
		}

		default:
			return 1;			/* Unsupported */
	}
}



/* Move (but don't necessarily display) the cursor */
static errr Term_curs_acn(int x, int y)
{
	term_data *t = (term_data *)Term;

	if (t->cursor.visible)
		mark_ood(t, t->cursor.pos.x, t->cursor.pos.y,
				 t->cursor.pos.x + 1, t->cursor.pos.y + 1);

	t->cursor.pos.x = x;
	t->cursor.pos.y = y;

	if (t->cursor.visible)
		mark_ood(t, t->cursor.pos.x, t->cursor.pos.y,
				 t->cursor.pos.x + 1, t->cursor.pos.y + 1);

	return 0;
}



/*
 | NB: these two are very simple since we use the Term's contents
 | directly to generate the r_data for ZapRedraw.
 */

/* Erase 'n' characters at (x,y) */
static errr Term_wipe_acn(int x, int y, int n)
{
	mark_ood((term_data *)Term, x, y, x + n, y + 1);
	return 0;
}

/* Write 'n' characters from 's' with attr 'a' at (x,y) */
static errr Term_text_acn(int x, int y, int n, byte a, cptr s)
{
	mark_ood((term_data *)Term, x, y, x + n, y + 1);
	return 0;
}

#endif /* FULLSCREEN_ONLY */


/* Initialise one of our terms */
static void Term_init_acn(term *t)
{
	term_data *term = (term_data *)t;

	/* Ludicrous changed box settings :) */
	term->changed_box.min.x = 256;
	term->changed_box.min.y = 256;
	term->changed_box.max.x = 0;
	term->changed_box.max.y = 0;
}



static void term_data_link(term_data *td, int k)
{
	term *t = &(td->t);

	/* Initialise the term */
	term_init(t, 80, 24, k);

	/* Set flags and hooks */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Experiment (FS mode requires them) */
	t->always_text = TRUE;
	t->never_frosh = TRUE;
	/* Experiment (FS mode requires them) */
              
#ifdef FULLSCREEN_ONLY  
	t->wipe_hook  = Term_wipe_acnFS;
	t->xtra_hook  = Term_xtra_acnFS;
	t->curs_hook  = Term_curs_acnFS;
	t->text_hook  = Term_text_acnFS;
#else
	t->init_hook = Term_init_acn;
	t->xtra_hook = Term_xtra_acn;
	t->wipe_hook = Term_wipe_acn;
	t->curs_hook = Term_curs_acn;
	t->text_hook = Term_text_acn;
	t->user_hook = Term_user_acn;
#endif /* FULLSCREEN_ONLY */

	t->data = td;

	Term_activate(t);
}


#ifndef FULLSCREEN_ONLY

/* Open default windows (ie. as set in choices) at the appropriate sizes */
static void show_windows(void)
{
	int i;
	for (i = MAX_TERM_DATA; i-- > 0;)
	{
		if (!data[i].unopened)
		{
			if (data[i].def_open)
				Window_Show(data[i].w, open_WHEREVER);
		}
		else
		{
			if (data[i].def_open)
			{
				window_openblock ob;
				ob.window = data[i].w;
				ob.screenrect = data[i].def_pos;
				ob.scroll = data[i].def_scroll;
				ob.behind = -1;
				Wimp_OpenWindow(&ob);
				data[i].unopened = 0;
			}
		}
	}
}


/*
 | 'ref' is used to indicate whether this close is being forced by some other
 | part of the code (eg. the Windows> submenu code).  This is used to modify
 | the 'adjust doesn't close other terms' behavior.
 */

static BOOL Hnd_MainClose(event_pollblock * pb, void *ref)
{
	int i;
	window_state ws;
	mouse_block mb;

	/* New in 1.08: don't close other Terms if closed with adjust */
	Wimp_GetPointerInfo(&mb);
	if (ref || mb.button.data.adjust)
	{
		Wimp_CloseWindow(data[0].w);
	}
	else
	{
		/* Close all the terms, but mark the open ones as 'def_open' */
		for (i = 0; i < MAX_TERM_DATA; i++)
		{
			Wimp_GetWindowState(data[i].w, &ws);
			if (!ws.flags.data.open)
			{
				data[i].def_open = 0;
			}
			else
			{
				Wimp_CloseWindow(data[i].w);
				data[i].def_open = 1;
			}
		}
	}

	return TRUE;
}


static BOOL Hnd_PaletteChange(event_pollblock * pb, void *ref)
{
	cache_palette();
	return TRUE;
}



static BOOL Hnd_ModeChange(event_pollblock * pb, void *ref)
{
	int i;
	Screen_CacheModeInfo();
	set_up_zrb_for_mode();		/* (re)set up the redraw block */
	cache_palette();			/* (re)cache the palette */
	cache_fonts();				/* (re)cache the fonts */
	/* Enforce sizes (eg. if screen_eig.y has changed) */
	for (i = 0; i < MAX_TERM_DATA; i++)
		resize_term_for_font(&(data[i]));
	return TRUE;
}




static BOOL Hnd_Keypress(event_pollblock * pb, void *ref)
{
	static const char hex[] = "0123456789ABCDEF";
	int c = pb->data.key.code;
	/* Check whether this key was pressed in Term 0 */
	if (pb->data.key.caret.window == data[0].w)
	{
		switch (c)
		{
			case keycode_F12:
			case keycode_SHIFT_F12:
			case keycode_CTRL_F12:
			case keycode_CTRL_SHIFT_F12:
				/* Never intercept these */
				break;

			case 27:			/* handle escape specially */
				if (Kbd_KeyDown(inkey_CTRL))
				{
					ack_alarm();
					return TRUE;
				}

			/* Send everything else onto the Term package */
			default:  
				/* Take care of "special" keypresses */
				switch (c)
				{
					case keycode_TAB:
					{
						c = '\t';
						break;
					}
                   
					case keycode_PAGEUP:
					{
						c = '9';
						break;
					}

					case keycode_PAGEDOWN:
					{
						c = '3';
						break;
					}         

					case keycode_COPY:
					{
						c = '1';
						break;
					}          

					case keycode_HOME:
					{
						c = '7';
						break;
					}
				}
				/* Pass to the angband engine */
				/* Allow shift & ctrl to modify the keypad keys */
				if (c >= '0' && c <= '9')
				{
					kbd_modifiers m = Kbd_GetModifiers(FALSE);
					if (m.shift)
					{
						c |= 0x800;
					}
					if (m.ctrl)
					{
						c |= 0x400;
					}
					/* Could maybe add ALT as 0x1000 ??? */
				}

				/* Keys >255 have to be send as escape sequences (31=escape) */
				if (c > 255 || c == 31)
				{
					Term_keypress(31);
					Term_keypress(hex[(c & 0xf00) >> 8]);
					Term_keypress(hex[(c & 0x0f0) >> 4]);
					Term_keypress(hex[(c & 0x00f)]);
					c = 13;
				}
				Term_keypress(c);
				key_pressed = 1;
				/*if ( c==27 ) { escape_pressed = 1; } */
				return TRUE;
		}
	}

	Wimp_ProcessKey(c);
	return TRUE;
}


/*--------------------------------------------------------------------------*/
/* Gamma correction window stuff											*/
/*--------------------------------------------------------------------------*/

static void redraw_gamma(window_redrawblock * rb, BOOL *more)
{
	int i, y, x, h, w;
	int bx, by;
	int dither;

	bx = Coord_XToScreen(GC_XOFF, (convert_block *) & (rb->rect));
	by = Coord_YToScreen(GC_YOFF, (convert_block *) & (rb->rect));

	h = GC_HEIGHT / 4;
	w = GC_WIDTH / 16;

	x = bx;

	while (*more)
	{
		for (i = 0; i < 16; i++)
		{
			y = by;
			for (dither = 0; dither < 2; dither++)
			{
				/* Solid block: */
				ColourTrans_SetGCOL(palette[i], dither << 8, 0);
				GFX_RectangleFill(x, y, w, -h);
				y -= h;
				/* Dot on black: */
				ColourTrans_SetGCOL(palette[0], dither << 8, 0);
				GFX_RectangleFill(x, y, w, -h);
				ColourTrans_SetGCOL(palette[i], dither << 8, 0);
				GFX_RectangleFill(x + (w / 2) - 2, y - (h / 2), 2, 2);
				y -= h;
			}
			x += w;
		}
		Wimp_GetRectangle(rb, more);
	}
}


static void update_gamma(void)
{
	window_redrawblock rb;
	BOOL more;

	rb.window = gamma_win;
	rb.rect.min.x = GC_XOFF;
	rb.rect.min.y = GC_YOFF - GC_HEIGHT;
	rb.rect.max.y = GC_XOFF + GC_WIDTH + screen_delta.x;
	rb.rect.max.y = GC_YOFF + screen_delta.y;

	Wimp_UpdateWindow(&rb, &more);
	if (more)
	{
		redraw_gamma(&rb, &more);
	}
}



static BOOL Hnd_RedrawGamma(event_pollblock * pb, void *ref)
{
	window_redrawblock rb;
	BOOL more;

	rb.window = pb->data.openblock.window;
	Wimp_RedrawWindow(&rb, &more);
	if (more)
	{
		redraw_gamma(&rb, &more);
	}

	return TRUE;
}


static BOOL Hnd_GammaClick(event_pollblock * pb, void *ref)
{
	int up = (ref == 0);

	if (up)
	{
		if (gamma < 9.0)
		{
			gamma += 0.05;
			Icon_SetDouble(gamma_win, 0, gamma, 2);
			Term_xtra_acn_react();
			update_gamma();
		}
	}
	else
	{
		if (gamma > 0.05)
		{
			gamma -= 0.05;
			Icon_SetDouble(gamma_win, GAMMA_ICN, gamma, 2);
			Term_xtra_acn_react();
			update_gamma();
		}
	}

	/* Hack: if the user menu is active then force it to redraw */
	if (user_menu_active)
	{
		Term_keypress(18);
		key_pressed = 1;
	}

	return TRUE;
}

/*
 | Reflect the current options in the gamma window
 */
static void set_gamma_window_state(void)
{
	if (minimise_memory) return;

	Icon_SetDouble(gamma_win, 0, gamma, 2);
}


static void init_gamma_window(void)
{                                 
	if (minimise_memory) return;
	
	Template_UseSpriteArea(resource_sprites);
	gamma_win = Window_Create("gamma", template_TITLEMIN);
	Template_UseSpriteArea(NULL);
	Event_Claim(event_REDRAW, gamma_win, event_ANY, Hnd_RedrawGamma, 0);
	Event_Claim(event_CLICK, gamma_win, GAMMA_DOWN, Hnd_GammaClick, (void *)1);
	Event_Claim(event_CLICK, gamma_win, GAMMA_UP, Hnd_GammaClick, (void *)0);
	set_gamma_window_state();
}


/*--------------------------------------------------------------------------*/
/* Sound options window stuff												*/
/*--------------------------------------------------------------------------*/

static slider_info volume_slider;


/*
 | Reflect the current sound config in the sound options window
 */
static void set_sound_window_state(void)
{
	if (minimise_memory) return;
	
	Icon_SetSelect(sound_win, SND_ENABLE, enable_sound);
	Slider_SetValue(&volume_slider, sound_volume, NULL, NULL);

	if (sound_volume > 127)
		volume_slider.colour.foreground = colour_RED;
	else
		volume_slider.colour.foreground = colour_GREEN;
}



/*
 | The sound slider has been dragged, so update the sound volume setting
 */
static int update_volume_from_slider(slider_info *si, void *ref)
{
	sound_volume = Slider_ReadValue(si);

	if (sound_volume > 127)
		volume_slider.colour.foreground = colour_RED;
	else
		volume_slider.colour.foreground = colour_GREEN;

	return 0;
}


/*
 | Handle redraw events for the sound options window
 */
static BOOL Hnd_RedrawSnd(event_pollblock * pb, void *ref)
{
	window_redrawblock redraw;
	BOOL more;

	redraw.window = pb->data.openblock.window;
	Wimp_RedrawWindow(&redraw, &more);

	while (more)
	{
		Slider_Redraw(((slider_info *) ref), &redraw.cliprect);
		Wimp_GetRectangle(&redraw, &more);
	}
	return (TRUE);
}


/*
 | Handle clicks on the sound options window
 */
static BOOL Hnd_SndClick(event_pollblock * pb, void *ref)
{
	int icn = pb->data.mouse.icon;
	int adj = pb->data.mouse.button.data.adjust;
	slider_info *si = (slider_info *) ref;

	switch (icn)
	{
			/* Bump arrows for the slider: */
		case SND_VOL_DOWN:
			adj = !adj;

		case SND_VOL_UP:
			adj = adj ? -1 : 1;
			sound_volume += adj;
			if (sound_volume < SOUND_VOL_MIN)
			{
				sound_volume = SOUND_VOL_MIN;
			}
			if (sound_volume > SOUND_VOL_MAX)
			{
				sound_volume = SOUND_VOL_MAX;
			}
			set_sound_window_state();
			break;

			/* The slider itself */
		case SND_VOL_SLIDER:
			Icon_ForceRedraw(sound_win, SND_VOL_SLIDER);
			Slider_Drag(si, NULL, NULL, NULL);
			break;

			/* The enable/disable icon */
		case SND_ENABLE:
			enable_sound = !enable_sound;
			Icon_SetSelect(sound_win, SND_ENABLE, enable_sound);
			if (enable_sound)
			{
				initialise_sound();
			}
			break;
	}

	/* Hack: if the user menu is active then force it to redraw */
	if (user_menu_active)
	{
		Term_keypress(18);
		key_pressed = 1;
	}

	return TRUE;
}



/*
 | Set the sound options window up, ready to rock :)
 */
static void init_sound_window(void)
{
	Template_UseSpriteArea(resource_sprites);
	sound_win = Window_Create("sound", template_TITLEMIN);
	Template_UseSpriteArea(NULL);

	Event_Claim(event_REDRAW, sound_win, event_ANY, Hnd_RedrawSnd,
				(void *)&volume_slider);
	Event_Claim(event_CLICK, sound_win, event_ANY, Hnd_SndClick,
				(void *)&volume_slider);

	/* Set up the slider info */
	volume_slider.window = sound_win;
	volume_slider.icon = SND_VOL_SLIDER;
	volume_slider.limits.min = SOUND_VOL_MIN;
	volume_slider.limits.max = SOUND_VOL_MAX;
	volume_slider.colour.foreground = colour_GREEN;
	volume_slider.colour.background = colour_WHITE;
	volume_slider.border.x = 8;
	volume_slider.border.y = 8;
	volume_slider.update = update_volume_from_slider;

	set_sound_window_state();
}





/*--------------------------------------------------------------------------*/











/*
 | A font has been selected.
 | At this point, menu_term is a pointer to the term for which the
 | menu was opened.
 */
static void handle_font_selection(int *s)
{
	char name[260];
	os_error *e;
	char *r;
	menu_ptr mp = font_menu;
	int *mis;

	/* Follow the >s to the entry specified */
	for (mis = s; *mis != -1; mis++)
		mp = ((menu_item *) (mp + 1))[*mis].submenu.menu;

	/*
	   | Now, check to see if we've hit a leaf entry.
	   | NB: If the entry isn't a leaf entry then the first entry in its submenu
	   | is used instead
	 */
	if (((int)mp) != -1)
	{
		mis[0] = 0;
		mis[1] = -1;
		mp = ((menu_item *) (mp + 1))[0].submenu.menu;
	}

	if (((int)mp) != -1)
		return;

	e = Wimp_DecodeMenu(font_menu, s, name);
	if (e)
	{
		plog(e->errmess);
		return;
	}

	/* Make sure that the string is NULL terminated */
	for (r = name; *r >= ' '; r++)
		;
	*r = 0;

	attach_font_to_term(menu_term, name);
	mark_ood(menu_term, 0, 0, 80, 24);
	refresh_window(menu_term);
}


#endif /* FULLSCREEN_ONLY */




static void load_choices(void)
{
	FILE *fp = NULL;
	char *cf;
	int i;
	char buffer[260];

	cf = find_choices(FALSE);
	if (*cf)
		fp = fopen(cf, "r");

	/* Implement default choices */
	data[0].def_open = 1;
	data[0].unopened = 1;		/* ie. force def_pos */
	data[0].def_pos.min.x = (screen_size.x - 1280) / 2;
	data[0].def_pos.max.x = (screen_size.x + 1280) / 2;
	data[0].def_pos.min.y = (screen_size.y - 768) / 2 - 32;
	data[0].def_pos.max.y = (screen_size.y + 768) / 2 - 32;
	data[0].def_scroll.x = data[0].def_scroll.y = 0;
	for (i = 1; i < MAX_TERM_DATA; i++)
	{
		data[i].def_open = 0;
		data[i].unopened = 1;	/* ie. force def_pos */
		data[i].def_pos.min.x = (screen_size.x - 1280) / 2;
		data[i].def_pos.max.x = (screen_size.x + 1280) / 2;
		data[i].def_pos.min.y = (screen_size.y - 768) / 2;
		data[i].def_pos.max.y = (screen_size.y + 768) / 2;
		data[i].def_scroll.x = data[i].def_scroll.y = 0;
	}

	if (fp)
	{
		const char *t_;
		char *o_;

		if (!fgets(buffer, sizeof(buffer), fp))
		{
			fclose(fp);
			return;
		}
		if (strcmp(buffer, "[Angband config, Musus' port]\n"))
		{
			fclose(fp);
			return;
		}

		/* Load choices */
		while (fgets(buffer, sizeof(buffer), fp))
		{
			t_ = strtok(buffer, " ");	/* Term number (or keyword, "Gamma", etc.) */
			o_ = strtok(NULL, "\n");	/* argument string */
			if (!o_)
			{
				o_ = "";
			}					/* missing (or null) argument? */
			if (t_)
			{
				if (!strcmp(t_, "Gamma"))
					gamma = atof(o_);
				else if (!strcmp(t_, "Monochrome"))
					force_mono = !strcmp(o_, "on");
				else if (!strcmp(t_, "Sound"))
					enable_sound = !strcmp(o_, "on");
				else if (!strcmp(t_, "Volume"))
					sound_volume = atoi(o_);
				else if (!strcmp(t_, "FullScreen"))
					start_fullscreen = !strcmp(o_, "on");
				else if (!strcmp(t_, "Hourglass"))
					use_glass = !strcmp(o_, "on");
				else if (!strcmp(t_, "HackFlush"))
					hack_flush = !strcmp(o_, "on");
				else if (!strcmp(t_, "AlarmTimeH"))
					alarm_h = atoi(o_);
				else if (!strcmp(t_, "AlarmTimeM"))
					alarm_m = atoi(o_);
				else if (!strcmp(t_, "AlarmText"))
					strcpy(alarm_message, o_);
				else if (!strcmp(t_, "AlarmBeep"))
					alarm_beep = !strcmp(o_, "on");
				else if (!strcmp(t_, "AlarmType"))
				{
					int i;
					for (i = 0; i < 4; i++)
						if (!strcmp(alarm_types[i], o_))
							alarm_type = i;
				}
				else if (isdigit((unsigned char)*t_))
				{
					int t = atoi(t_);
					if (t >= 0 && t < MAX_TERM_DATA)
					{
						char *f_, *x0_, *y0_, *x1_, *y1_, *sx_, *sy_;
						o_ = strtok(o_, " ");	/* first word */
						f_ = strtok(NULL, " ");	/* font name */
						x0_ = strtok(NULL, " ");	/* x posn (min) */
						y0_ = strtok(NULL, " ");	/* y posn (min) */
						x1_ = strtok(NULL, " ");	/* x posn (max) */
						y1_ = strtok(NULL, " ");	/* y posn (max) */
						sx_ = strtok(NULL, " ");	/* x scroll offset */
						sy_ = strtok(NULL, "\n");	/* y scroll offset */
						data[t].def_open = (t == 0) || atoi(o_);
						data[t].def_pos.min.x = atoi(x0_);
						data[t].def_pos.min.y = atoi(y0_);
						data[t].def_pos.max.x = atoi(x1_);
						data[t].def_pos.max.y = atoi(y1_);
						data[t].def_scroll.x = atoi(sx_);
						data[t].def_scroll.y = atoi(sy_);
						data[t].unopened = 1;	/* ie. force def_pos */
#ifndef FULLSCREEN_ONLY
						attach_font_to_term(&(data[t]), f_);
#endif /* FULLSCREEN_ONLY */						
					}
				}
			}
		}
		fclose(fp);
	}

#ifndef FULLSCREEN_ONLY
	/*
	   | Fudge so that the main term is *always* fullsize
	 */
	{
		int fw, fh;

		set_up_zrb(&(data[0]));
		fw = zrb.r_charw << screen_eig.x;
		fh = zrb.r_charh << screen_eig.y;
		if (zrb.r_flags.bits.double_height)
		{
			fh *= 2;
		}
		fw *= 80;
		fh *= 24;
		data[0].def_pos.max.x = data[0].def_pos.min.x + fw;
		data[0].def_pos.max.y = data[0].def_pos.min.y + fh;
		data[0].def_scroll.x = 0;
		data[0].def_scroll.y = 0;
	}
#endif /* FULLSCREEN_ONLY */


}




static void save_choices(void)
{
	FILE *fp = NULL;
	FILE *fpm = NULL;
	char *cf;
	int i;

	write_alarm_choices();

	cf = find_choices(TRUE);
	if (!*cf)
	{
		plog("Failed to locate writable choices file!");
		return;
	}

	fp = fopen(cf, "w");
	if (!fp)
	{
		plog("Can't write choices file");
		return;
	}

	fpm = fopen(find_choices_mirror(), "w");

	f2printf(fp, fpm, "[Angband config, Musus' port]\n");
	f2printf(fp, fpm, "Gamma %.2lf\n", gamma);
	f2printf(fp, fpm, "Monochrome %s\n", force_mono ? "on" : "off");
	f2printf(fp, fpm, "Sound %s\n", enable_sound ? "on" : "off");
	f2printf(fp, fpm, "Volume %d\n", sound_volume);
	f2printf(fp, fpm, "FullScreen %s\n", start_fullscreen ? "on" : "off");
	f2printf(fp, fpm, "Hourglass %s\n", use_glass ? "on" : "off");
	f2printf(fp, fpm, "HackFlush %s\n", hack_flush ? "on" : "off");

	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		window_state ws;
		Wimp_GetWindowState(data[i].w, &ws);
		f2printf(fp, fpm, "%d %d %s ", i, ws.flags.data.open,
				 data[i].font->name);
		f2printf(fp, fpm, "%d ", ws.openblock.screenrect.min.x);
		f2printf(fp, fpm, "%d ", ws.openblock.screenrect.min.y);
		f2printf(fp, fpm, "%d ", ws.openblock.screenrect.max.x);
		f2printf(fp, fpm, "%d ", ws.openblock.screenrect.max.y);
		f2printf(fp, fpm, "%d %d\n", ws.openblock.scroll.x,
				 ws.openblock.scroll.y);
	}

	fclose(fp);

	if (fpm)
	{
		fclose(fpm);
	}
}

/*
 | Update the Alarm choices file to reflect changed alarm settings.
 */
static void write_alarm_choices(void)
{
	FILE *fp;
	char *cf;

	/* Open the choices file for reading */
	cf = find_alarmfile(TRUE);
	if (!*cf)
	{
		plog("Can't determine Alarm file location!");
		return;
	}

	fp = fopen(cf, "w");
	if (!fp)
	{
		plog("Can't write Alarm file");
		return;
	}

	/* Write the new alarm options */
	fprintf(fp, "AlarmType %s\n", alarm_types[alarm_type]);
	fprintf(fp, "AlarmTimeH %d\n", alarm_h);
	fprintf(fp, "AlarmTimeM %d\n", alarm_m);
	fprintf(fp, "AlarmText %s\n", alarm_message);
	fprintf(fp, "AlarmBeep %s\n", alarm_beep ? "on" : "off");

	fclose(fp);
}

/*
 | Read the Alarm choices file.
 */
static void read_alarm_choices(void)
{
	char buffer[260];
	FILE *fp;
	char *cf;

	cf = find_alarmfile(FALSE);
	if (!*cf)
	{
		return;
	}

	fp = fopen(cf, "r");
	if (fp)
	{
		const char *t_, *o_;
		/* Load choices */
		while (fgets(buffer, sizeof(buffer), fp))
		{
			t_ = strtok(buffer, " ");	/* Keyword */
			o_ = strtok(NULL, "\n");	/* argument string */
			if (!o_)
			{
				o_ = "";
			}					/* missing (or null) argument? */
			if (t_)
			{
				if (!strcmp(t_, "AlarmTimeH"))
					alarm_h = atoi(o_);
				else if (!strcmp(t_, "AlarmTimeM"))
					alarm_m = atoi(o_);
				else if (!strcmp(t_, "AlarmText"))
					strcpy(alarm_message, o_);
				else if (!strcmp(t_, "AlarmBeep"))
					alarm_beep = !strcmp(o_, "on");
				else if (!strcmp(t_, "AlarmType"))
				{
					int i;
					for (i = 0; i < 4; i++)
						if (!strcmp(alarm_types[i], o_))
							alarm_type = i;
				}
			}
		}
		fclose(fp);
	}
}



#ifndef FULLSCREEN_ONLY
/*
 | Handle selections from the term menu(s)
 */
static BOOL Hnd_TermMenu(event_pollblock * pb, void *ref)
{
	mouse_block mb;
	int i;

	Wimp_GetPointerInfo(&mb);

	switch (pb->data.selection[0])
	{
		case TERM_MENU_INFO:	/* Info> */
			break;
		case TERM_MENU_FONT:	/* Font> */
			/* Sub item selected? */
			if (pb->data.selection[1] == -1)
			{
				break;
			}
			handle_font_selection(pb->data.selection + 1);
			break;
		case TERM_MENU_WINDOWS:	/* Windows> */
			if (pb->data.selection[1] == -1)
			{
				break;
			}
			i = pb->data.selection[1];
			{
				window_state ws;
				Wimp_GetWindowState(data[i].w, &ws);
				if (ws.flags.data.open)
				{
					if (!i)
						Hnd_MainClose(NULL, (void *)TRUE);
					else
						Window_Hide(data[i].w);
				}
				else
				{
					if (!i)
					{
						show_windows();
						grab_caret();
					}
					else
					{
						if (!data[i].unopened)
						{
							Window_Show(data[i].w, open_WHEREVER);
						}
						else
						{
							window_openblock ob;
							ob.window = data[i].w;
							ob.screenrect = data[i].def_pos;
							ob.scroll = data[i].def_scroll;
							ob.behind = -1;	/* could use data[0].w; ? */
							Wimp_OpenWindow(&ob);
							data[i].unopened = 0;
						}
					}
				}
			}
			break;
	}

	if (mb.button.data.adjust)
	{
		set_up_term_menu(menu_term);
		Menu_ShowLast();
	}

	return TRUE;
}






/*
 | Handle selections from the iconbar menu
 */
static BOOL Hnd_IbarMenu(event_pollblock * pb, void *ref)
{
	mouse_block mb;
	Wimp_GetPointerInfo(&mb);

	switch (pb->data.selection[0])
	{
		case IBAR_MENU_INFO:	/* Info> */
			break;
		case IBAR_MENU_FULLSCREEN:	/* Full screen */
			/* Do Full Screen mode */
			enter_fullscreen_mode();
			break;
		case IBAR_MENU_GAMMA:	/* Gamma correction */
			break;
		case IBAR_MENU_SOUND:	/* Sound */
			/*
			   | enable_sound = !enable_sound;
			   | if ( enable_sound ) { initialise_sound(); }
			   | Menu_SetFlags( ibar_menu, IBAR_MENU_SOUND, enable_sound, 0 );
			   | set_sound_window_state();
			 */
			break;
		case IBAR_MENU_WINDOWS:	/* Windows> */
			/*
			   | Hack: pass it off as the equivalent selection from
			   | the term menu.
			 */
			pb->data.selection[0] = TERM_MENU_WINDOWS;
			return Hnd_TermMenu(pb, ref);
			break;
		case IBAR_MENU_SAVECHOICES:	/* Save choices */
			save_choices();
			break;
		case IBAR_MENU_QUIT:	/* Quit */
			if (game_in_progress && character_generated)
				save_player();
			quit(NULL);
			break;
	}

	if (mb.button.data.adjust)
		Menu_ShowLast();

	return TRUE;
}

 
 

/*
 * Handler for NULL events (should this check the alarm in the desktop?
 */
static BOOL Hnd_null(event_pollblock *event, void *ref)
{
	/* Really no need to check the alarm more than once per second. */
	if (alarm_type && Time_Monotonic() > alarm_lastcheck + 100)
	{
		check_alarm();
	}

	return TRUE;
}

 
 
 




static BOOL Hnd_MenuSel(event_pollblock * pb, void *ref)
{
	if (menu_currentopen == ibar_menu)
		return Hnd_IbarMenu(pb, ref);
	else if (menu_currentopen == term_menu)
		return Hnd_TermMenu(pb, ref);
	return FALSE;
}


static BOOL Hnd_IbarClick(event_pollblock * pb, void *ref)
{
	if (pb->data.mouse.button.data.menu)
	{
		set_gamma_window_state();
		set_sound_window_state();

		/* Hack: shade the Save> option if appropriate */
		if (game_in_progress && character_generated)
			Menu_SetFlags(ibar_menu, IBAR_MENU_SAVE, 0, PDEADCHK);
		else
			Menu_SetFlags(ibar_menu, IBAR_MENU_SAVE, 0, TRUE);

		/*
		   | Hack: set up the Term menu as if it was opened over the main
		   | window (so that the Windows> submenu is set correctly)
		 */
		menu_term = (term_data *)&data[0];
		set_up_term_menu(menu_term);

		Menu_Show(ibar_menu, pb->data.mouse.pos.x, -1);
		return TRUE;
	}

	if (pb->data.mouse.button.data.select)
	{
		show_windows();
		grab_caret();
		return TRUE;
	}

	if (pb->data.mouse.button.data.adjust)
	{
		enter_fullscreen_mode();
		return TRUE;
	}

	return FALSE;
}






/*
 | Handler for PreQuit messages (eg. at shutdown).
 */
static BOOL Hnd_PreQuit(event_pollblock * b, void *ref)
{
	BOOL shutdown = (b->data.message.data.words[0] & 1) == 0;
	task_handle originator = b->data.message.header.sender;
	unsigned int quitref;
	message_block mb;
	char buffer1[64];
	os_error e;
	int ok;

	if (!(game_in_progress && character_generated))
		return TRUE;			/* ignore, we're OK to die */

	/* Stop the shutdown/quit */
	memcpy(&mb, &(b->data.message), 24);
	quitref = mb.header.yourref;
	mb.header.yourref = mb.header.myref;
	Wimp_SendMessage(event_ACK, &mb, originator, 0);

	/*
	   | We handle this differently depending on the version of the Wimp;
	   | newer versions give us much more flexibility.
	 */
	if (event_wimpversion < 350)
	{
		/*
		   | Older versions - use 'OK' and 'Cancel'.
		   | There is no "Save & Quit" button.
		 */
		Msgs_Lookup("err.shuttitl:Query from %s", e.errmess, 64);
		sprintf(buffer1, e.errmess, VARIANT);
		Msgs_Lookup("err.shutdown:Unsaved game; are you sure you want to quit?",
					e.errmess, 260);
		e.errnum = 0;
		SWI(3, 2, SWI_Wimp_ReportError, &e, 3 | 16, buffer1, NULL, &ok);

		if (ok != 1)
			return TRUE;		/* no! Pleeeeeease don't kill leeeeddle ol' me! */
	}
	else
	{
		/*
		   | Newer version: can add buttons to the dialog.
		   | we add a 'Save and Quit' button to allow the shutdown to
		   | continue /after/ saving.
		 */
		int flags;
		char buttons[64];

		Msgs_Lookup("err.shutbuts:Save & quit,Don't quit,Quit anyway",
					buttons, 64);
		Msgs_Lookup("err.shuttitl:Query from %s", e.errmess, 64);
		sprintf(buffer1, e.errmess, VARIANT);
		Msgs_Lookup("err.shutdown:Unsaved game; are you sure you want to quit?",
					e.errmess, 260);
		e.errnum = 0;

		flags = 0 | 16 | 256 | (4 << 9);

		SWI(6, 2, SWI_Wimp_ReportError, &e, flags, buffer1, ICONNAME, 0,
			buttons, NULL, &ok);

		if (ok == 4)
			return TRUE;		/* no! Pleeeeeease don't kill leeeeddle ol' me! */

		if (ok == 3)
			save_player();		/* Save & Quit */
	}


	/* RO2 doesn't use the shudown flag */
	if (shutdown && event_wimpversion >= 300 && mb.header.size >= 24)
	{
		key_block kb;
		kb.code = 0x1fc;		/* restart shutdown sequence */
		Wimp_SendMessage(event_KEY, (message_block *) & kb, originator, 0);
	}

	/* "Time... to die." */
	Event_CloseDown();
	exit(0);
	return TRUE;				/* The one great certainty (sic) */
}

#endif /* FULLSCREEN_ONLY */




static void initialise_terms(void)
{
	char t[80];
	int i;

#ifndef FULLSCREEN_ONLY
	if (!minimise_memory)
	{
		/* Create a window for each term.  Term 0 is special (no scroll bars) */
		data[0].w = Window_Create("angband", sizeof(angband_term_name[0]));
		data[0].font = SYSTEM_FONT;
		data[0].def_open = 1;
		data[0].unopened = 1;
		sprintf(t, "%s %s", VARIANT, VERSION);
		Window_SetTitle(data[0].w, t);
		strncpy(data[0].name, VARIANT, 12);
		Event_Claim(event_KEY, data[0].w, event_ANY, Hnd_Keypress,
					(void *)&(data[0]));
		Event_Claim(event_REDRAW, data[0].w, event_ANY, Hnd_Redraw,
					(void *)&(data[0]));
		Event_Claim(event_CLICK, data[0].w, event_ANY, Hnd_TermClick,
					(void *)&(data[0]));
		Event_Claim(event_CLOSE, data[0].w, event_ANY, Hnd_MainClose, NULL);
	
		for (i = 1; i < MAX_TERM_DATA; i++)
		{
			data[i].w = Window_Create("term", template_TITLEMIN);
			data[i].font = SYSTEM_FONT;
			data[i].def_open = 0;
			data[i].unopened = 1;
#ifndef OLD_TERM_MENU
			sprintf(t, "%s (%s %s)", angband_term_name[i], VARIANT, VERSION);
#else
			sprintf(t, "Term-%d (%s %s)", i, VARIANT, VERSION);
#endif
			Window_SetTitle(data[i].w, t);
			strncpy(data[i].name, t, 12);
			Event_Claim(event_CLICK, data[i].w, event_ANY, Hnd_TermClick,
						(void *)&(data[i]));
			Event_Claim(event_REDRAW, data[i].w, event_ANY, Hnd_Redraw,
						(void *)&(data[i]));
		}
	}
#endif /* FULLSCREEN_ONLY */

	term_data_link(&(data[0]), 256);

	for (i = 1; i < MAX_TERM_DATA; i++)
	{
		term_data_link(&(data[i]), 16);
		angband_term[i] = &(data[i].t);
	}

	angband_term[0] = &(data[0].t);
	Term_activate(&(data[0].t));
}




/*
 | Hack(ish) - determine the version of RISC OS
 */
static int os_version(void)
{
	int osv;
	SWI(3, 2, SWI_OS_Byte, 129, 0, 255, NULL, &osv);
	switch (osv)
	{
		case 0xa0: return 120;
		case 0xa1: return 200;
		case 0xa2: return 201;
		case 0xa3: return 300;
		case 0xa4: return 310;
		case 0xa5: return 350;
		case 0xa6: return 360;
		case 0xa7: return 370;
		case 0xa8: return 400;
		default: return 370;
	}
	return -1;					/* -sigh- */
}

#ifndef FULLSCREEN_ONLY
/*
 | Determine whether the current screen mode is "high-res"
 | (ie. should we use the "Sprites22" or the "Sprites" file.
 */
static int sprites22(void)
{
	int yeig;

	OS_ReadModeVariable(-1, modevar_YEIGFACTOR, &yeig);

	return yeig < 2;
}

/*
 | Determine whether we should use 2D or 3D templates.
 | 2D templates *must* be used under Wimp <3.00, but under RO3 we
 | use the CMOS settings to decide.
 */
static int templates2d(void)
{
	int r1, r2;

	if (event_wimpversion < 300)
		return TRUE;

	/* The 3D bit is bit 0 of byte 140 */
	OS_Byte(osbyte_READCMOSRAM, 140, 0, &r1, &r2);

	return !(r2 && 1);
}
#endif /* FULLSCREEN_ONLY */



static unsigned int htoi(char *s)
{
	static const char hex[] = "0123456789ABCDEF";
	unsigned int v = 0;
	while (*s)
	{
		char *m;
		int d = toupper((unsigned char)*s++);
		m = strchr(hex, d);
		if (!m)
		{
			return v;
		}
		v = (v << 4) + (m - hex);
	}
	return v;
}

static int read_unsigned(char *t)
{
	int r;
	if (SWI(2, 3, SWI_OS_ReadUnsigned, 2, t, NULL, NULL, &r))
		r = 0;
	return r;
}

/*
 | Scan the string at 'n', replacing dodgy characters with underbars
 */
static void sanitise_name(char *n)
{
	for (; *n; n++)
	{
		if (strchr("\"$%^&*\\\'@#.,", *n))
			*n = '_';
	}
}


/*
 | Ensure that the path to a given object exists.
 | Ie. if |p| = "a.b.c.d" then we attempt to
 | create directories a, a.b and a.b.c if they don't
 | already exist.
 | Note that 'd' may be absent.
 */
static int ensure_path(char *p)
{
	char tmp[260];
	char *l = tmp;

	while (*p)
	{
		if (*p == '.')
		{
			*l = 0;
			if (SWI(5, 0, SWI_OS_File, 8, tmp, 0, 0, 77))
				return 0;		/* Eeek! */
		}
		*l++ = *p++;
	}

	return 1;
}


/*
 * Set up the Scrap, Choices and Alarm paths, trying for
 * Choices:blah...,etc.  by preference, but falling back on lib/xtra
 * if need be.
 */
static void init_paths(void)
{
	char tmp[512];
	char subpath[128];
	char *v;
	char *t;

	/* Form the sub-path we use for both Choices and Scrap dirs: */
	v = subpath + sprintf(subpath, "%s", VARIANT);
	sanitise_name(subpath);
	sprintf(v, ".%s", VERSION);
	sanitise_name(v + 1);

	/* Do the Scrap path first: */
	*scrap_path = 0;

	/* Try for Wimp$ScrapDir... */
	t = getenv("Wimp$ScrapDir");
	if (t && *t)
	{
		sprintf(tmp, "%s.AngbandEtc.%s.", t, subpath);
		if (ensure_path(tmp))
		{
			strcpy(scrap_path, tmp);
		}
	}

	/* Couldn't use Wimp$ScrapDir, so fall back on lib.xtra.scrap */
	if (!*scrap_path)
	{
		sprintf(tmp, "%sxtra.scrap.", resource_path);
		if (ensure_path(tmp))
		{
			strcpy(scrap_path, tmp);
		}
	}

	/* Now set up the Choices and Alarm files: */

	/* Read only Choices file is always lib.xtra.Choices */
	sprintf(choices_file[CHFILE_READ], "%sXtra.Choices", resource_path);
	/* Default writable Choices file is the same */
	strcpy(choices_file[CHFILE_WRITE], choices_file[CHFILE_READ]);
	/* No default mirror Choices file */
	strcpy(choices_file[CHFILE_MIRROR], "");

	/* Read only Alarm file is always  lib.xtra.Alarm */
	sprintf(alarm_file[CHFILE_READ], "%sXtra.Alarm", resource_path);
	/* Default writable Alarm file is the same */
	strcpy(alarm_file[CHFILE_WRITE], alarm_file[CHFILE_READ]);

	/* Try to use Choices$Path, etc. for the others... */

	t = getenv("Choices$Write");	/* Ie. where choices should be written */
	if (t && *t)
	{
		/* Choices file: */
		sprintf(tmp, "%s.AngbandEtc.%s", t, subpath);
		if (ensure_path(tmp))
		{
			/* Use for writable file: */
			strcpy(choices_file[CHFILE_WRITE], tmp);
			/* Form 'mirror' filename: same path but with a fixed leafname */
			strcpy(v + 1, "Default");
			sprintf(tmp, "%s.AngbandEtc.%s", t, subpath);
			strcpy(choices_file[CHFILE_MIRROR], tmp);
		}

		/* Alarm file (doesn't involve subpath) */
		sprintf(tmp, "%s.AngbandEtc.Global.Alarm", t);
		if (ensure_path(tmp))
		{
			/* Use for read/writable file */
			strcpy(alarm_file[CHFILE_WRITE], tmp);
		}
	}
}







/*
 * Return the appropriate (full) pathname.
 *
 * For write ops, the read/write file is returned.
 *
 * For read ops, either the read/write file, the mirror file,
 * or the read only file will be returned as appropriate.
 */
static char *find_choices(int write)
{
	if (write)
		return choices_file[CHFILE_WRITE];

	if (myFile_Size(choices_file[CHFILE_WRITE]) > 0)
		return choices_file[CHFILE_WRITE];

	if (myFile_Size(choices_file[CHFILE_MIRROR]) > 0)
		return choices_file[CHFILE_MIRROR];

	return choices_file[CHFILE_READ];
}

static char *find_choices_mirror(void)
{
	return choices_file[CHFILE_MIRROR];
}

static char *find_alarmfile(int write)
{
	if (write)
		return alarm_file[CHFILE_WRITE];

	if (myFile_Size(alarm_file[CHFILE_WRITE]) > 0)
		return alarm_file[CHFILE_WRITE];

	return alarm_file[CHFILE_READ];
}




int main(int argc, char *argv[])
{
	int i, j;
	int start_full = 0;
	char *arg_savefile = 0;
	char *t;
#ifdef USE_DA
	int da_font = 1, da_game = 1;
#endif

	atexit(final_acn);			/* "I never did care about the little things." */

	Start_Hourglass;

	/* Parse arguments */
	for (i = 1; i < argc; i++)
	{
		if (argv[i][0] == '-')
		{
			switch (tolower((unsigned char)argv[i][1]))
			{
				case 'm':
				{
					/* Minimise Memory */
					minimise_memory = 1;

					/* Break */
					break;
				}
				case 'c':		/* -c[a][s][f][] */
					for (j = 2; argv[i][j]; j++)
					{
						int on = isupper((unsigned char)argv[i][j]);

						switch (tolower((unsigned char)argv[i][j]))
						{
#ifdef ABBR_FILECACHE
							case 'a': abbr_filecache =
									on;
								break;
							case 'f': abbr_tmpfile =
									on;
								break;
#endif
#ifdef SMART_FILECACHE
							case 's': smart_filecache =
									on;
								break;
#endif

							case 'p': flush_scrap =
									!on;
								break;

							default:
								if (isdigit((unsigned char)argv[i][j]))
								{
									max_file_cache_size =
										atoi(argv[i] + j) << 10;
									while (isdigit((unsigned char)argv[i][++j]))
										;
									if (max_file_cache_size <= 0)
									{
										use_filecache = 0;
									}
									j--;
								}
								else
								{
									fprintf(stderr, "Unrecognised option: -c%s",
											argv[i] + j);
									exit(EXIT_FAILURE);
								}
						}
					}
					break;
				case 'w':		/* -waitrelease */
					hack_flush = 1;
					break;
				case 'e':		/* -Evil */
					allow_iclear_hack = 1;
					break;
				case 's':		/* -s */
					if (argv[i][2])
						arg_savefile = argv[i] + 2;
					break;
				case 'f':		/* -fullscreen */
					start_full = 1;
					break;
				case 'h':		/* -hourglass */
					use_glass = 1;
					break;
				case 't':		/* -T */
					if (argv[i][2])
						vfiletype = htoi(argv[i] + 2);
					break;
#ifdef USE_DA
				case 'd':		/* -df, -dg, -dc or -d : disable DAs */
					switch (tolower((unsigned char)argv[i][2]))
					{
						case 0:	/* -d => disable both */
							da_font = da_game = 0;
							break;
						case 'f':	/* -df => disable font only */
							da_font = 0;
							break;
						case 'g':	/* -dg => disable game only */
							da_game = 0;
							break;
					}
					break;
#endif
				case '%':		/* -% */
				{
					int v = read_unsigned(argv[i] + 2);
					log_g_malloc = v & 1;
					show_sound_alloc = v & 2;
				}
					break;
				default:
					fprintf(stderr, "Unrecognised option: %s", argv[i]);
					exit(EXIT_FAILURE);
			}
		}
	}
          
	/* 1.27 - new handling of -minimise-memory: */
#ifndef FULLSCREEN_ONLY
	if (minimise_memory)
#endif /* FULLSCREEN_ONLY */
	{
		start_full = 1;
		fs_quit_key_text = "(fullscreen only mode)";
	}
#ifdef USE_DA
	init_memory(da_font, da_game);	/* Set up dynamic areas, etc. if possible */

	/* Install memory allocation hooks */
	ralloc_aux = g_malloc;
	rnfree_aux = g_free;
#endif

	/* Install replacement error reporting routines */
	quit_aux = quit_hook;
	plog_aux = plog_hook;
	core_aux = core_hook;

	/* Expand the (Angband) resource path */
	t = getenv(RISCOS_VARIANT "$Path");
	if (!t || !*t) Msgs_ReportFatal(0, "A resources path could not be formed.");
	strcpy(resource_path, t);

	/* Decide where scrap, choices and alarm files live: */
	init_paths();

	/* Hack: if no savefile specified, use a default */
	if (!arg_savefile)
	{
		arg_savefile = malloc(strlen(resource_path) + 32);
		if (!arg_savefile)
		{
			Msgs_ReportFatal(0, "err.mem");
		}
		sprintf(arg_savefile, "%s%s", resource_path, ">Save.Savefile");
	}

	/* This crap appears here so that plog() will work properly before
	   init_acn() is called... */
	Resource_Initialise(RISCOS_VARIANT);
	Msgs_LoadFile("Messages");

#ifndef FULLSCREEN_ONLY
	if (!minimise_memory)
	{
		/* This is a hack to only call Event_Initialise3 under RO3 */
		if (os_version() < 300)
			Event_Initialise(RISCOS_VARIANT);
		else
			Event_Initialise3(RISCOS_VARIANT, 300, message_list);
	
		EventMsg_Initialise();
	
		/*
		   | This is a possible workaround for the FP regs getting
		   | bolloxed in the ! menu because the compiler sets them
		   | up before a call to Wimp_Poll if CSE optimisation is on.
		   | At the moment I've just turned off CSE for the function
		   | affected.
		   |
		   | event_mask.data.keepfpregisters = 1;
		 */
	
		/* Load Templates */
		Template_Initialise();
		if (templates2d())
			Template_LoadFile("Templates2");
		else
			Template_LoadFile("Templates");
	
		/* Load Sprites */
		if (sprites22())
			resource_sprites =
				Sprite_LoadFile("<" RISCOS_VARIANT "$Dir>.Sprites22");
		else
			resource_sprites = Sprite_LoadFile("<" RISCOS_VARIANT "$Dir>.Sprites");
	}
#endif /* FULLSCREEN_ONLY */

	Screen_CacheModeInfo();

	/* Initialise some ZapRedraw stuff */
	initialise_palette();
	initialise_fonts();			/* Set up the fonts */
#ifndef FULLSCREEN_ONLY
	initialise_r_data();		/* Set up the r_data buffer */
    
	if (!minimise_memory)
	{
		/* Initialise some Wimp specific stuff */
		init_gamma_window();
		init_sound_window();
		init_save_window();
		init_menus();
		ibar_icon = Icon_BarIcon(ICONNAME, iconbar_RIGHT);
	
		/* Global handlers */
		Event_Claim(event_OPEN, event_ANY, event_ANY, Handler_OpenWindow, NULL);
		Event_Claim(event_CLOSE, event_ANY, event_ANY, Handler_CloseWindow, NULL);
		Event_Claim(event_GAINCARET, event_ANY, event_ANY, Hnd_Caret, (void *)1);
		Event_Claim(event_LOSECARET, event_ANY, event_ANY, Hnd_Caret, (void *)0);
		Event_Claim(event_MENU, event_ANY, event_ANY, Hnd_MenuSel, NULL);
		Event_Claim(event_CLICK, window_ICONBAR, ibar_icon, Hnd_IbarClick, NULL);
		Event_Claim(event_CLICK, event_ANY, event_ANY, Hnd_Click, NULL);
		EventMsg_Claim(message_PALETTECHANGE, event_ANY, Hnd_PaletteChange, NULL);
		EventMsg_Claim(message_MODECHANGE, event_ANY, Hnd_ModeChange, NULL);
		EventMsg_Claim(message_PREQUIT, event_ANY, Hnd_PreQuit, NULL);
	
		/* Initialise the sound stuff */
		initialise_sound();
	}
#endif /* FULLSCREEN_ONLY */

	/* Initialise some Angband stuff */
	initialise_terms();
	load_choices();
	read_alarm_choices();
	init_file_paths(unixify_name(resource_path));

	Start_Hourglass;			/* Paranoia */

	/* Hack - override the saved options if -F was on the command line */
	start_fullscreen |= start_full;

	/* hack so that the cursor is yellow if undefined */
	if (palette[CURSOR_COLOUR] == palette[0])
	{
		angband_color_table[CURSOR_COLOUR][1] = (CURSOR_RGB & 0xff00) >> 8;
		angband_color_table[CURSOR_COLOUR][2] = (CURSOR_RGB & 0xff0000) >> 16;
		angband_color_table[CURSOR_COLOUR][3] = (CURSOR_RGB & 0xff000000) >> 24;
	}

	/* Catch nasty signals */
	signals_init();
	/* use pref-acn.prf */
	ANGBAND_SYS = "acn";

#ifndef FULLSCREEN_ONLY
	if (start_fullscreen)
	{
#endif /* FULLSCREEN_ONLY */
		enter_fullscreen_mode();   
#ifndef FULLSCREEN_ONLY
	}
	else
	{
		Start_Hourglass;		/* Paranoia */
		Hnd_ModeChange(NULL, NULL);	/* Caches the various fonts/palettes */
		show_windows();
		grab_caret();

		Event_Claim(event_NULL, event_ANY, event_ANY, Hnd_null, NULL);

		/* Wait for a null poll so that the windows can appear */
		do
		{
			Event_Poll();
		}
		while (event_lastevent.type != 0);
	}
#endif /* FULLSCREEN_ONLY */

	/* Initialise Angband */
	Start_Hourglass;			/* Paranoia */

	strncpy(savefile, unixify_name(arg_savefile), sizeof(savefile));
	savefile[sizeof(savefile) - 1] = '\0';

	use_sound = 1;
	init_angband();
	initialised = 1;
	game_in_progress = 1;
/*	pause_line(23);*/
	flush();
	/* Stop_Hourglass; */
	play_game(FALSE);

	if (fullscreen_mode) leave_fullscreen_mode();
    
	Stop_Hourglass;

	quit(NULL);

	return 0;

	debug("to stop the 'unused' warning :)");
}













/*--------------------------------------------------------------------------*/
/* Stuff below here is for the full screen display							*/
/*--------------------------------------------------------------------------*/

static errr Term_xtra_acn_checkFS(void);
static errr Term_xtra_acn_eventFS(void);
static errr Term_xtra_acn_reactFS(int force);
static errr Term_curs_acnFS(int x, int y);
static errr Term_xtra_acn_clearFS(void);
static errr Term_xtra_acnFS(int n, int v);
static errr Term_wipe_acnFS(int x, int y, int n);
static errr Term_text_acnFS(int x, int y, int n, byte a, cptr s);
static void bored(void);
static void redraw_areaFS(int x, int y, int w, int h);
static void draw_cursor(int x, int y);

/*
 | We use this to keep the mouse in the same place on return from full-screen
 | mode.
 */
static wimp_point old_mouse_posn;

/*
 | Take a copy of the current mode descriptor/number and return either
 | a pointer to it (as an int) if it's a new mode, or the mode number.
 | NB: A static pointer is used and the descriptor returned is only
 | valid until the next call to this function.
 |
 | Basically, a replacement for OS_Byte 135 / OS_ScreenMode1, IYSWIM.
 */
static int current_mode(void)
{
	static void *descriptor = NULL;
	int mode;
	int size;
	int i;
	int *vals;

	if (descriptor)
	{
		free(descriptor);
		descriptor = NULL;
	}

	SWI(1, 3, SWI_OS_Byte, 135, NULL, NULL, &mode);
	if (mode < 256)
	{
		return mode;
	}

	vals = (int *)(mode + 20);
	for (i = 0; vals[i] != -1; i += 2)
		;

	size = 24 + 8 * i;			/* Size of data */
	descriptor = malloc(size);
	if (!descriptor)
	{
		core("Out of memory!");
	}
	memcpy(descriptor, (void *)mode, size);

	return (int)descriptor;
}



/*
 | Select the best mode we can for full screen.
 | Returns 12 for (low-res, ie. mode 12) or 27 for high-res,
 | or a pointer to a mode descriptor (as an int).
 */
static int select_fullscreen_mode(void)
{
	static struct
	{
		int flags, x, y, l2bpp, hz, term;
	}
	desc;
	int mode = 0;

	desc.flags = 1;				/* format 0 */
	desc.x = 640;
	desc.y = 480;				/* 640x480 */
	desc.l2bpp = 2;				/* 16 colours */
	desc.hz = -1;				/* best we can get */
	desc.term = -1;	/* don't fuss about modevars */

	SWI(1, 1, SWI_OS_CheckModeValid, &desc, &mode);
	if (mode != (int)&desc)
	{
		SWI(1, 1, SWI_OS_CheckModeValid, 27, /**/ &mode);
		if (mode != 27)
		{
			SWI(1, 1, SWI_OS_CheckModeValid, 12, /**/ &mode);
			if (mode != 12)
			{
				mode = 0;
			}
		}
	}

	return mode;
}


/*
 | Change screen mode
 */
static void change_screenmode(int to)
{
	if (SWI(2, 0, SWI_OS_ScreenMode, 0, to))
	{
		if (to < 256)
		{
			GFX_VDU(22);
			GFX_VDU(to);
		}
		else
		{
			/* Finished with my woman / cos she couldn't help me with ... */
			core("Eeek! mode isn't valid, but it /should/ be...");
		}
	}
}


/*
 | Constrain the mouse pointer to a point - this means that the damn
 | hourglass won't move around with the mouse :)
 */
static void constrain_pointer(void)
{
	mouse_block ptr;
	wimp_rect r;
	int ys = screen_eig.y == 1 ? 32 : 64;	/* Cope with dbl height glass */

	Screen_CacheModeInfo();		/* Make sure we know the screen size */
	r.min.x = r.max.x = screen_size.x - 32;
	r.min.y = r.max.y = screen_size.y - ys; 

	/* Retrieve and store old (wimp) pointer position */
	Wimp_GetPointerInfo(&ptr);
	old_mouse_posn = ptr.pos;

	Pointer_RestrictToRect(r);

	/* Turn the pointer off also */
	SWI(2, 0, SWI_OS_Byte, 106, 0);
}

static void release_pointer()
{             
	wimp_rect r;

	r.min.x = r.max.x = old_mouse_posn.x;
	r.min.y = r.max.y = old_mouse_posn.y;

	Pointer_RestrictToRect(r);
	
	Pointer_Unrestrict();
	 
	/* Turn the pointer back on also */
	SWI(2, 0, SWI_OS_Byte, 106, 1);
}
 
 



/*
 | Convert a 1bpp bitmap into a 4bpp bitmap (bit flipped)
 */
static int byte_to_word_flipped(int b)
{
	int w;
	if (b & 128)
	{
		w = 0xf0000000;
	}
	else
	{
		w = 0;
	}
	if (b & 64)
	{
		w |= 0x0f000000;
	}
	if (b & 32)
	{
		w |= 0x00f00000;
	}
	if (b & 16)
	{
		w |= 0x000f0000;
	}
	if (b & 8)
	{
		w |= 0x0000f000;
	}
	if (b & 4)
	{
		w |= 0x00000f00;
	}
	if (b & 2)
	{
		w |= 0x000000f0;
	}
	if (b & 1)
	{
		w |= 0x0000000f;
	}
	return w;
}




/*
 | try to load the fallback fullscreen font and convert it to 4bpp
 */
static int cache_zapfontHR(void)
{
	int handle;
	unsigned int extent;
	char buffer[260];
	struct
	{
		char id[8];
		int w, h, f, l, r1, r2;
	}
	zfh;
	int *op;
	char *ip;
	int l, i;

	/* Try to open the file */
	sprintf(buffer, "%s%s", resource_path, "xtra.FullScreen");
	handle = myFile_Open(buffer, 0x4f);
	if (!handle)
	{
		return 0;
	}

	/* Check file's extent */
	extent = myFile_Extent(handle);
	if (extent > sizeof(zfh) + 256 * 16)
	{
		myFile_Close(handle);
		return 0;
	}

	/* Load the header */
	if (myFile_ReadBytes(handle, &zfh, sizeof(zfh)))
	{
		myFile_Close(handle);
		return 0;
	}

	/* Check font size */
	if ((zfh.w != 8) || (zfh.h > 16))
	{
		myFile_Close(handle);
		return 0;
	}

	/* Load the 1bpp data */
	if (myFile_ReadBytes(handle, fullscreen_font, extent - sizeof(zfh)))
	{
		myFile_Close(handle);
		return 0;
	}

	myFile_Close(handle);

	l = zfh.l > 255 ? 255 : zfh.l;

	if (zfh.h > 8)
	{
		op = (int *)(((int)fullscreen_font) + (l + 1) * zfh.h * 4);
		ip = (char *)(((int)fullscreen_font) + (l + 1) * zfh.h -
					  (zfh.f * zfh.h));
		while (l-- >= zfh.f)
		{
			for (i = 0; i < zfh.h; i++)
			{
				*--op = byte_to_word_flipped(*--ip);
			}
		}
		fullscreen_height = zfh.h;
	}
	else
	{
		op = (int *)(((int)fullscreen_font) + (l + 1) * zfh.h * 8);
		ip = (char *)(((int)fullscreen_font) + (l + 1) * zfh.h -
					  (zfh.f * zfh.h));
		while (l-- >= zfh.f)
		{
			for (i = -zfh.h; i < zfh.h; i++)
			{
				int t = byte_to_word_flipped(*--ip);
				*--op = t;
				*--op = t;
			}
		}
		fullscreen_height = zfh.h * 2;
	}

	fullscreen_topline = TERM_TOPLINE_HR;
	fullscreen_topline += ((16 - fullscreen_height) * 13);

	return 1;
}





static int cache_fs_fontHR(void)
{
	ZapFont *src = SYSTEM_FONT;
	int c;
	int *op;
	char *ip;

	/* Allocate the storage for the font */
	fullscreen_font = f_malloc(256 * 4 * 16);
	if (!fullscreen_font)
	{
		return 0;
	}
	op = (int *)fullscreen_font;

	/* Check to see if the main term's font is suitable (ie. 8x16 or 8x8) */
	if ((data[0].font->w == 8) && (data[0].font->h <= 16))
		src = data[0].font;

	/*
	   | Hack: if we're forced to use the system font, try to load the
	   | 'fullscreen' font from lib.xtra.  If that fails, then I guess we're
	   | stuck with the system font.
	 */

	if (src == SYSTEM_FONT)
		if (cache_zapfontHR())
		{
			return 1;
		}

	ip = (char *)(src->bpp_1);

	/* Now, create the font */
	if (src->h > 8)
	{
		int e = src->h * (src->l > 256 ? 256 : src->l);
		op += (src->f * src->h);
		for (c = src->f * src->h; c < e; c++)
			*op++ = byte_to_word_flipped(*ip++);
		fullscreen_height = src->h;
	}
	else
	{
		int e = src->h * (src->l > 256 ? 256 : src->l);
		op += (src->f * src->h) * 2;
		for (c = src->f * src->h; c < e; c++)
		{
			int t = byte_to_word_flipped(*ip++);
			*op++ = t;
			*op++ = t;
		}
		fullscreen_height = src->h * 2;
	}

	fullscreen_topline = TERM_TOPLINE_HR;
	fullscreen_topline += ((16 - fullscreen_height) * 13);

	return 1;
}





static int cache_fs_fontLR(void)
{
	ZapFont *src = SYSTEM_FONT;
	int c, e;
	int *op;
	char *ip;

	/* Allocate the storage for the font */
	fullscreen_font = f_malloc(256 * 4 * 8);
	if (!fullscreen_font)
	{
		return 0;
	}
	op = (int *)fullscreen_font;

	/* Check to see if the main term's font is suitable (ie. 8x8) */
	if ((data[0].font->w == 8) && (data[0].font->h <= 8))
		src = data[0].font;

	ip = (char *)(src->bpp_1);

	/* Now, create the font */
	e = src->h * (src->l > 256 ? 256 : src->l);
	op += (src->f * src->h);
	for (c = src->f * src->h; c < e; c++)
		*op++ = byte_to_word_flipped(*ip++);

	fullscreen_height = src->h;
	fullscreen_topline = TERM_TOPLINE_LR;
	fullscreen_topline += ((8 - fullscreen_height) * 13);

	return 1;
}



static void set_keys(int claim)
{
	static int old_c_state;
	static int old_f_state[8];
	int i;

	if (claim)
	{
		/* Cursors/copy act as function keys */
		/* f0-f9, cursors, generate 0x80-0x8f */
		/* sh-f0-f9,cursors, generate 0x90-0x9f */
		/* ctrl f0-f9,cursors, generate 0xa0-0xaf */
		/* sh-c-f0-f9,cursors, generate 0xb0-0xbf */
		/* f10-f12 generate 0xca-0xcc */
		/* shift f10-f12 generate 0xda-0xdc */
		/* ctrl f10-f12 generate 0xea-0xec */
		/* ctrlshift f10-f12 generate 0xfa-0xfc */

		SWI(3, 2, SWI_OS_Byte, 4, 2, 0, /**/ NULL, &old_c_state);

		for (i = 0; i < 4; i++)
		{
			SWI(3, 2, SWI_OS_Byte, 225 + i, 0x80 + (i * 0x10), 0, NULL,
				old_f_state + i);
			SWI(3, 2, SWI_OS_Byte, 221 + i, 0xc0 + (i * 0x10), 0, NULL,
				old_f_state + i + 4);
		}
	}
	else
	{
		SWI(3, 0, SWI_OS_Byte, 4, old_c_state, 0);
		for (i = 0; i < 4; i++)
		{
			SWI(3, 0, SWI_OS_Byte, 225 + i, old_f_state[i], 0);
			SWI(3, 0, SWI_OS_Byte, 221 + i, old_f_state[i + 4], 0);
		}
	}
}






/*
 | Enter the full screen mode.
 |
 | Full screen display uses either mode 27 (if supported) and 8x16 fonts
 | (or system font 'twiddled' to double height), or mode 12 (if mode 27
 | is unavailable) and the system font (or an 8x8 font).
 |
 */

static void enter_fullscreen_mode(void)
{
	int vduvars[2] =
	{ 149, -1 };
	int i;

	/* New in 1.18 - protect against 're-entracy' */
	if (fullscreen_font)
		return;

	/* New in 1.20 - hack IClear out of the way */
	if (allow_iclear_hack)
		iclear_hack();

	/* Choose the mode we want */
	fullscreen_mode = select_fullscreen_mode();

	if (!fullscreen_mode)
	{
		plog("Unable to select a suitable screen mode (27 or 12)");
		return;
	}

	if (!((fullscreen_mode == 12) ? cache_fs_fontLR() : cache_fs_fontHR()))
	{
		plog("Unable to cache a font for full screen mode");
		return;
	}

	/* Read the current screen mode */
	/* SWI( 1,3, SWI_OS_Byte, 135, NULL, NULL, &old_screenmode ); */
	old_screenmode = current_mode();

	Stop_Hourglass;

	/* Change to the chosen screen mode */
	change_screenmode(fullscreen_mode);

	/* Restrict the pointer */
	constrain_pointer();

	/* Remove the cursors */
	SWI(0, 0, SWI_OS_RemoveCursors);

	Start_Hourglass;

	/* Get the base address of screen memory */
	SWI(2, 0, SWI_OS_ReadVduVariables, vduvars, vduvars);
	fullscreen_base = (int *)(vduvars[0]);

	/* Fudge the Term interface */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		term *t = &(data[i].t);
		t->xtra_hook = Term_xtra_acnFS;
		t->wipe_hook = Term_wipe_acnFS;
		t->curs_hook = Term_curs_acnFS;
		t->text_hook = Term_text_acnFS;
	}

	/* Grab the palette */
	Term_xtra_acn_reactFS(TRUE);

	/* Make sure that the keys work properly */
	set_keys(TRUE);

	/* refresh the term */
	/*Term_activate( &(data[0].t) ); */
	redraw_areaFS(0, 0, 80, 24);
	if (data[0].cursor.visible)
		draw_cursor(data[0].cursor.pos.x, data[0].cursor.pos.y);

	/* Display a reminder of how to get back... */
	/* Hack: disable force_mono */
	i = force_mono;
	force_mono = 0;
	Term_text_acnFS(0, TIME_LINE, strlen(fs_quit_key_text), 8,
					fs_quit_key_text);
	force_mono = i;
}




static void leave_fullscreen_mode(void)
{
	int i;

	/* New in 1.18 - protect against 're-entracy' */
	if (!fullscreen_font)
		return;

	/* Restore the Term interface */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
#ifndef FULLSCREEN_ONLY
		term *t = &(data[i].t);
		t->xtra_hook = Term_xtra_acn;
		t->wipe_hook = Term_wipe_acn;
		t->curs_hook = Term_curs_acn;
		t->text_hook = Term_text_acn;
#endif		
		mark_ood(&(data[i]), 0, 0, 80, 24);
	}

	/* Deallocate the font */
	f_free(fullscreen_font);
	fullscreen_font = 0;
	fullscreen_mode = 0;

	Stop_Hourglass;

	/* Restore the screen mode */
	Wimp_SetMode(old_screenmode);

	/* Restore the pointer */
	release_pointer();

	Start_Hourglass;

	/* Restore the various soft keys */
	set_keys(FALSE);

	/* New in 1.20 Remove the IClear hack */
	if (allow_iclear_hack)
		remove_iclear_hack();

#ifndef FULLSCREEN_ONLY
	/* Refresh the windows - this probably isn't necessary anyway */
	if (!minimise_memory)
		refresh_windows();
#endif /* FULLSCREEN_ONLY */
}





static void fs_writechars(int x, int y, int n, const char *chars, char attr)
{
	int *scr, *scrb;
	int *cdat;
	int j;
	unsigned int fgm;

	if (force_mono)
	{
		if (attr != TERM_DARK)
		{
			attr = TERM_WHITE;
		}
	}
	fgm = (unsigned int)zpalette[(unsigned int) attr];

	scrb = (int *)(((int)fullscreen_base) + y * fullscreen_height * 320
				   + x * 4 + 320 * fullscreen_topline);

	while (n--)
	{
		scr = scrb++;
		cdat = (int *)(((int)fullscreen_font)
					   + (*chars++) * (fullscreen_height << 2));
		for (j = 0; j < fullscreen_height; j++)
		{
			*scr = *cdat++ & fgm;
			scr += 80;
		}
	}
}


static void fs_writechar(int x, int y, char c, char attr)
{
	int *scrb;
	int *cdat;
	int j;
	unsigned int fgm;

	if (force_mono)
	{
		if (attr != TERM_DARK)
		{
			attr = TERM_WHITE;
		}
	}
	fgm = (unsigned int)zpalette[(unsigned int) attr];

	scrb = (int *)(((int)fullscreen_base) + y * fullscreen_height * 320
				   + x * 4 + 320 * fullscreen_topline);
	cdat = (int *)(((int)fullscreen_font) + (c * (fullscreen_height << 2)));
	for (j = 0; j < fullscreen_height; j++)
	{
		*scrb = *cdat++ & fgm;
		scrb += 80;
	}
}



static void draw_cursorHR(int x, int y)
{
	ColourTrans_SetGCOL(cursor_rgb, 0, 0);
	GFX_Move(x * 16,
			 959 - y * (fullscreen_height * 2) - fullscreen_topline * 2);
	GFX_DrawBy(14, 0);
	GFX_DrawBy(0, -(fullscreen_height * 2 - 2));
	GFX_DrawBy(-14, 0);
	GFX_DrawBy(0, fullscreen_height * 2 - 2);
}

static void draw_cursorLR(int x, int y)
{
	ColourTrans_SetGCOL(cursor_rgb, 0, 0);
	GFX_Move(x * 16,
			 1023 - y * (fullscreen_height * 4) - fullscreen_topline * 4);
	GFX_DrawBy(14, 0);
	GFX_DrawBy(0, -(fullscreen_height * 4 - 4));
	GFX_DrawBy(-14, 0);
	GFX_DrawBy(0, fullscreen_height * 4 - 4);
}





static void draw_cursor(int x, int y)
{
	if (fullscreen_mode == 12)
		draw_cursorLR(x, y);
	else
		draw_cursorHR(x, y);
}



static void redraw_areaFS(int x, int y, int w, int h)
{
	int i, j;
	for (j = y; j < y + h; j++)
		for (i = x; i < x + w; i++)
			fs_writechar(i, j, data[0].t.old->c[j][i], data[0].t.old->a[j][i]);
}



static int wimp_code(int c)
{
	/* shift/ctrl keypad? */
	if (c >= '0' && c <= '9')
	{
		kbd_modifiers m = Kbd_GetModifiers(FALSE);
		if (m.shift)
		{
			c |= 0x800;
		}
		if (m.ctrl)
		{
			c |= 0x400;
		}
		return c;
	}
	if (c == 9)
	{
		return 0x18a;
	}							/* Tab */
	if (c <= 127)
	{
		return c;
	}							/* normal ASCII/ctrl */
	if (c >= 0x80 && c <= 0xff)
	{
		return c + 0x100;
	}							/* f0-f9, etc. */

	return -1;					/* unknown */
}




static void do_keypress(int code)
{
	static const char hex[] = "0123456789ABCDEF";

	if (code == KEYPRESS_QUIT && !minimise_memory)
	{
#ifdef FULLSCREEN_ONLY
		Sound_SysBeep();
#else
		leave_fullscreen_mode();
#endif
		return;
	}

	if (code == 27)
	{
		if (Kbd_KeyDown(inkey_CTRL))
		{
			ack_alarm();
			return;
		}
	}

	if (code <= 255)
	{
		Term_keypress(code);
	}
	else
	{
		Term_keypress(31);
		Term_keypress(hex[(code & 0xf00) >> 8]);
		Term_keypress(hex[(code & 0x0f0) >> 4]);
		Term_keypress(hex[(code & 0x00f)]);
		Term_keypress(13);
	}
}




static errr Term_xtra_acn_checkFS(void)
{
	int bh, bl;
	int c;

	Stop_Hourglass;

	bored();

	SWI(3, 3, SWI_OS_Byte, 128, 255, 0, /**/ NULL, &bl, &bh);
	bl = (bl & 0xff) + (bh << 8);

	if (bl > 0)
	{
		SWI(0, 1, SWI_OS_ReadC, &c);
		bl = wimp_code(c);
		if (bl >= 0)
		{
			do_keypress(bl);
		}
	}

	Start_Hourglass;

	return 0;
}




static errr Term_xtra_acn_eventFS(void)
{
	int c;
	int w = -1;

	Stop_Hourglass;

	for (w = -1; w == -1;)
	{
		int bh, bl;
		do
		{
			bored();
			SWI(3, 3, SWI_OS_Byte, 128, 255, 0, /**/ NULL, &bl, &bh);
			bl = (bl & 0xff) + (bh << 8);
		}
		while (!bl);

		SWI(0, 1, SWI_OS_ReadC, &c);
		w = wimp_code(c);
		if (w >= 0)
		{
			do_keypress(w);
		}
	}

	Start_Hourglass;

	return 0;
}



/*
 * React to changes
 */
static errr Term_xtra_acn_reactFS(int force)
{
	unsigned int i;
	int p, r, g, b;

	static double old_gamma = -1.0;

	if (gamma != old_gamma)
	{
		force = 1;
		old_gamma = gamma;
	}

	/* Set the screen colours */
	for (i = 0; i < 16; i++)
	{
		if (COLOUR_CHANGED(i) || force)
		{
			r = (int)(255.0 *
					  pow(angband_color_table[i][1] / 255.0, 1.0 / gamma));
			g = (int)(255.0 *
					  pow(angband_color_table[i][2] / 255.0, 1.0 / gamma));
			b = (int)(255.0 *
					  pow(angband_color_table[i][3] / 255.0, 1.0 / gamma));
			GFX_VDU(19);
			GFX_VDU(i);
			GFX_VDU(16);
			GFX_VDU(r);
			GFX_VDU(g);
			GFX_VDU(b);

			palette[i] = (b << 24) | (g << 16) | (r << 8);
			p = i;
			p |= (p << 4);
			p |= (p << 8);
			p |= (p << 16);
			zpalette[i] = p;

			a_palette[i][1] = angband_color_table[i][1];
			a_palette[i][2] = angband_color_table[i][2];
			a_palette[i][3] = angband_color_table[i][3];

			/* Find any higher colour numbers and make them "wrong" */
			for (p = 16; p < 256; p++)
				if ((zpalette[p] & 0xf) == i)
					a_palette[p][1] = angband_color_table[p][1] + 2;
		}
	}


	/* Go through the palette updating any changed values */
	for (i = 16; i < 256; i++)
	{
		if (COLOUR_CHANGED(i) || force)
		{
			r = (int)(255.0 *
					  pow(angband_color_table[i][1] / 255.0, 1.0 / gamma));
			g = (int)(255.0 *
					  pow(angband_color_table[i][2] / 255.0, 1.0 / gamma));
			b = (int)(255.0 *
					  pow(angband_color_table[i][3] / 255.0, 1.0 / gamma));
			p = (b << 24) | (g << 16) | (r << 8);
			palette[i] = p;
			SWI(1, 1, SWI_ColourTrans_ReturnColourNumber, palette[i], &p);
			p |= (p << 4);
			p |= (p << 8);
			p |= (p << 16);
			zpalette[i] = p;
			a_palette[i][1] = angband_color_table[i][1];
			a_palette[i][2] = angband_color_table[i][2];
			a_palette[i][3] = angband_color_table[i][3];
		}
	}

	cursor_rgb = palette[CURSOR_COLOUR];

	return 0;
}


static errr Term_curs_acnFS(int x, int y)
{
	if (Term == &(data[0].t))
	{
		if (data[0].cursor.visible)
			redraw_areaFS(data[0].cursor.pos.x, data[0].cursor.pos.y, 1, 1);
		data[0].cursor.pos.x = x;
		data[0].cursor.pos.y = y;
		if (data[0].cursor.visible)
			draw_cursor(x, y);
	}
	return 0;
}

static errr Term_xtra_acn_clearFS(void)
{
	char e[80];
	int j;

	if (Term == &(data[0].t))
	{
		for (j = 0; j < 80; j++)
			e[j] = ' ';

		GFX_Wait();

		for (j = 0; j < 24; j++)
			fs_writechars(0, j, 80, e, 0);
	}

	return 0;
}







static errr Term_xtra_acnFS(int n, int v)
{
	term_data *t = (term_data *)Term;

	switch (n)
	{
		case TERM_XTRA_CLEAR:
			if (t == (&data[0]))
				Term_xtra_acn_clearFS();
			return 0;

		case TERM_XTRA_EVENT:
			if (v)
				return Term_xtra_acn_eventFS();
			else
				return Term_xtra_acn_checkFS();

		case TERM_XTRA_BORED:
			bored();
			return Term_xtra_acn_checkFS();

		case TERM_XTRA_FLUSH:
			/* 1.21 - Hack: wait until no keys are pressed */
			if (hack_flush)
				for (v = 0; v != 0xff;)
					SWI(1, 2, SWI_OS_Byte, 122, 0, &v);
			SWI(3, 0, SWI_OS_Byte, 21, 0, 0);	/* Flush Kbd buffer */
			return 0;

		case TERM_XTRA_FRESH:
			return 0;

		case TERM_XTRA_FROSH:
			return 0;

		case TERM_XTRA_SHAPE:
			if (t == (&data[0]))
			{
				t->cursor.visible = v;
				if (v)
					draw_cursor(t->cursor.pos.x, t->cursor.pos.y);
				else
					redraw_areaFS(t->cursor.pos.x, t->cursor.pos.y, 1, 1);
			}
			return 0;

		case TERM_XTRA_NOISE:
			Sound_SysBeep();
			return 0;

		case TERM_XTRA_REACT:
			return Term_xtra_acn_reactFS(FALSE);

		case TERM_XTRA_DELAY:
			if (v > 0)
			{
				int start = Time_Monotonic();
				v = (v + 5) / 10;	/* Round to nearest cs */
				GFX_Wait();
				while ((Time_Monotonic() - start) < v)
					;
			}
			return (0);

		case TERM_XTRA_SOUND:	/* Play a sound :) */
			if (enable_sound)
			{
				play_sound(v);
			}
			return 0;

		/* Subdirectory scan */
		case TERM_XTRA_SCANSUBDIR:
		{
		    filing_dirdata directory;
		    filing_direntry *entry;

			scansubdir_max = 0;

			if (Filing_OpenDir(riscosify_name(scansubdir_dir), &directory, sizeof(filing_direntry), readdirtype_DIRENTRY) != NULL)
			{
			  Error_Report(0, "Couldn't open directory \"%s\"", riscosify_name(scansubdir_dir));
			  return 0;
			}

			while ((entry = Filing_ReadDir(&directory)) != NULL)
			{
				if (entry->objtype == filing_DIRECTORY)
				{    
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(entry->name);
					++scansubdir_max;
				}
			}

			Filing_CloseDir(&directory);

			return 0;
		}

		/* Return current "time" in milliseconds */
		case TERM_XTRA_GET_DELAY:
		{
			Term_xtra_long = Time_Monotonic() * 100;

			return 0;
		}

		/* Rename main window */
		case TERM_XTRA_RENAME_MAIN_WIN:
		{
			Window_SetTitle(data[0].w, angband_term_name[0]);
			return 0;
		}

		default:
			return 1;
	}
}

static errr Term_wipe_acnFS(int x, int y, int n)
{
	if (Term == &(data[0].t))
		while (n--)
			fs_writechar(x++, y, ' ', 0);
	return 0;
}

static errr Term_text_acnFS(int x, int y, int n, byte a, cptr s)
{
	if (Term == &(data[0].t))
		fs_writechars(x, y, n, s, (char)a);
	return 0;
}



static void bored()
{
	static int last = -1;
	char ts[80];
	time_t ct;
	struct tm *lt;
	unsigned int l;
	int ofm;
	static int alarm_flash = 1;

	/* Really no need to check the alarm more than once per second. */
	if (alarm_type && Time_Monotonic() > alarm_lastcheck + 100)
	{
		check_alarm();
	}

	l = Time_Monotonic();
	if ((l - last) < (alarm_flash ? 25 : 50))
	{
		return;
	}
	last = l;

	time(&ct);
	lt = localtime(&ct);
	l = strftime(ts, 80, "%c %Z", lt);

	/* Hack: disable force_mono around printing the time */
	ofm = force_mono;
	force_mono = 0;

	/* Hack: Is the alarm supposed to be going off? */
	if (alarm_disp || alarm_flash)
	{
		char blk[60];
		int c = 8;
		if (!alarm_disp)
		{
			alarm_flash = 11;
		}
		switch (alarm_flash / 2)
		{
			case 4: sprintf(blk, "%-57s", alarm_cancel_text);
				break;
			case 5: sprintf(blk, "%-57s", fs_quit_key_text);
				break;
			default:
				c = alarm_flash & 1 ? TERM_RED : TERM_WHITE;
				sprintf(blk, "%02d:%02d %-51s", alarm_h, alarm_m,
						alarm_message);
		}
		fs_writechars(0, TIME_LINE, 57, blk, c);
		if (++alarm_flash > 11)
		{
			alarm_flash = 0;
		}
	}

	/* Display time */
	fs_writechar(79 - l, TIME_LINE, ' ', 0);
	fs_writechars(80 - l, TIME_LINE, l, ts, 8);

	force_mono = ofm;
}






#ifdef USE_DA
/*--------------------------------------------------------------------------*/
/* (Simple) Heap management (using OS_Heap)									*/
/*--------------------------------------------------------------------------*/

typedef void *heap;

static os_error *Heap_Initialise(heap h, size_t size)
{
	return SWI(4, 0, SWI_OS_Heap, 0, h, 0, size);
}

static void *Heap_Claim(heap h, size_t size)
{
	void *fred;
	os_error *e;
	e = SWI(4, 3, SWI_OS_Heap, 2, h, 0, size, NULL, NULL, &fred);
	return e ? NULL : fred;
}

static os_error *Heap_Release(heap h, void *block)
{
	return SWI(3, 0, SWI_OS_Heap, 3, h, block);
}

static int Heap_ChangeHeapSize(heap h, int resize_by)
{
	int by;
	SWI(4, 4, SWI_OS_Heap, 5, h, 0, resize_by, 0, 0, 0, &by);
	return by;
}



/*--------------------------------------------------------------------------*/
/* Stuff below here is for using Dynamic areas (under RO3.5+)				*/
/*--------------------------------------------------------------------------*/

static int game_area = -1;	/* The DA the game is using */
static int font_area = -1;	/* The DA the fonts are using */

static void *game_area_base;	/* base address of game area */
static void *font_area_base;	/* base address of font area */

static int font_area_size;	/* size of the fonts' DA */
static int font_heap_size;	/* size of the fonts' heap */
static int game_area_size;	/* size of the game's DA */
static int game_heap_size;	/* size of the game's heap */

#define MAX_F_DA_SIZE (2<<20)	/* Max size of font area (2Mb) */
#define MAX_G_DA_SIZE (4<<20)	/* Max size of game area (4Mb) */
#define SHRINK_GRAN (4<<10)		/* Try to recalaim wastage > this (4Kb) */


/*
 | Free dynamic areas when we exit
 */
static void cleanup_memory(void)
{
	if (game_area != -1)
	{
		SWI(2, 0, SWI_OS_DynamicArea, 1, game_area);
		game_area = -1;
	}

	if (font_area != -1)
	{
		SWI(2, 0, SWI_OS_DynamicArea, 1, font_area);
		font_area = -1;
	}

}



/*
 | Set up the memory allocation stuff.
 | We check to see if DAs are possible and if so initialise two:
 | one for the game's use (via the rnalloc() hooks) and one for
 | our own use (for fonts, etc).
 |
 | Each area is created 16Kb in size, with a max size of 2/4Mb.
 |
 | If 'daf' is TRUE, an area is created for the fonts.
 | If 'dag' is TRUE, an area is created for the game.
 */
static void init_memory(int daf, int dag)
{       
	os_error *e = NULL;
	
	if (!daf)
	{
		/* Paranoia */
		font_area = -1;
		font_area_base = 0;
	}
	else
	{
		e = SWI(9, 4, SWI_OS_DynamicArea, 0,	/* Create */
				-1,				/* Let OS allocate no. */
				16 << 10,		/* Initial size */
				-1,				/* Let OS allocate address */
				1 << 7,			/* Cacheable, bufferable, RW */
				MAX_F_DA_SIZE,	/* Max size */
				0,				/* handler */
				0,				/* handler workspace */
				VARIANT " font data",	/* Name */
				/* */
				NULL,			/* r0 */
				&font_area,		/* area number allocated */
				NULL,			/* r2 */
				&font_area_base	/* base address of area */
			);

		if (e)
		{
			game_area = font_area = -1;
			game_area_base = font_area_base = 0;	/* paranoia */
			return;
		}
		else
		{
			e = SWI(2, 3, SWI_OS_DynamicArea, 2, font_area,
					NULL, NULL, &font_area_size);
			if (e)
			{
				Error_ReportFatal(e->errnum, "%d:%s", e->errmess);
			}

			e = Heap_Initialise((heap) font_area_base, font_area_size);
			if (e)
			{
				Error_ReportFatal(e->errnum, "%d:%s", e->errmess);
			}
			font_heap_size = font_area_size;
		}
	}

	/* Make sure DA(s) are removed when we quit */
	atexit(cleanup_memory);

	if (!dag)
	{
		/* Paranoia */
		game_area = -1;
		game_area_base = 0;
	}
	else
	{
		e = SWI(9, 4, SWI_OS_DynamicArea, 0,	/* Create */
				-1,				/* Let OS allocate no. */
				16 << 10,		/* Initial size */
				-1,				/* Let OS allocate address */
				1 << 7,			/* Cacheable, bufferable, RW */
				MAX_G_DA_SIZE,	/* Max size */
				0,				/* handler */
				0,				/* handler workspace */
				VARIANT " game data",	/* Name */
				/* */
				NULL,			/* r0 */
				&game_area,		/* area number allocated */
				NULL,			/* r2 */
				&game_area_base	/* base address of area */
			);

		if (e)
		{
			game_area = -1;
			game_area_base = 0;	/* paranoia */
		}
		else
		{
			e = SWI(2, 3, SWI_OS_DynamicArea, 2, game_area,
					NULL, NULL, &game_area_size);
			if (e)
			{
				Error_ReportFatal(e->errnum, "%d:%s", e->errmess);
			}

			e = Heap_Initialise((heap) game_area_base, game_area_size);
			if (e)
			{
				Error_ReportFatal(e->errnum, "%d:%s", e->errmess);
			}
			game_heap_size = game_area_size;
		}
	}
}

static int grow_dynamicarea(int area, int by)
{
	os_error *e;
	e = SWI(2, 2, SWI_OS_ChangeDynamicArea, area, by, /**/ NULL, &by);
	/* Can't check errors since a 'failed' shrink returns one... */
	return by;
}


/*
 | Try to shrink the font-cache heap and area as much as possible.
 */
static void f_shrink_heap(void)
{
	int s;
	/* Shrink the heap as far as possible */
	font_heap_size -=
		Heap_ChangeHeapSize((heap) font_area_base, -MAX_F_DA_SIZE);
	/* Shrink the dynamic area if necessary */
	s = font_area_size - font_heap_size;
	if (s >= SHRINK_GRAN)
		font_area_size -= grow_dynamicarea(font_area, -s);
}

/*
 | Allocate a block of memory in the font heap
 */
static void *f_malloc(size_t size)
{
	void *c;
	int s;
	if (font_area == -1)
	{
		return malloc(size);
	}
	c = Heap_Claim((heap) font_area_base, size);

	if (!c)
	{
		/* The Claim failed.  Try to grow the area by the size of the block */
		s = grow_dynamicarea(font_area, size + 64);	/* 64 is overkill */
		if (!s)
		{
			return NULL;
		}
		font_area_size += s;
		s = font_area_size - font_heap_size;
		font_heap_size += Heap_ChangeHeapSize((heap) font_area_base, s);
		c = Heap_Claim((heap) font_area_base, size);
		if (c)
		{
			f_shrink_heap();
		}
	}
	return c;
}


/*
 | Free a block of memory in the font heap
 */
static void f_free(void *blk)
{
	os_error *e;
	if (font_area == -1)
	{
		free(blk);
		return;
	}
	e = Heap_Release((heap) font_area_base, blk);
	if (e)
		Msgs_ReportFatal(e->errnum, "err.swi", __LINE__, e->errmess);
	f_shrink_heap();
}





/*
 | Allocate a block of memory in the game heap
 */
static vptr g_malloc(huge size)
{
	void *c;
	int s;

	if (game_area == -1)
	{
		return malloc((size_t) size);
	}
	c = Heap_Claim((heap) game_area_base, (size_t) size + 4);
	if (!c)
	{
		/* The Claim failed.  Try to grow the area by the size of the block */
		s = grow_dynamicarea(game_area, (size_t) size + 64);	/* 64 is overkill */
		if (!s)
		{
			return NULL;
		}
		game_area_size += s;
		s = game_area_size - game_heap_size;
		game_heap_size += Heap_ChangeHeapSize((heap) game_area_base, s);
		c = Heap_Claim((heap) game_area_base, (size_t) size + 4);
	}

	if (c)
	{
		strcpy((char *)c, "MUSH");
		c = (void *)(((int)c) + 4);
	}

	if (log_g_malloc)
		fprintf(stderr, "ralloc(%ld) == %p\n", (long)size, c);

	return c;
}


/*
 | Free a block of memory in the game heap
 |
 | The 'len' is to be compatible with z-virt.c (we don't need/use it)
 | Returns NULL.
 */
static vptr g_free(vptr blk, huge size)
{
	os_error *e;
	int s;

	if (game_area == -1)
	{
		free(blk);
		return NULL;
	}

	if (log_g_malloc)
		fprintf(stderr, "rnfree(%p)\n", blk);

	if (strncmp(((char *)blk) - 4, "MUSH", 4))
		core("game heap corrupt / bad attempt to free memory");

	blk = (void *)(((int)blk) - 4);

	e = Heap_Release((heap) game_area_base, blk);
	if (e)
		Msgs_ReportFatal(e->errnum, "err.swi", __LINE__, e->errmess);

	/* Shrink the heap as far as possible */
	game_heap_size -=
		Heap_ChangeHeapSize((heap) game_area_base, -MAX_G_DA_SIZE);
		
	/* Shrink the dynamic area if necessary */
	s = game_area_size - game_heap_size;
	if (s >= SHRINK_GRAN)
		game_area_size -= grow_dynamicarea(game_area, -s);

	return NULL;
}


#endif /* USE_DA */



/*--------------------------------------------------------------------------*/

/*
 | New to 1.04: Sound support :)
 |
 | We use the PlayIt module (for convenience).
 |
 | The Lib/xtra/sound/sound.cfg file is used to map sample names onto
 | event names.
 |
 | Since textual names are used in the .cfg file, we need to have a lookup
 | table to translate them into numbers.  At present we use the
 | angband_sound_name array defined in variable.c
 |
 | Since there can be multiple sounds for each event we need to use a
 | list to store them.
 */

/* NB: This will be clipped to 10 under RISC OS 2 */
#define MAX_SAMPNAME_LEN 64




/*
 | The list format:
 */
typedef struct samp_node
{
	char sample_name[MAX_SAMPNAME_LEN + 1];	/* Sample name */
	struct samp_node *next;	/* -> next node */
}
SampNode;

typedef struct samp_info
{
	int samples;	/* # samples for this event */
	SampNode *samplist;	/* list of sample names */
}
SampInfo;


/*
 | Just need an array of SampInfos
 */
static SampInfo sample[SOUND_MAX];

/*
 | This flag will only be set non-zero if the SampInfo array is
 | valid.
 */
static int sound_initd = 0;


static void read_sound_config(void)
{
	int i;
	char buffer[2048];
	FILE *f;
	int max_sampname_len = truncate_names()? 10 : MAX_SAMPNAME_LEN;
	FILE *dbo = NULL;

	if (show_sound_alloc)
	{
		sprintf(buffer, "%s%s", resource_path, "sndmap/out");
		dbo = fopen(buffer, "w");
		if (!dbo)
		{
			core("can't create sndmap/out debugging file");
		}
	}

	if (!sound_initd)
	{
		/* Initialise the sample array */
		for (i = 0; i < SOUND_MAX; i++)
		{
			sample[i].samples = 0;
			sample[i].samplist = NULL;
		}
		sound_initd = 1;
	}
	else
	{
		/* Deallocate the sample lists */
		for (i = 0; i < SOUND_MAX; i++)
		{
			SampNode *si = sample[i].samplist;
			sample[i].samples = 0;
			sample[i].samplist = NULL;
			while (si)
			{
				SampNode *ns = si->next;
				free(si);
				si = ns;
			}
		}
	}


	/* Open the config file */
	sprintf(buffer, "%sSound:%s", RISCOS_VARIANT, "sound/cfg");
	f = fopen(buffer, "r");

	/* No cfg file => no sounds */
	if (!f)
	{
		if (show_sound_alloc)
		{
			fprintf(dbo, "** Can't open cfg file '%s'\n", buffer);
			fclose(dbo);
		}
		return;
	}

	/* Parse the file */
	while (fgets(buffer, sizeof(buffer), f))
	{
		char *sample_name;
		int event_number;

		/* Skip comments and lines that begin with whitespace */
		if (*buffer == '#' || isspace((unsigned char)*buffer))
		{
			continue;
		}

		/* Hack: ignore any line beginning '[' (section marker) */
		if (*buffer == '[')
		{
			continue;
		}

		/* Place a NULL after the event name and find the first sample name */
		sample_name = buffer;
		while (*sample_name && !isspace((unsigned char)*sample_name))
			sample_name++;

		/* Bad line? */
		if (*sample_name == 0)
		{
			continue;
		}						/* just ignore it */

		/* Terminate the sample name */
		*sample_name++ = 0;

		/* Look up the event name to get the event number */
		for (event_number = SOUND_MAX - 1; event_number >= 0; event_number--)
			if (!strcmp(buffer, angband_sound_name[event_number]))
				break;

		/* No match -> just ignore the line */
		if (event_number < 0)
		{
			if (show_sound_alloc)
				fprintf(dbo, "* Ignoring unknown event '%s'\n", buffer);
			continue;
		}

		/* Find the = */
		while (*sample_name && *sample_name != '=')
			sample_name++;

		/* Bad line? */
		if (*sample_name == 0)
		{
			continue;
		}						/* just ignore it */

		/* Skip the '=' */
		sample_name++;


		/*
		   | Now we find all the sample names and add them to the
		   | appropriate list in the sample mapping array
		 */

		while (*sample_name)
		{
			char *s;
			SampNode *sn;

			/* Find the start of the next word */
			while (isspace((unsigned char)*sample_name) && *sample_name)
				sample_name++;

			/* End of line? */
			if (!*sample_name)
			{
				break;
			}

			/* Find the end of the sample name */
			s = sample_name;	/* start of the name */
			while (!isspace((unsigned char)*sample_name) && *sample_name)
				sample_name++;

			/* Hack: shorten sample names that are too long */
			if ((sample_name - s) > max_sampname_len)
				s[max_sampname_len] = ' ';

			/* Allocate a node in the sample list for the event */
			if ((sn = malloc(sizeof(SampNode))) == NULL)
				core("Out of memory (scanning sound.cfg)");

			/* Link the node to the list */
			sn->next = sample[event_number].samplist;
			sample[event_number].samplist = sn;

			/* Imcrement the sample count for that event */
			sample[event_number].samples++;

			/*
			   | Copy the sample name into the node, converting it into
			   | RISC OS style as we go.
			 */
			for (i = 0; !isspace((unsigned char)s[i]) && s[i]; i++)
			{
				if (s[i] == '.')
					sn->sample_name[i] = '/';
				else if (s[i] == '/')
					sn->sample_name[i] = '.';
				else
					sn->sample_name[i] = s[i];
			}
			/*
			   | The sample name '*' is special and means "no new sound"
			   | so don't store a filename for these mappings.
			 */
			if (i == 1 && sn->sample_name[0] == '*')
			{
				i = 0;
			}
			sn->sample_name[i] = 0;
		}
	}

	/* Close the file */
	fclose(f);

	if (show_sound_alloc)
	{
		int i;
		SampNode *l;

		for (i = 0; i < SOUND_MAX; i++)
		{
			fprintf(dbo, "\n\nEvent '%s'", angband_sound_name[i]);
			fprintf(dbo, " (%d sounds)\n", sample[i].samples);
			for (l = sample[i].samplist; l; l = l->next)
				fprintf(dbo, "\t%s\n", l->sample_name);
		}
		fclose(dbo);
	}

}



/*
 | Try to make sure that PlayIt is loaded.
 | This requires AngSound rel. 4
 */
static void check_playit(void)
{
	if (SWI(2, 0, SWI_OS_Module, 18, "PlayIt"))
	{
		int t;
		SWI(2, 1, SWI_OS_File, 17, "Angsound:LoadPlayIt", &t);
		if (t == 1)
			SWI(1, 0, SWI_OS_CLI,
				"RMEnsure PlayIt 0.00 Run AngSound:LoadPlayIt");
	}
}




static void initialise_sound(void)
{
	/* Load the configuration file */
	Hourglass_On();
	read_sound_config();
	check_playit();
	Hourglass_Off();
}



static void play_sample(char *leafname)
{
	char buffer[260];

	strcpy(buffer, "%playit_stop");

	if (!SWI(1, 0, SWI_OS_CLI, buffer))
	{
		SWI(1, 0, SWI_PlayIt_Volume, sound_volume);
		sprintf(buffer, "%%playit_play %sSound:%s", RISCOS_VARIANT, leafname);
		SWI(1, 0, SWI_OS_CLI, buffer);
	}

	return;
}



static void play_sound(int event)
{
	/* Paranoia */
	if (!sound_initd)
	{
		return;
	}

	/* Paranoia */
	if (event < 0 || event >= SOUND_MAX)
		return;

	/* msg_format("Sound '%s'",angband_sound_name[event]); */

	/* Choose a sample */
	if (sample[event].samples)
	{
		int s = rand() % sample[event].samples;
		SampNode *sn = sample[event].samplist;
		while (s--)
		{
			sn = sn->next;
			if (!sn)
			{
				plog("Adny botched the sound config - please send him a copy of your sound/cfg file.");
			}
		}
		if (*(sn->sample_name))
			play_sample(sn->sample_name);
	}
}




/*--------------------------------------------------------------------------*/

/*
 | This stuff is for the Term_user hook
 */



static void display_line(int x, int y, int c, const char *fmt, ...)
{
	va_list ap;
	char buffer[260];

	va_start(ap, fmt);
	vsprintf(buffer, fmt, ap);
	Term_putstr(x, y, -1, c, buffer);
	va_end(ap);
}



/*
 | Let the user change the alarm message
 */
static void do_alarm_message_input(int y)
{
	int k;
	int inspos = strlen(alarm_message);
	char old_message[52];

	strcpy(old_message, alarm_message);

	do
	{
		display_line(26, y, TERM_YELLOW, "%-51s", alarm_message);
		Term_gotoxy(26 + inspos, y);
		k = inkey();
		switch (k)
		{
			case 21:			/* ^U */
				*alarm_message = 0;
				inspos = 0;
				break;
			case 128:  case 8:	/* delete */
				if (inspos > 0)
				{
					alarm_message[--inspos] = 0;
				}
				break;
			case 27:			/* escape */
				strcpy(alarm_message, old_message);
				k = 13;
				break;
			default:
				if (k > 31 && k < 127 && inspos < 50)
				{
					alarm_message[inspos++] = k;
					alarm_message[inspos] = 0;
				}
		}
	}
	while (k != 13);

	display_line(26, y, TERM_WHITE, "%-51s", alarm_message);
}


#define tum_col(X)  ((X) ? TERM_L_BLUE : TERM_WHITE )
#define tum_onoff(X)  ((X) ? "On " : "Off")

static errr Term_user_acn(int n)
{
	int cursor_state;
	int optn = 0;
	int k, adj;
	int redraw_mung = 0;
	int max_opt = 11;
	int alarm_modified = 0;	/* Will be true if the alarm choices need to be (re)saved */

	/*
	   | Hack: let the desktop front end know that
	   | the user menu is active...
	 */
	user_menu_active = TRUE;


	/*
	   | This is thanks to Norcroft CC...  it seems to want
	   | to set up FP regs nice and early and then relies
	   | on them remaining constant over the function call.
	   | The trouble is that we implicitly call Wimp_Poll
	   | whilst waiting for a key press...
	 */
	event_mask.data.keepfpregisters = 1;

	/*
	   | Hack: alarm type 1 /looks/ the same as type 3 but doesn't get
	   | cancelled as a type 3 would.  This allows alarms to go off and
	   | be cancelled without affecting the alarm type whilst it's being
	   | set up here.
	 */
	if (alarm_type == 3)
	{
		alarm_type = 1;
	}

	/*
	   | Store the screen
	 */
	Term_activate(&(data[0].t));
	Term_save();
	Term_get_cursor(&cursor_state);
	Term_set_cursor(TRUE);

	do
	{
		redraw_mung = 0;
		Term_clear();
		display_line(2, 1, TERM_YELLOW, "%s %s", VARIANT, VERSION);
		display_line(2, 2, TERM_SLATE, "Front-end %s", PORTVERSION);
		display_line(2, 4, TERM_WHITE,
					 "Use cursor up/down to select an option then cursor left/right to alter it.");
		display_line(2, 5, TERM_WHITE,
					 "Hit 'S' to save these settings (alarm settings are saved automatically).");
		display_line(2, 6, TERM_WHITE, "Hit ESC to return to the game.");

		for (k = 0; k < 16; k++)
			display_line(31 + k * 3, 8, k, "##", k);

		do
		{
			display_line(2, 8, tum_col(optn == 0),
						 "     Gamma correction : %.2lf", gamma);
			display_line(2, 9, tum_col(optn == 1), "     Force monochrome : %s",
						 tum_onoff(force_mono));
			display_line(2, 10, tum_col(optn == 2), "        Sound effects : %s",
						 tum_onoff(enable_sound));
			display_line(2, 11, tum_col(optn == 3), "  Sound effect volume : ");
			display_line(26, 11,
						 sound_volume > 127 ? TERM_RED : tum_col(optn == 3),
						 "%-3d", sound_volume);
			display_line(30, 11, tum_col(optn == 3), "(127 = full volume)");
			display_line(2, 12, tum_col(optn == 4), "     Start fullscreen : %s",
						 tum_onoff(start_fullscreen));
			display_line(30, 12, tum_col(optn == 4),
						 "(also selects fullscreen/desktop now)");
			display_line(2, 13, tum_col(optn == 5), "        Use hourglass : %s",
						 tum_onoff(use_glass));
			display_line(2, 14, tum_col(optn == 6),
						 "'Hard' input flushing : %s", tum_onoff(hack_flush));

			display_line(7, 16, tum_col(optn == 7), "      Alarm type : %-20s",
						 alarm_types[alarm_type]);
			display_line(7, 17, TERM_WHITE, "            Time : ");
			display_line(26, 17, tum_col(optn == 8), "%02d", alarm_h);
			display_line(28, 17, TERM_WHITE, ":");
			display_line(29, 17, tum_col(optn == 9), "%02d", alarm_m);
			display_line(7, 18, tum_col(optn == 10), "         Message : %-51s",
						 alarm_message);
			display_line(7, 19, tum_col(optn == 11), "            Beep : %s",
						 tum_onoff(alarm_beep));

#ifdef FE_DEBUG_INFO
			display_line(2, 23, tum_col(optn == 23), "Show debug info");
			max_opt = 12;
#endif

			switch (optn)
			{
				case 12: Term_gotoxy(2, 23);
					break;
				case 11: Term_gotoxy(26, 19);
					break;
				case 10: Term_gotoxy(26, 18);
					break;
				case 9: Term_gotoxy(29, 17);
					break;
				case 8: Term_gotoxy(26, 17);
					break;
				case 7: Term_gotoxy(26, 16);
					break;
				default: Term_gotoxy(26, optn + 8);
			}

			k = inkey();
			adj = (k == '4' || k == 'h') ? -1 : (k == '6' || k == 'l') ? 1 : 0;

			switch (k)
			{
				case 18:		/* Hack: force the screen to update */
					redraw_mung = 1;
					k = 27;
					break;
				case 's':  case 'S':
					save_choices();
					display_line(2, 23, TERM_YELLOW, "Options saved.	   ");
					Term_fresh();
					Term_xtra(TERM_XTRA_DELAY, 750);
					Term_erase(2, 23, 60);
					break;
				case '8':  case 'k':
					if (--optn < 0)
					{
						optn = max_opt;
					}
					break;
				case '2':  case 'j':
					if (++optn > max_opt)
					{
						optn = 0;
					}
					break;
				case 13:  case 32:  case 't':	/* Allow return, space and t to toggle some options */
				case '4':  case 'h':
				case '6':  case 'l':
				{
					switch (optn)
					{
						case 0:	/* Gamma correction */
							gamma += adj * 0.05;
							if (gamma > 9.00)
							{
								gamma = 9.00;
							}
							if (gamma < 0.05)
							{
								gamma = 0.05;
							}
							Term_xtra(TERM_XTRA_REACT, 0);
#ifndef FULLSCREEN_ONLY
							set_gamma_window_state();
#endif /* FULLSCREEN_ONLY */							
							/* flush(); */
							Term_fresh();
							break;
						case 1:	/* Force monochrome */
							force_mono = !force_mono;
							if (fullscreen_font)
								redraw_areaFS(0, 0, 80, 24);
							else
								Term_xtra(TERM_XTRA_REACT, 0);
							/* flush(); */
							Term_fresh();
							break;
						case 2:	/* Sound enable / disable */
							enable_sound = !enable_sound;
#ifndef FULLSCREEN_ONLY
							set_sound_window_state();
#endif /* FULLSCREEN_ONLY */
							if (enable_sound)
							{
								initialise_sound();
							}
							break;
						case 3:	/* Sound volume */
							sound_volume += adj;
							if (sound_volume < SOUND_VOL_MIN)
								sound_volume = SOUND_VOL_MIN;
							if (sound_volume > SOUND_VOL_MAX)
								sound_volume = SOUND_VOL_MAX;
#ifndef FULLSCREEN_ONLY
							set_sound_window_state();
#endif /* FULLSCREEN_ONLY */
							break;
						case 4:	/* Start fullscreen */
							start_fullscreen = !start_fullscreen;
							if (start_fullscreen)
								enter_fullscreen_mode();
							else if (!minimise_memory)
								leave_fullscreen_mode();
							break;
						case 5:	/* Start fullscreen */
							use_glass = !use_glass;
							if (!use_glass)
							{
								if (glass_on)
								{
									Hourglass_Off();
								}
								glass_on = 0;
							}
							break;
						case 6:	/* hack flush */
							hack_flush = !hack_flush;
							break;
						case 7:	/* Alarm on/off */
							alarm_type += adj;
							if (adj)
							{
								alarm_modified = 1;
							}
							if (alarm_type > 2)
							{
								alarm_type = 0;
							}
							if (alarm_type < 0)
							{
								alarm_type = 2;
							}
							if (!alarm_type && alarm_disp)
							{
								ack_alarm();
							}	/* XXXXX Cancel an already active alarm? */
							break;
						case 8:	/* Alarm hours */
							alarm_h += adj;
							if (adj)
							{
								alarm_modified = 1;
							}
							if (alarm_h < 0)
							{
								alarm_h += 24;
							}
							if (alarm_h > 23)
							{
								alarm_h -= 24;
							}
							if (alarm_disp)
							{
								ack_alarm();
							}
							break;
						case 9:	/* Alarm minutes */
							alarm_m += adj;
							if (adj)
							{
								alarm_modified = 1;
							}
							if (alarm_m < 0)
							{
								alarm_m += 60;
							}
							if (alarm_m > 59)
							{
								alarm_m -= 60;
							}
							if (alarm_disp)
							{
								ack_alarm();
							}
							break;
						case 10:
							alarm_modified = 1;
							do_alarm_message_input(18);
							break;
						case 11:
							alarm_modified = 1;
							alarm_beep = !alarm_beep;
							break;
						case 12:
							show_debug_info();
							redraw_mung = 1;
							k = 27;
							break;
					}
				}
			}
		}
		while (k != 27);
	}
	while (redraw_mung);

	/* Rehack the alarm type: */
	if (alarm_type == 1)
	{
		alarm_type = 3;
	}

	if (alarm_modified)
	{
		write_alarm_choices();
	}

	Term_set_cursor(cursor_state);

	/* Restore the screen */
	Term_load();

	/* Don't need to preserve FP regs any more */
	event_mask.data.keepfpregisters = 0;

	/*
	   | Hack: tell the desktop front end that we're done.
	 */
	user_menu_active = FALSE;

	return 0;
}




/*--------------------------------------------------------------------------*/

#ifdef USE_FILECACHE

/*
 | 'Random' File-cacheing for *band.
 |
 | Rewritten since as of Zang 225 the mechanism for handling
 | these files has changed dramatically and the old system
 | is no longer viable.
 |
 | These new functions basically provide an alternative to the
 | normal my_fopen() (or fopen()) and my_fgets() functions.
 |
 | To use the file caching it is therefore necessary to alter
 | files.c to call cached_fopen(), cached_fclose() and cached_fgets()
 | rather than the normal functions.
 |
 | Note that these funtions will only work for files that are intended
 | to be read as a series of \n terminated lines of ASCII text using my_fgets().
 |
 */

/*
 | Hack: use the game's dynamic area if possible:
 */
#define fc_malloc(X) (g_malloc(X))
#define fc_free(X) (g_free(X,0))

#ifndef ABBR_FILECACHE
/*
 | Make these to do nothing.  They'll never
 | be called anyway.  Having them present makes
 | for neater code later on (ie. we use a variable
 | rather than the pre-processor to decide whether
 | to do compression).
 */
static int compress_string(char *os, char *s)
{
	core("main-acn internal logic error 001");
	return 0;
}
static int decompress_string(char *d, char *s, int max_len)
{
	core("main-acn internal logic error 002");
	return 0;
}
static int compressed_length(char *s)
{
	core("main-acn internal logic error 003");
	return 0;
}

#else

/*
 | When caching files we try to use some abbreviations.
 | We use both whole words and pairs of letters.
 | NB: For this to work, the file must contain only
 | 7 bit characters.
 */
static char *abbrv_w[] =
{
	/* These words all begin with a space */
	" of ", " the ", " you ", " to ", " a ", " says", " is ", " that ", " and ",
	" your ", " are ", " it ", " be ", " for ", " me", " will ", " in ",
	" not ", " this ", " have ", " can ", " on ", " my ", " with ", " say ",
	" all", " by ", " get ", " but ", " just ", " die", " as ", " time ",
		" if ",
	" like ",
	/* These words do not */
	"I ", "The ", "You ", "They ", "It ", "don", 0
};

/* Number of words */
#define FC_ABBRV_NUMWORDS 41

/* Number of them that don't start with a space */
#define FC_ABBRV_NONSPC   6

/*
 | NB: No letter pair may start with \0.
 */
static char abbrv_lp[] =
	"e  ttht s heiner aoure'\0, anonf  sd y r  ongofator.\0"
	"n arllstha wes m ieaisen bl  yndtoo yometele d f hve"
	"ayuralitneelN: chig ilroassaseliti lraa otedbede 'ri" "..u  nntno!'ee\0\0";


/*
 | Compress the given string using the abbreviation tables above.
 | Returns compressed length *including* terminator (it may
 | be part of an abbreviation, you see...)
 | Note that we can compress the string in-place, ie. 'os' may be
 | the same as 's'.
 */
static int compress_string(char *os, char *s)
{
	char *o, *f, *d;
	int i;

	o = os;

	while (*s)
	{
		int fw, lw;
		if (*s == ' ')
		{
			fw = 0;
			lw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC;
		}
		else
		{
			fw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC;
			lw = FC_ABBRV_NUMWORDS;
		}
		for (i = fw; i < lw; i++)
		{
			d = abbrv_w[i];		/* Word to check against */
			for (f = s; *f && *f == *d; f++, d++)
				;
			if (*d == 0)		/* Match? */
			{
				s = *f ? f : f - 1;	/* Update string pointer */
				*o++ = 128 + i;	/* store code */
				break;			/* Quit looking for words */
			}
		}

		/* Do we need to check the letter pairs? */
		if (i == lw)
		{
			for (i = 0; abbrv_lp[i]; i += 2)
			{
				if (s[0] == abbrv_lp[i] && s[1] == abbrv_lp[i + 1])
				{
					*o++ = 128 + FC_ABBRV_NUMWORDS + i / 2;
					/* NB: If the next character is the terminator then we're done. */
					if (!s[1])
					{
						return (o - os);
					}
					s += 2;		/* Quit looking for letters */
					break;
				}
			}
			/* NB: This next check is only safe because no letter pair starts with a NULL */
			if (!abbrv_lp[i])
				*o++ = *s++;
		}
	}

	/* Don't forget that terminator! */
	*o++ = 0;

	return o - os;
}

/*
 | As compress_string (above), but stores nothing and
 | only returns the length of the compressed string.
 */
static int compressed_length(char *s)
{
	char *f, *d;
	int i, l;

	l = 0;
	while (*s)
	{
		int fw, lw;
		if (*s == ' ')
		{
			fw = 0;
			lw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC;
		}
		else
		{
			fw = FC_ABBRV_NUMWORDS - FC_ABBRV_NONSPC;
			lw = FC_ABBRV_NUMWORDS;
		}
		for (i = fw; i < lw; i++)
		{
			d = abbrv_w[i];
			for (f = s; *f && *f == *d; f++, d++)
				;
			if (*d == 0)		/* Match? */
			{
				s = *f ? f : f - 1;	/* Update string pointer */
				l++;			/* increment output length */
				break;			/* Quit looking for words */
			}
		}

		/* Do we need to check the letter pairs? */
		if (i == lw)
		{
			for (i = 0; abbrv_lp[i]; i += 2)
			{
				if (s[0] == abbrv_lp[i] && s[1] == abbrv_lp[i + 1])
				{
					l++;		/* increment output length */
					/* NB: If the next character is the terminator then we're done. */
					if (!s[1])
					{
						return l;
					}
					s += 2;		/* Quit looking for letters */
					break;
				}
			}
			/* NB: This next check is only safe because no letter pair starts with a NULL */
			if (!abbrv_lp[i])
			{
				l++;
				s++;
			}
		}
	}
	/* Don't forget that terminator! */
	return l + 1;
}



/*
 | Decompress the given string 's' into the buffer at 'd'.
 | At most, max_len characters (incl. \0 terminator) will be
 | written into d.
 | Returns the length of 's'.
 */
static int decompress_string(char *d, char *s, int max_len)
{
	char *os = s;

	while (max_len > 1)
	{
		int nc = *s++;	/* Get next character */

		if (nc < 128)			/* Is it a plain character? */
		{
			if (0 == (*d++ = nc))
			{
				break;
			}
			max_len--;
		}
		else					/* Abbreviation to expand. */
		{
			if (nc >= FC_ABBRV_NUMWORDS + 128)	/* Letter pair? */
			{
				*d++ = abbrv_lp[(nc - (FC_ABBRV_NUMWORDS + 128)) * 2];
				if (0 ==
					(*d++ = abbrv_lp[(nc - (FC_ABBRV_NUMWORDS + 128)) * 2 + 1]))
					break;
				max_len -= 2;
			}
			else				/* It's a word */
			{
				char *ws = abbrv_w[nc - 128];
				while (*ws && max_len > 1)
				{
					*d++ = *ws++;
					max_len--;
				}
			}
		}
	}

	/* Skip over the rest of the abbreviated string if we ran out of space */
	if (max_len <= 1)			/* Out of space? */
	{
		int nc;
		*d = 0;					/* Terminate */
		do
		{
			nc = *s++;			/* Next char */
			if (nc >= 128 + FC_ABBRV_NUMWORDS)	/* Ignore words */
				nc = abbrv_lp[(nc - (FC_ABBRV_NUMWORDS + 128) * 2) + 1];	/* Only check 2nd letter of pair */
		}
		while (nc);
	}
	return s - os;				/* Length of abbreviated string */
}

#endif /* ABBR_FILECACHE */


/* Each entry in the cache looks like this: */
typedef struct fce_
{
	char *name;	/* canonical pathname of file */
	char *text;	/* text (be it compressed or not) */
	char *eof;	/* byte beyond the last byte of text */
	int used;	/* access counter when the file was last used */
	int compressed;	/* compression method, (ie. 0 for none or 1 for abbreviations) */
}
FileCacheEntry;

/*
 | The handles we chuck around are pointers to one of these structs.
 | Note that since we actually return (and take) |FILE*|s we just
 | compare the value of a |FILE*| with the limits of the array of
 | |CachedFileHandle|s to decide whether its 'ours' or a genuine
 | (ie. stdio) file handle.  This /is/ pretty lame, I know...
 */
typedef struct cfh_
{
	char *ptr;	/* sequential file pointer, as it were */
	FileCacheEntry *fce;	/* ->the file-cache entry data */
}
CachedFileHandle;

#define MAX_OPEN_CACHED_FILES	16	/* We allow up to 16 of these files open at once */
#define MAX_CACHE_ENTRIES		64	/* We allow up to 64 cache entries */

static FileCacheEntry *file_cache;	/* to be used as file_cache[MAX_CACHE_ENTRIES] */
static CachedFileHandle *cached_file_handle;	/* to be used as cached_file_handle[MAX_OPEN_CACHED_FILES] */
static int file_cache_initd = 0;	/* Is the cache initialised? */
static int file_cache_size = 0;	/* Total size of the cached files */
static int fc_access_counter = 1;	/* incremented on each cache access */
/*
 | Pre-calculate max. possible value of a FILE* (ie. address in memory)
 | that could be a valid |CachedFileHandle*|.
 */
static FILE *max_cfh_addr;	/* == (FILE*) (&(cached_file_handle[MAX_OPEN_CACHED_FILES-1])) */

/*
 | Initialise the file cache
 */
static void init_file_cache(void)
{
	int i;

	/* Allocate storage */
	file_cache = fc_malloc(MAX_CACHE_ENTRIES * sizeof(FileCacheEntry));
	cached_file_handle =
		fc_malloc(MAX_OPEN_CACHED_FILES * sizeof(CachedFileHandle));

	if (!file_cache || !cached_file_handle)
	{
		/* Disable file-caching */
		if (file_cache)
		{
			fc_free(file_cache);
		}
		if (cached_file_handle)
		{
			fc_free(cached_file_handle);
		}
		use_filecache = 0;
	}
	else
	{
		/* Initialise the cache */
		for (i = 0; i < MAX_CACHE_ENTRIES; i++)
			file_cache[i].name = NULL;
		for (i = 0; i < MAX_OPEN_CACHED_FILES; i++)
			cached_file_handle[i].fce = NULL;
		fc_access_counter = 1;
		file_cache_size = 0;
		max_cfh_addr =
			(FILE *)(&(cached_file_handle[MAX_OPEN_CACHED_FILES - 1]));
	}
	file_cache_initd = 1;
}


/*
 | Helper: take a copy of the string and return a pointer to it
 */
static char *string_cpy(char *s)
{
	char *d = fc_malloc(strlen(s) + 1L);
	if (d)
	{
		strcpy(d, s);
	}
	return d;
}


/*
 | Cache the specified file, returning either the cache entry
 | that it has been cached at, or NULL for failure.
 |
 | Note that for the abbreviated file cache a temporary file
 | is used to allow the compression to be applied just once.
 | (otherwise it has to be done twice - once to determine the
 | eventual compressed size and once to actually store and compress
 | it).
 */
static FileCacheEntry *cache_file(char *name)
{
	int i, size = 0;
	FILE *fp;
	char buffer[1024];
	char *d;

	FILE *tf = NULL;	/* Used if abbr_filecache and abbr_tmpfile are set */
	char cfn[1024];	/* Used if abbr_filecache and abbr_tmpfile are set */

	/* Find the first free slot in the cache */
	for (i = 0; i < MAX_CACHE_ENTRIES; i++)
		if (!file_cache[i].name)
			break;

	/* No more entries? */
	if (i >= MAX_CACHE_ENTRIES)
	{
		return NULL;
	}

	/* Set up the info on the file */
	if ((file_cache[i].name = string_cpy(name)) == NULL)
	{
		return NULL;
	}

	/* Open the file */
	fp = my_fopen(name, "r");
	if (!fp)
	{
		fc_free(file_cache[i].name);
		file_cache[i].name = 0;
		return NULL;
	}

	/* Open/create tempfile if need be: */
	if (abbr_filecache && abbr_tmpfile)
	{
		/* Hack: Form the pathname of the cached compressed file (in canonical form) */
		sprintf(cfn, "%s%s", scrap_path,
				riscosify_name(name + strlen(resource_path)));
		/* Ensure that that particular directory exists... */
		ensure_path(cfn);
		/* Check whether cache file is out of date */
		if (file_is_newer(riscosify_name(name), cfn))
		{
			tf = fopen(cfn, "wb");
			size = 0;
		}
		else
		{
			tf = fopen(cfn, "rb");
			if (tf)
			{
				size = myFile_Size(cfn);
			}
		}
	}

	/* If we don't have the cached file (but want it), compress the source text to it */
	if (tf)
	{
		if (!size)
		{
			int k;
			while (!my_fgets(fp, buffer, sizeof(buffer)))
			{
				if (smart_filecache && (!*buffer || *buffer == '#'))
					continue;
				k = compress_string(buffer, buffer);
				if (fwrite(buffer, 1, k, tf) != k)
				{
					fclose(tf);
					remove(cfn);
					core("error writing tempfile");
				}
				size += k;
			}
			fclose(tf);
			tf = fopen(cfn, "rb");
		}
	}
	else
	{
		/* Count the number of bytes */
		while (!my_fgets(fp, buffer, sizeof(buffer)))
		{
			if (smart_filecache && (!*buffer || *buffer == '#'))
				continue;
			if (abbr_filecache)
				size += compressed_length(buffer);
			else
				size += strlen(buffer) + 1;
		}
	}

	/* Close the (source) file */
	my_fclose(fp);

	/* Allocate enough storage for the text */
	file_cache[i].text = fc_malloc(size + 1L);
	if (!file_cache[i].text)
	{
		fc_free(file_cache[i].name);
		file_cache[i].name = 0;
		if (tf)
		{
			fclose(tf);
		}
		return NULL;
	}

	/* Do we have a tempfile to load? */
	if (tf)
	{
		if (fread(file_cache[i].text, 1, size, tf) != size)
			core("error reading tempfile");
		fclose(tf);
	}
	else
	{
		/* Re-open the file... */
		fp = my_fopen(name, "r");
		if (!fp)
		{
			fc_free(file_cache[i].name);
			fc_free(file_cache[i].text);
			file_cache[i].name = 0;
			return NULL;
		}

		/* And read it into the buffer... */
		d = file_cache[i].text;
		while (!my_fgets(fp, buffer, sizeof(buffer)))
		{
			if (smart_filecache && (!*buffer || *buffer == '#'))
				continue;
			if (abbr_filecache)
				d += compress_string(d, buffer);
			else
			{
				strcpy(d, buffer);
				d += strlen(buffer) + 1;
			}
		}

		if ((d - file_cache[i].text) != size)
		{
			debug("Calculated size is %d, pointer offset is %d", size,
				  (d - file_cache[i].text));
			core("Cached file is larger than calculated!");
		}

		/* Close the file */
		my_fclose(fp);
	}

	/* Set up the 'last accessed' value, etc. */
	file_cache[i].used = fc_access_counter++;
	file_cache[i].eof = file_cache[i].text + size;
	file_cache[i].compressed = abbr_filecache;
	file_cache_size += size;

	/* Return success */
	return &(file_cache[i]);
}


/*
 | Discard a file from the cache
 */
static void discard_cached_file(int i)
{
	if (!file_cache[i].name)
	{
		return;
	}							/* invalid request */
	fc_free(file_cache[i].text);
	fc_free(file_cache[i].name);
	file_cache_size -= (file_cache[i].eof) - (file_cache[i].text);
	file_cache[i].name = 0;
}


/*
 | Attempt to flush as much of the cache as required
 | to bring it within the size limit.
 | If protect != 0 then that entry in the cache won't be flushed.
 */
static void flush_file_cache(FileCacheEntry * protect)
{
	int i, j, done;
	int oldest_u, oldest_e;
	FileCacheEntry *fce;
	int needed = (4 << 10);	/* Hack: try to free at least 4K */

	done = (file_cache_size + needed) <= max_file_cache_size;

	while (!done)
	{
		oldest_u = fc_access_counter;
		oldest_e = -1;

		fce = file_cache;
		/* Find oldest entry that isn't in use */
		for (i = 0; i < MAX_CACHE_ENTRIES; fce++, i++)
		{
			if (fce == protect)
			{
				continue;
			}					/* Hack ;) */
			if (fce->name)		/* Is this cache slot full? */
			{
				for (j = 0; j < MAX_OPEN_CACHED_FILES; j++)
					if (cached_file_handle[j].fce == fce)
						break;
				if (j < MAX_OPEN_CACHED_FILES)
					continue;	/* Cached file is still open */
				if (fce->used < oldest_u)
				{
					oldest_e = i;
					oldest_u = file_cache[i].used;
				}
			}
		}

		if (oldest_e < 0)
			done = 1;			/* We can flush nothing more */
		else
		{
			discard_cached_file(oldest_e);
			done = (file_cache_size + needed) <= max_file_cache_size;
		}
	}
}


/*
 | Locate the specified file within the cache.
 | Returns NULL if the file is not cached
 */
static FileCacheEntry *find_cached_file(char *name)
{
	int i;
	FileCacheEntry *fce = file_cache;

	for (i = 0; i < MAX_CACHE_ENTRIES; i++, fce++)
	{
		if (fce->name)
			if (streq(fce->name, name))
				return fce;
	}
	return NULL;
}



/*--------------------------------------------------------------------------*/
/* Externally visible file cache stuff										*/
/*--------------------------------------------------------------------------*/

/*
 | Open a file...
 | Returns the file cache handle of the file, or NULL for failure.
 | Note that if mode is anything other than "r" the call defers to
 | my_fopen().
 |
 | NB: The returned handle is almost certainly *NOT* a |FILE*|
 | (although it may be if the cache cannot accomodate the file).
 |
 | Therefore, you *MUST* ensure that any file opened with cached_fopen()
 | is only ever accessed via cached_fgets() and cached_fclose().
 |
 | Failure to do so will result in, ahem, unpleasantness.  Extreme
 | unpleasantness.
 */
FILE *cached_fopen(char *name, char *mode)
{
	FileCacheEntry *fcs = NULL;
	int fch;

	if (strcmp(mode, "r") || !use_filecache)
		return my_fopen(name, mode);

	if (!file_cache_initd)
	{
		init_file_cache();
	}

	if (max_file_cache_size >= 0)
	{
		/* Find a free cache entry */
		for (fch = 0; fch < MAX_OPEN_CACHED_FILES; fch++)
			if (!cached_file_handle[fch].fce)
				break;

		/* Out of handles? */
		if (fch >= MAX_OPEN_CACHED_FILES)
			return my_fopen(name, mode);

		/* Is the file already cached? */
		fcs = find_cached_file(name);
		if (!fcs)
		{
			/* File wasn't cached, so cache it */
			flush_file_cache(NULL);	/* Clean stuff out of the cache if need be */
			fcs = cache_file(name);	/* Cache the new file */
			flush_file_cache(fcs);	/* Flush, but keep the latest file */
		}
	}

	/* Did we fail to cache the file? */
	if (!fcs)
	{
		return my_fopen(name, mode);
	}

	/* File was cached OK */
	cached_file_handle[fch].ptr = fcs->text;	/* Init sequential pointer */
	cached_file_handle[fch].fce = fcs;	/* Cache block pointer */
	fcs->used = fc_access_counter++;	/* Opening the file counts as an access */

	return (FILE *)(&cached_file_handle[fch]);
}


/*
 | Close a file
 */
errr cached_fclose(FILE *fch_)
{
	CachedFileHandle *fch;

	/* Is the FILE* genuine? */
	if ((fch_ < (FILE *)cached_file_handle) || (fch_ > max_cfh_addr))
		return my_fclose(fch_);

	fch = (CachedFileHandle *) fch_;

	/* Check for "Ooopses": */
	if (fch->fce == NULL)
		core("cached_fclose called on a non-open file handle");

	flush_file_cache(NULL);		/* Clean out the cache if need be */
	fch->fce = NULL;			/* Mark file handle as inactive */

	return 0;
}


/*
 | Do the my_fgets thing on a file
 */
errr cached_fgets(FILE *fch_, char *buffer, int max_len)
{
	CachedFileHandle *fch;
	char *eof;
	char *ptr;

	/* Is the FILE* genuine? */
	if ((fch_ < (FILE *)cached_file_handle) || (fch_ > max_cfh_addr))
		return my_fgets(fch_, buffer, max_len);

	fch = (CachedFileHandle *) fch_;

	/* Check for "Oopses": */
	if (!file_cache_initd)
		core("cached_fgets() on uninitialised file-cache");
	if (!fch->fce)
		core("cached_fgets called for a un-open file");

	eof = fch->fce->eof;
	ptr = fch->ptr;

	/* Out of bounds? */
	if (ptr >= eof)
	{
		return 1;
	}							/* Read failed */

	/*
	   | Read the next line, up to \0 (which would have v=been \n in the original file),
	   | or max_len-1 characters
	 */
	if (fch->fce->compressed)
		ptr += decompress_string(buffer, ptr, max_len);
	else
	{
		if (eof - ptr < max_len)
		{
			max_len = eof - ptr;
		}
		for (; max_len >= 1; max_len--)
			if ((*buffer++ = *ptr++) == 0)
				break;
		*buffer = 0;			/* terminate (paranoia) */
	}

	/* Update sequential pointer */
	fch->ptr = ptr;

	return 0;
}

#endif /* USE_FILECACHE */


/*
 | This section deals with checking that the .raw files are up to date
 | wrt to the .txt files.  Note that this function won't work for RISC OS 2
 | (due to the lack of OS_Args 7) so it simply returns 0 to indicate that
 | the file isn't OOD.
 |
 | For this to work, the equivalent function (in init2.c) needs to be
 | #if-d out (and this function should be declared).  You'll probably
 | also need to zap the UNIX #includes at the top of the file
 */

extern errr check_modification_date(int fd, cptr template_file)
{
	char raw_buf[1024];
	char txt_buf[1024];
	int i;
	os_error *e;

	if (os_version() < 300)
	{
		return 0;
	}

	/* Use OS_Args 7 to find out the pathname 'fd' refers to */
	e = SWI(6, 0, SWI_OS_Args,
			/* In: */
			7,					/* Get path from filehandle */
			fd,					/* file handle */
			raw_buf,			/* buffer */
			0, 0,				/* unused */
			1024				/* size of buffer */
			/* No output regs used */
		);
	if (e)
	{
		core(e->errmess);
	}

	/* Build the path to the template_file */
	path_build(txt_buf, sizeof(txt_buf), ANGBAND_DIR_EDIT, template_file);

	i = file_is_newer(riscosify_name(txt_buf), raw_buf);

	return i;
}


/*--------------------------------------------------------------------------*/

/*
 | This is the hideous IClear hack.  Basically what we do is to take a copy
 | of the module and kill it in the RMA.  Then, on return to the desktop
 | we reinstate the module.
 |
 | NB: This is truly, truly evil.
 */

static int *iclear_module = NULL;

/*
 | Start the IClear hack
 */
static void iclear_hack(void)
{
	os_error *e;
	int code = 0;
	int *i;

	/* Get base address of module */
	e = SWI(2, 4, SWI_OS_Module, 18, "IClear", 0, 0, 0, &code);
	if (e || !code)
		return;

	/* Module size is at code!-4 */
	i = (int *)code;
	iclear_module = malloc(i[-1] + 4);
	if (!iclear_module)
		return;

	/* Copy the module */
	*iclear_module = i[-1];
	memcpy(iclear_module + 1, (void *)code, i[-1]);

	/* Kill the current version */
	e = SWI(2, 0, SWI_OS_Module, 4, "IClear");
	if (e)
	{
		free(iclear_module);
		iclear_module = NULL;
	}
}


/*
 | Remove the IClear hack
 */
static void remove_iclear_hack(void)
{
	os_error *e;

	if (!iclear_module)
		return;

	e = SWI(3, 0, SWI_OS_Module, 11, iclear_module + 1, *iclear_module);
	if (e)
		debug("Failed to reinstall IClear: %s", e->errmess);

	free(iclear_module);
	iclear_module = NULL;
}



/*--------------------------------------------------------------------------*/

/* Alarm functions */
static int alarm_ackd = 0;	/* has the alarm been acknowledged? */
static window_handle aw = 0;	/* alarm window */

/*
 | Is the alarm due to go off, ie. is it enabled, and if so
 | does the current time match the alarm time?
 */
static void check_alarm()
{
	time_t t;
	struct tm *lt;

	alarm_lastcheck = Time_Monotonic();

	time(&t);
	lt = localtime(&t);
	if (lt->tm_hour == alarm_h && lt->tm_min == alarm_m)
	{
		if (!alarm_ackd) alarm_disp = 1;
	}
	else
	{
		alarm_ackd = 0;
	}

	/* Hack: if the alarm has already been acknowledged then don't re-trigger it */
	if (alarm_ackd)
	{
		alarm_disp = 0;
	}

	/* Hack: if the alarm should make a noise, then make one: */
	if (alarm_disp && alarm_beep == 1)
	{
		static unsigned int last_beep = 0;
		unsigned int t = Time_Monotonic();
		if (t >= last_beep + 100)
		{
			Sound_SysBeep();
			last_beep = t;
		}
	}

	/*
	   | If we're in the desktop then fire the alarm off if need be.
	   | If we aren't then do nothing - the fullscreen bored() function
	   | will take care of the alarm.
	 */
#ifndef FULLSCREEN_ONLY
	if (!fullscreen_font && alarm_disp)
		trigger_alarm_desktop();
#endif /* FULLSCREEN_ONLY */		
}


static void ack_alarm(void)
{
	if (aw)
	{
		Window_Delete(aw);
		aw = 0;
	}
	alarm_ackd = 1;
	alarm_disp = 0;

	if (alarm_type == 3)
	{
		/* One shot alarm */
		alarm_type = 0;
		write_alarm_choices();
	}

}

#ifndef FULLSCREEN_ONLY
/*
 | Click in the (desktop) alarm window
 */
static BOOL Hnd_AlarmClick(event_pollblock * pb, void *ref)
{
	ack_alarm();
	return TRUE;
}


/*
 | The alarm has gone off in the desktop
 */
static void trigger_alarm_desktop(void)
{
	char buffer[120];
	if (aw)
		return;

	aw = Window_Create("alarm", template_TITLEMIN);
	if (!aw)
	{
		core("failed to create Alarm window!");
	}
	sprintf(buffer, "Alarm from %s", VARIANT);
	Window_SetTitle(aw, buffer);
	Event_Claim(event_CLICK, aw, 0, Hnd_AlarmClick, NULL);
	Event_Claim(event_CLOSE, aw, event_ANY, Hnd_AlarmClick, NULL);

	Icon_printf(aw, 1, "An alarm was set for %02d:%02d", alarm_h, alarm_m);
	Icon_SetText(aw, 2, alarm_message);
	Window_Show(aw, open_CENTERED);
}

#endif /* FULLSCREEN_ONLY */


/*--------------------------------------------------------------------------*/

#ifndef FE_DEBUG_INFO
static void show_debug_info(void)
{
	core("main-acn internal logic error 004");
}
#else

static int debug_cx = 0;
static int debug_cy = 0;
static int debug_cl = TERM_WHITE;
static int debug_sl = 0;


static void debug_cls(void)
{
	Term_clear();
	debug_cx = debug_cy = debug_sl = 0;
}

static void debug_tcol(int c)
{
	debug_cl = c;
}


static void debug_scroll(void)
{
	char **c = ((term_data *)Term)->t.scr->c;	/* char array [24][80] */
	byte **a = ((term_data *)Term)->t.scr->a;	/* attr array [24][80] */
	int cc;
	char tmp[82];
	int y, x, p;

	cc = a[1][0];

	for (y = 1; y < 23; y++)
	{
		for (x = p = 0; x < 80; x++)
		{
			if (a[y][x] != cc)
			{
				tmp[p] = 0;
				Term_putstr(x - p, y - 1, p, cc, tmp);
				p = 0;
				cc = a[y][x];
			}
			tmp[p++] = c[y][x];
		}
		Term_putstr(x - p, y - 1, p, cc, tmp);
	}

	Term_erase(0, 22, 80);
}


static void debug_print_line(char *l)
{
	char *le;
	int cr = 0;

	/* Handle scrolling */
	if (debug_cy > 22)
	{
		debug_cy = 22;
		if (--debug_sl < 0)
		{
			int k;
			display_line(0, 23, TERM_YELLOW, "[RET one line, SPC one page]");
			do
			{
				k = inkey();
			}
			while (k != 32 && k != 13);
			Term_erase(0, 23, 79);
			debug_sl = k == 32 ? 21 : 0;
		}
		debug_scroll();
	}

	/* Hack: check for NL */
	for (le = l; *le; le++)
		if (*le == '\n')
		{
			cr = 1;
			break;
		}

	/* display text */
	Term_putstr(debug_cx, debug_cy, le - l, debug_cl, l);

	/* move cursor */
	if (!cr)
	{
		debug_cx += (le - l);
		if (debug_cx >= 80)
		{
			cr = 1;
		}
	}
	if (cr)
	{
		debug_cx = 0;
		debug_cy += 1;
	}

	Term_gotoxy(debug_cx, debug_cy);

}


static int debug_next_line(char *lb, char **t, int cx)
{
	int i = 0;
	char *lt = *t;

	if (!*lt)
	{
		return -1;
	}							/* Out of text */

	while (*lt && cx < 80)
	{
		lb[i] = *lt++;

		if (lb[i] == '\n')		/* New line */
		{
			cx = 0;				/* Cursor x will be 0 after displaying */
			i++;				/* Keep the \n in the output */
			break;				/* All done */
		}
		else if (lb[i] == '\t')	/* Tab */
		{
			while (cx < 80)
			{
				lb[i++] = ' ';
				cx++;
				if ((cx & 7) == 0)
				{
					break;
				}
			}
		}
		else					/* Anything else */
		{
			cx++;
			i++;
		}
	}

	lb[i] = 0;					/* terminate line buffer */
	*t = lt;					/* update text pointer */
	return cx;					/* return cursor x after printing */
}

static void debug_printf(char *fmt, ...)
{
	char buffer[1024];
	char line[82];
	va_list ap;
	char *p = buffer;

	va_start(ap, fmt);
	vsprintf(buffer, fmt, ap);
	va_end(ap);

	/* Now split the string into display lines */
	while (debug_next_line(line, &p, debug_cx) >= 0)
		debug_print_line(line);
}


static void debug_version_info(void)
{
	debug_tcol(TERM_YELLOW);

	debug_printf("\n\nMisc. Info:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\tVariant name = \"%s\"\n", VARIANT);
	debug_printf("\tFront-end version: %s\n", PORTVERSION);
	debug_printf("\tFront-end compiled: %s %s\n", __TIME__, __DATE__);
	debug_printf("\tCompile time flags:\n");

#ifdef USE_FILECACHE
	debug_printf("\t\tUSE_FILECACHE\n");
#endif

#ifdef ABBR_FILECACHE
	debug_printf("\t\tABBR_FILECACHE\n");
#endif

#ifdef SMART_FILECACHE
	debug_printf("\t\tSMART_FILECACHE\n");
#endif

	debug_tcol(TERM_YELLOW);
	debug_printf("\nResource path:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\t\"%s\"\n", resource_path);

	debug_tcol(TERM_YELLOW);
	debug_printf("\nTempfile path:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\t\"%s\"\n", scrap_path);
	debug_printf("\tScrapfiles are %s deleted at exit.\n",
				 (flush_scrap ? "" : "NOT"));

	debug_tcol(TERM_YELLOW);
	debug_printf("\nChoices files:\n");
	debug_tcol(TERM_L_BLUE);
	debug_printf("\tDesired files:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\tPrimary (r/w): \"%s\"\n", choices_file[CHFILE_WRITE]);
	debug_printf("\t Fallback (r): \"%s\"\n", choices_file[CHFILE_READ]);
	debug_printf("\t Mirror (r/w): \"%s\"\n", choices_file[CHFILE_MIRROR]);
	debug_tcol(TERM_L_BLUE);
	debug_printf("\tActual files:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\t		Write: \"%s\"\n", find_choices(TRUE));
	debug_printf("\t		 Read: \"%s\"\n", find_choices(FALSE));

	debug_tcol(TERM_YELLOW);
	debug_printf("\nAlarm files:\n");
	debug_tcol(TERM_L_BLUE);
	debug_printf("\tDesired files:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\tPrimary (r/w): \"%s\"\n", alarm_file[CHFILE_WRITE]);
	debug_printf("\t Fallback (r): \"%s\"\n", alarm_file[CHFILE_READ]);
	debug_tcol(TERM_L_BLUE);
	debug_printf("\tActual files:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\t		Write: \"%s\"\n", find_alarmfile(TRUE));
	debug_printf("\t		 Read: \"%s\"\n", find_alarmfile(FALSE));
#ifdef USE_DA
	debug_tcol(TERM_YELLOW);
	debug_printf("\nDynamic areas:\n");
	debug_tcol(TERM_WHITE);
	debug_printf("\tFontcache DA = %d\t", font_area);
	debug_printf("size = %d\theap size = %d\n", font_area_size, font_heap_size);
	debug_printf("\t   ralloc DA = %d\t", game_area);
	debug_printf("size = %d\theap size = %d\n", game_area_size, game_heap_size);
#endif
}


static void debug_filecache_info(void)
{
#ifndef USE_FILECACHE
	debug_tcol(TERM_L_DARK);
	debug_printf("File cache disabled at compile time.\n");
#else
	int j, k;
	int t, cs, ucs, cf;

	cf = cs = ucs = j = k = 0;	/* To stop an usused warning if USE_FILECACHE is undefined */
	t = strlen(resource_path);

	if (!file_cache_initd)
	{
		init_file_cache();
	}							/* Paranoia */
	debug_tcol(TERM_YELLOW);
	debug_printf("\nFilecache contents:\n");
	debug_tcol(TERM_L_BLUE);
	debug_printf("Flags: Smart=%d;  Abbrv=%d;  Slave=%d;   Enable=%d\n",
				 smart_filecache, abbr_filecache, abbr_tmpfile, use_filecache);
	debug_tcol(TERM_SLATE);
	if (smart_filecache || abbr_filecache)
		debug_printf("\t\t%3s  %6s/%-6s  %6s  %6s  Path (relative to lib/)\n",
					 "Hnd", "Cache", "Disc", "Time", "Status");
	else
		debug_printf("\t\t%3s  %6s  %6s  %6s  Path (relative to lib/)\n", "Hnd",
					 "Size", "Time", "Status");

	for (j = 0; j < MAX_CACHE_ENTRIES; j++)
	{
		FileCacheEntry *fce = &(file_cache[j]);
		if (fce->name)
		{
			cf++;
			debug_tcol(TERM_L_GREEN);
			debug_printf("\t\t%3d  ", j);
			debug_tcol(TERM_L_UMBER);
			if (!smart_filecache && !abbr_filecache)
				debug_printf("%6d  ", fce->eof - fce->text);
			else
			{
				debug_printf("%6d/", fce->eof - fce->text);
				k = myFile_Size(riscosify_name(fce->name));
				debug_printf("%-6d  ", k);
				if (k > 0)
				{
					ucs += k;
				}
			}
			cs += fce->eof - fce->text;
			debug_printf("%6d  ", fce->used);
			for (k = 0; k < MAX_OPEN_CACHED_FILES; k++)
				if (cached_file_handle[k].fce == fce)
					break;
			debug_tcol(TERM_RED);
			debug_printf("%-6s  ", k < MAX_OPEN_CACHED_FILES ? "Open" : "");
			debug_tcol(TERM_L_UMBER);
			debug_printf("%s\n", fce->name + t);
		}
	}

	debug_tcol(TERM_L_BLUE);
	debug_printf("\tTotal:\t%3d  ", cf);
	if (ucs)
		debug_printf("%6d/%-6d\n", cs, ucs);
	else
		debug_printf("%6d\n", cs);
	debug_tcol(TERM_BLUE);
#endif /* USE_FILECACHE */
}


static void show_debug_info(void)
{
	int k;
	/* blank the term */
	debug_cls();

	/* Repeatedly prompt for a command */
	do
	{
		debug_tcol(TERM_VIOLET);
		debug_printf("\nInfo: (V)ersion, (F)ilecache, ESC=exit ");
		do
		{
			k = inkey();
			switch (k)
			{
				case 'v':  case 'V': debug_version_info();
					break;
				case 'f':  case 'F': debug_filecache_info
						();
					break;
				case 27: break;
				default: k = 0;
			}
		}
		while (!k);
	}
	while (k != 27);

	Term_clear();
}

#endif /* FE_DEBUG_INFO */

#endif /* __riscos */


tome-235-src/src/main-sla.c0000644000076400017500000001741611012107763013333 0ustar  dgdg/* File: main-sla.c */

/* Purpose: Actual Unix "slang" support for Angband */

/*
 * Author: hans@grumbeer.pfalz.de (Hans-Joachim Baader)
 *
 * Most of this code is adapted directly from "main-gcu.c"
 */

#include "angband.h"


#ifdef USE_SLA



#include 


/*
 * Are we "active"?
 */
static int slang_on = FALSE;


/*
 * Can we use "color"?
 */
static bool can_use_color = FALSE;


/*
 * Angband to SLang color conversion table
 */
static int colortable[16];


/*
 * Currently, only a single "term" is supported here
 */
static term term_screen_body;





/*
 * Hack -- see below
 */
void init_pair (int index, char *foreground, char *background)
{
	SLtt_set_color (index, "", foreground, background);
}





#define A_NORMAL        0
#define A_BOLD          8
#define A_REVERSE       0
#define REVERSE         8

#define COLOR_BLACK     "black"
#define COLOR_BLUE      "blue"
#define COLOR_GREEN     "green"
#define COLOR_CYAN      "cyan"
#define COLOR_RED       "red"
#define COLOR_MAGENTA   "magenta"
#define COLOR_YELLOW    "brown"
#define COLOR_WHITE     "lightgray"
#define COLOR_BBLACK     "gray"
#define COLOR_BBLUE      "brightblue"
#define COLOR_BGREEN     "brightgreen"
#define COLOR_BCYAN      "brightcyan"
#define COLOR_BRED       "brightred"
#define COLOR_BMAGENTA   "brightmagenta"
#define COLOR_BYELLOW    "yellow"
#define COLOR_BWHITE     "white"





static char *color_terminals [] =
{
#ifdef linux
	"console",
#endif
	"linux",
	"xterm-color",
	"color-xterm",
	"xtermc",
	"ansi",
	0
};





/*
 * Stolen from the Midnight Commander
 */
int has_colors(void)
{
	int i;

	char *terminal;


	/* Access the terminal type */
	terminal = getenv("TERM");

	/* Check for colors */
	SLtt_Use_Ansi_Colors = 0;
	if (NULL != getenv ("COLORTERM"))
	{
		SLtt_Use_Ansi_Colors = 1;
	}

	/* We want to allow overriding */
	for (i = 0; color_terminals [i]; i++)
	{
		if (strcmp (color_terminals [i], terminal) == 0)
		{
			SLtt_Use_Ansi_Colors = 1;
		}
	}

	/* Setup emulated colors */
	if (SLtt_Use_Ansi_Colors)
	{
		/*init_pair (REVERSE, "black", "white");*/
	}

	/* Setup bizarre colors */
	else
	{
		SLtt_set_mono (A_BOLD, NULL, SLTT_BOLD_MASK);
		SLtt_set_mono (A_REVERSE, NULL, SLTT_REV_MASK);
		SLtt_set_mono (A_BOLD | A_REVERSE, NULL, SLTT_BOLD_MASK | SLTT_REV_MASK);
	}

	return SLtt_Use_Ansi_Colors;
}





/*
 * Nuke SLang
 */
static void Term_nuke_sla(term *t)
{
	if (!slang_on) return;

	/* Show the cursor */
	/* curs_set(1); */

	/* Clear the screen */
	(void)SLsmg_cls();

	/* Refresh */
	SLsmg_refresh();

	/* We are now off */
	slang_on = FALSE;

	/* Shut down */
	SLsmg_reset_smg();
	SLang_reset_tty();
}


/*
 * Init SLang
 */
static void Term_init_sla(term *t)
{
	/* Note that we are on */
	slang_on = TRUE;
}


/*
 * Process an event, wait if requested
 */
static errr Term_xtra_sla_event(int v)
{
	/* Do not wait unless requested */
	if (!v && (SLang_input_pending (0) == 0)) return (1);

	/* Get and enqueue the key */
	Term_keypress(SLang_getkey ());

	/* Success */
	return 0;
}



/*
 * Suspend / Resume
 */
static errr Term_xtra_sla_alive(int v)
{
	/* Suspend */
	if (!v)
	{
		/* Oops */
		if (!slang_on) return (1);

		/* We are now off */
		slang_on = FALSE;

		/* Shut down (temporarily) */
		SLsmg_reset_smg();
		SLang_reset_tty();
	}

	/* Resume */
	else
	{
		/* Oops */
		if (slang_on) return (1);

		/* Fix the screen */
		SLsmg_refresh();

		/* Note that we are on */
		slang_on = TRUE;
	}

	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_sla(int n, int v)
{
	/* Analyze the request */
	switch (n)
	{
		/* Make a noise */
	case TERM_XTRA_NOISE:
		(void)SLsmg_write_char('\007');
		return (0);

		/* Flush the ncurses buffer */
	case TERM_XTRA_FRESH:
		(void)SLsmg_refresh();
		return (0);

		/* Make the cursor invisible or visible */
	case TERM_XTRA_SHAPE:
		/* curs_set(v); */
		return (0);

		/* Handle events */
	case TERM_XTRA_EVENT:
		return (Term_xtra_sla_event(v));

		/* Handle events */
	case TERM_XTRA_FLUSH:
		while (!Term_xtra_sla_event(FALSE));
		return (0);

		/* Suspend/Resume */
	case TERM_XTRA_ALIVE:
		return (Term_xtra_sla_alive(v));

		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		(void)SLsmg_cls();
		SLsmg_gotorc(0, 0);
		return (0);

		/* Delay */
	case TERM_XTRA_DELAY:
		usleep(1000 * v);
		return (0);
	}

	/* Oops */
	return (1);
}




/*
 * Actually MOVE the hardware cursor
 */
static errr Term_curs_sla(int x, int y, int z)
{
	/* Literally move the cursor */
	SLsmg_gotorc (y, x);

	/* Success */
	return 0;
}


/*
 * Erase some characters
 */
static errr Term_wipe_sla(int x, int y, int n)
{
	int i;

	/* Place the cursor */
	SLsmg_gotorc(y, x);

	/* Dump spaces */
	for (i = 0; i < n; i++) SLsmg_write_char(' ');

	/* Success */
	return 0;
}


/*
 * Place some text on the screen using an attribute
 */
static errr Term_text_sla(int x, int y, int n, byte a, cptr s)
{
	/* Move the cursor */
	SLsmg_gotorc(y, x);

	/* Set the color */
	if (can_use_color) SLsmg_set_color(colortable[a&0x0F]);

	/* Dump the string */
	SLsmg_write_nchars(s, n);

	/* Success */
	return 0;
}


/*
 * Prepare "SLang" for use by the file "term.c"
 * Installs the "hook" functions defined above
 */
errr init_sla(void)
{
	int i, err;

	term *t = &term_screen_body;


	/* Initialize, check for errors */
	err = (SLang_init_tty( -1, TRUE, 0) == -1);

	/* Quit on error */
	if (err) quit("SLang initialization failed");

	/* Get terminal info */
	SLtt_get_terminfo ();

	/* Initialize some more */
	if (SLsmg_init_smg() == 0)
	{
		quit("Could not get virtual display memory");
	}

	/* Check we have enough screen. */
	err = ((SLtt_Screen_Rows < 24) || (SLtt_Screen_Cols < 80));

	/* Quit with message */
	if (err) quit("SLang screen must be at least 80x24");

	/* Now let's go for a little bit of color! */
	err = !has_colors();

	/* Do we have color available? */
	can_use_color = !err;

	/* Init the Color-pairs and set up a translation table */
	/* If the terminal has enough colors */
	/* Color-pair 0 is *always* WHITE on BLACK */

	/* XXX XXX XXX See "main-gcu.c" for proper method */

	/* Only do this on color machines */
	if (can_use_color)
	{
		/* Prepare the color pairs */
		init_pair(1, COLOR_RED, COLOR_BLACK);
		init_pair(2, COLOR_GREEN, COLOR_BLACK);
		init_pair(3, COLOR_YELLOW, COLOR_BLACK);
		init_pair(4, COLOR_BLUE, COLOR_BLACK);
		init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
		init_pair(6, COLOR_CYAN, COLOR_BLACK);
		init_pair(7, COLOR_BLACK, COLOR_BLACK);
		init_pair(9, COLOR_BRED, COLOR_BLACK);
		init_pair(10, COLOR_BGREEN, COLOR_BLACK);
		init_pair(11, COLOR_BYELLOW, COLOR_BLACK);
		init_pair(12, COLOR_BBLUE, COLOR_BLACK);
		init_pair(13, COLOR_BMAGENTA, COLOR_BLACK);
		init_pair(14, COLOR_BCYAN, COLOR_BLACK);
		init_pair(15, COLOR_BBLACK, COLOR_BLACK);

		/* Prepare the color table */
		colortable[0] = 7;        /* Black */
		colortable[1] = 0;        /* White */
		colortable[2] = 6;        /* Grey XXX */
		colortable[3] = 11;       /* Orange XXX */
		colortable[4] = 1;        /* Red */
		colortable[5] = 2;        /* Green */
		colortable[6] = 4;        /* Blue */
		colortable[7] = 3;        /* Brown */
		colortable[8] = 15;       /* Dark-grey XXX */
		colortable[9] = 14;       /* Light-grey XXX */
		colortable[10] = 5;        /* Purple */
		colortable[11] = 11;       /* Yellow */
		colortable[12] = 9;        /* Light Red */
		colortable[13] = 10;       /* Light Green */
		colortable[14] = 12;       /* Light Blue */
		colortable[15] = 3;        /* Light Brown XXX */
	}


	/* Initialize the term */
	term_init(t, 80, 24, 64);

	/* Stick in some hooks */
	t->nuke_hook = Term_nuke_sla;
	t->init_hook = Term_init_sla;

	/* Stick in some more hooks */
	t->xtra_hook = Term_xtra_sla;
	t->curs_hook = Term_curs_sla;
	t->wipe_hook = Term_wipe_sla;
	t->text_hook = Term_text_sla;

	/* Save the term */
	term_screen = t;

	/* Activate it */
	Term_activate(t);


	/* Success */
	return 0;
}

#endif /* USE_SLA */

tome-235-src/src/main-vme.c0000644000076400017500000006405311012107763013342 0ustar  dgdg/* File: main-vme.c */

/* Purpose: Support for "Vax Angband" */

/*
This is MAIN-VME C for VM/ESA machines.
First enable definition of VM in file "h-config.h"
You need to unpack archive EXT-VM VMARC .
 
To do that first set fixed file record length:
'COPYFILE EXT-VM VMARC A = = = ( REC F'
Then unpack:
VMARC UNPACK EXT-VM VMARC A
 
( if you don't have archivator vmarc, there is many places where you
get it, i got it from cc1.kuleuven.ac.be )
 
Then read MAKEFILE EXEC. It contains all neccessary information to
compile Angband.
 
EXT-VM VMARC content:
MAKEFILE EXEC
VMSERV TXTLIB
CNSHND ASSEMBLE
 
You will need about 3-4 MB free disk space to compile it.
If you have any problems, mail to
 
SM20616@vm.lanet.lv or SD30066@vm.lanet.lv
 
A large amount of this file appears to be a complete hack, but
what can you expect from a system designed for the Vax... :-)
 */


#include "angband.h"

#if defined(USE_VME) || defined(VM)


/*
 * Convert EBCDIC to ASCII
 */
char e2a[] =
{
	0x00, 0x01, 0x02, 0x03, 0x1A, 0x09, 0x1A, 0x7F, 0x1A, 0x1A, 0x1A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
	0x10, 0x11, 0x12, 0x13, 0x1A, 0x0A, 0x08, 0x1A, 0x18, 0x19, 0x1A, 0x1A, 0x1C, 0x1D, 0x1E, 0x1F,
	0x1A, 0x1A, 0x1C, 0x1A, 0x1A, 0x0A, 0x17, 0x1B, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x05, 0x06, 0x07,
	0x1A, 0x1A, 0x16, 0x1A, 0x1A, 0x1E, 0x1A, 0x04, 0x1A, 0x1A, 0x1A, 0x1A, 0x14, 0x15, 0x1A, 0x1A,
	0x20, 0xA6, 0xE1, 0x80, 0xEB, 0x90, 0x9F, 0xE2, 0xAB, 0x8B, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
	0x26, 0xA9, 0xAA, 0x9C, 0xDB, 0xA5, 0x99, 0xE3, 0xA8, 0x9E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
	0x2D, 0x2F, 0xDF, 0xDC, 0x9A, 0xDD, 0xDE, 0x98, 0x9D, 0xAC, 0xBA, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
	0xD7, 0x88, 0x94, 0xB0, 0xB1, 0xB2, 0xFC, 0xD6, 0xFB, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
	0xF8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x96, 0xA4, 0xF3, 0xAF, 0xAE, 0xC5,
	0x8C, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x97, 0x87, 0xCE, 0x93, 0xF1, 0xFE,
	0xC8, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xEF, 0xC0, 0xDA, 0x5B, 0xF2, 0xF9,
	0xB5, 0xB6, 0xFD, 0xB7, 0xB8, 0xB9, 0xE6, 0xBB, 0xBC, 0xBD, 0x8D, 0xD9, 0xBF, 0x5D, 0xD8, 0xC4,
	0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xCB, 0xCA, 0xBE, 0xE8, 0xEC, 0xED,
	0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xA1, 0xAD, 0xF5, 0xF4, 0xA3, 0x8F,
	0x5C, 0xE7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xA0, 0x85, 0x8E, 0xE9, 0xE4, 0xD1,
	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xF7, 0xF0, 0xFA, 0xA7, 0xFF
};


/*
 * Convert ASCII to EBCDIC
 */
char a2e[] =
{
	0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
	0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x35, 0x1F,
	0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
	0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
	0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
	0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
	0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
	0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
	0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
	0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x35, 0x1F,
	0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
	0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
	0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
	0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
	0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
	0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07
};


/*
 * System headers (already included by "angband.h" XXX XXX XXX)
 */
#include 
#include 
#include 

/* Some prototypes and definitions */

#define FIELD_SY 1
#define FIELD_SX 80
#define FIELD_EY 2
#define FIELD_EX 10

void GetAddr(int, int, char *);
void InitConsole(void);
void TerminateConsole(void);
void ResetScrBuf(void);
void AddScrBuf(char *, int);
char InKey(void);
char InKeyBuf(void);
void ScreenClear(void);
void ResetDISP(void);
int kbhit(void);
void ShowLine(int y, int x, int len);
void LoadProfile(void);

/* Changed lines marker. */

char DISP[26];

/* Max rows & columns number in screen (note that in older version
 ** than 2.7.9 we needed 25 lines, though 24th was unused. So it is set
 ** to 25 although screen actually has only 24 lines. (we just used to
 ** transfer 25th line into 24th.
 ** But in new version we no longer use it.
 */

int rows, cols;

/* Game cursor position on screen */

int curx = 1;
int cury = 1;

/*
 * Virtual Screen
 */
byte VirtualScreen[2048];
byte ScreenAttr[2048];

/*
 * This array is used for "wiping" the screen, initialized in "init_wat()"
 */
byte wiper[256];

/*
 * The main screen
 */
static term term_screen_body;


/* Update line on screen.
 ** Actually just set flag that we should update it.
 */
void ScreenUpdateLine(int line)
{
	DISP[line + 1] = 1;
}

/*
 * Clear the whole screen
 */
void ScreenClear(void)
{
	int iy;

	for (iy = 0; iy < rows; iy++)
	{
		memcpy(VirtualScreen + (iy*cols), wiper, cols);
		memset(ScreenAttr + (iy*cols), 0xF1, cols);
		ScreenUpdateLine(iy);
	}
}


/*
 * Nuke a Term
 */
static void Term_nuke_vm(term *t)
{
	TerminateConsole();
	puts("Console has been terminated(nuke).");
}

/*
 * Move the cursor
 */
static errr Term_curs_vm(int x, int y)
{
	/* Hack: mark line cursor was at as changed to ensure that old
	 ** cursor would be removed.
	 */
	DISP[cury] = 1;
	curx = x + 1;
	cury = y + 1;
	return (0);
}


/*
 * The Angband color table
 *
 * Comment: White has been changed to blue to make screen look better.
 *          Green and Light Green are exchanged for the same reason.
 *          -0x80 means changing to bold font.
 *
 * Color Table:
 * Dark to Blue, White to Blue, Slate to Blue, Orange to Pink,
 * Red to Red, Green to GreenB, Blue to BlueB, Umber to Yellow,
 * Gray to Blue, Light White to WhiteB, Violet to PinkB, Yellow to Yellow
 * Light colors: Red to RedB,Green to Green,Blue to Cyan, Umber to YellB
 */
static const byte vm_color[] =
{
	0xF1, 0xF1, 0xF1, 0xF3,
	0xF2, 0xF4 - 0x80, 0xF1 - 0x80, 0xF6,
	0xF1, 0xF7 - 0x80, 0xF3 - 0x80, 0xF6,
	0xF2 - 0x80, 0xF4, 0xF5, 0xF6 - 0x80
};

/*
 * Place some text on the screen using an attribute
 */
static errr Term_text_vm(int x, int y, int n, byte a, cptr s)
{
	register int i;
	register byte attr;
	register byte *dest;
	register byte *dest2;

	/* Attribute... */
	attr = vm_color[a & 0x0F];

	/* Paranoia */
	if (n > cols - x) n = cols - x;

	/* Access the destination */
	dest = VirtualScreen + ((cols * y) + x);
	dest2 = ScreenAttr + ((cols * y) + x);

	/* Virtually write the string */
	for (i = 0; (i < n) && s[i]; i++)
	{
		*dest++ = s[i];
		*dest2++ = attr;
	}

	/* Dump the line */
	ScreenUpdateLine(y);

	/* Success */
	return (0);
}


/*
 * Erase part of line.
 */
static errr Term_wipe_vm(int x, int y, int w)
{

	/* Paranoia -- Verify the dimensions */
	if (cols < (w + x)) w = (cols - x);

	/* Wipe part of the virtual screen, and update */
	memcpy(VirtualScreen + (y*cols + x), wiper, w);
	memset(ScreenAttr + (y*cols + x), 0xF1, w);
	ScreenUpdateLine(y);

	/* Success */
	return (0);
}


/*
 * Handle special request.
 */
static errr Term_xtra_vm(int n, int v)
{
	int i, j;
	char tmp;

	/* Analyze the request */
	switch (n)
	{

		/* Make a noise */
	case TERM_XTRA_NOISE:

		/* No noises here! :) */
		return (0);

		/* Wait for a single event */
	case TERM_XTRA_EVENT:

		/* No wait key press check */
		if (!v && !kbhit()) return (1);

		/* Wait for a keypress */
		i = getkey();

		/* Save keypress */
		Term_keypress(i);

		/* Success */
		return (0);

	case TERM_XTRA_CLEAR:

		ScreenClear();
		return (0);

#if 0
	case TERM_XTRA_FROSH:
		ScreenUpdateLine(VirtualScreen + (cols*v), v);
		return (0);
#endif

	case TERM_XTRA_FLUSH:

		/* Flush keys */
		while (1)
		{
			tmp = getkeybuf();
			if (!tmp) break;
			Term_keypress(tmp);
		}

		/* Success */
		return (0);
	}

	/* Unknown request */
	return (1);
}


/*
 * Initialize the VM/CNSconsole.
 */
errr init_vme(void)
{
	register i;

	term *t = &term_screen_body;

	short blank = ' ';

	static int done = FALSE;

	/* Paranoia -- Already done */
	if (done) return ( -1);

	/* Build a "wiper line" of blank spaces */
	for (i = 0; i < 256; i++) wiper[i] = blank;

	/* Acquire the size of the screen */
	rows = 25;
	cols = 80;

	/* Initialize the console */
	InitConsole();

	/* Wipe the screen */
	for (i = 0; i < rows; i++)
	{
		/* Wipe that row */
		memcpy(VirtualScreen + (i*cols), wiper, cols);
		memset(ScreenAttr + (i*cols), 0xF1, cols);
	}

	/* Erase the screen */
	ScreenClear();

	/* Initialize the term -- very large key buffer */
	term_init(t, cols, rows - 1, 1024);

	/* Prepare the init/nuke hooks */
	t->nuke_hook = Term_nuke_vm;

	/* Connect the hooks */
	t->text_hook = Term_text_vm;
	t->wipe_hook = Term_wipe_vm;
	t->curs_hook = Term_curs_vm;
	t->xtra_hook = Term_xtra_vm;

	/* Save it */
	term_screen = t;

	/* Activate it */
	Term_activate(term_screen);

	/* Done */
	done = TRUE;

	/* Success */
	return 0;
}

/* Wait for keypress */
int
getkey(void)
{
	return ((int)InKey());
}

/* Read key buffer if not empty */

int
getkeybuf(void)
{
	return ((int)InKeyBuf());
}


/*********************************************************************/
/*********************************************************************/
/******************   Actual work with console   *********************/
/*********************************************************************/


/* Low-level functions */
int CNSINIT(char *path, int device);
int CNSTERM(char *path);
int CNSREAD(char *path, char *buffer, int buflen);
int CNSWRITE(char *path, char *buffer, int buflen);

#define _PF1    (0xF1)
#define _PF2    (0xF2)
#define _PF3    (0xF3)
#define _PF4    (0xF4)
#define _PF5    (0xF5)
#define _PF6    (0xF6)
#define _PF7    (0xF7)
#define _PF8    (0xF8)
#define _PF9    (0xF9)
#define _PF10   (0x7A)
#define _PF11   (0x7B)
#define _PF12   (0x7C)
#define _PF13   (0xC1)
#define _PF14   (0xC2)
#define _PF15   (0xC3)
#define _PF16   (0xC4)
#define _PF17   (0xC5)
#define _PF18   (0xC6)
#define _PF19   (0xC7)
#define _PF20   (0xC8)
#define _PF21   (0xC9)
#define _PF22   (0x4A)
#define _PF23   (0x4B)
#define _PF24   (0x4C)

#define _PA2    (0x6E)
#define _PA3    (0x6B)

#define _CLEAR  (0x60)

#define _ENTER  (0x7D)

extern char cnscrstb[];    /* Hardware 3270 cursor offsets */

/* Console identificator */
char *cons = "console";

/* Console interrupt flag; should be set by assembler patch */
int CNSINTR;
/* Assembler function prototype; this handles console interrupt */
extern int CNSHD();

/* Buffer for output stream (VM/ESA uses streams to control terminals */
static char * ScrBuf;
/* Incoming buffer from console after cnsread */
static char * InBuf;
/* User entered command buffer (paranoia: make it so long no one will
 ** ever run short of it :)
 */
static char ComBuf[256];
/* Pointer to current position in ComBuf */
static char * ComPtr;
/* This array is used to clean up input field.
 ** Comment: erase everything user entered after we accepted it.
 */
static char wiping[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/* Flag: should we wipe input field ? */
static int wipe = 0;
/* Counter: how many times did game checked if we pressed any key.
 ** Comment: after every 100th we update the screen.
 ** Comment2: because of slow work with screen it would be _very_
 **           unwise to make it more often.
 */
static int kbhitcount;
/* Keep length of collected output stream */
static int BufLen;
/* Define array which will be used to bring actual cursor
 ** (not game cursor!!!) back to the beginning of input field.
 */
static char CursorHome[] = {0, 0, 0, 0x13};
/* Define array to make fields on the screen.
 ** Comment: 2 fields: input field(writable), and game field(protected).
 ** Comment2: We will change PSS settings into dumb repeating of color
 **           setting if PSS fonts are not abailable.
 */
static char ScrField[] =
        {0, 0, 0, 0x29, 0x03, 0xC0, 0xC1, 0x42, 0xF3, 0x43, 0xC1, \
         0, 0, 0, 0x29, 0x03, 0xC0, 0x60, 0x42, 0xF1, 0x43, 0xC1};
/* Last command user entered (for repeating purposes */
static char LastCmd[256];
/* Array which holds PFkeys definitions */
static char PFcmd[25][80];


/* Actually initialize console ... */
void InitConsole(void)
{
	/* Use this to activate full screen mode after console has been
	 ** initialized.
	 */
	unsigned char init[6] =
	        {0xC2, 0x11, 0x40, 0x40, 0, 0};
	int i;
	/* Array for checking is PSS fonts are loaded */
	char pss[256];

	/* Allocate memory */
	ScrBuf = malloc(4100);
	if (ScrBuf == NULL)
	{
		puts("Cannot mallocate memory for screen buffer!");
		exit(77);
	}
	/* Block system standarts... */
	system("cp set msg off");
	system("cp set emsg off");
	system("cp set imsg off");
	system("cp term brkkey none");
	/* Test PSS */
	system("desbuf");
	system("query display (stack");
	gets(pss);
	i = 1;
	if (pss[63] != 'P') i = 0;
	if (pss[64] != 'S') i = 0;
	if (pss[65] != 'S') i = 0;
	if (pss[72] != '0') i = 0;
	if (pss[73] != '1') i = 0;
	if (pss[74] != 'A') i = 0;
	if (pss[75] != 'B') i = 0;
	if (i == 0)
	{
		/* No PSS. Cannot run without them... */
		puts("ERROR: Cannot run without PSS fonts!");
		exit(77);
	}
	ScrBuf[0] = 0xC2;
	ScrBuf[1] = 0;
	BufLen = 1;
	/* Allocate memory */
	InBuf = malloc(200);
	if (InBuf == NULL)
	{
		puts("Cannot mallocate memory for screen buffer!");
		exit(77);
	}
	/* Okay, lets make some intial assigments */
	InBuf[0] = 0;
	ComBuf[0] = 0;
	ComPtr = ComBuf;
	LastCmd[0] = 0;
	GetAddr(FIELD_SY, FIELD_SX, ScrField);
	GetAddr(FIELD_EY, FIELD_EX, ScrField + 11);
	GetAddr(FIELD_SY, FIELD_SX + 1, wiping);
	GetAddr(FIELD_SY, FIELD_SX + 1, CursorHome);
	/* Initialize console */
	cnsxinit(cons, 0x9, 1, CNSHD);
	/* Activate full-screen mode */
	cnswrite(cons, init, 6);
	/* No lines on screen were changed */
	for (i = 1; i < 25; i++)
		DISP[i] = 0;
	/* Corsor home... */
	AddScrBuf(CursorHome, sizeof(CursorHome));
	/* No console interrupt yet */
	CNSINTR = 0;
	/* No check keypresses yet */
	kbhitcount = 0;
	/* Let's load 'profile angband' for PFs settings */
	LoadProfile();
}

void TerminateConsole(void)
{
	free(ScrBuf);
	free(InBuf);
	/* Terminate console */
	cnsterm(cons);
	/* Restore system defaults.
	 ** Comment: better we should have written them down at start but
	 ** it is reasonably difficult to make, so just set standart values.
	 */
	system("cp set msg on");
	system("cp set emsg on");
	system("cp set imsg on");
	system("cp term brkkey pa1");
}

/* Reset collected output stream */
void ResetScrBuf(void)
{
	int i;
	unsigned char attr;

	/* Where shall cursor be ? */
	GetAddr(cury, curx, ScrBuf + BufLen);
	BufLen += 3;
	/* Actually 'make' cursor : underline symbol */
	ScrBuf[BufLen++] = 0x28;
	ScrBuf[BufLen++] = 0x41;
	ScrBuf[BufLen++] = 0xF4;
	attr = *(ScreenAttr + (cury - 1) * cols + curx - 1);
	ScrBuf[BufLen++] = 0x28;
	ScrBuf[BufLen++] = 0x42;
	ScrBuf[BufLen++] = attr | 0x80;
	ScrBuf[BufLen++] = 0x28;
	ScrBuf[BufLen++] = 0x43;
	if (attr > 0x80) ScrBuf[BufLen++] = 0xC1;
	else ScrBuf[BufLen++] = 0xC2;
	ScrBuf[BufLen++] = *(VirtualScreen + (cury - 1) * cols + curx - 1);
	ScrBuf[BufLen++] = 0x28;
	ScrBuf[BufLen++] = 0x41;
	ScrBuf[BufLen++] = 0x00;
	ScrBuf[BufLen++] = 0x28;
	ScrBuf[BufLen++] = 0x43;
	ScrBuf[BufLen++] = 0xC1;
	/* Draw screen fields.
	 ** Comment: paranoia, should always be there, but won't be any worse
	 **          if we redraw them.
	 */
	memcpy(ScrBuf + BufLen, ScrField, 22);
	if (wipe)
	{
		/* If we should wipe input field, let's do it. */
		wipe = 0;
		memcpy(ScrBuf + BufLen + 22, wiping, sizeof(wiping));
		/* Actually write to terminal */
		cnswrite(cons, ScrBuf, BufLen + 22 + sizeof(wiping));
	}
	else
	{
		/* Actually write to terminal */
		cnswrite(cons, ScrBuf, BufLen + 22);
	}
	/* Discard old output stream */
	ScrBuf[0] = 0xC2;
	ScrBuf[1] = 0;
	BufLen = 1;
}

/* Just add some more to output stream */
void AddScrBuf(char * ptr, int len)
{
	/* Stream cannot be longer than 4k, so reset it */
	if (len + BufLen > 4000) ResetScrBuf();
	memcpy(ScrBuf + BufLen, ptr, len);
	BufLen += len;
}

/* Calculate codes for cursor setting and write them down into *stream.
 ** Comment: system has _really crazy tables for this calculation so
 **          we need function for this.
 */
void GetAddr(int y, int x, char *stream)
{
	int sx, sy, len;

	len = y * 80 + x - 81;

	sx = len & 0x3F;
	sy = len >> 6;

	*stream++ = 0x11;
	/* Use standart array for cursor offsets (VMSERV TXTLIB) */
	*stream++ = cnscrstb[sy];
	*stream = cnscrstb[sx];
}

/* Okay, program requested pressed key, let's return it */
char InKey(void)
{
	char ret;
	char * info;
	int i;
	char *ptr, *ptrs;
	int PF;
	int prev;

	/* If we didn't finish previous line user entered just return
	 ** next symbol.
	 ** Comment: unlikely IBM PC and others user may enter string
	 **          of any length (limited by input field length to 9
	 **          symbols) and only them by pressing ENTER key or
	 **          functional key make real console interrupt.
	 **          So we should handle everything user entered.
	 */
	if (*ComPtr)
	{
		ret = *ComPtr;
		ComPtr++;
		return (ret);
	}
	/* If we get here than user command buffer is empty and we have
	 ** actually wait for new command.
	 */
	/* Okay, update screen before :) */
	ResetDISP();
	/* Well, now wait till user enters something and read it. */
	cnsread(cons, InBuf, 200);
	/* Oh, we already handling interrupt so, reset interrupt flag */
	CNSINTR = 0;
	/* No previous cmd inserted yet */
	prev = 0;
	/* User pressed CLEAR key. Redraw all screen then. */
	if (*InBuf == 0x6D)
	{
		/* Hack: mark all lines as changed */
		for (i = 1; i < 26; i++)
			DISP[i] = 1;
		/* Cursor home */
		AddScrBuf(CursorHome, sizeof(CursorHome));
		/* Redraw the whole screen */
		ResetDISP();
		/* Hack: we should return something, shouldn't we?
		 ** Just return CR. It seems safest.
		 */ 
		return (13);
	}
	/* Okay parse stream from console to make string only of
	 ** user's input.
	 */
	info = memchr(InBuf, 0x1D, 200);
	info += 2;
	info[9] = 0;
	/* Mark that we should clear input field */
	wipe = 1;
	/* Cursor home */
	AddScrBuf(CursorHome, sizeof(CursorHome));
	/* Pointer to current letter in buffered command set to start */
	ComPtr = ComBuf;
	/* Clear length buffer */
	ComBuf[0] = 0;
	switch (*InBuf)
	{
		/* PA2 & PA1 */
	case 0x6E:
		;
	case 0x6C:
		/* These 2 keys are supposed to mean 'ESC' */
		return (27);
		break;
		/* Hack: determine which PF key was exactly pressed.
		 */
	case _PF1:
		PF = 1;
		break;
	case _PF2:
		PF = 2;
		break;
	case _PF3:
		PF = 3;
		break;
	case _PF4:
		PF = 4;
		break;
	case _PF5:
		PF = 5;
		break;
	case _PF6:
		PF = 6;
		break;
	case _PF7:
		PF = 7;
		break;
	case _PF8:
		PF = 8;
		break;
	case _PF9:
		PF = 9;
		break;
	case _PF10:
		PF = 10;
		break;
	case _PF11:
		PF = 11;
		break;
	case _PF12:
		PF = 12;
		break;
	case _PF13:
		PF = 13;
		break;
	case _PF14:
		PF = 14;
		break;
	case _PF15:
		PF = 15;
		break;
	case _PF16:
		PF = 16;
		break;
	case _PF17:
		PF = 17;
		break;
	case _PF18:
		PF = 18;
		break;
	case _PF19:
		PF = 19;
		break;
	case _PF20:
		PF = 20;
		break;
	case _PF21:
		PF = 21;
		break;
	case _PF22:
		PF = 22;
		break;
	case _PF23:
		PF = 23;
		break;
	case _PF24:
		PF = 24;
		break;
		/* Uh, user pressed ENTER.
		 ** Determine if we should add 'CR' at the end or not ?
		 */
	case _ENTER:
		PF = 0;
		/* Copy entered string into buffer */
		strcpy(ComBuf, info);
		/* Never end strings of length 1 or 0 with CR */
		if (strlen(ComBuf) < 2) break;
		/* If string ends with R* or R& add CR */
		ptr = info + strlen(info) - 1;
		if (*ptr == '*' || *ptr == '&')
		{
			ptr--;
			if (ptr < info) break;
			if (*ptr != 'R') break;
			ptr = ComBuf + strlen(ComBuf);
			ptr[0] = 13;
			ptr[1] = 0;
			break;
		}
		/* Well, only numbers should be padded with CR.
		 ** Comment: handle 18/... too.
		 */
		if (!isdigit(*ptr)) break;
		ptr--;
		i = 1;
		while (ptr >= info)
		{
			if (*ptr == 'R') break;
			if (*ptr == '@' && ptr == info)
				break;
			if (*ptr == '/')
			{
				i = 0;
				if (*(ptr - 1) != '8') break;
				if (*(ptr - 2) != '1') break;
				if ((ptr - 2) != info) break;
				i = 1;
				break;
			}
			if (!isdigit(*ptr))
			{
				i = 0;
				break;
			}
			ptr--;
		}
		if (i)
			ptr = ComBuf + strlen(ComBuf);
		ptr[0] = 13;
		ptr[1] = 0;
		break;
	default:
		PF = 0;
	}
	/* Okay let's proceed with parsing PFkeys commands */
	ptrs = PFcmd[PF];
	ptr = ComBuf;
	/* If key actually was PF and we didn't run into end of PF
	 ** command definition...
	 */
	while (*ptrs && PF)
	{
		/* If not '\' just copy symbol into buffer */
		if (*ptrs != '\\')
		{
			*ptr = *ptrs;
			ptr++;
			ptrs++;
			continue;
		}
		/* We have discovered '\'. Let's resolve it. */
		ptrs++;
		switch (*ptrs)
		{
			/* End of line ? Do nothing then. */
		case 0:
			break;
			/* User actually wants '\' */
		case '\\':
			*ptr = '\\';
			ptr++;
			break;
			/* User wants his previous command inserted. */
		case 'p':
			/* Set flag that we used previous command */
			prev = 1;
			strcpy(ptr, LastCmd);
			ptr = ComBuf + strlen(ComBuf);
			break;
			/* Insert string user actually entered */
		case 's':
			strcpy(ptr, info);
			ptr = ComBuf + strlen(ComBuf);
			break;
			/* User wants 'CR' */
		case 'n':
			*ptr = 13;
			ptr++;
			break;
			/* Simulate CTRL key pressing */
		case '^':
			ptrs++;
			if (!(*ptrs)) break;
			*ptr = KTRL(*ptrs);
			ptr++;
			break;
			/* ESC */
		case 'c':
			*ptr = 27;
			ptr++;
			break;
			/* Hmm, urecognized command. Just copy letter. */
		default:
			*ptr = *ptrs;
			ptr++;
		}
		if (ptrs) ptrs++;
	}
	/* Terminate string with 0 if neccessary */
	if (PF) *ptr = 0;
	/* Empty string? User probably wants to send CR. */
	if (!(*ComBuf))
	{
		return (13);
	}
	/* Okay, set pointer to next letter */
	ComPtr++;
	/* Backup last command if not empty */
	ptr = ComBuf;
	/* String still "empty" */
	i = 1;
	while ((*ptr) && i)
	{
		if ((*ptr != 13) && (*ptr != 27) && (*ptr != ' '))
			i = 0;
		ptr++;
	}
	/* Never update previous command if we inserted it.
	 ** Comment: this is to avoid recursively multiplying previous
	 **          commands.
	 */
	if ((!i) && (!prev))
		strcpy(LastCmd, ComBuf);
	/* Return something */
	return (*ComBuf);
}

/* Get symbol from buffer if exists */

char InKeyBuf(void)
{
	char ret;

	ret = *ComPtr;
	if (ret) ComPtr++;
	return (ret);
}

/* Here we draw all changed lines */
void ResetDISP(void)
{
	int i;

	/* No need to redraw screen in near future */
	kbhitcount = 0;
	for (i = 1; i < 25; i++)
		if (DISP[i] != 0)
		{
			/* If line was changed, it won't stay changed any more */
			DISP[i] = 0;
			/* We don't want to erase input field definitons from
			 ** screen, so check it carefully.
			 */
			switch (i)
			{
			case FIELD_SY:
				ShowLine(i, 1, FIELD_SX - 1);
				if (i == FIELD_EY)
				{
					ShowLine(i, FIELD_EX + 1, 80-FIELD_EX);
				}
				break;
			case FIELD_EY:
				ShowLine(i, FIELD_EX + 1, 80-FIELD_EX);
				break;
			default:
				ShowLine(i, 1, 80);
			}
		}
	/* Okay, actually show something */
	ResetScrBuf();
}

/* Did user press something? */
int kbhit(void)
{
	kbhitcount++;
	if (kbhitcount > 99)
	{
		/* We waited long enough, time to redraw screen.
		 ** Comment: during sleep every 100th turn is shown.
		 */
		kbhitcount = 0;
		ResetDISP();
	}
	return (CNSINTR);
}

/* Let's show requested line(or part of it). */
void ShowLine(int y, int x, int len)
{
	char slbuf[512];
	char *ptr, *scr, *attr;
	int i;
	unsigned char curattr;

	ptr = slbuf + 3;
	/* Hack: was used for older version to place 25th string on
	 ** 24th.
	 */
	if (y < 25)
		GetAddr(y, x, slbuf);
	else
		GetAddr(24, x, slbuf);
	/* Set some adresses */
	curattr = 0;
	scr = VirtualScreen + (y - 1) * cols + x - 1;
	attr = ScreenAttr + (y - 1) * cols + x - 1;
	/* Let's proceed with string. */
	for (i = 0; i < len; i++)
	{
		/* Attribute has changed ? Let's add codes for changing color */
		if (*attr != curattr)
		{
			/* Pss has changed ? Let's change pss. */
			if (((*attr)&0x80) != (curattr&0x80) || (!curattr))
			{
				*ptr++ = 0x28;
				*ptr++ = 0x43;
				if (*attr > 0x80) *ptr++ = 0xC1;
				else *ptr++ = 0xC2;
			}
			/* Color has changed ? Let's change it. */
			if (((*attr)&0x7F) != (curattr&0x7F))
			{
				*ptr++ = 0x28;
				*ptr++ = 0x42;
				if (*attr > 0x80) *ptr++ = *attr;
				else *ptr++ = *attr + 0x80;
			}
			curattr = *attr;
		}
		*ptr++ = *scr;
		scr++;
		attr++;
	}
	/* Add string to output stream */
	AddScrBuf(slbuf, ptr - slbuf);
}

void LoadProfile(void)
{

	FILE *fp;
	char line[128], *ptr, *pfptr, *p;
	int pf, i;

	for (i = 1; i <= 24; i++) strcpy(PFcmd[i], "\\s");

	fp = fopen("PROFILE ANGBAND", "r");
	if (!fp) return;
	{
		while (fgets(line, 128, fp))
		{
			if (*line == '#') continue;
			ptr = strstr(line, "PF");
			if (!ptr) continue;
			ptr += 2;
			p = ptr;
			while (isdigit(*p)) ++p;
			*p++ = 0;
			pf = atoi(ptr);
			if (pf < 1 || pf > 24) continue;
			ptr = strchr(p, '"');
			++ptr;
			p = strchr(ptr, '"');
			if (!p)
			{
				puts("'\"' missing in PROFILE ANGBAND.");
				continue;
			}
			*p = 0;
			strcpy(PFcmd[pf], ptr);
		}
	}
}

/*
 **
 ** File descriptor emulation for VM/ESA
 **
 **
 */

#include 
#include 
#include "fcntl.h"

static FILE *file_descriptors[40];

int
open(char *name, int flags, int mode)
{
	char fmode[16];
	FILE *fp;
	int i;

	strcpy(fmode, "rb");
	if ((flags & O_WRONLY) || (flags & O_RDWR)) strcpy(fmode, "wb+");

	fp = fopen(name, fmode);

	if (!fp) return ( -1);
	for (i = 1; i < 40; i++)
		if (!file_descriptors[i])
		{
			file_descriptors[i] = fp;
			return (i);
		}
	return ( -1);
}

void
close(int fd)
{
	fclose(file_descriptors[fd]);
}

int
read(int fd, char *buff, int bytes)
{
	return (fread(buff, 1, bytes, file_descriptors[fd]));
}

int
write(int fd, char *buff, int bytes)
{
	return (fwrite(buff, 1, bytes, file_descriptors[fd]));
}

long
lseek(int fd, long pos, int set)
{
	return (fseek(file_descriptors[fd], pos, set));
}

void
unlink(char *filename)
{
	remove(filename);
}


#endif /* USE_VME */

tome-235-src/src/main-win.c0000644000076400017500000025730011012107763013347 0ustar  dgdg/* File: main-win.c */

/*
 * Copyright (c) 1997 Ben Harrison, Skirmantas Kligys, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband work with Windows computers.
 *
 * To use this file, use an appropriate "Makefile" or "Project File",
 * make sure that "WINDOWS" and/or "WIN32" are defined somewhere, and
 * make sure to obtain various extra files as described below.
 *
 * The official compilation uses the CodeWarrior Pro compiler, which
 * includes a special project file and precompilable header file.
 *
 *
 * See also "main-dos.c" and "main-ibm.c".
 *
 *
 * The "lib/user/pref-win.prf" file contains keymaps, macro definitions,
 * and/or color redefinitions.
 *
 * The "lib/user/font-win.prf" contains attr/char mappings for use with the
 * normal "lib/xtra/font/ .fon" font files.
 *
 * The "lib/user/graf-win.prf" contains attr/char mappings for use with the
 * special "lib/xtra/graf/ .bmp" bitmap files, which are activated by a
 * menu item.
 *
 *
 * Compiling this file, and using the resulting executable, requires
 * several extra files not distributed with the standard Angband code.
 * If "USE_GRAPHICS" is defined, then "readdib.h" and "readdib.c" must
 * be placed into "src/", and the "8X8.BMP" bitmap file must be placed
 * into "lib/xtra/graf".  In any case, some "*.fon" files (including
 * "8X13.FON" if nothing else) must be placed into "lib/xtra/font/".
 * If "USE_SOUND" is defined, then some special library (for example,
 * "winmm.lib") may need to be linked in, and desired "*.WAV" sound
 * files must be placed into "lib/xtra/sound/".  All of these extra
 * files can be found in the "ext-win" archive.
 *
 *
 * The "Term_xtra_win_clear()" function should probably do a low-level
 * clear of the current window, and redraw the borders and other things,
 * if only for efficiency.  XXX XXX XXX
 *
 * A simpler method is needed for selecting the "tile size" for windows.
 * XXX XXX XXX
 *
 * The various "warning" messages assume the existance of the "screen.w"
 * window, I think, and only a few calls actually check for its existance,
 * this may be okay since "NULL" means "on top of all windows". (?)  The
 * user must never be allowed to "hide" the main window, or the "menubar"
 * will disappear.  XXX XXX XXX
 *
 * Special "Windows Help Files" can be placed into "lib/xtra/help/" for
 * use with the "winhelp.exe" program.  These files *may* be available
 * at the ftp site somewhere, but I have not seen them.  XXX XXX XXX
 *
 *
 * Initial framework (and most code) by Ben Harrison (benh@phial.com).
 *
 * Original code by Skirmantas Kligys (kligys@scf.usc.edu).
 *
 * Additional code by Ross E Becker (beckerr@cis.ohio-state.edu),
 * and Chris R. Martin (crm7479@tam2000.tamu.edu).
 */


#include "angband.h"


#ifdef WINDOWS


/*
 * Extract the "WIN32" flag from the compiler
 */
#if defined(__WIN32__) || defined(__WINNT__) || defined(__NT__)
# ifndef WIN32
# define WIN32
# endif 
#endif


/*
 * Hack -- allow use of "screen saver" mode
 */
#define USE_SAVER

/*
 * Menu constants -- see "ANGBAND.RC"
 */

#define IDM_FILE_NEW			100
#define IDM_FILE_OPEN			101
#define IDM_FILE_SAVE			110
#ifdef ALLOW_QUITTING
# define IDM_FILE_ABORT	120
#else
# define IDM_FILE_SCORE	120
#endif
#define IDM_FILE_EXIT			121

#define IDM_WINDOW_VIS_0		200
#define IDM_WINDOW_VIS_1		201
#define IDM_WINDOW_VIS_2		202
#define IDM_WINDOW_VIS_3		203
#define IDM_WINDOW_VIS_4		204
#define IDM_WINDOW_VIS_5		205
#define IDM_WINDOW_VIS_6		206
#define IDM_WINDOW_VIS_7		207

#define IDM_WINDOW_FONT_0		210
#define IDM_WINDOW_FONT_1		211
#define IDM_WINDOW_FONT_2		212
#define IDM_WINDOW_FONT_3		213
#define IDM_WINDOW_FONT_4		214
#define IDM_WINDOW_FONT_5		215
#define IDM_WINDOW_FONT_6		216
#define IDM_WINDOW_FONT_7		217

#define IDM_WINDOW_BIZ_0		230
#define IDM_WINDOW_BIZ_1		231
#define IDM_WINDOW_BIZ_2		232
#define IDM_WINDOW_BIZ_3		233
#define IDM_WINDOW_BIZ_4		234
#define IDM_WINDOW_BIZ_5		235
#define IDM_WINDOW_BIZ_6		236
#define IDM_WINDOW_BIZ_7		237

#define IDM_WINDOW_I_WID_0		240
#define IDM_WINDOW_I_WID_1		241
#define IDM_WINDOW_I_WID_2		242
#define IDM_WINDOW_I_WID_3		243
#define IDM_WINDOW_I_WID_4		244
#define IDM_WINDOW_I_WID_5		245
#define IDM_WINDOW_I_WID_6		246
#define IDM_WINDOW_I_WID_7		247

#define IDM_WINDOW_D_WID_0		250
#define IDM_WINDOW_D_WID_1		251
#define IDM_WINDOW_D_WID_2		252
#define IDM_WINDOW_D_WID_3		253
#define IDM_WINDOW_D_WID_4		254
#define IDM_WINDOW_D_WID_5		255
#define IDM_WINDOW_D_WID_6		256
#define IDM_WINDOW_D_WID_7		257

#define IDM_WINDOW_I_HGT_0		260
#define IDM_WINDOW_I_HGT_1		261
#define IDM_WINDOW_I_HGT_2		262
#define IDM_WINDOW_I_HGT_3		263
#define IDM_WINDOW_I_HGT_4		264
#define IDM_WINDOW_I_HGT_5		265
#define IDM_WINDOW_I_HGT_6		266
#define IDM_WINDOW_I_HGT_7		267

#define IDM_WINDOW_D_HGT_0		270
#define IDM_WINDOW_D_HGT_1		271
#define IDM_WINDOW_D_HGT_2		272
#define IDM_WINDOW_D_HGT_3		273
#define IDM_WINDOW_D_HGT_4		274
#define IDM_WINDOW_D_HGT_5		275
#define IDM_WINDOW_D_HGT_6		276
#define IDM_WINDOW_D_HGT_7		277

#define IDM_OPTIONS_OLD_GRAPHICS	400
#define IDM_OPTIONS_NEW_GRAPHICS	401
#define IDM_OPTIONS_ASCII_GRAPHICS  403
#define IDM_OPTIONS_SOUND		402
#define IDM_OPTIONS_BIGTILE		409
#define IDM_OPTIONS_UNUSED		410
#define IDM_OPTIONS_SAVER		411

#define IDM_HELP_GENERAL		901
#define IDM_HELP_SPOILERS		902


/*
 * This may need to be removed for some compilers XXX XXX XXX
 */
#define STRICT

/*
 * Exclude parts of WINDOWS.H that are not needed
 */
#define NOCOMM            /* Comm driver APIs and definitions */
#define NOLOGERROR        /* LogError() and related definitions */
#define NOPROFILER        /* Profiler APIs */
#define NOLFILEIO         /* _l* file I/O routines */
#define NOOPENFILE        /* OpenFile and related definitions */
#define NORESOURCE        /* Resource management */
#define NOATOM            /* Atom management */
#define NOLANGUAGE        /* Character test routines */
#define NOLSTRING         /* lstr* string management routines */
#define NODBCS            /* Double-byte character set routines */
#define NOKEYBOARDINFO    /* Keyboard driver routines */
#define NOCOLOR           /* COLOR_* color values */
#define NODRAWTEXT        /* DrawText() and related definitions */
#define NOSCALABLEFONT    /* Truetype scalable font support */
#define NOMETAFILE        /* Metafile support */
#define NOSYSTEMPARAMSINFO /* SystemParametersInfo() and SPI_* definitions */
#define NODEFERWINDOWPOS  /* DeferWindowPos and related definitions */
#define NOKEYSTATES       /* MK_* message key state flags */
#define NOWH              /* SetWindowsHook and related WH_* definitions */
#define NOCLIPBOARD       /* Clipboard APIs and definitions */
#define NOICONS           /* IDI_* icon IDs */
#define NOMDI             /* MDI support */
#define NOHELP            /* Help support */

/* Not defined since it breaks Borland C++ 5.5 */
/* #define NOCTLMGR */    /* Control management and controls */

/*
 * Exclude parts of WINDOWS.H that are not needed (Win32)
 */
#define WIN32_LEAN_AND_MEAN
#define NONLS             /* All NLS defines and routines */
#define NOSERVICE         /* All Service Controller routines, SERVICE_ equates, etc. */
#define NOKANJI           /* Kanji support stuff. */
#define NOMCX             /* Modem Configuration Extensions */

/*
 * Include the "windows" support file
 */
#include 

/*
 * For IRC stuff
 */
#ifdef USE_WINSOCK
#define ZSOCK_TIMER_ID   1
#define ZSOCK_TIMER_RATE 50
#endif


/*
 * Exclude parts of MMSYSTEM.H that are not needed
 */
#define MMNODRV          /* Installable driver support */
#define MMNOWAVE         /* Waveform support */
#define MMNOMIDI         /* MIDI support */
#define MMNOAUX          /* Auxiliary audio support */
#define MMNOJOY          /* Joystick support */
#define MMNOMCI          /* MCI support */
#define MMNOMMIO         /* Multimedia file I/O support */
#define MMNOMMSYSTEM     /* General MMSYSTEM functions */

/*
 * Include some more files
 */
#include 
#include 

/*
 * Include the support for loading bitmaps
 */
#ifdef USE_GRAPHICS
# include "readdib.h"
#endif

/*
 * Hack -- Fake declarations from "dos.h" XXX XXX XXX
 */
#ifdef WIN32
#define INVALID_FILE_NAME (DWORD)0xFFFFFFFF
#else /* WIN32 */
#define FA_LABEL    0x08        /* Volume label */
#define FA_DIREC    0x10        /* Directory */
unsigned _cdecl _dos_getfileattr(const char *, unsigned *);
#endif /* WIN32 */

/*
 * Silliness in WIN32 drawing routine
 */
#ifdef WIN32
# define MoveTo(H, X, Y) MoveToEx(H, X, Y, NULL)
#endif /* WIN32 */

/*
 * Silliness for Windows 95
 */
#ifndef WS_EX_TOOLWINDOW
# define WS_EX_TOOLWINDOW 0
#endif

/*
 * Foreground color bits (hard-coded by DOS)
 */
#define VID_BLACK	0x00
#define VID_BLUE	0x01
#define VID_GREEN	0x02
#define VID_CYAN	0x03
#define VID_RED		0x04
#define VID_MAGENTA	0x05
#define VID_YELLOW	0x06
#define VID_WHITE	0x07

/*
 * Bright text (hard-coded by DOS)
 */
#define VID_BRIGHT	0x08

/*
 * Background color bits (hard-coded by DOS)
 */
#define VUD_BLACK	0x00
#define VUD_BLUE	0x10
#define VUD_GREEN	0x20
#define VUD_CYAN	0x30
#define VUD_RED		0x40
#define VUD_MAGENTA	0x50
#define VUD_YELLOW	0x60
#define VUD_WHITE	0x70

/*
 * Blinking text (hard-coded by DOS)
 */
#define VUD_BRIGHT	0x80



/*
 * Forward declare
 */
typedef struct _term_data term_data;

/*
 * Extra "term" data
 *
 * Note the use of "font_want" for the names of the font file requested by
 * the user, and the use of "font_file" for the currently active font file.
 *
 * The "font_file" is uppercased, and takes the form "8X13.FON", while
 * "font_want" can be in almost any form as long as it could be construed
 * as attempting to represent the name of a font.
 */
struct _term_data
{
	term t;

	cptr s;

	HWND w;

	DWORD dwStyle;
	DWORD dwExStyle;

	uint keys;

	uint rows;
	uint cols;

	uint pos_x;
	uint pos_y;
	uint size_wid;
	uint size_hgt;
	uint size_ow1;
	uint size_oh1;
	uint size_ow2;
	uint size_oh2;

	bool size_hack;

	bool xtra_hack;

	bool visible;

	bool bizarre;

	cptr font_want;

	cptr font_file;

	HFONT font_id;

	uint font_wid;
	uint font_hgt;

	uint tile_wid;
	uint tile_hgt;
};


/*
 * Maximum number of windows XXX XXX XXX
 */
#define MAX_TERM_DATA 8

/*
 * An array of term_data's
 */
static term_data data[MAX_TERM_DATA];

/*
 * Hack -- global "window creation" pointer
 */
static term_data *my_td;

/*
 * game in progress
 */
bool game_in_progress = FALSE;

/*
 * note when "open"/"new" become valid
 */
bool initialized = FALSE;

/*
 * screen paletted, i.e. 256 colors
 */
bool paletted = FALSE;

/*
 * 16 colors screen, don't use RGB()
 */
bool colors16 = FALSE;

/*
 * Saved instance handle
 */
static HINSTANCE hInstance;

/*
 * Yellow brush for the cursor
 */
static HBRUSH hbrYellow;

/*
 * An icon
 */
static HICON hIcon;

/*
 * A palette
 */
static HPALETTE hPal;


#ifdef USE_SAVER

/*
 * The screen saver window
 */
static HWND hwndSaver;

#endif /* USE_SAVER */


#ifdef USE_GRAPHICS

/*
 * Flag set once "graphics" has been initialized
 */
static bool can_use_graphics = FALSE;

/*
 * The global bitmap
 */
static DIBINIT infGraph;

#ifdef USE_TRANSPARENCY

/*
 * The global bitmap mask
 */
static DIBINIT infMask;

#endif /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */


#ifdef USE_SOUND

/*
 * Flag set once "sound" has been initialized
 */
static bool can_use_sound = FALSE;

/*
 * An array of sound file names
 */
static cptr sound_file[SOUND_MAX];

#endif /* USE_SOUND */


/*
 * Full path to ANGBAND.INI
 */
static cptr ini_file = NULL;

/*
 * Name of application
 */
static cptr AppName = "ANGBAND";

/*
 * Name of sub-window type
 */
static cptr AngList = "AngList";

/*
 * Directory names
 */
static cptr ANGBAND_DIR_XTRA_FONT;
static cptr ANGBAND_DIR_XTRA_GRAF;
static cptr ANGBAND_DIR_XTRA_SOUND;
static cptr ANGBAND_DIR_XTRA_HELP;


/*
 * The "complex" color values
 */
static COLORREF win_clr[256];


/*
 * The "simple" color values
 *
 * See "main-ibm.c" for original table information
 *
 * The entries below are taken from the "color bits" defined above.
 *
 * Note that many of the choices below suck, but so do crappy monitors.
 */
static BYTE win_pal[256] =
{
	VID_BLACK, 					/* Dark */
	VID_WHITE, 					/* White */
	VID_CYAN, 					/* Slate XXX */
	VID_RED | VID_BRIGHT, 		/* Orange XXX */
	VID_RED, 					/* Red */
	VID_GREEN, 					/* Green */
	VID_BLUE, 					/* Blue */
	VID_YELLOW, 					/* Umber XXX */
	VID_BLACK | VID_BRIGHT, 		/* Light Dark */
	VID_CYAN | VID_BRIGHT, 		/* Light Slate XXX */
	VID_MAGENTA, 				/* Violet XXX */
	VID_YELLOW | VID_BRIGHT, 	/* Yellow */
	VID_MAGENTA | VID_BRIGHT, 	/* Light Red XXX */
	VID_GREEN | VID_BRIGHT, 		/* Light Green */
	VID_BLUE | VID_BRIGHT, 		/* Light Blue */
	VID_YELLOW					/* Light Umber XXX */
};


/*
 * Hack -- define which keys are "special"
 */
static bool special_key[256];
static bool ignore_key[256];

#if 1
/*
 * Hack -- initialization list for "special_key"
 */
static byte special_key_list[] = {
	VK_CLEAR, VK_PAUSE, VK_CAPITAL, VK_KANA,
#ifdef JP
	VK_JUNJA, VK_FINAL, VK_KANJI, VK_CONVERT, VK_NONCONVERT, VK_ACCEPT, VK_MODECHANGE,
#endif
	VK_PRIOR, VK_NEXT, VK_END, VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN,
	VK_SELECT, VK_PRINT, VK_EXECUTE, VK_SNAPSHOT, VK_INSERT, VK_DELETE,
	VK_HELP, VK_APPS,
	VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10,
	VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18, VK_F19, VK_F20,
	VK_F21, VK_F22, VK_F23, VK_F24, VK_NUMLOCK, VK_SCROLL,
	VK_ATTN, VK_CRSEL, VK_EXSEL, VK_EREOF, VK_PLAY, VK_ZOOM, VK_NONAME,
	VK_PA1, 0
};

static byte ignore_key_list[] = {
	VK_ESCAPE, VK_TAB, VK_SPACE,
	'F', 'W', 'O', 'H',  /* these are menu characters.*/
	VK_SHIFT, VK_CONTROL, VK_MENU, VK_LWIN, VK_RWIN,
	VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU, VK_RMENU, 0
};

#else
/*
* Hack -- initialization list for "special_key"
*
* We ignore the modifier keys (shift, control, alt, num lock, scroll lock),
* and the normal keys (escape, tab, return, letters, numbers, etc), but we
* catch the keypad keys (with and without numlock set, including keypad 5),
* the function keys (including the "menu" key which maps to F10), and the
* "pause" key (between scroll lock and numlock).  We also catch a few odd
* keys which I do not recognize, but which are listed among keys which we
* do catch, so they should be harmless to catch.
*/
static byte special_key_list[] =
{
	VK_CLEAR, 		/* 0x0C (KP<5>) */

	VK_PAUSE, 		/* 0x13 (pause) */

	VK_PRIOR, 		/* 0x21 (KP<9>) */
	VK_NEXT, 		/* 0x22 (KP<3>) */
	VK_END, 			/* 0x23 (KP<1>) */
	VK_HOME, 		/* 0x24 (KP<7>) */
	VK_LEFT, 		/* 0x25 (KP<4>) */
	VK_UP, 			/* 0x26 (KP<8>) */
	VK_RIGHT, 		/* 0x27 (KP<6>) */
	VK_DOWN, 		/* 0x28 (KP<2>) */
	VK_SELECT, 		/* 0x29 (?????) */
	VK_PRINT, 		/* 0x2A (?????) */
	VK_EXECUTE, 		/* 0x2B (?????) */
	VK_SNAPSHOT, 	/* 0x2C (?????) */
	VK_INSERT, 		/* 0x2D (KP<0>) */
	VK_DELETE, 		/* 0x2E (KP<.>) */
	VK_HELP, 		/* 0x2F (?????) */

#if 0
	VK_NUMPAD0, 		/* 0x60 (KP<0>) */
	VK_NUMPAD1, 		/* 0x61 (KP<1>) */
	VK_NUMPAD2, 		/* 0x62 (KP<2>) */
	VK_NUMPAD3, 		/* 0x63 (KP<3>) */
	VK_NUMPAD4, 		/* 0x64 (KP<4>) */
	VK_NUMPAD5, 		/* 0x65 (KP<5>) */
	VK_NUMPAD6, 		/* 0x66 (KP<6>) */
	VK_NUMPAD7, 		/* 0x67 (KP<7>) */
	VK_NUMPAD8, 		/* 0x68 (KP<8>) */
	VK_NUMPAD9, 		/* 0x69 (KP<9>) */
	VK_MULTIPLY, 	/* 0x6A (KP<*>) */
	VK_ADD, 			/* 0x6B (KP<+>) */
	VK_SEPARATOR, 	/* 0x6C (?????) */
	VK_SUBTRACT, 	/* 0x6D (KP<->) */
	VK_DECIMAL, 		/* 0x6E (KP<.>) */
	VK_DIVIDE, 		/* 0x6F (KP) */
#endif

	VK_F1, 			/* 0x70 */
	VK_F2, 			/* 0x71 */
	VK_F3, 			/* 0x72 */
	VK_F4, 			/* 0x73 */
	VK_F5, 			/* 0x74 */
	VK_F6, 			/* 0x75 */
	VK_F7, 			/* 0x76 */
	VK_F8, 			/* 0x77 */
	VK_F9, 			/* 0x78 */
	VK_F10, 			/* 0x79 */
	VK_F11, 			/* 0x7A */
	VK_F12, 			/* 0x7B */
	VK_F13, 			/* 0x7C */
	VK_F14, 			/* 0x7D */
	VK_F15, 			/* 0x7E */
	VK_F16, 			/* 0x7F */
	VK_F17, 			/* 0x80 */
	VK_F18, 			/* 0x81 */
	VK_F19, 			/* 0x82 */
	VK_F20, 			/* 0x83 */
	VK_F21, 			/* 0x84 */
	VK_F22, 			/* 0x85 */
	VK_F23, 			/* 0x86 */
	VK_F24, 			/* 0x87 */

	0
};
#endif


/*
 * Hack -- given a pathname, point at the filename
 */
static cptr extract_file_name(cptr s)
{
	cptr p;

	/* Start at the end */
	p = s + strlen(s) - 1;

	/* Back up to divider */
	while ((p >= s) && (*p != ':') && (*p != '\\')) p--;

	/* Return file name */
	return (p + 1);
}


/*
 * Hack -- given a simple filename, extract the "font size" info
 *
 * Return a pointer to a static buffer holding the capitalized base name.
 */
static char *analyze_font(char *path, int *wp, int *hp)
{
	int wid, hgt;

	char *s, *p;

	/* Start at the end */
	p = path + strlen(path) - 1;

	/* Back up to divider */
	while ((p >= path) && (*p != ':') && (*p != '\\')) --p;

	/* Advance to file name */
	++p;

	/* Capitalize */
	for (s = p; *s; ++s)
	{
		/* Capitalize (be paranoid) */
		if (islower(*s)) *s = toupper(*s);
	}

	/* Find first 'X' */
	s = strchr(p, 'X');

	/* Extract font width */
	wid = atoi(p);

	/* Extract height */
	hgt = s ? atoi(s + 1) : 0;

	/* Save results */
	(*wp) = wid;
	(*hp) = hgt;

	/* Result */
	return (p);
}


/*
 * Check for existance of a file
 */
static bool check_file(cptr s)
{
	char path[1024];

#ifdef WIN32

	DWORD attrib;

#else /* WIN32 */

	unsigned int attrib;

#endif /* WIN32 */

	/* Copy it */
	strcpy(path, s);

#ifdef WIN32

	/* Examine */
	attrib = GetFileAttributes(path);

	/* Require valid filename */
	if (attrib == INVALID_FILE_NAME) return (FALSE);

	/* Prohibit directory */
	if (attrib & FILE_ATTRIBUTE_DIRECTORY) return (FALSE);

#else /* WIN32 */

	/* Examine and verify */
	if (_dos_getfileattr(path, &attrib)) return (FALSE);

	/* Prohibit something */
	if (attrib & FA_LABEL) return (FALSE);

	/* Prohibit directory */
	if (attrib & FA_DIREC) return (FALSE);

#endif /* WIN32 */

	/* Success */
	return (TRUE);
}


/*
 * Check for existance of a directory
 */
static bool check_dir(cptr s)
{
	int i;

	char path[1024];

#ifdef WIN32

	DWORD attrib;

#else /* WIN32 */

	unsigned int attrib;

#endif /* WIN32 */

	/* Copy it */
	strcpy(path, s);

	/* Check length */
	i = strlen(path);

	/* Remove trailing backslash */
	if (i && (path[i - 1] == '\\')) path[--i] = '\0';

#ifdef WIN32

	/* Examine */
	attrib = GetFileAttributes(path);

	/* Require valid filename */
	if (attrib == INVALID_FILE_NAME) return (FALSE);

	/* Require directory */
	if (!(attrib & FILE_ATTRIBUTE_DIRECTORY)) return (FALSE);

#else /* WIN32 */

	/* Examine and verify */
	if (_dos_getfileattr(path, &attrib)) return (FALSE);

	/* Prohibit something */
	if (attrib & FA_LABEL) return (FALSE);

	/* Require directory */
	if (!(attrib & FA_DIREC)) return (FALSE);

#endif /* WIN32 */

	/* Success */
	return (TRUE);
}


/*
 * Validate a file
 */
static void validate_file(cptr s)
{
	/* Verify or fail */
	if (!check_file(s))
	{
		quit_fmt("Cannot find required file:\n%s", s);
	}
}


/*
 * Validate a directory
 */
static void validate_dir(cptr s)
{
	/* Verify or fail */
	if (!check_dir(s))
	{
		quit_fmt("Cannot find required directory:\n%s", s);
	}
}


/*
 * Get the "size" for a window
 */
static void term_getsize(term_data *td)
{
	RECT rc;

	int wid, hgt;

	/*
	 * The Angband window is always at least 80x24. I'm not sure if
	 * small windows work... -- pelpel
	 */
	if (td == &data[0])
	{
		if (td->cols < 80) td->cols = 80;
		if (td->rows < 24) td->rows = 24;
	}

	/* The other windows can be smaller */
	else
	{
		/* Paranoia */
		if (td->cols < 1) td->cols = 1;
		if (td->rows < 1) td->rows = 1;
	}

	/* Paranoia */
	if (td->cols > 255) td->cols = 255;
	if (td->rows > 255) td->rows = 255;

	/* Window sizes */
	wid = td->cols * td->tile_wid + td->size_ow1 + td->size_ow2;
	hgt = td->rows * td->tile_hgt + td->size_oh1 + td->size_oh2;

	/* Fake window size */
	rc.left = 0;
	rc.right = rc.left + wid;
	rc.top = 0;
	rc.bottom = rc.top + hgt;

	/* XXX XXX XXX */
	/* rc.right += 1; */
	/* rc.bottom += 1; */

	/* Adjust */
	AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);

	/* Total size */
	td->size_wid = rc.right - rc.left;
	td->size_hgt = rc.bottom - rc.top;

	/* See CreateWindowEx */
	if (!td->w) return;

	/* Extract actual location */
	GetWindowRect(td->w, &rc);

	/* Save the location */
	td->pos_x = rc.left;
	td->pos_y = rc.top;
}


/*
 * Write the "prefs" for a single term
 */
static void save_prefs_aux(term_data *td, cptr sec_name)
{
	char buf[1024];

	RECT rc;

	/* Paranoia */
	if (!td->w) return;

	/* Visible */
	strcpy(buf, td->visible ? "1" : "0");
	WritePrivateProfileString(sec_name, "Visible", buf, ini_file);

	/* Font */
	strcpy(buf, td->font_file ? td->font_file : "8X13.FON");
	WritePrivateProfileString(sec_name, "Font", buf, ini_file);

	/* Bizarre */
	strcpy(buf, td->bizarre ? "1" : "0");
	WritePrivateProfileString(sec_name, "Bizarre", buf, ini_file);

	/* Tile size (x) */
	wsprintf(buf, "%d", td->tile_wid);
	WritePrivateProfileString(sec_name, "TileWid", buf, ini_file);

	/* Tile size (y) */
	wsprintf(buf, "%d", td->tile_hgt);
	WritePrivateProfileString(sec_name, "TileHgt", buf, ini_file);

	/* Window size (x) */
	wsprintf(buf, "%d", td->cols);
	WritePrivateProfileString(sec_name, "NumCols", buf, ini_file);

	/* Window size (y) */
	wsprintf(buf, "%d", td->rows);
	WritePrivateProfileString(sec_name, "NumRows", buf, ini_file);

	/* Acquire position */
	GetWindowRect(td->w, &rc);

	/* Window position (x) */
	wsprintf(buf, "%d", rc.left);
	WritePrivateProfileString(sec_name, "PositionX", buf, ini_file);

	/* Window position (y) */
	wsprintf(buf, "%d", rc.top);
	WritePrivateProfileString(sec_name, "PositionY", buf, ini_file);
}


/*
 * Write the "prefs"
 *
 * We assume that the windows have all been initialized
 */
static void save_prefs(void)
{
	int i;

	char buf[128];

	/* Save the "arg_graphics" flag */
	sprintf(buf, "%d", arg_graphics);
	WritePrivateProfileString("Angband", "Graphics", buf, ini_file);

	/* Save the "arg_bigtile" flag */
	strcpy(buf, arg_bigtile ? "1" : "0");
	WritePrivateProfileString("Angband", "Bigtile", buf, ini_file);

	/* Save the "arg_sound" flag */
	strcpy(buf, arg_sound ? "1" : "0");
	WritePrivateProfileString("Angband", "Sound", buf, ini_file);

#ifdef SUPPORT_GAMMA
	/* Save the "gamma_val" */
	sprintf(buf, "%d", gamma_val);
	WritePrivateProfileString("Angband", "GammaVal", buf, ini_file);
#endif /* SUPPORT_GAMMA */

	/* Save window prefs */
	for (i = 0; i < MAX_TERM_DATA; ++i)
	{
		term_data *td = &data[i];

		sprintf(buf, "Term-%d", i);

		save_prefs_aux(td, buf);
	}
}


/*
 * Load the "prefs" for a single term
 */
static void load_prefs_aux(term_data *td, cptr sec_name)
{
	char tmp[1024];

	int wid, hgt;

	/* Visible */
	td->visible = (GetPrivateProfileInt(sec_name, "Visible", td->visible, ini_file) != 0);

	/* Desired font, with default */
	GetPrivateProfileString(sec_name, "Font", "8X13.FON", tmp, 127, ini_file);

	/* Bizarre */
	td->bizarre = (GetPrivateProfileInt(sec_name, "Bizarre", td->bizarre, ini_file) != 0);

	/* Analyze font, save desired font name */
	td->font_want = string_make(analyze_font(tmp, &wid, &hgt));

	/* Tile size */
	td->tile_wid = GetPrivateProfileInt(sec_name, "TileWid", wid, ini_file);
	td->tile_hgt = GetPrivateProfileInt(sec_name, "TileHgt", hgt, ini_file);

	/* Window size */
	td->cols = GetPrivateProfileInt(sec_name, "NumCols", td->cols, ini_file);
	td->rows = GetPrivateProfileInt(sec_name, "NumRows", td->rows, ini_file);

	/* Window position */
	td->pos_x = GetPrivateProfileInt(sec_name, "PositionX", td->pos_x, ini_file);
	td->pos_y = GetPrivateProfileInt(sec_name, "PositionY", td->pos_y, ini_file);
}


/*
 * Load the "prefs"
 */
static void load_prefs(void)
{
	int i;

	char buf[1024];

	/* Extract the "arg_graphics" flag */
	arg_graphics = GetPrivateProfileInt("Angband", "Graphics", 0, ini_file);

	/* Extract the "arg_bigtile" flag */
	arg_bigtile = GetPrivateProfileInt("Angband", "Bigtile", FALSE, ini_file);
	use_bigtile = arg_bigtile;

	/* Extract the "arg_sound" flag */
	arg_sound = (GetPrivateProfileInt("Angband", "Sound", 0, ini_file) != 0);

#ifdef SUPPORT_GAMMA
	/* Extract the "gamma_val" */
	gamma_val = GetPrivateProfileInt("Angband", "GammaVal", 0, ini_file);
#endif /* SUPPORT_GAMMA */

	/* Load window prefs */
	for (i = 0; i < MAX_TERM_DATA; ++i)
	{
		term_data *td = &data[i];

		sprintf(buf, "Term-%d", i);

		load_prefs_aux(td, buf);
	}
}


/*
 * Create the new global palette based on the bitmap palette
 * (if any), and the standard 16 entry palette derived from
 * "win_clr[]" which is used for the basic 16 Angband colors.
 *
 * This function is never called before all windows are ready.
 *
 * This function returns FALSE if the new palette could not be
 * prepared, which should normally be a fatal error.  XXX XXX
 *
 * Note that only some machines actually use a "palette".
 */
static int new_palette(void)
{
	HPALETTE hBmPal;
	HPALETTE hNewPal;
	HDC hdc;
	int i, nEntries;
	int pLogPalSize;
	int lppeSize;
	LPLOGPALETTE pLogPal;
	LPPALETTEENTRY lppe;

	term_data *td;


	/* This makes no sense */
	if (!paletted) return (TRUE);


	/* No palette */
	hBmPal = NULL;

	/* No bitmap */
	lppeSize = 0;
	lppe = NULL;
	nEntries = 0;

#ifdef USE_GRAPHICS

	/* Check the bitmap palette */
	hBmPal = infGraph.hPalette;

	/* Use the bitmap */
	if (hBmPal)
	{
		lppeSize = 256 * sizeof(PALETTEENTRY);
		lppe = (LPPALETTEENTRY)ralloc(lppeSize);
		nEntries = GetPaletteEntries(hBmPal, 0, 255, lppe);
		if ((nEntries == 0) || (nEntries > 220))
		{
			/* Warn the user */
			plog_fmt("Unusable bitmap palette (%d entries)", nEntries);

			/* Cleanup */
			rnfree(lppe, lppeSize);

			/* Fail */
			return (FALSE);
		}
	}

#endif

	/* Size of palette */
	pLogPalSize = sizeof(LOGPALETTE) + (nEntries + 16) * sizeof(PALETTEENTRY);

	/* Allocate palette */
	pLogPal = (LPLOGPALETTE)ralloc(pLogPalSize);

	/* Version */
	pLogPal->palVersion = 0x300;

	/* Make room for bitmap and normal data */
	pLogPal->palNumEntries = nEntries + 16;

	/* Save the bitmap data */
	for (i = 0; i < nEntries; i++)
	{
		pLogPal->palPalEntry[i] = lppe[i];
	}

	/* Save the normal data */
	for (i = 0; i < 16; i++)
	{
		LPPALETTEENTRY p;

		/* Access the entry */
		p = &(pLogPal->palPalEntry[i + nEntries]);

		/* Save the colors */
		p->peRed = GetRValue(win_clr[i]);
		p->peGreen = GetGValue(win_clr[i]);
		p->peBlue = GetBValue(win_clr[i]);

		/* Save the flags */
		p->peFlags = PC_NOCOLLAPSE;
	}

	/* Free something */
	if (lppe) rnfree(lppe, lppeSize);

	/* Create a new palette, or fail */
	hNewPal = CreatePalette(pLogPal);
	if (!hNewPal) quit("Cannot create palette!");

	/* Free the palette */
	rnfree(pLogPal, pLogPalSize);

	/* Main window */
	td = &data[0];

	/* Realize the palette */
	hdc = GetDC(td->w);
	SelectPalette(hdc, hNewPal, 0);
	i = RealizePalette(hdc);
	ReleaseDC(td->w, hdc);
	if (i == 0) quit("Cannot realize palette!");

	/* Sub-windows */
	for (i = 1; i < MAX_TERM_DATA; i++)
	{
		td = &data[i];

		hdc = GetDC(td->w);
		SelectPalette(hdc, hNewPal, 0);
		ReleaseDC(td->w, hdc);
	}

	/* Delete old palette */
	if (hPal) DeleteObject(hPal);

	/* Save new palette */
	hPal = hNewPal;

	/* Success */
	return (TRUE);
}


/*
 * Initialize graphics
 */
static bool init_graphics()
{
	/* Initialize once */
	/*if (can_use_graphics != arg_graphics) */
	{
		char buf[1024];
		int wid, hgt;
		cptr name;

#ifdef USE_TRANSPARENCY

		/* Unused */
		PALETTEENTRY entry =
		        {
		                0, 0, 0, 0
		        };
		(void)entry;

#endif /* USE_TRANSPARENCY */

		if (arg_graphics == 2)
		{
			wid = 16;
			hgt = 16;

			name = "16X16.BMP";

			ANGBAND_GRAF = "new";
		}
		else
		{
			wid = 8;
			hgt = 8;

			name = "8X8.BMP";
			ANGBAND_GRAF = "old";
		}

		/* Access the bitmap file */
		path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, name);

		/* Load the bitmap or quit */
		if (!ReadDIB(data[0].w, buf, &infGraph))
		{
			plog_fmt("Cannot read bitmap file '%s'", name);
			return (FALSE);
		}

		/* Save the new sizes */
		infGraph.CellWidth = wid;
		infGraph.CellHeight = hgt;


#ifdef USE_TRANSPARENCY

		path_build(buf, 1024, ANGBAND_DIR_XTRA_GRAF, "mask.bmp");
		/* Load the bitmap or quit */
		if (!ReadDIB(data[0].w, buf, &infMask))
		{
			plog_fmt("Cannot read bitmap file '%s'", name);
			return (FALSE);
		}

#endif /* USE_TRANSPARENCY */

		/* Activate a palette */
		if (!new_palette())
		{
			/* Free bitmap XXX XXX XXX */

			/* Oops */
			plog("Cannot activate palette!");
			return (FALSE);
		}

		/* Graphics available */
		can_use_graphics = arg_graphics;
	}

	/* Result */
	return (can_use_graphics);
}


/*
 * Initialize sound
 */
static bool init_sound()
{
	/* Initialize once */
	if (!can_use_sound)
	{
		int i;

		char wav[128];
		char buf[1024];

		/* Prepare the sounds */
		for (i = 1; i < SOUND_MAX; i++)
		{
			/* Extract name of sound file */
			sprintf(wav, "%s.wav", angband_sound_name[i]);

			/* Access the sound */
			path_build(buf, 1024, ANGBAND_DIR_XTRA_SOUND, wav);

			/* Save the sound filename, if it exists */
			if (check_file(buf)) sound_file[i] = string_make(buf);
		}

		/* Sound available */
		can_use_sound = TRUE;
	}

	/* Result */
	return (can_use_sound);
}



/*
 * Resize a window
 */
static void term_window_resize(term_data *td)
{
	/* Require window */
	if (!td->w) return;

	/* Resize the window */
	SetWindowPos(td->w, 0, 0, 0,
	             td->size_wid, td->size_hgt,
	             SWP_NOMOVE | SWP_NOZORDER);

	/* Redraw later */
	InvalidateRect(td->w, NULL, TRUE);
}



/*
 * Force the use of a new "font file" for a term_data
 *
 * This function may be called before the "window" is ready
 *
 * This function returns zero only if everything succeeds.
 *
 * Note that the "font name" must be capitalized!!!
 */
static errr term_force_font(term_data *td, cptr path)
{
	int i;

	int wid, hgt;

	char *base;

	char buf[1024];


	/* Forget the old font (if needed) */
	if (td->font_id) DeleteObject(td->font_id);

	/* Forget old font */
	if (td->font_file)
	{
		bool used = FALSE;

		/* Scan windows */
		for (i = 0; i < MAX_TERM_DATA; i++)
		{
			/* Check "screen" */
			if ((td != &data[i]) &&
			                (data[i].font_file) &&
			                (streq(data[i].font_file, td->font_file)))
			{
				used = TRUE;
			}
		}

		/* Remove unused font resources */
		if (!used) RemoveFontResource(td->font_file);

		/* Free the old name */
		string_free(td->font_file);

		/* Forget it */
		td->font_file = NULL;
	}


	/* No path given */
	if (!path) return (1);


	/* Local copy */
	strcpy(buf, path);

	/* Analyze font path */
	base = analyze_font(buf, &wid, &hgt);

	/* Verify suffix */
	if (!suffix(base, ".FON")) return (1);

	/* Verify file */
	if (!check_file(buf)) return (1);

	/* Load the new font */
	if (!AddFontResource(buf)) return (1);

	/* Save new font name */
	td->font_file = string_make(base);

	/* Remove the "suffix" */
	base[strlen(base) - 4] = '\0';

	/* Create the font (using the 'base' of the font file name!) */
	td->font_id = CreateFont(hgt, wid, 0, 0, FW_DONTCARE, 0, 0, 0,
	                         ANSI_CHARSET, OUT_DEFAULT_PRECIS,
	                         CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
	                         FIXED_PITCH | FF_DONTCARE, base);

	/* Hack -- Unknown size */
	if (!wid || !hgt)
	{
		HDC hdcDesktop;
		HFONT hfOld;
		TEXTMETRIC tm;

		/* all this trouble to get the cell size */
		hdcDesktop = GetDC(HWND_DESKTOP);
		hfOld = SelectObject(hdcDesktop, td->font_id);
		GetTextMetrics(hdcDesktop, &tm);
		SelectObject(hdcDesktop, hfOld);
		ReleaseDC(HWND_DESKTOP, hdcDesktop);

		/* Font size info */
		wid = tm.tmAveCharWidth;
		hgt = tm.tmHeight;
	}

	/* Save the size info */
	td->font_wid = wid;
	td->font_hgt = hgt;

	/* Success */
	return (0);
}



/*
 * Allow the user to change the font for this window.
 */
static void term_change_font(term_data *td)
{
	OPENFILENAME ofn;

	char tmp[1024] = "";

	/* Extract a default if possible */
	if (td->font_file) strcpy(tmp, td->font_file);

	/* Ask for a choice */
	memset(&ofn, 0, sizeof(ofn));
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = data[0].w;
	ofn.lpstrFilter = "Angband Font Files (*.fon)\0*.fon\0";
	ofn.nFilterIndex = 1;
	ofn.lpstrFile = tmp;
	ofn.nMaxFile = 128;
	ofn.lpstrInitialDir = ANGBAND_DIR_XTRA_FONT;
	ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
	ofn.lpstrDefExt = "fon";

	/* Force choice if legal */
	if (GetOpenFileName(&ofn))
	{
		/* Force the font */
		if (term_force_font(td, tmp))
		{
			/* Access the standard font file */
			path_build(tmp, 1024, ANGBAND_DIR_XTRA_FONT, "8X13.FON");

			/* Force the use of that font */
			(void)term_force_font(td, tmp);
		}

		/* Assume not bizarre */
		td->bizarre = FALSE;

		/* Reset the tile info */
		td->tile_wid = td->font_wid;
		td->tile_hgt = td->font_hgt;

		/* Analyze the font */
		term_getsize(td);

		/* Resize the window */
		term_window_resize(td);
	}
}



/*
 * Hack -- redraw a term_data
 */
static void term_data_redraw(term_data *td)
{
	/* Activate the term */
	Term_activate(&td->t);

	/* Redraw the contents */
	Term_redraw();

	/* Restore the term */
	Term_activate(term_screen);
}





/*** Function hooks needed by "Term" ***/


#if 0

/*
 * Initialize a new Term
 */
static void Term_init_win(term *t)
{
	/* XXX Unused */
}


/*
 * Nuke an old Term
 */
static void Term_nuke_win(term *t)
{
	/* XXX Unused */
}

#endif


/*
 * Interact with the User
 */
static errr Term_user_win(int n)
{
	/* Success */
	return (0);
}


#ifdef SUPPORT_GAMMA

/*
 * When set to TRUE, indicates that we can use gamma_table
 */
static bool gamma_table_ready = FALSE;

#endif /* SUPPORT_GAMMA */


/*
 * React to global changes
 */
static errr Term_xtra_win_react(void)
{
	int i;


	/* Simple color */
	if (colors16)
	{
		/* Save the default colors */
		for (i = 0; i < 256; i++)
		{
			/* Simply accept the desired colors */
			win_pal[i] = angband_color_table[i][0];
		}
	}

	/* Complex color */
	else
	{
		COLORREF code;

		byte rv, gv, bv;

		bool change = FALSE;

#ifdef SUPPORT_GAMMA

		static u16b old_gamma_val = 0;


		/* React to change in the gamma value */
		if (gamma_val != old_gamma_val)
		{
			/* Temporarily inactivate the gamma table */
			gamma_table_ready = FALSE;

			/* Only need to build the table if gamma exists */
			if (gamma_val)
			{
				/* Rebuild the table */
				build_gamma_table(gamma_val);

				/* Activate the table */
				gamma_table_ready = TRUE;
			}

			/* Remember the gamma value used */
			old_gamma_val = gamma_val;
		}

#endif /* SUPPORT_GAMMA */

		/* Save the default colors */
		for (i = 0; i < 256; i++)
		{
			/* Extract desired values */
			rv = angband_color_table[i][1];
			gv = angband_color_table[i][2];
			bv = angband_color_table[i][3];

#ifdef SUPPORT_GAMMA

			/* Hack - Gamma correction */
			if (gamma_table_ready)
			{
				rv = gamma_table[rv];
				gv = gamma_table[gv];
				bv = gamma_table[bv];
			}

#endif /* SUPPORT_GAMMA */

			/* Extract a full color code */
			code = PALETTERGB(rv, gv, bv);

			/* Activate changes */
			if (win_clr[i] != code)
			{
				/* Note the change */
				change = TRUE;

				/* Apply the desired color */
				win_clr[i] = code;
			}
		}

		/* Activate the palette if needed */
		if (change) (void)new_palette();
	}


#ifdef USE_SOUND

	/* Handle "arg_sound" */
	if (use_sound != arg_sound)
	{
		/* Initialize (if needed) */
		if (arg_sound && !init_sound())
		{
			/* Warning */
			plog("Cannot initialize sound!");

			/* Cannot enable */
			arg_sound = FALSE;
		}

		/* Change setting */
		use_sound = arg_sound;
	}

#endif


#ifdef USE_GRAPHICS

	/* Handle "arg_graphics" */
	if (use_graphics != arg_graphics)
	{
		/* Initialize (if needed) */
		if (arg_graphics && !init_graphics())
		{
			/* Warning */
			plog("Cannot initialize graphics!");

			/* Cannot enable */
			arg_graphics = FALSE;
		}

		/* Change setting */
		use_graphics = arg_graphics;

		/* Reset visuals */
		reset_visuals();
	}

#endif /* USE_GRAPHICS */


	/* Clean up windows */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		term *old = Term;

		term_data *td = &data[i];

		/* Update resized windows */
		if ((td->cols != td->t.wid) || (td->rows != td->t.hgt))
		{
			/* Activate */
			Term_activate(&td->t);

			/* Hack -- Resize the term */
			Term_resize(td->cols, td->rows);

			/* Redraw the contents */
			Term_redraw();

			/* Restore */
			Term_activate(old);
		}
	}


	/* Success */
	return (0);
}


/*
 * Process at least one event
 */
static errr Term_xtra_win_event(int v)
{
	MSG msg;

	/* Wait for an event */
	if (v)
	{
		/* Block */
		if (GetMessage(&msg, NULL, 0, 0))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	/* Check for an event */
	else
	{
		irc_poll();

		/* Check */
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	/* Success */
	return 0;
}


/*
 * Process all pending events
 */
static errr Term_xtra_win_flush(void)
{
	MSG msg;

	/* Process all pending events */
	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	/* Success */
	return (0);
}


/*
 * Hack -- clear the screen
 *
 * Make this more efficient XXX XXX XXX
 */
static errr Term_xtra_win_clear(void)
{
	term_data *td = (term_data*)(Term->data);

	HDC hdc;
	RECT rc;

	/* Rectangle to erase */
	rc.left = td->size_ow1;
	rc.right = rc.left + td->cols * td->tile_wid;
	rc.top = td->size_oh1;
	rc.bottom = rc.top + td->rows * td->tile_hgt;

	/* Erase it */
	hdc = GetDC(td->w);
	SetBkColor(hdc, RGB(0, 0, 0));
	SelectObject(hdc, td->font_id);
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
	ReleaseDC(td->w, hdc);

	/* Success */
	return 0;
}


/*
 * Hack -- make a noise
 */
static errr Term_xtra_win_noise(void)
{
	MessageBeep(MB_ICONASTERISK);
	return (0);
}


/*
 * Hack -- make a sound
 */
static errr Term_xtra_win_sound(int v)
{
	/* Sound disabled */
	if (!use_sound) return (1);

	/* Illegal sound */
	if ((v < 0) || (v >= SOUND_MAX)) return (1);

	/* Unknown sound */
	if (!sound_file[v]) return (1);

#ifdef USE_SOUND

#ifdef WIN32

	/* Play the sound, catch errors */
	return (PlaySound(sound_file[v], 0, SND_FILENAME | SND_ASYNC));

#else /* WIN32 */

/* Play the sound, catch errors */
	return (sndPlaySound(sound_file[v], SND_ASYNC));

#endif /* WIN32 */

#endif /* USE_SOUND */

	/* Oops */
	return (1);
}


/*
 * Delay for "x" milliseconds
 */
static int Term_xtra_win_delay(int v)
{

#ifdef WIN32

	/* Sleep */
	Sleep(v);

#else /* WIN32 */

	DWORD t;
	MSG msg;

	/* Final count */
	t = GetTickCount() + v;

	/* Wait for it */
	while (GetTickCount() < t)
	{
		/* Handle messages */
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

#endif /* WIN32 */

	/* Success */
	return (0);
}

/*
 * Return the HWND of the main window
 */
HWND get_main_hwnd()
{
	return data[0].w;
}

/*
 * Do a "special thing"
 */
static errr Term_xtra_win(int n, int v)
{
	/* Handle a subset of the legal requests */
	switch (n)
	{
		/* Make a bell sound */
	case TERM_XTRA_NOISE:
		{
			return (Term_xtra_win_noise());
		}

		/* Make a special sound */
	case TERM_XTRA_SOUND:
		{
			return (Term_xtra_win_sound(v));
		}

		/* Process random events */
	case TERM_XTRA_BORED:
		{
			return (Term_xtra_win_event(0));
		}

		/* Process an event */
	case TERM_XTRA_EVENT:
		{
			return (Term_xtra_win_event(v));
		}

		/* Flush all events */
	case TERM_XTRA_FLUSH:
		{
			return (Term_xtra_win_flush());
		}

		/* Clear the screen */
	case TERM_XTRA_CLEAR:
		{
			return (Term_xtra_win_clear());
		}

		/* React to global changes */
	case TERM_XTRA_REACT:
		{
			return (Term_xtra_win_react());
		}

		/* Delay for some milliseconds */
	case TERM_XTRA_DELAY:
		{
			irc_poll();

			return (Term_xtra_win_delay(v));
		}

		/* Get the current time in milliseconds */
	case TERM_XTRA_GET_DELAY:
		{
			DWORD t;

			t = GetTickCount();
			Term_xtra_long = t;
			return 0;
		}

		/*
		 * Scans for subdirectories in a directory "scansubdir_dir"
		 * and place teh result in "scansubdir_result/scansubdir_max"
		 */
	case TERM_XTRA_SCANSUBDIR:
		{
			BOOL ok;
			HANDLE h;
			WIN32_FIND_DATA fd;
			for (h = FindFirstFile(format("%s\\*", scansubdir_dir), &fd), ok = 1;
			                h != INVALID_HANDLE_VALUE && ok;
			                ok = FindNextFile(h, &fd))
			{
				if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(fd.cFileName, ".")) && (strcmp(fd.cFileName, "..")))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(fd.cFileName);
					scansubdir_max++;
				}
			}

			return 0;
		}

		/* Rename main window */
	case TERM_XTRA_RENAME_MAIN_WIN:
		SetWindowText(get_main_hwnd(), angband_term_name[0]); return (0);
	}

	/* Oops */
	return 1;
}



/*
 * Low level graphics (Assumes valid input).
 *
 * Draw a "cursor" at (x,y), using a "yellow box".
 */
static errr Term_curs_win(int x, int y)
{
	term_data *td = (term_data*)(Term->data);

	RECT rc;
	HDC hdc;

	/* Frame the grid */
	rc.left = x * td->tile_wid + td->size_ow1;
	rc.right = rc.left + td->tile_wid;
	rc.top = y * td->tile_hgt + td->size_oh1;
	rc.bottom = rc.top + td->tile_hgt;

	if (use_bigtile && x + 1 < Term->wid && Term->old->a[y][x + 1] == 255)
		rc.right += td->tile_wid;

	/* Cursor is done as a yellow "box" */
	hdc = GetDC(data[0].w);
	FrameRect(hdc, &rc, hbrYellow);
	ReleaseDC(data[0].w, hdc);

	/* Success */
	return 0;
}


/*
 * Low level graphics (Assumes valid input).
 *
 * Erase a "block" of "n" characters starting at (x,y).
 */
static errr Term_wipe_win(int x, int y, int n)
{
	term_data *td = (term_data*)(Term->data);

	HDC hdc;
	RECT rc;

	/* Rectangle to erase in client coords */
	rc.left = x * td->tile_wid + td->size_ow1;
	rc.right = rc.left + n * td->tile_wid;
	rc.top = y * td->tile_hgt + td->size_oh1;
	rc.bottom = rc.top + td->tile_hgt;

	hdc = GetDC(td->w);
	SetBkColor(hdc, RGB(0, 0, 0));
	SelectObject(hdc, td->font_id);
	ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
	ReleaseDC(td->w, hdc);

	/* Success */
	return 0;
}

/*
 * Low level graphics.  Assumes valid input.
 *
 * Draw several ("n") chars, with an attr, at a given location.
 *
 * All "graphic" data is handled by "Term_pict_win()", below.
 *
 * One would think there is a more efficient method for telling a window
 * what color it should be using to draw with, but perhaps simply changing
 * it every time is not too inefficient.  XXX XXX XXX
 */
static errr Term_text_win(int x, int y, int n, byte a, const char *s)
{
	term_data *td = (term_data*)(Term->data);
	RECT rc;
	HDC hdc;


	/* Total rectangle */
	rc.left = x * td->tile_wid + td->size_ow1;
	rc.right = rc.left + n * td->tile_wid;
	rc.top = y * td->tile_hgt + td->size_oh1;
	rc.bottom = rc.top + td->tile_hgt;

	/* Acquire DC */
	hdc = GetDC(td->w);

	/* Background color */
	SetBkColor(hdc, RGB(0, 0, 0));

	/* Foreground color */
	if (colors16)
	{
		SetTextColor(hdc, PALETTEINDEX(win_pal[a]));
	}
	else if (paletted)
	{
		SetTextColor(hdc, win_clr[a&0x0F]);
	}
	else
	{
		SetTextColor(hdc, win_clr[a]);
	}

	/* Use the font */
	SelectObject(hdc, td->font_id);

	/* Bizarre size */
	if (td->bizarre ||
	                (td->tile_hgt != td->font_hgt) ||
	                (td->tile_wid != td->font_wid))
	{
		int i;

		/* Erase complete rectangle */
		ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);

		/* New rectangle */
		rc.left += ((td->tile_wid - td->font_wid) / 2);
		rc.right = rc.left + td->font_wid;
		rc.top += ((td->tile_hgt - td->font_hgt) / 2);
		rc.bottom = rc.top + td->font_hgt;

		/* Dump each character */
		for (i = 0; i < n; i++)
		{
			/* Dump the text */
			ExtTextOut(hdc, rc.left, rc.top, 0, &rc,
			           s + i, 1, NULL);

			/* Advance */
			rc.left += td->tile_wid;
			rc.right += td->tile_wid;
		}
	}

	/* Normal size */
	else
	{
		/* Dump the text */
		ExtTextOut(hdc, rc.left, rc.top, ETO_OPAQUE | ETO_CLIPPED, &rc,
		           s, n, NULL);
	}

	/* Release DC */
	ReleaseDC(td->w, hdc);

	/* Success */
	return 0;
}


/*
 * Low level graphics.  Assumes valid input.
 *
 * Draw an array of "special" attr/char pairs at the given location.
 *
 * We use the "Term_pict_win()" function for "graphic" data, which are
 * encoded by setting the "high-bits" of both the "attr" and the "char"
 * data.  We use the "attr" to represent the "row" of the main bitmap,
 * and the "char" to represent the "col" of the main bitmap.  The use
 * of this function is induced by the "higher_pict" flag.
 *
 * If "graphics" is not available, we simply "wipe" the given grids.
 */
# ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp, const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp, const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
# else /* USE_TRANSPARENCY */
static errr Term_pict_win(int x, int y, int n, const byte *ap, const char *cp)
# endif  /* USE_TRANSPARENCY */
{
	term_data *td = (term_data*)(Term->data);

#ifdef USE_GRAPHICS

	int i;
	int x1, y1, w1, h1;
	int x2, y2, w2, h2, tw2;

# ifdef USE_TRANSPARENCY

	int x3, y3;

	HDC hdcMask = NULL;

#ifdef USE_EGO_GRAPHICS

	int x4, y4;

#endif

# endif  /* USE_TRANSPARENCY */

	HDC hdc;
	HDC hdcSrc;
	HBITMAP hbmSrcOld;

	/* Paranoia */
	if (!use_graphics)
	{
		/* Erase the grids */
		return (Term_wipe_win(x, y, n));
	}

	/* Size of bitmap cell */
	w1 = infGraph.CellWidth;
	h1 = infGraph.CellHeight;

	/* Size of window cell */
	w2 = td->tile_wid;
	h2 = td->tile_hgt;
	tw2 = w2;

	/* big tile mode */
	if (use_bigtile) tw2 *= 2;

	/* Location of window cell */
	x2 = x * w2 + td->size_ow1;
	y2 = y * h2 + td->size_oh1;

	/* Info */
	hdc = GetDC(td->w);

	/* More info */
	hdcSrc = CreateCompatibleDC(hdc);
	hbmSrcOld = SelectObject(hdcSrc, infGraph.hBitmap);

# ifdef USE_TRANSPARENCY

	if (arg_graphics == 2)
	{
		hdcMask = CreateCompatibleDC(hdc);
		SelectObject(hdcMask, infMask.hBitmap);
	}

# endif  /* USE_TRANSPARENCY */

	/* Draw attr/char pairs */
	for (i = 0; i < n; i++, x2 += w2)
	{
		byte a = ap[i];
		char c = cp[i];

		/* Extract picture */
		int row = (a & 0x7F);
		int col = (c & 0x7F);

		/* Location of bitmap cell */
		x1 = col * w1;
		y1 = row * h1;

# ifdef USE_TRANSPARENCY

		if (arg_graphics == 2)
		{
			x3 = (tcp[i] & 0x7F) * w1;
			y3 = (tap[i] & 0x7F) * h1;

			/* Perfect size */
			if ((w1 == tw2) && (h1 == h2))
			{
				/* Copy the terrain picture from the bitmap to the window */
				BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, SRCCOPY);

				/* Mask out the tile */
				BitBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, SRCAND);

				/* Draw the tile */
				BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCPAINT);

#ifdef USE_EGO_GRAPHICS
				if (ecp[i] != 0 && eap[i] != 0)
				{
					x4 = (ecp[i] & 0x7F) * w1;
					y4 = (eap[i] & 0x7F) * h1;

					/* Mask out the tile */
					BitBlt(hdc, x2, y2, tw2, h2, hdcMask, x4, y4, SRCAND);

					/* Draw the tile */
					BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x4, y4, SRCPAINT);
				}
#endif
			}

			/* Need to stretch */
			else
			{
				/* Set the correct mode for stretching the tiles */
				SetStretchBltMode(hdc, COLORONCOLOR);

				/* Copy the terrain picture from the bitmap to the window */
				StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x3, y3, w1, h1, SRCCOPY);

				/* Only draw if terrain and overlay are different */
				if ((x1 != x3) || (y1 != y3))
				{
					/* Mask out the tile */
					StretchBlt(hdc, x2, y2, tw2, h2, hdcMask, x1, y1, w1, h1, SRCAND);

					/* Draw the tile */
					StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCPAINT);
				}

#ifdef USE_EGO_GRAPHICS
				if (ecp[i] != 0 && eap[i] != 0)
				{
					x4 = (ecp[i] & 0x7F) * w1;
					y4 = (eap[i] & 0x7F) * h1;

					/* Mask out the tile */
					StretchBlt(hdc, x2, y2, tw2, h2, hdcMask, x4, y4, w1, h1, SRCAND);

					/* Draw the tile */
					StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x4, y4, w1, h1, SRCPAINT);
				}
#endif
			}
		}
		else

# endif  /* USE_TRANSPARENCY */

		{
			/* Perfect size */
			if ((w1 == tw2) && (h1 == h2))
			{
				/* Copy the picture from the bitmap to the window */
				BitBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, SRCCOPY);
			}

			/* Need to stretch */
			else
			{
				/* Set the correct mode for stretching the tiles */
				SetStretchBltMode(hdc, COLORONCOLOR);

				/* Copy the picture from the bitmap to the window */
				StretchBlt(hdc, x2, y2, tw2, h2, hdcSrc, x1, y1, w1, h1, SRCCOPY);
			}
		}
	}

	/* Release */
	SelectObject(hdcSrc, hbmSrcOld);
	DeleteDC(hdcSrc);

# ifdef USE_TRANSPARENCY

	if (arg_graphics == 2)
	{
		/* Release */
		SelectObject(hdcMask, hbmSrcOld);
		DeleteDC(hdcMask);
	}

# endif  /* USE_TRANSPARENCY */

	/* Release */
	ReleaseDC(td->w, hdc);

#else /* USE_GRAPHICS */

	/* Just erase this grid */
	return (Term_wipe_win(x, y, n));

#endif /* USE_GRAPHICS */

	/* Success */
	return 0;
}


/*** Other routines ***/


/*
 * Create and initialize a "term_data" given a title
 */
static void term_data_link(term_data *td)
{
	term *t = &td->t;

	/* Initialize the term */
	term_init(t, td->cols, td->rows, td->keys);

	/* Use a "software" cursor */
	t->soft_cursor = TRUE;

	/* Use "Term_pict" for "graphic" data */
	t->higher_pict = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

#if 0
	/* Prepare the init/nuke hooks */
	t->init_hook = Term_init_win;
	t->nuke_hook = Term_nuke_win;
#endif

	/* Prepare the template hooks */
	t->user_hook = Term_user_win;
	t->xtra_hook = Term_xtra_win;
	t->curs_hook = Term_curs_win;
	t->wipe_hook = Term_wipe_win;
	t->text_hook = Term_text_win;
	t->pict_hook = Term_pict_win;

	/* Remember where we came from */
	t->data = (vptr)(td);
}


/*
 * Create the windows
 *
 * First, instantiate the "default" values, then read the "ini_file"
 * to over-ride selected values, then create the windows, and fonts.
 *
 * Must use SW_SHOW not SW_SHOWNA, since on 256 color display
 * must make active to realize the palette.  XXX XXX XXX
 */
static void init_windows(void)
{
	int i;

	term_data *td;

	char buf[1024];


	/* Main window */
	td = &data[0];
	WIPE(td, term_data);
	td->s = angband_term_name[0];
	td->keys = 1024;
	td->rows = 24;
	td->cols = 80;
	td->visible = TRUE;
	td->size_ow1 = 2;
	td->size_ow2 = 2;
	td->size_oh1 = 2;
	td->size_oh2 = 2;
	td->pos_x = 7 * 30;
	td->pos_y = 7 * 20;

	/* Sub windows */
	for (i = 1; i < MAX_TERM_DATA; i++)
	{
		td = &data[i];
		WIPE(td, term_data);
		td->s = angband_term_name[i];
		td->keys = 16;
		td->rows = 24;
		td->cols = 80;
		td->visible = FALSE;
		td->size_ow1 = 1;
		td->size_ow2 = 1;
		td->size_oh1 = 1;
		td->size_oh2 = 1;
		td->pos_x = (7 - i) * 30;
		td->pos_y = (7 - i) * 20;
	}


	/* Load prefs */
	load_prefs();


	/* Main window (need these before term_getsize gets called) */
	td = &data[0];
	td->dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU |
	               WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION |
	               WS_VISIBLE);
	td->dwExStyle = 0;
	td->visible = TRUE;

	/* Sub windows (need these before term_getsize gets called) */
	for (i = 1; i < MAX_TERM_DATA; i++)
	{
		td = &data[i];
		td->dwStyle = (WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU);
		td->dwExStyle = (WS_EX_TOOLWINDOW);
	}


	/* All windows */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		td = &data[i];

		/* Access the standard font file */
		path_build(buf, 1024, ANGBAND_DIR_XTRA_FONT, td->font_want);

		/* Activate the chosen font */
		if (term_force_font(td, buf))
		{
			/* Access the standard font file */
			path_build(buf, 1024, ANGBAND_DIR_XTRA_FONT, "8X13.FON");

			/* Force the use of that font */
			(void)term_force_font(td, buf);

			/* Oops */
			td->tile_wid = 8;
			td->tile_hgt = 13;

			/* Assume not bizarre */
			td->bizarre = FALSE;
		}

		/* Analyze the font */
		term_getsize(td);

		/* Resize the window */
		term_window_resize(td);
	}


	/* Sub windows (reverse order) */
	for (i = MAX_TERM_DATA - 1; i >= 1; --i)
	{
		td = &data[i];

		my_td = td;
		td->w = CreateWindowEx(td->dwExStyle, AngList,
		                       td->s, td->dwStyle,
		                       td->pos_x, td->pos_y,
		                       td->size_wid, td->size_hgt,
		                       HWND_DESKTOP, NULL, hInstance, NULL);
		my_td = NULL;
		if (!td->w) quit("Failed to create sub-window");

		if (td->visible)
		{
			td->size_hack = TRUE;
			ShowWindow(td->w, SW_SHOW);
			td->size_hack = FALSE;
		}

		term_data_link(td);
		angband_term[i] = &td->t;

		if (td->visible)
		{
			/* Activate the window */
			SetActiveWindow(td->w);

			/* Bring window to top */
			SetWindowPos(td->w, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
		}
	}


	/* Main window */
	td = &data[0];

	/* Main window */
	my_td = td;
	td->w = CreateWindowEx(td->dwExStyle, AppName,
	                       td->s, td->dwStyle,
	                       td->pos_x, td->pos_y,
	                       td->size_wid, td->size_hgt,
	                       HWND_DESKTOP, NULL, hInstance, NULL);
	my_td = NULL;
	if (!td->w) quit("Failed to create Angband window");

	term_data_link(td);
	angband_term[0] = &td->t;

	/* Activate the main window */
	SetActiveWindow(td->w);

	/* Bring main window back to top */
	SetWindowPos(td->w, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);


	/* New palette XXX XXX XXX */
	(void)new_palette();


	/* Create a "brush" for drawing the "cursor" */
	hbrYellow = CreateSolidBrush(win_clr[TERM_YELLOW]);


	/* Process pending messages */
	(void)Term_xtra_win_flush();
}



/*
 * Prepare the menus
 */
static void setup_menus(void)
{
	int i;

	HMENU hm = GetMenu(data[0].w);


	/* Menu "File", Disable all */
	EnableMenuItem(hm, IDM_FILE_NEW,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_FILE_OPEN,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_FILE_SAVE,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
#ifdef ALLOW_QUITTING
	EnableMenuItem(hm, IDM_FILE_ABORT,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
#else
	EnableMenuItem(hm, IDM_FILE_SCORE,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
#endif /* ALLOW_QUITTING */
	EnableMenuItem(hm, IDM_FILE_EXIT,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

	/* No character available */
	if (!character_generated)
	{
		/* Menu "File", Item "New" */
		EnableMenuItem(hm, IDM_FILE_NEW,
		               MF_BYCOMMAND | MF_ENABLED);

		/* Menu "File", Item "Open" */
		EnableMenuItem(hm, IDM_FILE_OPEN,
		               MF_BYCOMMAND | MF_ENABLED);
	}

	/* A character available */
	if (character_generated)
	{
		/* Menu "File", Item "Save" */
		EnableMenuItem(hm, IDM_FILE_SAVE,
		               MF_BYCOMMAND | MF_ENABLED);
	}

#ifdef ALLOW_QUITTING

	/* Menu "File", Item "Abort" */
	EnableMenuItem(hm, IDM_FILE_ABORT,
	               MF_BYCOMMAND | MF_ENABLED);

#else

	/* Menu "File", Item "Score" */
	if (initialized && character_generated && !character_icky)
	{
		EnableMenuItem(hm, IDM_FILE_SCORE,
		               MF_BYCOMMAND | MF_ENABLED);
	}

#endif

	/* Menu "File", Item "Exit" */
	EnableMenuItem(hm, IDM_FILE_EXIT,
	               MF_BYCOMMAND | MF_ENABLED);


	/* Menu "Window::Visibility" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		EnableMenuItem(hm, IDM_WINDOW_VIS_0 + i,
		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

		CheckMenuItem(hm, IDM_WINDOW_VIS_0 + i,
		              (data[i].visible ? MF_CHECKED : MF_UNCHECKED));

		EnableMenuItem(hm, IDM_WINDOW_VIS_0 + i,
		               MF_BYCOMMAND | MF_ENABLED);
	}

	/* Menu "Window::Font" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		EnableMenuItem(hm, IDM_WINDOW_FONT_0 + i,
		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

		if (data[i].visible)
		{
			EnableMenuItem(hm, IDM_WINDOW_FONT_0 + i,
			               MF_BYCOMMAND | MF_ENABLED);
		}
	}

	/* Menu "Window::Bizarre Display" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		EnableMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

		CheckMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
		              (data[i].bizarre ? MF_CHECKED : MF_UNCHECKED));

		if (data[i].visible)
		{
			EnableMenuItem(hm, IDM_WINDOW_BIZ_0 + i,
			               MF_BYCOMMAND | MF_ENABLED);

		}
	}

	/* Menu "Window::Increase Tile Width" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		EnableMenuItem(hm, IDM_WINDOW_I_WID_0 + i,
		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

		if (data[i].visible)
		{
			EnableMenuItem(hm, IDM_WINDOW_I_WID_0 + i,
			               MF_BYCOMMAND | MF_ENABLED);

		}
	}

	/* Menu "Window::Decrease Tile Width" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		EnableMenuItem(hm, IDM_WINDOW_D_WID_0 + i,
		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

		if (data[i].visible)
		{
			EnableMenuItem(hm, IDM_WINDOW_D_WID_0 + i,
			               MF_BYCOMMAND | MF_ENABLED);

		}
	}

	/* Menu "Window::Increase Tile Height" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		EnableMenuItem(hm, IDM_WINDOW_I_HGT_0 + i,
		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

		if (data[i].visible)
		{
			EnableMenuItem(hm, IDM_WINDOW_I_HGT_0 + i,
			               MF_BYCOMMAND | MF_ENABLED);

		}
	}

	/* Menu "Window::Decrease Tile Height" */
	for (i = 0; i < MAX_TERM_DATA; i++)
	{
		EnableMenuItem(hm, IDM_WINDOW_D_HGT_0 + i,
		               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

		if (data[i].visible)
		{
			EnableMenuItem(hm, IDM_WINDOW_D_HGT_0 + i,
			               MF_BYCOMMAND | MF_ENABLED);

		}
	}

	/* Menu "Options", disable all */
	EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_OPTIONS_ASCII_GRAPHICS,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_OPTIONS_BIGTILE,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_OPTIONS_SOUND,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_OPTIONS_UNUSED,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
	EnableMenuItem(hm, IDM_OPTIONS_SAVER,
	               MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

	/* Menu "Options", update all */
	CheckMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS,
	              (arg_graphics == 1 ? MF_CHECKED : MF_UNCHECKED));
	CheckMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS,
	              (arg_graphics == 2 ? MF_CHECKED : MF_UNCHECKED));
	CheckMenuItem(hm, IDM_OPTIONS_ASCII_GRAPHICS,
	              (arg_graphics == 0 ? MF_CHECKED : MF_UNCHECKED));
	CheckMenuItem(hm, IDM_OPTIONS_BIGTILE,
	              (arg_bigtile ? MF_CHECKED : MF_UNCHECKED));
	CheckMenuItem(hm, IDM_OPTIONS_SOUND,
	              (arg_sound ? MF_CHECKED : MF_UNCHECKED));
	CheckMenuItem(hm, IDM_OPTIONS_UNUSED,
	              (0 ? MF_CHECKED : MF_UNCHECKED));
	CheckMenuItem(hm, IDM_OPTIONS_SAVER,
	              (hwndSaver ? MF_CHECKED : MF_UNCHECKED));

#ifdef USE_GRAPHICS
	/* Menu "Options", Item "Graphics" */
	EnableMenuItem(hm, IDM_OPTIONS_OLD_GRAPHICS, MF_ENABLED);
	/* Menu "Options", Item "Graphics" */
	EnableMenuItem(hm, IDM_OPTIONS_NEW_GRAPHICS, MF_ENABLED);
	/* Menu "Options", Item "Graphics" */
	EnableMenuItem(hm, IDM_OPTIONS_ASCII_GRAPHICS, MF_ENABLED);
	/* Menu "Options", Item "Graphics" */
	EnableMenuItem(hm, IDM_OPTIONS_BIGTILE, MF_ENABLED);
#endif

#ifdef USE_SOUND
	/* Menu "Options", Item "Sound" */
	EnableMenuItem(hm, IDM_OPTIONS_SOUND, MF_ENABLED);
#endif

#ifdef USE_SAVER
	/* Menu "Options", Item "ScreenSaver" */
	EnableMenuItem(hm, IDM_OPTIONS_SAVER,
	               MF_BYCOMMAND | MF_ENABLED);
#endif

}


/*
 * Check for double clicked (or dragged) savefile
 *
 * Apparently, Windows copies the entire filename into the first
 * piece of the "command line string".  Perhaps we should extract
 * the "basename" of that filename and append it to the "save" dir.
 */
static void check_for_save_file(LPSTR cmd_line)
{
	char *s, *p;

	/* First arg */
	s = cmd_line;

	/* Second arg */
	p = strchr(s, ' ');

	/* Tokenize, advance */
	if (p) *p++ = '\0';

	/* No args */
	if (!*s) return;

	/* Extract filename */
	strcat(savefile, s);

	/* Validate the file */
	validate_file(savefile);

	/* Game in progress */
	game_in_progress = TRUE;

	/* Play game */
	play_game(FALSE);
}


/*
 * Process a menu command
 */
static void process_menus(WORD wCmd)
{
	int i;

	term_data *td;

	OPENFILENAME ofn;

	/* Analyze */
	switch (wCmd)
	{
		/* New game */
	case IDM_FILE_NEW:
		{
			if (!initialized)
			{
				plog("You cannot do that yet...");
			}
			else if (game_in_progress)
			{
				plog("You can't start a new game while you're still playing!");
			}
			else
			{
				game_in_progress = TRUE;
				Term_flush();
				play_game(TRUE);
				quit(NULL);
			}
			break;
		}

		/* Open game */
	case IDM_FILE_OPEN:
		{
			if (!initialized)
			{
				plog("You cannot do that yet...");
			}
			else if (game_in_progress)
			{
				plog("You can't open a new game while you're still playing!");
			}
			else
			{
				memset(&ofn, 0, sizeof(ofn));
#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0500)
				ofn.lStructSize = sizeof(OPENFILENAME) - (sizeof(void*) + 2 * sizeof(DWORD));
#else // old headers
ofn.lStructSize = sizeof(OPENFILENAME);
#endif
				ofn.hwndOwner = data[0].w;
				ofn.lpstrFilter = "Save Files (*.)\0*\0";
				ofn.nFilterIndex = 1;
				ofn.lpstrFile = savefile;
				ofn.nMaxFile = 1024;
				ofn.lpstrInitialDir = ANGBAND_DIR_SAVE;
				ofn.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;

				if (GetOpenFileName(&ofn))
				{
					/* Load 'savefile' */
					validate_file(savefile);
					game_in_progress = TRUE;
					Term_flush();
					play_game(FALSE);
					quit(NULL);
				}
			}
			break;
		}

		/* Save game */
	case IDM_FILE_SAVE:
		{
			if (game_in_progress && character_generated)
			{
				/* Paranoia */
				if (!inkey_flag)
				{
					plog("You may not do that right now.");
					break;
				}

				/* Hack -- Forget messages */
				msg_flag = FALSE;

				/* Save the game */
				do_cmd_save_game();
			}
			else
			{
				plog("You may not do that right now.");
			}
			break;
		}

		/* Exit */
	case IDM_FILE_EXIT:
		{
			if (game_in_progress && character_generated)
			{
				/* Paranoia */
				if (!inkey_flag)
				{
					plog("You may not do that right now.");
					break;
				}

				/* Hack -- Forget messages */
				msg_flag = FALSE;

				/* Save the game */
				do_cmd_save_game();
			}
			quit(NULL);
			break;
		}

#ifdef ALLOW_QUITTING

		/* Abort */
	case IDM_FILE_ABORT:
		{
			if (game_in_progress && character_generated)
			{
				/* XXX XXX XXX */
				if (MessageBox(data[0].w,
				                "Your character will be not saved!", "Warning",
				                MB_ICONEXCLAMATION | MB_OKCANCEL) == IDCANCEL)
				{
					break;
				}
			}
			quit(NULL);
			break;
		}

#else

		/* Score */
	case IDM_FILE_SCORE:
		{
			char buf[1024];

			/* Paranoia */
			if (!initialized || character_icky ||
			                !game_in_progress || !character_generated)
			{
				/* Can't happen but just in case */
				plog("You may not do that right now.");

				break;
			}

			/* Build the pathname of the score file */
			path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw");

			/* Hack - open the score file for reading */
			highscore_fd = fd_open(buf, O_RDONLY);

			/* Paranoia - No score file */
			if (highscore_fd < 0)
			{
				msg_print("Score file is not available.");

				break;
			}

			/* Mega-Hack - prevent various functions XXX XXX XXX */
			initialized = FALSE;

			/* Save screen */
			screen_save();

			/* Clear screen */
			Term_clear();

			/* Prepare scores */
			if (game_in_progress && character_generated)
			{
				predict_score();
			}

#if 0 /* I don't like this - pelpel */

			/* Mega-Hack - No current player XXX XXX XXX XXX */
			else
			{
				display_scores_aux(0, MAX_HISCORES, -1, NULL);
			}

#endif

			/* Close the high score file */
			(void)fd_close(highscore_fd);

			/* Forget the fd */
			highscore_fd = -1;

			/* Restore screen */
			screen_load();

			/* Hack - Flush it */
			Term_fresh();

			/* Mega-Hack - We are ready again */
			initialized = TRUE;

			/* Done */
			break;
		}

#endif

	case IDM_WINDOW_VIS_0:
		{
			plog("You are not allowed to do that!");

			break;
		}

		/* Window visibility */
	case IDM_WINDOW_VIS_1:
	case IDM_WINDOW_VIS_2:
	case IDM_WINDOW_VIS_3:
	case IDM_WINDOW_VIS_4:
	case IDM_WINDOW_VIS_5:
	case IDM_WINDOW_VIS_6:
	case IDM_WINDOW_VIS_7:
		{
			i = wCmd - IDM_WINDOW_VIS_0;

			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			td = &data[i];

			if (!td->visible)
			{
				td->visible = TRUE;
				ShowWindow(td->w, SW_SHOW);
				term_data_redraw(td);
			}
			else
			{
				td->visible = FALSE;
				ShowWindow(td->w, SW_HIDE);
			}

			break;
		}

		/* Window fonts */
	case IDM_WINDOW_FONT_0:
	case IDM_WINDOW_FONT_1:
	case IDM_WINDOW_FONT_2:
	case IDM_WINDOW_FONT_3:
	case IDM_WINDOW_FONT_4:
	case IDM_WINDOW_FONT_5:
	case IDM_WINDOW_FONT_6:
	case IDM_WINDOW_FONT_7:
		{
			i = wCmd - IDM_WINDOW_FONT_0;

			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			td = &data[i];

			term_change_font(td);

			break;
		}

		/* Bizarre Display */
	case IDM_WINDOW_BIZ_0:
	case IDM_WINDOW_BIZ_1:
	case IDM_WINDOW_BIZ_2:
	case IDM_WINDOW_BIZ_3:
	case IDM_WINDOW_BIZ_4:
	case IDM_WINDOW_BIZ_5:
	case IDM_WINDOW_BIZ_6:
	case IDM_WINDOW_BIZ_7:
		{
			i = wCmd - IDM_WINDOW_BIZ_0;

			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			td = &data[i];

			td->bizarre = !td->bizarre;

			term_getsize(td);

			term_window_resize(td);

			break;
		}

		/* Increase Tile Width */
	case IDM_WINDOW_I_WID_0:
	case IDM_WINDOW_I_WID_1:
	case IDM_WINDOW_I_WID_2:
	case IDM_WINDOW_I_WID_3:
	case IDM_WINDOW_I_WID_4:
	case IDM_WINDOW_I_WID_5:
	case IDM_WINDOW_I_WID_6:
	case IDM_WINDOW_I_WID_7:
		{
			i = wCmd - IDM_WINDOW_I_WID_0;

			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			td = &data[i];

			td->tile_wid += 1;

			term_getsize(td);

			term_window_resize(td);

			break;
		}

		/* Decrease Tile Height */
	case IDM_WINDOW_D_WID_0:
	case IDM_WINDOW_D_WID_1:
	case IDM_WINDOW_D_WID_2:
	case IDM_WINDOW_D_WID_3:
	case IDM_WINDOW_D_WID_4:
	case IDM_WINDOW_D_WID_5:
	case IDM_WINDOW_D_WID_6:
	case IDM_WINDOW_D_WID_7:
		{
			i = wCmd - IDM_WINDOW_D_WID_0;

			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			td = &data[i];

			td->tile_wid -= 1;

			term_getsize(td);

			term_window_resize(td);

			break;
		}

		/* Increase Tile Height */
	case IDM_WINDOW_I_HGT_0:
	case IDM_WINDOW_I_HGT_1:
	case IDM_WINDOW_I_HGT_2:
	case IDM_WINDOW_I_HGT_3:
	case IDM_WINDOW_I_HGT_4:
	case IDM_WINDOW_I_HGT_5:
	case IDM_WINDOW_I_HGT_6:
	case IDM_WINDOW_I_HGT_7:
		{
			i = wCmd - IDM_WINDOW_I_HGT_0;

			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			td = &data[i];

			td->tile_hgt += 1;

			term_getsize(td);

			term_window_resize(td);

			break;
		}

		/* Decrease Tile Height */
	case IDM_WINDOW_D_HGT_0:
	case IDM_WINDOW_D_HGT_1:
	case IDM_WINDOW_D_HGT_2:
	case IDM_WINDOW_D_HGT_3:
	case IDM_WINDOW_D_HGT_4:
	case IDM_WINDOW_D_HGT_5:
	case IDM_WINDOW_D_HGT_6:
	case IDM_WINDOW_D_HGT_7:
		{
			i = wCmd - IDM_WINDOW_D_HGT_0;

			if ((i < 0) || (i >= MAX_TERM_DATA)) break;

			td = &data[i];

			td->tile_hgt -= 1;

			term_getsize(td);

			term_window_resize(td);

			break;
		}

	case IDM_OPTIONS_OLD_GRAPHICS:
		{
			/* Paranoia */
			if (!inkey_flag)
			{
				plog("You may not do that right now.");
				break;
			}

			/* Set "arg_graphics" */
			arg_graphics = 1;

			/* React to changes */
			Term_xtra_win_react();

			/* Hack -- Force redraw */
			Term_key_push(KTRL('R'));

			break;
		}

	case IDM_OPTIONS_NEW_GRAPHICS:
		{
			/* Paranoia */
			if (!inkey_flag)
			{
				plog("You may not do that right now.");
				break;
			}

			/* Set "arg_graphics" */
			arg_graphics = 2;

			/* React to changes */
			Term_xtra_win_react();

			/* Hack -- Force redraw */
			Term_key_push(KTRL('R'));

			break;
		}
	case IDM_OPTIONS_ASCII_GRAPHICS:
		{
			/* Paranoia */
			if (!inkey_flag)
			{
				plog("You may not do that right now.");
				break;
			}

			/* Set "ASCII Graphics" */
			arg_graphics = 0;
			/* React to Changes */
			Term_xtra_win_react();

			/* Hack -- Force redraw */
			Term_key_push(KTRL('R'));

			break;
		}

	case IDM_OPTIONS_BIGTILE:
		{
			term_data *td = &data[0];

			/* Paranoia */
			if (!inkey_flag)
			{
				plog("You may not do that right now.");
				break;
			}

			/* Toggle "arg_sound" */
			arg_bigtile = !arg_bigtile;

			/* Activate */
			Term_activate(&td->t);

			/* Resize the term */
			Term_resize(td->cols, td->rows);

			/* Redraw later */
			InvalidateRect(td->w, NULL, TRUE);

			break;
		}

	case IDM_OPTIONS_SOUND:
		{
			/* Paranoia */
			if (!inkey_flag)
			{
				plog("You may not do that right now.");
				break;
			}

			/* Toggle "arg_sound" */
			arg_sound = !arg_sound;

			/* React to changes */
			Term_xtra_win_react();

			/* Hack -- Force redraw */
			Term_key_push(KTRL('R'));

			break;
		}

	case IDM_OPTIONS_UNUSED:
		{
			/* Unused for now XXX XXX XXX */

			break;
		}

#ifdef USE_SAVER

	case IDM_OPTIONS_SAVER:
		{
			if (hwndSaver)
			{
				DestroyWindow(hwndSaver);
				hwndSaver = NULL;
			}
			else
			{
				/* Create a screen scaver window */
				hwndSaver = CreateWindowEx(WS_EX_TOPMOST, "WindowsScreenSaverClass",
				                           "Angband Screensaver",
				                           WS_POPUP | WS_MAXIMIZE | WS_VISIBLE,
				                           0, 0, GetSystemMetrics(SM_CXSCREEN),
				                           GetSystemMetrics(SM_CYSCREEN),
				                           NULL, NULL, hInstance, NULL);

				if (hwndSaver)
				{
					/* Push the window to the bottom XXX XXX XXX */
					SetWindowPos(hwndSaver, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
				}
				else
				{
					plog("Failed to create saver window");
				}
			}
			break;
		}

#endif

	case IDM_HELP_GENERAL:
		{
			char buf[1024];
			char tmp[1024];
			path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "angband.hlp");
			if (check_file(tmp))
			{
				sprintf(buf, "winhelp.exe %s", tmp);
				WinExec(buf, SW_NORMAL);
			}
			else
			{
				plog_fmt("Cannot find help file: %s", tmp);
				plog("Use the online help files instead.");
			}
			break;
		}

	case IDM_HELP_SPOILERS:
		{
			char buf[1024];
			char tmp[1024];
			path_build(tmp, 1024, ANGBAND_DIR_XTRA_HELP, "spoilers.hlp");
			if (check_file(tmp))
			{
				sprintf(buf, "winhelp.exe %s", tmp);
				WinExec(buf, SW_NORMAL);
			}
			else
			{
				plog_fmt("Cannot find help file: %s", tmp);
				plog("Use the online help files instead.");
			}
			break;
		}
	}
}



#ifdef __MWERKS__
LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
                                  WPARAM wParam, LPARAM lParam);
LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
                                  WPARAM wParam, LPARAM lParam)
#else /* __MWERKS__ */
LRESULT FAR PASCAL AngbandWndProc(HWND hWnd, UINT uMsg,
                                  WPARAM wParam, LPARAM lParam)
#endif /* __MWERKS__ */
{
	PAINTSTRUCT ps;
	HDC hdc;
	term_data *td;
	MINMAXINFO FAR *lpmmi;
	RECT rc;
	int i;


	/* Acquire proper "term_data" info */
	td = (term_data *)GetWindowLong(hWnd, 0);

	/* Handle message */
	switch (uMsg)
	{
		/* XXX XXX XXX */
	case WM_NCCREATE:
		{
			SetWindowLong(hWnd, 0, (LONG)(my_td));
			break;
		}

		/* XXX XXX XXX */
	case WM_CREATE:
		{
			return 0;
		}

	case WM_GETMINMAXINFO:
		{
			lpmmi = (MINMAXINFO FAR *)lParam;

			/* this message was sent before WM_NCCREATE */
			if (!td) return 1;

			/* Minimum window size is 8x2 */
			rc.left = rc.top = 0;
			rc.right = rc.left + 8 * td->tile_wid + td->size_ow1 + td->size_ow2;
			rc.bottom = rc.top + 2 * td->tile_hgt + td->size_oh1 + td->size_oh2 + 1;

			/* Adjust */
			AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);

			/* Save minimum size */
			lpmmi->ptMinTrackSize.x = rc.right - rc.left;
			lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;

			/* Maximum window size */
			rc.left = rc.top = 0;
			rc.right = rc.left + 255 * td->tile_wid + td->size_ow1 + td->size_ow2;
			rc.bottom = rc.top + 255 * td->tile_hgt + td->size_oh1 + td->size_oh2;

			/* Paranoia */
			rc.right += (td->tile_wid - 1);
			rc.bottom += (td->tile_hgt - 1);

			/* Adjust */
			AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);

			/* Save maximum size */
			lpmmi->ptMaxSize.x = rc.right - rc.left;
			lpmmi->ptMaxSize.y = rc.bottom - rc.top;

			/* Save maximum size */
			lpmmi->ptMaxTrackSize.x = rc.right - rc.left;
			lpmmi->ptMaxTrackSize.y = rc.bottom - rc.top;

			return 0;
		}

	case WM_PAINT:
		{
			BeginPaint(hWnd, &ps);
			if (td) term_data_redraw(td);
			EndPaint(hWnd, &ps);
			ValidateRect(hWnd, NULL);
			return 0;
		}

	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
		{
			/* Unused */
			/* BYTE KeyState = 0x00; */

			bool mc = FALSE;
			bool ms = FALSE;
			bool ma = FALSE;

			/* Extract the modifiers */
			if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
			if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE;
			if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE;

			/* Handle "special" keys */
			if (special_key[(byte)(wParam)] || (ma && !ignore_key[(byte)(wParam)]) )
			{
				/* Begin the macro trigger */
				Term_keypress(31);

				/* Send the modifiers */
				if (mc) Term_keypress('C');
				if (ms) Term_keypress('S');
				if (ma) Term_keypress('A');

				/* Extract "scan code" */
				i = LOBYTE(HIWORD(lParam));

				/* Introduce the scan code */
				Term_keypress('x');

				/* Encode the hexidecimal scan code */
				Term_keypress(hexsym[i / 16]);
				Term_keypress(hexsym[i % 16]);

				/* End the macro trigger */
				Term_keypress(13);

				return 0;
			}

			break;
		}

	case WM_CHAR:
		{
			Term_keypress(wParam);
			return 0;
		}

	case WM_INITMENU:
		{
			setup_menus();
			return 0;
		}

	case WM_CLOSE:
		{
			if (game_in_progress && character_generated)
			{
				/* Hack -- Forget messages */
				msg_flag = FALSE;

				/* Save the game */
				do_cmd_save_game();
			}
			quit(NULL);
			return 0;
		}

	case WM_QUIT:
		{
			quit(NULL);
			return 0;
		}

	case WM_COMMAND:
		{
			process_menus(LOWORD(wParam));
			return 0;
		}

	case WM_SIZE:
		{
			/* this message was sent before WM_NCCREATE */
			if (!td) return 1;

			/* it was sent from inside CreateWindowEx */
			if (!td->w) return 1;

			/* was sent from WM_SIZE */
			if (td->size_hack) return 1;

			switch (wParam)
			{
			case SIZE_MINIMIZED:
				{
					/* Hide sub-windows */
					for (i = 1; i < MAX_TERM_DATA; i++)
					{
						if (data[i].visible) ShowWindow(data[i].w, SW_HIDE);
					}
					return 0;
				}

			case SIZE_MAXIMIZED:
				{
					/* fall through XXX XXX XXX */
				}

			case SIZE_RESTORED:
				{
					uint cols = (LOWORD(lParam) - td->size_ow1 - td->size_ow2) / td->tile_wid;
					uint rows = (HIWORD(lParam) - td->size_oh1 - td->size_oh2) / td->tile_hgt;

					/* New size */
					if ((td->cols != cols) || (td->rows != rows))
					{
						/* save the new size */
						td->cols = cols;
						td->rows = rows;

						/* Activate */
						Term_activate(&td->t);

						/* Resize the term */
						Term_resize(td->cols, td->rows);

						/* Redraw later */
						InvalidateRect(td->w, NULL, TRUE);
					}

					td->size_hack = TRUE;

					/* Restore sub-windows */
					for (i = 1; i < MAX_TERM_DATA; i++)
					{
						if (data[i].visible) ShowWindow(data[i].w, SW_SHOWNOACTIVATE);
					}

					td->size_hack = FALSE;

					return 0;
				}
			}
			break;
		}

	case WM_PALETTECHANGED:
		{
			/* Ignore if palette change caused by itself */
			if ((HWND)wParam == hWnd) return 0;

			/* Fall through... */
		}

	case WM_QUERYNEWPALETTE:
		{
			if (!paletted) return 0;

			hdc = GetDC(hWnd);

			SelectPalette(hdc, hPal, FALSE);

			i = RealizePalette(hdc);

			/* if any palette entries changed, repaint the window. */
			if (i) InvalidateRect(hWnd, NULL, TRUE);

			ReleaseDC(hWnd, hdc);

			return 0;
		}

	case WM_ACTIVATE:
		{
			if (wParam && !HIWORD(lParam))
			{
				/* Do something to sub-windows */
				for (i = 1; i < MAX_TERM_DATA; i++)
				{
					SetWindowPos(data[i].w, hWnd, 0, 0, 0, 0,
					             SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
				}

				/* Focus on main window */
				SetFocus(hWnd);

				return 0;
			}

			break;
		}
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


#ifdef __MWERKS__
LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
                                   WPARAM wParam, LPARAM lParam);
LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
                                   WPARAM wParam, LPARAM lParam)
#else /* __MWERKS__ */
LRESULT FAR PASCAL AngbandListProc(HWND hWnd, UINT uMsg,
                                   WPARAM wParam, LPARAM lParam)
#endif /* __MWERKS__ */
{
	term_data *td;
	MINMAXINFO FAR *lpmmi;
	RECT rc;
	PAINTSTRUCT ps;
	HDC hdc;
	int i;


	/* Acquire proper "term_data" info */
	td = (term_data *)GetWindowLong(hWnd, 0);

	/* Process message */
	switch (uMsg)
	{
		/* XXX XXX XXX */
	case WM_NCCREATE:
		{
			SetWindowLong(hWnd, 0, (LONG)(my_td));
			break;
		}

		/* XXX XXX XXX */
	case WM_CREATE:
		{
			return 0;
		}

	case WM_GETMINMAXINFO:
		{
			/* this message was sent before WM_NCCREATE */
			if (!td) return 1;

			lpmmi = (MINMAXINFO FAR *)lParam;

			/* Minimum size */
			rc.left = rc.top = 0;
			rc.right = rc.left + 8 * td->tile_wid + td->size_ow1 + td->size_ow2;
			rc.bottom = rc.top + 2 * td->tile_hgt + td->size_oh1 + td->size_oh2;

			/* Adjust */
			AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);

			/* Save the minimum size */
			lpmmi->ptMinTrackSize.x = rc.right - rc.left;
			lpmmi->ptMinTrackSize.y = rc.bottom - rc.top;

			/* Maximum window size */
			rc.left = rc.top = 0;
			rc.right = rc.left + 80 * td->tile_wid + td->size_ow1 + td->size_ow2;
			rc.bottom = rc.top + 24 * td->tile_hgt + td->size_oh1 + td->size_oh2;

			/* Paranoia */
			rc.right += (td->tile_wid - 1);
			rc.bottom += (td->tile_hgt - 1);

			/* Adjust */
			AdjustWindowRectEx(&rc, td->dwStyle, TRUE, td->dwExStyle);

			/* Save maximum size */
			lpmmi->ptMaxSize.x = rc.right - rc.left;
			lpmmi->ptMaxSize.y = rc.bottom - rc.top;

			/* Save the maximum size */
			lpmmi->ptMaxTrackSize.x = rc.right - rc.left;
			lpmmi->ptMaxTrackSize.y = rc.bottom - rc.top;

			return 0;
		}

	case WM_SIZE:
		{
			/* this message was sent before WM_NCCREATE */
			if (!td) return 1;

			/* it was sent from inside CreateWindowEx */
			if (!td->w) return 1;

			/* was sent from inside WM_SIZE */
			if (td->size_hack) return 1;

			td->size_hack = TRUE;

			td->cols = (LOWORD(lParam) - td->size_ow1 - td->size_ow2) / td->tile_wid;
			td->rows = (HIWORD(lParam) - td->size_oh1 - td->size_oh2) / td->tile_hgt;

			term_getsize(td);

			MoveWindow(hWnd, td->pos_x, td->pos_y, td->size_wid, td->size_hgt, TRUE);

			td->size_hack = FALSE;

			return 0;
		}

	case WM_PAINT:
		{
			BeginPaint(hWnd, &ps);
			if (td) term_data_redraw(td);
			EndPaint(hWnd, &ps);
			return 0;
		}

	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
		{
			/* Unused */
			/* BYTE KeyState = 0x00; */

			bool mc = FALSE;
			bool ms = FALSE;
			bool ma = FALSE;

			/* Extract the modifiers */
			if (GetKeyState(VK_CONTROL) & 0x8000) mc = TRUE;
			if (GetKeyState(VK_SHIFT) & 0x8000) ms = TRUE;
			if (GetKeyState(VK_MENU) & 0x8000) ma = TRUE;

			/* Handle "special" keys */
			if (special_key[(byte)(wParam)] || (ma && !ignore_key[(byte)(wParam)]) )
			{
				/* Begin the macro trigger */
				Term_keypress(31);

				/* Send the modifiers */
				if (mc) Term_keypress('C');
				if (ms) Term_keypress('S');
				if (ma) Term_keypress('A');

				/* Extract "scan code" */
				i = LOBYTE(HIWORD(lParam));

				/* Introduce the scan code */
				Term_keypress('x');

				/* Encode the hexidecimal scan code */
				Term_keypress(hexsym[i / 16]);
				Term_keypress(hexsym[i % 16]);

				/* End the macro trigger */
				Term_keypress(13);

				return 0;
			}

			break;
		}

	case WM_CHAR:
		{
			Term_keypress(wParam);
			return 0;
		}

	case WM_PALETTECHANGED:
		{
			/* ignore if palette change caused by itself */
			if ((HWND)wParam == hWnd) return FALSE;
			/* otherwise, fall through!!! */
		}

	case WM_QUERYNEWPALETTE:
		{
			if (!paletted) return 0;
			hdc = GetDC(hWnd);
			SelectPalette(hdc, hPal, FALSE);
			i = RealizePalette(hdc);
			/* if any palette entries changed, repaint the window. */
			if (i) InvalidateRect(hWnd, NULL, TRUE);
			ReleaseDC(hWnd, hdc);
			return 0;
		}

	case WM_NCLBUTTONDOWN:
		{

#ifdef HTCLOSE
			if (wParam == HTCLOSE) wParam = HTSYSMENU;
#endif /* HTCLOSE */

			if (wParam == HTSYSMENU)
			{
				if (td->visible)
				{
					td->visible = FALSE;
					ShowWindow(td->w, SW_HIDE);
				}

				return 0;
			}

			break;
		}
	}

	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


#ifdef USE_SAVER

#define MOUSE_SENS 40

#ifdef __MWERKS__
LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
                                    WPARAM wParam, LPARAM lParam);
LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
                                    WPARAM wParam, LPARAM lParam)
#else /* __MWERKS__ */
LRESULT FAR PASCAL AngbandSaverProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
#endif /* __MWERKS__ */
{
	static int iMouse = 0;
	static WORD xMouse = 0;
	static WORD yMouse = 0;

	int dx, dy;


	/* Process */
	switch (uMsg)
	{
		/* XXX XXX XXX */
	case WM_NCCREATE:
		{
			break;
		}

	case WM_SETCURSOR:
		{
			SetCursor(NULL);
			return 0;
		}

#if 0
	case WM_ACTIVATE:
		{
			if (LOWORD(wParam) == WA_INACTIVE) break;

			/* else fall through */
		}
#endif

	case WM_LBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_RBUTTONDOWN:
	case WM_KEYDOWN:
		{
			SendMessage(hWnd, WM_CLOSE, 0, 0);
			return 0;
		}

	case WM_MOUSEMOVE:
		{
			if (iMouse)
			{
				dx = LOWORD(lParam) - xMouse;
				dy = HIWORD(lParam) - yMouse;

				if (dx < 0) dx = -dx;
				if (dy < 0) dy = -dy;

				if ((dx > MOUSE_SENS) || (dy > MOUSE_SENS))
				{
					SendMessage(hWnd, WM_CLOSE, 0, 0);
				}
			}

			/* Save last location */
			iMouse = 1;
			xMouse = LOWORD(lParam);
			yMouse = HIWORD(lParam);

			return 0;
		}

	case WM_CLOSE:
		{
			DestroyWindow(hwndSaver);
			hwndSaver = NULL;
			return 0;
		}
	}

	/* Oops */
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

#endif /* USE_SAVER */





/*** Temporary Hooks ***/


/*
 * Display warning message (see "z-util.c")
 */
static void hack_plog(cptr str)
{
	/* Give a warning */
	if (str)
	{
		MessageBox(NULL, str, "Warning",
		           MB_ICONEXCLAMATION | MB_OK);
	}
}


/*
 * Display error message and quit (see "z-util.c")
 */
static void hack_quit(cptr str)
{
	/* Give a warning */
	if (str)
	{
		MessageBox(NULL, str, "Error",
		           MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
	}

	/* Unregister the classes */
	UnregisterClass(AppName, hInstance);

	/* Destroy the icon */
	if (hIcon) DestroyIcon(hIcon);

	/* Exit */
	exit(0);
}



/*** Various hooks ***/


/*
 * Display warning message (see "z-util.c")
 */
static void hook_plog(cptr str)
{
	/* Warning */
	if (str)
	{
		MessageBox(data[0].w, str, "Warning",
		           MB_ICONEXCLAMATION | MB_OK);
	}
}


/*
 * Display error message and quit (see "z-util.c")
 */
static void hook_quit(cptr str)
{
	int i;


	/* Give a warning */
	if (str)
	{
		MessageBox(data[0].w, str, "Error",
		           MB_ICONEXCLAMATION | MB_OK | MB_ICONSTOP);
	}


	/* Save the preferences */
	save_prefs();


	/*** Could use 'Term_nuke_win()' XXX XXX XXX */

	/* Destroy all windows */
	for (i = MAX_TERM_DATA - 1; i >= 0; --i)
	{
		term_force_font(&data[i], NULL);
		if (data[i].font_want) string_free(data[i].font_want);
		if (data[i].w) DestroyWindow(data[i].w);
		data[i].w = 0;
	}


	/*** Free some other stuff ***/

	DeleteObject(hbrYellow);

	if (hPal) DeleteObject(hPal);

	UnregisterClass(AppName, hInstance);

	if (hIcon) DestroyIcon(hIcon);

	exit(0);
}

/*** Initialize ***/


/*
 * Init some stuff
 */
static void init_stuff(void)
{
	int i;

	char path[1024];


	/* Get program name with full path */
	GetModuleFileName(hInstance, path, 512);

	/* Get the name of the "*.ini" file */
	strcpy(path + strlen(path) - 4, ".INI");

	/* Save the the name of the ini-file */
	ini_file = string_make(path);

	/* Validate the ini-file */
	validate_file(ini_file);

	/* Analyze the path */
	i = strlen(path);

	/* Get the path */
	for (; i > 0; i--)
	{
		if (path[i] == '\\')
		{
			/* End of path */
			break;
		}
	}

	/* Add "lib" to the path */
	strcpy(path + i + 1, "lib\\");

	/* Validate the path */
	validate_dir(path);

	/*** Initialise the file paths ***/

	/* Start with standard ones */
	init_file_paths(path);

	/* Build the "font" path */
	path_build(path, 1024, ANGBAND_DIR_XTRA, "font");

	/* Allocate the path */
	ANGBAND_DIR_XTRA_FONT = string_make(path);


	/*** Validate the paths to ensure we have a working install ***/

	validate_dir(ANGBAND_DIR_APEX);
	validate_dir(ANGBAND_DIR_BONE);
	validate_dir(ANGBAND_DIR_DATA);
	validate_dir(ANGBAND_DIR_EDIT);
	validate_dir(ANGBAND_DIR_FILE);
	validate_dir(ANGBAND_DIR_HELP);
	validate_dir(ANGBAND_DIR_INFO);
	validate_dir(ANGBAND_DIR_NOTE);
	validate_dir(ANGBAND_DIR_SAVE);
	validate_dir(ANGBAND_DIR_PREF);
	validate_dir(ANGBAND_DIR_USER);
	validate_dir(ANGBAND_DIR_XTRA);
	validate_dir(ANGBAND_DIR_CMOV);
	validate_dir(ANGBAND_DIR_XTRA_FONT);

	/* Build the filename */
	path_build(path, 1024, ANGBAND_DIR_XTRA_FONT, "8X13.FON");

	/* Hack -- Validate the basic font */
	validate_file(path);


#ifdef USE_GRAPHICS

	/* Build the "graf" path */
	path_build(path, 1024, ANGBAND_DIR_XTRA, "graf");

	/* Allocate the path */
	ANGBAND_DIR_XTRA_GRAF = string_make(path);

	/* Validate the "graf" directory */
	validate_dir(ANGBAND_DIR_XTRA_GRAF);

	/* Build the filename */
	path_build(path, 1024, ANGBAND_DIR_XTRA_GRAF, "8X8.BMP");

	/* Hack -- Validate the basic graf */
	validate_file(path);

#endif


#ifdef USE_SOUND

	/* Build the "sound" path */
	path_build(path, 1024, ANGBAND_DIR_XTRA, "sound");

	/* Allocate the path */
	ANGBAND_DIR_XTRA_SOUND = string_make(path);

	/* Validate the "sound" directory */
	validate_dir(ANGBAND_DIR_XTRA_SOUND);

#endif


	/* Build the "help" path */
	path_build(path, 1024, ANGBAND_DIR_XTRA, "help");

	/* Allocate the path */
	ANGBAND_DIR_XTRA_HELP = string_make(path);

	/* Validate the "help" directory */
	/* validate_dir(ANGBAND_DIR_XTRA_HELP); */
}

int FAR PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
                       LPSTR lpCmdLine, int nCmdShow)
{
	int i;

	WNDCLASS wc;
	HDC hdc;
	MSG msg;

	/* Save globally */
	hInstance = hInst;

	/* Initialize */
	if (hPrevInst == NULL)
	{
		wc.style = CS_CLASSDC;
		wc.lpfnWndProc = AngbandWndProc;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 4;  /* one long pointer to term_data */
		wc.hInstance = hInst;
		wc.hIcon = hIcon = LoadIcon(hInst, AppName);
		wc.hCursor = LoadCursor(NULL, IDC_ARROW);
		wc.hbrBackground = GetStockObject(BLACK_BRUSH);
		wc.lpszMenuName = AppName;
		wc.lpszClassName = AppName;

		if (!RegisterClass(&wc)) exit(1);

		wc.lpfnWndProc = AngbandListProc;
		wc.lpszMenuName = NULL;
		wc.lpszClassName = AngList;

		if (!RegisterClass(&wc)) exit(2);

#ifdef USE_SAVER

		wc.style = CS_VREDRAW | CS_HREDRAW | CS_SAVEBITS | CS_DBLCLKS;
		wc.lpfnWndProc = AngbandSaverProc;
		wc.hCursor = NULL;
		wc.lpszMenuName = NULL;
		wc.lpszClassName = "WindowsScreenSaverClass";

		if (!RegisterClass(&wc)) exit(3);

#endif

	}

	/* Temporary hooks */
	plog_aux = hack_plog;
	quit_aux = hack_quit;
	core_aux = hack_quit;

	/* Prepare the filepaths */
	init_stuff();

	/* Initialize the keypress analyzer */
	for (i = 0; special_key_list[i]; ++i)
	{
		special_key[special_key_list[i]] = TRUE;
	}

	/* Determine if display is 16/256/true color */
	hdc = GetDC(NULL);
	colors16 = (GetDeviceCaps(hdc, BITSPIXEL) == 4);
	paletted = ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) ? TRUE : FALSE);
	ReleaseDC(NULL, hdc);

	/* Initialize the colors */
	for (i = 0; i < 256; i++)
	{
		byte rv, gv, bv;

		/* Extract desired values */
		rv = angband_color_table[i][1];
		gv = angband_color_table[i][2];
		bv = angband_color_table[i][3];

		/* Extract the "complex" code */
		win_clr[i] = PALETTERGB(rv, gv, bv);

		/* Save the "simple" code */
		angband_color_table[i][0] = win_pal[i];
	}

	/* Prepare the windows */
	init_windows();

	/* Activate hooks */
	plog_aux = hook_plog;
	quit_aux = hook_quit;
	core_aux = hook_quit;

	/* Set the system suffix */
	ANGBAND_SYS = "win";


	/* Set the keyboard suffix */
	if (7 != GetKeyboardType(0))
		ANGBAND_KEYBOARD = "0";
	else
	{
		/* Japanese keyboard */
		switch (GetKeyboardType(1))
		{
		case 0x0D01:
		case 0x0D02:
		case 0x0D03:
		case 0x0D04:
		case 0x0D05:
		case 0x0D06:
			/* NEC PC-98x1 */
			ANGBAND_KEYBOARD = "NEC98";
			break;
		default:
			/* PC/AT */
			ANGBAND_KEYBOARD = "JAPAN";
		}
	}

	/* Initialize */
	init_angband();

	/* Prompt the user */
	prt("", 23, 0);
	prt("[Press any key to proceed]", 23, 27);
	Term_fresh();

	inkey();

	/* We are now initialized */
	initialized = TRUE;

	/* Did the user double click on a save file? */
	check_for_save_file(lpCmdLine);

	game_in_progress = TRUE;
	play_game(FALSE);

	/* Prompt the user */
	Term_fresh();

	/* Process messages forever */
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	/* Initialize the keypress analyzer */
	for (i = 0; ignore_key_list[i]; ++i)
	{
		ignore_key[ignore_key_list[i]] = TRUE;
	}

	/* Paranoia */
	quit(NULL);

	/* Paranoia */
	return (0);
}


#endif /* WINDOWS */


tome-235-src/src/main-xaw.c0000644000076400017500000013036511012107763013352 0ustar  dgdg/* File: main-xaw.c */

/*
 * Copyright (c) 1997 Ben Harrison, Torbjorn Lindgren, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband work with UNIX/X11 computers.
 *
 * To use this file, compile with "USE_XAW" defined, and link against all
 * the various "X11" libraries which may be needed.
 *
 * See also "main-x11.c".
 *
 * The Angband widget is not as self-contained as it really should be.
 * Originally everything was output to a Pixmap which was later copied
 * to the screen when necessary.  The idea was abandoned since Pixmaps
 * create big performance problems for some really old X terminals (such
 * as 3/50's running Xkernel).
 *
 * Initial framework (and some code) by Ben Harrison (benh@phial.com).
 *
 * Most of this file is by Torbjorn Lindgren (tl@cd.chalmers.se).
 *
 * Major modifications by Ben Harrison (benh@phial.com).
 */


#include "angband.h"


#ifdef USE_XAW


#ifndef __MAKEDEPEND__
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#endif /* __MAKEDEPEND__ */

#include 
#include 
#include 
#include 

/* /me pffts Solaris */
#ifndef NAME_MAX
#define	NAME_MAX	_POSIX_NAME_MAX
#endif


/*
 * Include some helpful X11 code.
 */
#include "maid-x11.c"



/**** Resources ****/


/*

Name                Class              RepType         Default Value
----                -----              -------         -------------
background          Background         Pixel           XtDefaultBackground
border              BorderColor        Pixel           XtDefaultForeground
borderWidth         BorderWidth        Dimension       1
cursor              Cursor             Cursor          None
cursorName          Cursor             String          NULL
destroyCallback     Callback           Pointer         NULL
height              Height             Dimension       0
insensitiveBorder   Insensitive        Pixmap          Gray
mappedWhenManaged   MappedWhenManaged  Boolean         True
pointerColor        Foreground         Pixel           XtDefaultForeground
pointerColorBackground Background      Pixel           XtDefaultBackground
sensitive           Sensitive          Boolean         True
width               Width              Dimension       0
x                   Position           Position        0
y                   Position           Position        0


The colors can be changed using the standard Angband user pref files,
which can also be used to provide black text on a white background,
by setting color zero to "#FFFFFF" and color one to "#000000", since
the other colors are unused.

*/


/*
 * New resource names
 */
#define XtNstartRows        "startRows"
#define XtNstartColumns     "startColumns"
#define XtNminRows          "minRows"
#define XtNminColumns       "minColumns"
#define XtNmaxRows          "maxRows"
#define XtNmaxColumns       "maxColumns"
#define XtNinternalBorder   "internalBorder"
#define XtNredrawCallback   "redrawCallback"

/*
 * Total normal colors
 */
#define NUM_COLORS 256

/*
 * Special "XOR" color
 */
#define COLOR_XOR 256



/**** The Widget Code ****/


/*
 * Forward declarations
 */
typedef struct AngbandPart AngbandPart;
typedef struct AngbandRec *AngbandWidget;
typedef struct AngbandRec AngbandRec;
typedef struct AngbandClassRec *AngbandWidgetClass;
typedef struct AngbandClassPart AngbandClassPart;
typedef struct AngbandClassRec AngbandClassRec;

typedef struct term_data term_data;


/*
 * A structure for each "term"
 */
struct term_data
{
	term t;

	AngbandWidget widget;
};


/*
 * Maximum number of windows
 */
#define MAX_TERM_DATA 8


/*
 * An array of term_data's
 */
static term_data data[MAX_TERM_DATA];


/*
 * Current number of windows open
 */
static int num_term = MAX_TERM_DATA;


/*
 * New fields for the Angband widget record
 */
struct AngbandPart
{
	/* Settable resources */
	int start_rows;
	int start_columns;
	int min_rows;
	int min_columns;
	int max_rows;
	int max_columns;
	int internal_border;
	String font;

	XtCallbackList redraw_callbacks;

#ifdef USE_GRAPHICS

	/* Tiles */
	XImage *tiles;

#ifdef USE_TRANSPARENCY

	/* Tempory storage for overlaying tiles. */
	XImage *TmpImage;

#endif

#endif /* USE_GRAPHICS */

	/* Private state */
	XFontStruct *fnt;
	Dimension fontheight;
	Dimension fontwidth;
	Dimension fontascent;

	/* Color info for GC's */
	byte color[NUM_COLORS][4];

	/* GC's (including "xor") */
	GC gc[NUM_COLORS + 1];
};


/*
 * Full instance record declaration
 */
struct AngbandRec
{
	CorePart core;
	SimplePart simple;
	AngbandPart angband;
};


/*
 * New fields for the Angband widget class record
 */
struct AngbandClassPart
{
	int dummy;
};


/*
 * Full class record declaration
 */
struct AngbandClassRec
{
	CoreClassPart core_class;
	SimpleClassPart simple_class;
	AngbandClassPart angband_class;
};



/*
 * Hack -- see below
 */
#define offset(field) XtOffsetOf(AngbandRec, angband.field)


/*
 * Fallback resources for Angband widget
 */
static XtResource resources[] =
{
	{ XtNstartRows, XtCValue, XtRInt, sizeof(int),
	  offset(start_rows), XtRImmediate, (XtPointer) 24 },
	{ XtNstartColumns, XtCValue, XtRInt, sizeof(int),
	  offset(start_columns), XtRImmediate, (XtPointer) 80 },
	{ XtNminRows, XtCValue, XtRInt, sizeof(int),
	  offset(min_rows), XtRImmediate, (XtPointer) 1 },
	{ XtNminColumns, XtCValue, XtRInt, sizeof(int),
	  offset(min_columns), XtRImmediate, (XtPointer) 1 },
	{ XtNmaxRows, XtCValue, XtRInt, sizeof(int),
	  offset(max_rows), XtRImmediate, (XtPointer) 255 },
	{ XtNmaxColumns, XtCValue, XtRInt, sizeof(int),
	  offset(max_columns), XtRImmediate, (XtPointer) 255 },
	{ XtNinternalBorder, XtCValue, XtRInt, sizeof(int),
	  offset(internal_border), XtRImmediate, (XtPointer) 2 },
	{ XtNfont, XtCFont, XtRString, sizeof(char *),
	  offset(font), XtRString, DEFAULT_X11_FONT },
	{ XtNredrawCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
	  offset(redraw_callbacks), XtRCallback, (XtPointer)NULL }
};


/*
 * Hack -- see above
 */
#undef offset


/*
 * Forward declarations for Widget functions
 */
static void Initialize(AngbandWidget request, AngbandWidget wnew);
static void Redisplay(AngbandWidget w, XEvent *event, Region region);
static Boolean SetValues(AngbandWidget current, AngbandWidget request,
                         AngbandWidget wnew, ArgList args, Cardinal *num_args);
static void Destroy(AngbandWidget widget);
static void Resize_term(AngbandWidget wnew);

/*
 * Forward declaration for internal functions
 */
static void calculateSizeHints(AngbandWidget wnew);
static XFontStruct *getFont(AngbandWidget widget,
                            String font, Boolean fallback);


/*
 * Hack -- see below
 */
#define superclass (&simpleClassRec)


/*
 * Class record constanst
 */
AngbandClassRec angbandClassRec =
{
	{
		/* Core class fields initialization */
		/* superclass           */      (WidgetClass) superclass,
		/* class_name           */      "Angband",
		/* widget_size          */      sizeof(AngbandRec),
		/* class_initialize     */      NULL,
		/* class_part_initialize*/      NULL,
		/* class_inited         */      FALSE,
		/* initialize           */      (XtInitProc) Initialize,
		/* initialize_hook      */      NULL,
		/* realize              */      XtInheritRealize,
		/* actions              */      NULL,
		/* num_actions          */      0,
		/* resources            */      resources,
		/* num_resources        */      XtNumber(resources),
		/* xrm_class            */      NULLQUARK,
		/* compress_motion      */      TRUE,
		/* compress_exposure    */      XtExposeCompressMultiple,
		/* compress_enterleave  */      TRUE,
		/* visible_interest     */      FALSE,
		/* destroy              */      (XtWidgetProc) Destroy,
		/* resize               */      (XtWidgetProc) Resize_term,
		/* expose               */      (XtExposeProc) Redisplay,
		/* set_values           */      (XtSetValuesFunc) SetValues,
		/* set_values_hook      */      NULL,
		/* set_values_almost    */      XtInheritSetValuesAlmost,
		/* get_values_hook      */      NULL,
		/* accept_focus         */      NULL,
		/* version              */      XtVersion,
		/* callback_private     */      NULL,
		/* tm_table             */      NULL,
		/* query_geometry       */      NULL,
		/* display_accelerator  */      XtInheritDisplayAccelerator,
		/* extension            */      NULL
	},
	/* Simple class fields initialization */
	{
		/* change_sensitive     */      XtInheritChangeSensitive
#ifndef OLDXAW
										, NULL
#endif
	},
	/* Angband class fields initialization */
	{
		/* nothing              */      0
	}
};

/*
 * Hack -- see above
 */
#undef superclass


/*
 * Class record pointer
 */
WidgetClass angbandWidgetClass = (WidgetClass) &angbandClassRec;


/*
 * Public procedures
 */

/*
 * Simple routine to save the state of the game when the display connection
 * is broken. Remember, you cannot do anything in this function that will
 * generate X protocol requests.
 */
static int x_io_error_handler(Display *d)
{
	/* We have nothing to save */
	if (!character_generated) return 0;

	save_dungeon();
	save_player();

	return 0;
}


/*
 * Clear an area
 */
static void AngbandClearArea(AngbandWidget widget,
                             int x, int y, int w, int h, int a)
{
	/* Figure out which area to clear */
	y = y * widget->angband.fontheight + widget->angband.internal_border;
	x = x * widget->angband.fontwidth + widget->angband.internal_border;

	/* Clear the area */
	XFillRectangle(XtDisplay(widget), XtWindow(widget),
	               widget->angband.gc[a],
	               x, y,
	               widget->angband.fontwidth * w,
	               widget->angband.fontheight * h);
}



/*
 * Output some text
 */
static void AngbandOutputText(AngbandWidget widget, int x, int y,
                              String txt, int len, int a)
{
	/* Do nothing if the string is null */
	if (!txt || !*txt) return;

	/* Check the length, and fix it if it's below zero */
	if (len < 0) len = strlen(txt);

	/* Figure out where to place the text */
	y = (y * widget->angband.fontheight + widget->angband.fontascent +
	     widget->angband.internal_border);
	x = (x * widget->angband.fontwidth + widget->angband.internal_border);

	/* Place the string */
	XDrawImageString(XtDisplay(widget), XtWindow(widget),
	                 widget->angband.gc[a], x, y, txt, len);
}


#ifdef USE_GRAPHICS

/*
 * Draw some graphical characters.
 */
# ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static void AngbandOutputPict(AngbandWidget widget, int x, int y, int n,
                              const byte *ap, const char *cp, const byte *tap, const char *tcp,
                              const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static void AngbandOutputPict(AngbandWidget widget, int x, int y, int n,
                              const byte *ap, const char *cp, const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
# else /* USE_TRANSPARENCY */
static void AngbandOutputPict(AngbandWidget widget, int x, int y, int n,
                              const byte *ap, const char *cp)
# endif  /* USE_TRANSPARENCY */


{
	int i, x1, y1;

	byte a;
	char c;

#ifdef USE_TRANSPARENCY
	byte ta;
	char tc;

	int x2, y2;

# ifdef USE_EGO_GRAPHICS
	byte ea;
	char ec;

	int x3, y3;
	bool has_overlay;

# endif  /* USE_EGO_GRAPHICS */
	int k, l;
	unsigned long pixel, blank;

#endif /* USE_TRANSPARENCY */

	/* Figure out where to place the text */
	y = (y * widget->angband.fontheight + widget->angband.internal_border);
	x = (x * widget->angband.fontwidth + widget->angband.internal_border);

	for (i = 0; i < n; ++i)
	{
		a = *ap++;
		c = *cp++;

		/* For extra speed - cache these values */
		x1 = (c & 0x7F) * widget->angband.fontwidth;
		y1 = (a & 0x7F) * widget->angband.fontheight;

#ifdef USE_TRANSPARENCY

		ta = *tap++;
		tc = *tcp++;

		/* For extra speed - cache these values */
		x2 = (tc & 0x7F) * widget->angband.fontwidth;
		y2 = (ta & 0x7F) * widget->angband.fontheight;

# ifdef USE_EGO_GRAPHICS

		ea = *eap++;
		ec = *ecp++;
		has_overlay = (ea && ec);

		/* For extra speed -- cache these values */
		x3 = (ec & 0x7F) * widget->angband.fontwidth;
		y3 = (ea & 0x7F) * widget->angband.fontheight;

# endif  /* USE_EGO_GRAPHICS */

		/* Optimise the common case */
		if ((x1 == x2) && (y1 == y2))
		{

# ifndef USE_EGO_GRAPHICS

			/* Draw object / terrain */
			XPutImage(XtDisplay(widget), XtWindow(widget),
			          widget->angband.gc[0],
			          widget->angband.tiles,
			          x1, y1,
			          x, y,
			          widget->angband.fontwidth,
			          widget->angband.fontheight);

# else /* !USE_EGO_GRAPHICS */

			/* No overlay */
			if (!has_overlay)
			{
				/* Draw object / terrain */
				XPutImage(XtDisplay(widget), XtWindow(widget),
				          widget->angband.gc[0],
				          widget->angband.tiles,
				          x1, y1,
				          x, y,
				          widget->angband.fontwidth,
				          widget->angband.fontheight);
			}

			/* Terrain overlay */
			else
			{
				/* Mega Hack^2 - assume the top left corner is "black" */
				blank = XGetPixel(widget->angband.tiles,
				                  0, widget->angband.fontheight * 6);

				for (k = 0; k < widget->angband.fontwidth; k++)
				{
					for (l = 0; l < widget->angband.fontheight; l++)
					{
						/* If mask set... */
						if ((pixel = XGetPixel(widget->angband.tiles,
						                       x3 + k, y3 + l)) == blank)
						{
							/* Output from the terrain */
							pixel = XGetPixel(widget->angband.tiles,
							                  x1 + k, y1 + l);
						}

						/* Store into the temp storage */
						XPutPixel(widget->angband.TmpImage,
						          k, l, pixel);
					}
				}

				/* Draw terrain + overlay */
				XPutImage(XtDisplay(widget), XtWindow(widget),
				          widget->angband.gc[0],
				          widget->angband.TmpImage,
				          0, 0,
				          x, y,
				          widget->angband.fontwidth,
				          widget->angband.fontheight);
			}

# endif  /* !USE_EGO_GRAPHICS */

		}
		else
		{
			/* Mega Hack^2 - assume the top left corner is "black" */
			blank = XGetPixel(widget->angband.tiles,
			                  0, widget->angband.fontheight * 6);

# ifndef USE_EGO_GRAPHICS

			for (k = 0; k < widget->angband.fontwidth; k++)
			{
				for (l = 0; l < widget->angband.fontheight; l++)
				{
					/* If mask set... */
					if ((pixel = XGetPixel(widget->angband.tiles,
					                       x1 + k, y1 + l)) == blank)
					{

						/* Output from the terrain */
						pixel = XGetPixel(widget->angband.tiles,
						                  x2 + k, y2 + l);
					}

					/* Store into the temp storage. */
					XPutPixel(widget->angband.TmpImage,
					          k, l, pixel);
				}
			}

#else /* !USE_EGO_GRAPHICS */

		for (k = 0; k < widget->angband.fontwidth; k++)
		{
			for (l = 0; l < widget->angband.fontheight; l++)
			{
				/* Get overlay pixel */
				if (has_overlay)
				{
					pixel = XGetPixel(widget->angband.tiles,
					                  x3 + k, y3 + l);
				}

				/* Hack -- no overlay */
				else
				{
					pixel = blank;
				}

				/* If it's blank */
				if (pixel == blank)
				{
					/* Use obj/mon */
					pixel = XGetPixel(widget->angband.tiles,
					                  x1 + k, y1 + l);
				}

				/* Use terrain if it's blank too */
				if (pixel == blank)
				{
					pixel = XGetPixel(widget->angband.tiles,
					                  x2 + k, y2 + l);
				}

				/* Store into the temp storage. */
				XPutPixel(widget->angband.TmpImage,
				          k, l, pixel);
			}
		}

#endif /* !USE_EGO_GRAPHICS */

			/* Draw to screen */

			/* Draw object / terrain */
			XPutImage(XtDisplay(widget), XtWindow(widget),
			          widget->angband.gc[0],
			          widget->angband.TmpImage,
			          0, 0,
			          x, y,
			          widget->angband.fontwidth,
			          widget->angband.fontheight);
		}

#else /* USE_TRANSPARENCY */

		/* Draw object / terrain */
		XPutImage(XtDisplay(widget), XtWindow(widget),
		          widget->angband.gc[0],
		          widget->angband.tiles,
		          x1, y1,
		          x, y,
		          widget->angband.fontwidth,
		          widget->angband.fontheight);

#endif /* USE_TRANSPARENCY */

		x += widget->angband.fontwidth;
	}
}

#endif /* USE_GRAPHICS */

/*
 * Private procedures
 */


/*
 * Procedure Initialize() is called during the widget creation
 * process.  Initialize() load fonts and calculates window geometry.
 * The request parameter is filled in by parents to this widget.  The
 * wnew parameter is the request parameter plus data filled in by this
 * widget. All changes should be done to the wnew parameter.
 */
static void Initialize(AngbandWidget request, AngbandWidget wnew)
{
	Display *dpy = XtDisplay(wnew);

	int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew));

	XGCValues gcv;
	TopLevelShellWidget parent =
	        (TopLevelShellWidget)XtParent((Widget) wnew);
	int i;

	/* Default background pixel */
	unsigned long bg = create_pixel(dpy,
	                                angband_color_table[0][1],
	                                angband_color_table[0][2],
	                                angband_color_table[0][3]);

	/* Default foreground pixel */
	unsigned long fg = create_pixel(dpy,
	                                angband_color_table[1][1],
	                                angband_color_table[1][2],
	                                angband_color_table[1][3]);

	/* Fix the background color */
	wnew->core.background_pixel = bg;

	/* Get some information about the font */
	wnew->angband.fnt = getFont(wnew, wnew->angband.font, TRUE);
	wnew->angband.fontheight = wnew->angband.fnt->ascent +
	                           wnew->angband.fnt->descent;
	wnew->angband.fontwidth = wnew->angband.fnt->max_bounds.width;
	wnew->angband.fontascent = wnew->angband.fnt->ascent;

	/* Create and initialize the graphics contexts */ /* GXset? */
	gcv.font = wnew->angband.fnt->fid;
	gcv.graphics_exposures = FALSE;
	gcv.background = bg;

	for (i = 0; i < NUM_COLORS; i++)
	{
		unsigned long pixel;

		/* Acquire Angband colors */
		wnew->angband.color[i][0] = angband_color_table[i][0];
		wnew->angband.color[i][1] = angband_color_table[i][1];
		wnew->angband.color[i][2] = angband_color_table[i][2];
		wnew->angband.color[i][3] = angband_color_table[i][3];

		if (depth > 1)
		{
			/* Create pixel */
			pixel = create_pixel(dpy,
			                     wnew->angband.color[i][1],
			                     wnew->angband.color[i][2],
			                     wnew->angband.color[i][3]);
		}
		else
		{
			/* Use background or foreground */
			pixel = ((i == 0) ? bg : fg);
		}

		gcv.foreground = pixel;

		/* Copy */
		gcv.function = 3;

		wnew->angband.gc[i] = XtGetGC((Widget)wnew,
		                              (GCFont | GCForeground | GCFunction |
		                               GCBackground | GCGraphicsExposures),
		                              &gcv);
	}

	/* Create a special GC for highlighting */
	gcv.foreground = (BlackPixelOfScreen(XtScreen((Widget)wnew)) ^
	                  WhitePixelOfScreen(XtScreen((Widget)wnew)));
	gcv.background = 0;

	gcv.function = GXxor;
	wnew->angband.gc[COLOR_XOR] = XtGetGC((Widget)wnew,
	                                      (GCFunction | GCForeground | GCBackground |
	                                       GCGraphicsExposures),
	                                      &gcv);

	/* Calculate window geometry */
	wnew->core.height = (wnew->angband.start_rows * wnew->angband.fontheight +
	                     2 * wnew->angband.internal_border);
	wnew->core.width = (wnew->angband.start_columns * wnew->angband.fontwidth +
	                    2 * wnew->angband.internal_border);

	/* We need to be able to resize the Widget if the user wants to */
	/* change font on the fly! */
	parent->shell.allow_shell_resize = TRUE;

	/* Calculates all the size hints */
	calculateSizeHints(wnew);
}


/*
 * Procedure Destroy() is called during the destruction of the widget.
 * Destroy() releases and frees GCs, frees the pixmaps and frees the
 * fonts.
 */
static void Destroy(AngbandWidget widget)
{
	int n;

	/* Free all GC's */
	for (n = 0; n < NUM_COLORS + 1; n++)
	{
		XtReleaseGC((Widget)widget, widget->angband.gc[n]);
	}

	/* Free the font */
	XFreeFont(XtDisplay((Widget)widget), widget->angband.fnt);
}


static void Resize_term(AngbandWidget wnew)
{
	int cols, rows, wid, hgt;

	int ox = wnew->angband.internal_border;
	int oy = wnew->angband.internal_border;

	int i;
	term_data *old_td;
	term_data *td = &data[0];


	/*
	 * Mega-Hack -- avoid calling this before the terms package is
	 * initialised
	 */
	if (!Term) return;

	old_td = (term_data*)(Term->data);

	/* Hack - Find the term to activate */
	for (i = 0; i < num_term; i++)
	{
		td = &data[i];

		/* Paranoia:  none of the widgets matched */
		if (!td) return;

		/* Have we found it? */
		if (td->widget == wnew) break;
	}

	/* Paranoia -- No matches */
	if (i == num_term) return;

	/* Activate the proper Term */
	Term_activate(&td->t);

	/* Determine "proper" number of rows/cols */
	cols = ((wnew->core.width - (ox + ox)) / wnew->angband.fontwidth);
	rows = ((wnew->core.height - (oy + oy)) / wnew->angband.fontheight);

	/* Hack -- minimal size */
	if (cols < 1) cols = 1;
	if (rows < 1) rows = 1;

	if (i == 0)
	{
		/* Hack the main window must be at least 80x24 */
		if (cols < 80) cols = 80;
		if (rows < 24) rows = 24;
	}

	/* Desired size of window */
	wid = cols * wnew->angband.fontwidth + (ox + ox);
	hgt = rows * wnew->angband.fontheight + (oy + oy);

	/* Resize the Term (if needed) */
	(void) Term_resize(cols, rows);

	/* Activate the old term */
	Term_activate(&old_td->t);
}

/*
 * Procedure Redisplay() is called as the result of an Expose event.
 * Use the redraw callback to do a full redraw
 */
static void Redisplay(AngbandWidget wnew, XEvent *xev, Region region)
{
	int x1, x2, y1, y2;

	int i;

	term_data *old_td = (term_data*)(Term->data);
	term_data *td = &data[0];

	/* Hack - Find the term to activate */
	for (i = 0; i < num_term; i++)
	{
		td = &data[i];

		/* Have we found it? */
		if (td->widget == wnew) break;

		/* Paranoia:  none of the widgets matched */
		if (!td) return;
	}

	/* Activate the proper Term */
	Term_activate(&td->t);

	/* Find the bounds of the exposed region */

	/*
	 * This probably could be obtained from the Region parameter -
	 * but I don't know anything about XAW.
	 */
	x1 = (xev->xexpose.x - wnew->angband.internal_border)
	     / wnew->angband.fontwidth;
	x2 = (xev->xexpose.x + xev->xexpose.width -
	      wnew->angband.internal_border) / wnew->angband.fontwidth;

	y1 = (xev->xexpose.y - wnew->angband.internal_border)
	     / wnew->angband.fontheight;
	y2 = (xev->xexpose.y + xev->xexpose.height -
	      wnew->angband.internal_border) / wnew->angband.fontheight;

	Term_redraw_section(x1, y1, x2, y2);

	/* Activate the old term */
	Term_activate(&old_td->t);


#if 0
	if (XtHasCallbacks((Widget)widget, XtNredrawCallback) == XtCallbackHasSome)
	{
		XtCallCallbacks((Widget)widget, XtNredrawCallback, NULL);
	}
#endif /* 0 */
}


/*
 * Font and internal_border can be changed on the fly.
 *
 * The entire widget is redrawn if any of those parameters change (all
 * can potentially have effects that spans the whole widget).
 *
 * Color changes are handled elsewhere.
 *
 * This function is very underspecified, in terms of how these changes can
 * occur, and what is true about the various AngbandWidget's passed in.  It
 * is very likely that this code no longer works.
 */
static Boolean SetValues(AngbandWidget current, AngbandWidget request,
                         AngbandWidget wnew, ArgList args,
                         Cardinal *num_args)
{
	Display *dpy = XtDisplay(wnew);

	Boolean font_changed = FALSE;
	Boolean border_changed = FALSE;
	int height, width;
	int i;


	/* Handle font change */
	if (wnew->angband.font != current->angband.font)
	{
		/* Check if the font exists */
		wnew->angband.fnt = getFont(wnew, wnew->angband.font, FALSE);

		/* The font didn't exist */
		if (wnew->angband.fnt == NULL)
		{
			wnew->angband.fnt = current->angband.fnt;
			wnew->angband.font = current->angband.font;
			XtWarning("Couldn't find the requested font!");
		}
		else
		{
			font_changed = TRUE;

			/* Free the old font */
			XFreeFont(XtDisplay((Widget)wnew), current->angband.fnt);
			/* Update font information */
			wnew->angband.fontheight = wnew->angband.fnt->ascent +
			                           wnew->angband.fnt->descent;
			wnew->angband.fontwidth = wnew->angband.fnt->max_bounds.width;
			wnew->angband.fontascent = wnew->angband.fnt->ascent;
		}
	}

	/* Handle font change */
	if (font_changed)
	{
		/* Update all GC's */
		for (i = 0; i < NUM_COLORS; i++)
		{
			/* Steal the old GC */
			wnew->angband.gc[i] = current->angband.gc[i];
			current->angband.gc[i] = NULL;

			/* Be sure the correct font is ready */
			XSetFont(dpy, wnew->angband.gc[i], wnew->angband.fnt->fid);
		}

		/* Steal the old GC */
		wnew->angband.gc[NUM_COLORS] = current->angband.gc[NUM_COLORS];
		current->angband.gc[NUM_COLORS] = NULL;
	}


	/* Check if internal border width has changed, used later */
	if (current->angband.internal_border != wnew->angband.internal_border)
	{
		border_changed = TRUE;
	}


	/* If the font or the internal border has changed, all geometry */
	/* has to be recalculated */
	if (font_changed || border_changed)
	{
		/* Change window size */
		height = ((current->core.height - 2 * current->angband.internal_border) /
		          current->angband.fontheight * wnew->angband.fontheight +
		          2 * current->angband.internal_border);
		width = ((current->core.width - 2 * current->angband.internal_border) /
		         current->angband.fontwidth * wnew->angband.fontwidth +
		         2 * wnew->angband.internal_border);

		/* Get the new width */
		if (XtMakeResizeRequest((Widget)wnew, width, height, NULL, NULL) ==
		                XtGeometryNo)
		{
			/* Not allowed */
			XtWarning("Size change denied!");
		}
		else
		{
			/* Recalculate size hints */
			calculateSizeHints(wnew);
		}
	}

	/* Tell it to redraw the widget if anything has changed */
	return (font_changed || border_changed);
}


/*
 * Calculate size hints
 */
static void calculateSizeHints(AngbandWidget wnew)
{
	TopLevelShellWidget parent =
	        (TopLevelShellWidget)XtParent((Widget) wnew);

	/* Calculate minimum size */
	parent->wm.size_hints.min_height =
	        (wnew->angband.min_rows * wnew->angband.fontheight +
	         2 * wnew->angband.internal_border);

	/* Calculate minimum size */
	parent->wm.size_hints.min_width =
	        (wnew->angband.min_columns * wnew->angband.fontwidth +
	         2 * wnew->angband.internal_border);

	/* Calculate minimum size */
	parent->wm.size_hints.flags |= PMinSize;

	/* Calculate maximum size */
	parent->wm.size_hints.max_height =
	        (wnew->angband.max_rows * wnew->angband.fontheight +
	         2 * wnew->angband.internal_border);

	/* Calculate maximum size */
	parent->wm.size_hints.max_width =
	        (wnew->angband.max_columns * wnew->angband.fontwidth +
	         2 * wnew->angband.internal_border);

	/* Calculate maximum size */
	parent->wm.size_hints.flags |= PMaxSize;

	/* Calculate increment size */
	parent->wm.size_hints.height_inc = wnew->angband.fontheight;
	parent->wm.size_hints.width_inc = wnew->angband.fontwidth;
	parent->wm.size_hints.flags |= PResizeInc;

	/* Calculate base size */
	parent->wm.base_height = 2 * wnew->angband.internal_border;
	parent->wm.base_width = 2 * wnew->angband.internal_border;
	parent->wm.size_hints.flags |= PBaseSize;
}


/*
 * Load a font
 */
static XFontStruct *getFont(AngbandWidget widget,
                            String font, Boolean fallback)
{
	Display *dpy = XtDisplay((Widget) widget);
	char buf[256];
	XFontStruct *fnt = NULL;

	if (!(fnt = XLoadQueryFont(dpy, font)) && fallback)
	{
		sprintf(buf, "Can't find the font \"%s\", trying fixed\n", font);
		XtWarning(buf);
		if (!(fnt = XLoadQueryFont(dpy, "fixed")))
		{
			XtError("Can't fint the font \"fixed\"!, bailing out\n");
		}
	}

	return fnt;
}



/*** The Angband code ****/





/*
 * Number of fallback resources per window
 */
#define TERM_FALLBACKS 6



/*
 * The names of the term_data's
 */
char *termNames[MAX_TERM_DATA] =
{
	"angband",
	"mirror",
	"recall",
	"choice",
	"term-4",
	"term-5",
	"term-6",
	"term-7"
};


/*
 * The special Arg's
 */
Arg specialArgs[TERM_FALLBACKS] =
{
	{ XtNstartRows, 24},
	{ XtNstartColumns, 80},
	{ XtNminRows, 24},
	{ XtNminColumns, 80},
	{ XtNmaxRows, 255},
	{ XtNmaxColumns, 255}
};


/*
 * The default Arg's
 */
Arg defaultArgs[TERM_FALLBACKS] =
{
	{ XtNstartRows, 24},
	{ XtNstartColumns, 80},
	{ XtNminRows, 1},
	{ XtNminColumns, 1},
	{ XtNmaxRows, 255},
	{ XtNmaxColumns, 255}
};


/*
 * The application context
 */
XtAppContext appcon;


/*
 * User changable information about widgets
 */
static String fallback[] =
{
	"Angband.angband.iconName:   ToME",
	"Angband.angband.title:      ToME",
	"Angband.term-1.iconName:    Mirror",
	"Angband.term-1.title:       Mirror",
	"Angband.term-2.iconName:    Recall",
	"Angband.term-2.title:       Recall",
	"Angband.term-3.iconName:    Choice",
	"Angband.term-3.title:       Choice",
	"Angband.term-4.iconName:    Term 4",
	"Angband.term-4.title:       Term 4",
	"Angband.term-5.iconName:    Term 5",
	"Angband.term-5.title:       Term 5",
	"Angband.term-6.iconName:    Term 6",
	"Angband.term-6.title:       Term 6",
	"Angband.term-7.iconName:    Term 7",
	"Angband.term-7.title:       Term 7",
	NULL
};



/*
 * Do a redraw
 */
static void react_redraw(Widget widget,
                         XtPointer client_data, XtPointer call_data)
{
	term_data *old_td = (term_data*)(Term->data);
	term_data *td = (term_data*)client_data;

	/* Activate the proper Term */
	Term_activate(&td->t);

	/* Request a redraw */
	Term_redraw();

	/* Activate the old Term */
	Term_activate(&old_td->t);
}



/*
 * Process a keypress event
 *
 * Also appears in "main-x11.c".
 */
static void react_keypress(XKeyEvent *xev)
{
	int i, n, mc, ms, mo, mx;

	uint ks1;

	XKeyEvent *ev = (XKeyEvent*)(xev);

	KeySym ks;

	char buf[128];
	char msg[128];


	/* Check for "normal" keypresses */
	n = XLookupString(ev, buf, 125, &ks, NULL);

	/* Terminate */
	buf[n] = '\0';


	/* Hack -- Ignore "modifier keys" */
	if (IsModifierKey(ks)) return;


	/* Hack -- convert into an unsigned int */
	ks1 = (uint)(ks);

	/* Extract four "modifier flags" */
	mc = (ev->state & ControlMask) ? TRUE : FALSE;
	ms = (ev->state & ShiftMask) ? TRUE : FALSE;
	mo = (ev->state & Mod1Mask) ? TRUE : FALSE;
	mx = (ev->state & Mod2Mask) ? TRUE : FALSE;


	/* Normal keys with no modifiers */
	if (n && !mo && !mx && !IsSpecialKey(ks))
	{
		/* Enqueue the normal key(s) */
		for (i = 0; buf[i]; i++) Term_keypress(buf[i]);

		/* All done */
		return;
	}


	/* Handle a few standard keys (bypass modifiers) XXX XXX XXX */
	switch (ks1)
	{
	case XK_Escape:
		{
			Term_keypress(ESCAPE);
			return;
		}

	case XK_Return:
		{
			Term_keypress('\r');
			return;
		}

	case XK_Tab:
		{
			Term_keypress('\t');
			return;
		}

	case XK_Delete:
	case XK_BackSpace:
		{
			Term_keypress('\010');
			return;
		}
	}


	/* Hack -- Use the KeySym */
	if (ks)
	{
		sprintf(msg, "%c%s%s%s%s_%lX%c", 31,
		        mc ? "N" : "", ms ? "S" : "",
		        mo ? "O" : "", mx ? "M" : "",
		        (unsigned long)(ks), 13);
	}

	/* Hack -- Use the Keycode */
	else
	{
		sprintf(msg, "%c%s%s%s%sK_%X%c", 31,
		        mc ? "N" : "", ms ? "S" : "",
		        mo ? "O" : "", mx ? "M" : "",
		        ev->keycode, 13);
	}

	/* Enqueue the "macro trigger" string */
	for (i = 0; msg[i]; i++) Term_keypress(msg[i]);


	/* Hack -- auto-define macros as needed */
	if (n && (macro_find_exact(msg) < 0))
	{
		/* Create a macro */
		macro_add(msg, buf);
	}
}


/*
 * Handle an event
 */
static void handle_event(Widget widget, XtPointer client_data, XEvent *event,
                         Boolean *continue_to_dispatch)
{
	term_data *old_td = (term_data*)(Term->data);
	term_data *td = (term_data *)client_data;

	/* Continue to process the event by default */
	*continue_to_dispatch = TRUE;

	/* Activate the Term */
	Term_activate(&td->t);

	switch (event->type)
	{
	case KeyPress:
		{
			/* Hack -- use old term */
			Term_activate(&old_td->t);

			/* Handle the keypress */
			react_keypress(&(event->xkey));

			/* We took care of the event */
			*continue_to_dispatch = FALSE;

			break;
		}

		/* Oops */
	default:
		{
			break;
		}
	}

	/* Activate the old term */
	Term_activate(&old_td->t);

	return;
}


/*
 * Process an event (or just check for one)
 */
errr CheckEvent(bool wait)
{
	XEvent event;

	/* No events ready, and told to just check */
	if (!wait && !XtAppPending(appcon)) return 1;

	/* Process */
	while (1)
	{
		XtAppNextEvent(appcon, &event);
		XtDispatchEvent(&event);
		if (!XtAppPending(appcon)) break;
	}

	return (0);
}


/*
 * Monstrous hack.
 */
static void Term_xtra_xaw_react_aux(term_data *td)
{
	AngbandWidget wnew = td->widget;

	Display *dpy = XtDisplay((Widget) wnew);

	int depth = DefaultDepthOfScreen(XtScreen((Widget) wnew));

	int i;

	/* See if any colors need to be changed */
	for (i = 0; i < NUM_COLORS; i++)
	{
		if (depth > 1)
		{
			if ((wnew->angband.color[i][0] != angband_color_table[i][0]) ||
			                (wnew->angband.color[i][1] != angband_color_table[i][1]) ||
			                (wnew->angband.color[i][2] != angband_color_table[i][2]) ||
			                (wnew->angband.color[i][3] != angband_color_table[i][3]))
			{
				unsigned long pixel;

				/* Save new values */
				wnew->angband.color[i][0] = angband_color_table[i][0];
				wnew->angband.color[i][1] = angband_color_table[i][1];
				wnew->angband.color[i][2] = angband_color_table[i][2];
				wnew->angband.color[i][3] = angband_color_table[i][3];

				/* Create pixel */
				pixel = create_pixel(dpy,
				                     wnew->angband.color[i][1],
				                     wnew->angband.color[i][2],
				                     wnew->angband.color[i][3]);


				/* Change */
				XSetForeground(dpy, wnew->angband.gc[i], pixel);
			}
		}
	}
}


/*
 * Monstrous hack.
 */
static errr Term_xtra_xaw_react(void)
{
	int i;

	/* Initialize the windows */
	for (i = 0; i < num_term; i++)
	{
		term_data *td = &data[i];

		if (!td) break;

		Term_xtra_xaw_react_aux(td);
	}

	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_xaw(int n, int v)
{
	term_data *td = (term_data*)(Term->data);

	Widget widget = (Widget)(td->widget);

	Display *dpy = XtDisplay(widget);

	/* Handle a subset of the legal requests */
	switch (n)
	{
		/* Make a noise */
	case TERM_XTRA_NOISE:
		XBell(dpy, 100);
		return (0);

		/* Flush the output */
	case TERM_XTRA_FRESH:
		XFlush(dpy);
		/* Allow flushed events to be showed */
		CheckEvent(FALSE);
		return (0);

		/* Process random events */
	case TERM_XTRA_BORED:
		return (CheckEvent(0));

		/* Process events */
	case TERM_XTRA_EVENT:
		return (CheckEvent(v));

		/* Flush events */
	case TERM_XTRA_FLUSH:
		while (!CheckEvent(FALSE));
		return (0);

		/* Clear the window */
	case TERM_XTRA_CLEAR:
		XClearWindow(dpy, XtWindow(widget));
		return (0);

		/* Delay */
	case TERM_XTRA_DELAY:
		usleep(1000 * v);
		return (0);

		/* Get Delay of some milliseconds */
	case TERM_XTRA_GET_DELAY:
		{
			int ret;
			struct timeval tv;

			ret = gettimeofday(&tv, NULL);
			Term_xtra_long = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);

			return ret;
		}

		/* Subdirectory scan */
	case TERM_XTRA_SCANSUBDIR:
		{
			DIR *directory;
			struct dirent *entry;

			scansubdir_max = 0;

			directory = opendir(scansubdir_dir);
			if (!directory)
				return 1;

			while (entry = readdir(directory))
			{
				char file[PATH_MAX + NAME_MAX + 2];
				struct stat filedata;

				file[PATH_MAX + NAME_MAX] = 0;
				strncpy(file, scansubdir_dir, PATH_MAX);
				strncat(file, "/", 2);
				strncat(file, entry->d_name, NAME_MAX);
				if (!stat(file, &filedata) && S_ISDIR((filedata.st_mode)))
				{
					string_free(scansubdir_result[scansubdir_max]);
					scansubdir_result[scansubdir_max] = string_make(entry->d_name);
					++scansubdir_max;
				}
			}
		}

	case TERM_XTRA_REACT:
		return (Term_xtra_xaw_react());
	}

	/* Unknown */
	return (1);
}



/*
 * Erase a number of characters
 */
static errr Term_wipe_xaw(int x, int y, int n)
{
	term_data *td = (term_data*)(Term->data);

	/* Erase using color 0 */
	AngbandClearArea(td->widget, x, y, n, 1, 0);

	/* Success */
	return (0);
}



/*
 * Draw the cursor, by hiliting with XOR
 *
 * Should perhaps use rectangle outline, ala "main-mac.c".  XXX XXX XXX
 */
static errr Term_curs_xaw(int x, int y)
{
	term_data *td = (term_data*)(Term->data);

	/* Hilite the cursor character */
	AngbandClearArea(td->widget, x, y, 1, 1, COLOR_XOR);

	/* Success */
	return (0);
}


/*
 * Draw a number of characters
 */
static errr Term_text_xaw(int x, int y, int n, byte a, cptr s)
{
	term_data *td = (term_data*)(Term->data);

	/* Draw the text */
	AngbandOutputText(td->widget, x, y, (String)s, n, a);

	/* Success */
	return (0);
}


#ifdef USE_GRAPHICS

/*
 * Draw some graphical characters.
 */
# ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
static errr Term_pict_xaw(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp, const byte *eap, const char *ecp)
# else /* USE_EGO_GRAPHICS */
static errr Term_pict_xaw(int x, int y, int n, const byte *ap, const char *cp,
                          const byte *tap, const char *tcp)
# endif  /* USE_EGO_GRAPHICS */
# else /* USE_TRANSPARENCY */
static errr Term_pict_xaw(int x, int y, int n, const byte *ap, const char *cp)
# endif  /* USE_TRANSPARENCY */
{
	term_data *td = (term_data*)(Term->data);

	/* Draw the pictures */
# ifdef USE_TRANSPARENCY
# ifdef USE_EGO_GRAPHICS
	AngbandOutputPict(td->widget, x, y, n, ap, cp, tap, tcp, eap, ecp);
# else /* USE_EGO_GRAPHICS */
	AngbandOutputPict(td->widget, x, y, n, ap, cp, tap, tcp);
# endif  /* USE_EGO_GRAPHICS */
# else /* USE_TRANSPARENCY */
	AngbandOutputPict(td->widget, x, y, n, ap, cp);
# endif  /* USE_TRANSPARENCY */

	/* Success */
	return (0);
}

#endif /* USE_GRAPHICS */


/*
 * Raise a term
 */
static void term_raise(term_data *td)
{
	Widget widget = (Widget)(td->widget);

	XRaiseWindow(XtDisplay(XtParent(widget)), XtWindow(XtParent(widget)));
}


/*
 * Initialize a term_data
 */
static errr term_data_init(term_data *td, Widget topLevel,
                           int key_buf, String name,
                           ArgList widget_arg, Cardinal widget_arg_no, int i)
{
	Widget parent;
	term *t = &td->t;

	int cols = 80;
	int rows = 24;

	char buf[80];
	cptr str;

	int val;

	/* Create the shell widget */
	parent = XtCreatePopupShell(name, topLevelShellWidgetClass, topLevel,
	                            NULL, 0);

	/* Window specific cols */
	sprintf(buf, "ANGBAND_X11_COLS_%d", i);
	str = getenv(buf);
	val = (str != NULL) ? atoi(str) : -1;
	if (val > 0) cols = val;

	/* Window specific rows */
	sprintf(buf, "ANGBAND_X11_ROWS_%d", i);
	str = getenv(buf);
	val = (str != NULL) ? atoi(str) : -1;
	if (val > 0) rows = val;

	/* Hack the main window must be at least 80x24 */
	if (i == 0)
	{
		if (cols < 80) cols = 80;
		if (rows < 24) rows = 24;
	}

	/* Reset the initial size */
	widget_arg[0].value = rows;
	widget_arg[1].value = cols;

	/* Create the interior widget */
	td->widget = (AngbandWidget)
	             XtCreateManagedWidget(name, angbandWidgetClass,
	                                   parent, widget_arg, widget_arg_no);

	/* Initialize the term (full size) */
	term_init(t, cols, rows, key_buf);

	/* Use a "soft" cursor */
	t->soft_cursor = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Hooks */
	t->xtra_hook = Term_xtra_xaw;
	t->curs_hook = Term_curs_xaw;
	t->wipe_hook = Term_wipe_xaw;
	t->text_hook = Term_text_xaw;

	/* Save the data */
	t->data = td;

	/* Register the keypress event handler */
	XtAddEventHandler((Widget)td->widget, KeyPressMask,
	                  False, (XtEventHandler) handle_event, td);

	/* Redraw callback */
	XtAddCallback((Widget)td->widget, XtNredrawCallback,
	              react_redraw, td);

	/* Realize the widget */
	XtRealizeWidget(parent);

	/* Make it visible */
	XtPopup(parent, XtGrabNone);

	/* Activate (important) */
	Term_activate(t);

	Resize_term(td->widget);

	return 0;
}


/*
 * Initialization function for an X Athena Widget module to Angband
 *
 * We should accept "-d" requests in the "argv" array.  XXX XXX XXX
 */
errr init_xaw(int argc, char *argv[])
{
	int i;
	Widget topLevel;
	Display *dpy;

	cptr dpy_name = "";


#ifdef USE_GRAPHICS

	char filename[1024];

	int pict_wid = 0;
	int pict_hgt = 0;
	bool force_old_graphics = FALSE;

#ifdef USE_TRANSPARENCY

	char *TmpData;
#endif /* USE_TRANSPARENCY */

#endif /* USE_GRAPHICS */

	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-d"))
		{
			dpy_name = &argv[i][2];
			continue;
		}

#ifdef USE_GRAPHICS

		if (prefix(argv[i], "-s"))
		{
			smoothRescaling = FALSE;
			continue;
		}

		if (prefix(argv[i], "-o"))
		{
			force_old_graphics = TRUE;
			continue;
		}

#endif /* USE_GRAPHICS */

		if (prefix(argv[i], "-n"))
		{
			num_term = atoi(&argv[i][2]);
			if (num_term > MAX_TERM_DATA) num_term = MAX_TERM_DATA;
			else if (num_term < 1) num_term = 1;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}


	/* Attempt to open the local display */
	dpy = XOpenDisplay(dpy_name);

	/* Failure -- assume no X11 available */
	if (!dpy) return ( -1);

	/* Close the local display */
	XCloseDisplay(dpy);


#ifdef USE_XAW_LANG

	/* Support locale processing */
	XtSetLanguageProc(NULL, NULL, NULL);

#endif /* USE_XAW_LANG */


	/* Initialize the toolkit */
	topLevel = XtAppInitialize(&appcon, "Angband", NULL, 0, &argc, argv,
	                           fallback, NULL, 0);

	XSetIOErrorHandler(x_io_error_handler);

	/* Initialize the windows */
	for (i = 0; i < num_term; i++)
	{
		term_data *td = &data[i];

		term_data_init(td, topLevel, 1024, termNames[i],
		               (i == 0) ? specialArgs : defaultArgs,
		               TERM_FALLBACKS, i);

		angband_term[i] = Term;
	}

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

	/* Raise the "Angband" window */
	term_raise(&data[0]);


#ifdef USE_GRAPHICS

	/* Try graphics */
	if (arg_graphics)
	{
		/* Try the "16x16.bmp" file */
		path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/16x16.bmp");

		/* Use the "16x16.bmp" file if it exists */
		if (!force_old_graphics &&
		                (0 == fd_close(fd_open(filename, O_RDONLY))))
		{
			/* Use graphics */
			use_graphics = TRUE;

			pict_wid = pict_hgt = 16;

			ANGBAND_GRAF = "new";
		}
		else
		{
			/* Try the "8x8.bmp" file */
			path_build(filename, 1024, ANGBAND_DIR_XTRA, "graf/8x8.bmp");

			/* Use the "8x8.bmp" file if it exists */
			if (0 == fd_close(fd_open(filename, O_RDONLY)))
			{
				/* Use graphics */
				use_graphics = TRUE;

				pict_wid = pict_hgt = 8;

				ANGBAND_GRAF = "old";
			}
		}
	}

	/* Load graphics */
	if (use_graphics)
	{
		/* Hack -- Get the Display */
		term_data *td = &data[0];
		Widget widget = (Widget)(td->widget);
		Display *dpy = XtDisplay(widget);

		XImage *tiles_raw;

		/* Load the graphical tiles */
		tiles_raw = ReadBMP(dpy, filename);

		/* Initialize the windows */
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];

			term *t = &td->t;

			t->pict_hook = Term_pict_xaw;

			t->higher_pict = TRUE;

			/* Resize tiles */
			td->widget->angband.tiles =
			        ResizeImage(dpy, tiles_raw,
			                    pict_wid, pict_hgt,
			                    td->widget->angband.fontwidth,
			                    td->widget->angband.fontheight);
		}

#ifdef USE_TRANSPARENCY

		/* Initialize the transparency temp storage*/
		for (i = 0; i < num_term; i++)
		{
			term_data *td = &data[i];
			int ii, jj;
			int depth = DefaultDepth(dpy, DefaultScreen(dpy));
			Visual *visual = DefaultVisual(dpy, DefaultScreen(dpy));
			int total;


			/* Determine total bytes needed for image */
			ii = 1;
			jj = (depth - 1) >> 2;
			while (jj >>= 1) ii <<= 1;
			total = td->widget->angband.fontwidth *
			        td->widget->angband.fontheight * ii;


			TmpData = (char *)malloc(total);

			td->widget->angband.TmpImage = XCreateImage(dpy,
			                               visual, depth,
			                               ZPixmap, 0, TmpData,
			                               td->widget->angband.fontwidth,
			                               td->widget->angband.fontheight, 8, 0);

		}

#endif /* USE_TRANSPARENCY */


		/* Free tiles_raw? XXX XXX */
	}

#endif /* USE_GRAPHICS */

	/* Success */
	return (0);
}

#endif /* USE_XAW */

tome-235-src/src/main-xxx.c0000644000076400017500000005375111012107763013405 0ustar  dgdg/* File: main-xxx.c */

/* Purpose: Sample visual module for Angband 2.8.1 */

/*
 * This file written by "Ben Harrison (benh@phial.com)".
 *
 * This file is intended to show one way to build a "visual module"
 * for Angband to allow it to work with a new system.  It does not
 * actually work, but if the code near "XXX XXX XXX" comments were
 * replaced with functional code, then it probably would.
 *
 * See "z-term.c" for info on the concept of the "generic terminal",
 * and for more comments about what this file must supply.
 *
 * There are two basic ways to port Angband to a new system.  The
 * first involves modifying the "main-gcu.c" and/or "main-x11.c"
 * files to support some version of "curses" and/or "X11" on your
 * machine, and to compile with the "USE_GCU" and/or "USE_X11"
 * compilation flags defined.  The second involves creating a
 * new "main-xxx.c" file, based on this sample file (or on any
 * existing "main-xxx.c" file), and comes in two flavors, based
 * on whether it contains a "main()" function (as in "main-mac.c"
 * and "main-win.c") or not (as in "main-gcu.c" or "main-x11.c").
 *
 * If the "main-xxx.c" file includes its own "main()" function,
 * then you should NOT link in the "main.c" file, and your "main()"
 * function must process any command line arguments, initialize the
 * "visual system", and call "play_game()" with appropriate arguments.
 *
 * If the "main-xxx.c" file does not include its own "main()"
 * function, then you must add some code to "main.c" which, if
 * the appropriate "USE_XXX" compilation flag is defined, will
 * attempt to call the "init_xxx()" function in the "main-xxx.c"
 * file, which should initialize the "visual system" and return
 * zero if it was successful.  The "main()" function in "main.c"
 * will take care of processing command line arguments and then
 * calling "play_game()" with appropriate arguments.
 *
 * Note that the "util.c" file often contains functions which must
 * be modified in small ways for various platforms, even if you are
 * able to use the existing "main-gcu.c" and/or "main-x11.c" files,
 * in particular, the "file handling" functions may not work on all
 * systems.
 *
 * When you complete a port to a new system, you should email any
 * newly created files, and any changes made to existing files,
 * including "h-config.h", "config.h", and any of the "Makefile"
 * files, to "benh@phial.com" for inclusion in the next version.
 *
 * Try to stick to a "three letter" naming scheme for "main-xxx.c"
 * and "Makefile.xxx" and such for consistency and simplicity.
 */


#include "angband.h"


#ifdef USE_XXX


/*
 * Extra data to associate with each "window"
 *
 * Each "window" is represented by a "term_data" structure, which
 * contains a "term" structure, which contains a pointer (t->data)
 * back to the term_data structure.
 */

typedef struct term_data term_data;

struct term_data
{
	term t;

	/* Other fields if needed XXX XXX XXX */
};



/*
 * Number of "term_data" structures to support XXX XXX XXX
 *
 * You MUST support at least one "term_data" structure, and the
 * game will currently use up to eight "term_data" structures if
 * they are available.
 *
 * If only one "term_data" structure is supported, then a lot of
 * the things that would normally go into a "term_data" structure
 * could be made into global variables instead.
 */
#define MAX_TERM_DATA 1


/*
 * An array of "term_data" structures, one for each "sub-window"
 */
static term_data data[MAX_TERM_DATA];


#if 0	/* Fix the syntax below XXX XXX XXX */

/*
 * The "color" array for the visual module XXX XXX XXX
 *
 * This table should be used in whetever way is necessary to
 * convert the Angband Color Indexes into the proper "color data"
 * for the visual system.  On the Macintosh, these are arrays of
 * three shorts, on the IBM, these are combinations of the eight
 * basic color codes with optional "bright" bits, on X11, these
 * are actual "pixel" codes extracted from another table which
 * contains textual color names.
 *
 * The Angband Color Set (0 to 15):
 *   Black, White, Slate, Orange,    Red, Blue, Green, Umber
 *   D-Gray, L-Gray, Violet, Yellow, L-Red, L-Blue, L-Green, L-Umber
 *
 * Colors 8 to 15 are basically "enhanced" versions of Colors 0 to 7.
 *
 * As decribed in one of the header files, in a perfect world, the
 * colors below should fit a nice clean "quartered" specification
 * in RGB codes, but this must often be Gamma Corrected.  The 1/4
 * parts of each Red,Green,Blue are shown in the comments below,
 * again, these values are *before* gamma correction.
 */
static local_color_data_type color_data[16] =
{
	/* XXX XXX XXX 0,0,0 */, 		/* TERM_DARK */
	/* XXX XXX XXX 4,4,4 */, 		/* TERM_WHITE */
	/* XXX XXX XXX 2,2,2 */, 		/* TERM_SLATE */
	/* XXX XXX XXX 4,2,0 */, 		/* TERM_ORANGE */
	/* XXX XXX XXX 3,0,0 */, 		/* TERM_RED */
	/* XXX XXX XXX 0,2,1 */, 		/* TERM_GREEN */
	/* XXX XXX XXX 0,0,4 */, 		/* TERM_BLUE */
	/* XXX XXX XXX 2,1,0 */, 		/* TERM_UMBER */
	/* XXX XXX XXX 1,1,1 */, 		/* TERM_L_DARK */
	/* XXX XXX XXX 3,3,3 */, 		/* TERM_L_WHITE */
	/* XXX XXX XXX 4,0,4 */, 		/* TERM_VIOLET */
	/* XXX XXX XXX 4,4,0 */, 		/* TERM_YELLOW */
	/* XXX XXX XXX 4,0,0 */, 		/* TERM_L_RED */
	/* XXX XXX XXX 0,4,0 */, 		/* TERM_L_GREEN */
	/* XXX XXX XXX 0,4,4 */, 		/* TERM_L_BLUE */
	/* XXX XXX XXX 3,2,1 */ 		/* TERM_L_UMBER */
};

#endif



/*** Function hooks needed by "Term" ***/


/*
 * Init a new "term"
 *
 * This function should do whatever is necessary to prepare a new "term"
 * for use by the "term.c" package.  This may include clearing the window,
 * preparing the cursor, setting the font/colors, etc.  Usually, this
 * function does nothing, and the "init_xxx()" function does it all.
 */
static void Term_init_xxx(term *t)
{
	term_data *td = (term_data*)(t->data);

	/* XXX XXX XXX */
}



/*
 * Nuke an old "term"
 *
 * This function is called when an old "term" is no longer needed.  It should
 * do whatever is needed to clean up before the program exits, such as wiping
 * the screen, restoring the cursor, fixing the font, etc.  Often this function
 * does nothing and lets the operating system clean up when the program quits.
 */
static void Term_nuke_xxx(term *t)
{
	term_data *td = (term_data*)(t->data);

	/* XXX XXX XXX */
}



/*
 * Do a "user action" on the current "term"
 *
 * This function allows the visual module to do implementation defined
 * things when the user activates the "system defined command" command.
 *
 * This function is normally not used.
 *
 * In general, this function should return zero if the action is successfully
 * handled, and non-zero if the action is unknown or incorrectly handled.
 */
static errr Term_user_xxx(int n)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Unknown */
	return (1);
}


/*
 * Do a "special thing" to the current "term"
 *
 * This function must react to a large number of possible arguments, each
 * corresponding to a different "action request" by the "z-term.c" package,
 * or by the application itself.
 *
 * The "action type" is specified by the first argument, which must be a
 * constant of the form "TERM_XTRA_*" as given in "term.h", and the second
 * argument specifies the "information" for that argument, if any, and will
 * vary according to the first argument.
 *
 * In general, this function should return zero if the action is successfully
 * handled, and non-zero if the action is unknown or incorrectly handled.
 */
static errr Term_xtra_xxx(int n, int v)
{
	term_data *td = (term_data*)(Term->data);

	/* Analyze */
	switch (n)
	{
	case TERM_XTRA_EVENT:
		{
			/*
			 * Process some pending events XXX XXX XXX
			 *
			 * Wait for at least one event if "v" is non-zero
			 * otherwise, if no events are ready, return at once.
			 * When "keypress" events are encountered, the "ascii"
			 * value corresponding to the key should be sent to the
			 * "Term_keypress()" function.  Certain "bizarre" keys,
			 * such as function keys or arrow keys, may send special
			 * sequences of characters, such as control-underscore,
			 * plus letters corresponding to modifier keys, plus an
			 * underscore, plus carriage return, which can be used by
			 * the main program for "macro" triggers.  This action
			 * should handle as many events as is efficiently possible
			 * but is only required to handle a single event, and then
			 * only if one is ready or "v" is true.
			 *
			 * This action is required.
			 */

			return (0);
		}

	case TERM_XTRA_FLUSH:
		{
			/*
			 * Flush all pending events XXX XXX XXX
			 *
			 * This action should handle all events waiting on the
			 * queue, optionally discarding all "keypress" events,
			 * since they will be discarded anyway in "z-term.c".
			 *
			 * This action is required, but may not be "essential".
			 */

			return (0);
		}

	case TERM_XTRA_CLEAR:
		{
			/*
			 * Clear the entire window XXX XXX XXX
			 *
			 * This action should clear the entire window, and redraw
			 * any "borders" or other "graphic" aspects of the window.
			 *
			 * This action is required.
			 */

			return (0);
		}

	case TERM_XTRA_SHAPE:
		{
			/*
			 * Set the cursor visibility XXX XXX XXX
			 *
			 * This action should change the visibility of the cursor,
			 * if possible, to the requested value (0=off, 1=on)
			 *
			 * This action is optional, but can improve both the
			 * efficiency (and attractiveness) of the program.
			 */

			return (0);
		}

	case TERM_XTRA_FROSH:
		{
			/*
			 * Flush a row of output XXX XXX XXX
			 *
			 * This action should make sure that row "v" of the "output"
			 * to the window will actually appear on the window.
			 *
			 * This action is optional, assuming that "Term_text_xxx()"
			 * (and similar functions) draw directly to the screen, or
			 * that the "TERM_XTRA_FRESH" entry below takes care of any
			 * necessary flushing issues.
			 */

			return (0);
		}

	case TERM_XTRA_FRESH:
		{
			/*
			 * Flush output XXX XXX XXX
			 *
			 * This action should make sure that all "output" to the
			 * window will actually appear on the window.
			 *
			 * This action is optional, assuming that "Term_text_xxx()"
			 * (and similar functions) draw directly to the screen, or
			 * that the "TERM_XTRA_FROSH" entry above takes care of any
			 * necessary flushing issues.
			 */

			return (0);
		}

	case TERM_XTRA_NOISE:
		{
			/*
			 * Make a noise XXX XXX XXX
			 *
			 * This action should produce a "beep" noise.
			 *
			 * This action is optional, but convenient.
			 */

			return (0);
		}

	case TERM_XTRA_SOUND:
		{
			/*
			 * Make a sound XXX XXX XXX
			 *
			 * This action should produce sound number "v", where the
			 * "name" of that sound is "sound_names[v]".  This method
			 * is still under construction.
			 *
			 * This action is optional, and not very important.
			 */

			return (0);
		}

	case TERM_XTRA_BORED:
		{
			/*
			 * Handle random events when bored XXX XXX XXX
			 *
			 * This action is optional, and normally not important
			 */

			return (0);
		}

	case TERM_XTRA_REACT:
		{
			/*
			 * React to global changes XXX XXX XXX
			 *
			 * For example, this action can be used to react to
			 * changes in the global "color_table[256][4]" array.
			 *
			 * This action is optional, but can be very useful for
			 * handling "color changes" and the "arg_sound" and/or
			 * "arg_graphics" options.
			 */

			return (0);
		}

	case TERM_XTRA_ALIVE:
		{
			/*
			 * Change the "hard" level XXX XXX XXX
			 *
			 * This action is used if the program changes "aliveness"
			 * by being either "suspended" (v=0) or "resumed" (v=1)
			 * This action is optional, unless the computer uses the
			 * same "physical screen" for multiple programs, in which
			 * case this action should clean up to let other programs
			 * use the screen, or resume from such a cleaned up state.
			 *
			 * This action is currently only used by "main-gcu.c",
			 * on UNIX machines, to allow proper "suspending".
			 */

			return (0);
		}

	case TERM_XTRA_LEVEL:
		{
			/*
			 * Change the "soft" level XXX XXX XXX
			 *
			 * This action is used when the term window changes "activation"
			 * either by becoming "inactive" (v=0) or "active" (v=1)
			 *
			 * This action can be used to do things like activate the proper
			 * font / drawing mode for the newly active term window.  This
			 * action should NOT change which window has the "focus", which
			 * window is "raised", or anything like that.
			 *
			 * This action is optional if all the other things which depend
			 * on what term is active handle activation themself, or if only
			 * one "term_data" structure is supported by this file.
			 */

			return (0);
		}

	case TERM_XTRA_DELAY:
		{
			/*
			 * Delay for some milliseconds XXX XXX XXX
			 *
			 * This action is useful for proper "timing" of certain
			 * visual effects, such as breath attacks.
			 *
			 * This action is optional, but may be required by this file,
			 * especially if special "macro sequences" must be supported.
			 */

			return (0);
		}

	case TERM_XTRA_GET_DELAY:
		{
			/*
			                      * Get Delay of some milliseconds XXX XXX XXX
			                      * place the result in Term_xtra_long
			 *
			 * This action is useful for proper "timing" of certain
			 * visual effects, such as recording cmovies.
			 *
			                      * This action is optional, but cmovies wont perform
			                      * good without it
			 */

			return (0);
		}
	}

	/* Unknown or Unhandled action */
	return (1);
}


/*
 * Display the cursor
 *
 * This routine should display the cursor at the given location
 * (x,y) in some manner.  On some machines this involves actually
 * moving the physical cursor, on others it involves drawing a fake
 * cursor in some form of graphics mode.  Note the "soft_cursor"
 * flag which tells "z-term.c" to treat the "cursor" as a "visual"
 * thing and not as a "hardware" cursor.
 *
 * You may assume "valid" input if the window is properly sized.
 *
 * You may use the "Term_grab(x, y, &a, &c)" function, if needed,
 * to determine what attr/char should be "under" the new cursor,
 * for "inverting" purposes or whatever.
 */
static errr Term_curs_xxx(int x, int y)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Success */
	return (0);
}


/*
 * Erase some characters
 *
 * This function should erase "n" characters starting at (x,y).
 *
 * You may assume "valid" input if the window is properly sized.
 */
static errr Term_wipe_xxx(int x, int y, int n)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Success */
	return (0);
}


/*
 * Draw some text on the screen
 *
 * This function should actually display an array of characters
 * starting at the given location, using the given "attribute",
 * and using the given string of characters, which contains
 * exactly "n" characters and which is NOT null-terminated.
 *
 * You may assume "valid" input if the window is properly sized.
 *
 * You must be sure that the string, when written, erases anything
 * (including any visual cursor) that used to be where the text is
 * drawn.  On many machines this happens automatically, on others,
 * you must first call "Term_wipe_xxx()" to clear the area.
 *
 * In color environments, you should activate the color contained
 * in "color_data[a & 0x0F]", if needed, before drawing anything.
 *
 * You may ignore the "attribute" if you are only supporting a
 * monochrome environment, since this routine is normally never
 * called to display "black" (invisible) text, including the
 * default "spaces", and all other colors should be drawn in
 * the "normal" color in a monochrome environment.
 *
 * Note that if you have changed the "attr_blank" to something
 * which is not black, then this function must be able to draw
 * the resulting "blank" correctly.
 *
 * Note that this function must correctly handle "black" text if
 * the "always_text" flag is set, if this flag is not set, all the
 * "black" text will be handled by the "Term_wipe_xxx()" hook.
 */
static errr Term_text_xxx(int x, int y, int n, byte a, const char *cp)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Success */
	return (0);
}


/*
 * Draw some attr/char pairs on the screen
 *
 * This routine should display the given "n" attr/char pairs at
 * the given location (x,y).  This function is only used if one
 * of the flags "always_pict" or "higher_pict" is defined.
 *
 * You must be sure that the attr/char pairs, when displayed, will
 * erase anything (including any visual cursor) that used to be at
 * the given location.  On many machines this is automatic, but on
 * others, you must first call "Term_wipe_xxx(x, y, 1)".
 *
 * With the "higher_pict" flag, this function can be used to allow
 * the display of "pseudo-graphic" pictures, for example, by using
 * the attr/char pair as an encoded index into a pixmap of special
 * "pictures".
 *
 * With the "always_pict" flag, this function can be used to force
 * every attr/char pair to be drawn by this function, which can be
 * very useful if this file can optimize its own display calls.
 *
 * This function is often associated with the "arg_graphics" flag.
 *
 * This function is only used if one of the "higher_pict" and/or
 * "always_pict" flags are set.
 */
static errr Term_pict_xxx(int x, int y, int n, const byte *ap, const char *cp)
{
	term_data *td = (term_data*)(Term->data);

	/* XXX XXX XXX */

	/* Success */
	return (0);
}



/*** Internal Functions ***/


/*
 * Instantiate a "term_data" structure
 *
 * This is one way to prepare the "term_data" structures and to
 * "link" the various informational pieces together.
 *
 * This function assumes that every window should be 80x24 in size
 * (the standard size) and should be able to queue 256 characters.
 * Technically, only the "main screen window" needs to queue any
 * characters, but this method is simple.  One way to allow some
 * variation is to add fields to the "term_data" structure listing
 * parameters for that window, initialize them in the "init_xxx()"
 * function, and then use them in the code below.
 *
 * Note that "activation" calls the "Term_init_xxx()" hook for
 * the "term" structure, if needed.
 */
static void term_data_link(int i)
{
	term_data *td = &data[i];

	/* Initialize the term */
	term_init(td->t, 80, 24, 256);

	/* Choose "soft" or "hard" cursor XXX XXX XXX */
	/* A "soft" cursor must be explicitly "drawn" by the program */
	/* while a "hard" cursor has some "physical" existance and is */
	/* moved whenever text is drawn on the screen.  See "term.c". */
	/* td->t->soft_cursor = TRUE; */

	/* Avoid the "corner" of the window XXX XXX XXX */
	/* td->t->icky_corner = TRUE; */

	/* Use "Term_pict()" for all attr/char pairs XXX XXX XXX */
	/* See the "Term_pict_xxx()" function above. */
	/* td->t->always_pict = TRUE; */

	/* Use "Term_pict()" for some attr/char pairs XXX XXX XXX */
	/* See the "Term_pict_xxx()" function above. */
	/* td->t->higher_pict = TRUE; */

	/* Use "Term_text()" even for "black" text XXX XXX XXX */
	/* See the "Term_text_xxx()" function above. */
	/* td->t->always_text = TRUE; */

	/* Ignore the "TERM_XTRA_BORED" action XXX XXX XXX */
	/* This may make things slightly more efficient. */
	/* td->t->never_bored = TRUE; */

	/* Ignore the "TERM_XTRA_FROSH" action XXX XXX XXX */
	/* This may make things slightly more efficient. */
	/* td->t->never_frosh = TRUE; */

	/* Erase with "white space" XXX XXX XXX */
	/* td->t->attr_blank = TERM_WHITE; */
	/* td->t->char_blank = ' '; */

	/* Prepare the init/nuke hooks */
	td->t->init_hook = Term_init_xxx;
	td->t->nuke_hook = Term_nuke_xxx;

	/* Prepare the template hooks */
	td->t->user_hook = Term_user_xxx;
	td->t->xtra_hook = Term_xtra_xxx;
	td->t->curs_hook = Term_curs_xxx;
	td->t->wipe_hook = Term_wipe_xxx;
	td->t->text_hook = Term_text_xxx;
	td->t->pict_hook = Term_pict_xxx;

	/* Remember where we came from */
	td->t->data = (vptr)(td);

	/* Activate it */
	Term_activate(td->t);

	/* Global pointer */
	ang_term[i] = td->t;
}



/*
 * Initialization function
 */
errr init_xxx(void)
{
	/* Initialize globals XXX XXX XXX */

	/* Initialize "term_data" structures XXX XXX XXX */

	/* Create windows (backwards!) */
	for (i = TERM_DATA_MAX - 1; i >= 0; i--)
	{
		/* Link */
		term_data_link(i);
	}

	/* Success */
	return (0);
}


#ifdef INTERNAL_MAIN


/*
 * Some special machines need their own "main()" function, which they
 * can provide here, making sure NOT to compile the "main.c" file.
 *
 * These systems usually have some form of "event loop", run forever
 * as the last step of "main()", which handles things like menus and
 * window movement, and calls "play_game(FALSE)" to load a game after
 * initializing "savefile" to a filename, or "play_game(TRUE)" to make
 * a new game.  The event loop would also be triggered by "Term_xtra()"
 * (the TERM_XTRA_EVENT action), in which case the event loop would not
 * actually "loop", but would run once and return.
 */


/*
 * An event handler XXX XXX XXX
 *
 * You may need an event handler, which can be used by both
 * by the "TERM_XTRA_BORED" and "TERM_XTRA_EVENT" entries in
 * the "Term_xtra_xxx()" function, and also to wait for the
 * user to perform whatever user-interface operation is needed
 * to request the start of a new game or the loading of an old
 * game, both of which should launch the "play_game()" function.
 */
static bool CheckEvents(bool wait)
{
	/* XXX XXX XXX */

	return (0);
}


/*
 * Init some stuff
 *
 * This function is used to keep the "path" variable off the stack.
 */
static void init_stuff(void)
{
	char path[1024];

	/* Prepare the path XXX XXX XXX */
	/* This must in some way prepare the "path" variable */
	/* so that it points at the "lib" directory.  Every */
	/* machine handles this in a different way... */
	strcpy(path, "XXX XXX XXX");

	/* Prepare the filepaths */
	init_file_paths(path);
}


/*
 * Main function
 *
 * This function must do a lot of stuff.
 */
int main(int argc, char *argv[])
{
	/* Initialize the machine itself XXX XXX XXX */

	/* Process command line arguments XXX XXX XXX */

	/* Initialize the windows */
	if (init_xxx()) quit("Oops!");

	/* XXX XXX XXX */
	ANGBAND_SYS = "xxx";

	/* Initialize some stuff */
	init_stuff();

	/* Initialize */
	init_angband * /

	/* Allow auto-startup XXX XXX XXX */

	/* Event loop forever XXX XXX XXX */
	while (TRUE) CheckEvents(TRUE);
}


#endif /* INTERNAL_MAIN */


#endif /* USE_XXX */
tome-235-src/src/ENGLISH.txt0000644000076400017500000000210411012107763013304 0ustar  dgdg                         English Text Style

* Use British spelling in preference to American spelling. Quotations,
  however, should be left intact.

* Capitalize the name of spells and special powers as you would the
  title of a book.

* Avoid unnecessary modernisms.  This helps preserve the mood -- an
  item "allows", rather than "enables", you to do something.

* When describing a person possessing an item, use "its wielder" or
  "its wearer" in preference to "the wielder" or "the wearer".

* When describing a gendered person of indeterminate gender, use
  masculine terms.  "This icy sword increases its wielder's statistics
  and sustains his strength."

* Use the British Imperial system for measurements.  This means feet
  and inches, not meters and centimeters.


                           Specific Issues

* Use "hit points", not "hitpoints".

* Use "Long Sword", not "Long-sword" or "Longsword".

* Use "Middle-earth", not "middle-earth" or "Middle Earth".

* Use "staves", not "staffs".

* Use "dwarves", not "dwarfs".

-- markrax (Mark Schreiber) 
tome-235-src/src/files.c0000644000076400017500000043307211012107763012734 0ustar  dgdg/* File: files.c */

/* Purpose: code dealing with files (and death) */

/*
 * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
 *
 * This software may be copied and distributed for educational, research, and
 * not for profit purposes provided that this copyright and statement are
 * included in all such copies.
 */

#include "angband.h"


static bool setuid_grabbed = TRUE;


/*
 * You may or may not want to use the following "#undef".
 */
/* #undef _POSIX_SAVED_IDS */


/*
 * Hack -- drop permissions
 */
void safe_setuid_drop(void)
{
	if (setuid_grabbed)
	{
		setuid_grabbed = FALSE;
#ifdef SET_UID

# ifdef SAFE_SETUID

# ifdef SAFE_SETUID_POSIX

		if (setuid(getuid()) != 0)
		{
			quit("setuid(): cannot set permissions correctly!");
		}
		if (setgid(getgid()) != 0)
		{
			quit("setgid(): cannot set permissions correctly!");
		}

# else

		if (setreuid(geteuid(), getuid()) != 0)
		{
			quit("setreuid(): cannot set permissions correctly!");
		}
		if (setregid(getegid(), getgid()) != 0)
		{
			quit("setregid(): cannot set permissions correctly!");
		}

# endif

# endif

#endif
	}

}


/*
 * Hack -- grab permissions
 */
void safe_setuid_grab(void)
{
	if (!setuid_grabbed)
	{
		setuid_grabbed = TRUE;
#ifdef SET_UID

# ifdef SAFE_SETUID

# ifdef SAFE_SETUID_POSIX

		if (setuid(player_euid) != 0)
		{
			quit("setuid(): cannot set permissions correctly!");
		}
		if (setgid(player_egid) != 0)
		{
			quit("setgid(): cannot set permissions correctly!");
		}

# else

		if (setreuid(geteuid(), getuid()) != 0)
		{
			quit("setreuid(): cannot set permissions correctly!");
		}
		if (setregid(getegid(), getgid()) != 0)
		{
			quit("setregid(): cannot set permissions correctly!");
		}

# endif  /* SAFE_SETUID_POSIX */

# endif  /* SAFE_SETUID */

#endif /* SET_UID */
	}

}


/*
 * Extract the first few "tokens" from a buffer
 *
 * This function uses "colon" and "slash" and delim arg as the delimeter characters.
 *
 * We never extract more than "num" tokens.  The "last" token may include
 * "delimeter" characters, allowing the buffer to include a "string" token.
 *
 * We save pointers to the tokens in "tokens", and return the number found.
 *
 * Hack -- Attempt to handle the 'c' character formalism
 *
 * Hack -- An empty buffer, or a final delimeter, yields an "empty" token.
 *
 * Hack -- We will always extract at least one token
 */
s16b tokenize(char *buf, s16b num, char **tokens, char delim1, char delim2)
{
	int i = 0;

	char *s = buf;


	/* Process */
	while (i < num - 1)
	{
		char *t;

		/* Scan the string */
		for (t = s; *t; t++)
		{
			/* Found a delimiter */
			if ((*t == delim1) || (*t == delim2)) break;

			/* Handle single quotes */
			if (*t == '\'')
			{
				/* Advance */
				t++;

				/* Handle backslash */
				if (*t == '\\') t++;

				/* Require a character */
				if (!*t) break;

				/* Advance */
				t++;

				/* Hack -- Require a close quote */
				if (*t != '\'') *t = '\'';
			}

			/* Handle back-slash */
			if (*t == '\\') t++;
		}

		/* Nothing left */
		if (!*t) break;

		/* Nuke and advance */
		*t++ = '\0';

		/* Save the token */
		tokens[i++] = s;

		/* Advance */
		s = t;
	}

	/* Save the token */
	tokens[i++] = s;

	/* Number found */
	return (i);
}



/*
 * Parse a sub-file of the "extra info" (format shown below)
 *
 * Each "action" line has an "action symbol" in the first column,
 * followed by a colon, followed by some command specific info,
 * usually in the form of "tokens" separated by colons or slashes.
 *
 * Blank lines, lines starting with white space, and lines starting
 * with pound signs ("#") are ignored (as comments).
 *
 * Note the use of "tokenize()" to allow the use of both colons and
 * slashes as delimeters, while still allowing final tokens which
 * may contain any characters including "delimiters".
 *
 * Note the use of "strtol()" to allow all "integers" to be encoded
 * in decimal, hexidecimal, or octal form.
 *
 * Note that "monster zero" is used for the "player" attr/char, "object
 * zero" will be used for the "stack" attr/char, and "feature zero" is
 * used for the "nothing" attr/char.
 *
 * Parse another file recursively, see below for details
 *   %:
 *
 * Specify the attr/char values for "monsters" by race index
 *   R:::
 *
 * Specify the attr/char values for "objects" by kind index
 *   K:::
 *
 * Specify the attr/char values for "features" by feature index
 *   F:::
 *
 * Specify the attr/char values for "stores" by store index
 *   B:::
 *
 * Specify the attr/char values for unaware "objects" by kind tval
 *   U:::
 *
 * Specify the attr/char values for inventory "objects" by kind tval
 *   E:::
 *
 * Define a macro action, given an encoded macro action
 *   A:
 *
 * Create a normal macro, given an encoded macro trigger
 *   P:
 *
 * Create a command macro, given an encoded macro trigger
 *   C:
 *
 * Create a keyset mapping
 *   S:::
 *
 * Turn an option off, given its name
 *   X:
 *
 * Turn an option on, given its name
 *   Y:
 *
 * Specify visual information, given an index, and some data
 *   V:::::
 *
 * Specify squelch settings
 *   Q::
 */
errr process_pref_file_aux(char *buf)
{
	int i, j, n1, n2;

	char *zz[16];


	/* Skip "empty" lines */
	if (!buf[0]) return (0);

	/* Skip "blank" lines */
	if (isspace(buf[0])) return (0);

	/* Skip comments */
	if (buf[0] == '#') return (0);

	/* Require "?:*" format */
	if (buf[1] != ':') return (1);


	/* Process "%:" */
	if (buf[0] == '%')
	{
		/* Attempt to Process the given file */
		return (process_pref_file(buf + 2));
	}


	/* Process "R::/" -- attr/char for monster races */
	if (buf[0] == 'R')
	{
		if (tokenize(buf + 2, 3, zz, ':', '/') == 3)
		{
			monster_race *r_ptr;
			i = (huge)strtol(zz[0], NULL, 0);
			n1 = strtol(zz[1], NULL, 0);
			n2 = strtol(zz[2], NULL, 0);
			if (i >= max_r_idx) return (1);
			r_ptr = &r_info[i];
			if (n1) r_ptr->x_attr = n1;
			if (n2)
			{
				r_ptr->x_char = n2;
			}
			return (0);
		}
	}


	/* Process "G:::/" -- attr/char for overlay graphics */
	if (buf[0] == 'G')
	{
		/* Process "G:M::/" -- attr/char for ego monsters */
		if (buf[2] == 'M')
		{
			if (tokenize(buf + 4, 3, zz, ':', '/') == 3)
			{
				monster_ego *re_ptr;
				i = (huge)strtol(zz[0], NULL, 0);
				n1 = strtol(zz[1], NULL, 0);
				n2 = strtol(zz[2], NULL, 0);
				if (i >= max_re_idx) return (1);
				re_ptr = &re_info[i];
				if (n1) re_ptr->g_attr = n1;
				if (n2)
				{
					re_ptr->g_char = n2;
				}
				return (0);
			}
		}

		/* Process "G:P::/" -- attr/char for race modifiers */
		if (buf[2] == 'P')
		{
			if (tokenize(buf + 4, 3, zz, ':', '/') == 3)
			{
				player_race_mod *rmp_ptr;
				i = (huge)strtol(zz[0], NULL, 0);
				n1 = strtol(zz[1], NULL, 0);
				n2 = strtol(zz[2], NULL, 0);
				if (i >= max_rmp_idx) return (1);
				rmp_ptr = &race_mod_info[i];
				if (n1) rmp_ptr->g_attr = n1;
				if (n2)
				{
					rmp_ptr->g_char = n2;
				}
				return (0);
			}
		}

		/* Process "G:T::/" -- attr/char for traps */
		if (buf[2] == 'T')
		{
			if (tokenize(buf + 4, 3, zz, ':', '/') == 3)
			{
				trap_type *t_ptr;
				i = (huge)strtol(zz[0], NULL, 0);
				n1 = strtol(zz[1], NULL, 0);
				n2 = strtol(zz[2], NULL, 0);
				if (i >= max_t_idx) return (1);
				t_ptr = &t_info[i];
				if (n1) t_ptr->g_attr = n1;
				if (n2)
				{
					t_ptr->g_char = n2;
				}
				return (0);
			}
		}
	}


	/* Process "K::/"  -- attr/char for object kinds */
	else if (buf[0] == 'K')
	{
		if (tokenize(buf + 2, 3, zz, ':', '/') == 3)
		{
			object_kind *k_ptr;
			i = (huge)strtol(zz[0], NULL, 0);
			n1 = strtol(zz[1], NULL, 0);
			n2 = strtol(zz[2], NULL, 0);
			if (i >= max_k_idx) return (1);
			k_ptr = &k_info[i];
			if (n1) k_ptr->x_attr = n1;
			if (n2)
			{
				k_ptr->x_char = n2;
			}
			return (0);
		}
	}


	/* Process "F::/" -- attr/char for terrain features */
	else if (buf[0] == 'F')
	{
		if (tokenize(buf + 2, 3, zz, ':', '/') == 3)
		{
			feature_type *f_ptr;
			i = (huge)strtol(zz[0], NULL, 0);
			n1 = strtol(zz[1], NULL, 0);
			n2 = strtol(zz[2], NULL, 0);
			if (i >= max_f_idx) return (1);
			f_ptr = &f_info[i];
			if (n1) f_ptr->x_attr = n1;
			if (n2)
			{
				f_ptr->x_char = n2;
			}
			return (0);
		}
	}

	/* Process "B::/" -- attr/char for stores */
	else if (buf[0] == 'B')
	{
		if (tokenize(buf + 2, 3, zz, ':', '/') == 3)
		{
			store_info_type *st_ptr;
			i = (huge)strtol(zz[0], NULL, 0);
			n1 = strtol(zz[1], NULL, 0);
			n2 = strtol(zz[2], NULL, 0);
			if (i >= max_st_idx) return (1);
			st_ptr = &st_info[i];
			if (n1) st_ptr->x_attr = n1;
			if (n2) st_ptr->x_char = n2;
			return (0);
		}
	}

	/* Process "S::/" -- attr/char for special things */
	else if (buf[0] == 'S')
	{
		if (tokenize(buf + 2, 3, zz, ':', '/') == 3)
		{
			j = (byte)strtol(zz[0], NULL, 0);
			n1 = strtol(zz[1], NULL, 0);
			n2 = strtol(zz[2], NULL, 0);
			misc_to_attr[j] = n1;
			misc_to_char[j] = n2;
			return (0);
		}
	}

	/* Process "U::/" -- attr/char for unaware items */
	else if (buf[0] == 'U')
	{
		if (tokenize(buf + 2, 3, zz, ':', '/') == 3)
		{
			j = (huge)strtol(zz[0], NULL, 0);
			n1 = strtol(zz[1], NULL, 0);
			n2 = strtol(zz[2], NULL, 0);
			for (i = 1; i < max_k_idx; i++)
			{
				object_kind *k_ptr = &k_info[i];
				if (k_ptr->tval == j)
				{
					if (n1) k_ptr->d_attr = n1;
					if (n2) k_ptr->d_char = n2;
				}
			}
			return (0);
		}
	}


	/* Process "E::" -- attribute for inventory objects */
	else if (buf[0] == 'E')
	{
		if (tokenize(buf + 2, 2, zz, ':', '/') == 2)
		{
			j = (byte)strtol(zz[0], NULL, 0) % 128;
			n1 = strtol(zz[1], NULL, 0);
			if (n1) tval_to_attr[j] = n1;
			return (0);
		}
	}


	/* Process "A:" -- save an "action" for later */
	else if (buf[0] == 'A')
	{
		text_to_ascii(macro__buf, buf + 2);
		return (0);
	}

	/* Process "P:" -- normal macro */
	else if (buf[0] == 'P')
	{
		char tmp[1024];
		text_to_ascii(tmp, buf + 2);
		macro_add(tmp, macro__buf);
		return (0);
	}

	/* Process "L::: -- extended command macro */
	else if (buf[0] == 'L')
	{
		switch (tokenize(buf + 2, 3, zz, ':', 0))
		{
		case 3:
			cli_add(zz[0], zz[1], zz[2]);
			return 0;
		case 2:
			cli_add(zz[0], zz[1], 0);
			return 0;
		default:
			return 1;
		}
	}

	/* Process "C:" -- create keymap */
	else if (buf[0] == 'C')
	{
		int mode;

		char tmp[1024];

		if (tokenize(buf + 2, 2, zz, ':', '/') != 2) return (1);

		mode = strtol(zz[0], NULL, 0);
		if ((mode < 0) || (mode >= KEYMAP_MODES)) return (1);

		text_to_ascii(tmp, zz[1]);
		if (!tmp[0] || tmp[1]) return (1);
		i = (byte)(tmp[0]);

		string_free(keymap_act[mode][i]);

		keymap_act[mode][i] = string_make(macro__buf);

		return (0);
	}


	/* Process "V:::::" -- visual info */
	else if (buf[0] == 'V')
	{
		if (tokenize(buf + 2, 5, zz, ':', '/') == 5)
		{
			i = (byte)strtol(zz[0], NULL, 0);
			angband_color_table[i][0] = (byte)strtol(zz[1], NULL, 0);
			angband_color_table[i][1] = (byte)strtol(zz[2], NULL, 0);
			angband_color_table[i][2] = (byte)strtol(zz[3], NULL, 0);
			angband_color_table[i][3] = (byte)strtol(zz[4], NULL, 0);
			return (0);
		}
	}
	/* set macro trigger names and a template */
	/* Process "T:::" */
	/* Process "T: