Merge branch 'NetHack-3.6.0'
This commit is contained in:
20
Files
20
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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
334
dat/tribute
334
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
|
||||
#
|
||||
|
||||
439
doc/Guidebook.mn
439
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
|
||||
- - - - - - - - - -
|
||||
|
||||
@@ -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}]
|
||||
|
||||
3310
doc/Guidebook.txt
3310
doc/Guidebook.txt
File diff suppressed because it is too large
Load Diff
@@ -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 <lawful god> 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 <return> or <enter> during role, race, &c selection
|
||||
behaved same as <escape> to quit; now it will pick [random] instead
|
||||
tty: rename struct variable 'filter' (role.c) and function 'winch()' (wintty.c)
|
||||
to avoid conflicts with <curses.h>
|
||||
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
|
||||
|
||||
@@ -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 ### */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
40
include/integer.h
Normal file
40
include/integer.h
Normal file
@@ -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 <stdint.h>
|
||||
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 */
|
||||
100
include/mextra.h
100
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;
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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 */
|
||||
|
||||
43
include/tileset.h
Normal file
43
include/tileset.h
Normal file
@@ -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
|
||||
@@ -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 */
|
||||
|
||||
20
src/apply.c
20
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");
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
131
src/invent.c
131
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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) {
|
||||
|
||||
46
src/mhitu.c
46
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
114
src/muse.c
114
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);
|
||||
}
|
||||
|
||||
|
||||
18
src/pline.c
18
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 */
|
||||
|
||||
44
src/role.c
44
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";
|
||||
|
||||
100
src/steal.c
100
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
22
src/u_init.c
22
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))
|
||||
|
||||
@@ -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:
|
||||
|
||||
121
src/wizard.c
121
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);
|
||||
|
||||
53
src/worm.c
53
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*/
|
||||
|
||||
36
src/zap.c
36
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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <dos.h>
|
||||
#include <ctype.h>
|
||||
@@ -102,6 +102,8 @@
|
||||
#include <conio.h>
|
||||
#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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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\
|
||||
:<Key>?: set() notify() unset()
|
||||
NetHack*extended_commands*dismiss.accelerators: #override\n\
|
||||
<Key>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.
|
||||
|
||||
@@ -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") },
|
||||
|
||||
@@ -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);
|
||||
|
||||
622
win/share/bmptiles.c
Normal file
622
win/share/bmptiles.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
225
win/share/tileset.c
Normal file
225
win/share/tileset.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 <signal.h>
|
||||
#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 */
|
||||
|
||||
Reference in New Issue
Block a user