text:
tag:blogger.com,1999:blog-89541765686805462552019-08-07T07:02:27.009-04:00Mister SanitySanity? Why yes, indeed, I do have sanity. I've got loads of sanity, all kinds of sanity. Perhaps I've got a little too much sanity. I've got so much sanity, it's driving me out of my mind!Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-33359590655591138462018-03-22T19:24:00.000-04:002018-04-05T21:35:16.199-04:00Nice error message, Microsoft<q>We're sorry, but your password couldn't be changed. Code: 0x8007052d</q>
What does this mean? It took me a bit of experimentation, but I figured it out. Windows Ten has, believe it or not, a maximum password length. (That's not a typo. I don't mean a minimum. That would actually make sense.) It has two maximum password lengths, actually.

The above error message is what you get if you exceed the longer length limit of 63, when changing the password at some point after the account is set up or, at any rate, after the computer is set up. (I haven't tested what the rules are for additional accounts you create later.)

So what's the shorter limit? 20. When you turn on your computer for the first time and create an account and enter a password, you must enter a password that is 20 characters or shorter. There's nothing on the account creation screen to indicate this, and no warning if you exceed it. Everything seems to go fine, in fact, until you later try to log in, at which point you can't. (This can, of course, be solved in the usual ways. So much fun.)

Now if you'll excuse me, I have an urgent need to go install a real operating system. Immediately.
Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-26302525741967904702017-12-07T05:27:00.000-05:002017-12-07T05:27:09.577-05:00Screenshots: NetHack Fourk 22.214.171.124These screenshots are for NetHack Fourk version 220.127.116.11, which is being released today.

Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-25277345369952074232017-09-09T00:30:00.000-04:002017-09-09T00:34:49.829-04:00When Sheryl Ran for GrantedIt started on a Tuesday,
I remember that much now,
When Sheryl ran for granted.
She never really did say,
But we heard her anyhow,
When Sheryl ran for granted.

When Sheryl ran for granted,
 before two, after three,
When Sheryl ran for granted,
 over you, and under me,
When Sheryl ran for granted,
 feeling trapped, feeling free,
When Sheryl ran for granted,
 we were there, you and me,
When Sheryl ran for granted.

We had a lot of backers,
They poured in by the dozen,
When Sheryl ran for granted.
Some of us were slackers,
But the diligent were chosen,
When Sheryl ran for granted.

When Sheryl ran for granted,
 day by day, thick and thin,
When Sheryl ran for granted,
 'twas the way, that was then,
When Sheryl ran for granted,
 child's play, kith and kin,
When Sheryl ran for granted,
 what she'd say, how we'd win,
When Sheryl ran for granted.

Surprises kept on coming,
So much was unexpected,
No one foresaw the end.
Sheryl just kept on running,
She was so underrated,
It was such a mighty trend.

When Sheryl ran for granted,
 all as one, none alone,
When Sheryl ran for granted,
 what a run, in the zone,
When Sheryl ran for granted,
 she was the one, our backbone,
When Sheryl ran for granted,
 it was fun, the world to own,
When Sheryl ran for granted.

Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-71787249258758549692016-03-24T20:11:00.000-04:002016-07-15T14:23:06.477-04:00Pear Cake
Note that, for this to be any good, you must use proper canned pears. Do not go to the grocery store and buy flavorless so-unripe-they-are-crunchy canned pears. Ever. Nothing good can come from that.

Cake Ingredients:
1 quart of home-canned pears (in light syrup, ideally).
1.5 cups of (granulated white) table sugar
3 eggs
1/4 cup oil
1/2 cup milk
2.5 cups all-purpose flour
1 tsp. soda
1/2 tsp. nutmeg
1/2 tsp. allspice
2 tsp. vanilla flavoring or extract
1/2 cup golden raisins (optional)

Glaze Ingredients:
all the juice/syrup from the pears
plus any excess blended pears (see instructions)
1/2 cup sugar
2 TBSP cornstarch
1/4 tsp. pear extract (optional)
2 tsp. vanilla (optional)

Instructions:
Open the pears and pour the juice off into a saucepan, allowing the pears to drain well. (Not only do you want the juice for the glaze, you also don't want too much liquid in the cake.) Place the pears themselves in the blender and puree them, then divide the results: use up to 2 and 7/8 cups of the pear puree for the cake and whatever remains (if any) in the glaze. (If there isn't any pear puree left for the glaze, that's ok. The juice is enough.)
Preheat the oven to 350F.

Combine the larger portion of the pear puree with the sugar and eggs and beat until foamy, then beat in the oil and milk. Stir the dry ingredients together and then add them to the pear mixture. Beat until smooth. Fold in the raisins (if desired). Pour into a bundt pan. Bake at 350F for about 50 minutes (depending on your oven). When it's almost done, start the glaze (below). Let the finished cake cool in its pan for 5-10 minutes, then invert it onto a plate. Spoon glaze over the top while they are both still hot. If you get the top of the cake coated and a decent amount dripping down the sides and there is still glaze left, it can be spooned over individual slices while it lasts.

Glaze Instructions:

To make the glaze, combine the pear juice, the remaining pear puree (if any), the 1/2 cup of sugar, and the cornstarch in the saucepan. Stir and bring to a boil over medium heat, stirring frequently, until it thickens up. When you are just about ready to spoon the glaze over the cake, stir in the extract.
Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-16612603053858364792015-08-14T07:19:00.000-04:002015-08-14T07:19:00.070-04:00Big Rocks. This photo was taken on the <q>Cup and Saucer</q> hiking trail east of Kagawong.Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-72556910225802328442015-08-11T07:14:00.001-04:002015-08-11T07:14:37.165-04:00Sault Ste Marie
This is a photo of the bridge over the St. Marys river, taken from a lookout point on the campus of Lake Superior State University in the UP.
Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-85126373878762015572015-08-04T19:18:00.001-04:002015-08-04T19:18:13.864-04:00Crystal Falls, Kinsman Park, north of Sault Ste. MarieJonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-34216684637395560882015-07-21T12:53:00.000-04:002015-07-21T12:54:36.680-04:00Bridal Veil Falls, Kagawong
Ok, now that my Big Annual Thing is safely underway, I should probably start posting some photos from my vacation in June. Here's one from the falls in Kagawong.
Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-40207119742774056242015-06-18T18:57:00.002-04:002015-06-18T19:12:10.992-04:00Vacation Observations: on Currency
I just got back last night from a nine-day vacation trip with my sister. Yes, yes, photos will be forthcoming at some point. Meanwhile, a few observations. Tonight I'm going to focus on the currency.

There are some things I like about Canadian currency...

When you're counting it, you never worry that two bills are stuck together. That's basically impossible, because of how slick they are. I am not using the word <q>slick</q> for its colloquial meaning here: the bills are quite physically slippery. This feels really weird to me: they don't feel like US bills, that's for sure. But it's nice not to have to triple-check that you don't have two bills stuck together.

I could get used to the color coding. It looks weird at first, but it's pragmatically reasonable. You don't easily mistake a red fifty for a blue five or vice versa. Most of the colors were a bit stronger than they would really need to be, so yes, it kind of does look like Monopoly money if you're not accustomed to it (more subdued colors would still be easy to tell apart at a glance), but on the whole I think I like the coloring.

If you'd told me that I would like not getting pennies back (they round everything to the nearest nickel if you pay in cash), I'd have said you were crazy. But with the large pocketfuls of change that I was accumulating as it was (more on this below), I really really didn't need pennies too.

I didn't accumulate that many nickels and dimes either. Prices seemed to often work out to multiples of $.25. Maybe this was my imagination, but I don't think so. I think places of business deliberately set their prices so that with tax, the final price you pay comes out to a decently round number. This is in stark contrast to our American system where practially every single thing is priced to require pennies, nickels, _and_ dimes to each be involved somehow. (Our prices start at figures like $24.99, so you'd think oh, you just get one penny back, no big deal; but with tax, it doesn't work out that way.)

There are also a couple of things I dislike about Canadian currency.

Canadian currency does not stack nicely. Americans can take a big stack of bills, fold the entire stack in half down the middle, and conveniently store the whole thing in a pocket or wallet. This, as near as I can tell, is fundamentally impossible to do with Canadian bills. The slickness (mentioned above) may be a contributing factor, but I think the big issue is that the bills are so stiff, you can't fold two or more of them together and get them to fold in the same place. They won't both fold down the middle. Maybe one of them will, but then the other will fold in a different place, perhaps a third or a quarter of the bill's length from the end. So even with a small stack, say, six or eight bills, you end up with a pocket full of individual bills that are each folded differently and won't stack together well, so when you pull them out you feel like you're pulling out a fistful of random scraps of differently-shaped colored plastic, each unique. It's a big fat mess.

Did I mention that I accumulated huge piles of coins all the time and then proceed to say that I got no pennies and few nickels or dimes? Yes, I believe I did say both of those things, and they are both true. So yeah, I tended to accumulate a lot of quarters, but also, there are all these one- and two-dollar coins. Bazillions of them. When traveling in Canada, you must discipline yourself to spend coins on practically every transaction, out of self defense, or else your pockets will be so full of heavy coins as to pull your pants down. It's crazy. If you buy something that comes to $12.50 with tax and you hand them a twenty, you may get back six coins as your change and no bills whatsoever. They don't even have one-dollar bills, and they don't always use five-dollar bills when they could, probably because their cash drawers are all brimming with huge piles of giant two-dollar coins that they need to give out in order to make space in the drawer. This happens with every transaction, so let's say you start out with a single $50 bill. When you break it, you get back maybe a twenty, a ten, and coins. When you spend the ten, you usually just get back coins. When you break the twenty, maybe you get back a bill (maybe a five, maybe a ten) and coins. And when you spend the last bill, you certainly get back nothing but coins. So from a single $50 bill you can easily end up with more than $20 in coins. About halfway through the trip I finally got myself trained to spend the coins and divested myself, one way or another, of all of my large ones. (Have you ever paid for a more-than-ten-dollar purchase entirely in coins? I have, and the cashier didn't bat an eye. I'm sure people do it all the time up there.) Then I realized I might need a couple of coins for a parking meter at some point, so for one day I stopped spending coins, not realizing how much overkill this was. One day does not sound like that long to go without spending coins, but have a look at the result:

Also, you need a lot more of it, because things are very much more expensive in Canada. The exchange rate may be a contributor here (At the time of this writing, one US dollar is worth somewhere between $1.20 and $1.25 Canadian), but that does not fully explain the prices we saw everywhere, at every point along the spectrum from rural (think: population 300 and at least 30 minutes' drive from the nearest gas station) to highly urban (Yonge Street, Toronto). Even taking exchange rates into account, your money does not go as far in Canada. I am not exaggerating when I say that I paid $2.50 (Canadian) for a Sprite refill. (Pop is one of the worst things. Almost nobody in Canada has fountain pop. They use bottles and cans and mark them WAY up. We did stop at a McDonald's that had fountain pop, in Orangeville. This makes McDonald's _by far_ the most affordable place we found to buy cold drinks in Canada, and it was still more than at McDonald's in the US, where they're known for charging too much. The second-cheapest, ounce for ounce, was Freshmart in Manitowaning, where I paid something like $3 for a half gallon of chocolate milk.)

Finally, one observation is neither a like nor a dislike, just something I noticed: it pays to shop around a bit on exchange rates. The Duty Free in Sault Ste Marie offered me $1.14 Canadian for every $1 US, and ten minutes later at the Visitor's Center just across the border I got $1.17. Three cents on the dollar may not sound like much, but if you're changing a couple of thousand, it adds up. A few days later, the Scotia Bank in Fort Erie, where I changed my leftover money back, was paying $1.19 Canadian for $1 US. (The theoretically perfect rate at the time would have been something like $1.23, but of course you can't actually get that. Note that these numbers will not be useful for comparison if you take a trip some day in the future, because the exchange rate gradually drifts up and down over time. It pays to look up the going rates when you are preparing to go change your currency.)

So there you go, Canadian currency in a nutshell.
Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-38399496946547230542015-04-02T19:17:00.001-04:002015-04-02T19:18:50.720-04:00A Little Something I've Been Working On...
I recently made an announcement. Here are some screenshots...

The source repo is on github. You should totally play this game.
Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-43176725651089864812015-03-21T06:44:00.003-04:002015-03-21T06:49:33.768-04:00Explicability
When the news media go into absurd conniptions over some completely mundane thing, I generally don't pay much attention. That's what the news media do. There's nothing interesting to see there.

But generally don't expect Randall Munroe to be so easily excited and confused. I am referring, of course, to the placement of MH 370 in the upper-right corner of the graph, marking it as both highly weird and also very difficult to explain. I don't think it's the least bit of either.

I'm not going to spend any further time on the question of its weirdness, because that's so inherently subjective as to not be worth arguing about.

But I have a really hard time understanding why someone as creative and intelligent as the author of xkcd can find this difficult to explain. It's much easier to explain than most of the other stuff on the chart. It's so easy to come up with highly plausible explanations for this, I'm going to offer up three of them:

human malice

physical failure (of the aircraft)

human idiocy

I could go on at length, but I think I should probably just stop here. All three of these explanations are so inherently plausible, it is difficult to even rank them in terms of likelihood. All three of them are so likely, their probability is mainly limited by the fact that they're competing with each other (although, it's easily possible that more than one of them occurred). They're all things that you can easily see happen all the time in everyday life, and they're all things that could very easily lead to the loss of an airplane in the middle of the ocean and are known to have done so on other occasions.

I don't get it. What's hard to explain here?
Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-59185874638986529592015-01-25T06:57:00.001-05:002015-01-25T07:03:28.990-05:00ENABLE_EXTENDED_FLAGS undeclared
Ok, so I acquire an older-model computer (Pentium4, 2GB of RAM), and of course it comes with Windows XP installed. What's one of the first things I try to do with it?

What would a normal person try to do with it? Maybe watch some YouTube videos, or check Yahoo Mail, something like that? Facebook?

I tried to do this:

I my defense, I already have a computer, which in the first place is several years newer (multi-core, 8GB of RAM about to be increased to 16 next time I'm willing to reboot it) and, additionally, runs a much better operating system. So if I wanted to do just regular stuff on the computer, I could do it on my main system. I got this other, older system, and my thinking is, <q>while it still has the default Windows install on it, is there anything I want to try doing in Windows?</q> And in that context, this is the answer I came up with: <q>Didn't somebody on IRC say that building NetHack4 on Windows is broken right now? Maybe I should try that.</q>
 Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-16074817499236369252014-07-10T20:12:00.002-04:002015-04-19T08:59:09.153-04:00Why Profile Icons Matter
At some point during the 2.x dev cycle, the Gnome people removed an important feature from gnome-terminal, on the grounds that it might allow a user to make some of the icons in their UI look inconsistent the desktop-wide "icon theme," which is somehow more important than making it possible to distinguish between different things.

For a while, I simply downloaded the old version of gnome-terminal that still had the feature and compiled that myself, hoping maybe the whole stupid "icon theme" thing would blow over and someone would see sense. This did not occur, and when I upgraded to wheezy at work it became More Trouble Than It's Worth to try to compile the old gnome-terminal, so I switched to Konsole, which still has profile icons. I'm happy with this solution, because gnome-terminal was one of the last remaining vestiges of Gnome that I was still using, and frankly I'd just as soon move away from all of Gnome. Since sometime around version 1.0, Gnome has been systematically removing features and options and configurability at a rate that would make Apple blush. So good riddance.

But people who are not big terminal-window users keep asking me why on earth I would ever need profile icons. I want to have a post I can point to that answers this question. So I took a screenshot of my home desktop (which is spread across two monitors) and snipped out the two taskbars (one from each window) to show off here. I want to stress that this is not a contrived example. Somebody on IRC asked the question, and I took a screenshot, and then I wrote up this post. Here's my main taskbar:

The three icons at the left are Run, Screenshot, and a colorblind thingy. (Clarification: I'm not colorblind. The colorblind thingy is to show me what websites that I create might look like to people who are colorblind, so I can try to avoid making them unreadable. Not sure how effective it is.) After that there's a small blank space, then the task list, which contains the following, from left to right: Totem (a media player), dclock (the really generic-looking icon; this clock is positioned on the main monitor but often gets covered up by windows), Seamonkey (my main web browser), OpenOffice.org Writer, Opera (another web browser), Emacs, a gnome-terminal window (this computer hasn't upgraded to wheezy yet) that I use to tail logfiles, a gnome-terminal window that I use to play a game called Brogue, a gnome-terminal window that I use mostly for playing NetHack (another game) on NAO, a gnome-terminal window that I use for generic shell-related purposes, but in an auxilliary fashion (not my main shell profile), a gnome-terminal window that is remotely connected via ssh to a web server, a gnome-terminal window that I use for mostly NetHack-related purposes, but which is different from the other one (it's not for playing on NAO), another Seamonkey window, Chromium (another web browser), a gnome-terminal window that I mostly use for NetHack4, a text editor, a gnome-terminal window that is connected via ssh to the computer upstairs in the living room, a gnome-terminal window that is connected via ssh to the router, and a gnome-terminal window with a root (administrative) shell.

Here's the one from the second monitor:

The tasks on the tasklist here are a gnome-terminal window that I use to run a Perl script I wrote that reminds me when I'm supposed to be going somewhere or doing something, two more instances of dclock (these are positioned on the secondary monitor where they're less likely to get covered up by other windows), a gnome-terminal window that I use for interacting with MySQL (a relational database), two volume control applets (probably because I forgot I already had one opened and opened another; these things happen), and finally the gnome-terminal window that I use exclusively to run irssi (an IRC client).

It's important that I be able to tell different terminal windows apart on the task list. For example, if I'm looking for the web server window, I do NOT want to fiddle around with opening up six different game windows and three windows that are shelled into other systems besides the web server plus various other utility windows before finally finding the right window. This is what window icons are for. If anything, the difference between some of the terminal windows (particularly the ones used to ssh into other computers) is more important than the difference between e.g. a web browser and a word processor. Being able to quickly find the window I want is important, because otherwise hunting for the right one would cause me to waste a lot of time, and I'd get a lot less useful work done. Without profile icons, a lot of what I do would take 3-5 times as long as it should, sometimes more, because hunting for a lost window has a tendency to break a train of thought at unfortunate times.

For those who were not keeping count, the total number of gnome-terminal profiles visible on my desktop at this moment is thirteen. This is typical for me at any given time. About half of these windows are usually open, and the other half just happen to be open at the moment. Actually, my single most-frequently-used profile, my generic shell profile, isn't shown, because I don't happen to have any of those open right now. (I open them whenever I need one for something. Sometimes I have 2 or 3 of them open, but right now none. If I get more than about 4 generic shell windows open, I change the profiles on a couple of them to make it easier to keep straight which is which.)

Altogether, I have some 40 different terminal profiles, most of which are not in use at any given time, but they all get used sometimes. Every single one has its own icon. Most of them really NEED to have their own icons; a few (like the different NetHack windows) could probably do without. My situation at work is similar, in principle, though of course the details are different. At work, I don't have game windows; but I have way more shelled-into-another-computer windows, plus multiple distinct logfile windows, multiple distinct database windows, etc. If anything, the total number of terminal windows at work is often larger.

This is why profile icons matter, and this is why I don't really have any use for recent versions of gnome-terminal. This is why I am switching to Konsole.
Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-12818134383194516252013-12-24T20:44:00.000-05:002013-12-24T20:46:31.983-05:00Christmas: The Best Explanation I Know
The best explanation of Christmas that I think I have ever encountered is found (perhaps ironically —or perhaps obviously), in a book written mainly for Jewish audiences. It's a bit long, so I will attempt to summarize; but because my ability to express it as well as the book does is in doubt, I'll include a number of footnotes, which are references to particular sections of the book.

Without Christmas, humanity's hopes are pinned, as any practicing Jew knows very well, to an inherently flawed system1, wherein we (humans) are represented only by sinful men2 who can offer nothing but the blood of animals, which can never take away their sins or ours3. It is ultimately a depressing, futile system, one that makes us acutely aware of how flawed we are but can never actually solve the problem.

Here is the main point, then: it is only because God the Son was made one of us4 that we now, through the miracle of Christmas, have a perfect human representative, one of us who has offered a perfect sacrifice that completely takes away all our sin5, a man who can go to God as our representative and ask for anything for us6, and God will not say no to him.

As Christians we tend to focus on Easter, but while the resurrection is important, it is only really important in the context of Christmas. For God to conquer sin and death is all well and good, but by itself it is unremarkable, since God was sinless and immortal in the first place anyhow. For man to conquer sin and death, that is the real miracle, and it is only possible because God became a man. This is what we celebrate at Christmas.

So now instead of the worthless, flawed, futile system represented by Mount Sinai7, where the law was given that could only reveal our wickedness and so condemn us, we now have God's perfect system, the heavenly Jerusalem8, wherein our Great High Priest has made it possible for God to live among us and be our God and make us his people9. He will take away our wickedness and make us perfect10.

That is Christmas, according to the book of Hebrews.

Footnotes

#1 - 7:11-19

#2 - 5:1-4

#3 - 10:1-4

#4 - 2:14-17

#5 - 9:25-28

#6 - 7:24-28

#7 - 12:18-21

#8 - 12:22-24

#9 - 8:10-12, quoting from Jeremiah 31, and this may be the greatest promise in all scripture; I find it immensely, satisfyingly ironic that so wonderful a promise was given through the infamously depressing <q>weeping prophet</q>. God's sense of humor is really wonderful.

#10 - 10:14-18

Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-11405348114382242322013-11-25T18:51:00.001-05:002013-11-26T14:31:49.716-05:00A Tale of One Town and Three Governements... Or Is That Four? Five? Several.
This is a story about one town that is claimed by several governments. Exactly how many governments claim it is a matter of some debate -- the number could be as low as three (some people would even say two) or as high as four, depending on precisely how you count. (There are more than four, if you include historical claims, but that's true in a lot of places, so we'll only count current claims, and we'll say 3-4.)

The town itself is not very large. If it were in Ohio, it would be called a <q>village</q>, because it is not large enough to qualify as a <q>city</q> under Ohio's rules. (Of course, it's nowhere near Ohio.)

If you looked up the town on a political map that reflects the actual de facto situation, it would be in the country that I'm going to label as Blue. (I'm assigning these colors arbitrarily, as is traditional for political maps. I'm not going to try to pick them all from the respective national flags or anything.) However, it's very close to a three-way border. Just across the line in one direction is Green, and just across the line in another direction is Orange. Got that? Three-way border, Blue, Green, Orange, and the town is just barely in the Blue zone on our objective map.

Green, you may be surprised to learn, is not one of the governments involved in the dispute. They don't claim the town, and as far as I know they never have. It just happens to be close to their border.

Orange does claim the town. We'll come back to them presently.

Pink also claims the town. It's hundreds and hundreds of miles from any territory that they actually control, but they claim the town because they claim to be the successor state of White, which used to have a sort of mother/daughter or lord/vassal relationship with Red. Confused? Okay, we'll come back to Pink. In fact, we'll come back to the present day. Let's talk about the history of the situation.

The border question was originally raised between Yellow and Red. Yellow, a colonial power, had control of Blue at the time, and the town was near the border -- the poorly defined unclear fuzzy border -- between them and Red. So Yellow commissioned a study to iron out the details of exactly where the border with Red was. Yellow wanted everything to be precise and clear.

Now, the town was, and is, to this day, rather important to Red, for religious reasons. (There's an important building there, where somebody or another was born.) It's easily more important to Red than to everyone else involved combined. However, when working out the border treaty, Red was apparently not extremely careful with the implications and failed to realize, until after signing the thing, that the town is on the wrong side of the border. Oops.

Yellow, for its part, never really exerted effective control over the town. They did exert effective control over the (also disputed) surrounding area, but they mostly left the town alone. It had a trading post, but other than that it wasn't really critical, so as long as they were free to trade there (which Red didn't seem to have a problem with), it wasn't a big deal. Yellow never collected taxes from the town, and Red continued to do so, so in practice the town was de facto still part of Red's territory -- but on paper the treaty said it belonged to Yellow. Perhaps you can see how this might lead to a dispute later.

Now, a few years after Yellow and Red signed their treaty, White came along and forced Yellow and Brown to agree not to conduct negotiations directly with Red without involving White. (Too many colors? Don't worry about Brown. It doesn't come up in the story again.) The thing is, White at this point was a declining empire. The White government was overthrown not very much later. Other governments arose in the remnants of its territory. Pink was one of them.

Eventually, Blue gained independence from Yellow. So now the town was theoretically in Blue territory, but in practice still controlled by Red.

Orange, meanwhile, had gained de facto control over most of the old White territory. Looking to expand, Orange decided that since White used to have a bit of a protectorate relationship with Red, they should now have it. So Orange made plans to invade Red. The fact that they were doing so became known to Blue. Not wanting to lose any of the territory that Yellow had negotiated for with Red, Blue got out the treaty documents and moved its troops to wherever the treaty said the borders were. This is why the town is now in Blue territory -- the treaty that Yellow made has the town on the Yellow side, which is now the Blue side. Orange doesn't recognize the treaty, because it was never signed by White.

Pink also doesn't recognize the treaty, for the same reason Orange doesn't: it was never signed by White. So Pink also claims all of the territory that was formerly Red, including the small part that Blue now controls, where the town is. (Pink and Orange both claim to be the only really legitimate government for all of the territory White ever held, and they define <q>held</q> so loosely that it pretty much includes anything White ever looked at twice. This is nonsense, but they're both extremely serious about it. They both have extensive territorial disputes, with each other as well as with pretty much every other country in the region.)

So Blue, Orange, and Pink all claim the town. Just to clarify, Blue doesn't claim all of the red territory. They only claim the part Yellow negotiated for.

The Red government sort of kind of still exist in exile. They have de facto sovereignty over exactly zero square inches of territory, but they claim the territory that used to be Red. Until relatively recently, that included the small now-Blue region where the town is. They would still dearly love to claim that, because as noted the town has religious significance for them. But Red has now given up their claim to the town, because they are unwilling to deny the validity of the treaty they had with Yellow. You see, their evil invading enemy Orange claims that the treaty is invalid because it was not signed by White, and Red had no right, so Orange says, to give away territory without consulting with White. Red doesn't want any part of that, because White's supposed authority in Red affairs is the basis of Orange's claim to all of the Red territory. Red still wants Orange out of its former territory (which Red still claims) and out of its affairs entirely, and so although letting Blue have the piece with the town in it burns and chafes, it's better than admitting that Orange can have everything.

Yellow, of course, no longer claims the area, because they have acknowledge Blue independence. Blue and Yellow are actually allies now.

Green still doesn't claim the town because they never did. They're just nearby.

So the town is formally claimed by Blue, Orange, and Pink; and it is highly desired by Red. Orange and Pink have copious additional territorial disputes, with one another and with others. Actually, if you look up <q>territorial dispute</q> in the dictionary, you (figuratively, metaphorically, proverbially) see a picture of Orange and Pink.

Do you recognize these countries? The whole story can be found on Wikipedia, albeit not necessarily all in any one article. (I'll post the answers in a comment eventually, unless someone beats me to it.)
Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-86421354557700719872013-10-28T18:49:00.002-04:002013-10-28T18:49:53.666-04:00Wooden DishMy dad won this object in some kind of game or contest at a family reunion. It was made by my mom's oldest brother, who used to be a professional carpenter before he retired. He makes things out of wood as a hobby now and gives them away. This is typical of his work.

 I had to wait for a sunny day to take good photos. (I initially tried taking them indoors, but that didn't work out so well. Some of the woods he used have rather low albedo, and although my camera is significantly better in low lighting than the average consumer digicam, it does have limits.)Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-22810903897212111022012-12-20T18:56:00.000-05:002012-12-20T18:57:31.845-05:00Peach Cake
I had previously mentioned, when I posted my cherry cake recipe, that I was working on a peach variant. Today I had the opportunity to fine tune it, and I believe I finally got it right. It's a bit more bland than the cherry, but you'd expect that: peach is not such a smack-you-in-the-face flavor as cherry, nor would you really want it to be, I think. In my opinion, the peach has just the right amount of flavor for peach.

Note that, for this to be any good, you must use proper canned peaches. Do not go to the grocery store and buy flavorless crunchy picked-green canned peaches. Nothing good can come from that.

So, without further ado, the recipe for peach cake:

Ingredients:
1 quart of home-canned peaches (in light syrup, ideally).
1.5 cups of (granulated white) table sugar
3 eggs
1/4 cup oil
1/2 cup milk
2.5 cups all-purpose flour
1 tsp. soda
1/2 tsp. cinnamon
1/8 tsp. ginger
2 tsp. vanilla flavoring or extract

Glaze Ingredients:
all the juice/syrup from the peaches
about 1/2 cup of the blended peaches
1/3 cup sugar
1 TBSP cornstarch
1/4 tsp. almond extract (optional, or vanilla)

Instructions:
Open the peaches and pour off the juice into a saucepan, allowing them to drain well. (Not only do you want the juice for the glaze, you also don't want too much liquid in the cake.) Place the peaches themselves in the blender and puree them, the divide the results: use about 2 and 7/8 cups of the peach puree for the cake and the remaining half cup in the glaze. (The amount that goes in the cake is the critical measurement; if the glaze gets shorted a little or gets a bit extra, that's okay.)
Preheat the oven to 350F.

Combine the larger portion of the peach puree with the sugar and eggs and beat until foamy, then beat in the oil and milk. Stir the dry ingredients together and then add them to the peach mixture. Beat until smooth and pour into a bundt pan. Bake at 350F for about 50 minutes (depending on your oven). When it's almost done, start the glaze (below). Let the finished cake cool in its pan for 5-10 minutes, then invert it onto a plate. Spoon glaze over the top while they are both still hot. If you get the top of the cake coated and a decent amount dripping down the sides and there is still glaze left, it can be spooned over individual slices while it lasts.

Glaze Instructions:

To make the glaze, combine the peach juice, the remaining half cup of peach puree, the 1/3 cup of sugar, the cornstarch in the saucepan. Stir and bring to a boil over medium heat, stirring frequently, until it thickens up. When you are just about ready to spoon the glaze over the cake, stir in the almond extract.
Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-17143962129418113332012-09-26T07:52:00.000-04:002012-09-27T10:42:13.353-04:00NAO game 115, Turn 100856Another NetHack screenshot, this time in color:
You are blinded by the flash! ----------------------------------------------------------------------------- | 0| 0 * * ) |* | *| | | - - ----- | ----- ------------------------------| | -- --- | ----- | | | |*| | | | | | --------------| | | % <span style="color: #cfff8c;" title="< - stairs going up to DL38; these are the main level stairs, outside the Wizard's Tower">< | | | | | --- --- --- | | | -- | CaB | | --- ----------*| | | | | | | |^ | --@--------|--| | | | | | | | | ----- --- --- | |-- | @ c i@S | |-- | | | | ----- |---| | | |) | | | | : & :@E@H| | | | | | | | | | ------- | --| --- | -- c$qxc&@Q$| -|-| --- | ----|%----| | | | | | |*| |0Y | t |$HDcdf@@@| | | | | | | | | | | --------- | | -----%| |HH c d $| | | | ----- - - | --- --| | | | | | | | | | | C u d$||--%-- | | | ** | | | | | | | | - |-- | | | | | --- | Quacf O| |[ [| | ----- | | ------- | | | | |[ | | | | | | )| -----| | | | | | | | | | | --- --| | |%| | | | | H | - stairs going back down to DL40, the previous and first level inside the Wizard's Tower">> - | ^ | | --- | | |)----- | | --- | | | | | | | | -------- ---- | | | | | * |*| | --- | | - --- | --------------------------------- ----- - | | ------- | | |  - stairs going down to the next level, DL40, outside the Wizard's tower">> % H | ----------------------------------------------------------------------------- Jonadab the Heroine St:18/** Dx:22 Co:18 In:22 Wi:22 Ch:18 Lawful S:1675355 Dlvl:39 $:0 HP:236(241) Pw:71(71) AC:-40 Xp:22/25786222 T:100856 Blind

At this point in the game I am on my way to wake the Wizard. This room full of hostile monsters is just one of the things that's supposed to slow you down on the way, but it's a pretty weak defense against any character who has made it this far.

Yes, you see five pets. There's even a sixth: my original pet, Griff, found a polytrap somewhere when I wasn't paying attention and became a quivering blob, and I chose to leave him that way, because it keeps him from attacking things and getting killed. Quivering blobs, of course, do not show up on telepathy, which is why you don't see him. If all goes well, this will be the first time I ascend with my original starting pet. The other pets were domestics (cats, mostly) that I picked up in Gehennom using tripe and transformed into various more powerful things using polytraps on purpose. I originally collected them mainly so I could get the robe from the Valley priest, and then I kept them around for now just because I can. There used to be a Jabberwock, but something happened to it (possibly a purple worm; I've seen several).
Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-63880797594607636102012-08-02T09:16:00.001-04:002012-08-02T09:16:21.805-04:00Election Campaign CoverageOkay, there are a couple of months yet, so theoretically something could happen in that time to change things. Nonetheless, if I had to call the upcoming US Presidential election right now...

Working at a public library, I tend to catch glances of various local and regional newspapers from time to time.

The current, incumbent President recently made a campaign pass through Ohio. The newspapers, of course, covered this event. Some of them even put it on the front page, naturally. I mean, how often does the President of the Whole Entire United States visit your home town? That's gotta be news. But look at the photographs they're running.

I do not believe these photographs were selected to make the President look good. The Bucyrus Telegraph Forum has him squinting, brow wrinkled, lips pursed, teeth showing in the middle, so that he looks simultaneously disturbed and also comical. The Mansfield News Journal's choice of photo is worse: they apparently managed to get a shot of the President simultaneously scowling and screaming, face twisted with some obviously unpleasant emotion, possibly rage.

In video coverage, these kinds of faces flash past in a second or two, and the person goes on to have other expressions some of the time as well. In a still shot, you get one instant captured, and the people who pick the photo get to pick the instant. They were running these kinds of photos of George W. Bush four years ago. As those of you who have ever lived in a swing state know, the newspapers consistently lean just a little more to the liberal side than the average member of the population at large. I do not believe a Democrat can win in Ohio without their support.

And it would be somewhat unusual for anyone, Democrat or otherwise, to be elected President without winning Ohio's electoral votes.

So if I had to call the election today, I would predict that Romney will win.Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-54246535895472203472012-07-13T11:56:00.001-04:002012-07-13T11:56:50.107-04:00What I've Been Doing Lately
Some of my time has been going into this.Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-68387367201437484772012-04-30T09:30:00.000-04:002012-04-30T09:30:06.391-04:00Fuel Efficiency: A More Practical PerspectiveIt is undeniable, from a historical perspective, that there was a shift in emphasis in motor vehicle development and marketing from the seventies and eighties, when fuel efficiency was a major consideration, to the nineties and naughties, when fuel efficiency has mostly not been a major consideration. Now there are people who want to shift things back in the other direction, but... not everyone is buying it.

One thing I've noticed is that it seems like everyone talking about vehicle fuel efficiency these days is talking about the environment. While there's nothing per se wrong with that, it's not an effective motivator for most people. For one thing, it's very hard to quantify. If John buys a vehicle that uses 25% less fuel, how much impact can he expect that to have on the environment, anyway?

So I'd like to look at it from a more immediately practical and quantifiable perspective: the pocketbook. This is something almost everyone should be able to relate to. If John buys a vehicle that uses 25% less fuel, how much money will he save on gas, over the life of the vehicle? How much per year?

It depends on usage patterns, of course, but let's construct a hypothetical example. Let's say there are two models of vehicle, the Strontium and the Rubidium. Of course in practice there are way more than two models of vehicle available, but comparing only two makes the example simpler. So the Strontium gets almost 22 miles to the gallon (average, for the type of driving John does, blah, blah, blah) and the Rubidium gets a little over 29 mpg (with the same qualifications), i.e., it uses 25% less fuel to go the same distance. There are, of course, other differences between the vehicles, e.g., the Strontium is probably a little larger. But for now let's just figure how much difference it's going to make in gas costs.

If John is typical, he probably drives to work and back about five days a week, plus some assorted other driving. You can plug in figures that fit your situation more closely, but for the example we'll say he drives thirty minutes to work, averaging (with stop lights and everything) about 27 mph, which is typical for driving with only light traffic, only partly in town. During the 30 minute commute each way, then, he covers 13.5 miles, for a total of 135 miles a week just driving to and from work. Toss in another couple of hours of assorted other driving here and there (to church, to the mall, to the video store, to grandma's house, wherever) and you're looking at closer to 200 miles a week of driving. Again, you can plug in your own numbers and get something more relevant to your own situation.

200 miles a week means the Strontium will use about 9 gallons of gas, and the Rubidium will use about 6.8 gallons, in a week. At $4 per gallon (obviously, the price may fluctuate...) that means the Strontium costs John about $36/week to drive, and the Rubidium costs about $27.20/week, a difference of about $8.80 per week, or $460/year. If John intends to drive this vehicle for ten years, the more fuel-efficient vehicle is the better deal, from a purely financial perspective, unless it costs at least $4600 more (all else being equal).

You can plug in the numbers for actual vehicles at your leisure. Note, however, that for hybrid vehicles you have to factor in the cost of electricity you expend charging them, in addition to the gasoline (or diesel or alcohol or whatever).Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-87697379666148377532012-04-27T19:36:00.000-04:002012-04-27T19:36:19.424-04:00Convict Role patch 0.7 ported to NH4
As anyone who follows rgrn knows, Karl Garrison has created a patch for NetHack 3.4.3, which adds a Convict role. Meanwhile, some other people have been working on a fork, called "NetHack4" (which can be easily downloaded here).

I have now ported the Convict role patch to work with NetHack4. For lack of a better place to put it, here it is:

diff -Nurd nitrohack-ais523//libnethack/dat/CMakeLists.txt nitrohack-ais523-convict//libnethack/dat/CMakeLists.txt
--- nitrohack-ais523//libnethack/dat/CMakeLists.txt 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/dat/CMakeLists.txt 2012-04-27 11:44:41.000000000 -0400
@@ -6,6 +6,7 @@
 ${LNH_DAT}/bigroom.des
 ${LNH_DAT}/castle.des
 ${LNH_DAT}/Caveman.des
+ ${LNH_DAT}/Convict.des
 ${LNH_DAT}/endgame.des
 ${LNH_DAT}/gehennom.des
 ${LNH_DAT}/Healer.des
@@ -35,29 +36,30 @@
 Bar-loca.lev Bar-strt.lev bigrm-1.lev bigrm-2.lev
 bigrm-3.lev bigrm-4.lev bigrm-5.lev castle.lev
 Cav-fila.lev Cav-filb.lev Cav-goal.lev Cav-loca.lev
- Cav-strt.lev earth.lev fakewiz1.lev fakewiz2.lev
- fire.lev Hea-fila.lev Hea-filb.lev Hea-goal.lev
- Hea-loca.lev Hea-strt.lev juiblex.lev Kni-fila.lev
- Kni-filb.lev Kni-goal.lev Kni-loca.lev Kni-strt.lev
- knox.lev medusa-1.lev medusa-2.lev minefill.lev
- minend-1.lev minend-2.lev minend-3.lev minetn-1.lev
- minetn-2.lev minetn-3.lev minetn-4.lev minetn-5.lev
- minetn-6.lev minetn-7.lev Mon-fila.lev Mon-filb.lev
- Mon-goal.lev Mon-loca.lev Mon-strt.lev oracle.lev
- orcus.lev Pri-fila.lev Pri-filb.lev Pri-goal.lev
- Pri-loca.lev Pri-strt.lev Ran-fila.lev Ran-filb.lev
- Ran-goal.lev Ran-loca.lev Ran-strt.lev Rog-fila.lev
- Rog-filb.lev Rog-goal.lev Rog-loca.lev Rog-strt.lev
- Sam-fila.lev Sam-filb.lev Sam-goal.lev Sam-loca.lev
- Sam-strt.lev sanctum.lev soko1-1.lev soko1-2.lev
- soko2-1.lev soko2-2.lev soko3-1.lev soko3-2.lev
- soko4-1.lev soko4-2.lev Tou-fila.lev Tou-filb.lev
- Tou-goal.lev Tou-loca.lev Tou-strt.lev tower1.lev
- tower2.lev tower3.lev Val-fila.lev Val-filb.lev
- Val-goal.lev valley.lev Val-loca.lev Val-strt.lev
- water.lev wizard1.lev wizard2.lev wizard3.lev
- Wiz-fila.lev Wiz-filb.lev Wiz-goal.lev Wiz-loca.lev
- Wiz-strt.lev
+ Cav-strt.lev Con-strt.lev Con-loca.lev Con-goal.lev
+ Con-fila.lev Con-filb.lev earth.lev fakewiz1.lev
+ fakewiz2.lev fire.lev Hea-fila.lev Hea-filb.lev
+ Hea-goal.lev Hea-loca.lev Hea-strt.lev juiblex.lev
+ Kni-fila.lev Kni-filb.lev Kni-goal.lev Kni-loca.lev
+ Kni-strt.lev knox.lev medusa-1.lev medusa-2.lev
+ minefill.lev minend-1.lev minend-2.lev minend-3.lev
+ minetn-1.lev minetn-2.lev minetn-3.lev minetn-4.lev
+ minetn-5.lev minetn-6.lev minetn-7.lev Mon-fila.lev
+ Mon-filb.lev Mon-goal.lev Mon-loca.lev Mon-strt.lev
+ oracle.lev orcus.lev Pri-fila.lev Pri-filb.lev
+ Pri-goal.lev Pri-loca.lev Pri-strt.lev Ran-fila.lev
+ Ran-filb.lev Ran-goal.lev Ran-loca.lev Ran-strt.lev
+ Rog-fila.lev Rog-filb.lev Rog-goal.lev Rog-loca.lev
+ Rog-strt.lev Sam-fila.lev Sam-filb.lev Sam-goal.lev
+ Sam-loca.lev Sam-strt.lev sanctum.lev soko1-1.lev
+ soko1-2.lev soko2-1.lev soko2-2.lev soko3-1.lev
+ soko3-2.lev soko4-1.lev soko4-2.lev Tou-fila.lev
+ Tou-filb.lev Tou-goal.lev Tou-loca.lev Tou-strt.lev
+ tower1.lev tower2.lev tower3.lev Val-fila.lev
+ Val-filb.lev Val-goal.lev valley.lev Val-loca.lev
+ Val-strt.lev water.lev wizard1.lev wizard2.lev
+ wizard3.lev Wiz-fila.lev Wiz-filb.lev Wiz-goal.lev
+ Wiz-loca.lev Wiz-strt.lev
 )

 set (NHDAT_SRC dungeon quest.dat rumors oracles ${COMPILED_LEVELS} history data)
diff -Nurd nitrohack-ais523//libnethack/dat/Convict.des nitrohack-ais523-convict//libnethack/dat/Convict.des
--- nitrohack-ais523//libnethack/dat/Convict.des 1969-12-31 19:00:00.000000000 -0500
+++ nitrohack-ais523-convict//libnethack/dat/Convict.des 2012-04-27 09:37:17.000000000 -0400
@@ -0,0 +1,411 @@
+#
+# The "start" level for the quest.
+#
+# Here you meet your (besieged) class leader, Robert the Lifer
+# and receive your quest assignment.
+#
+MAZE:"Con-strt",' '
+FLAGS:noteleport,hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+|--------------------------------------------------------|-----------------|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|................K|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|---.---.---.---.---.---.---.---.---.---.---.---.---.---.|.................|
+|..........................................................................|
+|..........................................................................|
+|....|.---.---.---.---.---.---.---.---.---.---.---.---.--------------..----|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|---------------------------------------------------|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|--.---.---.---.---.---.---.---.---.---.---.---.---.|-----------------|
+|..........................................................................|
+|..........................................................................|
+|..........................................................................|
+|.----.---.---.---.---.---.---.---.---.---.---.---.---.--|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|--------------------------------------------------------|-----------------|
+ENDMAP
+# Dungeon Description
+REGION:(00,00,75,19),lit,"ordinary"
+# Stairs
+STAIR:(64,08),down
+# Portal arrival point
+BRANCH:(71,03,71,03),(0,0,0,0)
+# Altar
+ALTAR:(70,16),chaos,shrine
+# Robert the Lifer
+MONSTER:'@',"Robert the Lifer",(74,18)
+# fellow prisoners
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+# Corrupt guards
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+# Good `ol mimics
+MONSTER:'m',"giant mimic", (74,05), m_feature "staircase up"
+# Random traps
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+# Prison debris
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[50%]: '0', "heavy iron ball", random
+OBJECT[50%]: '0', "heavy iron ball", random
+# Non diggable walls
+NON_DIGGABLE:(00,00,75,19)
+
+#
+# The "locate" level for the quest.
+#
+# Here you have to find the exit from the Royal Dungeons
+# to go further towards your assigned quest.
+#
+
+MAZE:"Con-loca",' '
+FLAGS:noteleport,hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+--------------- ---------------
+|.....F.......| ################################# |............K|
+|.....F.......+## # #############+.............|
+|.....F.......| # # |.............|
+|.....+.......| # # |.............|
+|.....F.......| # # |.............|
+|.....F.......| ### # |.............|
+|.....F.......| ## # |FFFFFFFFFFFFF|
+|-------------- ######### # |......|......|
+ # |S-------| # |......|......|
+ # |........| ###### |-------------|
+ ################# |........| # H
+ # |........+####### #
+ # |----S---| # |----------|
+ |--+-------| # ##### |..........|
+ |..........| # # # |..........|
+ |..........| # |------| # #########+..........|
+ |..........| ######S......+### |..........|
+ |----------| |......| |----------|
+ |------|
+ENDMAP
+# Dungeon Description
+REGION:(01,01,13,07),lit,"ordinary"
+REGION:(02,15,11,17),lit,"ordinary"
+REGION:(62,01,74,09),lit,"ordinary"
+REGION:(62,14,71,17),lit,"shop"
+REGION:(28,10,35,12),lit,"barracks"
+REGION:(39,17,44,18),lit,"ordinary"
+# Stairs
+STAIR:(02,03),up
+STAIR:(39,17),down
+# Non diggable walls
+NON_DIGGABLE:(00,00,75,19)
+DOOR:locked,(04,14)
+DOOR:locked,(06,04)
+DOOR:open,(14,02)
+DOOR:closed,(61,16)
+DOOR:closed,(45,17)
+DOOR:locked,(36,12)
+DOOR:closed,(61,02)
+# Police station kops
+MONSTER: '@',"inmate",(63,08)
+MONSTER: '@',"inmate",(70,08)
+MONSTER: 'K',"Keystone Kop",(62,01),asleep
+MONSTER: 'K',"Keystone Kop",(65,01),asleep
+MONSTER: 'K',"Keystone Kop",(66,01),asleep
+MONSTER: 'K',"Keystone Kop",(74,02),asleep
+MONSTER: 'K',"Kop Sergeant",(63,03),asleep
+MONSTER: 'K',"Kop Sergeant",(72,03),asleep
+MONSTER: 'K',"Kop Lieutenant",(71,04),asleep
+MONSTER: 'K',"Kop Lieutenant",(68,05),asleep
+MONSTER: 'K',"Kop Kaptain",(64,06),asleep
+# Iron golem in supply room
+MONSTER: ''',"iron golem",(11,17),asleep
+# Supply room junk
+OBJECT: '_', "iron chain", (2,15)
+OBJECT: '_', "iron chain", (2,15)
+OBJECT: '_', "iron chain", (3,15)
+OBJECT: '_', "iron chain", (3,15)
+OBJECT: '_', "iron chain", (4,15)
+OBJECT: '0', "heavy iron ball", (4,15)
+OBJECT: '_', "iron chain", (4,15)
+OBJECT: '_', "iron chain", (5,15)
+OBJECT: '_', "iron chain", (5,15)
+OBJECT: '_', "iron chain", (6,15)
+OBJECT: '_', "iron chain", (6,15)
+OBJECT: '_', "iron chain", (6,15)
+OBJECT: '_', "iron chain", (7,15)
+OBJECT: '0', "heavy iron ball", (7,15)
+OBJECT: '_', "iron chain", (8,15)
+OBJECT: '_', "iron chain", (8,15)
+OBJECT: '_', "iron chain", (9,15)
+OBJECT: '_', "iron chain", (9,15)
+OBJECT: '_', "iron chain", (9,15)
+OBJECT: '_', "iron chain", (10,15)
+OBJECT: '_', "iron chain", (10,15)
+OBJECT: '_', "iron chain", (10,15)
+OBJECT: '_', "iron chain", (11,15)
+OBJECT: '_', "iron chain", (11,15)
+OBJECT: '0', "heavy iron ball", (11,15)
+OBJECT: '_', "iron chain", (2,16)
+OBJECT: '0', "heavy iron ball", (2,16)
+OBJECT: '_', "iron chain", (3,16)
+OBJECT: '_', "iron chain", (3,16)
+OBJECT: '_', "iron chain", (3,16)
+OBJECT: '_', "iron chain", (4,16)
+OBJECT: '_', "iron chain", (4,16)
+OBJECT: '_', "iron chain", (5,16)
+OBJECT: '_', "iron chain", (6,16)
+OBJECT: '_', "iron chain", (6,16)
+OBJECT: '_', "iron chain", (6,16)
+OBJECT: '_', "iron chain", (7,16)
+OBJECT: '_', "iron chain", (7,16)
+OBJECT: '0', "heavy iron ball", (7,16)
+OBJECT: '_', "iron chain", (7,16)
+OBJECT: '_', "iron chain", (8,16)
+OBJECT: '_', "iron chain", (8,16)
+OBJECT: '_', "iron chain", (9,16)
+OBJECT: '_', "iron chain", (9,16)
+OBJECT: '_', "iron chain", (9,16)
+OBJECT: '_', "iron chain", (10,16)
+OBJECT: '_', "iron chain", (10,16)
+OBJECT: '_', "iron chain", (11,16)
+OBJECT: '_', "iron chain", (2,17)
+OBJECT: '_', "iron chain", (3,17)
+OBJECT: '_', "iron chain", (3,17)
+OBJECT: '_', "iron chain", (3,17)
+OBJECT: '_', "iron chain", (4,17)
+OBJECT: '0', "heavy iron ball", (4,17)
+OBJECT: '_', "iron chain", (4,17)
+OBJECT: '_', "iron chain", (4,17)
+OBJECT: '0', "heavy iron ball", (4,17)
+OBJECT: '_', "iron chain", (5,17)
+OBJECT: '_', "iron chain", (6,17)
+OBJECT: '_', "iron chain", (7,17)
+OBJECT: '_', "iron chain", (7,17)
+OBJECT: '_', "iron chain", (7,17)
+OBJECT: '_', "iron chain", (8,17)
+OBJECT: '0', "heavy iron ball", (8,17)
+OBJECT: '_', "iron chain", (9,17)
+OBJECT: '_', "iron chain", (9,17)
+OBJECT: '0', "heavy iron ball", (9,17)
+OBJECT: '_', "iron chain", (9,17)
+OBJECT: '_', "iron chain", (10,17)
+OBJECT: '_', "iron chain", (10,17)
+OBJECT: '_', "iron chain", (10,17)
+OBJECT: '0', "heavy iron ball", (10,17)
+OBJECT: '_', "iron chain", (11,17)
+
+
+#
+# The "goal" level for the quest.
+#
+# Here you meet Warden Arianna, your nemesis monster. You have to
+# defeat Warden Arianna in combat to gain the artifact you have
+# been assigned to retrieve.
+#
+
+MAZE:"Con-goal",' '
+FLAGS:hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+---------------------------------------------------------
+|...| |............................| |
+|...| --............................| |
+|...| |.............................| |
+|...| --.............................| |
+|...| |..............................| |
+|...| --...................L..........| |
+|...| |....................L..........| |
+|...| --...................L.L.........| |
+|...| |..............L.L.L.L.L.L.L.L...| |
+|...|-----................L..L...L..L.....| |
+|...........................L.L.L.L.......| |
+|...........................L.L.L.L.......| |
+|..........................L.L...L.L......| |
+|.........................................|-------------|
+|.........................................|.............|
+|.........................................S.............|
+|.........................................|.............|
+|.........................................|.............|
+---------------------------------------------------------
+ENDMAP
+# Dungeon Description
+REGION:(00,00,56,19),lit,"ordinary"
+# Stairs
+STAIR:(02,02),up
+# Non diggable walls
+NON_DIGGABLE:(00,00,56,19)
+# Random traps
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+# Lava demons
+MONSTER: '&',"lava demon",(30,05),hostile,awake
+MONSTER: '&',"lava demon",(23,09),hostile,awake
+MONSTER: '&',"lava demon",(39,09),hostile,awake
+MONSTER: '&',"lava demon",(36,14),hostile,awake
+MONSTER: '&',"lava demon",(26,14),hostile,awake
+# Elite guard
+MONSTER: ''',"iron golem",(04,13),hostile
+# Objects
+OBJECT:'0',"heavy iron ball",(31,10),blessed,0,"The Iron Ball of Liberation"
+OBJECT:'(',"chest",(55,18),blessed,2
+# Warden Arianna
+MONSTER:'@',"Warden Arianna",(31,10),hostile
+
+#
+# The "fill" levels for the quest.
+#
+# These levels are used to fill out any levels not occupied by specific
+# levels as defined above. "filla" is the upper filler, between the
+# start and locate levels, and "fillb" the lower between the locate
+# and goal levels.
+#
+
+MAZE:"Con-fila",' '
+FLAGS:hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+----------------------------------------------------------------------------
+|....................---------.......................---------.............|
+|....................F...|...|.......................F...|...|.............|
+|....................|...|...F.......................|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|....F...|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...F.......|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|....F...|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...F.......|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|........|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...F.......|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|....F...|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...........|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|........|...|.......................F...|...|.............................|
+|....|...|...F.......................|...|...F.............................|
+|--------------------------------------------------------------------------|
+ENDMAP
+# Dungeon Description
+REGION:(00,00,75,19),lit,"ordinary"
+# Stairs
+STAIR:(74,03),up
+STAIR:(03,17),down
+# Non diggable walls
+NON_DIGGABLE:(00,00,75,19)
+# "Regular" prisoners
+MONSTER:'@',"inmate",(59,02)
+MONSTER:'@',"inmate",(55,08)
+MONSTER:'@',"inmate",(43,14)
+MONSTER:'@',"inmate",(38,05)
+MONSTER:'@',"inmate",(27,02)
+MONSTER:'@',"inmate",(23,08)
+MONSTER:'@',"inmate",(11,14)
+MONSTER:'@',"inmate",(06,05)
+# Undead prisoners
+MONSTER:' ',"ghost",(42,17),"Orzo the Inmate"
+MONSTER[50%]:' ',"ghost",(40,18),"Fredgar the Inmate"
+MONSTER[50%]:' ',"ghost",(06,12),"Rastilon the Inmate"
+MONSTER:'Z',"skeleton",(28,15),awake
+# Bugs and snakes
+MONSTER:'S',"pit viper",(06,17)
+MONSTER:'x',"xan",random
+# Corrupt guards
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+# Random traps
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+# Prison debris
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[50%]: '0', "heavy iron ball", random
+OBJECT[50%]: '0', "heavy iron ball", random
+
+
+MAZE:"Con-filb",' '
+FLAGS:hardfloor
+INIT_MAP: '#' , ' ', true, true, unlit, true
+MESSAGE: "This appears to be a prison level that is still under construction"
+NOMAP
+#
+STAIR: random, up
+STAIR: random, down
+# Peaceful miners
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+# Earth creatures
+MONSTER:'X',"xorn",random
+MONSTER:'E',"earth elemental",random
+MONSTER[50%]:'X',"xorn",random
+MONSTER[50%]:'E',"earth elemental",random
+# Other nasties
+MONSTER:'t',"lurker above",random
+MONSTER:'t',"trapper",random
+MONSTER[50%]:'t',"lurker above",random
+MONSTER[50%]:'t',"trapper",random
+MONSTER[50%]:'p',"rock piercer",random
+MONSTER[50%]:'p',"rock piercer",random
+MONSTER[50%]:'p',"iron piercer",random
+MONSTER[50%]:'p',"iron piercer",random
+MONSTER[50%]:'p',"glass piercer",random
+MONSTER[50%]:'p',"glass piercer",random
+# Tools and corpses
+OBJECT[50%]: '(', "pick-axe", random
+OBJECT[75%]: '(', "brass lantern", random
+OBJECT[50%]: '(', random, random
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+# Natural cavern hazards
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "falling rock", random
+TRAP: "falling rock", random
+TRAP: "falling rock", random
+TRAP: "falling rock", random
+TRAP: "web", random
+TRAP: "web", random
+
diff -Nurd nitrohack-ais523//libnethack/dat/quest.txt nitrohack-ais523-convict//libnethack/dat/quest.txt
--- nitrohack-ais523//libnethack/dat/quest.txt 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/dat/quest.txt 2012-04-27 09:41:09.000000000 -0400
@@ -809,6 +809,302 @@
 "Sacrifice the Amulet on the altar. Thus shall %d become supreme!"
 %E
 #
+# Convict
+#
+%Cc Con 00001
+Somehow, you have been captured and teleported back to
+%H! But wait, the portal you went through is still
+here. You had heard your old mentor %l,
+the prison chaplain who taught you the ways of
+%d calling for your help. Also, %H
+is not as you had left it. There seems to be damage
+to the walls, and you hear sounds of strife all
+around you.
+%E
+%Cp Con 00002
+You have returned to %H. Somehow, things are even
+worse now than when you were on your previous visit. Has
+%l managed to still hold out?
+%E
+%Cp Con 00003
+The situation seems to degrade, and you wonder how long
+your fellow %gp can hold out against the corrupt
+guards and creatures of the Underdark that pervade the
+formerly tranquil %H.
+%E
+%Cp Con 00005
+"How did you manage to escape?"
+%E
+%Cp Con 00006
+"How is life on the outside?"
+%E
+%Cp Con 00007
+"Between the abusive guards, and the nasty vermin, I
+don't know how we will hold out."
+%E
+%Cp Con 00008
+"This place used to be so much nicer before %n
+became corrupt."
+%E
+%Cp Con 00009
+"You are really back? I thought you were gone for
+good."
+%E
+%Cp Con 00010
+"Thank you for ridding us of %n. I hope the
+new warden will be better."
+%E
+%Cp Con 00011
+"Take me with you! I will be glad to be rid of this
+awful place."
+%E
+%Cp Con 00012
+"Don't forget to come back for us once you have
+completed your quest!"
+%E
+%Cp Con 00013
+"Thank you for coming back to help us in our hour
+of need!"
+%E
+%Cp Con 00014
+"Leave while you still can! If you can escape,
+maybe there is hope for the rest of us."
+%E
+%Cc Con 00015
+"%p, I am very happy to see that you are
+alive and well! We were all proud of your daring
+escape, and hoped that you were doing well.
+Things have become much worse in your absence,
+however, and we desperately need your help. Let
+me have a look at you, and see if you are ready."
+%E
+%Cp Con 00016
+"I see that you are back, %p. I hope that
+you are now ready to help us? Let me see if you
+are."
+%E
+%Cp Con 00017
+"Once again, you have returned. Let me see if you
+are finally ready to help us."
+%E
+%Cc Con 00018
+"You have betrayed us all, %p! Begone from
+here, and don't come back! You are not even worthy
+to share a cell with the least of us now."
+%E
+%Cc Con 00019
+"%p, I am afraid that a %r will be no
+match for %n. If I sent you now,
+she would dispatch you all too easily.
+
+"Continue your other quest, and practice your
+skills. Return to us once you have achieved the rank
+of %R."
+%E
+%Cc Con 00020
+"%p, I see that you are not yet a loyal servant of
+%d. Leave this place for now, and only
+return when you have cleansed your spirit. Only then
+will you be ready to stand up to %n and
+recover %o."
+%E
+%Cc Con 00021
+"Yes, %p, it looks like you are now ready to
+help us. Things have become much worse since you
+left. The dungeons are overrun by vermin, guards
+have become brutal and corrupt, and I believe that
+%n has had dealings with dark powers.
+
+"I had spent many years enchanting my iron ball
+with powers to help lead an escape from this place,
+turning it into %o.
+Unfortunately, %n stole it from me,
+likely using it for dark, twisted purposes.
+
+"We need your help to go down to the warden's level
+to defeat the corrupt %n and recover
+%o for us so that
+%H will be safe again."
+%E
+%Cp Con 00025
+"The sooner you are able to recover %o,
+the better off we will be."
+%E
+%Cp Con 00026
+"I am not sure what has happened, but even without
+%o, %n will make a formidable opponent."
+%E
+%Cp Con 00027
+"Stay true to the teachings of %d, and good
+fortune will be with you."
+%E
+%Cp Con 00028
+"I am afraid without the power of %o
+to protect us, we will soon be overwhelmed."
+%E
+%Cp Con 00029
+"%n used to be a woman of honor before turning
+to dark ways. It is much too late for
+redemption, however."
+%E
+%Cp Con 00030
+"%n is arrogant, and will try to diminish
+your confidence. Do not let yourself be
+discouraged!"
+%E
+%Cp Con 00031
+"You will have to be very alert, and will need
+to use all of your cunning if you hope to
+defeat %n."
+%E
+%Cp Con 00032
+"Call upon the power of %d to protect you
+when you encounter %n."
+%E
+%Cp Con 00033
+"If you remain true to your faith, you should
+be able to sense the power of %o when
+you are near."
+%E
+%Cp Con 00034
+"You should be able to defeat %n easily
+enough in a fair fight. Unfortunately, she doesn't
+fight fair."
+%E
+%Cc Con 00035
+This must be the level that leads to the warden's
+area. You must be getting closer to
+%o now!
+%E
+%Cp Con 00036
+Once again, you find yourself near the entrance to
+the warden's area. Hopefully, you can acquire
+%o before it's too late!
+%E
+%Cc Con 00040
+You sense the presence of %o as soon as you
+enter this level. If %o is here, then
+%n must not be far away.
+%E
+%Cp Con 00041
+Once again, you find yourself in the abode of
+%n, and feel the presence of
+%o.
+%E
+%Cc Con 00050
+"So, %p. You have returned, and are here to get
+%o for %l?
+What makes you think you can get it if
+%l couldn't? I have many
+allies that have made me even stronger."
+%E
+%Cp Con 00051
+"I see that you have returned, %p. I
+suggest you leave and save yourself while you still
+have a chance."
+%E
+%Cp Con 00052
+"Back again, %p? You will certainly die in
+your attempt to defeat me."
+%E
+%Cp Con 00053
+"I will get %o from you, just as I did
+%l! You can not defeat me."
+%E
+%Cp Con 00060
+"You should never come back. You will not escape
+here alive again!"
+%E
+%Cp Con 00061
+"Even all of your pathetic lot put together would
+not be enough to defeat me."
+%E
+%Cp Con 00062
+"You are no more than lowly prison scum. You are
+unworthy to even challenge me."
+%E
+%Cp Con 00063
+"Even %l could not stand up to me, so
+you have no chance at all."
+%E
+%Cp Con 00064
+"Even %o would not be enough to
+make you my equal."
+%E
+%Cp Con 00065
+"Your pathetic devotion to %d will not
+save you, either."
+%E
+%Cp Con 00066
+"After I kill you, I will go after %l next,
+and any that dare to defy me again!"
+%E
+%Cp Con 00067
+"Die with dishonor, lowly %c!"
+%E
+%Cp Con 00068
+"Once a %c, always a %c."
+%E
+%Cp Con 00069
+"How about you find yourself a cosy little cell,
+and hope that I forgive your insolence?"
+%E
+%Cc Con 00070
+As you pick up %o, you feel its power
+flow through you, protecting you, and making you
+more aware of your surroundings. You know that
+you need to get it back to %l as soon
+as possible now.
+%E
+%Cc Con 00080
+As %n approaches death, you see sudden
+clarity in her eyes.
+
+"What have I done? Those demons have been clouding my mind.
+Please forgive me, %p, although I know that I
+probably do not deserve it. Take
+%o back to %l
+with my blessing."
+
+With a final coughing fit, %n spasms, and her
+eyes see no more.
+%E
+%Cc Con 00081
+"Congratulations, %p! You have returned with
+your life, and with %o! I had
+planned to use %o to lead an
+escape from here, but with %n defeated,
+life should go back to normal before long.
+
+"Whether I like it or not, I know my place is here. I
+see that %o has already attuned
+itself to you. I offer it to you in hopes that
+it will aid in your quest to recover the Amulet
+of Yendor."
+%E
+%Cc Con 00082
+%l looks upon %o
+with fondness.
+"You are its keeper now. Take it with you back to
+%Z, through the magic portal
+that brought you here."
+%E
+%Cc Con 00090
+"Welcome back, %p. We have done well in your
+absence. How far have you come with your quest to
+regain the Amulet of Yendor for %d?"
+%E
+%Cc Con 00091
+"Congratulations, %p! You have redeemed yourself
+and proven yourself a worthy servant of %d,
+and in doing so have made all of us proud.
+
+"One final task remains for you now. You must take
+the Amulet up to the Great Temple of %d, on
+the Astral plane. There you must offer the Amulet
+to %d."
+%E
+#
 # Healer
 #
 %Cc Hea 00001
@@ -3504,3 +3800,25 @@
 S suffix: return s_suffix(capitalized(root));
 t suffix: return strip_the_prefix(root);
 %E
+#
+# Alternate legacy text for Convict role
+#
+%Cc - 00199
+It is written in the Book of %d:
+
+ After the Creation, the cruel god Moloch rebelled
+ against the authority of Marduk the Creator.
+ Moloch stole from Marduk the most powerful of all
+ the artifacts of the gods, the Amulet of Yendor,
+ and he hid it in the dark cavities of Gehennom, the
+ Under World, where he now lurks, and bides his time.
+
+Your %G %d seeks to possess the Amulet, and with it
+to gain deserved ascendance over the other gods.
+
+You, a newly escaped %r, have chosen to redeem
+yourself by recovering the Amulet for %d. You are
+determined to recover the Amulet for your deity, or die
+in the attempt. Your hour of destiny has come. For
+the sake of us all: Go bravely with %d!
+%E
diff -Nurd nitrohack-ais523//libnethack/include/artifact.h nitrohack-ais523-convict//libnethack/include/artifact.h
--- nitrohack-ais523//libnethack/include/artifact.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/artifact.h 2012-04-27 09:42:29.000000000 -0400
@@ -59,5 +59,6 @@
 #define CREATE_PORTAL (LAST_PROP+7)
 #define ENLIGHTENING (LAST_PROP+8)
 #define CREATE_AMMO (LAST_PROP+9)
+#define PHASING (LAST_PROP+10)

 #endif /* ARTIFACT_H */
diff -Nurd nitrohack-ais523//libnethack/include/artilist.h nitrohack-ais523-convict//libnethack/include/artilist.h
--- nitrohack-ais523//libnethack/include/artilist.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/artilist.h 2012-04-27 09:45:41.000000000 -0400
@@ -42,6 +42,10 @@
 A("Excalibur", LONG_SWORD,
 (SPFX_NOGEN|SPFX_RESTR|SPFX_SEEK|SPFX_DEFN|SPFX_INTEL|SPFX_SEARCH),0,0,
 PHYS(5,10), DRLI(0,0), NO_CARY, 0, A_LAWFUL, PM_KNIGHT, NON_PM, 4000L ),
+/* Convict role first sacrifice gift: */
+A("Luck Blade", BROADSWORD,
+ (SPFX_RESTR|SPFX_LUCK|SPFX_INTEL),0,0,
+ PHYS(5,6), NO_DFNS, NO_CARY, 0, A_CHAOTIC, PM_CONVICT, NON_PM, 3000L ),
 /*
 * Stormbringer only has a 2 because it can drain a level,
 * providing 8 more.
@@ -167,6 +171,12 @@
 PHYS(5,0), NO_DFNS, CARY(AD_MAGM),
 CONFLICT, A_LAWFUL, PM_CAVEMAN, NON_PM, 2500L ),

+A("The Iron Ball of Liberation", HEAVY_IRON_BALL,
+ (SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL),
+ (SPFX_STLTH|SPFX_SEARCH|SPFX_WARN), 0,
+ NO_ATTK, NO_DFNS, CARY(AD_MAGM),
+ PHASING, A_NEUTRAL, PM_PRISONER, NON_PM, 5000L ),
+
 A("The Staff of Aesculapius", QUARTERSTAFF,
 (SPFX_NOGEN|SPFX_RESTR|SPFX_ATTK|SPFX_INTEL|SPFX_DRLI|SPFX_REGEN), 0,0,
 DRLI(0,0), DRLI(0,0), NO_CARY,
diff -Nurd nitrohack-ais523//libnethack/include/decl.h nitrohack-ais523-convict//libnethack/include/decl.h
--- nitrohack-ais523//libnethack/include/decl.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/decl.h 2012-04-27 09:46:23.000000000 -0400
@@ -142,6 +142,7 @@
 extern char dogname[];
 extern char catname[];
 extern char horsename[];
+extern char ratname[];
 extern char preferred_pet;
 extern const char *occtxt; /* defined when occupation != NULL */
 extern const char *nomovemsg;
diff -Nurd nitrohack-ais523//libnethack/include/eshk.h nitrohack-ais523-convict//libnethack/include/eshk.h
--- nitrohack-ais523//libnethack/include/eshk.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/eshk.h 2012-04-27 09:47:07.000000000 -0400
@@ -31,6 +31,7 @@
 schar shoproom; /* index in rooms; set by inshop() */
 boolean following; /* following customer since he owes us sth */
 boolean surcharge; /* angry shk inflates prices */
+ boolean pbanned; /* player is banned from the shop (convict role) */
 char customer[PL_NSIZ]; /* most recent customer */
 char shknam[PL_NSIZ];
 };
diff -Nurd nitrohack-ais523//libnethack/include/mondata.h nitrohack-ais523-convict//libnethack/include/mondata.h
--- nitrohack-ais523//libnethack/include/mondata.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/mondata.h 2012-04-27 09:48:46.000000000 -0400
@@ -89,6 +89,11 @@
 #define is_bat(ptr) ((ptr) == &mons[PM_BAT] || \
 (ptr) == &mons[PM_GIANT_BAT] || \
 (ptr) == &mons[PM_VAMPIRE_BAT])
+# define is_rat(ptr) ((ptr) == &mons[PM_SEWER_RAT] || \
+ (ptr) == &mons[PM_GIANT_RAT] || \
+ (ptr) == &mons[PM_RABID_RAT] || \
+ (ptr) == &mons[PM_ENORMOUS_RAT] || \
+ (ptr) == &mons[PM_RODENT_OF_UNUSUAL_SIZE])
 #define is_bird(ptr) ((ptr)->mlet == S_BAT && !is_bat(ptr))
 #define is_giant(ptr) (((ptr)->mflags2 & M2_GIANT) != 0L)
 #define is_golem(ptr) ((ptr)->mlet == S_GOLEM)
@@ -195,6 +200,6 @@
 (ptr) != &mons[PM_BLACK_PUDDING]))

 #define befriend_with_obj(ptr, obj) ((obj)->oclass == FOOD_CLASS && \
- is_domestic(ptr))
+ (is_domestic(ptr) || (is_rat(ptr) && Role_if(PM_CONVICT))))

 #endif /* MONDATA_H */
diff -Nurd nitrohack-ais523//libnethack/include/youprop.h nitrohack-ais523-convict//libnethack/include/youprop.h
--- nitrohack-ais523//libnethack/include/youprop.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/youprop.h 2012-04-27 09:49:40.000000000 -0400
@@ -268,7 +268,7 @@
 #define EPasses_walls u.uprops[PASSES_WALLS].extrinsic
 #define Passes_walls (HPasses_walls || EPasses_walls || \
 passes_walls(youmonst.data))
-
+#define Phasing u.uprops[PASSES_WALLS].intrinsic

 /*** Physical attributes ***/
 #define HSlow_digestion u.uprops[SLOW_DIGESTION].intrinsic
diff -Nurd nitrohack-ais523//libnethack/src/allmain.c nitrohack-ais523-convict//libnethack/src/allmain.c
--- nitrohack-ais523//libnethack/src/allmain.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/allmain.c 2012-04-27 18:45:55.000000000 -0400
@@ -882,13 +882,26 @@
 if (MON_AT(level, u.ux, u.uy)) mnexto(m_at(level, u.ux, u.uy));
 makedog();
 doredraw();
+
+ if (Role_if(PM_CONVICT)) {
+ setworn(mkobj(level, CHAIN_CLASS, TRUE), W_CHAIN);
+ setworn(mkobj(level, BALL_CLASS, TRUE), W_BALL);
+ uball->spe = 1;
+ placebc();
+ newsym(u.ux,u.uy);
+ }

 /* help the window port get it's display charset/tiles sorted out */
 notify_levelchange();

 if (flags.legacy) {
- flush_screen();
- com_pager(1);
+ flush_screen();
+ if (Role_if(PM_CONVICT)) {
+ com_pager(199); /* Convicts are "escaped" rather than
+ * "trained", among other things. */
+ } else {
+ com_pager(1);
+ }
 }

 program_state.something_worth_saving++; /* useful data now exists */
diff -Nurd nitrohack-ais523//libnethack/src/artifact.c nitrohack-ais523-convict//libnethack/src/artifact.c
--- nitrohack-ais523//libnethack/src/artifact.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/artifact.c 2012-04-27 19:13:20.000000000 -0400
@@ -504,6 +504,17 @@
 if (yours) pline("%s your grasp!", Tobjnam(obj, "evade"));
 return 0;
 }
+ /* This is a kludge, but I'm not sure where else to put it */
+ if (oart == &artilist[ART_IRON_BALL_OF_LIBERATION]) {
+ if (Role_if(PM_CONVICT) && (!obj->oerodeproof)) {
+ obj->oerodeproof = TRUE;
+ obj->owt = 300; /* Magically lightened, but still heavy */
+ }
+
+ if (Punished && (obj != uball)) {
+ unpunish(); /* Remove a mundane heavy iron ball */
+ }
+ }

 return 1;
 }
@@ -1328,6 +1339,33 @@
 otmp->owt = weight(otmp);
 hold_another_object(otmp, "Suddenly %s out.", aobjnam(otmp, "fall"), NULL);
 break;
+ case PHASING: /* Walk through walls and stone like a xorn */
+ if (Passes_walls) goto nothing_special;
+ if (oart == &artilist[ART_IRON_BALL_OF_LIBERATION]) {
+ if (Punished && (obj != uball)) {
+ unpunish(); /* Remove a mundane heavy iron ball */
+ }
+
+ if (!Punished) {
+ setworn(mkobj(level, CHAIN_CLASS, TRUE), W_CHAIN);
+ setworn(obj, W_BALL);
+ uball->spe = 1;
+ if (!u.uswallow) {
+ placebc();
+ if (Blind) set_bc(1); /* set up ball and chain variables */
+ newsym(u.ux,u.uy); /* see ball&chain if can't see self */
+ }
+ pline("Your %s chains itself to you!", xname(obj));
+ }
+ }
+ if (!Hallucination) {
+ pline("Your body begins to feel less solid.");
+ } else {
+ pline("You feel one with the spirit world.");
+ }
+ incr_itimeout(&Phasing, (50 + rnd(100)));
+ obj->age += Phasing; /* Time begins after phasing ends */
+ break;
 }
 }
 } else {
diff -Nurd nitrohack-ais523//libnethack/src/attrib.c nitrohack-ais523-convict//libnethack/src/attrib.c
--- nitrohack-ais523//libnethack/src/attrib.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/attrib.c 2012-04-27 10:08:56.000000000 -0400
@@ -36,6 +36,11 @@
 { 15, &(HWarning), "sensitive", "" },
 { 0, 0, 0, 0 } },

+ con_abil[] = { { 1, &(HSick_resistance), "", "" },
+ { 7, &(HPoison_resistance), "healthy", "" },
+ { 20, &(HSearching), "perceptive", "unaware" },
+ { 0, 0, 0, 0 } },
+
 hea_abil[] = { { 1, &(HPoison_resistance), "", "" },
 { 15, &(HWarning), "sensitive", "" },
 { 0, 0, 0, 0 } },
@@ -467,6 +472,7 @@
 case PM_ARCHEOLOGIST: abil = arc_abil; break;
 case PM_BARBARIAN: abil = bar_abil; break;
 case PM_CAVEMAN: abil = cav_abil; break;
+ case PM_CONVICT: abil = con_abil; break;
 case PM_HEALER: abil = hea_abil; break;
 case PM_KNIGHT: abil = kni_abil; break;
 case PM_MONK: abil = mon_abil; break;
diff -Nurd nitrohack-ais523//libnethack/src/cmd.c nitrohack-ais523-convict//libnethack/src/cmd.c
--- nitrohack-ais523//libnethack/src/cmd.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/cmd.c 2012-04-27 18:53:41.000000000 -0400
@@ -632,6 +632,9 @@
 if (u.usick_type & SICK_NONVOMITABLE)
 you_are(&menu, "sick from illness");
 }
+ if (Punished) {
+ you_are(&menu, "punished");
+ }
 }
 if (Stoned) you_are(&menu, "turning to stone");
 if (Slimed) you_are(&menu, "turning into slime");
diff -Nurd nitrohack-ais523//libnethack/src/decl.c nitrohack-ais523-convict//libnethack/src/decl.c
--- nitrohack-ais523//libnethack/src/decl.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/decl.c 2012-04-27 10:24:44.000000000 -0400
@@ -135,6 +135,7 @@
 char dogname[PL_PSIZ];
 char catname[PL_PSIZ];
 char horsename[PL_PSIZ];
+char ratname[PL_PSIZ];
 char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */
 /* monsters that went down/up together with @ */
 struct monst *mydogs;
@@ -233,6 +234,7 @@
 memset(dogname, 0, sizeof(dogname));
 memset(catname, 0, sizeof(catname));
 memset(horsename, 0, sizeof(horsename));
+ memset(ratname, 0, sizeof(ratname));
 memset(&youmonst, 0, sizeof(youmonst));
 memset(&zeroobj, 0, sizeof(zeroobj));
 memset(mvitals, 0, sizeof(mvitals));
diff -Nurd nitrohack-ais523//libnethack/src/do.c nitrohack-ais523-convict//libnethack/src/do.c
--- nitrohack-ais523//libnethack/src/do.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/do.c 2012-04-27 10:13:15.000000000 -0400
@@ -1022,7 +1022,11 @@
 pline("You fly down along the %s.",
 at_ladder ? "ladder" : "stairs");
 else if (at_stairs &&
- (near_capacity() > UNENCUMBERED || Punished || Fumbling)) {
+ (near_capacity() > UNENCUMBERED
+ || (Punished && ((uwep != uball)
+ || ((P_SKILL(P_FLAIL) < P_BASIC))
+ || !Role_if(PM_CONVICT)))
+ || Fumbling)) {
 pline("You fall down the %s.", at_ladder ? "ladder" : "stairs");
 if (Punished) {
 drag_down();
diff -Nurd nitrohack-ais523//libnethack/src/dog.c nitrohack-ais523-convict//libnethack/src/dog.c
--- nitrohack-ais523//libnethack/src/dog.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/dog.c 2012-04-27 10:18:02.000000000 -0400
@@ -131,6 +131,8 @@
 petname = dogname;
 else if (pettype == PM_PONY)
 petname = horsename;
+ else if (pettype == PM_SEWER_RAT)
+ petname = ratname;
 else
 petname = catname;

@@ -142,6 +144,9 @@
 if (Role_if(PM_BARBARIAN)) petname = "Idefix"; /* Obelix */
 if (Role_if(PM_RANGER)) petname = "Sirius"; /* Orion's dog */
 }
+ if (!*petname && pettype == PM_SEWER_RAT) {
+ if(Role_if(PM_CONVICT)) petname = "Nicodemus"; /* Rats of NIMH */
+ }

 mtmp = makemon(&mons[pettype], level, u.ux, u.uy, MM_EDOG);

@@ -708,6 +713,12 @@
 && mtmp->data->mlet == S_DOG)
 return NULL;

+ if (Role_if(PM_CONVICT) && (is_domestic(mtmp->data) && obj)) {
+ /* Domestic animals are wary of the Convict */
+ pline("%s still looks wary of you.", Monnam(mtmp));
+ return NULL;
+ }
+
 /* If we cannot tame it, at least it's no longer afraid. */
 mtmp->mflee = 0;
 mtmp->mfleetim = 0;
diff -Nurd nitrohack-ais523//libnethack/src/dokick.c nitrohack-ais523-convict//libnethack/src/dokick.c
--- nitrohack-ais523//libnethack/src/dokick.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/dokick.c 2012-04-27 10:18:35.000000000 -0400
@@ -309,6 +309,8 @@
 goldreqd = 500L;
 else if (mtmp->data == &mons[PM_CAPTAIN])
 goldreqd = 750L;
+ else if (mtmp->data == &mons[PM_PRISON_GUARD])
+ goldreqd = 200L;

 if (goldreqd) {
 if (value > goldreqd +
diff -Nurd nitrohack-ais523//libnethack/src/eat.c nitrohack-ais523-convict//libnethack/src/eat.c
--- nitrohack-ais523//libnethack/src/eat.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/eat.c 2012-04-27 10:22:08.000000000 -0400
@@ -1210,12 +1210,15 @@
 "Mmm, tripe... not bad!");
 else {
 pline("Yak - dog food!");
+ if (Role_if(PM_CONVICT))
+ pline("At least it's not prison food.");
 more_experienced(1,0);
 newexplevel();
 /* not cannibalism, but we use similar criteria
 for deciding whether to be sickened by this meal */
 if (rn2(2) && !CANNIBAL_ALLOWED())
- make_vomiting((long)rn1(victual.reqtime, 14), FALSE);
+ if (!Role_if(PM_CONVICT))
+ make_vomiting((long)rn1(victual.reqtime, 14), FALSE);
 }
 break;
 case MEATBALL:
@@ -1253,7 +1256,10 @@
 #endif
 if (otmp->otyp == EGG && stale_egg(otmp)) {
 pline("Ugh. Rotten egg."); /* perhaps others like it */
- make_vomiting(Vomiting+dice(10,4), TRUE);
+ if (Role_if(PM_CONVICT) && (rn2(8) > u.ulevel)) {
+ pline("You feel a slight stomach ache."); /* prisoners are used to bad food */
+ } else
+ make_vomiting(Vomiting+dice(10,4), TRUE);
 } else
 give_feedback:
 pline("This %s is %s", singular(otmp, xname),
@@ -1943,6 +1949,8 @@

 if ((!u.usleep || !rn2(10)) /* slow metabolic rate while asleep */
 && (carnivorous(youmonst.data) || herbivorous(youmonst.data))
+ /* Convicts can last twice as long at hungry and below */
+ && (!Role_if(PM_CONVICT) || (moves % 2) || (u.uhs < HUNGRY))
 && !Slow_digestion)
 u.uhunger--; /* ordinary food consumption */

diff -Nurd nitrohack-ais523//libnethack/src/hack.c nitrohack-ais523-convict//libnethack/src/hack.c
--- nitrohack-ais523//libnethack/src/hack.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/hack.c 2012-04-27 10:25:45.000000000 -0400
@@ -590,7 +590,8 @@
 }
 if (invent && (inv_weight() + weight_cap() > 600)) {
 if (mode == DO_MOVE)
- pline("You are carrying too much to get through.");
+ if (!Passes_walls)
+ pline("You are carrying too much to get through.");
 return FALSE;
 }
 }
diff -Nurd nitrohack-ais523//libnethack/src/makemon.c nitrohack-ais523-convict//libnethack/src/makemon.c
--- nitrohack-ais523//libnethack/src/makemon.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/makemon.c 2012-04-27 18:56:16.000000000 -0400
@@ -179,6 +179,7 @@
 case PM_LIEUTENANT:
 w1 = rn2(2) ? BROADSWORD : LONG_SWORD;
 break;
+ case PM_PRISON_GUARD:
 case PM_CAPTAIN:
 case PM_WATCH_CAPTAIN:
 w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
@@ -229,6 +230,11 @@
 if (!rn2(2)) curse(otmp);
 mpickobj(mtmp, otmp);
 }
+ } else if (mm == PM_MINER) {
+ (void)mongets(mtmp, PICK_AXE);
+ otmp = mksobj(level, BRASS_LANTERN, TRUE, FALSE);
+ (void) mpickobj(mtmp, otmp);
+ begin_burn(otmp, FALSE);
 }
 break;

@@ -469,6 +475,7 @@

 switch(monsndx(ptr)) {
 case PM_GUARD: mac = -1; break;
+ case PM_PRISON_GUARD: mac = -2; break;
 case PM_SOLDIER: mac = 3; break;
 case PM_SERGEANT: mac = 0; break;
 case PM_LIEUTENANT: mac = -2; break;
@@ -513,6 +520,7 @@
 mongets(mtmp, LEATHER_CLOAK);

 if (ptr != &mons[PM_GUARD] &&
+ ptr != &mons[PM_PRISON_GUARD] &&
 ptr != &mons[PM_WATCHMAN] &&
 ptr != &mons[PM_WATCH_CAPTAIN]) {
 if (!rn2(3)) mongets(mtmp, K_RATION);
diff -Nurd nitrohack-ais523//libnethack/src/mondata.c nitrohack-ais523-convict//libnethack/src/mondata.c
--- nitrohack-ais523//libnethack/src/mondata.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/mondata.c 2012-04-27 10:29:44.000000000 -0400
@@ -511,6 +511,8 @@
 {PM_ORC, PM_ORC_CAPTAIN}, {PM_HILL_ORC, PM_ORC_CAPTAIN},
 {PM_MORDOR_ORC, PM_ORC_CAPTAIN}, {PM_URUK_HAI, PM_ORC_CAPTAIN},
 {PM_SEWER_RAT, PM_GIANT_RAT},
+ {PM_GIANT_RAT, PM_ENORMOUS_RAT},
+ {PM_ENORMOUS_RAT, PM_RODENT_OF_UNUSUAL_SIZE},
 {PM_CAVE_SPIDER, PM_GIANT_SPIDER},
 {PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING},
 {PM_ELF, PM_ELF_LORD}, {PM_WOODLAND_ELF, PM_ELF_LORD},
diff -Nurd nitrohack-ais523//libnethack/src/monmove.c nitrohack-ais523-convict//libnethack/src/monmove.c
--- nitrohack-ais523//libnethack/src/monmove.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/monmove.c 2012-04-27 10:32:57.000000000 -0400
@@ -45,6 +45,13 @@
 if (mtmp->mpeaceful && in_town(u.ux, u.uy) &&
 mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) {

+ if(Role_if(PM_CONVICT) && !Upolyd) {
+ verbalize("%s yells: Hey! You are the one from the wanted poster!",
+ Amonnam(mtmp));
+ angry_guards(!(flags.soundok));
+ stop_occupation();
+ return;
+ }
 if (picking_lock(&x, &y) && IS_DOOR(level->locations[x][y].typ) &&
 (level->locations[x][y].doormask & D_LOCKED)) {

@@ -327,7 +334,8 @@

 /* Demonic Blackmail! */
 if (nearby && mdat->msound == MS_BRIBE &&
- mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) {
+ (monsndx(mdat) != PM_PRISON_GUARD) &&
+ mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) {
 if (multi < 0) return(0); /* wait for you to be able to respond */
 if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
 pline("%s whispers at thin air.",
@@ -346,6 +354,24 @@
 } else if (demon_talk(mtmp)) return 1; /* you paid it off */
 }

+ /* Prison guard extortion */
+ if(nearby && (monsndx(mdat) == PM_PRISON_GUARD) && !mtmp->mpeaceful
+ && !mtmp->mtame && !u.uswallow && (!mtmp->mspec_used)) {
+ long gdemand = 500 * u.ulevel;
+ long goffer = 0;
+
+ pline("%s demands %ld %s to avoid re-arrest.", Amonnam(mtmp),
+ gdemand, currency(gdemand));
+ if ((goffer = bribe(mtmp)) >= gdemand) {
+ verbalize("Good. Now beat it, scum!");
+ mtmp->mpeaceful = 1;
+ set_malign(mtmp);
+ } else {
+ pline("I said %ld!", gdemand);
+ mtmp->mspec_used = 1000;
+ }
+ }
+
 /* the watch will look around and see if you are up to no good :-) */
 if (mdat == &mons[PM_WATCHMAN] || mdat == &mons[PM_WATCH_CAPTAIN])
 watch_on_duty(mtmp);
diff -Nurd nitrohack-ais523//libnethack/src/monst.c nitrohack-ais523-convict//libnethack/src/monst.c
--- nitrohack-ais523//libnethack/src/monst.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/monst.c 2012-04-27 10:38:38.000000000 -0400
@@ -810,6 +810,20 @@
 SIZ(40, 30, 0, MS_SQEEK, MZ_TINY), MR_POISON, 0,
 M1_NOHANDS|M1_POIS|M1_REGEN|M1_CARNIVORE,
 M2_NOPOLY|M2_WERE|M2_HOSTILE, M3_INFRAVISIBLE, CLR_BROWN|HI_ULINE),
+ MON("enormous rat", S_RODENT,
+ LVL(3, 9, 6, 0, 0), (G_GENO|G_SGROUP|1),
+ A(ATTK(AT_BITE, AD_PHYS, 1, 6),
+ NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(200, 100, 0, MS_SQEEK, MZ_SMALL), 0, 0,
+ M1_ANIMAL|M1_NOHANDS|M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
+ CLR_BROWN),
+ MON("rodent of unusual size", S_RODENT,
+ LVL(7, 8, 4, 0, 0), (G_GENO|1),
+ A(ATTK(AT_BITE, AD_PHYS, 2, 6),
+ NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(500, 200, 0, MS_SQEEK, MZ_MEDIUM), 0, 0,
+ M1_ANIMAL|M1_NOHANDS|M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
+ CLR_BROWN),
 MON("rock mole", S_RODENT,
 LVL(3, 3, 0, 20, 0), (G_GENO|2),
 A(ATTK(AT_BITE, AD_PHYS, 1, 6),
@@ -2234,6 +2248,22 @@
 M1_HUMANOID|M1_OMNIVORE,
 M2_NOPOLY|M2_HUMAN|M2_STRONG|M2_COLLECT,
 M3_INFRAVISIBLE, HI_DOMESTIC2),
+ MON("miner", S_HUMAN,
+ LVL(2, 6, 10, 10, 4), (G_GENO|G_NOGEN),
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 8),
+ NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_HUMANOID, MZ_HUMAN), 0, 0,
+ M1_TUNNEL|M1_NEEDPICK|M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_STRONG,
+ M3_INFRAVISIBLE, CLR_GRAY),
+ MON("prison guard", S_HUMAN,
+ LVL(12, 10, 10, 15, -6), G_NOGEN,
+ A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_WEAP, AD_PHYS, 4, 4),
+ NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_BRIBE, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_MERC|M2_STALK|M2_HOSTILE|M2_STRONG|M2_COLLECT,
+ M3_INFRAVISIBLE, HI_METAL),
 MON("wererat", S_HUMAN,
 LVL(2, 12, 10, 10, -7), (1),
 A(ATTK(AT_WEAP, AD_PHYS, 2, 4),
@@ -2475,6 +2505,14 @@
 M3_INFRAVISIBLE|M3_INFRAVISION, CLR_BLUE),
 /* standard demons & devils
 */
+ MON("lava demon", S_DEMON,
+ LVL(12, 12,-8, 40, -7), (G_NOCORPSE|G_NOGEN),
+ A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_BITE, AD_PHYS, 1, 8),
+ ATTK(AT_BITE, AD_FIRE, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_SILENT, MZ_HUMAN), MR_FIRE|MR_POISON, 0,
+ M1_HUMANOID|M1_POIS,
+ M2_NOPOLY|M2_DEMON|M2_STALK|M2_HOSTILE|M2_NASTY|M2_COLLECT,
+ M3_INFRAVISIBLE|M3_INFRAVISION, CLR_RED),
 MON("horned devil", S_DEMON,
 LVL(6, 9, -5, 50, 11), (G_HELL|G_NOCORPSE|2),
 A(ATTK(AT_WEAP, AD_PHYS, 1, 4), ATTK(AT_CLAW, AD_PHYS, 1, 4),
@@ -2483,7 +2521,7 @@
 SIZ(WT_HUMAN, 400, 0, MS_SILENT, MZ_HUMAN), MR_FIRE|MR_POISON, 0,
 M1_POIS|M1_THICK_HIDE,
 M2_DEMON|M2_STALK|M2_HOSTILE|M2_NASTY, M3_INFRAVISIBLE|M3_INFRAVISION,
- CLR_BROWN),
+ CLR_RED),
 #define SEDUCTION_ATTACKS \
 A(ATTK(AT_BITE, AD_SSEX, 2, 6), ATTK(AT_CLAW, AD_PHYS, 1, 3), \
 ATTK(AT_CLAW, AD_PHYS, 1, 3), NO_ATTK, NO_ATTK, NO_ATTK)
@@ -2870,6 +2908,13 @@
 M1_HUMANOID|M1_OMNIVORE,
 M2_NOPOLY|M2_HUMAN|M2_STRONG|M2_FEMALE|M2_COLLECT, M3_INFRAVISIBLE,
 HI_DOMESTIC3),
+ MON("convict", S_HUMAN,
+ LVL(10, 12, 10, 1, 0), G_NOGEN,
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6),
+ NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_HUMANOID, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_STRONG|M2_COLLECT, M3_INFRAVISIBLE, HI_DOMESTIC),
 MON("healer", S_HUMAN,
 LVL(10, 12, 10, 1, 0), G_NOGEN,
 A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
@@ -2984,6 +3029,15 @@
 M2_NOPOLY|M2_HUMAN|M2_PNAME|M2_PEACEFUL|M2_STRONG|M2_MALE|
 M2_COLLECT|M2_MAGIC,
 M3_CLOSE|M3_INFRAVISIBLE, HI_QUEST),
+ MON("Robert the Lifer", S_HUMAN,
+ LVL(20, 12, 0, 40, -20), (G_NOGEN|G_UNIQ),
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6),
+ NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_LEADER, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_PNAME|M2_PEACEFUL|M2_STRONG|M2_MALE|
+ M2_COLLECT|M2_MAGIC,
+ M3_CLOSE|M3_INFRAVISIBLE, HI_DOMESTIC),
 MON("Hippocrates", S_HUMAN,
 LVL(20, 12, 0, 40, 0), (G_NOGEN|G_UNIQ),
 A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
@@ -3115,6 +3169,15 @@
 M2_NOPOLY|M2_HOSTILE|M2_FEMALE|M2_STALK|M2_STRONG|M2_NASTY|
 M2_GREEDY|M2_JEWELS|M2_MAGIC,
 M3_WANTSARTI|M3_WAITFORU|M3_INFRAVISIBLE, HI_QUEST),
+ MON("Warden Arianna", S_HUMAN,
+ LVL(20, 12, 0, 40, -14), (G_NOGEN|G_UNIQ|G_NOCORPSE),
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 25), ATTK(AT_WEAP, AD_PHYS, 1, 25),
+ ATTK(AT_CLAW, AD_SAMU, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_NEMESIS, MZ_HUMAN), MR_FIRE|MR_POISON, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_PNAME|M2_HOSTILE|M2_STRONG|M2_STALK|
+ M2_NASTY|M2_FEMALE|M2_COLLECT|M2_MAGIC,
+ M3_WANTSARTI|M3_WAITFORU|M3_INFRAVISIBLE, HI_LORD),
 MON("Cyclops", S_GIANT,
 LVL(18, 12, 0, 0, -15), (G_NOGEN|G_UNIQ),
 A(ATTK(AT_WEAP, AD_PHYS, 4, 8), ATTK(AT_WEAP, AD_PHYS, 4, 8),
@@ -3235,6 +3298,14 @@
 M1_HUMANOID|M1_OMNIVORE,
 M2_NOPOLY|M2_HUMAN|M2_PEACEFUL|M2_STRONG|M2_COLLECT, M3_INFRAVISIBLE,
 HI_GUARDIAN),
+ MON("inmate", S_HUMAN,
+ LVL(12, 12, 10, 0, 0), G_NOGEN,
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
+ NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_GUARDIAN, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_PEACEFUL|M2_STRONG|M2_COLLECT,
+ M3_INFRAVISIBLE|M3_CLOSE, CLR_BLACK),
 MON("attendant", S_HUMAN,
 LVL(5, 12, 10, 10, 3), G_NOGEN,
 A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
diff -Nurd nitrohack-ais523//libnethack/src/objects.c nitrohack-ais523-convict//libnethack/src/objects.c
--- nitrohack-ais523//libnethack/src/objects.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/objects.c 2012-04-27 10:40:09.000000000 -0400
@@ -383,6 +383,8 @@
 /* shirts */
 ARMOR("Hawaiian shirt", NULL,
 1, 0, 0, 0, 8, 0, 5, 3, 10, 0, ARM_SHIRT, CLOTH, CLR_MAGENTA),
+ARMOR("striped shirt", NULL,
+ 1, 0, 0, 0, 0, 0, 5, 2, 10, 0, ARM_SHIRT, CLOTH, CLR_GRAY),
 ARMOR("T-shirt", NULL,
 1, 0, 0, 0, 2, 0, 5, 2, 10, 0, ARM_SHIRT, CLOTH, CLR_WHITE),

@@ -917,7 +919,7 @@
 OBJECT(OBJ("statue", NULL), BITS(1,0,0,1,0,0,0,0,0,0,0,P_NONE,MINERAL), 0,
 ROCK_CLASS, 900, 0, 2500, 0, 20, 20, 0, 0, 2500, CLR_WHITE),

-OBJECT(OBJ("heavy iron ball", NULL), BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
+OBJECT(OBJ("heavy iron ball", NULL), BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_FLAIL,IRON), 0,
 BALL_CLASS, 1000, 0, 480, 10, 25, 25, 0, 0, 200, HI_METAL),
 /* +d4 when "very heavy" */
 OBJECT(OBJ("iron chain", NULL), BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
diff -Nurd nitrohack-ais523//libnethack/src/options.c nitrohack-ais523-convict//libnethack/src/options.c
--- nitrohack-ais523//libnethack/src/options.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/options.c 2012-04-27 10:44:05.000000000 -0400
@@ -158,6 +158,7 @@
 { "catname", "the name of your (first) cat", OPTTYPE_STRING, {NULL}},
 { "dogname", "the name of your (first) dog", OPTTYPE_STRING, {NULL}},
 { "horsename", "the name of your (first) horse", OPTTYPE_STRING, {NULL}},
+ { "ratname", "the name of your (first) rat (e.g., ratname:Squeak)", OPTTYPE_STRING, {NULL}},
 { "pettype", "your preferred initial pet type", OPTTYPE_ENUM, {0}},

 {NULL, NULL, OPTTYPE_BOOL, { NULL }}
@@ -308,6 +309,7 @@
 find_option(birth_options, "catname")->s.maxlen = PL_PSIZ;
 find_option(birth_options, "dogname")->s.maxlen = PL_PSIZ;
 find_option(birth_options, "horsename")->s.maxlen = PL_PSIZ;
+ find_option(birth_options, "ratname")->s.maxlen = PL_PSIZ;

 /* If no config file exists, these values will not get set until they
 * have already been used during game startup. (-1) is a much better
@@ -638,6 +640,9 @@
 else if (!strcmp("horsename", option->name)) {
 strncpy(horsename, option->value.s, PL_PSIZ);
 }
+ else if (!strcmp("ratname", option->name)) {
+ strncpy(ratname, option->value.s, PL_PSIZ);
+ }
 else if (!strcmp("pettype", option->name)) {
 preferred_pet = (char)option->value.e;
 }
diff -Nurd nitrohack-ais523//libnethack/src/read.c nitrohack-ais523-convict//libnethack/src/read.c
--- nitrohack-ais523//libnethack/src/read.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/read.c 2012-04-27 10:47:04.000000000 -0400
@@ -1605,6 +1605,7 @@

 void punish(struct obj *sobj)
 {
+ struct obj *otmp;
 /* KMH -- Punishment is still okay when you are riding */
 pline("You are being punished for your misbehavior!");
 if (Punished){
@@ -1618,7 +1619,13 @@
 return;
 }
 setworn(mkobj(level, CHAIN_CLASS, TRUE), W_CHAIN);
- setworn(mkobj(level, BALL_CLASS, TRUE), W_BALL);
+ if (((otmp = carrying(HEAVY_IRON_BALL)) != 0)
+ &&(otmp->oartifact == ART_IRON_BALL_OF_LIBERATION)) {
+ setworn(otmp, W_BALL);
+ pline("Your %s chains itself to you!", xname(otmp));
+ } else {
+ setworn(mkobj(level, BALL_CLASS, TRUE), W_BALL);
+ }
 uball->spe = 1; /* special ball (see save) */

 /*
diff -Nurd nitrohack-ais523//libnethack/src/role.c nitrohack-ais523-convict//libnethack/src/role.c
--- nitrohack-ais523//libnethack/src/role.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/role.c 2012-04-27 10:48:59.000000000 -0400
@@ -108,6 +108,32 @@
 { 1, 0, 0, 1, 0, 1 },10, /* Energy */
 0, 12, 0, 1, 8, A_INT, SPE_DIG, -4
 },
+{ {"Convict", 0}, {
+ {"Detainee", 0},
+ {"Inmate", 0},
+ {"Jail-bird",0},
+ {"Prisoner",0},
+ {"Outlaw", 0},
+ {"Crook", 0},
+ {"Desperado", 0},
+ {"Felon", 0},
+ {"Fugitive", 0} },
+ "Ilmater", "Grumbar", "_Tymora", /* Faerunian */
+ "Con", "Castle Waterdeep Dungeon", "the Warden's Level",
+ PM_CONVICT, NON_PM, PM_SEWER_RAT,
+ PM_ROBERT_THE_LIFER, PM_INMATE, PM_WARDEN_ARIANNA,
+ PM_GIANT_BEETLE, PM_SOLDIER_ANT, S_RODENT, S_SPIDER,
+ ART_IRON_BALL_OF_LIBERATION,
+ MH_HUMAN|MH_DWARF|MH_GNOME|MH_ORC | ROLE_MALE|ROLE_FEMALE |
+ ROLE_CHAOTIC,
+ /* Str Int Wis Dex Con Cha */
+ { 10, 7, 7, 7, 13, 6 },
+ { 20, 20, 10, 20, 20, 10 },
+ /* Init Lower Higher */
+ { 8, 0, 0, 8, 0, 0 }, /* Hit points */
+ { 1, 0, 0, 1, 0, 1 },10, /* Energy */
+ -10, 5, 0, 2, 10, A_INT, SPE_TELEPORT_AWAY, -4
+},
 { {"Healer", 0}, {
 {"Rhizotomist", 0},
 {"Empiric", 0},
diff -Nurd nitrohack-ais523//libnethack/src/shk.c nitrohack-ais523-convict//libnethack/src/shk.c
--- nitrohack-ais523//libnethack/src/shk.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/shk.c 2012-04-27 18:58:40.000000000 -0400
@@ -485,6 +485,11 @@
 return;
 }

+ /* Visible striped prison shirt */
+ if ((uarmu && (uarmu->otyp == STRIPED_SHIRT)) && !uarm && !uarmc) {
+ eshkp->pbanned = TRUE;
+ }
+
 rt = level->rooms[*enterstring - ROOMOFFSET].rtype;

 if (ANGRY(shkp)) {
@@ -495,11 +500,12 @@
 } else if (eshkp->robbed) {
 pline("%s mutters imprecations against shoplifters.", shkname(shkp));
 } else {
- verbalize("%s, %s! Welcome%s to %s %s!",
- Hello(shkp), plname,
- eshkp->visitct++ ? " again" : "",
- s_suffix(shkname(shkp)),
- shtypes[rt - SHOPBASE].name);
+ if (!eshkp->pbanned || inside_shop(level, u.ux, u.uy))
+ verbalize("%s, %s! Welcome%s to %s %s!",
+ Hello(shkp), plname,
+ eshkp->visitct++ ? " again" : "",
+ s_suffix(shkname(shkp)),
+ shtypes[rt - SHOPBASE].name);
 }
 /* can't do anything about blocking if teleported in */
 if (!inside_shop(level, u.ux, u.uy)) {
@@ -536,6 +542,9 @@
 "Will you please leave %s outside?" :
 "Leave %s outside.", y_monnam(u.usteed));
 should_block = TRUE;
+ } else if (eshkp->pbanned) {
+ verbalize("I don't sell to your kind here.");
+ should_block = TRUE;
 } else {
 should_block = (Fast && (sobj_at(PICK_AXE, level, u.ux, u.uy) ||
 sobj_at(DWARVISH_MATTOCK, level, u.ux, u.uy)));
@@ -1400,6 +1409,7 @@
 else {
 numsk++;
 taken |= inherits(mtmp, numsk, croaked);
+ ESHK(mtmp)->pbanned = FALSE; /* Un-ban for bones levels */
 }
 }
 }
@@ -2948,6 +2958,7 @@
 uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
 if (uondoor) {
 badinv = (carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK) ||
+ eshkp->pbanned ||
 (Fast && (sobj_at(PICK_AXE, level, u.ux, u.uy) ||
 sobj_at(DWARVISH_MATTOCK, level, u.ux, u.uy))));
 if (satdoor && badinv)
diff -Nurd nitrohack-ais523//libnethack/src/sounds.c nitrohack-ais523-convict//libnethack/src/sounds.c
--- nitrohack-ais523//libnethack/src/sounds.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/sounds.c 2012-04-27 10:55:01.000000000 -0400
@@ -712,10 +712,31 @@
 }
 break;
 case MS_BRIBE:
- if (mtmp->mpeaceful && !mtmp->mtame) {
- demon_talk(mtmp);
- break;
- }
+ if (monsndx(ptr) == PM_PRISON_GUARD) {
+ long gdemand = 500 * u.ulevel;
+ long goffer = 0;
+
+ if (!mtmp->mpeaceful && !mtmp->mtame) {
+ pline("%s demands %ld %s to avoid re-arrest.",
+ Amonnam(mtmp), gdemand, currency(gdemand));
+ if ((goffer = bribe(mtmp)) >= gdemand) {
+ verbl_msg = "Good. Now beat it, scum!";
+ mtmp->mpeaceful = 1;
+ set_malign(mtmp);
+ break;
+ } else {
+ pline("I said %ld!", gdemand);
+ mtmp->mspec_used = 1000;
+ break;
+ }
+ } else {
+ verbl_msg = "Out of my way, scum!"; /* still a jerk */
+ }
+ } else
+ if (mtmp->mpeaceful && !mtmp->mtame) {
+ demon_talk(mtmp);
+ break;
+ }
 /* fall through */
 case MS_CUSS:
 if (!mtmp->mpeaceful)
@@ -881,6 +902,23 @@
 return 0;
 }

+ if (Role_if(PM_CONVICT) && is_rat(mtmp->data) && !mtmp->mpeaceful &&
+ !mtmp->mtame) {
+ pline("You attempt to soothe the %s with chittering sounds.",
+ l_monnam(mtmp));
+ if (rnl(10) < 2) {
+ (void) tamedog(mtmp, (struct obj *) 0);
+ } else {
+ if (rnl(10) > 8) {
+ pline("%s unfortunately ignores your overtures.",
+ Monnam(mtmp));
+ return 0;
+ }
+ mtmp->mpeaceful = 1;
+ set_malign(mtmp);
+ }
+ return 0;
+ }
 return domonnoise(mtmp);
 }

diff -Nurd nitrohack-ais523//libnethack/src/timeout.c nitrohack-ais523-convict//libnethack/src/timeout.c
--- nitrohack-ais523//libnethack/src/timeout.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/timeout.c 2012-04-27 19:01:19.000000000 -0400
@@ -6,6 +6,7 @@

 static void stoned_dialogue(void);
 static void vomiting_dialogue(void);
+static void phasing_dialogue(void);
 static void choke_dialogue(void);
 static void slime_dialogue(void);
 static void slip_or_trip(void);
@@ -40,6 +41,26 @@
 exercise(A_DEX, FALSE);
 }

+static void
+phasing_dialogue()
+{
+ if (Phasing == 15) {
+ if (!Hallucination) {
+ pline("Your body is beginning to feel more solid.");
+ } else {
+ pline("You feel more distant from the spirit world.");
+ }
+ stop_occupation();
+ } else if (Phasing == 1) {
+ if (!Hallucination) {
+ pline("Your body is solid again.");
+ } else {
+ pline("You feel totally separated from the spirit world.");
+ }
+ stop_occupation();
+ }
+}
+
 /* He is getting sicker and sicker prior to vomiting */
 static const char * const vomiting_texts[] = {
 "You are feeling mildly nauseated.", /* 14 */
@@ -176,6 +197,7 @@
 else if (u.uluck < baseluck && (nostone || time_luck > 0))
 u.uluck++;
 }
+ if (Phasing) phasing_dialogue();
 if (u.uinvulnerable) return; /* things past this point could kill you */
 if (Stoned) stoned_dialogue();
 if (Slimed) slime_dialogue();
diff -Nurd nitrohack-ais523//libnethack/src/uhitm.c nitrohack-ais523-convict//libnethack/src/uhitm.c
--- nitrohack-ais523//libnethack/src/uhitm.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/uhitm.c 2012-04-27 10:59:32.000000000 -0400
@@ -255,6 +255,14 @@
 if (is_orc(mtmp->data) && maybe_polyd(is_elf(youmonst.data),
 Race_if (PM_ELF)))
 tmp++;
+ /* Now that iron ball uses a weapon skill (flail), that gives
+ a -4 penalty for unskilled vs no penalty for non-weapon
+ objects. Add 4 to compensate. */
+ if (uwep && (uwep->otyp == HEAVY_IRON_BALL)) {
+ tmp += 4; /* Compensate for flail weapon skill -4
+ penalty for unskilled vs no penalty for
+ non- weapon objects. */
+ }
 if (Role_if(PM_MONK) && !Upolyd) {
 if (uarm) {
 pline("Your armor is rather cumbersome...");
@@ -551,7 +559,7 @@
 } else {
 strcpy(saved_oname, cxname(obj));
 if (obj->oclass == WEAPON_CLASS || is_weptool(obj) ||
- obj->oclass == GEM_CLASS) {
+ obj->oclass == GEM_CLASS || obj->otyp == HEAVY_IRON_BALL) {

 /* is it not a melee weapon? */
 if (/* if you strike with a bow... */
diff -Nurd nitrohack-ais523//libnethack/src/u_init.c nitrohack-ais523-convict//libnethack/src/u_init.c
--- nitrohack-ais523//libnethack/src/u_init.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/u_init.c 2012-04-27 19:07:02.000000000 -0400
@@ -54,6 +54,11 @@
 { LEATHER_ARMOR, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
 { 0, 0, 0, 0, 0 }
 };
+static struct trobj Convict[] = {
+ { ROCK, 0, GEM_CLASS, 1, 0 },
+ { STRIPED_SHIRT, 0, ARMOR_CLASS, 1, 0 },
+ { 0, 0, 0, 0, 0 }
+};
 static const struct trobj Healer[] = {
 { SCALPEL, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
 { LEATHER_GLOVES, 1, ARMOR_CLASS, 1, UNDEF_BLESS },
@@ -292,6 +297,18 @@
 { P_NONE, 0 }
 };

+static const struct def_skill Skill_Con[] = {
+ { P_DAGGER, P_SKILLED }, { P_KNIFE, P_EXPERT },
+ { P_HAMMER, P_SKILLED }, { P_PICK_AXE, P_EXPERT },
+ { P_CLUB, P_EXPERT }, { P_MACE, P_BASIC },
+ { P_DART, P_SKILLED }, { P_FLAIL, P_EXPERT },
+ { P_SHORT_SWORD, P_BASIC }, { P_SLING, P_SKILLED },
+ { P_ATTACK_SPELL, P_BASIC }, { P_ESCAPE_SPELL, P_EXPERT },
+ { P_TWO_WEAPON_COMBAT, P_SKILLED },
+ { P_BARE_HANDED_COMBAT, P_SKILLED },
+ { P_NONE, 0 }
+};
+
 static const struct def_skill Skill_H[] = {
 { P_DAGGER, P_SKILLED }, { P_KNIFE, P_EXPERT },
 { P_SHORT_SWORD, P_SKILLED }, { P_SCIMITAR, P_BASIC },
@@ -590,6 +607,18 @@
 ini_inv(trobj_list, nclist);
 skill_init(Skill_C);
 break;
+ case PM_CONVICT:
+ trobj_list = copy_trobj_list(Convict);
+ ini_inv(trobj_list, nclist);
+ knows_object(SKELETON_KEY);
+ knows_object(GRAPPLING_HOOK);
+ skill_init(Skill_Con);
+ u.uhunger = 200; /* On the verge of hungry */
+ u.ualignbase[A_CURRENT] = u.ualignbase[A_ORIGINAL] =
+ u.ualign.type = A_CHAOTIC; /* Override racial alignment */
+ urace.hatemask |= urace.lovemask; /* Hated by the race's allies */
+ urace.lovemask = 0; /* Convicts are pariahs of their race */
+ break;
 case PM_HEALER:
 u.umoney0 = rn1(1000, 1001);
 ini_inv(Healer, nclist);
@@ -744,7 +773,8 @@
 case PM_ORC:
 /* compensate for generally inferior equipment */
 if (!Role_if (PM_WIZARD))
- ini_inv(Xtra_food, nclist);
+ if (!Role_if(PM_CONVICT))
+ ini_inv(Xtra_food, nclist);
 /* Orcs can recognize all orcish objects */
 knows_object(ORCISH_SHORT_SWORD);
 knows_object(ORCISH_ARROW);
@@ -936,6 +966,9 @@
 is_graystone(obj) && obj->otyp != FLINT) {
 obj->quan = 1L;
 }
+ if (obj->otyp == STRIPED_SHIRT ) {
+ obj->cursed = TRUE;
+ }
 if (trop->trspe != UNDEF_SPE)
 obj->spe = trop->trspe;
 if (trop->trbless != UNDEF_BLESS)
diff -Nurd nitrohack-ais523//libnethack/src/vault.c nitrohack-ais523-convict//libnethack/src/vault.c
--- nitrohack-ais523//libnethack/src/vault.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/vault.c 2012-04-27 11:34:59.000000000 -0400
@@ -265,6 +265,15 @@
 mongone(guard);
 return;
 }
+ if (Role_if(PM_CONVICT) && !Upolyd) {
+ setmangry(guard);
+ verbalize("I saw your pic on the wanted poster!");
+ if (!MON_WEP(guard)) {
+ guard->weapon_check = NEED_HTH_WEAPON;
+ mon_wield_item(guard);
+ }
+ return;
+ }
 if (Strangled || is_silent(youmonst.data) || multi < 0) {
 /* [we ought to record whether this this message has already
 been given in order to vary it upon repeat visits, but
diff -Nurd nitrohack-ais523//libnethack/src/weapon.c nitrohack-ais523-convict//libnethack/src/weapon.c
--- nitrohack-ais523//libnethack/src/weapon.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/weapon.c 2012-04-27 11:35:36.000000000 -0400
@@ -1127,7 +1127,9 @@
 if (!obj)
 /* Not using a weapon */
 return P_BARE_HANDED_COMBAT;
- if (obj->oclass != WEAPON_CLASS && obj->oclass != TOOL_CLASS &&
+ if ((obj->otyp == HEAVY_IRON_BALL) && Role_if(PM_CONVICT))
+ return objects[obj->otyp].oc_skill;
+ if (obj->oclass != WEAPON_CLASS && obj->oclass != TOOL_CLASS &&
 obj->oclass != GEM_CLASS)
 /* Not a weapon, weapon-tool, or ammo */
 return P_NONE;
diff -Nurd nitrohack-ais523//README-convict.txt nitrohack-ais523-convict//README-convict.txt
--- nitrohack-ais523//README-convict.txt 1969-12-31 19:00:00.000000000 -0500
+++ nitrohack-ais523-convict//README-convict.txt 2012-04-27 09:51:30.000000000 -0400
@@ -0,0 +1,115 @@
+Convict role patch v0.7
+Karl Garrison <email@example.com>
+Originally for NetHack 3.4.3
+Ported to NetHack4 by Jonadab
+
+
+Non-spoiler Information
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This patch adds a new role to NetHack: the Convict. The Convict is an
+escaped prisoner who seeks to redeem himself by seeking the Amulet in
+the Dungeons of Doom. They start out with a striped shirt, some rocks,
+and heavy iron ball chained to them. A trusty sewer rat accompanies
+the Convict into the dungeon: a companion from his days of
+imprisonment. Convicts have an affinity with rats, but many other
+animals do not trust him.
+
+Race: Human, Dwarf, Gnome, or Orc
+Alignment: Chaotic
+Deity: Tymora (Forgotten Realms)
+
+New configuration file option: ratname. Example:
+
+OPTIONS=ratname:Squeak
+
+
+
+
+
+
+
+
+
+
+
+
+
+Spoiler Information
+~~~~~~~~~~~~~~~~~~~
+
+There may be a few surprises to this role for the unaware. They start
+with a negative alignment ("You have transgressed"). This means that a
+Convict will not be able to pray successfully early on. Some time and
+killing of monsters will make up for this before too long, though.
+They also start the game on the verge of hungry, which also makes the
+very early game challenging for Convicts. On the bright side, it takes
+them longer to progress from hungry to weak, etc, due to their higher
+tolerance for irregular meals.
+
+Stats: Excellent CON, good STR, average DEX and INT, poor WIS and CHA.
+
+Intrinsics: Sick resistance at level 1 (due to exposure to unhealthy
+prison conditions, as well as bad food), poison resistance at level 7,
+search at level 20.
+
+Pet: The convict starts with a sewer rat, which quickly advances to a
+giant rat, and can eventually become an enormous rat, then a rodent of
+unusual size. Convicts can tame rats with food, but not domestic
+amimals like dogs and cats. The latter are instead made peaceful.
+
+Convicts can also usually make rats peaceful and occasionally tame by
+#chatting with them.
+
+Iron Ball: The Convict starts with a heavy iron ball chained to him, as
+if he had read a scroll of punishment. Since he starts with no real
+weapons apart from his rocks, he may wish to wield it as a weapon.
+Convicts (and only Convicts) will practice the flail skill when he
+weilds an iron ball. Advancing flail skill improves his chance to hit,
+and prevents him from automatically falling down the stairs if one is
+chained to him, so long as he is currently wielding it.
+
+Striped Shirt: Shopkeepers who can see the Convict wearing his striped
+shirt will recognize the player as an escaped prisoner, and will ban
+him from the shop. Even if he later hides the shirt, that shopkeeper
+will remember the player.
+
+Guards: Guards (town watch and vault guards) who see a Convict will
+recognize him from wanted posters, and immediately become hostile.
+
+Hunger: Convicts start on the verge of hungry, but the effects of
+hunger kick in a bit more slowly for this role, due to their learned
+tolerance of inadequate nutrition.
+
+Weapon Skills:
+
+Basic: mace, short sword
+
+Skilled: dagger, dart, hammer, sling, two-weapon combat
+bare-handed combat
+
+Expert: club, flail, knife, pick-axe
+
+
+Spellcasting Skills:
+
+Basic: Matter
+
+Expert: Escape
+
+
+Luck Sword: This is a Chaotic broadsword which acts as a luckstone, and
+is the Convict's first sacrifice gift.
+
+The Quest: The Convict quest has the player return to Castle
+Waterdeep's dungeons in order to retrieve the Iron Ball of Liberation
+from the corrupted Warden Arianna on behalf of their quest leader,
+Robert the Lifer.
+
+The Iron Ball of Liberation: This is a (slightly lighter) heavy iron
+ball that grants magic resistance, stealth, searching and warning.
+When invoked, it allows phasing for a limited time (the ability to
+walk through walls/stone like a xorn). The downsides are its weight
+(almost as heavy as a normal iron ball) and the fact that it chains
+itself to the player everytime its power is invoked.
+

Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-58960949084901447712012-04-20T20:26:00.001-04:002012-04-20T20:26:20.295-04:00Management Concept: No ChairsI have concocted a business management concept worthy of Scott Adams. The more I think about this, the more I believe it could really catch on: more than open-plan offices (no walls), more than Six Sigma, more than flattening out the org chart, perhaps even more than synergy.

This concept is so simple, it beggars the imagination: eliminate all chairs (and stools and benches and anything else designed to be sat on) from the entire enterprise.

Yet that simplicity is deceptive, because the concept has a lot of implications. Here are just a few of the things it has going for it...

The sales pitch to upper management is so obvious I scarcely even need to explain it. The productivity benefits of not letting workers sit down while working are so straightforward that the English language has embodied them in an idiom, "sit down on the job", which means, roughly, "not work when one is supposed to be working". I could write pages and pages about how to pitch to management the concept that standing improves productivity, but I don't need to write it all out, because if you stop and think about it for a little while you already know exactly what kinds of things I would say.

Convincing employees to buck up and take it (as opposed to rioting in the hallways) would be a little harder, but there are a number of obvious lines of reasoning that can be used. For starters, any HR manager worth his benefits package ought to be able to stand there with a straight face and say that it'll actually be better for the employees (once they get warmed up to it) because sitting all the time contributes to the sedentary lifestyle that is responsible for most of the major health conditions that plague the developed world. Employees may think they *want* to sit all day, but it's not actually *good* for them, the HR guy says, and if he's any good at all it's almost impossible to be sure he doesn't actually believe this line of reasoning. You can also argue that throughout virtually the entire blue-collar world (err, but you don't say it that way, you say "many industries" or somesuch) workers take standing on the job for granted and don't even think to complain about it because it's Just How Things Are Done. (This has the virtue of being undeniably true, and even employees who are fairly sure it's completely irrelevant will generally have a difficult time articulating clearly WHY it's irrelevant.) If they can do it, you argue, so can we, and with that stroke you put anyone with self-esteem issues instantly on the defensive. Finally, you can appeal to the worker's ego by arguing that such a policy will build a better working environment by helping to encourage the laziest 5% of employees (which almost nobody will admit to being, even to themselves) to seek opportunities elsewhere. But the real clincher for employee compliance is, there's really no good way for them to play the Ghandi card (i.e., just peacefully cooperate as incompletely as possible). When there are no chairs, there are no chairs, and even if an employee brings in a canvas folding chair from home, it won't be the right height for the new furniture.

That brings us to the next point: the "no chairs" school of management does not allow for dipping your toes in the water. It's both feet or nothing. You can subject most of your corporate practices to Six Sigma and yet leave a few well-established procedures unmolested, but you can't do most of your work with no chairs in the building and then go back to using the chairs when it suits. Not only are the chairs themselves gone, but all the furniture (desks, meeting tables, everything) has been replaced with standing-height equivalents. Sitting down would put your head under the table. When you go to a no-chairs office, you're automatically fully committed to making it work.Jonadabhttp://firstname.lastname@example.com:blogger.com,1999:blog-8954176568680546255.post-44659864271242036632012-04-20T19:49:00.000-04:002012-04-20T19:49:18.330-04:00Preposition Chart

I found myself in a situation (in an online venue) wherein I wanted to refer to this chart, but the site in question didn't provide an easy way for me to attach an image to my message. So I'm posting it up here. This is a visual chart depicting several common English prepositions.

The chart is inspired by a similar one that William D. Mounce used to explain Greek prepositions in his excellent grammar (which I highly recommend to anyone who has even a slight interest in Greek in particular, dead languages in general, or the etymologies of English words; it is hands down the best textbook I have ever encountered, on any subject).
Jonadabhttp://email@example.com:blogger.com,1999:blog-8954176568680546255.post-22113575758051412222012-02-20T21:17:00.006-05:002012-02-20T21:30:37.713-05:00All Made Out of WinOkay, so my last set of lyrics turned out kind of emotionally down. I didn't set out to make them that way (and wasn't even in a down mood when I wrote them -- a weird mood, yes), but that's how they landed. So lest I present myself as some kind of bizarre incoherent emo-depressive nitwit, I wrote another set of lyrics. (These, no doubt, will still make me look like a bizarre incoherent nitwit, but in a much more upbeat way.) So, umm, here they are.

Yo, put me in a trebuchet and launch me to the stratosphere:
I'm gonna have some fun today, and then I'm gettin' outa here.
I've got a lot of gumption, and I'm gonna raise some ruckus now,
'Cause if I gain some traction I can bust it all up anyhow.
The secret of contentment isn't havin' things or doin' stuff.
You follow that old siren and you never ever have enough.
 Hey, take me to the river.
 Put me in a basket, or
 Lock me in a tower.
I'm gonna prosper yet.

I'm always feelin' happy when my mojo gets to flowin' good.
A billion-dollar industry has taken over Hollywood,
But nevermind the critics, we're a celebratin' irony,
'Cause once we have the hutzpah we can write an awesome comedy.
Forget about the dazzle, nevermind about the cam'ra work:
We'll shoot it in a castle, and we'll use the spoon and skip the fork.
 Hey, show me all the money.
 Livin' out of pocket, I've
 Never had a problem.
Now, tell me your excuse.

Our attitude is everything, so I am gonna celebrate.
An institute of joy has really drawn me to matriculate.
I'll never let my circumstances rule my mind or get me down,
And if I ever graduate then count on me to go to town.
I'm singin' and I'm dancin' and I'm tellin' lots of corny jokes.
Now tell me just what imag'ry my energizing rhyme invokes.
 Hey, let me lift your spirits.
 Lookin' on the bright side, we're
 Tackle-in' the issue.
I'm all made out of win.

[Musical bridge.]

Take me to the river.
Put me in a basket.
Lock me in a tower.
Show me all the money.
Livin' out of pocket.
Never had a problem.
Let me lift your spirits.
Lookin' on the bright side.
Tackle-in' the issue.

[Short musical interlude.]

I'm gonna prosper yet.
I don't need no excuse.
I'm all made out of win.
All made out of win.
All made out of win.Jonadabhttp://firstname.lastname@example.com