diff --git a/Files b/Files index 26a2d0d0b..959393d8e 100644 --- a/Files +++ b/Files @@ -36,16 +36,16 @@ align.h amiconf.h artifact.h artilist.h attrib.h beconf.h botl.h color.h config.h config1.h context.h coord.h decl.h def_os2.h dgn_file.h display.h dlb.h dungeon.h engrave.h extern.h -flag.h func_tab.h global.h hack.h lev.h -lint.h mail.h mextra.h mfndpos.h micro.h -mkroom.h monattk.h mondata.h monflag.h monst.h -monsym.h ntconf.h obj.h objclass.h os2conf.h -patchlevel.h pcconf.h permonst.h prop.h qtext.h -quest.h rect.h region.h rm.h skills.h -sp_lev.h spell.h sys.h system.h tcap.h -timeout.h tosconf.h tradstdc.h trampoli.h trap.h -unixconf.h vision.h vmsconf.h wceconf.h winami.h -winprocs.h wintype.h you.h youprop.h +flag.h func_tab.h global.h hack.h integer.h +lev.h lint.h mail.h mextra.h mfndpos.h +micro.h mkroom.h monattk.h mondata.h monflag.h +monst.h monsym.h ntconf.h obj.h objclass.h +os2conf.h patchlevel.h pcconf.h permonst.h prop.h +qtext.h quest.h rect.h region.h rm.h +skills.h sp_lev.h spell.h sys.h system.h +tcap.h timeout.h tosconf.h tradstdc.h trampoli.h +trap.h unixconf.h vision.h vmsconf.h wceconf.h +winami.h winprocs.h wintype.h you.h youprop.h (file for tty versions) wintty.h (files for X versions) diff --git a/dat/rumors.tru b/dat/rumors.tru index e6c4a5747..bcd37d044 100644 --- a/dat/rumors.tru +++ b/dat/rumors.tru @@ -19,7 +19,7 @@ Afraid of your valuables being stolen? Carry more junk! Always be aware of the phase of the moon! Always sweep the floor before engraving important messages. Amulets of Yendor are hard to make. Even for a wand of wishing. -An elven cloak protects against magic. +An elven cloak is useful against magic. An umber hulk can be a confusing sight. As Crom is my witness, I'll never go hungry again! Asking about monsters may be very useful. diff --git a/dat/tribute b/dat/tribute index d841095d2..574edfd01 100644 --- a/dat/tribute +++ b/dat/tribute @@ -311,7 +311,7 @@ comfortable--" [The Colour of Magic, by Terry Pratchett] %e passage -# p. 228-229 (passage starts mid-paragraph) +# pp. 228-229 (passage starts mid-paragraph) %passage 14 [...] She was the Goddess Who Must Not Be Named; those who sought her never found her, yet she was known to come to the aid of those in greatest @@ -962,7 +962,7 @@ racehorse." [Mort, by Terry Pratchett] %e passage -# p. 139-140 (passage ends mid-sentence) +# pp. 139-140 (passage ends mid-sentence) %passage 7 "You don't know much about monarchy, do you?" said Keli. @@ -983,8 +983,8 @@ appeal to my better nature under this here crusty exterior," he added, [Mort, by Terry Pratchett] %e passage -# p. 159-160 (Death has come to an employment agency--a new concept in -# Ankh-Morpork--looking for a job) +# pp. 159-160 (Death has come to an employment agency--a new concept in +# Ankh-Morpork--looking for a job) %passage 9 "And what was your previous position?" @@ -1091,8 +1091,8 @@ MANY HAVE, said Death evenly. [Sourcery, by Terry Pratchett] %e passage -# p. 40-41 (text has 'the moment and the words' which is obviously a typo; -# it might have intended 'that' for 'and'; we just drop 'and') +# pp. 40-41 (text has 'the moment and the words' which is obviously a typo; +# it might have intended 'that' for 'and'; we just drop 'and') %passage 4 The thief, as will become apparent, was a special type of thief. This thief was an artist of theft. Other thieves merely stole everything that @@ -1117,10 +1117,10 @@ words were out of your mouth. [Sourcery, by Terry Pratchett] %e passage -# p. 63-64 ('Compleet', 'Majik', 'enterr', 'physycal', 'hys', 'bodie', -# 'Destinie', 'Deathe', 'werre', 'nowe', 'menne', 'Ende', -# 'Worlde', 'hadd', 'bee', 'goddes', 'ould', 'Apocralypse', -# 'legende', 'thee': all accurate; 'ould' may be a typo...) +# pp. 63-64 ('Compleet', 'Majik', 'enterr', 'physycal', 'hys', 'bodie', +# 'Destinie', 'Deathe', 'werre', 'nowe', 'menne', 'Ende', +# 'Worlde', 'hadd', 'bee', 'goddes', 'ould', 'Apocralypse', +# 'legende', 'thee': all accurate; 'ould' may be a typo...) %passage 5 It was deathly quiet in the Library. The books were no longer frantic. They'd passed through their fear and out into the calm waters of abject @@ -1150,7 +1150,7 @@ his head. [Sourcery, by Terry Pratchett] %e passage -# p. 71-72 +# pp. 71-72 %passage 6 The current Patrician, head of the extremely rich and powerful Vetinari family, was thin, tall and apparently as cold-blooded as a dead penguin. @@ -1211,7 +1211,7 @@ He looked down at his feet. [Sourcery, by Terry Pratchett] %e passage -# p. 141-142 (Rincewind and Nijel have just entered a harem) +# pp. 141-142 (Rincewind and Nijel have just entered a harem) %passage 9 Rincewind had eyes for none of this. [...] they were swamped by the considerably bigger flood of panic at the sight of four guards turning @@ -1235,7 +1235,7 @@ would never quite forget to the end of this life. [Sourcery, by Terry Pratchett] %e passage -# p. 198-199 +# pp. 198-199 %passage 10 The astro-philosophers of Krull once succeeded in proving conclusively that all places are one place and that the distance between them is an @@ -1936,8 +1936,8 @@ The orangutan threw a complex salute and swung away into the darkness. [Guards! Guards!, by Terry Pratchett] %e passage -# p. 299-300 + 325 (final part comes quite a bit later; Carrot is trying to -# alert oblivious Sergeant Colon that the dragon is coming) +# pp. 299-300 + 325 (final part comes quite a bit later; Carrot is trying to +# alert oblivious Sergeant Colon that the dragon is coming) %passage 14 "This is what it comes to!" muttered Colon. "Decent women can't walk down the street without being eaten! Right, you bastards, you're... you're @@ -2315,8 +2315,8 @@ said Victor. [Moving Pictures, by Terry Pratchett] %e passage -# p. 111-112 ('dis', 'ort', 'yore', 'finking', 'mayonnaisey', 'specialitay', -# 'de lar mayson' all accurate) +# pp. 111-112 ('dis', 'ort', 'yore', 'finking', 'mayonnaisey', 'specialitay', +# 'de lar mayson' all accurate) %passage 10 Borgle's commissary had decided to experiment with salads tonight. The nearest salad growing district was thirty slow miles away. @@ -2566,7 +2566,7 @@ He heard the voices stop. There was the sound of feet hurrying away. [Reaper Man, by Terry Pratchett] %e passage -# p. 81-82 (things have stopped dying because Death is no longer on the job) +# pp. 81-82 (things have stopped dying because Death is no longer on the job) %passage 10 Everything that exists, yearns to live. That's what the cycle of life is all about. That's the engine that drives the great biological pumps of @@ -2654,13 +2654,273 @@ Rush off, or course, But slowly. # # # -%title Witches Abroad (1) +%title Witches Abroad (14) +# p. 92 (ROC edition) %passage 1 Vampires have risen from the dead, the grave and the crypt, but have never managed it from the cat. [Witches Abroad, by Terry Pratchett] %e passage +# pp. 12-13 +%passage 2 +Desiderata Hollow was making her will. + +When Desiderata Hollow was a girl, her grandmother had given her four +important pieces of advice to guide her young footsteps on the unexpectedly +twisting pathway of life. + +They were: + +Never trust a dog with orange eyebrows, + +Always get the young man's name and address, + +Never get between two mirrors, + +And always wear completely clean underwear every day because you never knew +when you were going to be knocked down and killed by a runaway horse and if +people found you had unsatisfactory underwear on, you'd die of shame. + +And then Desiderata grew up to become a witch. And one of the minor +benefits of being a witch is that you know exactly when you're going to die +and can wear what underwear you like.(1) + +That had been eighty years earlier, when the idea of knowing exactly when +you were going to die had seemed quite attractive because secretly, of +course, you knew you were going to live forever. + +That was then. + +And this was now. + +Forever didn't seem to last as long these days as once it did. + +(1) Which explains a lot about witches. + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 64 (passage ends mid-paragraph) +%passage 3 +"You know," said Nanny, investigating the recesses of the basket, "whenever +I deals with dwarfs, the phrase 'Duck's arse' swims across my mind." + +"Mean little devils. You should see the prices they tries to charge me +when I takes my broom to be repaired," said Granny. + +"Yes, but you never pay," said Magrat. + +"That's not the point," said Granny Weatherwax. "They shouldn't be allowed +to charge that sort of money. That's thievin', that is." + +"I don't see how it can be thieving if you don't pay anyway," said Magrat. + +"I never pay for anything," said Granny. [...] + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 93 (passage is a footnote) +%passage 4 +Nanny Ogg sent a number of cards home to her family, not a single one of +which got back before she did. This is traditional, and happens everywhere +in the universe. + + [Witches Abroad, by Terry Pratchett] +%e passage +# pp. 118-119 (Magrat has been teaching herself martial arts via books) +%passage 5 +"Lobsang Dibbler says sometimes you have to lose in order to win," said +Magrat. + +"Sounds daft to me," said Nanny. "That's Yen Buddhism, is it?" + +"No. They're the ones who say you have to have lots of money to win," said +Magrat.(1) "In the Path of the Scorpion, the way to win is to lose every +fight except the last one. You use the enemy's strength against himself." + +"What, you get him to hit himself, sort of thing?" said Nanny. "Sounds +daft." + +(1) The Yen Buddhists are the richest religious sect in the universe. They +hold that the accumulation of money is a great evil and burden to the soul. +They therefore, regardless of personal hazard, see it as their unpleasant +duty to acquire as much as possible to reduce the risk to innocent people. + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 131 +%passage 6 +They had breakfast in a forest clearing. It was grilled pumpkin. The dwarf +bread was brought out for inspection. But it was miraculous, the dwarf +bread. No one ever went hungry when they had some dwarf bread to avoid. +You only had to look at it for a moment, and instantly you could think of +dozens of things you'd rather eat. Your boots for example. Mountains. Raw +sheep. Your own foot. + + [Witches Abroad, by Terry Pratchett] +%e passage +# pp. 194-195 ("he just" is accurate; cockerel == adolescent rooster) +%passage 7 +"This is Legba, a dark and dangerous spirit," said Mrs. Gogol. She leaned +closer and spoke out of the corner of her mouth. "Between you and me, he +just a big black cockerel. But you know how it is." + +"It pays to advertise," Nanny agreed. "This is Greebo. Between you and me, +he's a fiend from hell." + +"Well, he's a cat," said Mrs. Gogol, generously. "It's only to be expected." + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 218 +%passage 8 +"/And/ still a bit of the wedding cake," said the first coachman. "Ain't +you et that up yet?" + +"We have it every night," said the undercoachman. + +The shed shook with the ensuing laughter. It is a universal fact that any +innocent comment made by any recently married young member of any workforce +is an instant trigger for coarse merriment among his or her older and more +cynical colleagues. This happens even if everyone concerned has nine legs +and lives at the bottom of an ocean of ammonia on a huge cold planet. It's +just one of those things. + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 228 +%passage 9 +"You ought to be more adventurous, Granny," said Magrat. + +"I ain't against adventure, in moderation," said Granny, "but not when I'm +eatin'." + + [Witches Abroad, by Terry Pratchett] +%e passage +# pp. 263-264 (Nanny is trying to stop an elaborate clock; despite damage +# inflicted on it, it goes on to announce midnight [early]) +%passage 10 +Let's see thought Nanny. This bit is connected to that bit, this one turns, +that one turns /faster/, this spiky bit wobbles backwards and forwards... + +Oh, well. Just twist the first thing you can grab, as the High Priest said +to the vestal virgin.(1) + +Nanny Ogg spat on her hands, gripped the largest cog-wheel, and twisted. + +It carried on turning, pulling her with it. + +Blimey. Oh, well... + +Then she did was neither Granny Weatherwax nor Magrat would have dreamed of +doing in the circumstances. But Nanny Ogg's voyages on the sea of +intersexual dalliance had gone rather further than twice around the +lighthouse, and she saw nothing demeaning in getting a man to help her. + +She simpered at Casanunda. + +"Things would be a lot more comfortable in our little /pie-de-terre/ if you +could just push this little wheel around a bit," she said. "I'm sure /you/ +could manage it," she added. + +"Oh, no problem, good lady," said Casanunda. He reached up with one hand. +Dwarfs are immensely strong for their size. The wheel seemed to offer him +no resistance at all. + +Somewhere in the mechanism something resisted for a moment and then went +/clonk/. Big wheels turned reluctantly. Little wheels screamed on their +axles. A small important piece flew out and pinged off of Casanunda's +small bullet head. + +And, much faster than nature had ever intended, the hands sped around the +face. + +(1) This is the last line to a Discworld joke lost, alas, to posterity. + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 265 ('pate' has a couple of accent marks which can't be rendered in ascii) +%passage 11 +There are various forms of voodoo in the multiverse, because it's a +religion that can be put together from any ingredients that happen to be +lying around. And all of them try, in some way, to call a god into the body +of a human being. + +That was stupid, Mrs. Gogol thought. That was dangerous. + +Mrs. Gogol's voodoo worked the other way about. What was a god? A focus of +belief. If people believed, a god began to grow. Feebly at first, but if +the swamp taught anything, it taught patience. Anything could be the focus +of a god. A handful of feathers with a red ribbon around them, a hat and +coat on a couple of sticks... anything. Because when all people had was +practically nothing, then anything could be almost everything. And then you +fed it, and lulled it, like a goose heading for pate, and let the power grow +very slowly, and when the time was ripe you opened the path... backwards. +A human could ride the god, rather than the other way around. There would +be a price to pay later, but there always was. In Mrs. Gogol's experience, +everyone ended up dying. + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 270 (Greebo has been temporarily transformed--polymorphed?--into a human) +%passage 12 +Greebo wasn't a happy cat. [...] + +Then he'd smelled the kitchen. Cats gravitate to kitchens like rocks +gravitate to gravity. + + [Witches Abroad, by Terry Pratchett] +%e passage +# p. 282 (Casanunda the dwarf is Discworld's Casanova; he appears again in +# /Lords and Ladies/) +%passage 13 +"How come you're in the palace guard, Casanunda?" + +"Soldier of fortune takes whatever jobs are going, Mrs. Ogg," said Casanunda +earestly. + +"But all the rest of 'em are six foot tall and you're--of the shorter +persuasion." + +"I lied about my height, Mrs. Ogg. I'm a world-famous liar." + +"Is that true?" + +"No." + +"What about you being the world's greatest lover?" + +There was silence for a while. + +"Well, maybe I'm only No. 2," said Casanunda. "But I try harder." + + [Witches Abroad, by Terry Pratchett] +%e passage +# pp. 285-286 (Greebo is still in human form) +%passage 14 +Greebo leapt. + +Cats are like witches. They don't fight to kill, but to win. There is a +difference. There's no point in killing an opponent. That way, they won't +know they've lost, and to be a real winner you have to have an opponent who +is beaten and knows it. There's no triumph over a corpse, but a beaten +opponent, who will remain beaten every day for the remainder of their sad +and wretched life, is something to treasure. + +Cats do not, of course, rationise this far. They just like to send someone +limping off minus a tail and a few square inches of fur. + +Greebo's technique was unscientific and wouldn't have stood a chance against +any decent swordsmanship, but on his side was the fact that it is almost +impossible to develop decent swordsmanship when you seem to have run into a +food mixer that is biting your ear off. + +The witches watched with interest. + +"I think we can leave him now," said Nanny. "I think he's having fun." + + [Witches Abroad, by Terry Pratchett] +%e passage %e title # # @@ -5015,8 +5275,8 @@ comp-lic-ated documents." [Carpe Jugulum, by Terry Pratchett] %e passage -# p. 336-337 (the plot is driven by the actions of a family of vampyres -# who do mostly cooperate with each other) +# pp. 336-337 (the plot is driven by the actions of a family of vampyres +# who do mostly cooperate with each other) %passage 7 Vampires are not naturally cooperative creatures. It's not in their nature. Every other vampire is a rival for the next meal. In fact, the ideal @@ -5344,8 +5604,8 @@ man!" [Thief of Time, by Terry Pratchett] %e passage -# p. 74-75 (the novices didn't know that the little old man known as Sweeper -# is actually Lu-Tze; see passage 3 regarding Rule One) +# pp. 74-75 (the novices didn't know that the little old man known as Sweeper +# is actually Lu-Tze; see passage 3 regarding Rule One) %passage 4 One day a group of senior novices, for mischief, kicked over the little shrine that Lu-Tze kept beside his sleeping mat. @@ -6645,9 +6905,9 @@ Treason than met the eye. [Wintersmith, by Terry Pratchett] %e passage -# p. 53-54 (in Carpe Jugulum, most of the lore [for humans] about how to kill -# vampires had been written by long-lived/long-not-defunct vampires -# [meaning that it was deliberately full of inaccuracies...]) +# pp. 53-54 (in Carpe Jugulum, most of the lore [for humans] about how to kill +# vampires had been written by long-lived/long-not-defunct vampires +# [meaning that it was deliberately full of inaccuracies...]) %passage 6 It was in fact Miss Tick who had written /Witch Hunting for Dumb People/, and she made sure that copies of it found their way into those areas where @@ -6663,7 +6923,7 @@ even underwater. [Wintersmith, by Terry Pratchett] %e passage -# p. 55-56 +# pp. 55-56 %passage 7 Working quickly, she emptied her pockets and started a shamble. @@ -6728,8 +6988,8 @@ dark art. It was just so /hard/. [Wintersmith, by Terry Pratchett] %e passage -# p. 126-127 (passage starts mid-paragraph; -# witches know in advance when they're going to die) +# pp. 126-127 (passage starts mid-paragraph; +# witches know in advance when they're going to die) %passage 10 "[...] We shall hold the funeral tomorrow afternoon." @@ -6756,8 +7016,8 @@ witches is an "argument." [Wintersmith, by Terry Pratchett] %e passage -# p. 174-175 (passage starts mid-paragraph; last paragraph continues, but -# changes topic so abruptly Tiffany gasps; 'rumbustious' is accurate) +# pp. 174-175 (passage starts mid-paragraph; last paragraph continues, but +# changes topic so abruptly Tiffany gasps; 'rumbustious' is accurate) %passage 12 "[...] And now I shall tell you something vitally important. It is the secret of my long life." @@ -6813,7 +7073,7 @@ as good as she ought to be. [Wintersmith, by Terry Pratchett] %e passage -# p. 360-361 ('wurds' is accurate) +# pp. 360-361 ('wurds' is accurate) %passage 15 "An heroic effect, Mr. Anybody," said Granny. "The first thing a hero must conquer is his fear, and when it comes to fightin', the Nac Mac Feegle @@ -6824,7 +7084,7 @@ o' wurds!" [Wintersmith, by Terry Pratchett] %e passage -# p. 398-399 ("Chumsfanleigh" is pronounced "Chuffley") +# pp. 398-399 ("Chumsfanleigh" is pronounced "Chuffley") %passage 16 At the back of the Feegles' chalk pit, more chalk had been carved out of the wall to make a tunnel about five feet high and perhaps as long. @@ -7314,7 +7574,7 @@ pp'd at all. Incidentally, how loud were his screams?" [Unseen Academicals, by Terry Pratchett] %e passage -# p. 192-193 ('pants': underpants; 'football': soccer ;-) +# pp. 192-193 ('pants': underpants; 'football': soccer ;-) %passage 9 "You will arrange yourself into two teams, set up goals, and strive to win! No man will leave the field of play unless injured! The hands are not to @@ -8040,7 +8300,7 @@ IF YOU ASK ME, said Death, NOBODY COULD DO ANY BETTER THAN THAT... # Death Quotes are always one line, and '%e passage' can be omitted. # %section Death -%title Death Quotes (30) +%title Death Quotes (31) %passage 1 WHERE THE FIRST PRIMAL CELL WAS, THERE WAS I ALSO. WHERE MAN IS, THERE AM I. WHEN THE LAST LIFE CRAWLS UNDER FREEZING STARS, THERE WILL I BE. %e passage @@ -8145,6 +8405,10 @@ JUST BECAUSE SOMETHING IS A METAPHORE DOESN'T MEAN IT CAN'T BE REAL. # p. 334 %passage 30 I AM ALWAYS ALONE. BUT JUST NOW I WANT TO BE ALONE BY MYSELF. +# Witches Abroad, p. 298 (Death's explanation why he didn't come for zombie 12 +# years earlier: YOU STOPPED LIVING. YOU NEVER DIED.) +%passage 31 +I HAD AN APPOINTMENT WITH YOU TONIGHT. %e title %e section # diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index a6a39f441..aab1169f9 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,11 +1,11 @@ -.\" $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.191 $ $NHDT-Date: 1450306152 2015/12/16 22:49:12 $ +.\" $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.203 $ $NHDT-Date: 1456192371 2016/02/23 01:52:51 $ .ds h0 "NetHack Guidebook .ds h1 .ds h2 % .ds vr "NetHack 3.6 .ds f0 "\*(vr .ds f1 -.ds f2 "January 18, 2016 +.ds f2 "February 22, 2016 .\" labeled paragraph start (should be part of tmac.n, but I don't want to .\" make changes to that file) .\" .PS word @@ -26,7 +26,7 @@ .br \\h'|-\\n(PYu'\\$1\\h'|-\\n(PXu'\ -\ \\c \" back up, output the label, then . \" skip to width-of(" - ") before the -. \" normal indentation, output the " - " +. \" normal indentation, output the " - " . \" then attach the next line (the . \" text) without stopping (\c: nroff . \" section 4.2) @@ -62,29 +62,29 @@ Original version - Eric S. Raymond Preface - Version 3.6 .pg This version of the game is special in a particular way. Near the end of -the development of 3.6, one of the significant inspirations for many of the +the development of 3.6, one of the significant inspirations for many of the humorous and fun features found in the game, author \fITerry Pratchett\fP, passed away. We have dedicated this version of the game in his memory. .hn 1 Introduction .pg -Recently, you have begun to find yourself unfulfilled and distant -in your daily occupation. Strange dreams of prospecting, stealing, -crusading, and combat have haunted you in your sleep for many months, -but you aren't sure of the reason. You wonder whether you have in -fact been having those dreams all your life, and somehow managed to +Recently, you have begun to find yourself unfulfilled and distant +in your daily occupation. Strange dreams of prospecting, stealing, +crusading, and combat have haunted you in your sleep for many months, +but you aren't sure of the reason. You wonder whether you have in +fact been having those dreams all your life, and somehow managed to forget about them until now. Some nights you awaken suddenly -and cry out, terrified at the vivid recollection of the strange and -powerful creatures that seem to be lurking behind every corner of the -dungeon in your dream. Could these details haunting your dreams be real? -As each night passes, you feel the desire to enter the mysterious caverns -near the ruins grow stronger. Each morning, however, you quickly put -the idea out of your head as you recall the tales of those who entered -the caverns before you and did not return. Eventually you can resist -the yearning to seek out the fantastic place in your dreams no longer. -After all, when other adventurers came back this way after spending time -in the caverns, they usually seemed better off than when they passed -through the first time. And who was to say that all of those who did +and cry out, terrified at the vivid recollection of the strange and +powerful creatures that seem to be lurking behind every corner of the +dungeon in your dream. Could these details haunting your dreams be real? +As each night passes, you feel the desire to enter the mysterious caverns +near the ruins grow stronger. Each morning, however, you quickly put +the idea out of your head as you recall the tales of those who entered +the caverns before you and did not return. Eventually you can resist +the yearning to seek out the fantastic place in your dreams no longer. +After all, when other adventurers came back this way after spending time +in the caverns, they usually seemed better off than when they passed +through the first time. And who was to say that all of those who did not return had not just kept going? .pg @@ -93,23 +93,23 @@ which, if you can find it, will bring you great wealth. One legend you were told even mentioned that the one who finds the amulet will be granted immortality by the gods. The amulet is rumored to be somewhere beyond the Valley of Gehennom, deep within the Mazes of Menace. Upon hearing the -legends, you immediately realize that there is some profound and -undiscovered reason that you are to descend into the caverns and seek -out that amulet of which they spoke. Even if the rumors of the amulet's -powers are untrue, you decide that you should at least be able to sell the -tales of your adventures to the local minstrels for a tidy sum, especially -if you encounter any of the terrifying and magical creatures of -your dreams along the way. You spend one last night fortifying yourself -at the local inn, becoming more and more depressed as you watch the odds -of your success being posted on the inn's walls getting lower and lower. +legends, you immediately realize that there is some profound and +undiscovered reason that you are to descend into the caverns and seek +out that amulet of which they spoke. Even if the rumors of the amulet's +powers are untrue, you decide that you should at least be able to sell the +tales of your adventures to the local minstrels for a tidy sum, especially +if you encounter any of the terrifying and magical creatures of +your dreams along the way. You spend one last night fortifying yourself +at the local inn, becoming more and more depressed as you watch the odds +of your success being posted on the inn's walls getting lower and lower. .pg - In the morning you awake, collect your belongings, and -set off for the dungeon. After several days of uneventful -travel, you see the ancient ruins that mark the entrance to the -Mazes of Menace. It is late at night, so you make camp at the entrance -and spend the night sleeping under the open skies. In the morning, you -gather your gear, eat what may be your last meal outside, and enter the + In the morning you awake, collect your belongings, and +set off for the dungeon. After several days of uneventful +travel, you see the ancient ruins that mark the entrance to the +Mazes of Menace. It is late at night, so you make camp at the entrance +and spend the night sleeping under the open skies. In the morning, you +gather your gear, eat what may be your last meal outside, and enter the dungeon... .hn 1 @@ -295,6 +295,9 @@ do other tasks requiring agility or manipulation of objects. .lp Constitution Constitution affects your ability to recover from injuries and other strains on your stamina. +When strength is low or modest, consitution also affects how much you +can carry. With sufficiently high strength, the contribution to +carrying capacity from your constitution no longer matters. .lp Intelligence Intelligence affects your ability to cast spells and read spellbooks. .lp Wisdom @@ -331,7 +334,7 @@ amount available. .lp "Armor Class A measure of how effectively your armor stops blows from unfriendly creatures. The lower this number is, the more effective the armor; it -is quite possible to have negative armor class. +is quite possible to have negative armor class. .lp Experience Your current experience level and experience points. As you adventure, you gain experience points. At certain experience point @@ -547,6 +550,8 @@ a monster there, you will fight the monster instead. Only these one-step movement commands cause you to fight monsters; the others (below) are ``safe.'' .sd +.\" note: the two number pad layouts are separated by a tab on each line; +.\" converting those tabs to spaces will screw up the formatting .TS S center; c c. @@ -582,8 +587,8 @@ is computed over map locations the hero knows about (e.g. seen or previously traversed). If there is no known path, a guess is made instead. Stops on most of the same conditions as the `G' command, but without picking up -objects, similar to the `M' command. For ports with mouse -support, the command is also invoked when a mouse-click takes place on a +objects, similar to the `M' command. For ports with mouse +support, the command is also invoked when a mouse-click takes place on a location other than the current position. .lp . Rest, do nothing for one turn. @@ -592,7 +597,7 @@ Apply (use) a tool (pick-axe, key, lamp...). .lp A Remove one or more worn items, such as armor. .lp "" -Use `T' (take off) to take off only one piece of armor +Use `T' (take off) to take off only one piece of armor or `R' (remove) to take off only one accessory. .lp ^A Redo the previous command. @@ -615,7 +620,7 @@ In answer to the question .lp "" ``What kinds of things do you want to drop? [!%= BUCXaium]'' .lp "" -you should type zero or more object symbols possibly followed by +you should type zero or more object symbols possibly followed by `a' and/or `i' and/or `u' and/or `m'. In addition, one or more of the blessed/uncursed/cursed groups may be typed. .sd @@ -641,7 +646,7 @@ Eat food. Engrave a message on the floor. .sd .si -E- - write in the dust with your fingers. +E- - write in the dust with your fingers. .ei .ed .lp "" @@ -912,7 +917,7 @@ Jump to another location. .lp #kick Kick something. .lp #loot -Loot a box or bag on the floor beneath you, or the saddle +Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. .lp #monster Use a monster's special ability (when polymorphed into monster form). @@ -1055,7 +1060,7 @@ Jump to another location. Same as ``#jump'' or ``M-j''. .lp k Kick something (usually a door). Same as `^D'. .lp l -Loot a box or bag on the floor beneath you, or the saddle +Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. Same as ``#loot'' or ``M-l''. .lp N Name a monster, an individual object, or a type of object. Same @@ -1068,7 +1073,7 @@ Untrap a trap, door, or chest. Same as ``#untrap'' or ``M-u''. Rooms and corridors .pg Rooms and corridors in the dungeon are either lit or dark. -Any lit areas within your line of sight will be displayed; +Any lit areas within your line of sight will be displayed; dark areas are only displayed if they are within one space of you. Walls and corridors remain on the map as you explore them. .pg @@ -1226,7 +1231,7 @@ you attack them. Some of them are very dangerous when angered. Remember: discretion is the better part of valor. .pg In most circumstances, if you attempt to attack a peaceful monster by -moving into its location, you'll be asked to confirm your intent. By +moving into its location, you'll be asked to confirm your intent. By default an answer of 'y' acknowledges that intent, which can be error prone if you're using 'y' to move. You can set the .op paranoid_confirmation @@ -1267,11 +1272,11 @@ Steeds .pg Some types of creatures in the dungeon can actually be ridden if you have the right equipment and skill. Convincing a wild beast to let -you saddle it up is difficult to say the least. Many a dungeoneer +you saddle it up is difficult to say the least. Many a dungeoneer has had to resort to magic and wizardry in order to forge the alliance. -Once you do have the beast under your control however, you can +Once you do have the beast under your control however, you can easily climb in and out of the saddle with the `#ride' command. Lead -the beast around the dungeon when riding, in the same manner as +the beast around the dungeon when riding, in the same manner as you would move yourself. It is the beast that you will see displayed on the map. .pg @@ -1289,7 +1294,7 @@ former player; it is probably still lurking around, gloating over its last victory. .hn 1 -Objects +Objects .pg When you find something in the dungeon, it is common to want to pick it up. In NetHack, this is accomplished automatically by walking over @@ -1298,7 +1303,7 @@ the object (unless you turn off the option (see below), or move with the `m' prefix (see above)), or manually by using the `,' command. .pg -If you're carrying too many items, NetHack will tell you so and you won't +If you're carrying too many items, NetHack will tell you so and you won't be able to pick up anything more. Otherwise, it will add the object(s) to your pack and tell you what you just picked up. @@ -1306,7 +1311,8 @@ you what you just picked up. As you add items to your inventory, you also add the weight of that object to your load. The amount that you can carry depends on your strength and your constitution. The -stronger you are, the less the additional load will affect you. There comes +stronger and sturdier +you are, the less the additional load will affect you. There comes a point, though, when the weight of all of that stuff you are carrying around with you through the dungeon will encumber you. Your reactions will get slower and you'll burn calories faster, requiring food more frequently @@ -1523,7 +1529,7 @@ To wield two weapons, you need to use the ``#twoweapon'' command. But first you need to have a weapon in each hand. (Note that your two weapons are not fully equal; the one in the hand you normally wield with is considered primary and the other -one is considered secondary. The most noticeable difference is +one is considered secondary. The most noticeable difference is after you stop--or before you begin, for that matter--wielding two weapons at once. The primary is your wielded weapon and the secondary is just an item in your inventory that's been designated @@ -1577,6 +1583,7 @@ elven mithril-coat 5 chain mail 5 orcish chain mail 6 scale mail 6 +dragon scales 7 studded leather armor 7 ring mail 7 orcish ring mail 8 @@ -1672,10 +1679,12 @@ The command to drink a potion is `q' (quaff). .hn 2 Wands (`/') .pg -Magic wands usually have multiple magical charges. Some wands are -directional\(emyou must give a direction in which to zap them. You can also +Wands usually have multiple magical charges. +Some types of wands require a direction in which to zap them. +You can also zap them at yourself (just give a `.' or `s' for the direction). Be warned, -however, for this is often unwise. Other wands are nondirectional\(emthey +however, for this is often unwise. +Other types of wands don't require a direction. The number of charges in a wand is random and decreases by one whenever you use it. .pg @@ -1711,7 +1720,7 @@ Putting on a ring activates its magic. You can wear only two rings, one on each ring finger. .pg Most rings also cause you to grow hungry more rapidly, the rate -varying with the type of ring. +varying with the type of ring. .pg The commands to use rings are `P' (put on) and `R' (remove). .hn 2 @@ -1731,16 +1740,18 @@ energy and the time required in casting. .pg Casting a spell calls forth magical energies and focuses them with your naked mind. Some of the magical energy released comes from within -you, and casting several spells in a row may tire you. +you. +Casting temporarily drains your magical power, which will slowly be +recovered, and causes you to need additional food. Casting of spells also requires practice. With practice, your skill in each category of spell casting will improve. Over time, however, your memory of each spell will dim, and you will need to relearn it. .pg -Some spells are -directional\(emyou must give a direction in which to cast them. You can also -cast them at yourself (just give a `.' or `s' for the direction). Be warned, -however, for this is often unwise. Other spells are nondirectional\(emthey -don't require a direction. +Some spells require a direction in which to cast them, similar to wands. +To cast one at yourself, just give a `.' or `s' for the direction. +A few spells require you to pick a target location rather than just specify +a particular direction. +Other spells don't require any direction or target. .pg Just as weapons are divided into groups in which a character can become proficient (to varying degrees), spells are similarly grouped. @@ -1816,6 +1827,9 @@ heavy. It is rumored that some statues are not what they seem. .pg Very large humanoids (giants and their ilk) have been known to use boulders as weapons. +.pg +For some configurations of the program, statues are no longer shown as `\`' +but by the letter representing the monster they depict instead. .hn 2 Gold (`$') .pg @@ -1955,7 +1969,7 @@ Using the NETHACKOPTIONS environment variable The NETHACKOPTIONS variable is a comma-separated list of initial values for the various options. Some can only be turned on or off. You turn one of these on by adding the name of the option to the list, -and turn it off by typing a `!' or ``no'' before the name. Others take a +and turn it off by typing a `!' or ``no'' before the name. Others take a character string as a value. You can set string options by typing the option name, a colon or equals sign, and then the value of the string. The value is terminated by the next comma or the end of string. @@ -1980,15 +1994,16 @@ Any line in the configuration file starting with ``OPTIONS='' may be filled out with options in the same syntax as in NETHACKOPTIONS. Any line starting with ``SYMBOLS='' is taken as defining the corresponding symbol -in a different syntax, a sequence of decimal numbers giving -the character position in the current font to be used in displaying -each entry. Such a sequence can be continued to multiple lines by putting a `\e' +in a different syntax, a sequence of decimal numbers giving +the character position in the current font to be used in displaying +each entry. Such a sequence can be continued to multiple lines by +putting a `\e' at the end of each line to be continued. .pg Any line starting with ``AUTOPICKUP_EXCEPTION='' is taken -as defining an exception to the +as defining an exception to the .op pickup_types -option. +option. There is a section of this Guidebook that discusses that. .pg The default name of the configuration file varies on different @@ -2031,7 +2046,7 @@ Persistent. Your starting alignment (align:lawful, align:neutral, or align:chaotic). You may specify just the first letter. The default is to randomly pick an appropriate alignment. -If you prefix a `!' or ``no'' to the value, you can +If you prefix the value with `!' or ``no'', you will exclude that alignment from being picked randomly. Cannot be set with the `O' command. Persistent. .lp autodescribe @@ -2059,34 +2074,39 @@ into account the blessed/cursed status, enchantment, damage, or quality of the weapon; you are free to manually fill your quiver or quiver sack or make ready with the `Q' command instead. If no weapon is found or the option is -false, the `t' (throw) command is executed instead. Persistent. (default false) +false, the `t' (throw) command is executed instead. +Persistent. (default false) .lp blind Start the character permanently blind. Persistent. (default false) .lp bones Allow saving and loading bones files. Persistent. (default true) .lp boulder -Set the character used to display boulders (default is rock class symbol). +Set the character used to display boulders (default is the ``large rock'' +class symbol, `\`'). .lp catname Name your starting cat (ex. ``catname:Morris''). Cannot be set with the `O' command. .lp character -Pick your type of character (ex. ``character:Monk''); -synonym for ``role''. See ``name'' for an alternate method -of specifying your role. Normally only the first letter of -the value is examined; the string ``random'' is an exception. +Synonym for ``role'' to pick the type of your character +(ex. ``character:Monk''). +See +.op role +for more details. .lp checkpoint Save game state after each level change, for possible recovery after program crash (default on). Persistent. .lp checkspace Check free disk space before writing files to disk (default on). You may have to turn this off if you have more than 2 GB free space -on the partition used for your save and level files. +on the partition used for your save and level files +(because too much space might overflow the calculation and end up +looking like insufficient space). Only applies when MFLOPPY was defined during compilation. .lp clicklook Allows looking at things on the screen by navigating the mouse over them and clicking the right mouse button (default off). .lp cmdassist -Have the game provide some additional command assistance for +Have the game provide some additional command assistance for new players if it detects some anticipated mistakes (default on). .lp "confirm " Have user confirm attacks on pets, shopkeepers, and other @@ -2144,7 +2164,7 @@ Cannot be set with the `O' command. .lp extmenu Changes the extended commands interface to pop-up a menu of available commands. It is keystroke compatible with the traditional interface except that it does -not require that you hit Enter. It is implemented only by the tty port +not require that you hit Enter. It is implemented only by the tty port (default off), when the game has been compiled to support tty graphics. .lp female An obsolete synonym for ``gender:female''. @@ -2165,7 +2185,7 @@ You may specify just the first letter. Although you can still denote your gender using the ``male'' and ``female'' options, the ``gender'' option will take precedence. The default is to randomly pick an appropriate gender. -If you prefix a `!' or ``no'' to the value, you can +If you prefix the value with `!' or ``no'', you will exclude that gender from being picked randomly. Cannot be set with the `O' command. Persistent. .lp "help " @@ -2269,7 +2289,7 @@ the object symbols act as menu accelerators (default off). Do not clear the screen before drawing menus, and align menus to the right edge of the screen. Only for the tty port. (default on) -.lp menu_previous_page +.lp menu_previous_page Menu character accelerator to goto the previous menu page. Implemented by the Amiga, Gem and tty ports. Default '<'. @@ -2412,7 +2432,7 @@ or match an autopickup exception. Default is on. Persistent. .lp pickup_types Specify the object types to be picked up when .op autopickup -is on. Default is all types. You can use +is on. Default is all types. You can use .op autopickup_exception configuration file lines to further refine .op autopickup @@ -2440,7 +2460,7 @@ Likewise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. .lp "race " Selects your race (for example, ``race:human''). Default is random. -If you prefix a `!' or ``no'' to the value, you can +If you prefix the value with `!' or ``no'', you will exclude that race from being picked randomly. Cannot be set with the `O' command. Persistent. .lp rest_on_space @@ -2451,13 +2471,15 @@ Pick your type of character (ex. ``role:Samurai''); synonym for ``character''. See ``name'' for an alternate method of specifying your role. Normally only the first letter of the value is examined; `r' is an exception with ``Rogue'', ``Ranger'', -and ``random'' values. If you prefix a `!' or ``no'' to the value, you can -exclude that role from being picked randomly. Persistent. +and ``random'' values. +If you prefix the value with `!' or ``no'', you will +exclude that role from being picked randomly. +Cannot be set with the `O' command. Persistent. .lp roguesymset This option may be used to select one of the named symbol sets found within ``symbols'' to alter the symbols displayed on the screen on the rogue level. .lp rlecomp -When writing out a save file, perform run length compression of the map. +When writing out a save file, perform run length compression of the map. Not all ports support run length compression. It has no effect on reading an existing save file. .lp runmode @@ -2476,7 +2498,7 @@ update the map after each step; like walk, but pause briefly after each step. .PE This option only affects the game's screen display, not the actual -results of moving. The default is `run'; versions prior to 3.4.1 +results of moving. The default is `run'; versions prior to 3.4.1 used `teleport' only. Whether or not the effect is noticeable will depend upon the window port used or on the type of terminal. Persistent. .lp safe_pet @@ -2525,11 +2547,11 @@ Enable coloring of status fields (default off). See ``Configuring Status Hilites'' for futher information. .lp suppress_alert This option may be set to a NetHack version level to suppress -alert notification messages about feature changes for that +alert notification messages about feature changes for that and prior versions (ex. ``suppress_alert:3.3.1''). .lp symset This option may be used to select one of the named symbol sets found within -``symbols'' to alter the symbols displayed on the screen. +``symbols'' to alter the symbols displayed on the screen. Use ``symset:default'' to explicitly select the default symbols. .lp "time " Show the elapsed game time in turns on bottom line (default off). Persistent. @@ -2578,8 +2600,8 @@ Select which windowing system to use, such as ``tty'' or ``X11'' (default depends on version). Cannot be set with the `O' command. .lp zerocomp -When writing out a save file, perform zero-comp compression of the -contents. Not all ports support zero-comp compression. It has no effect +When writing out a save file, perform zero-comp compression of the +contents. Not all ports support zero-comp compression. It has no effect on reading an existing save file. .hn 2 Window Port Customization options @@ -2603,44 +2625,44 @@ Where to align or place the message window (top, bottom, left, or right) Where to align or place the status window (top, bottom, left, or right). .lp ascii_map NetHack should display an ascii character map if it can. -.lp color -NetHack should display color if it can for different monsters, +.lp color +NetHack should display color if it can for different monsters, objects, and dungeon features -.lp eight_bit_tty +.lp eight_bit_tty NetHack should pass eight-bit character values (for example, specified with the .op traps option) straight through to your terminal (default off). -.lp font_map +.lp font_map NetHack should use a font by the chosen name for the map window. -.lp font_menu +.lp font_menu NetHack should use a font by the chosen name for menu windows. -.lp font_message +.lp font_message NetHack should use a font by the chosen name for the message window. -.lp font_status +.lp font_status NetHack should use a font by the chosen name for the status window. -.lp font_text +.lp font_text NetHack should use a font by the chosen name for text windows. -.lp font_size_map +.lp font_size_map NetHack should use this size font for the map window. -.lp font_size_menu +.lp font_size_menu NetHack should use this size font for menu windows. -.lp font_size_message +.lp font_size_message NetHack should use this size font for the message window. .lp font_size_status NetHack should use this size font for the status window. -.lp font_size_text +.lp font_size_text NetHack should use this size font for text windows. .lp fullscreen NetHack should try and display on the entire screen rather than in a window. -.lp large_font +.lp large_font NetHack should use a large font. -.lp map_mode +.lp map_mode NetHack should display the map in the manner specified. .lp mouse_support Allow use of the mouse for input and travel. .lp player_selection NetHack should pop up dialog boxes, or use prompts for character selection. -.lp popup_dialog +.lp popup_dialog NetHack should pop up dialog boxes for input. .lp preload_tiles NetHack should preload tiles into memory. @@ -2661,7 +2683,7 @@ choose from at game startup, if it can. Not all ports support this option. Display an onscreen keyboard. Handhelds are most likely to support this option. .lp splash_screen NetHack should display an opening splash screen when it starts up (default yes). -.lp tiled_map +.lp tiled_map NetHack should display a tiled map if it can. .lp tile_file Specify the name of an alternative tile file to override the default. @@ -2680,12 +2702,12 @@ the message window. NetHack should display windows with the specified foreground/background colors if it can. .lp wraptext -NetHack port should wrap long lines of text if they don't fit in +NetHack port should wrap long lines of text if they don't fit in the visible area of the window. .hn 2 Platform-specific Customization options .pg -Here are explanations of options that are used by specific platforms or ports +Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. .lp altkeyhandler Select an alternate keystroke handler dll to load (Win32 tty NetHack only). @@ -2740,7 +2762,7 @@ Cannot be set with the `O' command. Set the video mode used (PC NetHack only). Values are `autodetect', `default', or `vga'. Setting `vga' (or `autodetect' with vga hardware present) will cause -the game to display tiles. +the game to display tiles. Cannot be set with the `O' command. .lp videocolors Set the color palette for PC systems using NO_TERMS @@ -2769,17 +2791,17 @@ Configuring Autopickup Exceptions .pg You can further refine the behavior of the .op autopickup -option beyond what is available through the +option beyond what is available through the .op pickup_types -option. +option. .pg -By placing +By placing .op autopickup_exception lines in your configuration file, you can define patterns to be checked when the game is about to autopickup something. .lp autopickup_exception -Sets an exception to the +Sets an exception to the .op pickup_types option. The @@ -2788,7 +2810,7 @@ option should be followed by a regular expression to be used as a pattern to match against the singular form of the description of an object at your location. .lp "" -In addition, some characters are treated specially if they occur as the first +In addition, some characters are treated specially if they occur as the first character in the pattern, specifically: .sd .si @@ -2918,7 +2940,7 @@ displayed with the ``uncursed'' description. .hn 2 Configuring User Sounds .pg -Some platforms allow you to define sound files to be played when a message +Some platforms allow you to define sound files to be played when a message that matches a user-defined pattern is delivered to the message window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. @@ -2947,7 +2969,7 @@ The pattern should be a POSIX extended regular expression. Configuring Status Hilites .pg Your copy of NetHack may have been compiled with support for ``Status Hilites''. -If so, you can customize your game display by setting thresholds to +If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. .pg For example, the following line in your config file will cause @@ -2993,7 +3015,7 @@ config file. The whole feature can be disabled by setting option statushilites off. .pg .hn 2 -Modifying NetHack Symbols +Modifying NetHack Symbols .pg NetHack can load entire symbol sets from the symbol file. .pg @@ -3218,18 +3240,18 @@ overall location of items on the screen. .pg While it is not difficult for experienced users to edit the \fBdefaults.nh\fP file to accomplish this, novices may find this task somewhat daunting. -Included within the ``symbols'' file of all official distributions of NetHack +Included within the ``symbols'' file of all official distributions of NetHack is a symset called \fBNHAccess\fP. Selecting that symset in your -configuration file will cause the game to run in a manner accessible -to the blind. After you have gained some experience with the game -and with editing files, you may want to alter settings via \fBSYMBOLS=\fP -in your configuration file to better suit your preferences. +configuration file will cause the game to run in a manner accessible +to the blind. After you have gained some experience with the game +and with editing files, you may want to alter settings via \fBSYMBOLS=\fP +in your configuration file to better suit your preferences. The most crucial settings to make the game accessible are: .pg .lp symset:NHAccess Load a symbol set appropriate for use by blind players. .lp roguesymset:NHAccess -Load a symbol set for the rogue level that is appropriate for +Load a symbol set for the rogue level that is appropriate for use by blind players. .lp menustyle:traditional This will assist in the interface to speech synthesizers. @@ -3249,59 +3271,55 @@ The options recognized in this file are listed below. Any option not set uses a compiled-in default (which may not be appropriate for your system). .pg +.\" '\ =\ Word' follow each option name with space+equals+space+first +.\" word of sentence in a way that won't have spaces inserted +.\" there if that line is padded from left to right; +.\" essentially, "OPTION = Word" becomes one token as far +.\" as filling and justifying are concerned .lp -WIZARDS -A space-separated list of user names who are allowed to play in wizard +WIZARDS\ =\ A space-separated list of user names who are allowed to +play in wizard mode (the debugging mode, not the magic-using role). A value of a single asterisk (*) allows anyone to start a game in wizard mode. .lp -SHELLERS -A list of users who are allowed to use the shell escape command (!). The +SHELLERS\ =\ A list of users who are allowed to use the shell +escape command (!). The syntax is the same as WIZARDS. +.lp +EXPLORERS\ =\ A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. .lp -EXPLORERS -A list of users who are allowed to use the explore mode. The -syntax is the same as WIZARDS. +MAXPLAYERS\ =\ Limit the maximum number of games that can be running +at the same time. .lp -MAXPLAYERS -Limit the maximum number of games that can be running at the same time. +SUPPORT\ =\ A string explaining how to get local support (no default value). .lp -SUPPORT -A string explaining how to get local support (no default value). +RECOVER\ =\ A string explaining how to recover a game on this system +(no default value). .lp -RECOVER -A string explaining how to recover a game on this system (no default value). +SEDUCE\ =\ 0 or 1 to disable or enable, respectively, the SEDUCE option. +When disabled, incubi and succubi behave like nymphs. .lp -SEDUCE -0 or 1 to disable or enable, respectively, the SEDUCE option (see the source -for details on this function). +CHECK_PLNAME\ =\ Setting this to 1 will make the EXPLORERS, WIZARDS, and +SHELLERS check for the player name instead of the user's login name. .lp -CHECK_PLNAME -Setting this to 1 will make the EXPLORERS, WIZARDS, and SHELLERS check -for the player name instead of the user's login name. -.lp -CHECK_SAVE_UID -0 or 1 to disable or enable, respectively, the UID checking for savefiles. +CHECK_SAVE_UID\ =\ 0 or 1 to disable or enable, respectively, the UID +(used identification number) checking for save files (to verify that the +user who is restoring is the same one who saved). .pg The following options affect the score file: .pg .lp -PERSMAX -Maximum number of entries for one person. +PERSMAX\ =\ Maximum number of entries for one person. .lp -ENTRYMAX -Maximum number of entries in the score file. +ENTRYMAX\ =\ Maximum number of entries in the score file. .lp -POINTSMIN -Minimum number of points to get an entry in the score file. +POINTSMIN\ =\ Minimum number of points to get an entry in the score file. .lp -PERS_IS_UID -0 or 1 to use user names or numeric userids, respectively, to identify -unique people for the score file. +PERS_IS_UID\ =\ 0 or 1 to use user names or numeric userids, respectively, +to identify unique people for the score file. .lp -MAX_STATUENAME_RANK -Maximum number of score file entries to use for random statue names -(default is 10). +MAX_STATUENAME_RANK\ =\ Maximum number of score file entries to use for +random statue names (default is 10). .hn 1 Scoring .pg @@ -3370,7 +3388,7 @@ or not available will result in falling back to explore mode instead. .hn Credits .pg -The original \fIhack\fP game was modeled on the Berkeley +The original \fIhack\fP game was modeled on the Berkeley .ux \fIrogue\fP game. Large portions of this paper were shamelessly cribbed from \fIA Guide to the Dungeons of Doom\fP, by Michael C. Toy @@ -3492,29 +3510,31 @@ DevTeam and incorporated the best of these ideas in NetHack 3.3. The final update to 3.2 was the bug fix release 3.2.3, which was released simultaneously with 3.3.0 in December 1999 just in time for the Year 2000. .pg -The 3.3 development team, consisting of \fBMichael Allison\fP, \fBKen Arromdee\fP, -\fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBSteve Creps\fP, \fBKevin Darcy\fP, -\fBTimo Hakulinen\fP, \fBKevin Hugo\fP, \fBSteve Linhart\fP, \fBKen Lorber\fP, -\fBDean Luick\fP, \fBPat Rankin\fP, \fBEric Smith\fP, \fBMike Stephenson\fP, -\fBJanet Walz\fP, and \fBPaul Winner\fP, released 3.3.0 in +The 3.3 development team, consisting of +\fBMichael Allison\fP, \fBKen Arromdee\fP, +\fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBSteve Creps\fP, \fBKevin Darcy\fP, +\fBTimo Hakulinen\fP, \fBKevin Hugo\fP, \fBSteve Linhart\fP, \fBKen Lorber\fP, +\fBDean Luick\fP, \fBPat Rankin\fP, \fBEric Smith\fP, \fBMike Stephenson\fP, +\fBJanet Walz\fP, and \fBPaul Winner\fP, released 3.3.0 in December 1999 and 3.3.1 in August of 2000. .pg -Version 3.3 offered many firsts. It was the first version to separate race -and profession. The Elf class was removed in preference to an elf race, -and the races of dwarves, gnomes, and orcs made their first appearance in -the game alongside the familiar human race. Monk and Ranger roles joined -Archeologists, Barbarians, Cavemen, Healers, Knights, Priests, Rogues, Samurai, +Version 3.3 offered many firsts. It was the first version to separate race +and profession. The Elf class was removed in preference to an elf race, +and the races of dwarves, gnomes, and orcs made their first appearance in +the game alongside the familiar human race. Monk and Ranger roles joined +Archeologists, Barbarians, Cavemen, Healers, Knights, Priests, Rogues, +Samurai, Tourists, Valkyries and of course, Wizards. It was also the first version -to allow you to ride a steed, and was the first version to have a publicly -available web-site listing all the bugs that had been discovered. Despite +to allow you to ride a steed, and was the first version to have a publicly +available web-site listing all the bugs that had been discovered. Despite that constantly growing bug list, 3.3 proved stable enough to last for more than a year and a half. .pg The 3.4 development team initially consisted of \fBMichael Allison\fP, \fBKen Arromdee\fP, \fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBKevin Hugo\fP, \fBKen Lorber\fP, -\fBDean Luick\fP, \fBPat Rankin\fP, \fBMike Stephenson\fP, -\fBJanet Walz\fP, and \fBPaul Winner\fP, with \fB Warwick Allison\fP joining +\fBDean Luick\fP, \fBPat Rankin\fP, \fBMike Stephenson\fP, +\fBJanet Walz\fP, and \fBPaul Winner\fP, with \fB Warwick Allison\fP joining just before the release of NetHack 3.4.0 in March 2002. .pg As with version 3.3, various people contributed to the game as a whole as @@ -3528,46 +3548,48 @@ and \fBYitzhak Sapir\fP provided encouragement. \fBDean Luick\fP, \fBMark Modrall\fP, and \fBKevin Hugo\fP maintained and enhanced the Macintosh port of 3.4. .pg -\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP, and -\fBYitzhak Sapir\fP maintained and enhanced 3.4 for the Microsoft Windows platform. -\fBAlex Kompel\fP contributed a new graphical interface for the Windows port. +\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBAlex Kompel\fP, +\fBDion Nicolaas\fP, and +\fBYitzhak Sapir\fP maintained and enhanced 3.4 for the Microsoft Windows +platform. +\fBAlex Kompel\fP contributed a new graphical interface for the Windows port. \fBAlex Kompel\fP also contributed a Windows CE port for 3.4.1. .pg \fBRon Van Iwaarden\fP was the sole maintainer of NetHack for OS/2 the past several releases. Unfortunately Ron's last OS/2 machine stopped working in -early 2006. A great many thanks to Ron for keeping NetHack alive on OS/2 +early 2006. A great many thanks to Ron for keeping NetHack alive on OS/2 all these years. .pg -\fBJanne Salmijarvi\fP and \fBTeemu Suikki\fP maintained and -enhanced the Amiga port of 3.4 after \fBJanne Salmijarvi\fP resurrected +\fBJanne Salmijarvi\fP and \fBTeemu Suikki\fP maintained and +enhanced the Amiga port of 3.4 after \fBJanne Salmijarvi\fP resurrected it for 3.3.1. .pg -\fBChristian ``Marvin'' Bressler\fP maintained 3.4 for the Atari after he +\fBChristian ``Marvin'' Bressler\fP maintained 3.4 for the Atari after he resurrected it for 3.3.1. .pg -The release of NetHack 3.4.3 in December 2003 marked the beginning of a +The release of NetHack 3.4.3 in December 2003 marked the beginning of a long release hiatus. 3.4.3 proved to be a remarkably stable version that -provided continued enjoyment by the community for more than a decade. The -devteam slowly and quietly continued to work on the game behind the scenes -during the tenure of 3.4.3. It was during that same period that several new -variants emerged within the NetHack community. Notably sporkhack by -\fBDerek S. Ray\fP, unnethack by \fBPatric Mueller\fP, nitrohack and its -successors originally by \fBDaniel Thaler\fP and then by \fBAlex Smith\fP, -and Dynahack by \fBTung Nguyen\fP. Some of those variants continue to be +provided continued enjoyment by the community for more than a decade. The +devteam slowly and quietly continued to work on the game behind the scenes +during the tenure of 3.4.3. It was during that same period that several new +variants emerged within the NetHack community. Notably sporkhack by +\fBDerek S. Ray\fP, unnethack by \fBPatric Mueller\fP, nitrohack and its +successors originally by \fBDaniel Thaler\fP and then by \fBAlex Smith\fP, +and Dynahack by \fBTung Nguyen\fP. Some of those variants continue to be developed, maintained, and enjoyed by the community to this day. .pg At the beginning of development for what would eventually get released -as 3.6.0, the development team consisted of \fBWarwick Allison\fP, +as 3.6.0, the development team consisted of \fBWarwick Allison\fP, \fBMichael Allison\fP, \fBKen Arromdee\fP, -\fBDavid Cohrs\fP, \fBJessie Collet\fP, -\fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, +\fBDavid Cohrs\fP, \fBJessie Collet\fP, +\fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, \fBMike Stephenson\fP, \fBJanet Walz\fP, and \fBPaul Winner\fP. Leading up to the release of 3.6.0 in early 2015, new members \fBSean Hunt\fP, \fBPasi Kallinen\fP, and \fBDerek S. Ray\fP joined the NetHack development team. .pg -In September 2014, an interim snapshot of the code under development was -released publicly by other parties. Since that code was a work-in-progress +In September 2014, an interim snapshot of the code under development was +released publicly by other parties. Since that code was a work-in-progress and had not gone through the process of debugging it as a suitable release, it was decided that the version numbers present on that code snapshot would be retired and never used in an official NetHack release. An announcement @@ -3580,35 +3602,36 @@ version merges work done by the development team since the previous release with some of the beloved community patches. Many bugs were fixed and a large amount of code was restructured. .pg -\fBThe development team, as well as \fBSteve VanDevender\fP and -\fBKevin Smolkowski\fP ensured that NetHack 3.6 continued to operate on -various Unix flavors and maintained the X11 interface. +\fBThe development team, as well as \fBSteve VanDevender\fP and +\fBKevin Smolkowski\fP ensured that NetHack 3.6 continued to operate on +various Unix flavors and maintained the X11 interface. .pg -\fBKen Lorber\fP, \fBHaoyang Wang\fP, \fBPat Rankin\fP, and \fBDean Luick\fP +\fBKen Lorber\fP, \fBHaoyang Wang\fP, \fBPat Rankin\fP, and \fBDean Luick\fP maintained the port of NetHack 3.6 for Mac. .pg -\fBMichael Allison\fP, \fBDerek S. Ray\fP, \fBYitzhak Sapir\fP, -\fBAlex Kompel\fP, and \fBDion Nicolaas\fP maintained the port of +\fBMichael Allison\fP, \fBDerek S. Ray\fP, \fBYitzhak Sapir\fP, +\fBAlex Kompel\fP, and \fBDion Nicolaas\fP maintained the port of NetHack 3.6 for Microsoft Windows. .pg The 3.6 development team consisting of \fBMichael Allison\fP, \fBWarwick Allison\fP, \fBKen Arromdee\fP, -\fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBSean Hunt\fP, -\fBPasi Kallinen\fP, \fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, -\fBMike Stephenson\fP, \fBDerek S. Ray\fP, \fBJanet Walz\fP, and \fBPaul Winner\fP +\fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBSean Hunt\fP, +\fBPasi Kallinen\fP, \fBKen Lorber\fP, \fBDean Luick\fP, \fBPat Rankin\fP, +\fBMike Stephenson\fP, \fBDerek S. Ray\fP, \fBJanet Walz\fP, and +\fBPaul Winner\fP released 3.6.1 as a bug fix release in January 2016. .pg The official NetHack web site is maintained by \fBKen Lorber\fP at http://www.nethack.org/. .pg SHOUT-OUTS .pg -The devteam would like to give a special "shout-out" to thank the generous -people primarily responsible for the public NetHack servers available for -playing the game at nethack.alt.org and devnull.net. In addition to providing -a way for the public to play a game of NetHack from almost anywhere, they -have hosted annual NetHack tournaments for many, many years. -.pg -On behalf of the NetHack community, thank you very much to +The devteam would like to give a special "shout-out" to thank the generous +people primarily responsible for the public NetHack servers available for +playing the game at nethack.alt.org and devnull.net. In addition to providing +a way for the public to play a game of NetHack from almost anywhere, they +have hosted annual NetHack tournaments for many, many years. +.pg +On behalf of the NetHack community, thank you very much to \fBM. Drew Streib\fP, \fBPasi Kallinen\fP and \fBRobin Bandy\fP. .pg - - - - - - - - - - diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 5f13e784f..8f2e601b4 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.6 by Mike Stephenson and others)} -\date{January 18, 2016} +\date{February 22, 2016} \maketitle @@ -346,6 +346,9 @@ do other tasks requiring agility or manipulation of objects. \item[\bb{Constitution}] Constitution affects your ability to recover from injuries and other strains on your stamina. +When strength is low or modest, consitution also affects how much you +can carry. With sufficiently high strength, the contribution to +carrying capacity from your constitution no longer matters. %.lp \item[\bb{Intelligence}] Intelligence affects your ability to cast spells and read spellbooks. @@ -1599,7 +1602,8 @@ to your pack and tell you what you just picked up. As you add items to your inventory, you also add the weight of that object to your load. The amount that you can carry depends on your strength and your constitution. The -stronger you are, the less the additional load will affect you. There comes +stronger and sturdier +you are, the less the additional load will affect you. There comes a point, though, when the weight of all of that stuff you are carrying around with you through the dungeon will encumber you. Your reactions will get slower and you'll burn calories faster, requiring food more frequently @@ -1897,10 +1901,10 @@ crystal plate mail & 3 & & bronze plate mail & 4\\ splint mail & 4 & & banded mail & 4\\ dwarvish mithril-coat & 4 & & elven mithril-coat & 5\\ chain mail & 5 & & orcish chain mail & 6\\ -scale mail & 6 & & studded leather armor & 7\\ -ring mail & 7 & & orcish ring mail & 8\\ -leather armor & 8 & & leather jacket & 9\\ -no armor & 10 +scale mail & 6 & & dragon scales & 7\\ +studded leather armor & 7 & & ring mail & 7\\ +orcish ring mail & 8 & & leather armor & 8\\ +leather jacket & 9 & & no armor & 10\\ \end{tabular} \end{center} @@ -2015,11 +2019,13 @@ The command to drink a potion is `{\tt q}' (quaff). \subsection*{Wands (`{\tt /}')} %.pg -Magic wands usually have multiple magical charges. Some wands are -directional---you must give a direction in which to zap them. You can also +Wands usually have multiple magical charges. +Some types of wands require a direction in which to zap them. +You can also zap them at yourself (just give a `{\tt .}' or `{\tt s}' for the direction). -Be warned, however, for this is often unwise. Other wands are -nondirectional---they don't require a direction. The number of charges in a +Be warned, however, for this is often unwise. +Other types of wands +don't require a direction. The number of charges in a wand is random and decreases by one whenever you use it. %.pg @@ -2087,17 +2093,19 @@ energy and the time required in casting. %.pg Casting a spell calls forth magical energies and focuses them with your naked mind. Some of the magical energy released comes from within -you, and casting several spells in a row may tire you. +you. +Casting temporarily drains your magical power, which will slowly be +recovered, and causes you to need additional food. Casting of spells also requires practice. With practice, your skill in each category of spell casting will improve. Over time, however, your memory of each spell will dim, and you will need to relearn it. %.pg -Some spells are -directional---you must give a direction in which to cast them. You can also -cast them at yourself (just give a `{\tt .}' or `{\tt s}' for the direction). -Be warned, however, for this is often unwise. Other spells are -nondirectional---they don't require a direction. +Some spells require a direction in which to cast them, similar to wands. +To cast one at yourself, just give a `{\tt .}' or `{\tt s}' for the direction. +A few spells require you to pick a target location rather than just specify +a particular direction. +Other spells don't require any direction or target. %.pg Just as weapons are divided into groups in which a character can become @@ -2193,6 +2201,11 @@ heavy. It is rumored that some statues are not what they seem. Very large humanoids (giants and their ilk) have been known to use boulders as weapons. +%.pg +For some configurations of the program, statues are no longer shown +as `{\tt `}' +but by the letter representing the monster they depict instead. + %.hn 2 \subsection*{Gold (`{\tt \$}')} @@ -2447,7 +2460,7 @@ Persistent. Your starting alignment ({\tt align:lawful}, {\tt align:neutral}, or {\tt align:chaotic}). You may specify just the first letter. The default is to randomly pick an appropriate alignment. -If you prefix `{\tt !}' or ``{\tt no}'' to the value, you can +If you prefix the value with `{\tt !}' or ``{\tt no}'', you will exclude that alignment from being picked randomly. Cannot be set with the `{\tt O}' command. Persistent. %.lp @@ -2487,7 +2500,8 @@ Start the character permanently blind. Persistent. (default false) Allow saving and loading bones files. Persistent. (default true) %.lp \item[\ib{boulder}] -Set the character used to display boulders (default is rock class symbol). +Set the character used to display boulders (default is the ``large rock'' +class symbol, `{\tt `}'). %.lp \item[\ib{catname}] Name your starting cat (ex.\ ``{\tt catname:Morris}''). @@ -2495,9 +2509,7 @@ Cannot be set with the `{\tt O}' command. %.lp character \item[\ib{character}] Pick your type of character (ex.\ ``{\tt character:Monk}''); -synonym for ``{\it role\/}''. See ``{\it name\/}'' for an alternate method -of specifying your role. Normally only the first letter of -the value is examined; the string ``{\tt random}'' is an exception. +synonym for ``{\it role\/}''. See {\it role\/} for more details. %.lp \item[\ib{checkpoint}] Save game state after each level change, for possible recovery after @@ -2506,7 +2518,9 @@ program crash (default on). Persistent. \item[\ib{checkspace}] Check free disk space before writing files to disk (default on). You may have to turn this off if you have more than 2 GB free space -on the partition used for your save and level files. +on the partition used for your save and level files +(because too much space might overflow the calculation and end up +looking like insufficient space). Only applies when MFLOPPY was defined during compilation. %.lp \item[\ib{clicklook}] @@ -2603,7 +2617,7 @@ You may specify just the first letter. Although you can still denote your gender using the ``{\tt male}'' and ``{\tt female}'' options, the ``{\tt gender}'' option will take precedence. The default is to randomly pick an appropriate gender. -If you prefix `{\tt !}' or ``{\tt no}'' to the value, you can +If you prefix the value with `{\tt !}' or ``{\tt no}'', you will exclude that gender from being picked randomly. Cannot be set with the `{\tt O}' command. Persistent. %.lp @@ -2917,7 +2931,7 @@ become wielded. Persistent. %.Ip \item[\ib{race}] Selects your race (for example, ``{\tt race:human}''). Default is random. -If you prefix `{\tt !}' or ``{\tt no}'' to the value, you can +If you prefix the value with `{\tt !}' or ``{\tt no}'', you will exclude that race from being picked randomly. Cannot be set with the `{\tt O}' command. Persistent. %.lp @@ -2930,9 +2944,10 @@ Pick your type of character (ex.\ ``{\tt role:Samurai}''); synonym for ``{\it character\/}''. See ``{\it name\/}'' for an alternate method of specifying your role. Normally only the first letter of the value is examined; `r' is an exception with ``{\tt Rogue}'', {\tt Ranger}'', -and ``{\tt random}'' values. If you prefix `{\tt !}' or ``{\tt no}'' to the -value, you can exclude that role from being picked randomly. -Persistent. +and ``{\tt random}'' values. +If you prefix the value with `{\tt !}' or ``{\tt no}'', you will +exclude that role from being picked randomly. +Cannot be set with the `{\tt O}' command. Persistent. %.lp \item[\ib{roguesymset}] This option may be used to select one of the named symbol sets found within @@ -3885,7 +3900,7 @@ mode (the debugging mode, not the magic-useing role). A value of a single asterisk (*) allows anyone to start a game in wizard mode. %.lp \item[\ib{SHELLERS}] -A list of users who are allowed to use the shell escape command (!). +A list of users who are allowed to use the shell escape command (`{\tt !}'). The syntax is the same as WIZARDS. %.lp \item[\ib{EXPLORERS}] diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 54cc1048c..dfde235b4 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -126,7 +126,7 @@ - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -192,7 +192,7 @@ thing (including other orcs). Above all others, Orcs hate Elves - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -258,7 +258,7 @@ - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -318,13 +318,13 @@ Constitution Constitution affects your ability to recover from injuries - and other strains on your stamina. - - Intelligence - Intelligence affects your ability to cast spells and read + and other strains on your stamina. When strength is low or + modest, consitution also affects how much you can carry. + With sufficiently high strength, the contribution to carry- + ing capacity from your constitution no longer matters. - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -334,6 +334,8 @@ + Intelligence + Intelligence affects your ability to cast spells and read spellbooks. Wisdom @@ -342,55 +344,53 @@ Charisma Charisma affects how certain creatures react toward you. In - particular, it can affect the prices shopkeepers offer you. + particular, it can affect the prices shopkeepers offer you. Alignment Lawful, Neutral, or Chaotic. Often, Lawful is taken as good and Chaotic as evil, but legal and ethical do not always co- - incide. Your alignment influences how other monsters react + incide. Your alignment influences how other monsters react toward you. Monsters of a like alignment are more likely to - be non-aggressive, while those of an opposing alignment are + be non-aggressive, while those of an opposing alignment are more likely to be seriously offended at your presence. Dungeon Level How deep you are in the dungeon. You start at level one and - the number increases as you go deeper into the dungeon. - Some levels are special, and are identified by a name and - not a number. The Amulet of Yendor is reputed to be some- + the number increases as you go deeper into the dungeon. + Some levels are special, and are identified by a name and + not a number. The Amulet of Yendor is reputed to be some- where beneath the twentieth level. Gold - The number of gold pieces you are openly carrying. Gold + The number of gold pieces you are openly carrying. Gold which you have concealed in containers is not counted. Hit Points - Your current and maximum hit points. Hit points indicate - how much damage you can take before you die. The more you - get hit in a fight, the lower they get. You can regain hit - points by resting, or by using certain magical items or - spells. The number in parentheses is the maximum number + Your current and maximum hit points. Hit points indicate + how much damage you can take before you die. The more you + get hit in a fight, the lower they get. You can regain hit + points by resting, or by using certain magical items or + spells. The number in parentheses is the maximum number your hit points can reach. Power - Spell points. This tells you how much mystic energy (mana) - you have available for spell casting. Again, resting will + Spell points. This tells you how much mystic energy (mana) + you have available for spell casting. Again, resting will regenerate the amount available. Armor Class A measure of how effectively your armor stops blows from un- - friendly creatures. The lower this number is, the more ef- + friendly creatures. The lower this number is, the more ef- fective the armor; it is quite possible to have negative ar- mor class. Experience Your current experience level and experience points. As you - adventure, you gain experience points. At certain experi- - ence point totals, you gain an experience level. The more - experienced you are, the better you fight and withstand mag- - ical attacks. Many dungeons show only your experience level + adventure, you gain experience points. At certain experi- + ence point totals, you gain an experience level. The more - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -400,31 +400,33 @@ + experienced you are, the better you fight and withstand mag- + ical attacks. Many dungeons show only your experience level here. Time - The number of turns elapsed so far, displayed if you have + The number of turns elapsed so far, displayed if you have the time option set. Status - Hunger: your current hunger status. Values are Satiated, - Not Hungry (or Normal), Hungry, Weak, and Fainting. Not + Hunger: your current hunger status. Values are Satiated, + Not Hungry (or Normal), Hungry, Weak, and Fainting. Not shown when Normal. Encumbrance: an indication of how what your are carrying af- fects your ability to move. Values are Unencumbered, Encum- - bered, Stressed, Strained, Overtaxed, and Overloaded. Not + bered, Stressed, Strained, Overtaxed, and Overloaded. Not shown when Unencumbered. - Fatal conditions: Stone (aka Petrifying, turning to stone), - Slime (turning into green slime), Strngl (being strangled), - FoodPois (suffering from acute food poisoning), TermIll + Fatal conditions: Stone (aka Petrifying, turning to stone), + Slime (turning into green slime), Strngl (being strangled), + FoodPois (suffering from acute food poisoning), TermIll (suffering from a terminal illness). - Non-fatal conditions: Blind (can't see), Deaf (can't hear), + Non-fatal conditions: Blind (can't see), Deaf (can't hear), Stun (stunned), Conf (confused), Hallu (hallucinating). - Movement modifiers: Lev (levitating), Fly (flying), Ride + Movement modifiers: Lev (levitating), Fly (flying), Ride (riding). Other conditions and modifiers exist, but there isn't enough @@ -434,29 +436,27 @@ 3.2. The message line (top) The top line of the screen is reserved for messages that de- - scribe things that are impossible to represent visually. If you - see a ``--More--'' on the top line, this means that NetHack has - another message to display on the screen, but it wants to make - certain that you've read the one that is there first. To read + scribe things that are impossible to represent visually. If you + see a ``--More--'' on the top line, this means that NetHack has + another message to display on the screen, but it wants to make + certain that you've read the one that is there first. To read the next message, just press the space bar. - To change how and what messages are shown on the message + To change how and what messages are shown on the message line, see ``Configuring Message Types`` and the verbose option. 3.3. The map (rest of the screen) - The rest of the screen is the map of the level as you have - explored it so far. Each symbol on the screen represents some- - thing. You can set various graphics options to change some of - the symbols the game uses; otherwise, the game will use default + The rest of the screen is the map of the level as you have + explored it so far. Each symbol on the screen represents some- + thing. You can set various graphics options to change some of + the symbols the game uses; otherwise, the game will use default symbols. Here is a list of what the default symbols mean: - - and | - The walls of a room, or an open door. Or a grave (|). - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -466,16 +466,19 @@ + - and | + The walls of a room, or an open door. Or a grave (|). + . The floor of a room, ice, or a doorless doorway. - # A corridor, or iron bars, or a tree, or possibly a kitchen + # A corridor, or iron bars, or a tree, or possibly a kitchen sink (if your dungeon has sinks), or a drawbridge. > Stairs down: a way to the next level. < Stairs up: a way to the previous level. - + A closed door, or a spellbook containing a spell you may be + + A closed door, or a spellbook containing a spell you may be able to learn. @ Your character or a human. @@ -516,13 +519,10 @@ \ An opulent throne. - a-zA-Z and other symbols - Letters and certain other symbols represent the various in- - habitants of the Mazes of Menace. Watch out, they can be - nasty and vicious. Sometimes, however, they can be helpful. - NetHack 3.6 January 18, 2016 + + NetHack 3.6 February 22, 2016 @@ -532,63 +532,63 @@ + a-zA-Z and other symbols + Letters and certain other symbols represent the various in- + habitants of the Mazes of Menace. Watch out, they can be + nasty and vicious. Sometimes, however, they can be helpful. + I This marks the last known location of an invisible or other- - wise unseen monster. Note that the monster could have + wise unseen monster. Note that the monster could have moved. The `F' and `m' commands may be useful here. - You need not memorize all these symbols; you can ask the - game what any symbol represents with the `/' command (see the + You need not memorize all these symbols; you can ask the + game what any symbol represents with the `/' command (see the next section for more info). 4. Commands - Commands are initiated by typing one or two characters. - Some commands, like ``search'', do not require that any more in- - formation be collected by NetHack. Other commands might require - additional information, for example a direction, or an object to + Commands are initiated by typing one or two characters. + Some commands, like ``search'', do not require that any more in- + formation be collected by NetHack. Other commands might require + additional information, for example a direction, or an object to be used. For those commands that require additional information, - NetHack will present you with either a menu of choices or with a - command line prompt requesting information. Which you are pre- + NetHack will present you with either a menu of choices or with a + command line prompt requesting information. Which you are pre- sented with will depend chiefly on how you have set the menustyle option. - For example, a common question, in the form ``What do you - want to use? [a-zA-Z ?*]'', asks you to choose an object you are - carrying. Here, ``a-zA-Z'' are the inventory letters of your - possible choices. Typing `?' gives you an inventory list of - these items, so you can see what each letter refers to. In this - example, there is also a `*' indicating that you may choose an - object not on the list, if you wanted to use something unexpect- + For example, a common question, in the form ``What do you + want to use? [a-zA-Z ?*]'', asks you to choose an object you are + carrying. Here, ``a-zA-Z'' are the inventory letters of your + possible choices. Typing `?' gives you an inventory list of + these items, so you can see what each letter refers to. In this + example, there is also a `*' indicating that you may choose an + object not on the list, if you wanted to use something unexpect- ed. Typing a `*' lists your entire inventory, so you can see the - inventory letters of every object you're carrying. Finally, if + inventory letters of every object you're carrying. Finally, if you change your mind and decide you don't want to do this command after all, you can press the ESC key to abort the command. - You can put a number before some commands to repeat them - that many times; for example, ``10s'' will search ten times. If + You can put a number before some commands to repeat them + that many times; for example, ``10s'' will search ten times. If you have the number_pad option set, you must type `n' to prefix a - count, so the example above would be typed ``n10s'' instead. - Commands for which counts make no sense ignore them. In addi- - tion, movement commands can be prefixed for greater control (see + count, so the example above would be typed ``n10s'' instead. + Commands for which counts make no sense ignore them. In addi- + tion, movement commands can be prefixed for greater control (see below). To cancel a count or a prefix, press the ESC key. - The list of commands is rather long, but it can be read at - any time during the game through the `?' command, which accesses - a menu of helpful texts. Here are the commands for your refer- + The list of commands is rather long, but it can be read at + any time during the game through the `?' command, which accesses + a menu of helpful texts. Here are the commands for your refer- ence: ? Help menu: display one of several help texts available. - / The ``what-is'' command, to tell what a symbol represents. - You may choose to specify a location or type a symbol (or - even a whole word) to explain. Specifying a location is - done by moving the cursor to a particular spot on the map - and then pressing one of `.', `,', `;', or `:'. `.' will - explain the symbol at the chosen location, conditionally - NetHack 3.6 January 18, 2016 + + NetHack 3.6 February 22, 2016 @@ -598,44 +598,50 @@ + / The ``what-is'' command, to tell what a symbol represents. + You may choose to specify a location or type a symbol (or + even a whole word) to explain. Specifying a location is + done by moving the cursor to a particular spot on the map + and then pressing one of `.', `,', `;', or `:'. `.' will + explain the symbol at the chosen location, conditionally check for ``More info?'' depending upon whether the help op- tion is on, and then you will be asked to pick another loca- - tion; `,' will explain the symbol but skip any additional - information, then let you pick another location; `;' will - skip additional info and also not bother asking you to + tion; `,' will explain the symbol but skip any additional + information, then let you pick another location; `;' will + skip additional info and also not bother asking you to choose another location to examine; `:' will show additional info, if any, without asking for confirmation. When picking - a location, pressing the ESC key will terminate this com- - mand, or pressing `?' will give a brief reminder about how + a location, pressing the ESC key will terminate this com- + mand, or pressing `?' will give a brief reminder about how it works. - If the autodescribe option is on, a short description of - what you see at each location is shown as you move the cur- - sor. Typing `#' while picking a location will toggle that - option on or off. The whatis_coord option controls whether + If the autodescribe option is on, a short description of + what you see at each location is shown as you move the cur- + sor. Typing `#' while picking a location will toggle that + option on or off. The whatis_coord option controls whether the short description includes map coordinates. - Specifying a name rather than a location always gives any + Specifying a name rather than a location always gives any additional information available about that name. - You may also request a description of nearby monsters, all - monsters currently displayed, nearby objects, or all ob- + You may also request a description of nearby monsters, all + monsters currently displayed, nearby objects, or all ob- jects. The whatis_coord option controls which format of map coordinate is included with their descriptions. & Tell what a command does. - < Go up to the previous level (if you are on a staircase or + < Go up to the previous level (if you are on a staircase or ladder). > Go down to the next level (if you are on a staircase or lad- der). [yuhjklbn] - Go one step in the direction indicated (see Figure 2). If - you sense or remember a monster there, you will fight the - monster instead. Only these one-step movement commands - cause you to fight monsters; the others (below) are + Go one step in the direction indicated (see Figure 2). If + you sense or remember a monster there, you will fight the + monster instead. Only these one-step movement commands + cause you to fight monsters; the others (below) are ``safe.'' y k u 7 8 9 @@ -648,13 +654,7 @@ Figure 2 - [YUHJKLBN] - Go in that direction until you hit a wall or run into some- - thing. - - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -664,12 +664,16 @@ + [YUHJKLBN] + Go in that direction until you hit a wall or run into some- + thing. + m[yuhjklbn] - Prefix: move without picking up objects or fighting (even + Prefix: move without picking up objects or fighting (even if you remember a monster there) F[yuhjklbn] - Prefix: fight a monster (even if you only guess one is + Prefix: fight a monster (even if you only guess one is there) M[yuhjklbn] @@ -679,17 +683,17 @@ Prefix: move until something interesting is found. G[yuhjklbn] or [yuhjklbn] - Prefix: same as `g', but forking of corridors is not con- + Prefix: same as `g', but forking of corridors is not con- sidered interesting. _ Travel to a map location via a shortest-path algorithm. - The shortest path is computed over map locations the hero - knows about (e.g. seen or previously traversed). If there + The shortest path is computed over map locations the hero + knows about (e.g. seen or previously traversed). If there is no known path, a guess is made instead. Stops on most of - the same conditions as the `G' command, but without picking - up objects, similar to the `M' command. For ports with - mouse support, the command is also invoked when a mouse- + the same conditions as the `G' command, but without picking + up objects, similar to the `M' command. For ports with + mouse support, the command is also invoked when a mouse- click takes place on a location other than the current posi- tion. @@ -699,28 +703,24 @@ A Remove one or more worn items, such as armor. - Use `T' (take off) to take off only one piece of armor or + Use `T' (take off) to take off only one piece of armor or `R' (remove) to take off only one accessory. ^A Redo the previous command. c Close a door. - C Call (name) a monster, an individual object, or a type of + C Call (name) a monster, an individual object, or a type of object. Same as extended command ``#name''. ^C Panic button. Quit the game. - d Drop something. - - Ex. ``d7a'' means drop seven items of object a. - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -730,15 +730,19 @@ + d Drop something. + + Ex. ``d7a'' means drop seven items of object a. + D Drop several things. In answer to the question ``What kinds of things do you want to drop? [!%= BUCXaium]'' - you should type zero or more object symbols possibly fol- + you should type zero or more object symbols possibly fol- lowed by `a' and/or `i' and/or `u' and/or `m'. In addition, - one or more of the blessed/uncursed/cursed groups may be + one or more of the blessed/uncursed/cursed groups may be typed. DB - drop all objects known to be blessed. @@ -759,23 +763,39 @@ E- - write in the dust with your fingers. - Engraving the word ``Elbereth'' will cause most monsters to + Engraving the word ``Elbereth'' will cause most monsters to not attack you hand-to-hand (but if you attack, you will rub - it out); this is often useful to give yourself a breather. - (This feature may be compiled out of the game, so your ver- + it out); this is often useful to give yourself a breather. + (This feature may be compiled out of the game, so your ver- sion might not have it.) - f Fire one of the objects placed in your quiver (or quiver - sack, or that you have at the ready). You may select ammu- + f Fire one of the objects placed in your quiver (or quiver + sack, or that you have at the ready). You may select ammu- nition with a previous `Q' command, or let the computer pick something appropriate if autoquiver is true. i List your inventory (everything you're carrying). I List selected parts of your inventory, usually be specifying - the character for a particular set of objects, like `[' for + the character for a particular set of objects, like `[' for armor or `!' for potions. + + + + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 13 + + + I* - list all gems in inventory; Iu - list all unpaid items; Ix - list all used up items that are on your shopping bill; @@ -785,27 +805,16 @@ IX - list all items whose bless/curse status is known; I$ - count your money. - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 13 - - - o Open a door. O Set options. - A menu showing the current option values will be displayed. - You can change most values simply by selecting the menu en- + A menu showing the current option values will be displayed. + You can change most values simply by selecting the menu en- try for the given option (ie, by typing its letter or click- - ing upon it, depending on your user interface). For the - non-boolean choices, a further menu or prompt will appear - once you've closed this menu. The available options are + ing upon it, depending on your user interface). For the + non-boolean choices, a further menu or prompt will appear + once you've closed this menu. The available options are listed later in this Guidebook. Options are usually set be- fore the game rather than with the `O' command; see the sec- tion on options below. @@ -815,44 +824,35 @@ P Put on an accessory (ring, amulet, or blindfold). This command may also be used to wear armor. The prompt for - which inventory item to use will only list accessories, but - choosing an unlisted item of armor will attempt to wear it. + which inventory item to use will only list accessories, but + choosing an unlisted item of armor will attempt to wear it. (See the `W' command below. It lists armor as the inventory choices but will accept an accessory and attempt to put that on.) ^P Repeat previous message. - Subsequent ^P's repeat earlier messages. The behavior can + Subsequent ^P's repeat earlier messages. The behavior can be varied via the msg_window option. q Quaff (drink) something (potion, water, etc). - Q Select an object for your quiver, quiver sack, or just gen- - erally at the ready (only one of these is available at a - time). You can then throw this (or one of these) using the + Q Select an object for your quiver, quiver sack, or just gen- + erally at the ready (only one of these is available at a + time). You can then throw this (or one of these) using the `f' command. - (In versions prior to 3.3 this was the command to quit the + (In versions prior to 3.3 this was the command to quit the game, which has been moved to ``#quit''.) r Read a scroll or spellbook. R Remove a worn accessory (ring, amulet, or blindfold). - If you're wearing more than one, you'll be prompted for - which one to remove. When you're only wearing one, then by - default it will be removed without asking, but you can set - the paranoid_confirmation option to require a prompt. - - This command may also be used to take off armor. The prompt - for which inventory item to remove only lists worn acces- - sories, but an item of worn armor can be chosen. (See the - `T' command below. It lists armor as the inventory choices - but will accept an accessory and attempt to remove it.) - NetHack 3.6 January 18, 2016 + + NetHack 3.6 February 22, 2016 @@ -862,31 +862,42 @@ + If you're wearing more than one, you'll be prompted for + which one to remove. When you're only wearing one, then by + default it will be removed without asking, but you can set + the paranoid_confirmation option to require a prompt. + + This command may also be used to take off armor. The prompt + for which inventory item to remove only lists worn acces- + sories, but an item of worn armor can be chosen. (See the + `T' command below. It lists armor as the inventory choices + but will accept an accessory and attempt to remove it.) + ^R Redraw the screen. - s Search for secret doors and traps around you. It usually + s Search for secret doors and traps around you. It usually takes several tries to find something. - S Save (and suspend) the game. The game will be restored au- + S Save (and suspend) the game. The game will be restored au- tomatically the next time you play. t Throw an object or shoot a projectile. T Take off armor. - If you're wearing more than one piece, you'll be prompted - for which one to take off. (Note that this treats a cloak - covering a suit and/or a shirt, or a suit covering a shirt, + If you're wearing more than one piece, you'll be prompted + for which one to take off. (Note that this treats a cloak + covering a suit and/or a shirt, or a suit covering a shirt, as if the underlying items weren't there.) When you're only - wearing one, then by default it will be taken off without - asking, but you can set the paranoid_confirmation option to + wearing one, then by default it will be taken off without + asking, but you can set the paranoid_confirmation option to require a prompt. - This command may also be used to remove accessories. The - prompt for which inventory item to take off only lists worn - armor, but a worn accessory can be chosen. (See the `R' + This command may also be used to remove accessories. The + prompt for which inventory item to take off only lists worn + armor, but a worn accessory can be chosen. (See the `R' command above. It lists accessories as the inventory choic- - es but will accept an item of armor and attempt to take it + es but will accept an item of armor and attempt to take it off.) ^T Teleport, if you have the ability. @@ -899,26 +910,15 @@ w- - wield nothing, use your bare hands. - Some characters can wield two weapons at once; use the `X' + Some characters can wield two weapons at once; use the `X' command (or the ``#twoweapon'' extended command) to do so. W Wear armor. - This command may also be used to put on an accessory (ring, - amulet, or blindfold). The prompt for which inventory item - to use will only list armor, but choosing an unlisted acces- - sory will attempt to put it on. (See the `P' command above. - It lists accessories as the inventory choices but will ac- - cept an item of armor and attempt to wear it.) - - x Exchange your wielded weapon with the item in your alternate - weapon slot. - - The latter is used as your secondary weapon when engaging in - two-weapon combat. Note that if one of these slots is - NetHack 3.6 January 18, 2016 + + NetHack 3.6 February 22, 2016 @@ -928,23 +928,35 @@ - empty, the exchange still takes place. + This command may also be used to put on an accessory (ring, + amulet, or blindfold). The prompt for which inventory item + to use will only list armor, but choosing an unlisted acces- + sory will attempt to put it on. (See the `P' command above. + It lists accessories as the inventory choices but will ac- + cept an item of armor and attempt to wear it.) + + x Exchange your wielded weapon with the item in your alternate + weapon slot. + + The latter is used as your secondary weapon when engaging in + two-weapon combat. Note that if one of these slots is emp- + ty, the exchange still takes place. X Toggle two-weapon combat, if your character can do it. Also available via the ``#twoweapon'' extended command. - (In versions prior to 3.6 this was the command to switch + (In versions prior to 3.6 this was the command to switch from normal play to "explore mode", also known as "discovery mode", which has now been moved to ``#explore''.) ^X Display basic information about your character. - Displays name, role, race, gender (unless role name makes - that redundant, such as Caveman or Priestess), and align- - ment, along with your patron deity and his or her opposi- - tion. It also shows most of the various items of informa- + Displays name, role, race, gender (unless role name makes + that redundant, such as Caveman or Priestess), and align- + ment, along with your patron deity and his or her opposi- + tion. It also shows most of the various items of informa- tion from the status line(s) in a less terse form, including - several additional things which don't appear in the normal + several additional things which don't appear in the normal status display due to space considerations. z Zap a wand. @@ -967,6 +979,21 @@ @ Toggle the autopickup option on and off. + + __________ + (R)UNIX is a registered trademark of AT&T. + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 16 + + + ^ Ask for the type of a trap you found earlier. ) Tell what weapon you are wielding. @@ -979,21 +1006,6 @@ ( Tell what tools you are using. - - __________ - (R)UNIX is a registered trademark of AT&T. - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 16 - - - * Tell what equipment you are using. Combines the preceding five type-specific commands into one. @@ -1002,16 +1014,16 @@ + List the spells you know. - Using this command, you can also rearrange the order in - which your spells are listed, either by sorting the entire - list or by picking one spell from the menu then picking an- - other to swap places with it. Swapping pairs of spells + Using this command, you can also rearrange the order in + which your spells are listed, either by sorting the entire + list or by picking one spell from the menu then picking an- + other to swap places with it. Swapping pairs of spells changes their casting letters, so the change lasts after the - current `+' command finishes. Sorting the whole list is - temporary. To make the most recent sort order persist be- - yond the current `+' command, choose the sort option again - and then pick "reassign casting letters". (Any spells - learned after that will be added to the end of the list + current `+' command finishes. Sorting the whole list is + temporary. To make the most recent sort order persist be- + yond the current `+' command, choose the sort option again + and then pick "reassign casting letters". (Any spells + learned after that will be added to the end of the list rather than be inserted into the sorted ordering.) \ Show what types of objects have been discovered. @@ -1022,20 +1034,32 @@ # Perform an extended command. - As you can see, the authors of NetHack used up all the let- + As you can see, the authors of NetHack used up all the let- ters, so this is a way to introduce the less frequently used - commands. What extended commands are available depends on + commands. What extended commands are available depends on what features the game was compiled with. #adjust Adjust inventory letters (most useful when the fixinv option is ``on''). - This command allows you to move an item from one particular - inventory slot to another so that it has a letter which is + This command allows you to move an item from one particular + inventory slot to another so that it has a letter which is more meaningful for you or that it will appear in a particu- - lar location when inventory listings are displayed. ``#ad- - just'' can also be used to split a stack of objects; when + lar location when inventory listings are displayed. ``#ad- + just'' can also be used to split a stack of objects; when + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 17 + + + choosing the item to adjust, enter a count prior to its let- ter. @@ -1047,19 +1071,6 @@ #chat Talk to someone. - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 17 - - - #conduct List voluntary challenges you have maintained. @@ -1087,36 +1098,25 @@ Kick something. #loot - Loot a box or bag on the floor beneath you, or the saddle + Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. #monster - Use a monster's special ability (when polymorphed into mon- + Use a monster's special ability (when polymorphed into mon- ster form). #name - Name a monster, an individual object, or a type of object. + Name a monster, an individual object, or a type of object. Same as `C'. #offer Offer a sacrifice to the gods. - You'll need to find an altar to have any chance at success. - Corpses of recently killed monsters are the fodder of - choice. - - #overview - Display information you've discovered about the dungeon. - Any visited level (unless forgotten due to amnesia) with an - annotation is included, and many things (altars, thrones, - fountains, and so on; extra stairs leading to another dun- - geon branch) trigger an automatic annotation. If dungeon - overview is chosen during end-of-game disclosure, every vis- - ited level will be included regardless of annotations. + You'll need to find an altar to have any chance at success. + Corpses of recently killed monsters are the fodder of - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1126,24 +1126,35 @@ + choice. + + #overview + Display information you've discovered about the dungeon. + Any visited level (unless forgotten due to amnesia) with an + annotation is included, and many things (altars, thrones, + fountains, and so on; extra stairs leading to another dun- + geon branch) trigger an automatic annotation. If dungeon + overview is chosen during end-of-game disclosure, every vis- + ited level will be included regardless of annotations. + #pray Pray to the gods for help. - Praying too soon after receiving prior help is a bad idea. - (Hint: entering the dungeon alive is treated as having re- + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having re- ceived help. You probably shouldn't start off a new game by - praying right away.) Since using this command by accident - can cause trouble, there is an option to make you confirm - your intent before praying. It is enabled by default, and - you can reset the paranoid_confirmation option to disable + praying right away.) Since using this command by accident + can cause trouble, there is an option to make you confirm + your intent before praying. It is enabled by default, and + you can reset the paranoid_confirmation option to disable it. #quit Quit the program without saving your game. - Since using this command by accident would throw away the - current game, you are asked to confirm your intent before - quitting. By default a response of 'y' acknowledges that + Since using this command by accident would throw away the + current game, you are asked to confirm your intent before + quitting. By default a response of 'y' acknowledges that intent. You can set the paranoid_confirmation option to re- quire a response of "yes" instead. @@ -1157,11 +1168,11 @@ Sit down. #terrain - Show bare map without displaying monsters, objects, or + Show bare map without displaying monsters, objects, or traps. #tip - Tip over a container (bag or box) to pour out its contents. + Tip over a container (bag or box) to pour out its contents. #turn Turn undead. @@ -1169,20 +1180,9 @@ #twoweapon Toggle two-weapon combat on or off. - Note that you must use suitable weapons for this type of - combat, or it will be automatically turned off. - - #untrap - Untrap something (trap, door, or chest). - - In some circumstances it can also be used to rescue trapped - monsters. - - #version - Print compile time options for this version of NetHack. - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1192,6 +1192,18 @@ + Note that you must use suitable weapons for this type of + combat, or it will be automatically turned off. + + #untrap + Untrap something (trap, door, or chest). + + In some circumstances it can also be used to rescue trapped + monsters. + + #version + Print compile time options for this version of NetHack. + #wipe Wipe off your face. @@ -1199,12 +1211,12 @@ Help menu: get the list of available extended commands. If your keyboard has a meta key (which, when pressed in com- - bination with another key, modifies it by setting the `meta' - [8th, or `high'] bit), you can invoke many extended commands by + bination with another key, modifies it by setting the `meta' + [8th, or `high'] bit), you can invoke many extended commands by meta-ing the first letter of the command. In NT, OS/2, PC and ST NetHack, the `Alt' key can be used in this fashion; on the Amiga, - set the altmeta option to get this behavior. On other systems, - if typing `Alt' plus another key transmits a two character se- + set the altmeta option to get this behavior. On other systems, + if typing `Alt' plus another key transmits a two character se- quence consisting of an Escape followed by the other key, you may set the altmeta option to have nethack combine them into meta+key. @@ -1233,6 +1245,19 @@ M-l #loot + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 20 + + + M-m #monster M-n #name @@ -1245,19 +1270,6 @@ M-q #quit - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 20 - - - M-r #rub M-R #ride @@ -1274,47 +1286,35 @@ M-w #wipe - If the number_pad option is on, some additional letter com- + If the number_pad option is on, some additional letter com- mands are available: - h Help menu: display one of several help texts available, + h Help menu: display one of several help texts available, like ``?''. j Jump to another location. Same as ``#jump'' or ``M-j''. k Kick something (usually a door). Same as `^D'. - l Loot a box or bag on the floor beneath you, or the saddle - from a steed standing next to you. Same as ``#loot'' or + l Loot a box or bag on the floor beneath you, or the saddle + from a steed standing next to you. Same as ``#loot'' or ``M-l''. - N Name a monster, an individual object, or a type of object. - Same as ``#name'' (or ``M-n'') which is the same as the `C' + N Name a monster, an individual object, or a type of object. + Same as ``#name'' (or ``M-n'') which is the same as the `C' command. - u Untrap a trap, door, or chest. Same as ``#untrap'' or ``M- + u Untrap a trap, door, or chest. Same as ``#untrap'' or ``M- u''. 5. Rooms and corridors - Rooms and corridors in the dungeon are either lit or dark. - Any lit areas within your line of sight will be displayed; dark - areas are only displayed if they are within one space of you. - Walls and corridors remain on the map as you explore them. - - Secret corridors are hidden. You can find them with the `s' - (search) command. - - 5.1. Doorways - - Doorways connect rooms and corridors. Some doorways have no - doors; you can walk right through. Others have doors in them, - which may be open, closed, or locked. To open a closed door, use - the `o' (open) command; to close it again, use the `c' (close) + Rooms and corridors in the dungeon are either lit or dark. + Any lit areas within your line of sight will be displayed; dark - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1324,63 +1324,63 @@ + areas are only displayed if they are within one space of you. + Walls and corridors remain on the map as you explore them. + + Secret corridors are hidden. You can find them with the `s' + (search) command. + + 5.1. Doorways + + Doorways connect rooms and corridors. Some doorways have no + doors; you can walk right through. Others have doors in them, + which may be open, closed, or locked. To open a closed door, use + the `o' (open) command; to close it again, use the `c' (close) command. - You can get through a locked door by using a tool to pick + You can get through a locked door by using a tool to pick the lock with the `a' (apply) command, or by kicking it open with the `^D' (kick) command. - Open doors cannot be entered diagonally; you must approach - them straight on, horizontally or vertically. Doorways without + Open doors cannot be entered diagonally; you must approach + them straight on, horizontally or vertically. Doorways without doors are not restricted in this fashion. - Doors can be useful for shutting out monsters. Most mon- + Doors can be useful for shutting out monsters. Most mon- sters cannot open doors, although a few don't need to (ex. ghosts can walk through doors). - Secret doors are hidden. You can find them with the `s' - (search) command. Once found they are in all ways equivalent to + Secret doors are hidden. You can find them with the `s' + (search) command. Once found they are in all ways equivalent to normal doors. 5.2. Traps (`^') - There are traps throughout the dungeon to snare the unwary - delver. For example, you may suddenly fall into a pit and be + There are traps throughout the dungeon to snare the unwary + delver. For example, you may suddenly fall into a pit and be stuck for a few turns trying to climb out. Traps don't appear on your map until you see one triggered by moving onto it, see some- thing fall into it, or you discover it with the `s' (search) com- - mand. Monsters can fall prey to traps, too, which can be a very + mand. Monsters can fall prey to traps, too, which can be a very useful defensive strategy. There is a special pre-mapped branch of the dungeon based on - the classic computer game ``Sokoban.'' The goal is to push the - boulders into the pits or holes. With careful foresight, it is - possible to complete all of the levels according to the tradi- - tional rules of Sokoban. Some allowances are permitted in case + the classic computer game ``Sokoban.'' The goal is to push the + boulders into the pits or holes. With careful foresight, it is + possible to complete all of the levels according to the tradi- + tional rules of Sokoban. Some allowances are permitted in case the player gets stuck; however, they will lower your luck. 5.3. Stairs (`<', `>') - In general, each level in the dungeon will have a staircase + In general, each level in the dungeon will have a staircase going up (`<') to the previous level and another going down (`>') - to the next level. There are some exceptions though. For in- - stance, fairly early in the dungeon you will find a level with - two down staircases, one continuing into the dungeon and the oth- - er branching into an area known as the Gnomish Mines. Those - mines eventually hit a dead end, so after exploring them (if you - choose to do so), you'll need to climb back up to the main dun- - geon. - - When you traverse a set of stairs, or trigger a trap which - sends you to another level, the level you're leaving will be de- - activated and stored in a file on disk. If you're moving to a - previously visited level, it will be loaded from its file on disk - and reactivated. If you're moving to a level which has not yet - been visited, it will be created (from scratch for most random - levels, from a template for some ``special'' levels, or loaded + to the next level. There are some exceptions though. For in- + stance, fairly early in the dungeon you will find a level with + two down staircases, one continuing into the dungeon and the - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1390,63 +1390,63 @@ - from the remains of an earlier game for a ``bones'' level as - briefly described below). Monsters are only active on the cur- - rent level; those on other levels are essentially placed into + other branching into an area known as the Gnomish Mines. Those + mines eventually hit a dead end, so after exploring them (if you + choose to do so), you'll need to climb back up to the main dun- + geon. + + When you traverse a set of stairs, or trigger a trap which + sends you to another level, the level you're leaving will be de- + activated and stored in a file on disk. If you're moving to a + previously visited level, it will be loaded from its file on disk + and reactivated. If you're moving to a level which has not yet + been visited, it will be created (from scratch for most random + levels, from a template for some ``special'' levels, or loaded + from the remains of an earlier game for a ``bones'' level as + briefly described below). Monsters are only active on the cur- + rent level; those on other levels are essentially placed into stasis. - Ordinarily when you climb a set of stairs, you will arrive - on the corresponding staircase at your destination. However, - pets (see below) and some other monsters will follow along if + Ordinarily when you climb a set of stairs, you will arrive + on the corresponding staircase at your destination. However, + pets (see below) and some other monsters will follow along if they're close enough when you travel up or down stairs, and occa- - sionally one of these creatures will displace you during the + sionally one of these creatures will displace you during the climb. When that occurs, the pet or other monster will arrive on the staircase and you will end up nearby. 5.4. Ladders (`<', `>') - Ladders serve the same purpose as staircases, and the two - types of inter-level connections are nearly indistinguishable + Ladders serve the same purpose as staircases, and the two + types of inter-level connections are nearly indistinguishable during game play. 5.5. Shops and shopping - Occasionally you will run across a room with a shopkeeper - near the door and many items lying on the floor. You can buy + Occasionally you will run across a room with a shopkeeper + near the door and many items lying on the floor. You can buy items by picking them up and then using the `p' command. You can - inquire about the price of an item prior to picking it up by us- - ing the ``#chat'' command while standing on it. Using an item - prior to paying for it will incur a charge, and the shopkeeper - won't allow you to leave the shop until you have paid any debt + inquire about the price of an item prior to picking it up by us- + ing the ``#chat'' command while standing on it. Using an item + prior to paying for it will incur a charge, and the shopkeeper + won't allow you to leave the shop until you have paid any debt you owe. - You can sell items to a shopkeeper by dropping them to the - floor while inside a shop. You will either be offered an amount - of gold and asked whether you're willing to sell, or you'll be - told that the shopkeeper isn't interested (generally, your item - needs to be compatible with the type of merchandise carried by + You can sell items to a shopkeeper by dropping them to the + floor while inside a shop. You will either be offered an amount + of gold and asked whether you're willing to sell, or you'll be + told that the shopkeeper isn't interested (generally, your item + needs to be compatible with the type of merchandise carried by the shop). - If you drop something in a shop by accident, the shopkeeper - will usually claim ownership without offering any compensation. + If you drop something in a shop by accident, the shopkeeper + will usually claim ownership without offering any compensation. You'll have to buy it back if you want to reclaim it. - Shopkeepers sometimes run out of money. When that happens, - you'll be offered credit instead of gold when you try to sell - something. Credit can be used to pay for purchases, but it is - only good in the shop where it was obtained; other shopkeepers - won't honor it. (If you happen to find a "credit card" in the - dungeon, don't bother trying to use it in shops; shopkeepers will - not accept it.) - - The `$' command, which reports the amount of gold you are - carrying (in inventory, not inside bags or boxes), will also show - current shop debt or credit, if any. The `Iu' command lists un- - paid items (those which still belong to the shop) if you are car- - rying any. The `Ix' command shows an inventory-like display of - NetHack 3.6 January 18, 2016 + + NetHack 3.6 February 22, 2016 @@ -1456,7 +1456,20 @@ - any unpaid items which have been used up, along with other shop + Shopkeepers sometimes run out of money. When that happens, + you'll be offered credit instead of gold when you try to sell + something. Credit can be used to pay for purchases, but it is + only good in the shop where it was obtained; other shopkeepers + won't honor it. (If you happen to find a "credit card" in the + dungeon, don't bother trying to use it in shops; shopkeepers will + not accept it.) + + The `$' command, which reports the amount of gold you are + carrying (in inventory, not inside bags or boxes), will also show + current shop debt or credit, if any. The `Iu' command lists un- + paid items (those which still belong to the shop) if you are car- + rying any. The `Ix' command shows an inventory-like display of + any unpaid items which have been used up, along with other shop fees, if any. 5.5.1. Shop idiosyncracies @@ -1465,13 +1478,13 @@ * The price of a given item can vary due to a variety of factors. - * A shopkeeper treats the spot immediately inside the door as if + * A shopkeeper treats the spot immediately inside the door as if it were outside the shop. * While the shopkeeper watches you like a hawk, he will generally ignore any other customers. - * If a shop is "closed for inventory", it will not open of its + * If a shop is "closed for inventory", it will not open of its own accord. * Shops do not get restocked with new items, regardless of inven- @@ -1480,39 +1493,26 @@ 6. Monsters - Monsters you cannot see are not displayed on the screen. - Beware! You may suddenly come upon one in a dark place. Some - magic items can help you locate them before they locate you + Monsters you cannot see are not displayed on the screen. + Beware! You may suddenly come upon one in a dark place. Some + magic items can help you locate them before they locate you (which some monsters can do very well). - The commands `/' and `;' may be used to obtain information - about those monsters who are displayed on the screen. The com- - mand ``#name'', or its synonym `C', allows you to assign a name - to a monster, which may be useful to help distinguish one from - another when multiple monsters are present. Assigning a name + The commands `/' and `;' may be used to obtain information + about those monsters who are displayed on the screen. The com- + mand ``#name'', or its synonym `C', allows you to assign a name + to a monster, which may be useful to help distinguish one from + another when multiple monsters are present. Assigning a name which is just a space will remove any prior name. - The extended command ``#chat'' can be used to interact with - an adjacent monster. There is no actual dialog (in other words, - you don't get to choose what you'll say), but chatting with some + The extended command ``#chat'' can be used to interact with + an adjacent monster. There is no actual dialog (in other words, + you don't get to choose what you'll say), but chatting with some monsters such as a shopkeeper or the Oracle of Delphi can produce useful results. - 6.1. Fighting - If you see a monster and you wish to fight it, just attempt - to walk into it. Many monsters you find will mind their own - business unless you attack them. Some of them are very dangerous - when angered. Remember: discretion is the better part of valor. - - In most circumstances, if you attempt to attack a peaceful - monster by moving into its location, you'll be asked to confirm - your intent. By default an answer of 'y' acknowledges that in- - tent, which can be error prone if you're using 'y' to move. You - can set the paranoid_confirmation option to require a response of - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1522,63 +1522,63 @@ + 6.1. Fighting + + If you see a monster and you wish to fight it, just attempt + to walk into it. Many monsters you find will mind their own + business unless you attack them. Some of them are very dangerous + when angered. Remember: discretion is the better part of valor. + + In most circumstances, if you attempt to attack a peaceful + monster by moving into its location, you'll be asked to confirm + your intent. By default an answer of 'y' acknowledges that in- + tent, which can be error prone if you're using 'y' to move. You + can set the paranoid_confirmation option to require a response of "yes" instead. - If you can't see a monster (if it is invisible, or if you - are blinded), the symbol `I' will be shown when you learn of its - presence. If you attempt to walk into it, you will try to fight - it just like a monster that you can see; of course, if the mon- + If you can't see a monster (if it is invisible, or if you + are blinded), the symbol `I' will be shown when you learn of its + presence. If you attempt to walk into it, you will try to fight + it just like a monster that you can see; of course, if the mon- ster has moved, you will attack empty air. If you guess that the - monster has moved and you don't wish to fight, you can use the - `m' command to move without fighting; likewise, if you don't re- + monster has moved and you don't wish to fight, you can use the + `m' command to move without fighting; likewise, if you don't re- member a monster but want to try fighting anyway, you can use the `F' command. 6.2. Your pet - You start the game with a little dog (`d'), cat (`f'), or - pony (`u'), which follows you about the dungeon and fights mon- - sters with you. Like you, your pet needs food to survive. It + You start the game with a little dog (`d'), cat (`f'), or + pony (`u'), which follows you about the dungeon and fights mon- + sters with you. Like you, your pet needs food to survive. It usually feeds itself on fresh carrion and other meats. If you're - worried about it or want to train it, you can feed it, too, by - throwing it food. A properly trained pet can be very useful un- + worried about it or want to train it, you can feed it, too, by + throwing it food. A properly trained pet can be very useful un- der certain circumstances. - Your pet also gains experience from killing monsters, and - can grow over time, gaining hit points and doing more damage. - Initially, your pet may even be better at killing things than + Your pet also gains experience from killing monsters, and + can grow over time, gaining hit points and doing more damage. + Initially, your pet may even be better at killing things than you, which makes pets useful for low-level characters. - Your pet will follow you up and down staircases if it is - next to you when you move. Otherwise your pet will be stranded - and may become wild. Similarly, when you trigger certain types - of traps which alter your location (for instance, a trap door - which drops you to a lower dungeon level), any adjacent pet will + Your pet will follow you up and down staircases if it is + next to you when you move. Otherwise your pet will be stranded + and may become wild. Similarly, when you trigger certain types + of traps which alter your location (for instance, a trap door + which drops you to a lower dungeon level), any adjacent pet will accompany you and any non-adjacent pet will be left behind. Your - pet may trigger such traps itself; you will not be carried along + pet may trigger such traps itself; you will not be carried along with it even if adjacent at the time. 6.3. Steeds - Some types of creatures in the dungeon can actually be rid- + Some types of creatures in the dungeon can actually be rid- den if you have the right equipment and skill. Convincing a wild - beast to let you saddle it up is difficult to say the least. - Many a dungeoneer has had to resort to magic and wizardry in or- - der to forge the alliance. Once you do have the beast under your - control however, you can easily climb in and out of the saddle - with the `#ride' command. Lead the beast around the dungeon when - riding, in the same manner as you would move yourself. It is the - beast that you will see displayed on the map. - - Riding skill is managed by the `#enhance' command. See the - section on Weapon proficiency for more information about that. + beast to let you saddle it up is difficult to say the least. + Many a dungeoneer has had to resort to magic and wizardry in - - - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1588,13 +1588,22 @@ + order to forge the alliance. Once you do have the beast under + your control however, you can easily climb in and out of the sad- + dle with the `#ride' command. Lead the beast around the dungeon + when riding, in the same manner as you would move yourself. It + is the beast that you will see displayed on the map. + + Riding skill is managed by the `#enhance' command. See the + section on Weapon proficiency for more information about that. + 6.4. Bones levels - You may encounter the shades and corpses of other adventur- + You may encounter the shades and corpses of other adventur- ers (or even former incarnations of yourself!) and their personal - effects. Ghosts are hard to kill, but easy to avoid, since - they're slow and do little damage. You can plunder the deceased - adventurer's possessions; however, they are likely to be cursed. + effects. Ghosts are hard to kill, but easy to avoid, since + they're slow and do little damage. You can plunder the deceased + adventurer's possessions; however, they are likely to be cursed. Beware of whatever killed the former player; it is probably still lurking around, gloating over its last victory. @@ -1603,48 +1612,39 @@ When you find something in the dungeon, it is common to want to pick it up. In NetHack, this is accomplished automatically by - walking over the object (unless you turn off the autopickup op- - tion (see below), or move with the `m' prefix (see above)), or + walking over the object (unless you turn off the autopickup op- + tion (see below), or move with the `m' prefix (see above)), or manually by using the `,' command. - If you're carrying too many items, NetHack will tell you so - and you won't be able to pick up anything more. Otherwise, it - will add the object(s) to your pack and tell you what you just + If you're carrying too many items, NetHack will tell you so + and you won't be able to pick up anything more. Otherwise, it + will add the object(s) to your pack and tell you what you just picked up. - As you add items to your inventory, you also add the weight - of that object to your load. The amount that you can carry de- - pends on your strength and your constitution. The stronger you - are, the less the additional load will affect you. There comes a - point, though, when the weight of all of that stuff you are car- - rying around with you through the dungeon will encumber you. - Your reactions will get slower and you'll burn calories faster, - requiring food more frequently to cope with it. Eventually, - you'll be so overloaded that you'll either have to discard some - of what you're carrying or collapse under its weight. + As you add items to your inventory, you also add the weight + of that object to your load. The amount that you can carry de- + pends on your strength and your constitution. The stronger and + sturdier you are, the less the additional load will affect you. + There comes a point, though, when the weight of all of that stuff + you are carrying around with you through the dungeon will encum- + ber you. Your reactions will get slower and you'll burn calories + faster, requiring food more frequently to cope with it. Eventu- + ally, you'll be so overloaded that you'll either have to discard + some of what you're carrying or collapse under its weight. - NetHack will tell you how badly you have loaded yourself. - The symbols `Burdened', `Stressed', `Strained', `Overtaxed' and + NetHack will tell you how badly you have loaded yourself. + The symbols `Burdened', `Stressed', `Strained', `Overtaxed' and `Overloaded' are displayed on the bottom line display to indicate your condition. When you pick up an object, it is assigned an inventory let- - ter. Many commands that operate on objects must ask you to find - out which object you want to use. When NetHack asks you to + ter. Many commands that operate on objects must ask you to find + out which object you want to use. When NetHack asks you to choose a particular object you are carrying, you are usually pre- - sented with a list of inventory letters to choose from (see Com- - mands, above). - - Some objects, such as weapons, are easily differentiated. - Others, like scrolls and potions, are given descriptions which - vary according to type. During a game, any two objects with the - same description are the same type. However, the descriptions - will vary from game to game. + sented with a list of inventory letters to choose from (see - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1654,63 +1654,63 @@ + Commands, above). + + Some objects, such as weapons, are easily differentiated. + Others, like scrolls and potions, are given descriptions which + vary according to type. During a game, any two objects with the + same description are the same type. However, the descriptions + will vary from game to game. + When you use one of these objects, if its effect is obvious, - NetHack will remember what it is for you. If its effect isn't - extremely obvious, you will be asked what you want to call this - type of object so you will recognize it later. You can also use - the ``#name'' command, or its synonym `C', for the same purpose - at any time, to name all objects of a particular type or just an + NetHack will remember what it is for you. If its effect isn't + extremely obvious, you will be asked what you want to call this + type of object so you will recognize it later. You can also use + the ``#name'' command, or its synonym `C', for the same purpose + at any time, to name all objects of a particular type or just an individual object. When you use ``#name'' on an object which has - already been named, specifying a space as the value will remove + already been named, specifying a space as the value will remove the prior name instead of assigning a new one. 7.1. Curses and Blessings - Any object that you find may be cursed, even if the object + Any object that you find may be cursed, even if the object is otherwise helpful. The most common effect of a curse is being - stuck with (and to) the item. Cursed weapons weld themselves to - your hand when wielded, so you cannot unwield them. Any cursed - item you wear is not removable by ordinary means. In addition, - cursed arms and armor usually, but not always, bear negative en- + stuck with (and to) the item. Cursed weapons weld themselves to + your hand when wielded, so you cannot unwield them. Any cursed + item you wear is not removable by ordinary means. In addition, + cursed arms and armor usually, but not always, bear negative en- chantments that make them less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. - Objects can also be blessed. Blessed items usually work - better or more beneficially than normal uncursed items. For ex- + Objects can also be blessed. Blessed items usually work + better or more beneficially than normal uncursed items. For ex- ample, a blessed weapon will do more damage against demons. Objects which are neither cursed nor blessed are referred to - as uncursed. They could just as easily have been described as - unblessed, but the uncursed designation is what you will see - within the game. A ``glass half full versus glass half empty'' + as uncursed. They could just as easily have been described as + unblessed, but the uncursed designation is what you will see + within the game. A ``glass half full versus glass half empty'' situation; make of that what you will. There are magical means of bestowing or removing curses upon - objects, so even if you are stuck with one, you can still have - the curse lifted and the item removed. Priests and Priestesses - have an innate sensitivity to this property in any object, so - they can more easily avoid cursed objects than other character + objects, so even if you are stuck with one, you can still have + the curse lifted and the item removed. Priests and Priestesses + have an innate sensitivity to this property in any object, so + they can more easily avoid cursed objects than other character roles. - An item with unknown status will be reported in your inven- + An item with unknown status will be reported in your inven- tory with no prefix. An item which you know the state of will be - distinguished in your inventory by the presence of the word + distinguished in your inventory by the presence of the word ``cursed'', ``uncursed'' or ``blessed'' in the description of the item. In some cases ``uncursed'' will be omitted as being redun- - dant when enough other information is displayed. The implic- - it_uncursed option can be used to control this; toggle it off to + dant when enough other information is displayed. The implic- + it_uncursed option can be used to control this; toggle it off to have ``uncursed'' be displayed even when that can be deduced from - other attributes. - - 7.2. Weapons (`)') - - Given a chance, most monsters in the Mazes of Menace will - gratuitously try to kill you. You need weapons for self-defense - (killing them first). Without a weapon, you do only 1-2 hit - points of damage (plus bonuses, if any). Monk characters are an - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1720,63 +1720,63 @@ + other attributes. + + 7.2. Weapons (`)') + + Given a chance, most monsters in the Mazes of Menace will + gratuitously try to kill you. You need weapons for self-defense + (killing them first). Without a weapon, you do only 1-2 hit + points of damage (plus bonuses, if any). Monk characters are an exception; they normally do much more damage with bare hands than they do with weapons. There are wielded weapons, like maces and swords, and thrown - weapons, like arrows and spears. To hit monsters with a weapon, - you must wield it and attack them, or throw it at them. You can - simply elect to throw a spear. To shoot an arrow, you should - first wield a bow, then throw the arrow. Crossbows shoot cross- + weapons, like arrows and spears. To hit monsters with a weapon, + you must wield it and attack them, or throw it at them. You can + simply elect to throw a spear. To shoot an arrow, you should + first wield a bow, then throw the arrow. Crossbows shoot cross- bow bolts. Slings hurl rocks and (other) stones (like gems). Enchanted weapons have a ``plus'' (or ``to hit enhancement'' - which can be either positive or negative) that adds to your - chance to hit and the damage you do to a monster. The only way + which can be either positive or negative) that adds to your + chance to hit and the damage you do to a monster. The only way to determine a weapon's enchantment is to have it magically iden- - tified somehow. Most weapons are subject to some type of damage + tified somehow. Most weapons are subject to some type of damage like rust. Such ``erosion'' damage can be repaired. - The chance that an attack will successfully hit a monster, - and the amount of damage such a hit will do, depends upon many - factors. Among them are: type of weapon, quality of weapon (en- + The chance that an attack will successfully hit a monster, + and the amount of damage such a hit will do, depends upon many + factors. Among them are: type of weapon, quality of weapon (en- chantment and/or erosion), experience level, strength, dexterity, - encumbrance, and proficiency (see below). The monster's armor - class - a general defense rating, not necessarily due to wearing - of armor - is a factor too; also, some monsters are particularly + encumbrance, and proficiency (see below). The monster's armor + class - a general defense rating, not necessarily due to wearing + of armor - is a factor too; also, some monsters are particularly vulnerable to certain types of weapons. - Many weapons can be wielded in one hand; some require both - hands. When wielding a two-handed weapon, you can not wear a - shield, and vice versa. When wielding a one-handed weapon, you - can have another weapon ready to use by setting things up with - the `x' command, which exchanges your primary (the one being - wielded) and alternate weapons. And if you have proficiency in - the ``two weapon combat'' skill, you may wield both weapons si- - multaneously as primary and secondary; use the `#twoweapon' ex- - tended command to engage or disengage that. Only some types of - characters (barbarians, for instance) have the necessary skill - available. Even with that skill, using two weapons at once in- + Many weapons can be wielded in one hand; some require both + hands. When wielding a two-handed weapon, you can not wear a + shield, and vice versa. When wielding a one-handed weapon, you + can have another weapon ready to use by setting things up with + the `x' command, which exchanges your primary (the one being + wielded) and alternate weapons. And if you have proficiency in + the ``two weapon combat'' skill, you may wield both weapons si- + multaneously as primary and secondary; use the `#twoweapon' ex- + tended command to engage or disengage that. Only some types of + characters (barbarians, for instance) have the necessary skill + available. Even with that skill, using two weapons at once in- curs a penalty in the chance to hit your target compared to using just one weapon at a time. - There might be times when you'd rather not wield any weapon - at all. To accomplish that, wield `-', or else use the `A' com- - mand which allows you to unwield the current weapon in addition + There might be times when you'd rather not wield any weapon + at all. To accomplish that, wield `-', or else use the `A' com- + mand which allows you to unwield the current weapon in addition to taking off other worn items. - Those of you in the audience who are AD&D players, be aware - that each weapon which existed in AD&D does roughly the same dam- - age to monsters in NetHack. Some of the more obscure weapons - (such as the aklys, lucern hammer, and bec-de-corbin) are defined - in an appendix to Unearthed Arcana, an AD&D supplement. - - The commands to use weapons are `w' (wield), `t' (throw), - `f' (fire, an alternative way of throwing), `Q' (quiver), `x' - (exchange), `#twoweapon', and `#enhance' (see below). - NetHack 3.6 January 18, 2016 + + NetHack 3.6 February 22, 2016 @@ -1786,63 +1786,63 @@ + Those of you in the audience who are AD&D players, be aware + that each weapon which existed in AD&D does roughly the same dam- + age to monsters in NetHack. Some of the more obscure weapons + (such as the aklys, lucern hammer, and bec-de-corbin) are defined + in an appendix to Unearthed Arcana, an AD&D supplement. + + The commands to use weapons are `w' (wield), `t' (throw), + `f' (fire, an alternative way of throwing), `Q' (quiver), `x' + (exchange), `#twoweapon', and `#enhance' (see below). + 7.2.1. Throwing and shooting - You can throw just about anything via the `t' command. It - will prompt for the item to throw; picking `?' will list things - in your inventory which are considered likely to be thrown, or + You can throw just about anything via the `t' command. It + will prompt for the item to throw; picking `?' will list things + in your inventory which are considered likely to be thrown, or picking `*' will list your entire inventory. After you've chosen - what to throw, you will be prompted for a direction rather than - for a specific target. The distance something can be thrown de- + what to throw, you will be prompted for a direction rather than + for a specific target. The distance something can be thrown de- pends mainly on the type of object and your strength. Arrows can - be thrown by hand, but can be thrown much farther and will be + be thrown by hand, but can be thrown much farther and will be more likely to hit when thrown while you are wielding a bow. - You can simplify the throwing operation by using the `Q' - command to select your preferred ``missile'', then using the `f' - command to throw it. You'll be prompted for a direction as - above, but you don't have to specify which item to throw each + You can simplify the throwing operation by using the `Q' + command to select your preferred ``missile'', then using the `f' + command to throw it. You'll be prompted for a direction as + above, but you don't have to specify which item to throw each time you use `f'. There is also an option, autoquiver, which has NetHack choose another item to automatically fill your quiver (or - quiver sack, or have at the ready) when the inventory slot used + quiver sack, or have at the ready) when the inventory slot used for `Q' runs out. - Some characters have the ability to fire a volley of multi- - ple items in a single turn. Knowing how to load several rounds + Some characters have the ability to fire a volley of multi- + ple items in a single turn. Knowing how to load several rounds of ammunition at once -- or hold several missiles in your hand -- - and still hit a target is not an easy task. Rangers are among - those who are adept at this task, as are those with a high level - of proficiency in the relevant weapon skill (in bow skill if - you're wielding one to shoot arrows, in crossbow skill if you're + and still hit a target is not an easy task. Rangers are among + those who are adept at this task, as are those with a high level + of proficiency in the relevant weapon skill (in bow skill if + you're wielding one to shoot arrows, in crossbow skill if you're wielding one to shoot bolts, or in sling skill if you're wielding one to shoot stones). The number of items that the character has - a chance to fire varies from turn to turn. You can explicitly - limit the number of shots by using a numeric prefix before the - `t' or `f' command. For example, ``2f'' (or ``n2f'' if using + a chance to fire varies from turn to turn. You can explicitly + limit the number of shots by using a numeric prefix before the + `t' or `f' command. For example, ``2f'' (or ``n2f'' if using number_pad mode) would ensure that at most 2 arrows are shot even - if you could have fired 3. If you specify a larger number than + if you could have fired 3. If you specify a larger number than would have been shot (``4f'' in this example), you'll just end up shooting the same number (3, here) as if no limit had been speci- fied. Once the volley is in motion, all of the items will travel in the same direction; if the first ones kill a monster, the oth- ers can still continue beyond that spot. - 7.2.2. Weapon proficiency - - You will have varying degrees of skill in the weapons avail- - able. Weapon proficiency, or weapon skills, affect how well you - can use particular types of weapons, and you'll be able to im- - prove your skills as you progress through a game, depending on - your role, your experience level, and use of the weapons. - - For the purposes of proficiency, weapons have been divided - up into various groups such as daggers, broadswords, and - polearms. Each role has a limit on what level of proficiency a - character can achieve for each group. For instance, wizards can - become highly skilled in daggers or staves but not in swords or - NetHack 3.6 January 18, 2016 + + + + NetHack 3.6 February 22, 2016 @@ -1852,63 +1852,63 @@ + 7.2.2. Weapon proficiency + + You will have varying degrees of skill in the weapons avail- + able. Weapon proficiency, or weapon skills, affect how well you + can use particular types of weapons, and you'll be able to im- + prove your skills as you progress through a game, depending on + your role, your experience level, and use of the weapons. + + For the purposes of proficiency, weapons have been divided + up into various groups such as daggers, broadswords, and + polearms. Each role has a limit on what level of proficiency a + character can achieve for each group. For instance, wizards can + become highly skilled in daggers or staves but not in swords or bows. - The `#enhance' extended command is used to review current - weapons proficiency (also spell proficiency) and to choose which + The `#enhance' extended command is used to review current + weapons proficiency (also spell proficiency) and to choose which skill(s) to improve when you've used one or more skills enough to become eligible to do so. The skill rankings are ``none'' (some- - times also referred to as ``restricted'', because you won't be - able to advance), ``unskilled'', ``basic'', ``skilled'', and + times also referred to as ``restricted'', because you won't be + able to advance), ``unskilled'', ``basic'', ``skilled'', and ``expert''. Restricted skills simply will not appear in the list - shown by `#enhance'. (Divine intervention might unrestrict a + shown by `#enhance'. (Divine intervention might unrestrict a particular skill, in which case it will start at unskilled and be - limited to basic.) Some characters can enhance their barehanded - combat or martial arts skill beyond expert to ``master'' or + limited to basic.) Some characters can enhance their barehanded + combat or martial arts skill beyond expert to ``master'' or ``grand master''. Use of a weapon in which you're restricted or unskilled will incur a modest penalty in the chance to hit a monster and also in - the amount of damage done when you do hit; at basic level, there - is no penalty or bonus; at skilled level, you receive a modest - bonus in the chance to hit and amount of damage done; at expert - level, the bonus is higher. A successful hit has a chance to - boost your training towards the next skill level (unless you've - already reached the limit for this skill). Once such training - reaches the threshold for that next level, you'll be told that - you feel more confident in your skills. At that point you can - use `#enhance' to increase one or more skills. Such skills are - not increased automatically because there is a limit to your to- - tal overall skills, so you need to actively choose which skills + the amount of damage done when you do hit; at basic level, there + is no penalty or bonus; at skilled level, you receive a modest + bonus in the chance to hit and amount of damage done; at expert + level, the bonus is higher. A successful hit has a chance to + boost your training towards the next skill level (unless you've + already reached the limit for this skill). Once such training + reaches the threshold for that next level, you'll be told that + you feel more confident in your skills. At that point you can + use `#enhance' to increase one or more skills. Such skills are + not increased automatically because there is a limit to your to- + tal overall skills, so you need to actively choose which skills to enhance and which to ignore. 7.2.3. Two-Weapon combat Some characters can use two weapons at once. Setting things - up to do so can seem cumbersome but becomes second nature with - use. To wield two weapons, you need to use the ``#twoweapon'' - command. But first you need to have a weapon in each hand. - (Note that your two weapons are not fully equal; the one in the - hand you normally wield with is considered primary and the other - one is considered secondary. The most noticeable difference is - after you stop--or before you begin, for that matter--wielding - two weapons at once. The primary is your wielded weapon and the - secondary is just an item in your inventory that's been designat- - ed as alternate weapon.) - - If your primary weapon is wielded but your off hand is empty - or has the wrong weapon, use the sequence 'x', 'w', 'x' to first - swap your primary into your off hand, wield whatever you want as - secondary weapon, then swap them both back into the intended - hands. If your secondary or alternate weapon is correct but your - primary one is not, simply use 'w' to wield the primary. Lastly, - if neither hand holds the correct weapon, use 'w', 'x', 'w' to - first wield the intended secondary, swap it to off hand, and then - wield the primary. + up to do so can seem cumbersome but becomes second nature with + use. To wield two weapons, you need to use the ``#twoweapon'' + command. But first you need to have a weapon in each hand. + (Note that your two weapons are not fully equal; the one in the + hand you normally wield with is considered primary and the other + one is considered secondary. The most noticeable difference is + after you stop--or before you begin, for that matter--wielding + two weapons at once. The primary is your wielded weapon and the - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -1918,27 +1918,40 @@ - The whole process can be simplified via use of the push- + secondary is just an item in your inventory that's been designat- + ed as alternate weapon.) + + If your primary weapon is wielded but your off hand is empty + or has the wrong weapon, use the sequence 'x', 'w', 'x' to first + swap your primary into your off hand, wield whatever you want as + secondary weapon, then swap them both back into the intended + hands. If your secondary or alternate weapon is correct but your + primary one is not, simply use 'w' to wield the primary. Lastly, + if neither hand holds the correct weapon, use 'w', 'x', 'w' to + first wield the intended secondary, swap it to off hand, and then + wield the primary. + + The whole process can be simplified via use of the push- weapon option. When it is enabled, then using 'w' to wield some- - thing causes the currently wielded weapon to become your alter- + thing causes the currently wielded weapon to become your alter- nate weapon. So the sequence 'w', 'w' can be used to first wield the weapon you intend to be secondary, and then wield the one you - want as primary which will push the first into secondary posi- + want as primary which will push the first into secondary posi- tion. - When in two-weapon combat mode, using the ``#twoweapon'' + When in two-weapon combat mode, using the ``#twoweapon'' command toggles back to single-weapon mode. Throwing or dropping - either of the weapons or having one of them be stolen or de- + either of the weapons or having one of them be stolen or de- stroyed will also make you revert to single-weapon combat. 7.3. Armor (`[') Lots of unfriendly things lurk about; you need armor to pro- tect yourself from their blows. Some types of armor offer better - protection than others. Your armor class is a measure of this + protection than others. Your armor class is a measure of this protection. Armor class (AC) is measured as in AD&D, with 10 be- - ing the equivalent of no armor, and lower numbers meaning better - armor. Each suit of armor which exists in AD&D gives the same + ing the equivalent of no armor, and lower numbers meaning better + armor. Each suit of armor which exists in AD&D gives the same protection in NetHack. Here is an (incomplete) list of the armor classes provided by various suits of armor: @@ -1953,28 +1966,15 @@ chain mail 5 orcish chain mail 6 scale mail 6 + dragon scales 7 studded leather armor 7 ring mail 7 orcish ring mail 8 leather armor 8 - leather jacket 9 - no armor 10 - - You can also wear other pieces of armor (ex. helmets, boots, - shields, cloaks) to lower your armor class even further, but you - can only wear one item of each category (one suit of armor, one - cloak, one helmet, one shield, and so on) at a time. - - If a piece of armor is enchanted, its armor protection will - be better (or worse) than normal, and its ``plus'' (or minus) - will subtract from your armor class. For example, a +1 chain - mail would give you better protection than normal chain mail, - lowering your armor class one unit further to 4. When you put on - a piece of armor, you immediately find out the armor class and - any ``plusses'' it provides. Cursed pieces of armor usually have - NetHack 3.6 January 18, 2016 + + NetHack 3.6 February 22, 2016 @@ -1984,63 +1984,63 @@ + leather jacket 9 + no armor 10 + + You can also wear other pieces of armor (ex. helmets, boots, + shields, cloaks) to lower your armor class even further, but you + can only wear one item of each category (one suit of armor, one + cloak, one helmet, one shield, and so on) at a time. + + If a piece of armor is enchanted, its armor protection will + be better (or worse) than normal, and its ``plus'' (or minus) + will subtract from your armor class. For example, a +1 chain + mail would give you better protection than normal chain mail, + lowering your armor class one unit further to 4. When you put on + a piece of armor, you immediately find out the armor class and + any ``plusses'' it provides. Cursed pieces of armor usually have negative enchantments (minuses) in addition to being unremovable. - Many types of armor are subject to some kind of damage like - rust. Such damage can be repaired. Some types of armor may in- + Many types of armor are subject to some kind of damage like + rust. Such damage can be repaired. Some types of armor may in- hibit spell casting. The commands to use armor are `W' (wear) and `T' (take off). - The `A' command can also be used to take off armor as well as + The `A' command can also be used to take off armor as well as other worn items. 7.4. Food (`%') - Food is necessary to survive. If you go too long without - eating you will faint, and eventually die of starvation. Some - types of food will spoil, and become unhealthy to eat, if not + Food is necessary to survive. If you go too long without + eating you will faint, and eventually die of starvation. Some + types of food will spoil, and become unhealthy to eat, if not protected. Food stored in ice boxes or tins (``cans'') will usu- - ally stay fresh, but ice boxes are heavy, and tins take a while + ally stay fresh, but ice boxes are heavy, and tins take a while to open. When you kill monsters, they usually leave corpses which are also ``food.'' Many, but not all, of these are edible; some also - give you special powers when you eat them. A good rule of thumb + give you special powers when you eat them. A good rule of thumb is ``you are what you eat.'' Some character roles and some monsters are vegetarian. Veg- - etarian monsters will typically never eat animal corpses, while - vegetarian players can, but with some rather unpleasant side-ef- + etarian monsters will typically never eat animal corpses, while + vegetarian players can, but with some rather unpleasant side-ef- fects. - You can name one food item after something you like to eat + You can name one food item after something you like to eat with the fruit option. The command to eat food is `e'. 7.5. Scrolls (`?') - Scrolls are labeled with various titles, probably chosen by - ancient wizards for their amusement value (ex. ``READ ME,'' or + Scrolls are labeled with various titles, probably chosen by + ancient wizards for their amusement value (ex. ``READ ME,'' or ``THANX MAUD'' backwards). Scrolls disappear after you read them - (except for blank ones, without magic spells on them). - - One of the most useful of these is the scroll of identify, - which can be used to determine what another object is, whether it - is cursed or blessed, and how many uses it has left. Some ob- - jects of subtle enchantment are difficult to identify without - these. - - A mail daemon may run up and deliver mail to you as a scroll - of mail (on versions compiled with this feature). To use this - feature on versions where NetHack mail delivery is triggered by - electronic mail appearing in your system mailbox, you must let - NetHack know where to look for new mail by setting the ``MAIL'' - environment variable to the file name of your mailbox. You may - also want to set the ``MAILREADER'' environment variable to the - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2050,36 +2050,50 @@ - file name of your favorite reader, so NetHack can shell to it - when you read the scroll. On versions of NetHack where mail is - randomly generated internal to the game, these environment vari- - ables are ignored. You can disable the mail daemon by turning + (except for blank ones, without magic spells on them). + + One of the most useful of these is the scroll of identify, + which can be used to determine what another object is, whether it + is cursed or blessed, and how many uses it has left. Some ob- + jects of subtle enchantment are difficult to identify without + these. + + A mail daemon may run up and deliver mail to you as a scroll + of mail (on versions compiled with this feature). To use this + feature on versions where NetHack mail delivery is triggered by + electronic mail appearing in your system mailbox, you must let + NetHack know where to look for new mail by setting the ``MAIL'' + environment variable to the file name of your mailbox. You may + also want to set the ``MAILREADER'' environment variable to the + file name of your favorite reader, so NetHack can shell to it + when you read the scroll. On versions of NetHack where mail is + randomly generated internal to the game, these environment vari- + ables are ignored. You can disable the mail daemon by turning off the mail option. The command to read a scroll is `r'. 7.6. Potions (`!') - Potions are distinguished by the color of the liquid inside + Potions are distinguished by the color of the liquid inside the flask. They disappear after you quaff them. - Clear potions are potions of water. Sometimes these are + Clear potions are potions of water. Sometimes these are blessed or cursed, resulting in holy or unholy water. Holy water - is the bane of the undead, so potions of holy water are good - things to throw (`t') at them. It is also sometimes very useful + is the bane of the undead, so potions of holy water are good + things to throw (`t') at them. It is also sometimes very useful to dip (``#dip'') an object into a potion. The command to drink a potion is `q' (quaff). 7.7. Wands (`/') - Magic wands usually have multiple magical charges. Some - wands are directional--you must give a direction in which to zap - them. You can also zap them at yourself (just give a `.' or `s' - for the direction). Be warned, however, for this is often unwise. - Other wands are nondirectional--they don't require a direction. - The number of charges in a wand is random and decreases by one - whenever you use it. + Wands usually have multiple magical charges. Some types of + wands require a direction in which to zap them. You can also zap + them at yourself (just give a `.' or `s' for the direction). Be + warned, however, for this is often unwise. Other types of wands + don't require a direction. The number of charges in a wand is + random and decreases by one whenever you use it. When the number of charges left in a wand becomes zero, at- tempts to use the wand will usually result in nothing happening. @@ -2090,6 +2104,18 @@ such an explosion starts out very small and increases each time the wand is recharged. + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 33 + + + In a truly desperate situation, when your back is up against the wall, you might decide to go for broke and break your wand. This is not for the faint of heart. Doing so will almost cer- @@ -2104,18 +2130,6 @@ The command to use a wand is `z' (zap). To break one, use the `a' (apply) command. - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 33 - - - 7.8. Rings (`=') Rings are very useful items, since they are relatively per- @@ -2147,32 +2161,18 @@ Casting a spell calls forth magical energies and focuses them with your naked mind. Some of the magical energy released - comes from within you, and casting several spells in a row may - tire you. Casting of spells also requires practice. With prac- - tice, your skill in each category of spell casting will improve. - Over time, however, your memory of each spell will dim, and you - will need to relearn it. + comes from within you. Casting temporarily drains your magical + power, which will slowly be recovered, and causes you to need ad- + ditional food. Casting of spells also requires practice. With + practice, your skill in each category of spell casting will im- + prove. Over time, however, your memory of each spell will dim, + and you will need to relearn it. - Some spells are directional--you must give a direction in - which to cast them. You can also cast them at yourself (just - give a `.' or `s' for the direction). Be warned, however, for - this is often unwise. Other spells are nondirectional--they - don't require a direction. - - Just as weapons are divided into groups in which a character - can become proficient (to varying degrees), spells are similarly - grouped. Successfully casting a spell exercises its skill group; - using the `#enhance' command to advance a sufficiently exercised - skill will affect all spells within the group. Advanced skill - may increase the potency of spells, reduce their risk of failure - during casting attempts, and improve the accuracy of the estimate - for how much longer they will be retained in your memory. Skill - slots are shared with weapons skills. (See also the section on - ``Weapon proficiency''.) + Some spells require a direction in which to cast them, simi- + lar to wands. To cast one at yourself, just give a `.' or `s' - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2182,34 +2182,49 @@ + for the direction. A few spells require you to pick a target lo- + cation rather than just specify a particular direction. Other + spells don't require any direction or target. + + Just as weapons are divided into groups in which a character + can become proficient (to varying degrees), spells are similarly + grouped. Successfully casting a spell exercises its skill group; + using the `#enhance' command to advance a sufficiently exercised + skill will affect all spells within the group. Advanced skill + may increase the potency of spells, reduce their risk of failure + during casting attempts, and improve the accuracy of the estimate + for how much longer they will be retained in your memory. Skill + slots are shared with weapons skills. (See also the section on + ``Weapon proficiency''.) + Casting a spell also requires flexible movement, and wearing various types of armor may interfere with that. - The command to read a spellbook is the same as for scrolls, + The command to read a spellbook is the same as for scrolls, `r' (read). The `+' command lists each spell you know along with its level, skill category, chance of failure when casting, and an - estimate of how strongly it is remembered. The `Z' (cast) com- + estimate of how strongly it is remembered. The `Z' (cast) com- mand casts a spell. 7.10. Tools (`(') Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For - example, lamps burn out after a while. Other tools are contain- + tools have a limited number of uses, akin to wand charges. For + example, lamps burn out after a while. Other tools are contain- ers, which objects can be placed into or taken out of. The command to use tools is `a' (apply). 7.10.1. Containers - You may encounter bags, boxes, and chests in your travels. - A tool of this sort can be opened with the ``#loot'' extended - command when you are standing on top of it (that is, on the same - floor spot), or with the `a' (apply) command when you are carry- - ing it. However, chests are often locked, and are in any case - unwieldy objects. You must set one down before unlocking it by + You may encounter bags, boxes, and chests in your travels. + A tool of this sort can be opened with the ``#loot'' extended + command when you are standing on top of it (that is, on the same + floor spot), or with the `a' (apply) command when you are carry- + ing it. However, chests are often locked, and are in any case + unwieldy objects. You must set one down before unlocking it by using a key or lock-picking tool with the `a' (apply) command, by - kicking it with the `^D' command, or by using a weapon to force + kicking it with the `^D' command, or by using a weapon to force the lock with the ``#force'' extended command. Some chests are trapped, causing nasty things to happen when @@ -2218,27 +2233,12 @@ 7.11. Amulets (`"') - Amulets are very similar to rings, and often more powerful. + Amulets are very similar to rings, and often more powerful. Like rings, amulets have various magical properties, some benefi- cial, some harmful, which are activated by putting them on. - Only one amulet may be worn at a time, around your neck. - The commands to use amulets are the same as for rings, `P' - (put on) and `R' (remove). - - 7.12. Gems (`*') - - Some gems are valuable, and can be sold for a lot of gold. - They are also a far more efficient way of carrying your riches. - Valuable gems increase your score if you bring them with you when - you exit. - - Other small rocks are also categorized as gems, but they are - much less valuable. All rocks, however, can be used as - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2248,63 +2248,63 @@ - projectile weapons (if you have a sling). In the most desperate - of cases, you can still throw them by hand. + Only one amulet may be worn at a time, around your neck. + + The commands to use amulets are the same as for rings, `P' + (put on) and `R' (remove). + + 7.12. Gems (`*') + + Some gems are valuable, and can be sold for a lot of gold. + They are also a far more efficient way of carrying your riches. + Valuable gems increase your score if you bring them with you when + you exit. + + Other small rocks are also categorized as gems, but they are + much less valuable. All rocks, however, can be used as projec- + tile weapons (if you have a sling). In the most desperate of + cases, you can still throw them by hand. 7.13. Large rocks (``') - Statues and boulders are not particularly useful, and are - generally heavy. It is rumored that some statues are not what + Statues and boulders are not particularly useful, and are + generally heavy. It is rumored that some statues are not what they seem. - Very large humanoids (giants and their ilk) have been known + Very large humanoids (giants and their ilk) have been known to use boulders as weapons. + For some configurations of the program, statues are no + longer shown as ``' but by the letter representing the monster + they depict instead. + 7.14. Gold (`$') - Gold adds to your score, and you can buy things in shops - with it. There are a number of monsters in the dungeon that may + Gold adds to your score, and you can buy things in shops + with it. There are a number of monsters in the dungeon that may be influenced by the amount of gold you are carrying (shopkeepers aside). 8. Conduct - As if winning NetHack were not difficult enough, certain - players seek to challenge themselves by imposing restrictions on - the way they play the game. The game automatically tracks some - of these challenges, which can be checked at any time with the - #conduct command or at the end of the game. When you perform an - action which breaks a challenge, it will no longer be listed. + As if winning NetHack were not difficult enough, certain + players seek to challenge themselves by imposing restrictions on + the way they play the game. The game automatically tracks some + of these challenges, which can be checked at any time with the + #conduct command or at the end of the game. When you perform an + action which breaks a challenge, it will no longer be listed. This gives players extra ``bragging rights'' for winning the game - with these challenges. Note that it is perfectly acceptable to - win the game without resorting to these restrictions and that it - is unusual for players to adhere to challenges the first time + with these challenges. Note that it is perfectly acceptable to + win the game without resorting to these restrictions and that it + is unusual for players to adhere to challenges the first time they win the game. - Several of the challenges are related to eating behavior. - The most difficult of these is the foodless challenge. Although - creatures can survive long periods of time without food, there is - a physiological need for water; thus there is no restriction on - drinking beverages, even if they provide some minor food bene- - fits. Calling upon your god for help with starvation does not - violate any food challenges either. - - A strict vegan diet is one which avoids any food derived - from animals. The primary source of nutrition is fruits and veg- - etables. The corpses and tins of blobs (`b'), jellies (`j'), and - fungi (`F') are also considered to be vegetable matter. Certain - human food is prepared without animal products; namely, lembas - wafers, cram rations, food rations (gunyoki), K-rations, and C- - rations. Metal or another normally indigestible material eaten - while polymorphed into a creature that can digest it is also con- - sidered vegan food. Note however that eating such items still - counts against foodless conduct. + Several of the challenges are related to eating behavior. + The most difficult of these is the foodless challenge. Although - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2314,63 +2314,63 @@ - Vegetarians do not eat animals; however, they are less se- - lective about eating animal byproducts than vegans. In addition + creatures can survive long periods of time without food, there is + a physiological need for water; thus there is no restriction on + drinking beverages, even if they provide some minor food bene- + fits. Calling upon your god for help with starvation does not + violate any food challenges either. + + A strict vegan diet is one which avoids any food derived + from animals. The primary source of nutrition is fruits and veg- + etables. The corpses and tins of blobs (`b'), jellies (`j'), and + fungi (`F') are also considered to be vegetable matter. Certain + human food is prepared without animal products; namely, lembas + wafers, cram rations, food rations (gunyoki), K-rations, and C- + rations. Metal or another normally indigestible material eaten + while polymorphed into a creature that can digest it is also con- + sidered vegan food. Note however that eating such items still + counts against foodless conduct. + + Vegetarians do not eat animals; however, they are less se- + lective about eating animal byproducts than vegans. In addition to the vegan items listed above, they may eat any kind of pudding (`P') other than the black puddings, eggs and food made from eggs - (fortune cookies and pancakes), food made with milk (cream pies + (fortune cookies and pancakes), food made with milk (cream pies and candy bars), and lumps of royal jelly. Monks are expected to observe a vegetarian diet. - Eating any kind of meat violates the vegetarian, vegan, and - foodless conducts. This includes tripe rations, the corpses or - tins of any monsters not mentioned above, and the various other - chunks of meat found in the dungeon. Swallowing and digesting a + Eating any kind of meat violates the vegetarian, vegan, and + foodless conducts. This includes tripe rations, the corpses or + tins of any monsters not mentioned above, and the various other + chunks of meat found in the dungeon. Swallowing and digesting a monster while polymorphed is treated as if you ate the creature's - corpse. Eating leather, dragon hide, or bone items while poly- - morphed into a creature that can digest it, or eating monster + corpse. Eating leather, dragon hide, or bone items while poly- + morphed into a creature that can digest it, or eating monster brains while polymorphed into a mind flayer, is considered eating an animal, although wax is only an animal byproduct. - Regardless of conduct, there will be some items which are - indigestible, and others which are hazardous to eat. Using a + Regardless of conduct, there will be some items which are + indigestible, and others which are hazardous to eat. Using a swallow-and-digest attack against a monster is equivalent to eat- ing the monster's corpse. Please note that the term ``vegan'' is - used here only in the context of diet. You are still free to - choose not to use or wear items derived from animals (e.g. - leather, dragon hide, bone, horns, coral), but the game will not + used here only in the context of diet. You are still free to + choose not to use or wear items derived from animals (e.g. + leather, dragon hide, bone, horns, coral), but the game will not keep track of this for you. Also note that ``milky'' potions may be a translucent white, but they do not contain milk, so they are - compatible with a vegan diet. Slime molds or player-defined - ``fruits'', although they could be anything from ``cherries'' to + compatible with a vegan diet. Slime molds or player-defined + ``fruits'', although they could be anything from ``cherries'' to ``pork chops'', are also assumed to be vegan. An atheist is one who rejects religion. This means that you - cannot #pray, #offer sacrifices to any god, #turn undead, or - #chat with a priest. Particularly selective readers may argue - that playing Monk or Priest characters should violate this con- - duct; that is a choice left to the player. Offering the Amulet - of Yendor to your god is necessary to win the game and is not - counted against this conduct. You are also not penalized for be- - ing spoken to by an angry god, priest(ess), or other religious - figure; a true atheist would hear the words but attach no special - meaning to them. - - Most players fight with a wielded weapon (or tool intended - to be wielded as a weapon). Another challenge is to win the game - without using such a wielded weapon. You are still permitted to - throw, fire, and kick weapons; use a wand, spell, or other type - of item; or fight with your hands and feet. - - In NetHack, a pacifist refuses to cause the death of any - other monster (i.e. if you would get experience for the death). - This is a particularly difficult challenge, although it is still - possible to gain experience by other means. + cannot #pray, #offer sacrifices to any god, #turn undead, or + #chat with a priest. Particularly selective readers may argue + that playing Monk or Priest characters should violate this con- + duct; that is a choice left to the player. Offering the Amulet + of Yendor to your god is necessary to win the game and is not - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2380,63 +2380,63 @@ + counted against this conduct. You are also not penalized for be- + ing spoken to by an angry god, priest(ess), or other religious + figure; a true atheist would hear the words but attach no special + meaning to them. + + Most players fight with a wielded weapon (or tool intended + to be wielded as a weapon). Another challenge is to win the game + without using such a wielded weapon. You are still permitted to + throw, fire, and kick weapons; use a wand, spell, or other type + of item; or fight with your hands and feet. + + In NetHack, a pacifist refuses to cause the death of any + other monster (i.e. if you would get experience for the death). + This is a particularly difficult challenge, although it is still + possible to gain experience by other means. + An illiterate character cannot read or write. This includes - reading a scroll, spellbook, fortune cookie message, or t-shirt; + reading a scroll, spellbook, fortune cookie message, or t-shirt; writing a scroll; or making an engraving of anything other than a single ``x'' (the traditional signature of an illiterate person). Reading an engraving, or any item that is absolutely necessary to - win the game, is not counted against this conduct. The identity - of scrolls and spellbooks (and knowledge of spells) in your - starting inventory is assumed to be learned from your teachers + win the game, is not counted against this conduct. The identity + of scrolls and spellbooks (and knowledge of spells) in your + starting inventory is assumed to be learned from your teachers prior to the start of the game and isn't counted. - There are several other challenges tracked by the game. It + There are several other challenges tracked by the game. It is possible to eliminate one or more species of monsters by geno- - cide; playing without this feature is considered a challenge. + cide; playing without this feature is considered a challenge. When the game offers you an opportunity to genocide monsters, you - may respond with the monster type ``none'' if you want to de- - cline. You can change the form of an item into another item of - the same type (``polypiling'') or the form of your own body into - another creature (``polyself'') by wand, spell, or potion of + may respond with the monster type ``none'' if you want to de- + cline. You can change the form of an item into another item of + the same type (``polypiling'') or the form of your own body into + another creature (``polyself'') by wand, spell, or potion of polymorph; avoiding these effects are each considered challenges. - Polymorphing monsters, including pets, does not break either of - these challenges. Finally, you may sometimes receive wishes; a - game without an attempt to wish for any items is a challenge, as - is a game without wishing for an artifact (even if the artifact + Polymorphing monsters, including pets, does not break either of + these challenges. Finally, you may sometimes receive wishes; a + game without an attempt to wish for any items is a challenge, as + is a game without wishing for an artifact (even if the artifact immediately disappears). When the game offers you an opportunity - to make a wish for an item, you may choose ``nothing'' if you + to make a wish for an item, you may choose ``nothing'' if you want to decline. 9. Options - Due to variations in personal tastes and conceptions of how + Due to variations in personal tastes and conceptions of how NetHack should do things, there are options you can set to change how NetHack behaves. 9.1. Setting the options - Options may be set in a number of ways. Within the game, + Options may be set in a number of ways. Within the game, the `O' command allows you to view all options and change most of - them. You can also set options automatically by placing them in - the NETHACKOPTIONS environment variable or in a configuration - file. Some versions of NetHack also have front-end programs that - allow you to set options before starting the game or a global - configuration for system administrators. - - 9.2. Using the NETHACKOPTIONS environment variable - - The NETHACKOPTIONS variable is a comma-separated list of - initial values for the various options. Some can only be turned - on or off. You turn one of these on by adding the name of the - option to the list, and turn it off by typing a `!' or ``no'' be- - fore the name. Others take a character string as a value. You - can set string options by typing the option name, a colon or - equals sign, and then the value of the string. The value is ter- - minated by the next comma or the end of string. - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2446,14 +2446,31 @@ + them. You can also set options automatically by placing them in + the NETHACKOPTIONS environment variable or in a configuration + file. Some versions of NetHack also have front-end programs that + allow you to set options before starting the game or a global + configuration for system administrators. + + 9.2. Using the NETHACKOPTIONS environment variable + + The NETHACKOPTIONS variable is a comma-separated list of + initial values for the various options. Some can only be turned + on or off. You turn one of these on by adding the name of the + option to the list, and turn it off by typing a `!' or ``no'' be- + fore the name. Others take a character string as a value. You + can set string options by typing the option name, a colon or + equals sign, and then the value of the string. The value is ter- + minated by the next comma or the end of string. + For example, to set up an environment variable so that ``au- - toquiver'' is on, ``autopickup'' is off, the name is set to - ``Blue Meanie'', and the fruit is set to ``papaya'', you would + toquiver'' is on, ``autopickup'' is off, the name is set to + ``Blue Meanie'', and the fruit is set to ``papaya'', you would enter the command % setenv NETHACKOPTIONS "autoquiver,\!autopickup,name:Blue Meanie,fruit:papaya" - in csh (note the need to escape the ! since it's special to the + in csh (note the need to escape the ! since it's special to the shell), or $ NETHACKOPTIONS="autoquiver,!autopickup,name:Blue Meanie,fruit:papaya" @@ -2463,27 +2480,38 @@ 9.3. Using a configuration file - Any line in the configuration file starting with `#' is - treated as a comment. Any line in the configuration file start- - ing with ``OPTIONS='' may be filled out with options in the same + Any line in the configuration file starting with `#' is + treated as a comment. Any line in the configuration file start- + ing with ``OPTIONS='' may be filled out with options in the same syntax as in NETHACKOPTIONS. Any line starting with ``SYMBOLS='' is taken as defining the corresponding symbol in a different syn- - tax, a sequence of decimal numbers giving the character position - in the current font to be used in displaying each entry. Such a - sequence can be continued to multiple lines by putting a `\' at + tax, a sequence of decimal numbers giving the character position + in the current font to be used in displaying each entry. Such a + sequence can be continued to multiple lines by putting a `\' at the end of each line to be continued. Any line starting with ``AUTOPICKUP_EXCEPTION='' is taken as - defining an exception to the pickup_types option. There is a + defining an exception to the pickup_types option. There is a section of this Guidebook that discusses that. The default name of the configuration file varies on differ- - ent operating systems. On DOS and Windows, it is ``defaults.nh'' + ent operating systems. On DOS and Windows, it is ``defaults.nh'' in the same folder as nethack.exe or nethackW.exe. On Unix, Linux - and Mac OS X it is ``.nethackrc'' in the user's home directory. - NETHACKOPTIONS can also be set to the full name of a file you + and Mac OS X it is ``.nethackrc'' in the user's home directory. + NETHACKOPTIONS can also be set to the full name of a file you want to use (possibly preceded by an `@'). + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 39 + + + Here is a short example of config file contents: # Set your character's role, race, gender, and alignment. @@ -2499,45 +2527,32 @@ # No startup splash screen. Windows GUI only. OPTIONS=!splash_screen - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 39 - - - 9.4. Customization options Here are explanations of what the various options do. Char- - acter strings that are too long may be truncated. Some of the + acter strings that are too long may be truncated. Some of the options listed may be inactive in your dungeon. - Some options are persistent, and are saved and reloaded + Some options are persistent, and are saved and reloaded along with the game. Changing a persistent option in the config- uration file applies only to new games. acoustics - Enable messages about what your character hears (default on). + Enable messages about what your character hears (default on). Note that this has nothing to do with your computer's audio ca- pabilities. Persistent. align - Your starting alignment (align:lawful, align:neutral, or - align:chaotic). You may specify just the first letter. The - default is to randomly pick an appropriate alignment. If you - prefix a `!' or ``no'' to the value, you can exclude that - alignment from being picked randomly. Cannot be set with the + Your starting alignment (align:lawful, align:neutral, or + align:chaotic). You may specify just the first letter. The + default is to randomly pick an appropriate alignment. If you + prefix the value with `!' or ``no'', you will exclude that + alignment from being picked randomly. Cannot be set with the `O' command. Persistent. autodescribe - Automatically describe the terrain under cursor when asked to - get a location on the map. The whatis_coord option controls + Automatically describe the terrain under cursor when asked to + get a location on the map. The whatis_coord option controls whether the description includes map coordinates. autodig @@ -2549,26 +2564,11 @@ tent. autopickup - Automatically pick up things onto which you move (default on). + Automatically pick up things onto which you move (default on). Persistent. See pickup_types to refine the behavior. - autoquiver - This option controls what happens when you attempt the `f' - (fire) command with an empty quiver (or quiver sack or have - nothing at the ready). When true, the computer will fill your - quiver or quiver sack or make ready some suitable weapon. Note - that it will not take into account the blessed/cursed status, - enchantment, damage, or quality of the weapon; you are free to - manually fill your quiver or quiver sack or make ready with the - `Q' command instead. If no weapon is found or the option is - false, the `t' (throw) command is executed instead. Persis- - tent. (default false) - blind - Start the character permanently blind. Persistent. (default - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2578,63 +2578,63 @@ + autoquiver + This option controls what happens when you attempt the `f' + (fire) command with an empty quiver (or quiver sack or have + nothing at the ready). When true, the computer will fill your + quiver or quiver sack or make ready some suitable weapon. Note + that it will not take into account the blessed/cursed status, + enchantment, damage, or quality of the weapon; you are free to + manually fill your quiver or quiver sack or make ready with the + `Q' command instead. If no weapon is found or the option is + false, the `t' (throw) command is executed instead. Persis- + tent. (default false) + + blind + Start the character permanently blind. Persistent. (default false) bones - Allow saving and loading bones files. Persistent. (default + Allow saving and loading bones files. Persistent. (default true) boulder - Set the character used to display boulders (default is rock - class symbol). + Set the character used to display boulders (default is the + ``large rock'' class symbol, ``'). catname Name your starting cat (ex. ``catname:Morris''). Cannot be set with the `O' command. character - Pick your type of character (ex. ``character:Monk''); synonym - for ``role''. See ``name'' for an alternate method of specify- - ing your role. Normally only the first letter of the value is - examined; the string ``random'' is an exception. + Synonym for ``role'' to pick the type of your character (ex. + ``character:Monk''). See role for more details. checkpoint - Save game state after each level change, for possible recovery + Save game state after each level change, for possible recovery after program crash (default on). Persistent. checkspace - Check free disk space before writing files to disk (default - on). You may have to turn this off if you have more than 2 GB - free space on the partition used for your save and level files. - Only applies when MFLOPPY was defined during compilation. + Check free disk space before writing files to disk (default + on). You may have to turn this off if you have more than 2 GB + free space on the partition used for your save and level files + (because too much space might overflow the calculation and end + up looking like insufficient space). Only applies when MFLOPPY + was defined during compilation. clicklook - Allows looking at things on the screen by navigating the mouse + Allows looking at things on the screen by navigating the mouse over them and clicking the right mouse button (default off). cmdassist - Have the game provide some additional command assistance for - new players if it detects some anticipated mistakes (default + Have the game provide some additional command assistance for + new players if it detects some anticipated mistakes (default on). - confirm - Have user confirm attacks on pets, shopkeepers, and other - peaceable creatures (default on). Persistent. - - dark_room - Show out-of-sight areas of lit rooms (default off). Persis- - tent. - - disclose - Controls what information the program reveals when the game - ends. Value is a space separated list of prompting/category - pairs (default is `ni na nv ng nc no', prompt with default re- - sponse of `n' for each candidate). Persistent. The possibili- - ties are: - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2644,6 +2644,21 @@ + confirm + Have user confirm attacks on pets, shopkeepers, and other + peaceable creatures (default on). Persistent. + + dark_room + Show out-of-sight areas of lit rooms (default off). Persis- + tent. + + disclose + Controls what information the program reveals when the game + ends. Value is a space separated list of prompting/category + pairs (default is `ni na nv ng nc no', prompt with default re- + sponse of `n' for each candidate). Persistent. The possibili- + ties are: + i - disclose your inventory; a - disclose your attributes; v - summarize monsters that have been vanquished; @@ -2651,8 +2666,8 @@ c - display your conduct; o - display dungeon overview. - Each disclosure possibility can optionally be preceded by a - prefix which lets you refine how it behaves. Here are the + Each disclosure possibility can optionally be preceded by a + prefix which lets you refine how it behaves. Here are the valid prefixes: y - prompt you and default to yes on the prompt; @@ -2662,30 +2677,42 @@ Omitted categories are implicitly added with `n' prefix. Spec- ified categories with omitted prefix implicitly use `+' prefix. - Order of the disclosure categories does not matter, program + Order of the disclosure categories does not matter, program display for end-of-game disclosure follows a set sequence. - (ex. ``disclose:yi na +v -g o'') The example sets inventory to - prompt and default to yes, attributes to prompt and default to - no, vanquished to disclose without prompting, genocided to not - disclose and not prompt, conduct to implicitly prompt and de- + (ex. ``disclose:yi na +v -g o'') The example sets inventory to + prompt and default to yes, attributes to prompt and default to + no, vanquished to disclose without prompting, genocided to not + disclose and not prompt, conduct to implicitly prompt and de- fault to no, and overview to disclose without prompting. - Note that the vanquished monsters list includes all monsters + Note that the vanquished monsters list includes all monsters killed by traps and each other as well as by you. And the dun- geon overview shows all levels you had visited but does not re- veal things about them that you hadn't discovered. dogname - Name your starting dog (ex. ``dogname:Fang''). Cannot be set + Name your starting dog (ex. ``dogname:Fang''). Cannot be set with the `O' command. extmenu - Changes the extended commands interface to pop-up a menu of - available commands. It is keystroke compatible with the tradi- - tional interface except that it does not require that you hit - Enter. It is implemented only by the tty port (default off), - when the game has been compiled to support tty graphics. + Changes the extended commands interface to pop-up a menu of + available commands. It is keystroke compatible with the + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 42 + + + + traditional interface except that it does not require that you + hit Enter. It is implemented only by the tty port (default + off), when the game has been compiled to support tty graphics. female An obsolete synonym for ``gender:female''. Cannot be set with @@ -2697,59 +2724,58 @@ the remaining inventory letters. Persistent. fruit - Name a fruit after something you enjoy eating (ex. - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 42 - - - - ``fruit:mango'') (default ``slime mold''). Basically a nostal- - gic whimsy that NetHack uses from time to time. You should set - this to something you find more appetizing than slime mold. - Apples, oranges, pears, bananas, and melons already exist in - NetHack, so don't use those. + Name a fruit after something you enjoy eating (ex. ``fruit:man- + go'') (default ``slime mold''). Basically a nostalgic whimsy + that NetHack uses from time to time. You should set this to + something you find more appetizing than slime mold. Apples, + oranges, pears, bananas, and melons already exist in NetHack, + so don't use those. gender Your starting gender (gender:male or gender:female). You may specify just the first letter. Although you can still denote your gender using the ``male'' and ``female'' options, the ``gender'' option will take precedence. The default is to ran- - domly pick an appropriate gender. If you prefix a `!' or - ``no'' to the value, you can exclude that gender from being - picked randomly. Cannot be set with the `O' command. Persis- - tent. + domly pick an appropriate gender. If you prefix the value with + `!' or ``no'', you will exclude that gender from being picked + randomly. Cannot be set with the `O' command. Persistent. help - If more information is available for an object looked at with - the `/' command, ask if you want to see it (default on). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the ``More info?'' prompt, but it also + If more information is available for an object looked at with + the `/' command, ask if you want to see it (default on). Turn- + ing help off makes just looking at things faster, since you + aren't interrupted with the ``More info?'' prompt, but it also means that you might miss some interesting and/or important in- formation. Persistent. hilite_pet - Visually distinguish pets from similar animals (default off). - The behavior of this option depends on the type of windowing + Visually distinguish pets from similar animals (default off). + The behavior of this option depends on the type of windowing you use. In text windowing, text highlighting or inverse video - is often used; with tiles, generally displays a heart symbol + is often used; with tiles, generally displays a heart symbol near pets. hilite_pile - Visually distinguish piles of objects from individual objects + Visually distinguish piles of objects from individual objects (default off). The behavior of this option depends on the type - of windowing you use. In text windowing, text highlighting or - inverse video is often used; with tiles, generally displays a + of windowing you use. In text windowing, text highlighting or + inverse video is often used; with tiles, generally displays a small plus-symbol beside the object on the top of the pile. horsename - Name your starting horse (ex. ``horsename:Trigger''). Cannot + Name your starting horse (ex. ``horsename:Trigger''). Cannot + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 43 + + + be set with the `O' command. ignintr @@ -2763,76 +2789,50 @@ Display an introductory message when starting the game (default on). Persistent. - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 43 - - - lit_corridor - Show corridor squares seen by night vision or a light source + Show corridor squares seen by night vision or a light source held by your character as lit (default off). Persistent. lootabc - Use the old `a', `b', and `c' keyboard shortcuts when looting, - rather than the mnemonics `o', `i', and `b' (default off). + Use the old `a', `b', and `c' keyboard shortcuts when looting, + rather than the mnemonics `o', `i', and `b' (default off). Persistent. mail Enable mail delivery during the game (default on). Persistent. male - An obsolete synonym for ``gender:male''. Cannot be set with + An obsolete synonym for ``gender:male''. Cannot be set with the `O' command. mention_walls Give feedback when walking against a wall (default off). menucolors - Enable coloring menu lines (default off). See ``Configuring + Enable coloring menu lines (default off). See ``Configuring Menu Colors'' on how to configure the colors. menustyle Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, full, or partial. Tradi- - tional was the only interface available for early versions; it - consists of a prompt for object class characters, followed by - an object-by-object prompt for all items matching the selected - object class(es). Combination starts with a prompt for object + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol- + lowing: traditional, combination, full, or partial. Tradi- + tional was the only interface available for early versions; it + consists of a prompt for object class characters, followed by + an object-by-object prompt for all items matching the selected + object class(es). Combination starts with a prompt for object class(es) of interest, but then displays a menu of matching ob- - jects rather than prompting one-by-one. Full displays a menu - of object classes rather than a character prompt, and then a - menu of matching objects for selection. Partial skips the ob- + jects rather than prompting one-by-one. Full displays a menu + of object classes rather than a character prompt, and then a + menu of matching objects for selection. Partial skips the ob- ject class filtering and immediately displays a menu of all ob- jects. Persistent. menu_deselect_all - Menu character accelerator to deselect all items in a menu. - Implemented by the Amiga, Gem, X11 and tty ports. Default '-'. - - menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- - fault '\'. - - menu_first_page - Menu character accelerator to jump to the first page in a menu. - Implemented by the Amiga, Gem and tty ports. Default '^'. - - menu_headings - Controls how the headings in a menu are highlighted. Values + Menu character accelerator to deselect all items in a menu. - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2842,33 +2842,46 @@ - are 'none', 'bold', 'dim', 'underline', 'blink', or 'inverse'. + Implemented by the Amiga, Gem, X11 and tty ports. Default '-'. + + menu_deselect_page + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De- + fault '\'. + + menu_first_page + Menu character accelerator to jump to the first page in a menu. + Implemented by the Amiga, Gem and tty ports. Default '^'. + + menu_headings + Controls how the headings in a menu are highlighted. Values + are 'none', 'bold', 'dim', 'underline', 'blink', or 'inverse'. Not all ports can actually display all types. menu_invert_all - Menu character accelerator to invert all items in a menu. Im- + Menu character accelerator to invert all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default '@'. menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default '~'. menu_last_page - Menu character accelerator to jump to the last page in a menu. + Menu character accelerator to jump to the last page in a menu. Implemented by the Amiga, Gem and tty ports. Default '|'. menu_next_page - Menu character accelerator to goto the next menu page. Imple- + Menu character accelerator to goto the next menu page. Imple- mented by the Amiga, Gem and tty ports. Default '>'. menu_objsyms - Show object symbols in menu headings in menus where the object + Show object symbols in menu headings in menus where the object symbols act as menu accelerators (default off). menu_overlay - Do not clear the screen before drawing menus, and align menus - to the right edge of the screen. Only for the tty port. (de- + Do not clear the screen before drawing menus, and align menus + to the right edge of the screen. Only for the tty port. (de- fault on) menu_previous_page @@ -2876,29 +2889,16 @@ plemented by the Amiga, Gem and tty ports. Default '<'. menu_search - Menu character accelerator to search for a menu item. Imple- + Menu character accelerator to search for a menu item. Imple- mented by the Amiga, Gem, X11 and tty ports. Default ':'. menu_select_all - Menu character accelerator to select all items in a menu. Im- + Menu character accelerator to select all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default '.'. - menu_select_page - Menu character accelerator to select all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default - ','. - - msghistory - The number of top line messages to save (and recall with ^P) - (default 20). Cannot be set with the `O' command. - - msg_window - Allows you to change the way recalled messages are displayed. - (It is currently implemented for tty only.) The possible val- - ues are: - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2908,21 +2908,35 @@ + menu_select_page + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default + ','. + + msghistory + The number of top line messages to save (and recall with ^P) + (default 20). Cannot be set with the `O' command. + + msg_window + Allows you to change the way recalled messages are displayed. + (It is currently implemented for tty only.) The possible val- + ues are: + s - single message (default; only choice prior to 3.4.0); c - combination, two messages as `single', then as `full'; f - full window, oldest message first; r - full window reversed, newest message first. - For backward compatibility, no value needs to be specified - (which defaults to `full'), or it can be negated (which de- + For backward compatibility, no value needs to be specified + (which defaults to `full'), or it can be negated (which de- faults to `single'). name - Set your character's name (defaults to your user name). You - can also set your character's role by appending a dash and one + Set your character's name (defaults to your user name). You + can also set your character's role by appending a dash and one or more letters of the role (that is, by suffixing one of -A -B - -C -H -K -M -P -Ra -Ro -S -T -V -W). If -@ is used for the - role, then a random one will be automatically chosen. Cannot + -C -H -K -M -P -Ra -Ro -S -T -V -W). If -@ is used for the + role, then a random one will be automatically chosen. Cannot be set with the `O' command. news @@ -2937,7 +2951,7 @@ Send padding nulls to the terminal (default on). Persistent. number_pad - Use digit keys instead of letters to move (default 0 or off). + Use digit keys instead of letters to move (default 0 or off). Valid settings are: 0 - move by letters; `yuhjklbn' @@ -2947,24 +2961,10 @@ 4 - combines 3 with 2; phone layout plus MSDOS compatibility -1 - by letters but use `z' to go northwest, `y' to zap wands - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - 0. (Settings 2 and 4 are for compatibility with MSDOS or old - PC Hack; in addition to the different behavior for `5', `Alt-5' - acts as `G' and `Alt-0' acts as `I'. Setting -1 is to accommo- - date some German keyboards which have the location of the `y' - and `z' keys swapped.) When moving by numbers, to enter a - count prefix for those commands which accept one (such as - ``12s'' to search twelve times), precede it with the letter `n' - (``n12s''). - - packorder - Specify the order to list object types in (default - ``")[%?+!=/(*`0_''). The value of this option should be a - string containing the symbols for the various object types. + For backward compatibility, omitting a value is the same as - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -2974,63 +2974,63 @@ - Any omitted types are filled in at the end from the previous + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 2 and 4 are for compatibility with MSDOS or old + PC Hack; in addition to the different behavior for `5', `Alt-5' + acts as `G' and `Alt-0' acts as `I'. Setting -1 is to accommo- + date some German keyboards which have the location of the `y' + and `z' keys swapped.) When moving by numbers, to enter a + count prefix for those commands which accept one (such as + ``12s'' to search twelve times), precede it with the letter `n' + (``n12s''). + + packorder + Specify the order to list object types in (default + ``")[%?+!=/(*`0_''). The value of this option should be a + string containing the symbols for the various object types. + Any omitted types are filled in at the end from the previous order. paranoid_confirmation - A space separated list of specific situations where alternate - prompting is desired. The default is paranoid_confirma- + A space separated list of specific situations where alternate + prompting is desired. The default is paranoid_confirma- tion:pray. Confirm - for any prompts which are set to require "yes" rather - than 'y', also require "no" to reject instead of ac- + than 'y', also require "no" to reject instead of ac- cepting any non-yes response as no quit - require "yes" rather than 'y' to confirm quitting the game or switching into non-scoring explore mode; - die - require "yes" rather than 'y' to confirm dying (not + die - require "yes" rather than 'y' to confirm dying (not useful in normal play; applies to explore mode); bones - require "yes" rather than 'y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than 'y' to confirm attacking a + attack - require "yes" rather than 'y' to confirm attacking a peaceful monster; pray - require 'y' to confirm an attempt to pray rather than immediately praying; on by default; - wand - require "yes" rather than 'y' to confirm breaking a + wand - require "yes" rather than 'y' to confirm breaking a wand; Remove - require selection from inventory for 'R' and 'T' com- mands even when wearing just one applicable item. - By default, the pray choice is enabled, the others disabled. - To disable it without setting any of the other choices, use - ``paranoid_confirmation:none''. To keep it enabled while set- + By default, the pray choice is enabled, the others disabled. + To disable it without setting any of the other choices, use + ``paranoid_confirmation:none''. To keep it enabled while set- ting any of the others, include it in the list, such as ``para- noid_confirmation:attack pray Remove''. perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im- plement this feature. Persistent. pettype - Specify the type of your initial pet, if you are playing a - character class that uses multiple types of pets; or choose to - have no initial pet at all. Possible values are ``cat'', - ``dog'', ``horse'', and ``none''. If the choice is not allowed - for the role you are currently playing, it will be silently ig- - nored. For example, ``horse'' will only be honored when play- - ing a knight. Cannot be set with the `O' command. - - pickup_burden - When you pick up an item that would exceed this encumbrance - level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, - or overLoaded), you will be asked if you want to continue. - (Default `S'). Persistent. - - pickup_thrown - If this option is on and autopickup is also on, try to pick up + Specify the type of your initial pet, if you are playing a + character class that uses multiple types of pets; or choose to - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3040,7 +3040,21 @@ - things that you threw, even if they aren't in pickup_types or + have no initial pet at all. Possible values are ``cat'', + ``dog'', ``horse'', and ``none''. If the choice is not allowed + for the role you are currently playing, it will be silently ig- + nored. For example, ``horse'' will only be honored when play- + ing a knight. Cannot be set with the `O' command. + + pickup_burden + When you pick up an item that would exceed this encumbrance + level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, + or overLoaded), you will be asked if you want to continue. + (Default `S'). Persistent. + + pickup_thrown + If this option is on and autopickup is also on, try to pick up + things that you threw, even if they aren't in pickup_types or match an autopickup exception. Default is on. Persistent. pickup_types @@ -3050,53 +3064,39 @@ sistent. pile_limit - When walking across a pile of objects on the floor, threshold - at which the message "there are few/several/many objects here" - is given instead of showing a popup list of those objects. A - value of 0 means "no limit" (always list the objects); a value - of 1 effectively means "never show the objects" since the pile - size will always be at least that big; default value is 5. + When walking across a pile of objects on the floor, threshold + at which the message "there are few/several/many objects here" + is given instead of showing a popup list of those objects. A + value of 0 means "no limit" (always list the objects); a value + of 1 effectively means "never show the objects" since the pile + size will always be at least that big; default value is 5. Persistent. playmode - Values are `normal', `explore', or `debug'. Allows selection - of explore mode (also known as discovery mode) or debug mode + Values are `normal', `explore', or `debug'. Allows selection + of explore mode (also known as discovery mode) or debug mode (also known as wizard mode) instead of normal play. Debug mode - might only be allowed for someone logged in under a particular - user name (on multi-user systems) or specifying a particular + might only be allowed for someone logged in under a particular + user name (on multi-user systems) or specifying a particular character name (on single-user systems) or it might be disabled - entirely. Requesting it when not allowed or not possible re- + entirely. Requesting it when not allowed or not possible re- sults in explore mode instead. Default is normal play. pushweapon - Using the `w' (wield) command when already wielding something - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the + Using the `w' (wield) command when already wielding something + pushes the old item into your alternate weapon slot (default + off). Likewise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. race - Selects your race (for example, ``race:human''). Default is - random. If you prefix a `!' or ``no'' to the value, you can - exclude that race from being picked randomly. Cannot be set + Selects your race (for example, ``race:human''). Default is + random. If you prefix the value with `!' or ``no'', you will + exclude that race from being picked randomly. Cannot be set with the `O' command. Persistent. - rest_on_space - Make the space bar a synonym for the `.' (rest) command (de- - fault off). Persistent. - - role - Pick your type of character (ex. ``role:Samurai''); synonym for - ``character''. See ``name'' for an alternate method of speci- - fying your role. Normally only the first letter of the value - is examined; `r' is an exception with ``Rogue'', ``Ranger'', - and ``random'' values. If you prefix a `!' or ``no'' to the - value, you can exclude that role from being picked randomly. - Persistent. - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3106,20 +3106,33 @@ + rest_on_space + Make the space bar a synonym for the `.' (rest) command (de- + fault off). Persistent. + + role + Pick your type of character (ex. ``role:Samurai''); synonym for + ``character''. See ``name'' for an alternate method of speci- + fying your role. Normally only the first letter of the value + is examined; `r' is an exception with ``Rogue'', ``Ranger'', + and ``random'' values. If you prefix the value with `!' or + ``no'', you will exclude that role from being picked randomly. + Cannot be set with the `O' command. Persistent. + roguesymset - This option may be used to select one of the named symbol sets - found within ``symbols'' to alter the symbols displayed on the + This option may be used to select one of the named symbol sets + found within ``symbols'' to alter the symbols displayed on the screen on the rogue level. rlecomp When writing out a save file, perform run length compression of - the map. Not all ports support run length compression. It has + the map. Not all ports support run length compression. It has no effect on reading an existing save file. runmode - Controls the amount of screen updating for the map window when - engaged in multi-turn movement (running via shift+direction or - control+direction and so forth, or via the travel command or + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or + control+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -3128,41 +3141,28 @@ crawl - like walk, but pause briefly after each step. This option only affects the game's screen display, not the ac- - tual results of moving. The default is `run'; versions prior - to 3.4.1 used `teleport' only. Whether or not the effect is + tual results of moving. The default is `run'; versions prior + to 3.4.1 used `teleport' only. Whether or not the effect is noticeable will depend upon the window port used or on the type of terminal. Persistent. safe_pet - Prevent you from (knowingly) attacking your pets (default on). + Prevent you from (knowingly) attacking your pets (default on). Persistent. scores - Control what parts of the score list you are shown at the end - (ex. ``scores:5 top scores/4 around my score/own scores''). - Only the first letter of each category (`t', `a', or `o') is + Control what parts of the score list you are shown at the end + (ex. ``scores:5 top scores/4 around my score/own scores''). + Only the first letter of each category (`t', `a', or `o') is necessary. Persistent. showexp Show your accumulated experience points on bottom line (default off). Persistent. - showrace - Display yourself as the glyph for your race, rather than the - glyph for your role (default off). Note that this setting af- - fects only the appearance of the display, not the way the game - treats you. Persistent. - - showscore - Show your approximate accumulated score on bottom line (default - off). Persistent. - - silent - Suppress terminal beeps (default on). Persistent. - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3172,63 +3172,63 @@ + showrace + Display yourself as the glyph for your race, rather than the + glyph for your role (default off). Note that this setting af- + fects only the appearance of the display, not the way the game + treats you. Persistent. + + showscore + Show your approximate accumulated score on bottom line (default + off). Persistent. + + silent + Suppress terminal beeps (default on). Persistent. + sortloot Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible + and #loot commands and some others. Persistent. The possible values are: full - always sort the lists; - loot - only sort the lists that don't use inventory letters, + loot - only sort the lists that don't use inventory letters, like with the #loot and pickup commands; none - show lists the traditional way without sorting. sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de- fault on). Persistent. sparkle Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- + hit by an attack to which it is resistant (default on). Per- sistent. standout - Boldface monsters and ``--More--'' (default off). Persistent. + Boldface monsters and ``--More--'' (default off). Persistent. statushilites - Enable coloring of status fields (default off). See ``Config- + Enable coloring of status fields (default off). See ``Config- uring Status Hilites'' for futher information. suppress_alert - This option may be set to a NetHack version level to suppress - alert notification messages about feature changes for that and + This option may be set to a NetHack version level to suppress + alert notification messages about feature changes for that and prior versions (ex. ``suppress_alert:3.3.1''). symset - This option may be used to select one of the named symbol sets - found within ``symbols'' to alter the symbols displayed on the - screen. Use ``symset:default'' to explicitly select the de- + This option may be used to select one of the named symbol sets + found within ``symbols'' to alter the symbols displayed on the + screen. Use ``symset:default'' to explicitly select the de- fault symbols. time - Show the elapsed game time in turns on bottom line (default + Show the elapsed game time in turns on bottom line (default off). Persistent. - timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to ``tty'' interface - only; ``X11'' interface always uses a timer based delay. The - default is on if configured into the program.) Persistent. - - tombstone - Draw a tombstone graphic upon your death (default on). Persis- - tent. - - toptenwin - Put the ending display in a NetHack window instead of on stdout - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3238,24 +3238,37 @@ - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around + timed_delay + When pausing momentarily for display effect, such as with ex- + plosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to ``tty'' interface + only; ``X11'' interface always uses a timer based delay. The + default is on if configured into the program.) Persistent. + + tombstone + Draw a tombstone graphic upon your death (default on). Persis- + tent. + + toptenwin + Put the ending display in a NetHack window instead of on stdout + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around after game end on a terminal or emulating window. travel Allow the travel command (default on). Turning this option off - will prevent the game from attempting unintended moves if you + will prevent the game from attempting unintended moves if you make inadvertent mouse clicks on the map window. Persistent. verbose - Provide more commentary during the game (default on). Persis- + Provide more commentary during the game (default on). Persis- tent. whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to pick a location. The possibile settings are: @@ -3270,31 +3283,18 @@ ridden with `map'. windowtype - Select which windowing system to use, such as ``tty'' or - ``X11'' (default depends on version). Cannot be set with the + Select which windowing system to use, such as ``tty'' or + ``X11'' (default depends on version). Cannot be set with the `O' command. zerocomp - When writing out a save file, perform zero-comp compression of - the contents. Not all ports support zero-comp compression. It + When writing out a save file, perform zero-comp compression of + the contents. Not all ports support zero-comp compression. It has no effect on reading an existing save file. - 9.5. Window Port Customization options - - Here are explanations of the various options that are used - to customize and change the characteristics of the windowtype - that you have chosen. Character strings that are too long may be - truncated. Not all window ports will adjust for all settings - listed here. You can safely add any of these options to your - config file, and if the window port is capable of adjusting to - suit your preferences, it will attempt to do so. If it can't it - will silently ignore it. You can find out if an option is sup- - ported by the window port that you are currently using by check- - ing to see if it shows up in the Options list. Some options are - dynamic and can be specified during the game with the `O' - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3304,45 +3304,71 @@ - command. + 9.5. Window Port Customization options + + Here are explanations of the various options that are used + to customize and change the characteristics of the windowtype + that you have chosen. Character strings that are too long may be + truncated. Not all window ports will adjust for all settings + listed here. You can safely add any of these options to your + config file, and if the window port is capable of adjusting to + suit your preferences, it will attempt to do so. If it can't it + will silently ignore it. You can find out if an option is sup- + ported by the window port that you are currently using by check- + ing to see if it shows up in the Options list. Some options are + dynamic and can be specified during the game with the `O' com- + mand. align_message - Where to align or place the message window (top, bottom, left, + Where to align or place the message window (top, bottom, left, or right) align_status - Where to align or place the status window (top, bottom, left, + Where to align or place the status window (top, bottom, left, or right). ascii_map NetHack should display an ascii character map if it can. color - NetHack should display color if it can for different monsters, + NetHack should display color if it can for different monsters, objects, and dungeon features eight_bit_tty - NetHack should pass eight-bit character values (for example, - specified with the traps option) straight through to your ter- + NetHack should pass eight-bit character values (for example, + specified with the traps option) straight through to your ter- minal (default off). font_map - NetHack should use a font by the chosen name for the map win- + NetHack should use a font by the chosen name for the map win- dow. font_menu - NetHack should use a font by the chosen name for menu windows. + NetHack should use a font by the chosen name for menu windows. font_message - NetHack should use a font by the chosen name for the message + NetHack should use a font by the chosen name for the message window. font_status - NetHack should use a font by the chosen name for the status + NetHack should use a font by the chosen name for the status window. font_text - NetHack should use a font by the chosen name for text windows. + NetHack should use a font by the chosen name for text windows. + + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 52 + + font_size_map NetHack should use this size font for the map window. @@ -3359,17 +3385,6 @@ font_size_text NetHack should use this size font for text windows. - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 52 - - - fullscreen NetHack should try and display on the entire screen rather than in a window. @@ -3384,49 +3399,34 @@ Allow use of the mouse for input and travel. player_selection - NetHack should pop up dialog boxes, or use prompts for charac- + NetHack should pop up dialog boxes, or use prompts for charac- ter selection. popup_dialog NetHack should pop up dialog boxes for input. preload_tiles - NetHack should preload tiles into memory. For example, in the - protected mode MSDOS version, control whether tiles get pre- - loaded into RAM at the start of the game. Doing so enhances - performance of the tile graphics, but uses more memory. (de- + NetHack should preload tiles into memory. For example, in the + protected mode MSDOS version, control whether tiles get pre- + loaded into RAM at the start of the game. Doing so enhances + performance of the tile graphics, but uses more memory. (de- fault on). Cannot be set with the `O' command. scroll_amount - NetHack should scroll the display by this number of cells when + NetHack should scroll the display by this number of cells when the hero reaches the scroll_margin. scroll_margin - NetHack should scroll the display when the hero or cursor is + NetHack should scroll the display when the hero or cursor is this number of cells away from the edge of the window. selectsaved - NetHack should display a menu of existing saved games for the + NetHack should display a menu of existing saved games for the player to choose from at game startup, if it can. Not all ports support this option. - softkeyboard - Display an onscreen keyboard. Handhelds are most likely to - support this option. - splash_screen - NetHack should display an opening splash screen when it starts - up (default yes). - - tiled_map - NetHack should display a tiled map if it can. - - tile_file - Specify the name of an alternative tile file to override the - default. - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3436,8 +3436,23 @@ + softkeyboard + Display an onscreen keyboard. Handhelds are most likely to + support this option. + + splash_screen + NetHack should display an opening splash screen when it starts + up (default yes). + + tiled_map + NetHack should display a tiled map if it can. + + tile_file + Specify the name of an alternative tile file to override the + default. + tile_height - Specify the preferred height of each tile in a tile capable + Specify the preferred height of each tile in a tile capable port. tile_width @@ -3454,21 +3469,21 @@ message window. windowcolors - NetHack should display windows with the specified fore- + NetHack should display windows with the specified fore- ground/background colors if it can. wraptext - NetHack port should wrap long lines of text if they don't fit + NetHack port should wrap long lines of text if they don't fit in the visible area of the window. 9.6. Platform-specific Customization options - Here are explanations of options that are used by specific + Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without the .dll extension and without any path information. Cannot be set with the `O' command. @@ -3476,23 +3491,8 @@ On Amiga, this option controls whether typing `Alt' plus anoth- er key functions as a meta-shift for that key (default on). - altmeta - On other (non-Amiga) systems where this option is available, it - can be set to tell nethack to convert a two character sequence - beginning with ESC into a meta-shifted version of the second - character (default off). - This conversion is only done for commands, not for other input - prompts. Note that typing one or more digits as a count prefix - prior to a command--preceded by n if the number_pad option is - set--is also subject to this conversion, so attempting to abort - the count by typing ESC will leave nethack waiting for another - character to complete the two character sequence. Type a sec- - ond ESC to finish cancelling such a count. At other prompts a - single ESC suffices. - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3502,10 +3502,25 @@ + altmeta + On other (non-Amiga) systems where this option is available, it + can be set to tell nethack to convert a two character sequence + beginning with ESC into a meta-shifted version of the second + character (default off). + + This conversion is only done for commands, not for other input + prompts. Note that typing one or more digits as a count prefix + prior to a command--preceded by n if the number_pad option is + set--is also subject to this conversion, so attempting to abort + the count by typing ESC will leave nethack waiting for another + character to complete the two character sequence. Type a sec- + ond ESC to finish cancelling such a count. At other prompts a + single ESC suffices. + BIOS Use BIOS calls to update the screen display quickly and to read - the keyboard (allowing the use of arrow keys to move) on ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). flush @@ -3518,10 +3533,10 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof input (MS-DOS sometimes treats `^P' as a printer toggle - without it) (default off, OS/2, PC, and ST NetHack only). - Note: DEC Rainbows hang if this is turned on. Cannot be set + Force raw (non-cbreak) mode for faster output and more bullet- + proof input (MS-DOS sometimes treats `^P' as a printer toggle + without it) (default off, OS/2, PC, and ST NetHack only). + Note: DEC Rainbows hang if this is turned on. Cannot be set with the `O' command. soundcard @@ -3529,36 +3544,21 @@ mand. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of + (Win32 tty NetHack only). May be used to alter the value of keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally - going to be returned. You can use multiple subkeyvalue state- + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally + going to be returned. You can use multiple subkeyvalue state- ments in the config file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are `autode- - tect', `default', or `vga'. Setting `vga' (or `autodetect' - with vga hardware present) will cause the game to display - tiles. Cannot be set with the `O' command. - - videocolors - Set the color palette for PC systems using NO_TERMS (default - 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order - of colors is red, green, brown, blue, magenta, cyan, - bright.white, bright.red, bright.green, yellow, bright.blue, - bright.magenta, and bright.cyan. Cannot be set with the `O' - command. - - videoshades - Set the intensity level of the three gray scales available (de- - fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the + tect', `default', or `vga'. Setting `vga' (or `autodetect' + with vga hardware present) will cause the game to display - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3568,15 +3568,30 @@ + tiles. Cannot be set with the `O' command. + + videocolors + Set the color palette for PC systems using NO_TERMS (default + 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order + of colors is red, green, brown, blue, magenta, cyan, + bright.white, bright.red, bright.green, yellow, bright.blue, + bright.magenta, and bright.cyan. Cannot be set with the `O' + command. + + videoshades + Set the intensity level of the three gray scales available (de- + fault dark normal light, PC NetHack only). If the game display + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the `O' command. 9.7. Regular Expressions - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. @@ -3585,46 +3600,31 @@ You can further refine the behavior of the autopickup option beyond what is available through the pickup_types option. - By placing autopickup_exception lines in your configuration - file, you can define patterns to be checked when the game is + By placing autopickup_exception lines in your configuration + file, you can define patterns to be checked when the game is about to autopickup something. autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as a pattern to match against the singular form of + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as a pattern to match against the singular form of the description of an object at your location. - In addition, some characters are treated specially if they oc- + In addition, some characters are treated specially if they oc- cur as the first character in the pattern, specifically: < - always pickup an object that matches rest of pattern; > - never pickup an object that matches rest of pattern. - A `never pickup' rule takes precedence over an `always pickup' + A `never pickup' rule takes precedence over an `always pickup' rule if both match. - Exceptions can be set with the `O' command, but ones set that + Exceptions can be set with the `O' command, but ones set that way will not be preserved across saves and restores. - Here are some examples: - - autopickup_exception="<*arrow" - autopickup_exception=">*corpse" - autopickup_exception=">* cursed*" - - The first example above will result in autopickup of any - type of arrow. The second example results in the exclusion of - any corpse from autopickup. The last example results in the ex- - clusion of items known to be cursed from autopickup. - - 9.9. Configuring Message Types - - You can change the way the messages are shown in the message - area, when the message matches a user-defined pattern. - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3634,6 +3634,22 @@ + Here are some examples: + + autopickup_exception="<*arrow" + autopickup_exception=">*corpse" + autopickup_exception=">* cursed*" + + The first example above will result in autopickup of any + type of arrow. The second example results in the exclusion of + any corpse from autopickup. The last example results in the ex- + clusion of items known to be cursed from autopickup. + + 9.9. Configuring Message Types + + You can change the way the messages are shown in the message + area, when the message matches a user-defined pattern. + In general, the config file entries to configure the message types look like this: MSGTYPE=type "pattern" @@ -3649,48 +3665,32 @@ stop - wait for user with more-prompt. norep - show the message once, but not again if no other message is shown in between. - Here's an example of message types using NetHack's internal + Here's an example of message types using NetHack's internal pattern matching facility: MSGTYPE=stop "You feel hungry." MSGTYPE=hide "You displaced *." - specifies that whenever a message "You feel hungry" is shown, - the user is prompted with more-prompt, and a message matching + specifies that whenever a message "You feel hungry" is shown, + the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. - The order of the defined MSGTYPE-lines is important; the last - matching rule is used. Put the general case first, exceptions + The order of the defined MSGTYPE-lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.10. Configuring Menu Colors Some platforms allow you to define colors used in menu lines - when the line matches a user-defined pattern. At this time the + when the line matches a user-defined pattern. At this time the tty, win32tty and win32gui support this. - In general, the config file entries to configure the menu + In general, the config file entries to configure the menu color mappings look like this: - MENUCOLOR="pattern"=color&attribute - - pattern - the pattern to match; - color - the color to use for lines matching the pat- - tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if - left out, you must also leave out the preced- - ing ampersand. If no attribute is defined, - no attribute is used. - - The pattern should be a regular expression. - - Allowed colors are black, red, green, brown, blue, magenta, - cyan, gray, orange, lightgreen, yellow, lightblue, lightmagen- - ta, lightcyan, and white. - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3700,49 +3700,78 @@ - Allowed attributes are none, bold, dim, underline, blink, and - inverse. Note that the platform used may interpret the at- + MENUCOLOR="pattern"=color&attribute + + pattern - the pattern to match; + color - the color to use for lines matching the pat- + tern; + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if + left out, you must also leave out the preced- + ing ampersand. If no attribute is defined, + no attribute is used. + + The pattern should be a regular expression. + + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, lightgreen, yellow, lightblue, lightmagen- + ta, lightcyan, and white. + + Allowed attributes are none, bold, dim, underline, blink, and + inverse. Note that the platform used may interpret the at- tributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern matching facility: MENUCOLOR="* blessed *"=green MENUCOLOR="* cursed *"=red MENUCOLOR="* cursed *(being worn)"=red&underline - specifies that any menu line with " blessed " contained in it - will be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- - lined. You can have multiple MENUCOLOR entries in your config - file, and the last MENUCOLOR-line in your config file that + specifies that any menu line with " blessed " contained in it + will be shown in green color, lines with " cursed " will be + shown in red, and lines with " cursed " followed by "(being + worn)" on the same line will be shown in red color and under- + lined. You can have multiple MENUCOLOR entries in your config + file, and the last MENUCOLOR-line in your config file that matches a menu line will be used for the line. Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- + tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed are actually displayed with the ``uncursed'' description. 9.11. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. - The following config file entries are relevant to mapping + The following config file entries are relevant to mapping user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 58 + + + SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + An entry that maps a sound file to a user-specified message + pattern. Each SOUND entry is broken down into the following parts: - MESG - message window mapping (the only one supported in + MESG - message window mapping (the only one supported in 3.6); pattern - the pattern to match; sound file - the sound file to play; @@ -3753,29 +3782,17 @@ 9.12. Configuring Status Hilites Your copy of NetHack may have been compiled with support for - ``Status Hilites''. If so, you can customize your game display - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 58 - - - + ``Status Hilites''. If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. - For example, the following line in your config file will - cause the hitpoints field to display in the color red if your + For example, the following line in your config file will + cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: OPTION=hilite_status: hitpoints/30%/red/normal - For another example, the following line in your config file + For another example, the following line in your config file will cause wisdom to be displayed red if it drops and green if it rises. @@ -3791,38 +3808,21 @@ hitpoints hitpoints-max dungeon-level experience condition - Allowed colors are black, red, green, brown, blue, magenta, - cyan, gray, orange, lightgreen, yellow, lightblue, lightmagen- + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, lightgreen, yellow, lightblue, lightmagen- ta, lightcyan, and white. - Allowed attributes are bold, inverse, normal. Note that the + Allowed attributes are bold, inverse, normal. Note that the platform used may interpret the attributes any way it wants. Behaviours can occur based on percentage thresholds, updown, or - absolute values. The in-game options menu can help you deter- + absolute values. The in-game options menu can help you deter- mine the correct syntax for a config file. - The whole feature can be disabled by setting option sta- - tushilites off. - - 9.13. Modifying NetHack Symbols - - NetHack can load entire symbol sets from the symbol file. - - The options that are used to select a particular symbol set - from the symbol file are: - - symset - Set the name of the symbol set that you want to load. - - roguesymset - Set the name of the symbol set that you want to load for dis- - play on the rogue level. - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -3832,13 +3832,30 @@ - You can also override one or more symbols using the SYMBOLS - config file option. Symbols are specified as name:value pairs. - Note that NetHack escape-processes the value string in conven- + The whole feature can be disabled by setting option sta- + tushilites off. + + 9.13. Modifying NetHack Symbols + + NetHack can load entire symbol sets from the symbol file. + + The options that are used to select a particular symbol set + from the symbol file are: + + symset + Set the name of the symbol set that you want to load. + + roguesymset + Set the name of the symbol set that you want to load for dis- + play on the rogue level. + + You can also override one or more symbols using the SYMBOLS + config file option. Symbols are specified as name:value pairs. + Note that NetHack escape-processes the value string in conven- tional C fashion. This means that \ is a prefix to take the fol- lowing character literally. Thus \ needs to be represented as \\. The special escape form \m switches on the meta bit in the symbol - value, and the \^ prefix causes the following character to be + value, and the \^ prefix causes the following character to be treated as a control character. NetHack Symbols @@ -3868,6 +3885,19 @@ _ S_chain (iron chain) # S_cloud (cloud) c S_cockatrice (cockatrice) + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 60 + + + $ S_coin (pile of coins) # S_corr (corridor) - S_crwall (wall) @@ -3885,19 +3915,6 @@ `\' S_explode3 (explosion top right) | S_explode4 (explosion middle left) S_explode5 (explosion middle center) - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 60 - - - | S_explode6 (explosion middle right) `\' S_explode7 (explosion bottom left) - S_explode8 (explosion bottom center) @@ -3934,6 +3951,19 @@ } S_lava (molten lava) l S_leprechaun (leprechaun) ^ S_level_teleporter (level teleporter) + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 61 + + + L S_lich (lich) y S_light (light) # S_litcorr (lit corridor) @@ -3951,19 +3981,6 @@ p S_piercer (piercer) ^ S_pit (pit) # S_poisoncloud (poison cloud) - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 61 - - - ^ S_polymorph_trap (polymorph trap) } S_pool (water) ! S_potion (potion) @@ -4000,6 +4017,19 @@ `\' S_sw_tr (swallow top right) - S_tdwall (wall) ^ S_teleportation_trap (teleportation trap) + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 62 + + + S_throne (opulent throne) - S_tlcorn (top left corner) | S_tlwall (wall) @@ -4017,19 +4047,6 @@ < S_upstair (staircase up) V S_vampire (vampire) | S_vbeam (wall) - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 62 - - - # S_vcdbridge (vertical raised drawbridge) + S_vcdoor (closed door) ^ S_vibrating_square (vibrating square) @@ -4051,42 +4068,25 @@ 9.14. Configuring NetHack for Play by the Blind - NetHack can be set up to use only standard ASCII characters - for making maps of the dungeons. This makes the MS-DOS versions - of NetHack completely accessible to the blind who use speech - and/or Braille access technologies. Players will require a good - working knowledge of their screen-reader's review features, and - will have to know how to navigate horizontally and vertically - character by character. They will also find the search capabili- - ties of their screen-readers to be quite valuable. Be certain to - examine this Guidebook before playing so you have an idea what - the screen layout is like. You'll also need to be able to locate - the PC cursor. It is always where your character is located. - Merely searching for an @-sign will not always find your charac- + NetHack can be set up to use only standard ASCII characters + for making maps of the dungeons. This makes the MS-DOS versions + of NetHack completely accessible to the blind who use speech + and/or Braille access technologies. Players will require a good + working knowledge of their screen-reader's review features, and + will have to know how to navigate horizontally and vertically + character by character. They will also find the search capabili- + ties of their screen-readers to be quite valuable. Be certain to + examine this Guidebook before playing so you have an idea what + the screen layout is like. You'll also need to be able to locate + the PC cursor. It is always where your character is located. + Merely searching for an @-sign will not always find your charac- ter since there are other humanoids represented by the same sign. - Your screen-reader should also have a function which gives you - the row and column of your review cursor and the PC cursor. - These co-ordinates are often useful in giving players a better - sense of the overall location of items on the screen. - - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task - somewhat daunting. Included within the ``symbols'' file of all - official distributions of NetHack is a symset called NHAccess. - Selecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you - may want to alter settings via SYMBOLS= in your configuration - file to better suit your preferences. The most crucial settings - to make the game accessible are: - - symset:NHAccess - Load a symbol set appropriate for use by blind players. + Your screen-reader should also have a function which gives you + the row and column of your review cursor and the PC cursor. + These co-ordinates are often useful in giving players a better - - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -4096,63 +4096,63 @@ + sense of the overall location of items on the screen. + + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task + somewhat daunting. Included within the ``symbols'' file of all + official distributions of NetHack is a symset called NHAccess. + Selecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you + may want to alter settings via SYMBOLS= in your configuration + file to better suit your preferences. The most crucial settings + to make the game accessible are: + + symset:NHAccess + Load a symbol set appropriate for use by blind players. + roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for + Load a symbol set for the rogue level that is appropriate for use by blind players. menustyle:traditional This will assist in the interface to speech synthesizers. number_pad - A lot of speech access programs use the number-pad to review + A lot of speech access programs use the number-pad to review the screen. If this is the case, disable the number_pad option and use the traditional Rogue-like commands. 9.15. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system ad- - ministrator should set up a global configuration; this is a file + If NetHack is compiled with the SYSCF option, a system ad- + ministrator should set up a global configuration; this is a file in the same format as the traditional per-user configuration file (see above). This file should be named sysconf and placed in the - same directory as the other NetHack support files. The options + same directory as the other NetHack support files. The options recognized in this file are listed below. Any option not set us- - es a compiled-in default (which may not be appropriate for your + es a compiled-in default (which may not be appropriate for your system). - WIZARDS A space-separated list of user names who are allowed to - play in wizard mode (the debugging mode, not the magic-using + WIZARDS = A space-separated list of user names who are allowed + to play in wizard mode (the debugging mode, not the magic-using role). A value of a single asterisk (*) allows anyone to start a game in wizard mode. - SHELLERS A list of users who are allowed to use the shell es- + SHELLERS = A list of users who are allowed to use the shell es- cape command (!). The syntax is the same as WIZARDS. - EXPLORERS A list of users who are allowed to use the explore + EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. - MAXPLAYERS Limit the maximum number of games that can be run- + MAXPLAYERS = Limit the maximum number of games that can be run- ning at the same time. - SUPPORT A string explaining how to get local support (no de- - fault value). - - RECOVER A string explaining how to recover a game on this sys- - tem (no default value). - - SEDUCE 0 or 1 to disable or enable, respectively, the SEDUCE - option (see the source for details on this function). - - CHECK_SAVE_UID 0 or 1 to disable or enable, respectively, the - UID checking for savefiles. - - The following options affect the score file: - - PERSMAX Maximum number of entries for one person. - - NetHack 3.6 January 18, 2016 + NetHack 3.6 February 22, 2016 @@ -4162,16 +4162,38 @@ - ENTRYMAX Maximum number of entries in the score file. + SUPPORT = A string explaining how to get local support (no de- + fault value). - POINTSMIN Minimum number of points to get an entry in the score - file. + RECOVER = A string explaining how to recover a game on this + system (no default value). - PERS_IS_UID 0 or 1 to use user names or numeric userids, re- + SEDUCE = 0 or 1 to disable or enable, respectively, the SEDUCE + option. When disabled, incubi and succubi behave like nymphs. + + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- + ARDS, and SHELLERS check for the player name instead of the us- + er's login name. + + CHECK_SAVE_UID = 0 or 1 to disable or enable, respectively, the + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who + saved). + + The following options affect the score file: + + PERSMAX = Maximum number of entries for one person. + + ENTRYMAX = Maximum number of entries in the score file. + + POINTSMIN = Minimum number of points to get an entry in the + score file. + + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK Maximum number of score file entries to use - for random statue names (default is 10). + MAX_STATUENAME_RANK = Maximum number of score file entries to + use for random statue names (default is 10). 10. Scoring @@ -4194,6 +4216,18 @@ whatever you have. If you quit, you keep all your gold, but if you swing and live, you might find more. + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 65 + + + If you just want to see what the current top players/games list is, you can type nethack -s all on most versions. @@ -4216,18 +4250,6 @@ other benefits of explore mode are left for the trepid reader to discover. - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 65 - - - 11.1. Debug mode Debug mode, also known as wizard mode, is undocumented aside @@ -4261,6 +4283,17 @@ below: + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 66 + + + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome and Jon Payne. @@ -4281,19 +4314,6 @@ 1.4. He then coordinated a cast of thousands in enhancing and debugging NetHack 1.4 and released NetHack versions 2.2 and 2.3. - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 66 - - - Later, Mike coordinated a major rewrite of the game, heading a team which included Ken Arromdee, Jean-Christophe Collet, Steve Creps, Eric Hendrickson, Izchak Miller, John Rupley, Mike Threep- @@ -4329,6 +4349,17 @@ lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 67 + + + Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack @@ -4348,18 +4379,6 @@ The 3.2 development team, comprised of Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Eric - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 67 - - - Smith, Mike Stephenson, Janet Walz, and Paul Winner, released version 3.2 in April of 1996. @@ -4395,6 +4414,18 @@ The 3.3 development team, consisting of Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 68 + + + Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lorber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 in August @@ -4413,19 +4444,6 @@ bug list, 3.3 proved stable enough to last for more than a year and a half. - - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 68 - - - The 3.4 development team initially consisted of Michael Al- lison, Ken Arromdee, David Cohrs, Jessie Collet, Kevin Hugo, Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and @@ -4462,6 +4480,18 @@ Christian ``Marvin'' Bressler maintained 3.4 for the Atari after he resurrected it for 3.3.1. + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 69 + + + The release of NetHack 3.4.3 in December 2003 marked the be- ginning of a long release hiatus. 3.4.3 proved to be a remarkably stable version that provided continued enjoyment by the community @@ -4480,18 +4510,6 @@ let, Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and Paul Winner. Leading up to the release of 3.6.0 in early 2015, new members Sean Hunt, Pasi Kallinen, and Derek S. - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 69 - - - Ray joined the NetHack development team. In September 2014, an interim snapshot of the code under de- @@ -4527,6 +4545,19 @@ Stephenson, Derek S. Ray, Janet Walz, and Paul Winner released 3.6.1 as a bug fix release in January 2016. + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 70 + + + The official NetHack web site is maintained by Ken Lorber at http://www.nethack.org/. @@ -4546,18 +4577,6 @@ From time to time, some depraved individual out there in netland sends a particularly intriguing modification to help out - - - NetHack 3.6 January 18, 2016 - - - - - - NetHack Guidebook 70 - - - with the game. The Gods of the Dungeon sometimes make note of the names of the worst of these miscreants in this, the list of Dungeoneers: @@ -4592,6 +4611,19 @@ Eric R. Smith Mark Modrall Steve Creps Eric S. Raymond Marvin Bressler Steve Linhart Erik Andersen Matthew Day Steve VanDevender + + + + NetHack 3.6 February 22, 2016 + + + + + + NetHack Guidebook 71 + + + Frederick Roeber Merlyn LeRoy Teemu Suikki Gil Neiger Michael Allison Tim Lennan Greg Laskin Michael Feir Timo Hakulinen @@ -4614,7 +4646,41 @@ - NetHack 3.6 January 18, 2016 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NetHack 3.6 February 22, 2016 diff --git a/doc/fixes36.1 b/doc/fixes36.1 index fefa83ac6..d382342ee 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -163,6 +163,20 @@ using 'R' on armor would bypass some restrictions imposed by 'T' (inner layer when examining hidden monsters (probing, persistent monster detection), tell how they're hidden (under an object, on the ceiling, etc) some quest text corrections +use a much tighter upper bound when summoning nasties; old method could + theoretically create 200 critters at a time +if a long worm inherited inventory from a previous shape, and if an egg or + figurine in that inventory hatched or auto-activated, messages were + given when hero could see any tail segment even if head was unseen, + making it seem as if worm's inventory was kept in the visible segment +Wizard will now steal any quest artifact from hero, not just own role's +prevent a hostile renegade Angel of from delivering taunt + messages which mention threats of retribution from that god +a few types of monster (barrow wight, Nazgul, erinys) have weapon attacks that + don't deal physical damage, so special damage like stoning via wielded + cockatrice corpse wouldn't be inflicted +non-item-using monsters who happened to be carrying scroll or wand of fire or + a fire horn could use it to cure themselves of being turned into slime Platform- and/or Interface-Specific Fixes @@ -173,6 +187,8 @@ tty: specifying all four of role, race, gender, and alignment still prompted for confirmation with "Is this ok?" before starting play tty: responding with or during role, race, &c selection behaved same as to quit; now it will pick [random] instead +tty: rename struct variable 'filter' (role.c) and function 'winch()' (wintty.c) + to avoid conflicts with unix/X11: in top level Makefile, some commented out definitions of VARDATND misspelled pilemark.xbm (as pilemark.xpm) unix: options file with CR+LF line ends and an invalid option line resulted in @@ -211,7 +227,8 @@ allow knife and stiletto as possible tin opening tools wizard mode #wizintrinsic command additional tribute passages for The Colour of Magic, The Light Fantastic, Equal Rites, Mort, Sourcery, Wyrd Sisters, Pyramids, Guards! Guards!, - Eric, Moving Pictures, Reaper Man, Snuff, and Raising Steam + Eric, Moving Pictures, Reaper Man, Witches Abroad, Snuff, and + Raising Steam compile-time options SIMPLE_MAIL and SERVER_ADMIN_MSG for public server use database entries for Cleaver, Sunsword, Frost and Fire brands, and polymorph trap @@ -220,6 +237,12 @@ allow showing coordinates when picking a position on the map and new status line conditions Stone Strngl Deaf Lev Fly Ride allow some extra color name aliases for menucolors and status hilites add extended command #kick +when choosing an inventory item and '-' for bare-hands/fingers/no-ammo is a + choice, include that in the inventory menu if player types '?' or '*' +feedback from probing of long worm now includes number of segments it has +monk starts with 'shuriken' pre-discovered (despite language issue...) +item-using monster on or next to a fire trap can use it to be cured of + turning into slime Platform- and/or Interface-Specific New Features @@ -232,11 +255,26 @@ unix: add CHECK_PLNAME-option to sysconf to make WIZARDS, EXPLORERS, and X11: new NetHack*highlight_prompt resource to control whether the persistent prompt line between the map and message windows for the NetHack*slow configuration will be highlighted when it's expecting input +X11: NetHack*extcmd_height_delta resource can be used to adjust initial size + of the extended commands menu +X11: status display split into three columns to accomodate Stone/Deaf/Lev/&c; + NetHack*status_condition.foreground, .background, and .showGrip + resources replaced by status_condition[1-3].* NetHack Community Patches (or Variation) Included ------------------------------------------------- Malcolm Ryan's improved tin opener +Ray Chason's keyboard may stop responding after locking or unlocking a door when + using altkeyhandler=nhraykey.dll +Ray Chason's fix: window interfaces that support transparency may give away unseen + parts of the map +Ray Chason's xprname should honor iflags.menu_tab_sep +Ray Chason's punctuation for "That foo is really a mimic." +Ray Chason's proper background tiles for lava and water +Ray Chason's MS-DOS port restored to functionality with credit to Reddit user + b_helyer for the fix to sys/share/pcmain.c +Ray Chason's MSDOS port support for some VESA modes Code Cleanup and Reorganization diff --git a/include/extern.h b/include/extern.h index 81a0f3dcc..4277d3b63 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1455672983 2016/02/17 01:36:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.548 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1456992437 2016/03/03 08:07:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.550 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1136,8 +1136,8 @@ E const char *FDECL(mpoisons_subj, (struct monst *, struct attack *)); E void NDECL(u_slow_down); E struct monst *NDECL(cloneu); E void FDECL(expels, (struct monst *, struct permonst *, BOOLEAN_P)); -E struct attack *FDECL(getmattk, - (struct permonst *, int, int *, struct attack *)); +E struct attack *FDECL(getmattk, (struct monst *, struct monst *, + int, int *, struct attack *)); E int FDECL(mattacku, (struct monst *)); E int FDECL(magic_negation, (struct monst *)); E boolean NDECL(gulp_blnd_check); @@ -2715,6 +2715,7 @@ E void FDECL(place_worm_tail_randomly, (struct monst *, XCHAR_P, XCHAR_P)); E int FDECL(count_wsegs, (struct monst *)); E boolean FDECL(worm_known, (struct monst *)); E boolean FDECL(worm_cross, (int, int, int, int)); +E int FDECL(wseg_at, (struct monst *, int, int)); /* ### worn.c ### */ diff --git a/include/flag.h b/include/flag.h index af3b59b65..26009e26a 100644 --- a/include/flag.h +++ b/include/flag.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 flag.h $NHDT-Date: 1451683047 2016/01/01 21:17:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.93 $ */ +/* NetHack 3.6 flag.h $NHDT-Date: 1457207000 2016/03/05 19:43:20 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.101 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -261,6 +261,8 @@ struct instance_flags { #ifdef MSDOS boolean hasvga; /* has a vga adapter */ boolean usevga; /* use the vga adapter */ + boolean hasvesa; /* has a VESA-capable VGA adapter */ + boolean usevesa; /* use the VESA-capable VGA adapter */ boolean grmode; /* currently in graphics mode */ #endif #ifdef LAN_FEATURES diff --git a/include/integer.h b/include/integer.h new file mode 100644 index 000000000..3f77aec8d --- /dev/null +++ b/include/integer.h @@ -0,0 +1,40 @@ +/* NetHack 3.6 integer.h $NHDT-Date: 1457210314 2016/03/05 20:38:34 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */ +/* NetHack may be freely redistributed. See license for details. */ + +/* integer.h -- provide sized integer types */ + +#ifndef INTEGER_H +#define INTEGER_H + +#if defined(__STDC__) && __STDC__ >= 199101L + +/* The compiler claims to conform to C99. Use stdint.h */ +#include +typedef uint8_t uint8; +typedef int16_t int16; +typedef uint16_t uint16; +typedef int32_t int32; +typedef uint32_t uint32; + +#else /* !C99 */ + +/* Provide uint8, int16, uint16, int32 and uint32 */ +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; + +#if defined(__WATCOMC__) && !defined(__386__) +/* Open Watcom providing a 16 bit build for MS-DOS or OS/2 */ +/* int is 16 bits; use long for 32 bits */ +typedef long int32; +typedef unsigned long uint32; +#else +/* Otherwise, assume either a 32- or 64-bit compiler */ +/* long may be 64 bits; use int for 32 bits */ +typedef int int32; +typedef unsigned int uint32; +#endif + +#endif /* !C99 */ + +#endif /* INTEGER_H */ diff --git a/include/mextra.h b/include/mextra.h index 8a37a7483..e69d137df 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -12,55 +12,53 @@ /* * Adding new mextra structures: * - * 1. Add the structure definition and any required macros in this file - * above the mextra struct. - * 2. Add a pointer to your new struct to the mextra struct in this - *file. - * 3. Add a referencing macro at the bottom of this file after the - *mextra - * struct (see MNAME, EGD, EPRI, ESHK, EMIN, or EDOG for examples). - * 4. Create a newXX(mtmp) function and possibly a free_XX(mtmp) - *function - * in an appropriate new or existing source file and add a prototype - * for it to include/extern.h. + * 1. Add the structure definition and any required macros in this + * file above the mextra struct. + * 2. Add a pointer to your new struct to the mextra struct in this + * file. + * 3. Add a referencing macro at bottom of this file after the mextra + * struct (see MNAME, EGD, EPRI, ESHK, EMIN, or EDOG for examples). + * 4. Create a newXX(mtmp) function and possibly a free_XX(mtmp) + * function in an appropriate new or existing source file and add + * a prototype for it to include/extern.h. * - * void FDECL(newXX, (struct monst *)); - * void FDECL(free_XX, (struct monst *)); + * void FDECL(newXX, (struct monst *)); + * void FDECL(free_XX, (struct monst *)); * - * void - * newXX(mtmp) - * struct monst *mtmp; - * { - * if (!mtmp->mextra) mtmp->mextra = newmextra(); - * if (!XX(mtmp)) { - * XX(mtmp) = (struct XX *)alloc(sizeof(struct XX)); - * (void) memset((genericptr_t) XX(mtmp), - * 0, sizeof(struct XX)); - * } - * } + * void + * newXX(mtmp) + * struct monst *mtmp; + * { + * if (!mtmp->mextra) + * mtmp->mextra = newmextra(); + * if (!XX(mtmp)) { + * XX(mtmp) = (struct XX *) alloc(sizeof (struct XX)); + * (void) memset((genericptr_t) XX(mtmp), + * 0, sizeof (struct XX)); + * } + * } * - * 5. Consider adding a new makemon flag MM_XX flag to include/hack.h - *and - * a corresponding change to makemon() if you require your structure - * to be added at monster creation time. Initialize your struct - * after a successful return from makemon(). + * 5. Consider adding a new makemon flag MM_XX flag to include/hack.h + * and a corresponding change to makemon() if you require your + * structure to be added at monster creation time. Initialize your + * struct after a successful return from makemon(). * - * src/makemon.c: if (mmflags & MM_XX) newXX(mtmp); - * your new code: mon = makemon(&mons[mnum], x, y, MM_XX); + * src/makemon.c: if (mmflags & MM_XX) newXX(mtmp); + * your new code: mon = makemon(&mons[mnum], x, y, MM_XX); * - * 6. Adjust size_monst() in src/cmd.c appropriately. - * 7. Adjust dealloc_mextra() in src/mon.c to clean up - * properly during monst deallocation. - * 8. Adjust copy_mextra() in src/mon.c to make duplicate - * copies of your struct or data on another monst struct. - * 9. Adjust restmon() in src/restore.c to deal with your - * struct or data during a restore. - * 10. Adjust savemon() in src/save.c to deal with your - * struct or data during a save. + * 6. Adjust size_monst() in src/cmd.c appropriately. + * 7. Adjust dealloc_mextra() in src/mon.c to clean up + * properly during monst deallocation. + * 8. Adjust copy_mextra() in src/mon.c to make duplicate + * copies of your struct or data on another monst struct. + * 9. Adjust restmon() in src/restore.c to deal with your + * struct or data during a restore. + * 10. Adjust savemon() in src/save.c to deal with your + * struct or data during a save. */ /*** - ** formerly vault.h -- vault guard extension + ** formerly vault.h -- vault guard extension */ #define FCSIZ (ROWNO + COLNO) #define GD_EATGOLD 0x01 @@ -84,7 +82,7 @@ struct egd { }; /*** - ** formerly epri.h -- temple priest extension + ** formerly epri.h -- temple priest extension */ struct epri { aligntyp shralign; /* alignment of priest's shrine */ @@ -100,7 +98,7 @@ struct epri { (and emin extension) */ /*** - ** formerly eshk.h -- shopkeeper extension + ** formerly eshk.h -- shopkeeper extension */ #define REPAIR_DELAY 5 /* minimum delay between shop damage & repair */ #define BILLSZ 200 @@ -135,7 +133,7 @@ struct eshk { }; /*** - ** formerly emin.h -- minion extension + ** formerly emin.h -- minion extension */ struct emin { aligntyp min_align; /* alignment of minion */ @@ -143,17 +141,17 @@ struct emin { }; /*** - ** formerly edog.h -- pet extension + ** formerly edog.h -- pet extension */ -/* various types of pet food, the lower, the better liked */ +/* various types of pet food, the lower, the better liked */ #define DOGFOOD 0 #define CADAVER 1 #define ACCFOOD 2 #define MANFOOD 3 -#define APPORT 4 -#define POISON 5 -#define UNDEF 6 -#define TABU 7 +#define APPORT 4 +#define POISON 5 +#define UNDEF 6 +#define TABU 7 struct edog { long droptime; /* moment dog dropped object */ @@ -169,7 +167,7 @@ struct edog { }; /*** - ** mextra.h -- collection of all monster extensions + ** mextra.h -- collection of all monster extensions */ struct mextra { char *mname; diff --git a/include/obj.h b/include/obj.h index f2acaf80e..d03aec2ec 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 obj.h $NHDT-Date: 1450306176 2015/12/16 22:49:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 3.6 obj.h $NHDT-Date: 1456618994 2016/02/28 00:23:14 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.53 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -200,6 +200,8 @@ struct obj { && objects[otmp->otyp].oc_skill >= -P_SHURIKEN \ && objects[otmp->otyp].oc_skill <= -P_BOW) #define uslinging() (uwep && objects[uwep->otyp].oc_skill == P_SLING) +/* 'is_quest_artifact()' only applies to the current role's artifact */ +#define any_quest_artifact(o) ((o)->oartifact >= ART_ORB_OF_DETECTION) /* Armor */ #define is_shield(otmp) \ diff --git a/include/pcconf.h b/include/pcconf.h index a8806cfe5..01ae261b6 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcconf.h $NHDT-Date: 1432512776 2015/05/25 00:12:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.17 $ */ +/* NetHack 3.6 pcconf.h $NHDT-Date: 1457207019 2016/03/05 19:43:39 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -79,6 +79,7 @@ #if (defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST)) && !defined(PC9800) #ifdef USE_TILES #define SCREEN_VGA /* Include VGA graphics routines in the build */ +#define SCREEN_VESA #endif #endif #else @@ -86,6 +87,7 @@ #undef SCREEN_BIOS #undef SCREEN_DJGPPFAST #undef SCREEN_VGA +#undef SCREEN_VESA #undef TERMLIB #define ANSI_DEFAULT #endif @@ -310,9 +312,8 @@ #endif /* SCREEN_8514, SCREEN_VESA are only placeholders presently - sub VGA instead */ -#if defined(SCREEN_8514) || defined(SCREEN_VESA) +#if defined(SCREEN_8514) #undef SCREEN_8514 -#undef SCREEN_VESA #define SCREEN_VGA #endif /* Graphical tile sanity checks */ diff --git a/include/tileset.h b/include/tileset.h new file mode 100644 index 000000000..2ab145e66 --- /dev/null +++ b/include/tileset.h @@ -0,0 +1,43 @@ +/* NetHack 3.6 tileset.h $NHDT-Date: 1457207052 2016/03/05 19:44:12 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */ +/* Copyright (c) Ray Chason, 2016. */ +/* NetHack may be freely redistributed. See license for details. */ + +#ifndef TILESET_H +#define TILESET_H + +struct Pixel { + unsigned char r, g, b, a; +}; + +struct TileImage { + /* Image data */ + unsigned width, height; + struct Pixel *pixels; /* for direct color */ + unsigned char *indexes; /* for paletted images */ +}; + +boolean FDECL(read_tiles, (const char *filename, BOOLEAN_P true_color)); +const struct Pixel *NDECL(get_palette); +void NDECL(free_tiles); +const struct TileImage *FDECL(get_tile, (unsigned tile_index)); + +/* Used internally by the tile set code */ +struct TileSetImage { + /* Image data */ + unsigned width, height; + struct Pixel *pixels; /* for direct color */ + unsigned char *indexes; /* for paletted images */ + struct Pixel palette[256]; + + /* Image description from the file */ + char *image_desc; + + /* Tile dimensions */ + unsigned tile_width, tile_height; +}; + +boolean FDECL(read_bmp_tiles, (const char *filename, struct TileSetImage *image)); +boolean FDECL(read_gif_tiles, (const char *filename, struct TileSetImage *image)); +boolean FDECL(read_png_tiles, (const char *filename, struct TileSetImage *image)); + +#endif diff --git a/include/winX.h b/include/winX.h index 78648c8b4..796121405 100644 --- a/include/winX.h +++ b/include/winX.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 winX.h $NHDT-Date: 1454977916 2016/02/09 00:31:56 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 3.6 winX.h $NHDT-Date: 1457079196 2016/03/04 08:13:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -252,6 +252,7 @@ typedef struct { String tile_file; /* name of file to open for tiles */ String icon; /* name of desired icon */ int message_lines; /* number of lines to attempt to show */ + int extcmd_height_delta; /* bottom margin for extended command menu */ String pet_mark_bitmap; /* X11 bitmap file used to mark pets */ Pixel pet_mark_color; /* color of pet mark */ String pilemark_bitmap; /* X11 bitmap file used to mark item piles */ diff --git a/src/apply.c b/src/apply.c index e993db834..e30542dd2 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 apply.c $NHDT-Date: 1455140802 2016/02/10 21:46:42 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.220 $ */ +/* NetHack 3.6 apply.c $NHDT-Date: 1457207021 2016/03/05 19:43:41 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.223 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -323,6 +323,8 @@ register struct obj *obj; context.stethoscope_move = moves; context.stethoscope_movement = youmonst.movement; + bhitpos.x = u.ux, bhitpos.y = u.uy; /* tentative, reset below */ + notonhead = u.uswallow; if (u.usteed && u.dz > 0) { if (interference) { pline("%s interferes.", Monnam(u.ustuck)); @@ -369,6 +371,10 @@ register struct obj *obj; const char *mnm = x_monnam(mtmp, ARTICLE_A, (const char *) 0, SUPPRESS_IT | SUPPRESS_INVISIBLE, FALSE); + /* bhitpos needed by mstatusline() iff mtmp is a long worm */ + bhitpos.x = rx, bhitpos.y = ry; + notonhead = (mtmp->mx != rx || mtmp->my != ry); + if (mtmp->mundetected) { if (!canspotmon(mtmp)) There("is %s hidden there.", mnm); @@ -389,10 +395,11 @@ register struct obj *obj; break; } seemimic(mtmp); - pline("That %s is really %s", what, mnm); + pline("That %s is really %s.", what, mnm); } else if (flags.verbose && !canspotmon(mtmp)) { There("is %s there.", mnm); } + mstatusline(mtmp); if (!canspotmon(mtmp)) map_invisible(rx, ry); @@ -403,6 +410,7 @@ register struct obj *obj; newsym(rx, ry); pline_The("invisible monster must have moved."); } + lev = &levl[rx][ry]; switch (lev->typ) { case SDOOR: @@ -1966,8 +1974,8 @@ long timeout; if (mtmp) { char and_vanish[BUFSZ]; struct obj *mshelter = level.objects[mtmp->mx][mtmp->my]; - Sprintf(monnambuf, "%s", an(m_monnam(mtmp))); + Sprintf(monnambuf, "%s", an(m_monnam(mtmp))); and_vanish[0] = '\0'; if ((mtmp->minvis && !See_invisible) || (mtmp->data->mlet == S_MIMIC @@ -2009,11 +2017,13 @@ long timeout; case OBJ_MINVENT: if (cansee_spot && !silent && !suppress_see) { struct monst *mon; + mon = figurine->ocarry; /* figurine carrying monster might be invisible */ - if (canseemon(figurine->ocarry)) { + if (canseemon(figurine->ocarry) + && (!mon->wormno || cansee(mon->mx, mon->my))) Sprintf(carriedby, "%s pack", s_suffix(a_monnam(mon))); - } else if (is_pool(mon->mx, mon->my)) + else if (is_pool(mon->mx, mon->my)) Strcpy(carriedby, "empty water"); else Strcpy(carriedby, "thin air"); diff --git a/src/cmd.c b/src/cmd.c index 47cdf8a2e..40c711bd0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1452660189 2016/01/13 04:43:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.219 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1457207033 2016/03/05 19:43:53 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.220 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -355,7 +355,7 @@ doextlist(VOID_ARGS) return 0; } -#ifdef TTY_GRAPHICS +#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) #define MAX_EXT_CMD 50 /* Change if we ever have > 50 ext cmds */ /* diff --git a/src/display.c b/src/display.c index b4970378f..48101d432 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 display.c $NHDT-Date: 1446808439 2015/11/06 11:13:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.77 $ */ +/* NetHack 3.6 display.c $NHDT-Date: 1457207034 2016/03/05 19:43:54 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.82 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1748,7 +1748,8 @@ xchar x, y; int idx, bkglyph = NO_GLYPH; struct rm *lev = &levl[x][y]; - if (iflags.use_background_glyph) { + if (iflags.use_background_glyph && lev->seenv != 0 + && gbuf[y][x].glyph != cmap_to_glyph(S_stone)) { switch (lev->typ) { case SCORR: case STONE: @@ -1769,9 +1770,16 @@ xchar x, y; case CLOUD: idx = S_cloud; break; + case POOL: + case MOAT: + idx = S_pool; + break; case WATER: idx = S_water; break; + case LAVAPOOL: + idx = S_lava; + break; default: idx = S_room; break; diff --git a/src/engrave.c b/src/engrave.c index 088cad8ce..a4a07bd5b 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 engrave.c $NHDT-Date: 1455491569 2016/02/14 23:12:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */ +/* NetHack 3.6 engrave.c $NHDT-Date: 1456304550 2016/02/24 09:02:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.61 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -535,7 +535,7 @@ doengrave() return 0; if (otmp == &zeroobj) { - Strcat(strcpy(fbuf, "your "), makeplural(body_part(FINGER))); + Strcat(strcpy(fbuf, "your "), body_part(FINGERTIP)); writer = fbuf; } else writer = yname(otmp); @@ -993,8 +993,7 @@ doengrave() if (otmp != &zeroobj) You("%s the %s with %s.", everb, eloc, doname(otmp)); else - You("%s the %s with your %s.", everb, eloc, - makeplural(body_part(FINGER))); + You("%s the %s with your %s.", everb, eloc, body_part(FINGERTIP)); /* Prompt for engraving! */ Sprintf(qbuf, "What do you want to %s the %s here?", everb, eloc); diff --git a/src/invent.c b/src/invent.c index dfd3a9478..103ee9580 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1454061993 2016/01/29 10:06:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.193 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1457207035 2016/03/05 19:43:55 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.197 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,6 +6,7 @@ #define NOINVSYM '#' #define CONTAINED_SYM '>' /* designator for inside a container */ +#define HANDS_SYM '-' STATIC_DCL int FDECL(CFDECLSPEC sortloot_cmp, (struct obj *, struct obj *)); STATIC_DCL void NDECL(reorder_invent); @@ -21,7 +22,8 @@ STATIC_PTR int FDECL(ckunpaid, (struct obj *)); STATIC_PTR int FDECL(ckvalidcat, (struct obj *)); STATIC_PTR char *FDECL(safeq_xprname, (struct obj *)); STATIC_PTR char *FDECL(safeq_shortxprname, (struct obj *)); -STATIC_DCL char FDECL(display_pickinv, (const char *, BOOLEAN_P, long *)); +STATIC_DCL char FDECL(display_pickinv, (const char *, const char *, + BOOLEAN_P, long *)); STATIC_DCL char FDECL(display_used_invlets, (CHAR_P)); STATIC_DCL void FDECL(tally_BUCX, (struct obj *, int *, int *, int *, int *, int *)); @@ -1004,9 +1006,7 @@ register const char *let, *word; useboulder = TRUE; if (allownone) - *bp++ = '-'; - if (bp > buf && bp[-1] == '-') - *bp++ = ' '; + *bp++ = HANDS_SYM, *bp++ = ' '; /* '-' */ ap = altlets; if (!flags.invlet_constant) @@ -1184,6 +1184,7 @@ register const char *let, *word; ilet = yn_function(qbuf, (char *) 0, '\0'); if (digit(ilet)) { long tmpcnt = 0; + if (!allowcnt) { pline("No count allowed with this command."); continue; @@ -1199,7 +1200,7 @@ register const char *let, *word; pline1(Never_mind); return (struct obj *) 0; } - if (ilet == '-') { + if (ilet == HANDS_SYM) { /* '-' */ if (!allownone) { char *suf = (char *) 0; @@ -1225,21 +1226,34 @@ register const char *let, *word; char *allowed_choices = (ilet == '?') ? lets : (char *) 0; long ctmp = 0; + qbuf[0] = '\0'; + if (!strcmp(word, "grease")) + Sprintf(qbuf, "your %s", makeplural(body_part(FINGER))); + else if (!strcmp(word, "write with")) + Sprintf(qbuf, "your %s", body_part(FINGERTIP)); + else if (!strcmp(word, "wield")) + Sprintf(qbuf, "your %s %s", uarmg ? "gloved" : "bare", + makeplural(body_part(HAND))); + else if (!strcmp(word, "ready")) + Strcpy(qbuf, "empty quiver"); + if (ilet == '?' && !*lets && *altlets) allowed_choices = altlets; - ilet = display_pickinv(allowed_choices, TRUE, - allowcnt ? &ctmp : (long *) 0); + ilet = display_pickinv(allowed_choices, *qbuf ? qbuf : (char *) 0, + TRUE, allowcnt ? &ctmp : (long *) 0); if (!ilet) continue; - if (allowcnt && ctmp >= 0) { - cnt = ctmp; - cntgiven = TRUE; - } + if (ilet == HANDS_SYM) + return &zeroobj; if (ilet == '\033') { if (flags.verbose) pline1(Never_mind); return (struct obj *) 0; } + if (allowcnt && ctmp >= 0) { + cnt = ctmp; + cntgiven = TRUE; + } /* they typed a letter (not a space) at the prompt */ } /* find the item which was picked */ @@ -1423,7 +1437,7 @@ boolean combo; /* combination menu flag */ unsigned *resultflags; { int FDECL((*ckfn), (OBJ_P)) = (int FDECL((*), (OBJ_P))) 0; - boolean FDECL((*filter), (OBJ_P)) = (boolean FDECL((*), (OBJ_P))) 0; + boolean FDECL((*ofilter), (OBJ_P)) = (boolean FDECL((*), (OBJ_P))) 0; boolean takeoff, ident, allflag, m_seen; int itemcount; int oletct, iletct, unpaid, oc_of_sym; @@ -1441,13 +1455,13 @@ unsigned *resultflags; add_valid_menu_class(0); /* reset */ if (taking_off(word)) { takeoff = TRUE; - filter = is_worn; + ofilter = is_worn; } else if (!strcmp(word, "identify")) { ident = TRUE; - filter = not_fully_identified; + ofilter = not_fully_identified; } - iletct = collect_obj_classes(ilets, invent, FALSE, filter, &itemcount); + iletct = collect_obj_classes(ilets, invent, FALSE, ofilter, &itemcount); unpaid = count_unpaid(invent); if (ident && !iletct) { @@ -1905,22 +1919,25 @@ long quan; /* if non-0, print this quantity, not obj->quan */ #else static char li[BUFSZ]; #endif - boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM; + boolean use_invlet = (flags.invlet_constant + && let != CONTAINED_SYM && let != HANDS_SYM); long savequan = 0; if (quan && obj) { savequan = obj->quan; obj->quan = quan; } - /* * If let is: + * - Then obj == null and 'txt' refers to hands or fingers. * * Then obj == null and we are printing a total amount. * > Then the object is contained and doesn't have an inventory letter. */ if (cost != 0 || let == '*') { /* if dot is true, we're doing Iu, otherwise Ix */ - Sprintf(li, "%c - %-45s %6ld %s", + Sprintf(li, + iflags.menu_tab_sep ? "%c - %s\t%6ld %s" + : "%c - %-45s %6ld %s", (dot && use_invlet ? obj->invlet : let), (txt ? txt : doname(obj)), cost, currency(cost)); } else { @@ -1995,8 +2012,9 @@ free_pickinv_cache() * any count returned from the menu selection is placed here. */ STATIC_OVL char -display_pickinv(lets, want_reply, out_cnt) +display_pickinv(lets, xtra_choice, want_reply, out_cnt) register const char *lets; +const char *xtra_choice; /* "fingers", pick hands rather than an object */ boolean want_reply; long *out_cnt; { @@ -2009,7 +2027,7 @@ long *out_cnt; menu_item *selected; struct obj **oarray; - if (flags.perm_invent && lets && *lets) { + if (flags.perm_invent && ((lets && *lets) || xtra_choice)) { /* partial inventory in perm_invent setting; don't operate on full inventory window, use an alternate one instead; create the first time needed and keep it for re-use as needed later */ @@ -2029,8 +2047,21 @@ long *out_cnt; * don't know at this level if its up or not. This may not be * an issue if empty checks are done before hand and the call * to here is short circuited away. + * + * 2: our count here is only to distinguish between 0 and 1 and + * more than 1; for the last one, we don't need a precise number. + * For perm_invent update we force 'more than 1'. */ - if (!invent && !(flags.perm_invent && !lets && !want_reply)) { + n = (flags.perm_invent && !lets && !want_reply) ? 2 + : lets ? (int) strlen(lets) + : !invent ? 0 : !invent->nobj ? 1 : 2; + /* for xtra_choice, there's another 'item' not included in initial 'n'; + for !lets (full invent) and for override_ID (wizard mode identify), + skip message_menu handling of single item even if item count was 1 */ + if (xtra_choice || (n == 1 && (!lets || iflags.override_ID))) + ++n; + + if (n == 0) { pline("Not carrying anything."); return 0; } @@ -2039,31 +2070,39 @@ long *out_cnt; if (!flags.invlet_constant) reassign(); - if (lets && strlen(lets) == 1 && !iflags.override_ID) { + if (n == 1) { /* when only one item of interest, use pline instead of menus; we actually use a fake message-line menu in order to allow the user to perform selection at the --More-- prompt for tty */ ret = '\0'; - for (otmp = invent; otmp; otmp = otmp->nobj) { - if (otmp->invlet == lets[0]) { - ret = message_menu( - lets[0], want_reply ? PICK_ONE : PICK_NONE, - xprname(otmp, (char *) 0, lets[0], TRUE, 0L, 0L)); - if (out_cnt) - *out_cnt = -1L; /* select all */ - break; - } + if (xtra_choice) { + /* xtra_choice is "bare hands" (wield), "fingertip" (Engrave), + "nothing" (ready Quiver), or "fingers" (apply grease) */ + ret = message_menu(HANDS_SYM, PICK_ONE, + xprname((struct obj *) 0, xtra_choice, + HANDS_SYM, TRUE, 0L, 0L)); /* '-' */ + } else { + for (otmp = invent; otmp; otmp = otmp->nobj) + if (!lets || otmp->invlet == lets[0]) + break; + if (otmp) + ret = message_menu(otmp->invlet, + want_reply ? PICK_ONE : PICK_NONE, + xprname(otmp, (char *) 0, lets[0], + TRUE, 0L, 0L)); } + if (out_cnt) + *out_cnt = -1L; /* select all */ return ret; } - /* count the number of items */ + /* count the number of items (preliminary count of 0,1,more was 'more' + and is now obsolete); we have at least 2 items or want to behave as + if we do (full invent and wiz_identify use this even for 1 item) */ for (n = 0, otmp = invent; otmp; otmp = otmp->nobj) if (!lets || !*lets || index(lets, otmp->invlet)) n++; - oarray = objarr_init(n); - /* Add objects to the array */ i = 0; for (otmp = invent; otmp; otmp = otmp->nobj) @@ -2074,23 +2113,31 @@ long *out_cnt; start_menu(win); any = zeroany; if (wizard && iflags.override_ID) { - char prompt[BUFSZ]; + char prompt[QBUFSZ]; + any.a_char = -1; - /* wiz_identify stuffed the wiz_identify cmd character - into iflags.override_ID */ + /* wiz_identify stuffed the wiz_identify command character (^I) + into iflags.override_ID for our use as an accelerator */ Sprintf(prompt, "Debug Identify (%s to permanently identify)", visctrl(iflags.override_ID)); add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE, prompt, MENU_UNSELECTED); + } else if (xtra_choice) { + /* wizard override ID and xtra_choice are mutually exclusive */ + if (flags.sortpack) + add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, + "Miscellaneous", MENU_UNSELECTED); + any.a_char = HANDS_SYM; /* '-' */ + add_menu(win, NO_GLYPH, &any, HANDS_SYM, 0, ATR_NONE, + xtra_choice, MENU_UNSELECTED); } nextclass: classcount = 0; - any = zeroany; /* set all bits to zero */ for (i = 0; i < n; i++) { otmp = oarray[i]; - ilet = otmp->invlet; - any = zeroany; /* zero */ if (!flags.sortpack || otmp->oclass == *invlet) { + any = zeroany; /* all bits zero */ + ilet = otmp->invlet; if (flags.sortpack && !classcount) { add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, let_to_name(*invlet, FALSE, @@ -2138,7 +2185,7 @@ display_inventory(lets, want_reply) const char *lets; boolean want_reply; { - return display_pickinv(lets, want_reply, (long *) 0); + return display_pickinv(lets, (char *) 0, want_reply, (long *) 0); } /* diff --git a/src/mhitm.c b/src/mhitm.c index 533527cca..b52c6f226 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mhitm.c $NHDT-Date: 1446854229 2015/11/06 23:57:09 $ $NHDT-Branch: master $:$NHDT-Revision: 1.83 $ */ +/* NetHack 3.6 mhitm.c $NHDT-Date: 1456992461 2016/03/03 08:07:41 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.86 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -351,7 +351,7 @@ register struct monst *magr, *mdef; /* Now perform all attacks for the monster. */ for (i = 0; i < NATTK; i++) { res[i] = MM_MISS; - mattk = getmattk(pa, i, res, &alt_attk); + mattk = getmattk(magr, mdef, i, res, &alt_attk); otmp = (struct obj *) 0; attk = 1; switch (mattk->aatyp) { diff --git a/src/mhitu.c b/src/mhitu.c index d8c85a133..f7f0afde2 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mhitu.c $NHDT-Date: 1451084422 2015/12/25 23:00:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.132 $ */ +/* NetHack 3.6 mhitu.c $NHDT-Date: 1456992469 2016/03/03 08:07:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.136 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -256,12 +256,14 @@ boolean message; /* select a monster's next attack, possibly substituting for its usual one */ struct attack * -getmattk(mptr, indx, prev_result, alt_attk_buf) -struct permonst *mptr; +getmattk(magr, mdef, indx, prev_result, alt_attk_buf) +struct monst *magr, *mdef; int indx, prev_result[]; struct attack *alt_attk_buf; { + struct permonst *mptr = magr->data; struct attack *attk = &mptr->mattk[indx]; + struct obj *weap = (magr == &youmonst) ? uwep : MON_WEP(magr); /* prevent a monster with two consecutive disease or hunger attacks from hitting with both of them on the same turn; if the first has @@ -275,7 +277,7 @@ struct attack *alt_attk_buf; attk->adtyp = AD_STUN; /* make drain-energy damage be somewhat in proportion to energy */ - } else if (attk->adtyp == AD_DREN) { + } else if (attk->adtyp == AD_DREN && mdef == &youmonst) { int ulev = max(u.ulevel, 6); *alt_attk_buf = *attk; @@ -293,6 +295,25 @@ struct attack *alt_attk_buf; attk->damd += 3; /* very high energy: 3d6 -> 3d9 */ /* note: 3d9 is slightly higher than previous 4d6 */ } + + /* barrow wight, Nazgul, erinys have weapon attack for non-physical + damage; force physical damage if attacker has been cancelled or + if weapon is sufficiently interesting; a few unique creatures + have two weapon attacks where one does physical damage and other + doesn't--avoid forcing physical damage for those */ + } else if (indx == 0 && magr != &youmonst + && attk->aatyp == AT_WEAP && attk->adtyp != AD_PHYS + && !(mptr->mattk[1].aatyp == AT_WEAP + && mptr->mattk[1].adtyp == AD_PHYS) + && (magr->mcan + || (weap + && ((weap->otyp == CORPSE + && touch_petrifies(&mons[weap->corpsenm])) + || weap->oartifact == ART_STORMBRINGER + || weap->oartifact == ART_VORPAL_BLADE)))) { + *alt_attk_buf = *attk; + attk = alt_attk_buf; + attk->adtyp = AD_PHYS; } return attk; } @@ -608,7 +629,7 @@ register struct monst *mtmp; for (i = 0; i < NATTK; i++) { sum[i] = 0; - mattk = getmattk(mdat, i, sum, &alt_attk); + mattk = getmattk(mtmp, &youmonst, i, sum, &alt_attk); if ((u.uswallow && mattk->aatyp != AT_ENGL) || (skipnonmagc && mattk->aatyp != AT_MAGC)) continue; @@ -1321,11 +1342,11 @@ register struct attack *mattk; case AD_SAMU: hitmsg(mtmp, mattk); - /* when the Wiz hits, 1/20 steals the amulet */ - if (u.uhave.amulet || u.uhave.bell || u.uhave.book || u.uhave.menorah - || u.uhave.questart) /* carrying the Quest Artifact */ - if (!rn2(20)) - stealamulet(mtmp); + /* when the Wizard or quest nemesis hits, there's a 1/20 chance + to steal a quest artifact (any, not just the one for the hero's + own role) or the Amulet or one of the invocation tools */ + if (!rn2(20)) + stealamulet(mtmp); break; case AD_TLPT: @@ -1373,9 +1394,10 @@ register struct attack *mattk; hitmsg(mtmp, mattk); break; } - if (!uwep && !uarmu && !uarm && !uarmh && !uarms && !uarmg && !uarmc - && !uarmf) { + if (!uwep && !uarmu && !uarm && !uarmc + && !uarms && !uarmg && !uarmf && !uarmh) { boolean goaway = FALSE; + pline("%s hits! (I hope you don't mind.)", Monnam(mtmp)); if (Upolyd) { u.mh += rnd(7); diff --git a/src/monmove.c b/src/monmove.c index d13dc3c61..964db35ee 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1455402384 2016/02/13 22:26:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.84 $ */ +/* NetHack 3.6 monmove.c $NHDT-Date: 1456959639 2016/03/02 23:00:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.85 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1218,12 +1218,12 @@ postmov: } ptr = mtmp->data; - /* open a door, or crash through it, if you can */ + /* open a door, or crash through it, if 'mtmp' can */ if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ) && !passes_walls(ptr) /* doesn't need to open doors */ && !can_tunnel) { /* taken care of below */ struct rm *here = &levl[mtmp->mx][mtmp->my]; - boolean btrapped = (here->doormask & D_TRAPPED), + boolean btrapped = (here->doormask & D_TRAPPED) != 0, observeit = canseeit && canspotmon(mtmp); if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0 @@ -1296,7 +1296,7 @@ postmov: else if (!Deaf) You_hear("a door crash open."); } - if (here->doormask & D_LOCKED && !rn2(2)) + if ((here->doormask & D_LOCKED) != 0 && !rn2(2)) here->doormask = D_NODOOR; else here->doormask = D_BROKEN; diff --git a/src/muse.c b/src/muse.c index f5bec8c39..b0a843d7d 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 muse.c $NHDT-Date: 1449799863 2015/12/11 02:11:03 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 3.6 muse.c $NHDT-Date: 1457254910 2016/03/06 09:01:50 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.72 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -34,7 +34,7 @@ STATIC_DCL boolean FDECL(cures_stoning, (struct monst *, struct obj *, BOOLEAN_P)); STATIC_DCL boolean FDECL(mcould_eat_tin, (struct monst *)); STATIC_DCL boolean FDECL(muse_unslime, (struct monst *, struct obj *, - BOOLEAN_P)); + struct trap *, BOOLEAN_P)); STATIC_DCL int FDECL(cures_sliming, (struct monst *, struct obj *)); STATIC_DCL boolean FDECL(green_mon, (struct monst *)); @@ -605,7 +605,7 @@ struct monst *mtmp; int i, fleetim, how = 0; struct obj *otmp = m.defensive; boolean vis, vismon, oseen; - const char *mcsa = "%s can see again."; + const char *Mnam, *mcsa = "%s can see again."; if ((i = precheck(mtmp, otmp)) != 0) return i; @@ -824,9 +824,10 @@ struct monst *mtmp; if (vis) { struct trap *t = t_at(trapx, trapy); - pline("%s %s into a %s!", Monnam(mtmp), - makeplural(locomotion(mtmp->data, "jump")), - t->ttyp == TRAPDOOR ? "trap door" : "hole"); + Mnam = Monnam(mtmp); + pline("%s %s into a %s!", Mnam, + vtense(Mnam, locomotion(mtmp->data, "jump")), + (t->ttyp == TRAPDOOR) ? "trap door" : "hole"); if (levl[trapx][trapy].typ == SCORR) { levl[trapx][trapy].typ = CORR; unblock_point(trapx, trapy); @@ -920,8 +921,9 @@ struct monst *mtmp; case MUSE_TELEPORT_TRAP: m_flee(mtmp); if (vis) { - pline("%s %s onto a teleport trap!", Monnam(mtmp), - makeplural(locomotion(mtmp->data, "jump"))); + Mnam = Monnam(mtmp); + pline("%s %s onto a teleport trap!", Mnam, + vtense(Mnam, locomotion(mtmp->data, "jump"))); seetrap(t_at(trapx, trapy)); } /* don't use rloc_to() because worm tails must "move" */ @@ -1114,7 +1116,7 @@ struct monst *mtmp; m.has_offense = MUSE_WAN_FIRE; } nomore(MUSE_FIRE_HORN); - if (obj->otyp == FIRE_HORN && obj->spe > 0) { + if (obj->otyp == FIRE_HORN && obj->spe > 0 && can_blow(mtmp)) { m.offensive = obj; m.has_offense = MUSE_FIRE_HORN; } @@ -1124,7 +1126,7 @@ struct monst *mtmp; m.has_offense = MUSE_WAN_COLD; } nomore(MUSE_FROST_HORN); - if (obj->otyp == FROST_HORN && obj->spe > 0) { + if (obj->otyp == FROST_HORN && obj->spe > 0 && can_blow(mtmp)) { m.offensive = obj; m.has_offense = MUSE_FROST_HORN; } @@ -1862,9 +1864,12 @@ struct monst *mtmp; m_useup(mtmp, otmp); return 2; case MUSE_POLY_TRAP: - if (vismon) - pline("%s deliberately %s onto a polymorph trap!", Monnam(mtmp), - makeplural(locomotion(mtmp->data, "jump"))); + if (vismon) { + const char *Mnam = Monnam(mtmp); + + pline("%s deliberately %s onto a polymorph trap!", Mnam, + vtense(Mnam, locomotion(mtmp->data, "jump"))); + } if (vis) seetrap(t_at(trapx, trapy)); @@ -2069,7 +2074,7 @@ struct obj *obj; if (typ == UNICORN_HORN) return (boolean) (!obj->cursed && !is_unicorn(mon->data)); if (typ == FROST_HORN || typ == FIRE_HORN) - return (obj->spe > 0); + return (obj->spe > 0 && can_blow(mon)); break; case FOOD_CLASS: if (typ == CORPSE) @@ -2322,6 +2327,7 @@ struct monst *mon; boolean by_you; { struct obj *obj, odummy; + struct permonst *mptr = mon->data; /* * muse_unslime() gives "mon starts turning green", "mon zaps @@ -2330,7 +2336,7 @@ boolean by_you; * (via our caller) newcham()'s "mon turns into slime" feedback. */ - if (slimeproof(mon->data)) + if (slimeproof(mptr)) return FALSE; if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE; @@ -2342,27 +2348,61 @@ boolean by_you; [possible extension: monst capable of casting high level clerical spells could toss pillar of fire at self--probably too suicidal] */ if (!mon->mcan && !mon->mspec_used - && attacktype_fordmg(mon->data, AT_BREA, AD_FIRE)) { + && attacktype_fordmg(mptr, AT_BREA, AD_FIRE)) { odummy = zeroobj; /* otyp == STRANGE_OBJECT */ - return muse_unslime(mon, &odummy, by_you); + return muse_unslime(mon, &odummy, (struct trap *) 0, by_you); } - for (obj = mon->minvent; obj; obj = obj->nobj) - if (cures_sliming(mon, obj)) - return muse_unslime(mon, obj, by_you); + /* same MUSE criteria as use_defensive() */ + if (!is_animal(mptr) && !mindless(mptr)) { + struct trap *t; - /* TODO: check for and move onto an adjacent fire trap */ + for (obj = mon->minvent; obj; obj = obj->nobj) + if (cures_sliming(mon, obj)) + return muse_unslime(mon, obj, (struct trap *) 0, by_you); + + if (((t = t_at(mon->mx, mon->my)) == 0 || t->ttyp != FIRE_TRAP) + && !mon->mtrapped && !mptr->mmove == 0) { + int xy[2][8], x, y, idx, ridx, nxy = 0; + + for (x = mon->mx - 1; x <= mon->mx + 1; ++x) + for (y = mon->my - 1; y <= mon->my + 1; ++y) + if (isok(x, y) && accessible(x, y) + && !m_at(x, y) && (x != u.ux || y != u.uy)) { + xy[0][nxy] = x, xy[1][nxy] = y; + ++nxy; + } + for (idx = 0; idx < nxy; ++idx) { + ridx = rn1(nxy - idx, idx); + if (ridx != idx) { + x = xy[0][idx]; + xy[0][idx] = xy[0][ridx]; + xy[0][ridx] = x; + y = xy[1][idx]; + xy[1][idx] = xy[1][ridx]; + xy[1][ridx] = y; + } + if ((t = t_at(xy[0][idx], xy[1][idx])) != 0 + && t->ttyp == FIRE_TRAP) + break; + } + } + if (t && t->ttyp == FIRE_TRAP) + return muse_unslime(mon, &zeroobj, t, by_you); + + } /* MUSE */ return FALSE; } /* mon uses an item--selected by caller--to burn away incipient slime */ STATIC_OVL boolean -muse_unslime(mon, obj, by_you) +muse_unslime(mon, obj, trap, by_you) struct monst *mon; struct obj *obj; +struct trap *trap; boolean by_you; /* true: if mon kills itself, hero gets credit/blame */ -{ +{ /* [by_you not honored if 'mon' triggers fire trap]. */ struct obj *odummyp; int otyp = obj->otyp, dmg; boolean vis = canseemon(mon), res = TRUE; @@ -2373,7 +2413,30 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */ /* -4 => sliming, causes quiet loss of enhanced speed */ mon_adjust_speed(mon, -4, (struct obj *) 0); - if (otyp == STRANGE_OBJECT) { + if (trap) { + const char *Mnam = vis ? Monnam(mon) : 0; + + if (mon->mx == trap->tx && mon->my == trap->ty) { + if (vis) + pline("%s triggers %s fire trap!", Mnam, + trap->tseen ? "the" : "a"); + } else { + remove_monster(mon->mx, mon->my); + newsym(mon->mx, mon->my); + place_monster(mon, trap->tx, trap->ty); + if (mon->wormno) /* won't happen; worms don't MUSE to unslime */ + worm_move(mon); + newsym(mon->mx, mon->my); + if (vis) + pline("%s %s %s %s fire trap!", Mnam, + vtense(Mnam, locomotion(mon->data, "move")), + is_floater(mon->data) ? "over" : "onto", + trap->tseen ? "the" : "a"); + } + /* hack to avoid mintrap()'s chance of avoiding known trap */ + mon->mtrapseen &= ~(1 << (FIRE_TRAP - 1)); + mintrap(mon); + } else if (otyp == STRANGE_OBJECT) { /* monster is using fire breath on self */ if (vis) pline("%s breathes fire on %sself.", Monnam(mon), mhim(mon)); @@ -2429,7 +2492,8 @@ struct obj *obj; if (obj->otyp == SCR_FIRE) return (haseyes(mon->data) && mon->mcansee); /* hero doesn't need hands or even limbs to zap, so mon doesn't either */ - return ((obj->otyp == WAN_FIRE || obj->otyp == FIRE_HORN) + return ((obj->otyp == WAN_FIRE + || (obj->otyp == FIRE_HORN && can_blow(mon))) && obj->spe > 0); } diff --git a/src/pline.c b/src/pline.c index 0c9a400e3..3775a7c14 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pline.c $NHDT-Date: 1455672995 2016/02/17 01:36:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.48 $ */ +/* NetHack 3.6 pline.c $NHDT-Date: 1456528597 2016/02/26 23:16:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -397,6 +397,22 @@ register struct monst *mtmp; } } else if (mtmp->mpeaceful) Strcat(info, ", peaceful"); + + if (mtmp->data == &mons[PM_LONG_WORM]) { + int segndx, nsegs = count_wsegs(mtmp); + + /* the worm code internals don't consider the head of be one of + the worm's segments, but we count it as such when presenting + worm feedback to the player */ + if (!nsegs) { + Strcat(info, ", single segment"); + } else { + ++nsegs; /* include head in the segment count */ + segndx = wseg_at(mtmp, bhitpos.x, bhitpos.y); + Sprintf(eos(info), ", %d%s of %d segments", + segndx, ordin(segndx), nsegs); + } + } if (mtmp->cham >= LOW_PM && mtmp->data != &mons[mtmp->cham]) /* don't reveal the innate form (chameleon, vampire, &c), just expose the fact that this current form isn't it */ diff --git a/src/role.c b/src/role.c index 1c6d3e1a5..0657eb4f0 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 role.c $NHDT-Date: 1453514597 2016/01/23 02:03:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 3.6 role.c $NHDT-Date: 1456907852 2016/03/02 08:37:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.37 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /* NetHack may be freely redistributed. See license for details. */ @@ -768,7 +768,7 @@ const struct Align aligns[] = { static struct { boolean roles[SIZE(roles)]; short mask; -} filter; +} rfilter; STATIC_DCL int NDECL(randrole_filtered); STATIC_DCL char *FDECL(promptsep, (char *, int)); @@ -1046,7 +1046,7 @@ int rolenum, racenum, gendnum, alignnum; short allow; if (rolenum >= 0 && rolenum < SIZE(roles) - 1) { - if (filter.roles[rolenum]) + if (rfilter.roles[rolenum]) return FALSE; allow = roles[rolenum].allow; if (racenum >= 0 && racenum < SIZE(races) - 1 @@ -1062,7 +1062,7 @@ int rolenum, racenum, gendnum, alignnum; } else { /* random; check whether any selection is possible */ for (i = 0; i < SIZE(roles) - 1; i++) { - if (filter.roles[i]) + if (rfilter.roles[i]) continue; allow = roles[i].allow; if (racenum >= 0 && racenum < SIZE(races) - 1 @@ -1114,7 +1114,7 @@ int rolenum, racenum, gendnum, alignnum; short allow; if (racenum >= 0 && racenum < SIZE(races) - 1) { - if (filter.mask & races[racenum].selfmask) + if (rfilter.mask & races[racenum].selfmask) return FALSE; allow = races[racenum].allow; if (rolenum >= 0 && rolenum < SIZE(roles) - 1 @@ -1130,7 +1130,7 @@ int rolenum, racenum, gendnum, alignnum; } else { /* random; check whether any selection is possible */ for (i = 0; i < SIZE(races) - 1; i++) { - if (filter.mask & races[i].selfmask) + if (rfilter.mask & races[i].selfmask) continue; allow = races[i].allow; if (rolenum >= 0 && rolenum < SIZE(roles) - 1 @@ -1187,7 +1187,7 @@ int alignnum UNUSED; short allow; if (gendnum >= 0 && gendnum < ROLE_GENDERS) { - if (filter.mask & genders[gendnum].allow) + if (rfilter.mask & genders[gendnum].allow) return FALSE; allow = genders[gendnum].allow; if (rolenum >= 0 && rolenum < SIZE(roles) - 1 @@ -1200,7 +1200,7 @@ int alignnum UNUSED; } else { /* random; check whether any selection is possible */ for (i = 0; i < ROLE_GENDERS; i++) { - if (filter.mask & genders[i].allow) + if (rfilter.mask & genders[i].allow) continue; allow = genders[i].allow; if (rolenum >= 0 && rolenum < SIZE(roles) - 1 @@ -1256,7 +1256,7 @@ int alignnum; short allow; if (alignnum >= 0 && alignnum < ROLE_ALIGNS) { - if (filter.mask & aligns[alignnum].allow) + if (rfilter.mask & aligns[alignnum].allow) return FALSE; allow = aligns[alignnum].allow; if (rolenum >= 0 && rolenum < SIZE(roles) - 1 @@ -1269,7 +1269,7 @@ int alignnum; } else { /* random; check whether any selection is possible */ for (i = 0; i < ROLE_ALIGNS; i++) { - if (filter.mask & aligns[i].allow) + if (rfilter.mask & aligns[i].allow) return FALSE; allow = aligns[i].allow; if (rolenum >= 0 && rolenum < SIZE(roles) - 1 @@ -1356,13 +1356,13 @@ const char *bufp; boolean reslt = TRUE; if ((i = str2role(bufp)) != ROLE_NONE && i != ROLE_RANDOM) - filter.roles[i] = TRUE; + rfilter.roles[i] = TRUE; else if ((i = str2race(bufp)) != ROLE_NONE && i != ROLE_RANDOM) - filter.mask |= races[i].selfmask; + rfilter.mask |= races[i].selfmask; else if ((i = str2gend(bufp)) != ROLE_NONE && i != ROLE_RANDOM) - filter.mask |= genders[i].allow; + rfilter.mask |= genders[i].allow; else if ((i = str2align(bufp)) != ROLE_NONE && i != ROLE_RANDOM) - filter.mask |= aligns[i].allow; + rfilter.mask |= aligns[i].allow; else reslt = FALSE; return reslt; @@ -1373,10 +1373,10 @@ gotrolefilter() { int i; - if (filter.mask) + if (rfilter.mask) return TRUE; for (i = 0; i < SIZE(roles); ++i) - if (filter.roles[i]) + if (rfilter.roles[i]) return TRUE; return FALSE; } @@ -1387,8 +1387,8 @@ clearrolefilter() int i; for (i = 0; i < SIZE(roles); ++i) - filter.roles[i] = FALSE; - filter.mask = 0; + rfilter.roles[i] = FALSE; + rfilter.mask = 0; } #define BP_ALIGN 0 @@ -1836,7 +1836,7 @@ boolean preselect; what = "role"; f = r; for (i = 0; i < SIZE(roles); ++i) - if (i != f && !filter.roles[i]) + if (i != f && !rfilter.roles[i]) break; if (i == SIZE(roles)) { constrainer = "filter"; @@ -1855,7 +1855,7 @@ boolean preselect; constrainer = "role"; forcedvalue = races[c].noun; } else if (f >= 0 - && (allowmask & ~filter.mask) == races[f].selfmask) { + && (allowmask & ~rfilter.mask) == races[f].selfmask) { /* if there is only one race choice available due to user options disallowing others, race menu entry is disabled */ constrainer = "filter"; @@ -1877,7 +1877,7 @@ boolean preselect; constrainer = "role"; forcedvalue = genders[g].adj; } else if (f >= 0 - && (allowmask & ~filter.mask) == genders[f].allow) { + && (allowmask & ~rfilter.mask) == genders[f].allow) { /* if there is only one gender choice available due to user options disallowing other, gender menu entry is disabled */ constrainer = "filter"; @@ -1912,7 +1912,7 @@ boolean preselect; constrainer = "race"; } if (f >= 0 && !constrainer - && (ROLE_ALIGNMASK & ~filter.mask) == aligns[f].allow) { + && (ROLE_ALIGNMASK & ~rfilter.mask) == aligns[f].allow) { /* if there is only one alignment choice available due to user options disallowing others, algn menu entry is disabled */ constrainer = "filter"; diff --git a/src/steal.c b/src/steal.c index 4b5378d96..b3e5cb1f5 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steal.c $NHDT-Date: 1446713643 2015/11/05 08:54:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.65 $ */ +/* NetHack 3.6 steal.c $NHDT-Date: 1456618998 2016/02/28 00:23:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.67 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -506,50 +506,82 @@ register struct obj *otmp; return freed_otmp; } +/* called for AD_SAMU (the Wizard and quest nemeses) */ void stealamulet(mtmp) struct monst *mtmp; { - struct obj *otmp = (struct obj *) 0; - int real = 0, fake = 0; + char buf[BUFSZ]; + struct obj *otmp = 0, *obj = 0; + int real = 0, fake = 0, n; - /* select the artifact to steal */ - if (u.uhave.amulet) { - real = AMULET_OF_YENDOR; - fake = FAKE_AMULET_OF_YENDOR; - } else if (u.uhave.questart) { + /* target every quest artifact, not just current role's; + if hero has more than one, choose randomly so that player + can't use inventory ordering to influence the theft */ + for (n = 0, obj = invent; obj; obj = obj->nobj) + if (any_quest_artifact(obj)) + ++n, otmp = obj; + if (n > 1) { + n = rnd(n); for (otmp = invent; otmp; otmp = otmp->nobj) - if (is_quest_artifact(otmp)) - break; - if (!otmp) - return; /* should we panic instead? */ - } else if (u.uhave.bell) { - real = BELL_OF_OPENING; - fake = BELL; - } else if (u.uhave.book) { - real = SPE_BOOK_OF_THE_DEAD; - } else if (u.uhave.menorah) { - real = CANDELABRUM_OF_INVOCATION; - } else - return; /* you have nothing of special interest */ - - if (!otmp) { - /* If we get here, real and fake have been set up. */ - for (otmp = invent; otmp; otmp = otmp->nobj) - if (otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz)) + if (any_quest_artifact(otmp) && !--n) break; } + if (!otmp) { + /* if we didn't find any quest arifact, find another valuable item */ + if (u.uhave.amulet) { + real = AMULET_OF_YENDOR; + fake = FAKE_AMULET_OF_YENDOR; + } else if (u.uhave.bell) { + real = BELL_OF_OPENING; + fake = BELL; + } else if (u.uhave.book) { + real = SPE_BOOK_OF_THE_DEAD; + } else if (u.uhave.menorah) { + real = CANDELABRUM_OF_INVOCATION; + } else + return; /* you have nothing of special interest */ + + /* If we get here, real and fake have been set up. */ + for (n = 0, obj = invent; obj; obj = obj->nobj) + if (obj->otyp == real || (obj->otyp == fake && !mtmp->iswiz)) + ++n, otmp = obj; + if (n > 1) { + n = rnd(n); + for (otmp = invent; otmp; otmp = otmp->nobj) + if ((otmp->otyp == real + || (otmp->otyp == fake && !mtmp->iswiz)) && !--n) + break; + } + } + if (otmp) { /* we have something to snatch */ + /* take off outer gear if we're targetting [hypothetical] + quest artifact suit, shirt, gloves, or rings */ + if ((otmp == uarm || otmp == uarmu) && uarmc) + (void) Cloak_off(); + if (otmp == uarmu && uarm) + (void) Armor_off(); + if ((otmp == uarmg || ((otmp == uright || otmp == uleft) && uarmg)) + && uwep) { + /* gloves are about to be unworn; unwield weapon(s) first */ + if (u.twoweap) + uswapwepgone(); /* will clear u.twoweap */ + uwepgone(); + } + if ((otmp == uright || otmp == uleft) && uarmg) + (void) Gloves_off(); /* handles wielded cockatrice corpse */ + + /* finally, steal the target item */ if (otmp->owornmask) remove_worn_item(otmp, TRUE); if (otmp->unpaid) subfrombill(otmp, shop_keeper(*u.ushops)); freeinv(otmp); - /* mpickobj wont merge otmp because none of the above things - to steal are mergable */ - (void) mpickobj(mtmp, otmp); /* may merge and free otmp */ - pline("%s stole %s!", Monnam(mtmp), doname(otmp)); + Strcpy(buf, doname(otmp)); + (void) mpickobj(mtmp, otmp); /* could merge and free otmp but won't */ + pline("%s steals %s!", Monnam(mtmp), buf); if (can_teleport(mtmp->data) && !tele_restrict(mtmp)) (void) rloc(mtmp, TRUE); } @@ -643,7 +675,7 @@ boolean verbosely; /* some monsters bypass the normal rules for moving between levels or even leaving the game entirely; when that happens, prevent them from - taking the Amulet or invocation tools with them */ + taking the Amulet, invocation items, or quest artifact with them */ void mdrop_special_objs(mon) struct monst *mon; @@ -653,8 +685,10 @@ struct monst *mon; for (obj = mon->minvent; obj; obj = otmp) { otmp = obj->nobj; /* the Amulet, invocation tools, and Rider corpses resist even when - artifacts and ordinary objects are given 0% resistance chance */ - if (obj_resists(obj, 0, 0)) { + artifacts and ordinary objects are given 0% resistance chance; + current role's quest artifact is rescued too--quest artifacts + for the other roles are not */ + if (obj_resists(obj, 0, 0) || is_quest_artifact(obj)) { obj_extract_self(obj); mdrop_obj(mon, obj, FALSE); } diff --git a/src/timeout.c b/src/timeout.c index 7370b8b05..cb93622d7 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.c $NHDT-Date: 1452660198 2016/01/13 04:43:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 3.6 timeout.c $NHDT-Date: 1456526165 2016/02/26 22:36:05 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -614,14 +614,17 @@ long timeout; case OBJ_MINVENT: if (cansee_hatchspot) { /* egg carrying monster might be invisible */ - if (canseemon(egg->ocarry)) { + mon2 = egg->ocarry; + if (canseemon(mon2) + && (!mon2->wormno || cansee(mon2->mx, mon2->my))) { Sprintf(carriedby, "%s pack", - s_suffix(a_monnam(egg->ocarry))); + s_suffix(a_monnam(mon2))); knows_egg = TRUE; - } else if (is_pool(mon->mx, mon->my)) + } else if (is_pool(mon->mx, mon->my)) { Strcpy(carriedby, "empty water"); - else + } else { Strcpy(carriedby, "thin air"); + } You_see("%s %s out of %s!", monnambuf, locomotion(mon->data, "drop"), carriedby); } diff --git a/src/u_init.c b/src/u_init.c index 50e90d9d7..34e3b4cc1 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -701,31 +701,25 @@ u_init() ini_inv(Knight); knows_class(WEAPON_CLASS); knows_class(ARMOR_CLASS); - /* give knights chess-like mobility - * -- idea from wooledge@skybridge.scl.cwru.edu */ + /* give knights chess-like mobility--idea from wooledge@..cwru.edu */ HJumping |= FROMOUTSIDE; skill_init(Skill_K); break; - case PM_MONK: - switch (rn2(90) / 30) { - case 0: - Monk[M_BOOK].trotyp = SPE_HEALING; - break; - case 1: - Monk[M_BOOK].trotyp = SPE_PROTECTION; - break; - case 2: - Monk[M_BOOK].trotyp = SPE_SLEEP; - break; - } + case PM_MONK: { + static short M_spell[] = { SPE_HEALING, SPE_PROTECTION, SPE_SLEEP }; + + Monk[M_BOOK].trotyp = M_spell[rn2(90) / 30]; /* [0..2] */ ini_inv(Monk); if (!rn2(5)) ini_inv(Magicmarker); else if (!rn2(10)) ini_inv(Lamp); knows_class(ARMOR_CLASS); + /* sufficiently martial-arts oriented item to ignore language issue */ + knows_object(SHURIKEN); skill_init(Skill_Mon); break; + } case PM_PRIEST: ini_inv(Priest); if (!rn2(10)) diff --git a/src/uhitm.c b/src/uhitm.c index a35802029..1b3bb84ea 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1454664302 2016/02/05 09:25:02 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.154 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1456992470 2016/03/03 08:07:50 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.155 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2085,7 +2085,7 @@ register struct monst *mon; for (i = 0; i < NATTK; i++) { sum[i] = 0; - mattk = getmattk(youmonst.data, i, sum, &alt_attk); + mattk = getmattk(&youmonst, mon, i, sum, &alt_attk); switch (mattk->aatyp) { case AT_WEAP: use_weapon: diff --git a/src/wizard.c b/src/wizard.c index bb394349f..6ab8e57bd 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wizard.c $NHDT-Date: 1446078768 2015/10/29 00:32:48 $ $NHDT-Branch: master $:$NHDT-Revision: 1.42 $ */ +/* NetHack 3.6 wizard.c $NHDT-Date: 1456618999 2016/02/28 00:23:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -20,21 +20,37 @@ STATIC_DCL boolean FDECL(you_have, (int)); STATIC_DCL unsigned long FDECL(target_on, (int, struct monst *)); STATIC_DCL unsigned long FDECL(strategy, (struct monst *)); +/* adding more neutral creatures will tend to reduce the number of monsters + summoned by nasty(); adding more lawful creatures will reduce the number + of monsters summoned by lawfuls; adding more chaotic creatures will reduce + the number of monsters summoned by chaotics; prior to 3.6.1, there were + only four lawful candidates, so lawful summoners tended to summon more + (trying to get lawful or neutral but obtaining chaotic instead) than + their chaotic counterparts */ static NEARDATA const int nasties[] = { - PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, PM_RED_DRAGON, - PM_BLACK_DRAGON, PM_GREEN_DRAGON, PM_OWLBEAR, PM_PURPLE_WORM, - PM_ROCK_TROLL, PM_XAN, PM_GREMLIN, PM_UMBER_HULK, PM_VAMPIRE_LORD, - PM_XORN, PM_ZRUTY, PM_ELF_LORD, PM_ELVENKING, PM_YELLOW_DRAGON, - PM_LEOCROTTA, PM_BALUCHITHERIUM, PM_CARNIVOROUS_APE, PM_FIRE_GIANT, - PM_COUATL, PM_CAPTAIN, PM_WINGED_GARGOYLE, PM_MASTER_MIND_FLAYER, - PM_FIRE_ELEMENTAL, PM_JABBERWOCK, PM_ARCH_LICH, PM_OGRE_KING, PM_OLOG_HAI, - PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME, PM_DISENCHANTER + /* neutral */ + PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, + PM_OWLBEAR, PM_PURPLE_WORM, PM_XAN, PM_UMBER_HULK, + PM_XORN, PM_ZRUTY, PM_LEOCROTTA, PM_BALUCHITHERIUM, + PM_CARNIVOROUS_APE, PM_FIRE_ELEMENTAL, PM_JABBERWOCK, + PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME, + /* chaotic */ + PM_BLACK_DRAGON, PM_RED_DRAGON, PM_ARCH_LICH, PM_VAMPIRE_LORD, + PM_MASTER_MIND_FLAYER, PM_DISENCHANTER, PM_WINGED_GARGOYLE, + PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_LORD, PM_ELVENKING, + PM_OGRE_KING, PM_CAPTAIN, PM_GREMLIN, + /* lawful */ + PM_SILVER_DRAGON, PM_ORANGE_DRAGON, PM_GREEN_DRAGON, + PM_YELLOW_DRAGON, PM_GUARDIAN_NAGA, PM_FIRE_GIANT, + PM_ALEAX, PM_COUATL, PM_HORNED_DEVIL, PM_BARBED_DEVIL, + /* (titans, ki-rin, and golden nagas are suitably nasty, but + they're summoners so would aggravate excessive summoning) */ }; static NEARDATA const unsigned wizapp[] = { PM_HUMAN, PM_WATER_DEMON, PM_VAMPIRE, PM_RED_DRAGON, PM_TROLL, PM_UMBER_HULK, PM_XORN, PM_XAN, - PM_COCKATRICE, PM_FLOATING_EYE, PM_GUARDIAN_NAGA, PM_TRAPPER + PM_COCKATRICE, PM_FLOATING_EYE, PM_GUARDIAN_NAGA, PM_TRAPPER, }; /* If you've found the Amulet, make the Wizard appear after some time */ @@ -103,7 +119,8 @@ register struct monst *mtmp; register struct obj *otmp; for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) - if (otmp->otyp == AMULET_OF_YENDOR || is_quest_artifact(otmp) + if (otmp->otyp == AMULET_OF_YENDOR + || any_quest_artifact(otmp) || otmp->otyp == BELL_OF_OPENING || otmp->otyp == CANDELABRUM_OF_INVOCATION || otmp->otyp == SPE_BOOK_OF_THE_DEAD) @@ -159,7 +176,7 @@ register short otyp; if (otyp) { if (otmp->otyp == otyp) return 1; - } else if (is_quest_artifact(otmp)) + } else if (any_quest_artifact(otmp)) return 1; } return 0; @@ -191,7 +208,7 @@ register short otyp; if (otyp) { if (otmp->otyp == otyp) return otmp; - } else if (is_quest_artifact(otmp)) + } else if (any_quest_artifact(otmp)) return otmp; return (struct obj *) 0; } @@ -505,57 +522,88 @@ pick_nasty() return res; } -/* create some nasty monsters, aligned or neutral with the caster */ -/* a null caster defaults to a chaotic caster (e.g. the wizard) */ +/* create some nasty monsters, aligned with the caster or neutral; chaotic + and unaligned are treated as equivalent; if summoner is Null, this is + for late-game harassment (after the Wizard has been killed at least once + or the invocation ritual has been performed), in which case we treat + 'summoner' as neutral, since that will produce the greatest number of + creatures on average (in 3.6.0 and earlier, Null was treated as chaotic); + returns the number of monsters created */ int -nasty(mcast) -struct monst *mcast; +nasty(summoner) +struct monst *summoner; { register struct monst *mtmp; - register int i, j, tmp; - int castalign = (mcast ? sgn(mcast->data->maligntyp) : -1); + register int i, j; + int castalign = (summoner ? sgn(summoner->data->maligntyp) : 0); coord bypos; - int count, census; + int count, census, tmp, makeindex, s_cls, m_cls; + +#define MAXNASTIES 10 /* more than this can be created */ /* some candidates may be created in groups, so simple count of non-null makemon() return is inadequate */ census = monster_census(FALSE); if (!rn2(10) && Inhell) { + /* this might summon a demon prince or lord */ count = msummon((struct monst *) 0); /* summons like WoY */ } else { count = 0; - tmp = (u.ulevel > 3) ? u.ulevel / 3 : 1; /* just in case -- rph */ - /* if we don't have a casting monster, the nasties appear around you - */ + s_cls = summoner ? summoner->data->mlet : 0; + tmp = (u.ulevel > 3) ? u.ulevel / 3 : 1; + /* if we don't have a casting monster, nasties appear around hero, + otherwise they'll appear around spot summoner thinks she's at */ bypos.x = u.ux; bypos.y = u.uy; - for (i = rnd(tmp); i > 0; --i) + for (i = rnd(tmp); i > 0 && count < MAXNASTIES; --i) + /* Of the 42 nasties[], 10 are lawful, 14 are chaotic, + * and 18 are neutral. + * + * Neutral caster, used for late-game harrassment, + * has 18/42 chance to stop the inner loop on each + * critter, 24/42 chance for another iteration. + * Lawful caster has 28/42 chance to stop unless the + * summoner is an angel or demon, in which case the + * chance is 26/42. + * Chaotic or unaligned caster has 32/42 chance to + * stop, so will summon fewer creatures on average. + * + * The outer loop potentially gives chaotic/unaligned + * a chance to even things up since others will hit + * MAXNASTIES sooner, but its number of iterations is + * randomized so it won't always do so. + */ for (j = 0; j < 20; j++) { - int makeindex; - /* Don't create more spellcasters of the monsters' level or * higher--avoids chain summoners filling up the level. */ do { makeindex = pick_nasty(); - } while (mcast && attacktype(&mons[makeindex], AT_MAGC) - && monstr[makeindex] >= monstr[mcast->mnum]); + m_cls = mons[makeindex].mlet; + } while (summoner + && ((attacktype(&mons[makeindex], AT_MAGC) + && monstr[makeindex] >= monstr[summoner->mnum]) + || (s_cls == S_DEMON && m_cls == S_ANGEL) + || (s_cls == S_ANGEL && m_cls == S_DEMON))); /* do this after picking the monster to place */ - if (mcast - && !enexto(&bypos, mcast->mux, mcast->muy, - &mons[makeindex])) + if (summoner && !enexto(&bypos, summoner->mux, summoner->muy, + &mons[makeindex])) continue; + /* this honors genocide but overrides extinction; it ignores + inside-hell-only (G_HELL) & outside-hell-only (G_NOHELL) */ if ((mtmp = makemon(&mons[makeindex], bypos.x, bypos.y, NO_MM_FLAGS)) != 0) { mtmp->msleeping = mtmp->mpeaceful = mtmp->mtame = 0; set_malign(mtmp); - } else /* GENOD? */ + } else /* random monster to substitute for geno'd selection */ mtmp = makemon((struct permonst *) 0, bypos.x, bypos.y, NO_MM_FLAGS); if (mtmp) { - count++; - if (mtmp->data->maligntyp == 0 + /* delay first use of spell or breath attack */ + mtmp->mspec_used = rnd(4); + if (++count >= MAXNASTIES + || mtmp->data->maligntyp == 0 || sgn(mtmp->data->maligntyp) == castalign) break; } @@ -703,11 +751,12 @@ register struct monst *mtmp; verbalize("%s %s!", random_malediction[rn2(SIZE(random_malediction))], random_insult[rn2(SIZE(random_insult))]); - } else if (is_lminion(mtmp)) { + } else if (is_lminion(mtmp) + && !(mtmp->isminion && EMIN(mtmp)->renegade)) { com_pager(rn2(QTN_ANGELIC - 1 + (Hallucination ? 1 : 0)) + QT_ANGELIC); } else { - if (!rn2(5)) + if (!rn2(is_minion(mtmp->data) ? 100 : 5)) pline("%s casts aspersions on your ancestry.", Monnam(mtmp)); else com_pager(rn2(QTN_DEMONIC) + QT_DEMONIC); diff --git a/src/worm.c b/src/worm.c index 5d41c59f4..839b0193e 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 worm.c $NHDT-Date: 1446887540 2015/11/07 09:12:20 $ $NHDT-Branch: master $:$NHDT-Revision: 1.19 $ */ +/* NetHack 3.6 worm.c $NHDT-Date: 1456528599 2016/02/26 23:16:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -89,11 +89,9 @@ get_wormno() while (new_wormno < MAX_NUM_WORMS) { if (!wheads[new_wormno]) - return new_wormno; /* found an empty wtails[] slot at new_wormno - */ + return new_wormno; /* found empty wtails[] slot at new_wormno */ new_wormno++; } - return 0; /* level infested with worms */ } @@ -296,11 +294,9 @@ register struct monst *worm; /* if (!wnum) return; bullet proofing */ /* This does not work right now because mattacku() thinks that the head - * is - * out of range of the player. We might try to kludge, and bring the - * head - * within range for a tiny moment, but this needs a bit more looking at - * before we decide to do this. + * is out of range of the player. We might try to kludge, and bring + * the head within range for a tiny moment, but this needs a bit more + * looking at before we decide to do this. */ for (seg = wtails[wnum]; seg; seg = seg->nseg) if (distu(seg->wx, seg->wy) < 3) @@ -373,7 +369,6 @@ struct obj *weap; * it's head at "curr" and its tail at "new_tail". The old worm * must be at least level 3 in order to produce a new worm. */ - new_worm = 0; new_wnum = (worm->m_lev >= 3 && !rn2(3)) ? get_wormno() : 0; if (new_wnum) { @@ -683,22 +678,19 @@ register xchar *nx, *ny; } /* count_wsegs() - * returns the number of visible segments that a worm has. + * returns the number of segments that a worm has. */ int count_wsegs(mtmp) struct monst *mtmp; { register int i = 0; - register struct wseg *curr = (wtails[mtmp->wormno])->nseg; + register struct wseg *curr; - /* if (!mtmp->wormno) return 0; bullet proofing */ - - while (curr) { - i++; - curr = curr->nseg; + if (mtmp->wormno) { + for (curr = wtails[mtmp->wormno]->nseg; curr; curr = curr->nseg) + i++; } - return i; } @@ -802,4 +794,29 @@ int x1, y1, x2, y2; return FALSE; } +/* construct an index number for a worm tail segment */ +int +wseg_at(worm, x, y) +struct monst *worm; +int x, y; +{ + int res = 0; + + if (worm && worm->wormno && m_at(x, y) == worm) { + struct wseg *curr; + int i, n; + xchar wx = (xchar) x, wy = (xchar) y; + + for (i = 0, curr = wtails[worm->wormno]; curr; curr = curr->nseg) { + if (curr->wx == wx && curr->wy == wy) + break; + ++i; + } + for (n = i; curr; curr = curr->nseg) + ++n; + res = n - i; + } + return res; +} + /*worm.c*/ diff --git a/src/zap.c b/src/zap.c index 38d797e5a..d8784d12b 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1449669396 2015/12/09 13:56:36 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.238 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1456528600 2016/02/26 23:16:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.247 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -55,21 +55,21 @@ STATIC_DCL int FDECL(spell_hit_bonus, (int)); STATIC_VAR const char are_blinded_by_the_flash[] = "are blinded by the flash!"; -const char *const flash_types[] = - { /* also used in buzzmu(mcastu.c) */ - "magic missile", /* Wands must be 0-9 */ - "bolt of fire", "bolt of cold", "sleep ray", "death ray", - "bolt of lightning", "", "", "", "", +const char *const flash_types[] = /* also used in buzzmu(mcastu.c) */ + { + "magic missile", /* Wands must be 0-9 */ + "bolt of fire", "bolt of cold", "sleep ray", "death ray", + "bolt of lightning", "", "", "", "", - "magic missile", /* Spell equivalents must be 10-19 */ - "fireball", "cone of cold", "sleep ray", "finger of death", - "bolt of lightning", /* There is no spell, used for retribution */ - "", "", "", "", + "magic missile", /* Spell equivalents must be 10-19 */ + "fireball", "cone of cold", "sleep ray", "finger of death", + "bolt of lightning", /* there is no spell, used for retribution */ + "", "", "", "", - "blast of missiles", /* Dragon breath equivalents 20-29*/ - "blast of fire", "blast of frost", "blast of sleep gas", - "blast of disintegration", "blast of lightning", "blast of poison gas", - "blast of acid", "", "" + "blast of missiles", /* Dragon breath equivalents 20-29*/ + "blast of fire", "blast of frost", "blast of sleep gas", + "blast of disintegration", "blast of lightning", + "blast of poison gas", "blast of acid", "", "" }; /* @@ -140,12 +140,13 @@ struct obj *otmp; int dmg, otyp = otmp->otyp; const char *zap_type_text = "spell"; struct obj *obj; - boolean disguised_mimic = - (mtmp->data->mlet == S_MIMIC && mtmp->m_ap_type != M_AP_NOTHING); + boolean disguised_mimic = (mtmp->data->mlet == S_MIMIC + && mtmp->m_ap_type != M_AP_NOTHING); if (u.uswallow && mtmp == u.ustuck) reveal_invis = FALSE; + notonhead = (mtmp->mx != bhitpos.x || mtmp->my != bhitpos.y); switch (otyp) { case WAN_STRIKING: zap_type_text = "wand"; @@ -2523,6 +2524,8 @@ struct obj *obj; /* wand or spell */ { int steedhit = FALSE; + bhitpos.x = u.usteed->mx, bhitpos.y = u.usteed->my; + notonhead = FALSE; switch (obj->otyp) { /* * Wands that are allowed to hit the steed @@ -3915,6 +3918,7 @@ register int dx, dy; if (type >= 0) mon->mstrategy &= ~STRAT_WAITMASK; buzzmonst: + notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y); if (zap_hit(find_mac(mon), spell_type)) { if (mon_reflects(mon, (char *) 0)) { if (cansee(mon->mx, mon->my)) { diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 7258fd47a..68265b6c2 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.GCC $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.28 $ +# NetHack 3.6 Makefile.GCC $NHDT-Date: 1457207036 2016/03/05 19:43:56 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.29 $ # Copyright (c) NetHack PC Development Team 1996-2006. # PC NetHack 3.6 Makefile for djgpp V2 # @@ -66,7 +66,7 @@ LIBRARIES = $(LIBS) $(TERMLIB) # # If you have yacc/lex or a work-alike set YACC_LEX to Y # -YACC_LEX = Y +YACC_LEX = N ifeq ($(YACC_LEX),Y) DO_YACC = YACC_ACT DO_LEX = LEX_ACT @@ -161,8 +161,8 @@ LFLAGS = else # Debugging -#cflags = -pg -c -I../include $(DLBFLG) -DUSE_TILES -#LFLAGS = -pg +#cflags = -g -c -I../include $(DLBFLG) -DUSE_TILES +#LFLAGS = -g # Normal cflags = -c -O -I../include $(DLBFLG) -DUSE_TILES @@ -173,7 +173,7 @@ endif #================ RULES ================== #========================================== -.SUFFIXES: .exe .o .tib .til .uu .c .y .l +.SUFFIXES: .exe .o .til .uu .c .y .l #========================================== # Rules for files in src @@ -241,7 +241,7 @@ U = $(UTIL)/ # Utility Objects. #========================================== -VGAOBJ = $(O)vidvga.o +VGAOBJ = $(O)vidvga.o $(O)vidvesa.o MAKESRC = makedefs.c @@ -267,10 +267,10 @@ RECOVOBJS = $(O)recover.o ifeq ($(SUPPRESS_GRAPHICS),Y) TILOBJ = +TILOBJ2 = TEXTIO = TEXTIO2 = -PLANAR_TIB = -OVERVIEW_TIB = +TILE_BMP = TILEUTIL = TILEFILES = TILEFILES2 = @@ -281,7 +281,9 @@ PPMWRIT2 = else -TILOBJ = $(O)tile.o $(O)pctiles.o $(VGAOBJ) +TILOBJ = $(O)tile.o $(VGAOBJ) + +TILOBJ2 = $(O)tileset.o $(O)bmptiles.o $(O)giftiles.o TEXTIO = $(O)tiletext.o $(O)tiletxt.o $(O)drawing.o $(O)decl.o $(O)monst.o \ $(O)objects.o $(O)stubvid.o @@ -289,11 +291,9 @@ TEXTIO = $(O)tiletext.o $(O)tiletxt.o $(O)drawing.o $(O)decl.o $(O)monst.o TEXTIO2 = $(O)tiletex2.o $(O)tiletxt2.o $(O)drawing.o $(O)decl.o $(O)monst.o \ $(O)objects.o $(O)stubvid.o -PLANAR_TIB = $(DAT)/NetHack1.tib +TILE_BMP = $(DAT)/nhtiles.bmp -OVERVIEW_TIB = $(DAT)/NetHacko.tib - -TILEUTIL = $(TILOBJ) $(U)tile2bin.exe $(U)til2bin2.exe $(PLANAR_TIB) $(OVERVIEW_TIB) +TILEUTIL = $(TILOBJ) $(U)tile2bin.exe $(U)til2bin2.exe $(TILE_BMP) TILEFILES = $(WSHR)/monsters.txt $(WSHR)/objects.txt $(WSHR)/other.txt @@ -336,7 +336,7 @@ VOBJ19 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)vision.o VOBJ20 = $(O)vis_tab.o $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o VOBJ21 = $(O)wintty.o $(O)wizard.o $(O)worm.o $(O)worn.o $(O)write.o VOBJ22 = $(O)zap.o $(O)light.o $(O)dlb.o $(O)dig.o $(O)teleport.o -VOBJ23 = $(O)region.o $(O)sys.o +VOBJ23 = $(O)region.o $(O)sys.o $(O)pmatchre.o $(O)string.o $(O)unicode.o SOBJ = $(O)msdos.o $(O)sound.o $(O)pcsys.o $(O)tty.o $(O)unix.o \ $(O)video.o $(O)vidtxt.o $(O)pckeys.o @@ -349,7 +349,7 @@ VOBJ = $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \ $(VOBJ16) $(VOBJ17) $(VOBJ18) $(VOBJ19) $(VOBJ20) \ $(VOBJ21) $(VOBJ22) $(VOBJ23) -ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(VVOBJ) +ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(TILOBJ2) $(VVOBJ) #========================================== # Header file macros @@ -391,7 +391,7 @@ DLB_H = $(INCL)/dlb.h ifeq ($(SUPPRESS_GRAPHICS),Y) TILE_H = else -TILE_H = $(WSHR)/tile.h $(MSYS)/pctiles.h +TILE_H = $(WSHR)/tile.h $(INCL)/tileset.h endif ifeq ($(USE_DLB),Y) @@ -448,11 +448,12 @@ endif ifdef TERMLIB @$(subst /,\,copy $(SSHR)/termcap $(GAMEDIR)) endif - @$(subst /,\,if exist $(DAT)/*.tib copy $(DAT)/*.tib $(GAMEDIR)) + @$(subst /,\,if exist $(TILE_BMP) copy $(TILE_BMP) $(GAMEDIR)) @$(subst /,\,if exist $(DAT)/symbols copy $(DAT)/symbols $(GAMEDIR)) @$(subst /,\,copy $(SSHR)/NetHack.cnf $(GAMEDIR)/defaults.nh) - @$(subst /,\,copy $(MSYS)/NHAccess.nh $(GAMEDIR)) + -@$(subst /,\,touch $(GAMEDIR)/record) @$(subst /,\,copy $(DOC)/guidebo*.txt $(GAMEDIR)) + @$(subst /,\,copy ../sys/winnt/sysconf $(GAMEDIR)) @$(subst /,\,if exist $(DOC)/nethack.txt copy $(DOC)/nethack.txt $(GAMEDIR)) ifdef CWSDPMI @$(subst /,\,if exist $(CWSDPMI) copy $(CWSDPMI) $(GAMEDIR)) @@ -466,7 +467,35 @@ endif #========================================== $(GAMEFILE): $(O)obj.tag $(PATCHLEV_H) $(O)utility.tag $(ALLOBJ) $(O)$(GAME).lnk - $(LINK) $(LFLAGS) -o$(GAME).exe @$(O)$(GAME).lnk $(LIBRARIES) $(ZLIB) + @if exist temp.a del temp.a + @ar ru temp.a $(VOBJ01) + @ar ru temp.a $(VOBJ02) + @ar ru temp.a $(VOBJ03) + @ar ru temp.a $(VOBJ04) + @ar ru temp.a $(VOBJ05) + @ar ru temp.a $(VOBJ06) + @ar ru temp.a $(VOBJ07) + @ar ru temp.a $(VOBJ08) + @ar ru temp.a $(VOBJ09) + @ar ru temp.a $(VOBJ10) + @ar ru temp.a $(VOBJ11) + @ar ru temp.a $(VOBJ12) + @ar ru temp.a $(VOBJ13) + @ar ru temp.a $(VOBJ14) + @ar ru temp.a $(VOBJ15) + @ar ru temp.a $(VOBJ16) + @ar ru temp.a $(VOBJ17) + @ar ru temp.a $(VOBJ18) + @ar ru temp.a $(VOBJ19) + @ar ru temp.a $(VOBJ20) + @ar ru temp.a $(VOBJ21) + @ar ru temp.a $(VOBJ22) + @ar ru temp.a $(VOBJ23) + @ar ru temp.a $(SOBJ) + @ar ru temp.a $(TILOBJ) + @ar ru temp.a $(TILOBJ2) + @ar ru temp.a $(VVOBJ) + $(LINK) $(LFLAGS) -o$(GAME).exe temp.a $(LIBRARIES) $(ZLIB) @$(subst /,\,stubedit $(GAME).exe minstack=2048K) @$(subst /,\,copy $(GAME).exe $(GAMEFILE)) @$(subst /,\,del $(GAME).exe) @@ -497,6 +526,7 @@ $(O)$(GAME).lnk: $(ALLOBJ) echo $(VOBJ23) >> $(subst /,\,$@) echo $(SOBJ) >> $(subst /,\,$@) echo $(TILOBJ) >> $(subst /,\,$@) + echo $(TILOBJ2) >> $(subst /,\,$@) echo $(VVOBJ) >> $(subst /,\,$@) @@ -513,6 +543,7 @@ clean: $(subst /,\,if exist $(O)sp_lev.tag del $(O)sp_lev.tag) $(subst /,\,if exist $(O)thintile.tag del $(O)thintile.tag) $(subst /,\,if exist $(O)utility.tag del $(O)utility.tag) + $(subst /,\,if exist temp.a del temp.a) spotless: clean @@ -527,6 +558,7 @@ spotless: clean $(subst /,\,if exist $(U)dgn_comp.exe del $(U)dgn_comp.exe) $(subst /,\,if exist $(U)recover.exe del $(U)recover.exe) $(subst /,\,if exist $(U)tilemap.exe del $(U)tilemap.exe) + $(subst /,\,if exist $(U)tile2bmp.exe del $(U)tile2bmp.exe) $(subst /,\,if exist $(U)tile2bin.exe del $(U)tile2bin.exe) $(subst /,\,if exist $(U)til2bin2.exe del $(U)til2bin2.exe) $(subst /,\,if exist $(U)thintile.exe del $(U)thintile.exe) @@ -547,11 +579,13 @@ spotless: clean $(subst /,\,if exist $(DAT)/dungeon del $(DAT)/dungeon) $(subst /,\,if exist $(DAT)/oracles del $(DAT)/oracles) $(subst /,\,if exist $(DAT)/quest.dat del $(DAT)/quest.dat) + $(subst /,\,if exist $(DAT)/bogusmon del $(DAT)/bogusmon) + $(subst /,\,if exist $(DAT)/engrave del $(DAT)/engrave) + $(subst /,\,if exist $(DAT)/epitaph del $(DAT)/epitaph) $(subst /,\,if exist $(DAT)/dlb.lst del $(DAT)/dlb.lst) $(subst /,\,if exist $(DAT)/nhdat del $(DAT)/nhdat) $(subst /,\,if exist $(DAT)/*.lev del $(DAT)/*.lev) - $(subst /,\,if exist $(PLANAR_TIB) del $(PLANAR_TIB)) - $(subst /,\,if exist $(OVERVIEW_TIB) del $(OVERVIEW_TIB)) + $(subst /,\,if exist $(TILE_BMP) del $(TILE_BMP)) $(subst /,\,if exist $(WSHR)/monthin.txt del $(WSHR)/monthin.txt) $(subst /,\,if exist $(WSHR)/objthin.txt del $(WSHR)/objthin.txt) $(subst /,\,if exist $(WSHR)/oththin.txt del $(WSHR)/oththin.txt) @@ -614,7 +648,9 @@ $(O)makedefs.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/objclass.h \ #========================================== $(U)lev_comp.exe: $(SPLEVOBJS) - $(LINK) $(LFLAGS) -o$@ $(SPLEVOBJS) + @rm -f temp.a + @ar ru temp.a $(SPLEVOBJS) + $(LINK) $(LFLAGS) -o$@ temp.a ifeq ($(YACC_LEX),Y) @@ -770,23 +806,26 @@ $(O)tilemap.o: $(WSHR)/tilemap.c $(HACK_H) $(TILE_H) # Required for tile support #========================================== -$(DAT)/NetHack1.tib: $(TILEFILES) $(U)tile2bin.exe +$(DAT)/nhtiles.bmp: $(TILEFILES) $(U)tile2bmp.exe @echo Creating binary tile files (this may take some time) @$(subst /,\,chdir $(DAT)) - @$(subst /,\,$(U)tile2bin.exe) + @$(subst /,\,$(U)tile2bmp.exe $@) @$(subst /,\,chdir $(SRC)) -$(DAT)/NetHacko.tib: $(O)thintile.tag $(TILEFILES2) $(U)til2bin2.exe - @echo Creating overview binary tile files (this may take some time) - @$(subst /,\,chdir $(DAT)) - @$(subst /,\,$(U)til2bin2.exe) - @$(subst /,\,chdir $(SRC)) +$(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXTIO) + @rm -f temp.a + @ar ru temp.a $(TEXTIO) + $(LINK) $(LFLAGS) -o$@ $(O)tile2bmp.o temp.a $(U)tile2bin.exe: $(O)tile2bin.o $(TEXTIO) - $(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o $(TEXTIO) + @rm -f temp.a + @ar ru temp.a $(TEXTIO) + $(LINK) $(LFLAGS) -o$@ $(O)tile2bin.o temp.a $(U)til2bin2.exe: $(O)til2bin2.o $(TEXTIO2) - $(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o $(TEXTIO2) + @rm -f temp.a + @ar ru temp.a $(TEXTIO2) + $(LINK) $(LFLAGS) -o$@ $(O)til2bin2.o temp.a $(U)thintile.exe: $(O)thintile.o $(LINK) $(LFLAGS) -o$@ $(O)thintile.o @@ -798,6 +837,9 @@ $(O)thintile.tag: $(U)thintile.exe $(TILEFILES) @$(subst /,\,$(U)thintile.exe) @$(subst /,\,echo thintiles created >$@) +$(O)tile2bmp.o: $(HACK_H) $(TILE_H) $(WSHR)/tile2bmp.c + $(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(WSHR)/tile2bmp.c + $(O)tile2bin.o: $(HACK_H) $(TILE_H) $(MSYS)/pctiles.h $(MSYS)/pcvideo.h $(MSYS)/tile2bin.c $(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/tile2bin.c @@ -900,6 +942,15 @@ $(DAT)/quest.dat: $(O)utility.tag $(DAT)/quest.txt $(DAT)/oracles: $(O)utility.tag $(DAT)/oracles.txt @$(subst /,\,$(U)makedefs.exe -h) +$(DAT)/bogusmon: $(O)utility.tag $(DAT)/bogusmon.txt + @$(subst /,\,$(U)makedefs.exe -s) + +$(DAT)/engrave: $(O)utility.tag $(DAT)/engrave.txt + @$(subst /,\,$(U)makedefs.exe -s) + +$(DAT)/epitaph: $(O)utility.tag $(DAT)/epitaph.txt + @$(subst /,\,$(U)makedefs.exe -s) + $(O)sp_lev.tag: $(O)utility.tag $(DAT)/bigroom.des $(DAT)/castle.des \ $(DAT)/endgame.des $(DAT)/gehennom.des $(DAT)/knox.des \ $(DAT)/medusa.des $(DAT)/oracle.des $(DAT)/tower.des \ @@ -949,24 +1000,14 @@ $(DAT)/dungeon: $(O)utility.tag $(DAT)/dungeon.def #note that dir below assumes bin/dir.exe from djgpp distribution # $(DAT)/nhdat: $(U)dlb_main.exe $(DAT)/data $(DAT)/rumors $(DAT)/dungeon \ - $(DAT)/oracles $(DAT)/quest.dat $(O)sp_lev.tag + $(DAT)/oracles $(DAT)/quest.dat $(O)sp_lev.tag \ + $(DAT)/bogusmon $(DAT)/engrave $(DAT)/epitaph $(DAT)/tribute @$(subst /,\,echo dat done >$(O)dat.tag) @$(subst /,\,cd $(DAT)) @$(subst /,\,copy $(MSYS)/msdoshlp.txt .) - @$(subst /,\,echo data >dlb.lst) - @$(subst /,\,echo dungeon >>dlb.lst) - @$(subst /,\,echo oracles >>dlb.lst) - @$(subst /,\,echo options >>dlb.lst) - @$(subst /,\,echo quest.dat >>dlb.lst) - @$(subst /,\,echo rumors >>dlb.lst) - @$(subst /,\,echo help >>dlb.lst) - @$(subst /,\,echo hh >>dlb.lst) - @$(subst /,\,echo cmdhelp >>dlb.lst) - @$(subst /,\,echo history >>dlb.lst) - @$(subst /,\,echo opthelp >>dlb.lst) - @$(subst /,\,echo wizhelp >>dlb.lst) - @$(subst /,\,echo license >>dlb.lst) - @$(subst /,\,echo msdoshlp.txt >>dlb.lst) + @$(LS) data dungeon oracles options quest.dat rumors help hh >dlb.lst + @$(LS) cmdhelp history opthelp wizhelp license msdoshlp.txt >>dlb.lst + @$(LS) bogusmon engrave epitaph tribute >>dlb.lst $(LS) $(subst /,\,*.lev) >>dlb.lst @$(subst /,\,$(U)dlb_main cvIf dlb.lst nhdat) @$(subst /,\,cd $(SRC)) @@ -1013,6 +1054,9 @@ $(O)video.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(MSYS)/video.c $(O)vidvga.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidvga.c $(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/vidvga.c +$(O)vidvesa.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidvesa.c + $(CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/vidvesa.c + $(O)vidtxt.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidtxt.c # $(CC) $(cflags) -o$@ -I$(MSYS) $(MSYS)/vidtxt.c @@ -1270,6 +1314,10 @@ $(O)worm.o: worm.c $(HACK_H) $(INCL)/lev.h $(O)worn.o: worn.c $(HACK_H) $(O)write.o: write.c $(HACK_H) $(O)zap.o: zap.c $(HACK_H) +$(O)pmatchre.o: $(SSHR)/pmatchre.c $(HACK_H) +$(O)tileset.o: $(WSHR)/tileset.c $(HACK_H) +$(O)bmptiles.o: $(WSHR)/bmptiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h +$(O)giftiles.o: $(WSHR)/giftiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h # end of file diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index 567b8ee4d..352c916e8 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pckeys.c $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 pckeys.c $NHDT-Date: 1457207039 2016/03/05 19:43:59 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1996 */ /* NetHack may be freely redistributed. See license for details. */ @@ -14,6 +14,10 @@ #include "pcvideo.h" boolean FDECL(pckeys, (unsigned char, unsigned char)); +static void FDECL(userpan, (BOOLEAN_P)); +static void FDECL(overview, (BOOLEAN_P)); +static void FDECL(traditional, (BOOLEAN_P)); +static void NDECL(refresh); extern struct WinDesc *wins[MAXWIN]; /* from wintty.c */ extern boolean inmap; /* from video.c */ @@ -47,25 +51,25 @@ unsigned char shift; #endif case 0x74: /* Control-right_arrow = scroll horizontal to right */ if ((shift & CTRL) && iflags.tile_view && !opening_dialog) - vga_userpan(1); + userpan(1); break; case 0x73: /* Control-left_arrow = scroll horizontal to left */ if ((shift & CTRL) && iflags.tile_view && !opening_dialog) - vga_userpan(0); + userpan(0); break; case 0x3E: /* F4 = toggle overview mode */ if (iflags.tile_view && !opening_dialog && !Is_rogue_level(&u.uz)) { iflags.traditional_view = FALSE; - vga_overview(iflags.over_view ? FALSE : TRUE); - vga_refresh(); + overview(iflags.over_view ? FALSE : TRUE); + refresh(); } break; case 0x3F: /* F5 = toggle traditional mode */ if (iflags.tile_view && !opening_dialog && !Is_rogue_level(&u.uz)) { iflags.over_view = FALSE; - vga_traditional(iflags.traditional_view ? FALSE : TRUE); - vga_refresh(); + traditional(iflags.traditional_view ? FALSE : TRUE); + refresh(); } break; default: @@ -73,6 +77,61 @@ unsigned char shift; } return TRUE; } + +static void +userpan(on) +boolean on; +{ +#ifdef SCREEN_VGA + if (iflags.usevga) + vga_userpan(on); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_userpan(on); +#endif +} + +static void +overview(on) +boolean on; +{ +#ifdef SCREEN_VGA + if (iflags.usevga) + vga_overview(on); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_overview(on); +#endif +} + +static void +traditional(on) +boolean on; +{ +#ifdef SCREEN_VGA + if (iflags.usevga) + vga_traditional(on); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_traditional(on); +#endif +} + +static void +refresh() +{ +#ifdef SCREEN_VGA + if (iflags.usevga) + vga_refresh(); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_refresh(); +#endif +} #endif /* USE_TILES */ #endif /* MSDOS */ diff --git a/sys/msdos/pctiles.h b/sys/msdos/pctiles.h index 58f29a390..e56812371 100644 --- a/sys/msdos/pctiles.h +++ b/sys/msdos/pctiles.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 pctiles.h $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.6 pctiles.h $NHDT-Date: 1457207040 2016/03/05 19:44:00 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ @@ -11,6 +11,10 @@ */ #ifdef USE_TILES +#ifndef TILE_X +#define TILE_X 16 +#endif + #define NETHACK_PLANAR_TILEFILE "NetHack1.tib" /* Planar style tiles */ #define NETHACK_PACKED_TILEFILE "NetHack2.tib" /* Packed style tiles */ #define NETHACK_OVERVIEW_TILEFILE "NetHacko.tib" /* thin overview tiles */ diff --git a/sys/msdos/pcvideo.h b/sys/msdos/pcvideo.h index e62bd7be1..bc2f876fd 100644 --- a/sys/msdos/pcvideo.h +++ b/sys/msdos/pcvideo.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcvideo.h $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.6 pcvideo.h $NHDT-Date: 1457207040 2016/03/05 19:44:00 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ @@ -166,7 +166,7 @@ struct overview_planar_cell_struct { #define M_BRIGHTCYAN 11 #define M_TEXT M_GRAY -#define BACKGROUND_COLOR 0 +#define BACKGROUND_COLOR 1 #define ATTRIB_NORMAL M_TEXT /* Normal attribute */ #define ATTRIB_INTENSE M_WHITE /* Intense White */ #define ATTRIB_MONO_NORMAL 0x01 /* Underlined,white */ @@ -176,9 +176,9 @@ struct overview_planar_cell_struct { #endif /*SCREEN_BIOS || SCREEN_DJGPPFAST */ #if defined(SCREEN_VGA) || defined(SCREEN_8514) -#define BACKGROUND_VGA_COLOR 0 +#define BACKGROUND_VGA_COLOR 1 #define ATTRIB_VGA_NORMAL CLR_GRAY /* Normal attribute */ -#define ATTRIB_VGA_INTENSE 13 /* Intense White 94/06/07 palette chg*/ +#define ATTRIB_VGA_INTENSE 14 /* Intense White 94/06/07 palette chg*/ #endif /*SCREEN_VGA || SCREEN_8514*/ #if defined(PC9800) @@ -258,9 +258,6 @@ E int NDECL(vga_detect); #ifdef SIMULATE_CURSOR E void NDECL(vga_DrawCursor); #endif -E void FDECL(vga_DisplayCell, (struct planar_cell_struct *, int, int)); -E void FDECL(vga_DisplayCell_O, - (struct overview_planar_cell_struct *, int, int)); E void NDECL(vga_Finish); E char __far *NDECL(vga_FontPtrs); E void NDECL(vga_get_scr_size); @@ -272,12 +269,8 @@ E void FDECL(vga_update_positionbar, (char *)); E void NDECL(vga_HideCursor); #endif E void NDECL(vga_Init); -E void FDECL(vga_SwitchMode, (unsigned int)); -E void FDECL(vga_SetPalette, (char *)); E void NDECL(vga_tty_end_screen); E void FDECL(vga_tty_startup, (int *, int *)); -E void FDECL(vga_WriteChar, (int, int, int, int)); -E void FDECL(vga_WriteStr, (char *, int, int, int, int)); E void FDECL(vga_xputs, (const char *, int, int)); E void FDECL(vga_xputc, (CHAR_P, int)); E void FDECL(vga_xputg, (int, int, unsigned)); @@ -286,6 +279,35 @@ E void FDECL(vga_overview, (BOOLEAN_P)); E void FDECL(vga_traditional, (BOOLEAN_P)); E void NDECL(vga_refresh); #endif /* SCREEN_VGA */ +#ifdef SCREEN_VESA +E void NDECL(vesa_backsp); +E void FDECL(vesa_clear_screen, (int)); +E void FDECL(vesa_cl_end, (int, int)); +E void FDECL(vesa_cl_eos, (int)); +E int NDECL(vesa_detect); +#ifdef SIMULATE_CURSOR +E void NDECL(vesa_DrawCursor); +#endif +E void NDECL(vesa_Finish); +E void NDECL(vesa_get_scr_size); +E void FDECL(vesa_gotoloc, (int, int)); +#ifdef POSITIONBAR +E void FDECL(vesa_update_positionbar, (char *)); +#endif +#ifdef SIMULATE_CURSOR +E void NDECL(vesa_HideCursor); +#endif +E void NDECL(vesa_Init); +E void NDECL(vesa_tty_end_screen); +E void FDECL(vesa_tty_startup, (int *, int *)); +E void FDECL(vesa_xputs, (const char *, int, int)); +E void FDECL(vesa_xputc, (CHAR_P, int)); +E void FDECL(vesa_xputg, (int, int, unsigned)); +E void FDECL(vesa_userpan, (BOOLEAN_P)); +E void FDECL(vesa_overview, (BOOLEAN_P)); +E void FDECL(vesa_traditional, (BOOLEAN_P)); +E void NDECL(vesa_refresh); +#endif /* SCREEN_VESA */ #endif /* NO_TERMS */ #undef E diff --git a/sys/msdos/tile2bin.c b/sys/msdos/tile2bin.c index 8ecdbfe17..4c7a3228d 100644 --- a/sys/msdos/tile2bin.c +++ b/sys/msdos/tile2bin.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 tile2bin.c $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.6 tile2bin.c $NHDT-Date: 1457207041 2016/03/05 19:44:01 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 1995 */ /* NetHack may be freely redistributed. See license for details. */ @@ -38,6 +38,12 @@ extern unsigned _stklen = STKSIZ; #endif +/* Produce only a planar file if building the overview file; with packed + files, we can make overview-size tiles on the fly */ +#if defined(OVERVIEW_FILE) && defined(PACKED_FILE) +#undef PACKED_FILE +#endif + extern char *FDECL(tilename, (int, int)); #ifdef PLANAR_FILE @@ -62,7 +68,8 @@ struct tibhdr_struct tibheader; static void FDECL(write_tibtile, (int)); static void FDECL(write_tibheader, (FILE *, struct tibhdr_struct *)); -static void FDECL(build_tibtile, (pixel(*) [TILE_X])); +static void FDECL(build_tibtile, (pixel(*) [TILE_X], BOOLEAN_P)); +static void NDECL(remap_colors); #ifndef OVERVIEW_FILE char *tilefiles[] = { "../win/share/monsters.txt", "../win/share/objects.txt", @@ -85,6 +92,7 @@ char *argv[]; struct tm *newtime; time_t aclock; char *paletteptr; + unsigned num_monsters = 0; if (argc != 1) { Fprintf(stderr, "usage: tile2bin (from the util directory)\n"); @@ -135,6 +143,7 @@ char *argv[]; } if (!paletteflag) { + remap_colors(); paletteptr = tibheader.palette; for (i = 0; i < num_colors; i++) { *paletteptr++ = ColorMap[CM_RED][i], @@ -145,15 +154,33 @@ char *argv[]; } while (read_text_tile(pixels)) { - build_tibtile(pixels); + build_tibtile(pixels, FALSE); write_tibtile(tilecount); tilecount++; } (void) fclose_text_file(); + if (filenum == 0) { + num_monsters = tilecount; + } ++filenum; } + /* Build the statue glyphs */ + if (!fopen_text_file(tilefiles[0], RDTMODE)) { + Fprintf(stderr, + "usage: tile2bin (from the util or src directory)\n"); + exit(EXIT_FAILURE); + } + + while (read_text_tile(pixels)) { + build_tibtile(pixels, TRUE); + write_tibtile(tilecount); + tilecount++; + } + + (void) fclose_text_file(); + #if defined(_MSC_VER) tibheader.compiler = MSC_COMP; #elif defined(__BORLANDC__) @@ -207,17 +234,24 @@ struct tibhdr_struct *tibhdr; } static void -build_tibtile(pixels) +build_tibtile(pixels, statues) pixel (*pixels)[TILE_X]; +boolean statues; { + static int graymappings[] = { + /* . A B C D E F G H I J K L M N O P */ + 0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14 + }; int i, j, k, co_off; unsigned char co_mask, tmp; +#ifdef PLANAR_FILE #ifndef OVERVIEW_FILE memset((void *) &planetile, 0, sizeof(struct planar_cell_struct)); #else memset((void *) &planetile, 0, sizeof(struct overview_planar_cell_struct)); +#endif #endif for (j = 0; j < TILE_Y; j++) { for (i = 0; i < TILE_X; i++) { @@ -229,6 +263,15 @@ pixel (*pixels)[TILE_X]; } if (k >= num_colors) Fprintf(stderr, "color not in colormap!\n"); + if (statues) { + k = graymappings[k]; + } else { + if (k == 16) { + k = 13; + } else if (k == 13) { + k = 16; + } + } #ifdef PACKED_FILE packtile[j][i] = k; #endif @@ -242,6 +285,14 @@ pixel (*pixels)[TILE_X]; co_mask = masktable[i]; } + if (!statues) { + if (k == 28) { + k = 0; + } + if (k >= 16) { + fprintf(stderr, "Warning: pixel value %d in 16 color bitmap\n", k); + } + } tmp = planetile.plane[0].image[j][co_off]; planetile.plane[0].image[j][co_off] = (k & 0x0008) ? (tmp | co_mask) : (tmp & ~co_mask); @@ -299,3 +350,19 @@ int recnum; fwrite(&packtile, sizeof(packtile), 1, tibfile2); #endif } + +static void +remap_colors() +{ + char swap; + + swap = ColorMap[CM_RED][13]; + ColorMap[CM_RED][13] = ColorMap[CM_RED][16]; + ColorMap[CM_RED][16] = swap; + swap = ColorMap[CM_GREEN][13]; + ColorMap[CM_GREEN][13] = ColorMap[CM_GREEN][16]; + ColorMap[CM_GREEN][16] = swap; + swap = ColorMap[CM_BLUE][13]; + ColorMap[CM_BLUE][13] = ColorMap[CM_BLUE][16]; + ColorMap[CM_BLUE][16] = swap; +} diff --git a/sys/msdos/video.c b/sys/msdos/video.c index ce1de0415..cfa5e972e 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 video.c $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 video.c $NHDT-Date: 1457207042 2016/03/05 19:44:02 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 2001 */ /* NetHack may be freely redistributed. See license for details. */ /* */ @@ -79,6 +79,11 @@ get_scr_size() if (iflags.usevga) { vga_get_scr_size(); } else +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) { + vesa_get_scr_size(); + } else #endif txt_get_scr_size(); } @@ -141,6 +146,10 @@ backsp() #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_backsp(); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_backsp(); #endif } } @@ -153,6 +162,10 @@ clear_screen() #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_clear_screen(BACKGROUND_VGA_COLOR); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_clear_screen(BACKGROUND_VGA_COLOR); #endif } } @@ -168,6 +181,10 @@ void cl_end() /* clear to end of line */ #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_cl_end(col, row); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_cl_end(col, row); #endif } tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury); @@ -182,6 +199,10 @@ void cl_eos() /* clear to end of screen */ #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_cl_eos(cy); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_cl_eos(cy); #endif } tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + 1, (int) ttyDisplay->cury); @@ -198,6 +219,10 @@ register int col, row; #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_gotoloc(col, row); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_gotoloc(col, row); #endif } } @@ -223,6 +248,10 @@ home() #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_gotoloc(0, 0); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_gotoloc(0, 0); #endif } } @@ -236,6 +265,10 @@ int col, row; #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_gotoloc(col, row); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_gotoloc(col, row); #endif } } @@ -360,6 +393,10 @@ tty_end_screen() #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_tty_end_screen(); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_tty_end_screen(); #endif } } @@ -395,6 +432,11 @@ int *wid, *hgt; if (iflags.usevga) { vga_tty_startup(wid, hgt); } else +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) { + vesa_tty_startup(wid, hgt); + } else #endif txt_startup(wid, hgt); @@ -430,39 +472,44 @@ tty_start_screen() void gr_init() { - if (iflags.usevga) { #ifdef SCREEN_VGA + if (iflags.usevga) { vga_Init(); + } else #endif #ifdef SCREEN_VESA - } else if (iflags.usevesa) { + if (iflags.usevesa) { vesa_Init(); - + } else #endif #ifdef SCREEN_8514 - } else if (iflags.use8514) { + if (iflags.use8514) { v8514_Init(); + } else #endif - } + {} } void gr_finish() { if (iflags.grmode) { - if (iflags.usevga) { #ifdef SCREEN_VGA + if (iflags.usevga) { vga_Finish(); + } else #endif #ifdef SCREEN_VESA - } else if (iflags.usevesa) { + if (iflags.usevesa) { vesa_Finish(); + } else #endif #ifdef SCREEN_8514 - } else if (iflags.use8514) { + if (iflags.use8514) { v8514_Finish(); + } else #endif - } + {} } } @@ -510,6 +557,10 @@ const char *s; #ifdef SCREEN_VGA } else if (iflags.usevga) { vga_xputs(s, col, row); +#endif +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_xputs(s, col, row); #endif } } @@ -529,6 +580,10 @@ char ch; } else if (iflags.usevga) { vga_xputc(ch, attribute); #endif /*SCREEN_VGA*/ +#ifdef SCREEN_VESA + } else if (iflags.usevesa) { + vesa_xputc(ch, attribute); +#endif /*SCREEN_VESA*/ } } @@ -541,8 +596,12 @@ unsigned special; if (!iflags.grmode || !iflags.tile_view) { xputc((char) ch); #ifdef SCREEN_VGA - } else { + } else if (iflags.grmode && iflags.usevga) { vga_xputg(glyphnum, ch, special); +#endif +#ifdef SCREEN_VESA + } else if (iflags.grmode && iflags.usevesa) { + vesa_xputg(glyphnum, ch, special); #endif } } @@ -555,9 +614,13 @@ char *posbar; if (!iflags.grmode) return; #ifdef SCREEN_VGA - else + else if (iflags.usevga) vga_update_positionbar(posbar); #endif +#ifdef SCREEN_VESA + else if (iflags.usevesa) + vesa_update_positionbar(posbar); +#endif } #endif @@ -593,7 +656,12 @@ void DrawCursor() { #ifdef SCREEN_VGA - vga_DrawCursor(); + if (iflags.usevga) + vga_DrawCursor(); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_DrawCursor(); #endif } @@ -601,7 +669,12 @@ void HideCursor() { #ifdef SCREEN_VGA - vga_HideCursor(); + if (iflags.usevga) + vga_HideCursor(); +#endif +#ifdef SCREEN_VESA + if (iflags.usevesa) + vesa_HideCursor(); #endif } @@ -854,7 +927,9 @@ char *sopt; * getch(); */ iflags.grmode = 0; + iflags.hasvesa = 0; iflags.hasvga = 0; + iflags.usevesa = 0; iflags.usevga = 0; if (strncmpi(sopt, "def", 3) == 0) { /* default */ @@ -892,9 +967,10 @@ char *sopt; #endif /* * Auto-detect Priorities (arbitrary for now): - * VGA + * VESA, VGA */ - if (iflags.hasvga) { + if (iflags.hasvesa) iflags.usevesa = 1; + else if (iflags.hasvga) { iflags.usevga = 1; /* VGA depends on BIOS to enable function keys*/ iflags.BIOS = 1; @@ -911,9 +987,13 @@ tileview(enable) boolean enable; { #ifdef SCREEN_VGA - if (iflags.grmode) + if (iflags.grmode && iflags.usevga) vga_traditional(enable ? FALSE : TRUE); #endif +#ifdef SCREEN_VESA + if (iflags.grmode && iflags.usevesa) + vesa_traditional(enable ? FALSE : TRUE); +#endif } #endif /* NO_TERMS */ diff --git a/sys/msdos/vidtxt.c b/sys/msdos/vidtxt.c index 82e18e8a3..6dd23832b 100644 --- a/sys/msdos/vidtxt.c +++ b/sys/msdos/vidtxt.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vidtxt.c $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 vidtxt.c $NHDT-Date: 1457207043 2016/03/05 19:44:03 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ /* */ @@ -235,18 +235,19 @@ void txt_cl_eos() /* clear to end of screen */ #else txt_get_cursor(&col, &row); txt_cl_end(col, row); /* clear to end of line */ - txt_gotoxy(0, (row < (LI - 1) ? row + 1 : (LI - 1))); - regs.h.dl = (char) (CO - 1); /* X of lower right */ - regs.h.dh = (char) (LI - 1); /* Y of lower right */ - regs.h.cl = 0; /* X of upper left */ - /* Y (row) of upper left */ - regs.h.ch = (char) (row < (LI - 1) ? row + 1 : (LI - 1)); - regs.x.cx = 0; - regs.x.ax = 0; - regs.x.bx = 0; - regs.h.bh = (char) attrib_text_normal; - regs.h.ah = SCROLL; - (void) int86(VIDEO_BIOS, ®s, ®s); /* Scroll or initialize window */ + if (row < LI - 1) { + txt_gotoxy(0, (row < (LI - 1) ? row + 1 : (LI - 1))); + regs.h.dl = (char) (CO - 1); /* X of lower right */ + regs.h.dh = (char) (LI - 1); /* Y of lower right */ + regs.h.cl = 0; /* X of upper left */ + /* Y (row) of upper left */ + regs.h.ch = (char) (row < (LI - 1) ? row + 1 : (LI - 1)); + regs.x.ax = 0; + regs.x.bx = 0; + regs.h.bh = (char) attrib_text_normal; + regs.h.ah = SCROLL; + (void) int86(VIDEO_BIOS, ®s, ®s); /* Scroll or initialize window */ + } #endif } diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 533ce179f..888010d4b 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vidvga.c $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.17 $ */ +/* NetHack 3.6 vidvga.c $NHDT-Date: 1457207044 2016/03/05 19:44:04 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* @@ -10,7 +10,7 @@ #ifdef SCREEN_VGA /* this file is for SCREEN_VGA only */ #include "pcvideo.h" #include "tile.h" -#include "pctiles.h" +#include "tileset.h" #include #include @@ -102,6 +102,8 @@ #include #endif +extern short glyph2tile[]; + /* STATIC_DCL void FDECL(vga_NoBorder, (int)); */ void FDECL(vga_gotoloc, (int, int)); /* This should be made a macro */ void NDECL(vga_backsp); @@ -109,7 +111,7 @@ void NDECL(vga_backsp); STATIC_DCL void FDECL(vga_scrollmap, (BOOLEAN_P)); #endif STATIC_DCL void FDECL(vga_redrawmap, (BOOLEAN_P)); -void FDECL(vga_cliparound, (int, int)); +static void FDECL(vga_cliparound, (int, int)); STATIC_OVL void FDECL(decal_planar, (struct planar_cell_struct *, unsigned)); #ifdef POSITIONBAR @@ -117,6 +119,19 @@ STATIC_DCL void NDECL(positionbar); static void FDECL(vga_special, (int, int, int)); #endif +static void FDECL(vga_DisplayCell, (struct planar_cell_struct *, int, int)); +static void FDECL(vga_DisplayCell_O, + (struct overview_planar_cell_struct *, int, int)); +static void FDECL(vga_SwitchMode, (unsigned int)); +static void FDECL(vga_SetPalette, (const struct Pixel *)); +static void FDECL(vga_WriteChar, (int, int, int, int)); +static void FDECL(vga_WriteStr, (char *, int, int, int, int)); + +static void FDECL(read_planar_tile, (unsigned, struct planar_cell_struct *)); +static void FDECL(read_planar_tile_O, + (unsigned, struct overview_planar_cell_struct *)); +static void FDECL(read_tile_indexes, (unsigned, unsigned char (*)[TILE_X])); + extern int clipx, clipxmax; /* current clipping column from wintty.c */ extern boolean clipping; /* clipping on? from wintty.c */ extern int savevmode; /* store the original video mode */ @@ -135,7 +150,7 @@ extern boolean inmap; /* in the map window */ STATIC_VAR unsigned char __far *font; STATIC_VAR char *screentable[SCREENHEIGHT]; -STATIC_VAR char *paletteptr; +STATIC_VAR const struct Pixel *paletteptr; STATIC_VAR struct map_struct { int glyph; int ch; @@ -156,8 +171,8 @@ STATIC_VAR struct map_struct { } #define TOP_MAP_ROW 1 -STATIC_VAR int vgacmap[CLR_MAX] = { 0, 3, 5, 9, 4, 8, 12, 14, - 11, 2, 6, 7, 1, 8, 12, 13 }; +STATIC_VAR int vgacmap[CLR_MAX] = { 1, 4, 6, 10, 5, 9, 0, 15, + 12, 3, 7, 8, 2, 9, 0, 14 }; STATIC_VAR int viewport_size = 40; /* STATIC_VAR char masktable[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; */ /* STATIC_VAR char bittable[8]= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; */ @@ -187,13 +202,8 @@ int vp[SCREENPLANES] = { 8, 4, 2, 1 }; #endif int vp2[SCREENPLANES] = { 1, 2, 4, 8 }; -STATIC_VAR struct planar_cell_struct *planecell; -STATIC_VAR struct overview_planar_cell_struct *planecell_O; - -#if defined(USE_TILES) -STATIC_VAR struct tibhdr_struct tibheader; -/* extern FILE *tilefile; */ /* Not needed in here most likely */ -#endif +STATIC_VAR struct planar_cell_struct planecell; +STATIC_VAR struct overview_planar_cell_struct planecell_O; /* STATIC_VAR int g_attribute; */ /* Current attribute to use */ @@ -365,6 +375,11 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden - int attr; int ry; + /* If statue glyph, map to the generic statue */ + if (GLYPH_STATUE_OFF <= glyphnum && glyphnum < GLYPH_STATUE_OFF + NUMMONS) { + glyphnum = objnum_to_glyph(STATUE); + } + row = currow; col = curcol; if ((col < 0 || col >= COLNO) @@ -380,20 +395,14 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden - vga_WriteChar((unsigned char) ch, col, row, attr); } else if (!iflags.over_view) { if ((col >= clipx) && (col <= clipxmax)) { - if (!ReadPlanarTileFile(glyph2tile[glyphnum], &planecell)) { - if (map[ry][col].special) - decal_planar(planecell, special); - vga_DisplayCell(planecell, col - clipx, row); - } else - pline("vga_xputg: Error reading tile (%d,%d) from file", - glyphnum, glyph2tile[glyphnum]); + read_planar_tile(glyphnum, &planecell); + if (map[ry][col].special) + decal_planar(&planecell, special); + vga_DisplayCell(&planecell, col - clipx, row); } } else { - if (!ReadPlanarTileFile_O(glyph2tile[glyphnum], &planecell_O)) - vga_DisplayCell_O(planecell_O, col, row); - else - pline("vga_xputg: Error reading tile (%d,%d) from file", glyphnum, - glyph2tile[glyphnum]); + read_planar_tile_O(glyphnum, &planecell_O); + vga_DisplayCell_O(&planecell_O, col, row); } if (col < (CO - 1)) ++col; @@ -422,7 +431,7 @@ int col, row; } #if defined(USE_TILES) && defined(CLIPPING) -void +static void vga_cliparound(x, y) int x, y; { @@ -489,22 +498,13 @@ boolean clearfirst; t = map[y][x].glyph; if (!(clearfirst && t == cmap_to_glyph(S_stone))) { if (!iflags.over_view) { - if (!ReadPlanarTileFile(glyph2tile[t], &planecell)) { - if (map[y][x].special) - decal_planar(planecell, map[y][x].special); - vga_DisplayCell(planecell, x - clipx, - y + TOP_MAP_ROW); - } else - pline("vga_redrawmap: Error reading tile (%d,%d)", - t, glyph2tile[t]); + read_planar_tile(t, &planecell); + if (map[y][x].special) + decal_planar(&planecell, map[y][x].special); + vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); } else { - if (!ReadPlanarTileFile_O(glyph2tile[t], - &planecell_O)) { - vga_DisplayCell_O(planecell_O, x, - y + TOP_MAP_ROW); - } else - pline("vga_redrawmap: Error reading tile (%d,%d)", - t, glyph2tile[t]); + read_planar_tile_O(t, &planecell_O); + vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW); } } } @@ -632,19 +632,98 @@ boolean left; for (y = 0; y < ROWNO; ++y) { for (x = i; x < j; x += 2) { t = map[y][x].glyph; - if (!ReadPlanarTileFile(glyph2tile[t], &planecell)) { - if (map[y][x].special) - decal_planar(planecell, map[y][x].special); - vga_DisplayCell(planecell, x - clipx, y + TOP_MAP_ROW); - } else { - pline("vga_shiftmap: Error reading tile (%d,%d)", t, - glyph2tile[t]); - } + read_planar_tile(t, &planecell); + if (map[y][x].special) + decal_planar(&planecell, map[y][x].special); + vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); } } } #endif /* SCROLLMAP */ +static void +read_planar_tile(glyph, cell) +unsigned glyph; +struct planar_cell_struct *cell; +{ + unsigned char indexes[TILE_Y][TILE_X]; + unsigned plane, y, byte, bit; + + read_tile_indexes(glyph, indexes); + /* cell->plane[0..3].image[0..15][0..1] */ + for (plane = 0; plane < SCREENPLANES; ++plane) { + for (y = 0; y < TILE_Y; ++y) { + for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) { + unsigned char b = 0; + for (bit = 0; bit < 8; ++bit) { + unsigned char x = byte * 8 + bit; + unsigned char i = indexes[y][x]; + b <<= 1; + if (i & (0x8 >> plane)) b |= 1; + } + cell->plane[plane].image[y][byte] = b; + } + } + } +} + +static void +read_planar_tile_O(glyph, cell) +unsigned glyph; +struct overview_planar_cell_struct *cell; +{ + unsigned char indexes[TILE_Y][TILE_X]; + unsigned plane, y, bit; + + read_tile_indexes(glyph, indexes); + /* cell->plane[0..3].image[0..15][0..0] */ + for (plane = 0; plane < SCREENPLANES; ++plane) { + for (y = 0; y < TILE_Y; ++y) { + unsigned char b = 0; + for (bit = 0; bit < 8; ++bit) { + unsigned char x = bit * 2; + unsigned char i = indexes[y][x]; + b <<= 1; + if (i & (0x8 >> plane)) b |= 1; + } + cell->plane[plane].image[y][0] = b; + } + } +} + +static void +read_tile_indexes(glyph, indexes) +unsigned glyph; +unsigned char (*indexes)[TILE_X]; +{ + const struct TileImage *tile; + unsigned x, y; + + /* We don't have enough colors to show the statues */ + if (glyph >= GLYPH_STATUE_OFF) { + glyph = GLYPH_OBJ_OFF + STATUE; + } + + /* Get the tile from the image */ + tile = get_tile(glyph2tile[glyph]); + + /* Map to a 16 bit palette; assume colors laid out as in default tileset */ + memset(indexes, 0, sizeof(indexes)); + for (y = 0; y < TILE_Y && y < tile->height; ++y) { + for (x = 0; x < TILE_X && x < tile->width; ++x) { + unsigned i = tile->indexes[y * tile->width + x]; + if (i == 28) { + i = 0; + } else if (i == 16) { + i = 13; + } else if (i > 15) { + i = 15; + } + indexes[y][x] = i; + } + } +} + STATIC_OVL void decal_planar(gp, special) struct planar_cell_struct *gp; @@ -671,17 +750,20 @@ vga_Init(void) int i; #ifdef USE_TILES + const char *tile_file; int tilefailure = 0; /* * Attempt to open the required tile files. If we can't * don't perform the video mode switch, use TTY code instead. * */ - if (OpenTileFile(NETHACK_PLANAR_TILEFILE, FALSE)) + tile_file = iflags.wc_tile_file; + if (tile_file == NULL || tile_file == '\0') { + tile_file = "nhtiles.bmp"; + } + if (!read_tiles(tile_file, FALSE)) tilefailure |= 1; - if (OpenTileFile(NETHACK_OVERVIEW_TILEFILE, TRUE)) - tilefailure |= 2; - if (ReadTileFileHeader(&tibheader, FALSE)) + if (get_palette() == NULL) tilefailure |= 4; if (tilefailure) { @@ -708,7 +790,7 @@ vga_Init(void) /* vga_NoBorder(BACKGROUND_VGA_COLOR); */ /* Not needed after palette mod */ #ifdef USE_TILES - paletteptr = tibheader.palette; + paletteptr = get_palette(); iflags.tile_view = TRUE; iflags.over_view = FALSE; #else @@ -730,7 +812,7 @@ vga_Init(void) * mode (video mode 0x12). No other modes are currently supported. * */ -void +static void vga_SwitchMode(unsigned int mode) { union REGS regs; @@ -760,8 +842,7 @@ vga_SwitchMode(unsigned int mode) void vga_Finish(void) { - CloseTileFile(0); - CloseTileFile(1); + free_tiles(); vga_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; @@ -853,7 +934,7 @@ vga_detect() * do it using the colour 'colour'. * */ -void +static void vga_WriteChar(chr, col, row, colour) int chr, col, row, colour; { @@ -901,7 +982,7 @@ int chr, col, row, colour; * not the x,y pixel location. * */ -void +static void vga_DisplayCell(gp, col, row) struct planar_cell_struct *gp; int col, row; @@ -932,7 +1013,7 @@ int col, row; egawriteplane(15); } -void +static void vga_DisplayCell_O(gp, col, row) struct overview_planar_cell_struct *gp; int col, row; @@ -965,7 +1046,7 @@ int col, row; * is 'len' at location (x,y) using the 'colour' colour. * */ -void +static void vga_WriteStr(s, len, col, row, colour) char *s; int len, col, row, colour; @@ -993,19 +1074,20 @@ int len, col, row, colour; * 16 colour mode at 640 x 480. * */ -void +static void vga_SetPalette(p) -char *p; +const struct Pixel *p; { union REGS regs; int i; outportb(0x3c6, 0xff); for (i = 0; i < COLORDEPTH; ++i) { + struct Pixel color = (i == 13) ? p[16] : p[i]; outportb(0x3c8, i); - outportb(0x3c9, (*p++) >> 2); - outportb(0x3c9, (*p++) >> 2); - outportb(0x3c9, (*p++) >> 2); + outportb(0x3c9, color.r >> 2); + outportb(0x3c9, color.g >> 2); + outportb(0x3c9, color.b >> 2); } regs.x.bx = 0x0000; for (i = 0; i < COLORDEPTH; ++i) { @@ -1021,10 +1103,10 @@ static unsigned char colorbits[] = { 0x08, 0x04, 0x02, 0x01 }; #ifdef POSITIONBAR #define PBAR_ROW (LI - 4) -#define PBAR_COLOR_ON 15 /* slate grey background colour of tiles */ -#define PBAR_COLOR_OFF 12 /* bluish grey, used in old style only */ -#define PBAR_COLOR_STAIRS 9 /* brown */ -#define PBAR_COLOR_HERO 14 /* creamy white */ +#define PBAR_COLOR_ON 13 /* slate grey background colour of tiles */ +#define PBAR_COLOR_OFF 0 /* bluish grey, used in old style only */ +#define PBAR_COLOR_STAIRS 10 /* brown */ +#define PBAR_COLOR_HERO 15 /* creamy white */ static unsigned char pbar[COLNO]; @@ -1152,7 +1234,7 @@ int chr, col, color; pixy = PBAR_ROW * MAX_ROWS_PER_CELL; for (vplane = 0; vplane < SCREENPLANES; ++vplane) { - egareadplane(vplane); + egareadplane(SCREENPLANES - 1 - vplane); y = pixy; for (i = 0; i < ROWS_PER_CELL; ++i) { tmp_d = screentable[y++] + col; diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index a42c49233..df756234a 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcmain.c $NHDT-Date: 1451697809 2016/01/02 01:23:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.68 $ */ +/* NetHack 3.6 pcmain.c $NHDT-Date: 1457207045 2016/03/05 19:44:05 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.69 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -115,9 +115,11 @@ char *argv[]; { register int fd; register char *dir; -#if defined(WIN32) +#if defined(WIN32) || defined(MSDOS) char *envp = NULL; char *sptr = NULL; +#endif +#if defined(WIN32) char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ]; boolean save_getreturn_status = getreturn_enabled; #endif diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh index 84364636f..df71033b8 100644 --- a/sys/unix/hints/macosx.sh +++ b/sys/unix/hints/macosx.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 macosx.sh $NHDT-Date: 1455747518 2016/02/17 22:18:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.15 $ +# NetHack 3.6 macosx.sh $NHDT-Date: 1455930387 2016/02/20 01:06:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/winnt/nhraykey.c b/sys/winnt/nhraykey.c index 95dfddf24..cae80ccd8 100644 --- a/sys/winnt/nhraykey.c +++ b/sys/winnt/nhraykey.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nhraykey.c $NHDT-Date: 1432512794 2015/05/25 00:13:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.6 nhraykey.c $NHDT-Date: 1457207047 2016/03/05 19:44:07 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) NetHack PC Development Team 2003 */ /* NetHack may be freely redistributed. See license for details. */ @@ -559,19 +559,24 @@ INPUT_RECORD *ir; scan = ir->Event.KeyEvent.wVirtualScanCode; shiftstate = ir->Event.KeyEvent.dwControlKeyState; vk = ir->Event.KeyEvent.wVirtualKeyCode; - keycode = MapVirtualKey(vk, 2); - if (is_altseq(shiftstate)) { - if (ch || inmap(keycode, vk)) - altseq = 1; - else - altseq = -1; /* invalid altseq */ - } - if (ch || iskeypad(scan) || altseq) { - done = 1; /* Stop looking */ - retval = 1; /* Found what we sought */ + if (scan == 0 && vk == 0) { + /* It's the bogus_key. Discard it */ + ReadConsoleInput(hConIn,ir,1,&count); } else { - /* Strange Key event; let's purge it to avoid trouble */ - ReadConsoleInput(hConIn, ir, 1, &count); + keycode = MapVirtualKey(vk, 2); + if (is_altseq(shiftstate)) { + if (ch || inmap(keycode, vk)) + altseq = 1; + else + altseq = -1; /* invalid altseq */ + } + if (ch || iskeypad(scan) || altseq) { + done = 1; /* Stop looking */ + retval = 1; /* Found what we sought */ + } else { + /* Strange Key event; let's purge it to avoid trouble */ + ReadConsoleInput(hConIn, ir, 1, &count); + } } } else if ((ir->EventType == MOUSE_EVENT diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index 89a29fd58..0ad47b36b 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -1,4 +1,4 @@ -! $NHDT-Date: 1454977917 2016/02/09 00:31:57 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.10 $ +! $NHDT-Date: 1457079198 2016/03/04 08:13:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.11 $ ! The display_file, tombstone, and menu windows are all formatted assuming ! a fixed width font. Text windows may or may not be formatted as above. @@ -188,6 +188,15 @@ NetHack*extended_commands*help.accelerators: #override\n\ :?: set() notify() unset() NetHack*extended_commands*dismiss.accelerators: #override\n\ Escape: set() notify() unset() +! +! The extended command menu may be too big to fit on the screen so need +! a vertical scroll bar. When truncated, its height will be as tall as +! possible unless height_delta is non-zero, in which case there will be +! that many pixels of margin left unused. On OSX, this can be used to +! avoid overlapping with the desktop docking tray to prevent that from +! obscuring the bottom of the menu. +NetHack*extcmd_height_delta: 75 + ! ! ! The following are the default 15 colors that the nethack map uses. diff --git a/win/X11/winX.c b/win/X11/winX.c index 491f6f11e..25229541a 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 winX.c $NHDT-Date: 1455389907 2016/02/13 18:58:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 3.6 winX.c $NHDT-Date: 1457079197 2016/03/04 08:13:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -1064,6 +1064,9 @@ static XtResource resources[] = { XtOffset(AppResources *, icon), XtRString, nhStr("nh72") }, { nhStr("message_lines"), nhStr("Message_lines"), XtRInt, sizeof(int), XtOffset(AppResources *, message_lines), XtRString, nhStr("12") }, + { nhStr("extcmd_height_delta"), nhStr("Extcmd_height_delta"), + XtRInt, sizeof (int), + XtOffset(AppResources *, extcmd_height_delta), XtRString, nhStr("0") }, { nhStr("pet_mark_bitmap"), nhStr("Pet_mark_bitmap"), XtRString, sizeof(String), XtOffset(AppResources *, pet_mark_bitmap), XtRString, nhStr("pet_mark.xbm") }, diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index 23253f4a3..f9d4a248a 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 winmisc.c $NHDT-Date: 1455526714 2016/02/15 08:58:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.6 winmisc.c $NHDT-Date: 1457079197 2016/03/04 08:13:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.25 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -1199,36 +1199,20 @@ Widget *formp; /* return */ else free((char *) commands); - /* - * We actually want height of topmost background window, which - * may or may not be the root window. - * - * On OSX, screen height includes the space taken up by the - * desktop title bar, which isn't accessible to applications - * unless the preference settings for X11 are changed to force - * full-screen mode (so by default, this 'screen_height' value - * ends up being bigger than the available size...). - */ - screen_height = XHeightOfScreen(XtScreen(popup)); - /* * If the menu's complete height is too big for the display, * forcing the height to be smaller will cause the vertical * scroll bar (enabled but not forced above) to be included. */ + screen_height = XHeightOfScreen(XtScreen(popup)); + screen_height -= appResources.extcmd_height_delta; /* NetHack.ad */ if (cumulative_height >= screen_height) { - /* trial and error: - 25 is a guesstimate for scrollbar width on width adjustment; - 75 is for cumulative height of 3 title bars (desktop, - application, and popup) on height adjustment; that will be - bigger than needed if the popup can overlap the application's - title bar or if there is no desktop title bar; this ought to - be deriveable on the fly, or at least user-controlled by a - resource, but for now it's hardcoded--user can manually - resize if sufficiently motivated... */ + /* 25 is a guesstimate for scrollbar width; + window manager might override the request for y==1 */ num_args = 0; + XtSetArg(args[num_args], XtNy, 1); num_args++; XtSetArg(args[num_args], XtNwidth, max_width + 25); num_args++; - XtSetArg(args[num_args], XtNheight, screen_height - 75); num_args++; + XtSetArg(args[num_args], XtNheight, screen_height - 1); num_args++; XtSetValues(popup, args, num_args); } XtRealizeWidget(popup); diff --git a/win/share/bmptiles.c b/win/share/bmptiles.c new file mode 100644 index 000000000..641415915 --- /dev/null +++ b/win/share/bmptiles.c @@ -0,0 +1,622 @@ +/* NetHack 3.6 bmptiles.c $NHDT-Date: 1457207054 2016/03/05 19:44:14 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */ +/* Copyright (c) Ray Chason, 2016. */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "config.h" +#include "integer.h" +#include "tileset.h" + +/* First BMP file header */ +struct BitmapHeader { + char magic[2]; + uint32 bmp_size; + uint32 img_offset; +}; + +/* Color model information for larger BMP headers */ +struct CIE_XYZ { + uint32 ciexyzX; + uint32 ciexyzY; + uint32 ciexyzZ; +}; + +struct CIE_XYZTriple { + struct CIE_XYZ ciexyzRed; + struct CIE_XYZ ciexyzGreen; + struct CIE_XYZ ciexyzBlue; +}; + +/* Second BMP file header */ +/* This one can vary in size; contents can vary according to the size */ +struct BitmapInfoHeader { + uint32 Size; /* 12 40 52 56 108 124 64 */ + int32 Width; /* 12 40 52 56 108 124 64 */ + int32 Height; /* 12 40 52 56 108 124 64 */ + uint16 NumPlanes; /* 12 40 52 56 108 124 64 */ + uint16 BitsPerPixel; /* 12 40 52 56 108 124 64 */ + uint32 Compression; /* 40 52 56 108 124 64 */ + uint32 ImageDataSize; /* 40 52 56 108 124 64 */ + int32 XResolution; /* 40 52 56 108 124 64 */ + int32 YResolution; /* 40 52 56 108 124 64 */ + uint32 ColorsUsed; /* 40 52 56 108 124 64 */ + uint32 ColorsImportant; /* 40 52 56 108 124 64 */ + uint32 RedMask; /* 52 56 108 124 */ + uint32 GreenMask; /* 52 56 108 124 */ + uint32 BlueMask; /* 52 56 108 124 */ + uint32 AlphaMask; /* 56 108 124 */ + uint32 CSType; /* 108 124 */ + struct CIE_XYZTriple Endpoints; /* 108 124 */ + uint32 GammaRed; /* 108 124 */ + uint32 GammaGreen; /* 108 124 */ + uint32 GammaBlue; /* 108 124 */ + uint32 Intent; /* 124 */ + uint32 ProfileData; /* 124 */ + uint32 ProfileSize; /* 124 */ +}; +/* Compression */ +#define BI_RGB 0 +#define BI_RLE8 1 +#define BI_RLE4 2 +#define BI_BITFIELDS 3 +#define BI_JPEG 4 +#define BI_PNG 5 + +static uint16 FDECL(read_u16, (const unsigned char buf[2])); +static uint32 FDECL(read_u32, (const unsigned char buf[4])); +static int32 FDECL(read_s32, (const unsigned char buf[4])); +static struct Pixel FDECL(build_pixel, (const struct BitmapInfoHeader *, uint32)); +static unsigned char FDECL(pixel_element, (uint32, uint32)); +static boolean FDECL(read_header, (FILE *, struct BitmapHeader *)); +static boolean FDECL(read_info_header, (FILE *, struct BitmapInfoHeader *)); +static boolean FDECL(check_info_header, (const struct BitmapInfoHeader *)); +static unsigned FDECL(get_palette_size, (const struct BitmapInfoHeader *)); +static boolean FDECL(read_palette, (FILE *, struct Pixel *, unsigned)); + +/* Read a .BMP file into the image structure */ +/* Return TRUE if successful, FALSE on any error */ +boolean +read_bmp_tiles(filename, image) +const char *filename; +struct TileSetImage *image; +{ + struct BitmapHeader header1; + struct BitmapInfoHeader header2; + unsigned palette_size; + size_t num_pixels, size; + unsigned x, y, y_start, y_end, y_inc; + unsigned bytes_per_row; + + FILE *fp = NULL; /* custodial */ + unsigned char *row_bytes = NULL; /* custodial */ + + image->width = 0; + image->height = 0; + image->pixels = NULL; /* custodial, returned */ + image->indexes = NULL; /* custodial, returned */ + image->image_desc = NULL; /* custodial, returned */ + image->tile_width = 0; + image->tile_height = 0; + + fp = fopen(filename, "rb"); + if (fp == NULL) goto error; + + /* Read the headers */ + if (!read_header(fp, &header1)) goto error; + if (memcmp(header1.magic, "BM", 2) != 0) goto error; + + if (!read_info_header(fp, &header2)) goto error; + if (!check_info_header(&header2)) goto error; + +#if 0 /* TODO */ + if (header2.Compression == BI_PNG) { + /* Image data is an embedded PNG bit stream */ + boolean ok = do_read_png_tiles(fp, image)); + fclose(fp); + return ok; + } +#endif + + /* header2.Height < 0 means the Y coordinate is reversed; the origin is + * top left rather than bottom left */ + image->width = header2.Width; + image->height = labs(header2.Height); + + /* Allocate pixel area; watch out for overflow */ + num_pixels = (size_t) image->width * (size_t) image->height; + if (num_pixels / image->width != image->height) goto error; /* overflow */ + size = num_pixels * sizeof(image->pixels[0]); + if (size / sizeof(image->pixels[0]) != num_pixels) goto error; /* overflow */ + image->pixels = (struct Pixel *) alloc(size); + if (header2.BitsPerPixel <= 8) { + image->indexes = (unsigned char *) alloc(num_pixels); + } + + /* Read the palette */ + palette_size = get_palette_size(&header2); + if (!read_palette(fp, image->palette, palette_size)) goto error; + + /* Read the pixels */ + fseek(fp, header1.img_offset, SEEK_SET); + if (header2.Height < 0) { + y_start = 0; + y_end = image->height; + y_inc = 1; + } else { + y_start = image->height - 1; + y_end = (unsigned) -1; + y_inc = -1; + } + if (header2.Compression == BI_RLE4 || header2.Compression == BI_RLE8) { + unsigned char *p; + p = image->indexes; + memset(p, 0, num_pixels); + x = 0; + y = image->height - 1; + while (TRUE) { + int b1, b2; + b1 = fgetc(fp); + if (b1 == EOF) goto error; + b2 = fgetc(fp); + if (b2 == EOF) goto error; + /* + * b1 b2 + * 0 0 end of line + * 0 1 end of bitmap + * 0 2 next two bytes are x and y offset + * 0 >2 b2 is a count of bytes + * >0 any repeat b2, b1 times + */ + if (b1 == 0) { + if (b2 == 0) { + /* end of line */ + --y; + x = 0; + } else if (b2 == 1) { + /* end of bitmap */ + break; + } else if (b2 == 2) { + /* next two bytes are x and y offset */ + b1 = fgetc(fp); + if (b1 == EOF) break; + b2 = fgetc(fp); + if (b2 == EOF) break; + x += b1; + y += b2; + } else { + /* get bytes */ + int i; + if (y < image->height) { + p = image->indexes + y * image->width; + for (i = 0; i < b2; ++i) { + b1 = fgetc(fp); + if (b1 == EOF) break; + if (header2.BitsPerPixel == 8) { + if (x < image->width) { + p[x] = b1; + } + ++x; + } else { + if (x < image->width) { + p[x] = b1 >> 4; + } + ++x; + if (x < image->width) { + p[x] = b1 & 0xF; + } + ++x; + } + } + if (b2 & 1) { + b1 = fgetc(fp); + if (b1 == EOF) break; + } + } + } + } else { + /* repeat b2, b1 times */ + int i; + if (y < image->height) { + p = image->indexes + y * image->width; + for (i = 0; i < b1; ++i) { + if (header2.BitsPerPixel == 8) { + if (x < image->width) { + p[x] = b2; + } + ++x; + } else { + if (x < image->width) { + p[x] = b2 >> 4; + } + ++x; + if (x < image->width) { + p[x] = b2 & 0xF; + } + ++x; + } + } + } + } + } + } else { + bytes_per_row = (image->width * header2.BitsPerPixel + 31) / 32 * 4; + row_bytes = (unsigned char *) alloc(bytes_per_row); + if (header2.Compression == BI_RGB) { + switch (header2.BitsPerPixel) { + case 16: + header2.RedMask = 0x001F; + header2.GreenMask = 0x07E0; + header2.BlueMask = 0xF800; + header2.AlphaMask = 0x0000; + break; + + case 32: + header2.RedMask = 0x000000FF; + header2.GreenMask = 0x0000FF00; + header2.BlueMask = 0x00FF0000; + header2.AlphaMask = 0xFF000000; + break; + } + } + for (y = y_start; y != y_end; y += y_inc) { + struct Pixel *row = image->pixels + y * image->width; + unsigned char *ind = image->indexes + y * image->width; + size = fread(row_bytes, 1, bytes_per_row, fp); + if (size < bytes_per_row) goto error; + switch (header2.BitsPerPixel) { + case 1: + for (x = 0; x < image->width; ++x) { + unsigned byte = x / 8; + unsigned shift = x % 8; + unsigned color = (row_bytes[byte] >> shift) & 1; + ind[x] = color; + } + break; + case 4: + for (x = 0; x < image->width; ++x) { + unsigned byte = x / 2; + unsigned shift = (x % 2) * 4; + unsigned color = (row_bytes[byte] >> shift) & 1; + ind[x] = color; + } + break; + case 8: + for (x = 0; x < image->width; ++x) { + ind[x] = row_bytes[x]; + } + break; + case 16: + for (x = 0; x < image->width; ++x) { + uint16 color = read_u16(row_bytes + x * 2); + row[x] = build_pixel(&header2, color); + } + break; + case 24: + for (x = 0; x < image->width; ++x) { + row[x].r = row_bytes[x * 3 + 2]; + row[x].g = row_bytes[x * 3 + 1]; + row[x].b = row_bytes[x * 3 + 0]; + row[x].a = 255; + } + break; + case 32: + for (x = 0; x < image->width; ++x) { + uint32 color = read_u32(row_bytes + x * 2); + row[x] = build_pixel(&header2, color); + } + break; + } + } + free(row_bytes); + row_bytes = NULL; + } + + if (image->indexes != NULL) { + size_t i; + for (i = 0; i < num_pixels; ++i) { + image->pixels[i] = image->palette[image->indexes[i]]; + } + } + + fclose(fp); + return TRUE; + +error: + if (fp) fclose(fp); + free(row_bytes); + free(image->pixels); + image->pixels = NULL; + free(image->indexes); + image->indexes = NULL; + free(image->image_desc); + image->image_desc = NULL; + return FALSE; +} + +/* Read and decode the first header */ +static boolean +read_header(fp, header) +FILE *fp; +struct BitmapHeader *header; +{ + unsigned char buf[14]; + size_t size; + + size = fread(buf, 1, sizeof(buf), fp); + if (size < sizeof(buf)) return FALSE; + + memcpy(header->magic, buf + 0, 2); + header->bmp_size = read_u32(buf + 2); + /* 6 and 8 are 16 bit integers giving the hotspot of a cursor */ + header->img_offset = read_u32(buf + 10); + return TRUE; +} + +/* Read and decode the second header */ +static boolean +read_info_header(fp, header) +FILE *fp; +struct BitmapInfoHeader *header; +{ + unsigned char buf[124]; /* maximum size */ + size_t size; + boolean have_color_mask; + + memset(header, 0, sizeof(*header)); + + /* Get the header size */ + size = fread(buf, 1, 4, fp); + if (size < 4) return FALSE; + header->Size = read_u32(buf + 0); + if (header->Size > sizeof(buf)) return FALSE; + + /* Get the rest of the header */ + size = fread(buf + 4, 1, header->Size - 4, fp); + if (size < header->Size - 4) return FALSE; + + have_color_mask = FALSE; + switch (header->Size) { + case 124: /* BITMAPV5INFOHEADER */ + /* 120 is reserved */ + header->ProfileSize = read_u32(buf + 116); + header->ProfileData = read_u32(buf + 112); + header->Intent = read_u32(buf + 108); + /* fall through */ + + case 108: /* BITMAPV4INFOHEADER */ + header->GammaBlue = read_u32(buf + 104); + header->GammaGreen = read_u32(buf + 100); + header->GammaRed = read_u32(buf + 96); + header->Endpoints.ciexyzBlue.ciexyzZ = read_u32(buf + 92); + header->Endpoints.ciexyzBlue.ciexyzY = read_u32(buf + 88); + header->Endpoints.ciexyzBlue.ciexyzX = read_u32(buf + 84); + header->Endpoints.ciexyzGreen.ciexyzZ = read_u32(buf + 80); + header->Endpoints.ciexyzGreen.ciexyzY = read_u32(buf + 76); + header->Endpoints.ciexyzGreen.ciexyzX = read_u32(buf + 72); + header->Endpoints.ciexyzRed.ciexyzZ = read_u32(buf + 68); + header->Endpoints.ciexyzRed.ciexyzY = read_u32(buf + 64); + header->Endpoints.ciexyzRed.ciexyzX = read_u32(buf + 60); + header->CSType = read_u32(buf + 56); + /* fall through */ + + case 56: /* BITMAPV3INFOHEADER */ + header->AlphaMask = read_u32(buf + 52); + /* fall through */ + + case 52: /* BITMAPV2INFOHEADER */ + header->BlueMask = read_u32(buf + 48); + header->GreenMask = read_u32(buf + 44); + header->RedMask = read_u32(buf + 40); + have_color_mask = TRUE; + /* fall through */ + + case 40: /* BITMAPINFOHEADER */ + case 64: /* OS22XBITMAPHEADER */ + /* The last 24 bytes in OS22XBITMAPHEADER are incompatible with the + * later Microsoft versions of the header */ + header->ColorsImportant = read_u32(buf + 36); + header->ColorsUsed = read_u32(buf + 32); + header->YResolution = read_s32(buf + 28); + header->XResolution = read_s32(buf + 24); + header->ImageDataSize = read_u32(buf + 20); + header->Compression = read_u32(buf + 16); + header->BitsPerPixel = read_u16(buf + 14); + header->NumPlanes = read_u16(buf + 12); + header->Height = read_s32(buf + 8); + header->Width = read_s32(buf + 4); + break; + + case 12: /* BITMAPCOREHEADER */ + header->BitsPerPixel = read_u16(buf + 10); + header->NumPlanes = read_u16(buf + 8); + header->Height = read_u16(buf + 6); + header->Width = read_u16(buf + 4); + break; + + default: + return FALSE; + } + + /* For BI_BITFIELDS, the next three 32 bit words are the color masks */ + if (header->Compression == BI_BITFIELDS && !have_color_mask) { + size = fread(buf, 1, 12, fp); + if (size < 12) return FALSE; + header->RedMask = read_u32(buf + 0); + header->GreenMask = read_u32(buf + 4); + header->BlueMask = read_u32(buf + 8); + } + + return TRUE; +} + +/* Check the second header for consistency and unsupported features */ +static boolean +check_info_header(header) +const struct BitmapInfoHeader *header; +{ + if (header->NumPlanes != 1) return FALSE; + switch (header->BitsPerPixel) { +#if 0 /* TODO */ + case 0: + if (header->Compression != BI_PNG) return FALSE; + /* JPEG not supported */ + break; +#endif + + case 1: + case 24: + if (header->Compression != BI_RGB) return FALSE; + break; + + case 4: + if (header->Compression != BI_RGB + && header->Compression != BI_RLE4) return FALSE; + break; + + case 8: + if (header->Compression != BI_RGB + && header->Compression != BI_RLE8) return FALSE; + break; + + case 16: + case 32: + if (header->Compression != BI_RGB + && header->Compression != BI_BITFIELDS) return FALSE; + /* Any of the color masks could conceivably be zero; the bitmap, though + * limited, would still be meaningful */ + if (header->Compression == BI_BITFIELDS + && header->RedMask == 0 + && header->GreenMask == 0 + && header->BlueMask == 0) return FALSE; + break; + + default: + return FALSE; + } + + if (header->Height < 0 && header->Compression != BI_RGB + && header->Compression != BI_BITFIELDS) return FALSE; + + return TRUE; +} + +/* Return the number of palette entries to read from the file */ +static unsigned +get_palette_size(header) +const struct BitmapInfoHeader *header; +{ + switch (header->BitsPerPixel) { + case 1: + return 2; + + case 4: + return header->ColorsUsed ? header->ColorsUsed : 16; + + case 8: + return header->ColorsUsed ? header->ColorsUsed : 256; + + default: + return 0; + } +} + +/* + * Read the palette from the file + * palette_size is the number of entries to read, but no more than 256 will + * be written into the palette array + * Return TRUE if successful, FALSE on any error + */ +static boolean +read_palette(fp, palette, palette_size) +FILE *fp; +struct Pixel *palette; +unsigned palette_size; +{ + unsigned i; + unsigned char buf[4]; + unsigned read_size; + + read_size = (palette_size < 256) ? palette_size : 256; + for (i = 0; i < read_size; ++i) { + size_t size = fread(buf, 1, sizeof(buf), fp); + if (size < sizeof(buf)) return FALSE; + palette[i].b = buf[0]; + palette[i].g = buf[1]; + palette[i].r = buf[2]; + palette[i].a = 255; + } + for (; i < 256; ++i) { + palette[i].b = 0; + palette[i].g = 0; + palette[i].r = 0; + palette[i].a = 255; + } + fseek(fp, 4 * (palette_size - read_size), SEEK_CUR); + return TRUE; +} + +/* Decode an unsigned 16 bit quantity */ +static uint16 +read_u16(buf) +const unsigned char buf[2]; +{ + return ((uint16)buf[0] << 0) + | ((uint16)buf[1] << 8); +} + +/* Decode an unsigned 32 bit quantity */ +static uint32 +read_u32(buf) +const unsigned char buf[4]; +{ + return ((uint32)buf[0] << 0) + | ((uint32)buf[1] << 8) + | ((uint32)buf[2] << 16) + | ((uint32)buf[3] << 24); +} + +/* Decode a signed 32 bit quantity */ +static int32 +read_s32(buf) +const unsigned char buf[4]; +{ + return (int32)((read_u32(buf) ^ 0x80000000) - 0x80000000); +} + +/* Build a pixel structure, given the mask words in the second header and + * a packed 16 or 32 bit pixel */ +static struct Pixel +build_pixel(header, color) +const struct BitmapInfoHeader *header; +uint32 color; +{ + struct Pixel pixel; + + pixel.r = pixel_element(header->RedMask, color); + pixel.g = pixel_element(header->GreenMask, color); + pixel.b = pixel_element(header->BlueMask, color); + pixel.a = header->AlphaMask ? pixel_element(header->AlphaMask, color) : 255; + return pixel; +} + +/* Extract one element (red, green, blue or alpha) from a pixel */ +static unsigned char +pixel_element(mask, color) +uint32 mask; +uint32 color; +{ + uint32 bits, shift; + + if (mask == 0) return 0; + bits = 0xFFFF; /* 0xFF, 0xF, 0x3, 0x1 */ + shift = 16; /* 8, 4, 2, 1 */ + while (bits != 0) { + if ((mask & bits) == 0) { + mask >>= shift; + color >>= shift; + } + shift /= 2; + bits >>= shift; + } + color &= mask; + return color * 255 / mask; +} diff --git a/win/share/thintile.c b/win/share/thintile.c index 6980623c0..4d6793c46 100644 --- a/win/share/thintile.c +++ b/win/share/thintile.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 thintile.c $NHDT-Date: 1432512803 2015/05/25 00:13:23 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 thintile.c $NHDT-Date: 1457207049 2016/03/05 19:44:09 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) NetHack Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ @@ -32,7 +32,7 @@ copy_colormap() int r, g, b; char c[2]; - while (fscanf(infile, "%[A-Za-z0-9] = (%d, %d, %d) ", c, &r, &g, &b) + while (fscanf(infile, "%[A-Za-z0-9.] = (%d, %d, %d) ", c, &r, &g, &b) == 4) { Fprintf(outfile, "%c = (%d, %d, %d)\n", c[0], r, g, b); } diff --git a/win/share/tilemap.c b/win/share/tilemap.c index d743c549c..47a8155d1 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 tilemap.c $NHDT-Date: 1454502429 2016/02/03 12:27:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 3.6 tilemap.c $NHDT-Date: 1457207051 2016/03/05 19:44:11 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.29 $ */ /* NetHack may be freely redistributed. See license for details. */ /* @@ -21,7 +21,7 @@ extern void FDECL(exit, (int)); #endif #endif -#if defined(WIN32) +#if defined(MSDOS) || defined(WIN32) #define STATUES_LOOK_LIKE_MONSTERS #endif diff --git a/win/share/tileset.c b/win/share/tileset.c new file mode 100644 index 000000000..1b65c32b0 --- /dev/null +++ b/win/share/tileset.c @@ -0,0 +1,225 @@ +/* NetHack 3.6 tileset.c $NHDT-Date: 1457207053 2016/03/05 19:44:13 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */ +/* Copyright (c) Ray Chason, 2016. */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" +#include "tileset.h" + +static void FDECL(get_tile_map, (const char *)); +static void FDECL(split_tiles, (const struct TileSetImage *)); +static void FDECL(free_image, (struct TileSetImage *)); + +static struct TileImage *tiles; +static unsigned num_tiles; +static struct TileImage blank_tile; /* for graceful undefined tile handling */ + +static boolean have_palette; +static struct Pixel palette[256]; + +boolean +read_tiles(filename, true_color) +const char *filename; +boolean true_color; +{ + static const unsigned char png_sig[] = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A + }; + struct TileSetImage image; + FILE *fp = NULL; /* custodial */ + char header[16]; + boolean ok; + + /* Fill the image structure with known values */ + image.width = 0; + image.height = 0; + image.pixels = NULL; /* custodial */ + image.indexes = NULL; /* custodial */ + image.image_desc = NULL; /* custodial */ + image.tile_width = 0; + image.tile_height = 0; + + /* Identify the image type */ + fp = fopen(filename, "rb"); + if (fp == NULL) goto error; + memset(header, 0, sizeof(header)); + fread(header, 1, sizeof(header), fp); + fclose(fp); + + /* Call the loader appropriate for the image */ + if (memcmp(header, "BM", 2) == 0) { + ok = read_bmp_tiles(filename, &image); + } else if (memcmp(header, "GIF87a", 6) == 0 + || memcmp(header, "GIF89a", 6) == 0) { + ok = read_gif_tiles(filename, &image); + } else if (memcmp(header, png_sig, sizeof(png_sig)) == 0) { + ok = read_png_tiles(filename, &image); + } else { + ok = FALSE; + } + if (!ok) goto error; + + /* Reject if the interface cannot handle direct color and the image does + not use a palette */ + if (!true_color && image.indexes == NULL) goto error; + + /* Save the palette if present */ + have_palette = image.indexes != NULL; + memcpy(palette, image.palette, sizeof(palette)); + + /* Set defaults for tile metadata */ + if (image.tile_width == 0) { + image.tile_width = image.width / 40; + } + if (image.tile_height == 0) { + image.tile_height = image.tile_width; + } + /* Set the tile dimensions if the user has not done so */ + if (iflags.wc_tile_width == 0) { + iflags.wc_tile_width = image.tile_width; + } + if (iflags.wc_tile_height == 0) { + iflags.wc_tile_height = image.tile_height; + } + + /* Parse the tile map */ + get_tile_map(image.image_desc); + + /* Split the image into tiles */ + split_tiles(&image); + + fclose(fp); + free_image(&image); + return TRUE; + +error: + if (fp) fclose(fp); + free_image(&image); + return FALSE; +} + +const struct Pixel * +get_palette() +{ + return have_palette ? palette : NULL; +} + +/* TODO: derive tile_map from image_desc */ +static void +get_tile_map(image_desc) +const char *image_desc; +{ +} + +void +free_tiles() +{ + unsigned i; + + if (tiles != NULL) { + for (i = 0; i < num_tiles; ++i) { + free(tiles[i].pixels); + free(tiles[i].indexes); + } + } + free(tiles); + tiles = NULL; + num_tiles = 0; + + free(blank_tile.pixels); + blank_tile.pixels = NULL; + free(blank_tile.indexes); + blank_tile.indexes = NULL; +} + +static void +free_image(image) +struct TileSetImage *image; +{ + free(image->pixels); + image->pixels = NULL; + free(image->indexes); + image->indexes = NULL; + free(image->image_desc); + image->image_desc = NULL; +} + +const struct TileImage * +get_tile(tile_index) +unsigned tile_index; +{ + if (tile_index >= num_tiles) { + return &blank_tile; + } else { + return &tiles[tile_index]; + } +} + +static void +split_tiles(image) +const struct TileSetImage *image; +{ + unsigned tile_rows, tile_cols; + size_t tile_size, i, j; + unsigned x1, y1, x2, y2; + + /* Get the number of tiles */ + tile_rows = image->height / iflags.wc_tile_height; + tile_cols = image->width / iflags.wc_tile_width; + num_tiles = tile_rows * tile_cols; + tile_size = (size_t) iflags.wc_tile_height * (size_t) iflags.wc_tile_width; + + /* Allocate the tile array */ + tiles = (struct TileImage *) alloc(num_tiles * sizeof(tiles[0])); + memset(tiles, 0, num_tiles * sizeof(tiles[0])); + + /* Copy the pixels into the tile structures */ + for (y1 = 0; y1 < tile_rows; ++y1) { + for (x1 = 0; x1 < tile_cols; ++x1) { + struct TileImage *tile = &tiles[y1 * tile_cols + x1]; + tile->width = iflags.wc_tile_width; + tile->height = iflags.wc_tile_height; + tile->pixels = (struct Pixel *) + alloc(tile_size * sizeof(struct Pixel)); + if (image->indexes != NULL) { + tile->indexes = (unsigned char *) alloc(tile_size); + } + for (y2 = 0; y2 < iflags.wc_tile_height; ++y2) { + for (x2 = 0; x2 < iflags.wc_tile_width; ++x2) { + unsigned x = x1 * iflags.wc_tile_width + x2; + unsigned y = y1 * iflags.wc_tile_height + y2; + i = y * image->width + x; + j = y2 * tile->width + x2; + tile->pixels[j] = image->pixels[i]; + if (image->indexes != NULL) { + tile->indexes[j] = image->indexes[i]; + } + } + } + } + } + + /* Create a blank tile for use when the tile index is invalid */ + blank_tile.width = iflags.wc_tile_width; + blank_tile.height = iflags.wc_tile_height; + blank_tile.pixels = (struct Pixel *) + alloc(tile_size * sizeof(struct Pixel)); + for (i = 0; i < tile_size; ++i) { + blank_tile.pixels[i].r = 0; + blank_tile.pixels[i].g = 0; + blank_tile.pixels[i].b = 0; + blank_tile.pixels[i].a = 255; + } + if (image->indexes) { + blank_tile.indexes = (unsigned char *) alloc(tile_size); + memset(blank_tile.indexes, 0, tile_size); + } +} + +boolean +read_png_tiles(filename, image) +const char *filename; +struct TileSetImage *image; +{ + /* stub */ + return FALSE; +} diff --git a/win/tty/termcap.c b/win/tty/termcap.c index 262c89a46..5add02ac3 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 termcap.c $NHDT-Date: 1447234979 2015/11/11 09:42:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.23 $ */ +/* NetHack 3.6 termcap.c $NHDT-Date: 1456907853 2016/03/02 08:37:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1246,6 +1246,7 @@ int color; xputs(hilites[color]); } +/* not to be confused with has_colors() in unixtty.c */ int has_color(color) int color; @@ -1253,23 +1254,24 @@ int color; #ifdef X11_GRAPHICS /* XXX has_color() should be added to windowprocs */ if (windowprocs.name != NULL && !strcmpi(windowprocs.name, "X11")) - return TRUE; + return 1; #endif #ifdef GEM_GRAPHICS /* XXX has_color() should be added to windowprocs */ if (windowprocs.name != NULL && !strcmpi(windowprocs.name, "Gem")) - return TRUE; + return 1; #endif #ifdef QT_GRAPHICS /* XXX has_color() should be added to windowprocs */ if (windowprocs.name != NULL && !strcmpi(windowprocs.name, "Qt")) - return TRUE; + return 1; #endif #ifdef AMII_GRAPHICS /* hilites[] not used */ - return iflags.use_color; -#endif + return iflags.use_color ? 1 : 0; +#else return hilites[color] != (char *) 0; +#endif } #endif /* TEXTCOLOR */ diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 1e98c032b..199474869 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.c $NHDT-Date: 1453514601 2016/01/23 02:03:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.124 $ */ +/* NetHack 3.6 wintty.c $NHDT-Date: 1456907854 2016/03/02 08:37:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.125 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -31,8 +31,7 @@ extern void msmsg(const char *, ...); #include "wintty.h" #ifdef CLIPPING /* might want SIGWINCH */ -#if defined(BSD) || defined(ULTRIX) || defined(AIX_31) \ - || defined(_BULL_SOURCE) +#if defined(BSD) || defined(ULTRIX) || defined(AIX_31) || defined(_BULL_SOURCE) #include #endif #endif @@ -226,8 +225,21 @@ const char *mesg; } #if defined(SIGWINCH) && defined(CLIPPING) +STATIC_DCL void FDECL(winch_handler, (int)); + + /* + * This really ought to just set a flag like the hangup handler does, + * then check the flag at "safe" times, in case the signal arrives + * while something fragile is executing. Better to have a brief period + * where display updates don't fit the new size than for tty internals + * to become corrupted. + * + * 'winch_seen' has been "notyet" for a long time.... + */ +/*ARGUSED*/ STATIC_OVL void -winch() +winch_handler(sig_unused) /* signal handler is called with at least 1 arg */ +int sig_unused UNUSED; { int oldLI = LI, oldCO = CO, i; register struct WinDesc *cw; @@ -345,7 +357,7 @@ char **argv UNUSED; ttyDisplay->lastwin = WIN_ERR; #if defined(SIGWINCH) && defined(CLIPPING) && !defined(NO_SIGNAL) - (void) signal(SIGWINCH, winch); + (void) signal(SIGWINCH, (SIG_RET_TYPE) winch_handler); #endif /* add one a space forward menu command alias */