Boulder as '0' patch
Lars Huttar, lars_huttar at mail dot com

Boulders in NetHack are symbolized by '`', by analogy with statues.
There are some advantages to using '0' instead, the symbol shared by
iron balls.  The zero fills the character square, representing the space
boulders take up, with the result that player interactions with a boulder
are visually more intuitive: it's easy to see why a player and a boulder
can't fit in the same space.

This also makes Sokoban easier on the eyes, by increasing the contrast
between empty squares '.' and boulders, and by better indicating the
boundaries of each boulder (occupying the whole character cell instead
of just the top few pixel lines).

Compare:

                                -------- ------
                                |<|@...---....|
                                |^|-.``....`..|
                                |^||..``|.`.`.|
                                |^||....|.....|
                                |^|------`----|
                                |^|    |......|
                                |^------......|
                                |..^^^^````...|
                                |..-----......|
                                ----   --------
vs.

                                -------- ------
                                |<|@...---....|
                                |^|-.00....0..|
                                |^||..00|.0.0.|
                                |^||....|.....|
                                |^|------0----|
                                |^|    |......|
                                |^------......|
                                |..^^^^0000...|
                                |..-----......|
                                ----   --------

After using this kind of display, I find it hard to go back to '`'.

The code changes are further-reaching than I'd expected.  In order to
change the symbol for boulders I had to move them from ROCK_CLASS to
BALL_CLASS.  This required a number of adjustments having to do with
the fact that BALL_CLASS is no longer a single-element class: it now
contains both iron balls and boulders, while ROCK_CLASS now consists
only of statues.

After making these changes I've tested and played the modified nethack
for several months and have encountered no problems.  (And before someone
asks: no, you can't polymorph your heavy iron ball into a boulder. :-)  )

I hope this adds to your enjoyment of NetHack.

Lars
lars_huttar at mail dot com

diff -c -r nethack-3.3.1-orig/dat/endgame.des nethack-3.3.1/dat/endgame.des
*** nethack-3.3.1-orig/dat/endgame.des	Tue Dec 21 20:27:08 1999
--- nethack-3.3.1/dat/endgame.des	Sat Apr  7 20:29:30 2001
***************
*** 121,127 ****
  MONSTER:'E',"earth elemental",(04,17),hostile
  MONSTER:'E',"earth elemental",(04,18),hostile

! OBJECT:'`',"boulder",random


  MAZE:"air",' '
--- 121,127 ----
  MONSTER:'E',"earth elemental",(04,17),hostile
  MONSTER:'E',"earth elemental",(04,18),hostile

! OBJECT:'0',"boulder",random


  MAZE:"air",' '
***************
*** 364,374 ****
  MONSTER:':',"salamander",random,hostile
  MONSTER:':',"salamander",random,hostile

! OBJECT:'`',"boulder",random
! OBJECT:'`',"boulder",random
! OBJECT:'`',"boulder",random
! OBJECT:'`',"boulder",random
! OBJECT:'`',"boulder",random


  MAZE:"water",' '
--- 364,374 ----
  MONSTER:':',"salamander",random,hostile
  MONSTER:':',"salamander",random,hostile

! OBJECT:'0',"boulder",random
! OBJECT:'0',"boulder",random
! OBJECT:'0',"boulder",random
! OBJECT:'0',"boulder",random
! OBJECT:'0',"boulder",random


  MAZE:"water",' '
diff -c -r nethack-3.3.1-orig/dat/gehennom.des
nethack-3.3.1/dat/gehennom.des
*** nethack-3.3.1-orig/dat/gehennom.des	Thu May 11 17:18:12 2000
--- nethack-3.3.1/dat/gehennom.des	Sat Apr  7 20:30:42 2001
***************
*** 167,173 ****
  }}}}.}}}
  }}}}}}}}
  ENDMAP
! OBJECT:'`',"boulder",random
  GEOMETRY:right,top
  MAP
  }}}}}}}}
--- 167,173 ----
  }}}}.}}}
  }}}}}}}}
  ENDMAP
! OBJECT:'0',"boulder",random
  GEOMETRY:right,top
  MAP
  }}}}}}}}
***************
*** 176,182 ****
  }}...}}}
  }}}}}}}}
  ENDMAP
! OBJECT:'`',"boulder",random
  # lair
  GEOMETRY:center,center
  MAP
--- 176,182 ----
  }}...}}}
  }}}}}}}}
  ENDMAP
! OBJECT:'0',"boulder",random
  # lair
  GEOMETRY:center,center
  MAP
***************
*** 261,267 ****
  OBJECT:'%',random,random
  OBJECT:'%',random,random
  OBJECT:'%',random,random
! OBJECT:'`',"boulder",random
  # Some traps
  TRAP:"sleep gas",random
  TRAP:"sleep gas",random
--- 261,267 ----
  OBJECT:'%',random,random
  OBJECT:'%',random,random
  OBJECT:'%',random,random
! OBJECT:'0',"boulder",random
  # Some traps
  TRAP:"sleep gas",random
  TRAP:"sleep gas",random
***************
*** 303,332 ****
  BRANCH:levregion(01,00,12,20),levregion(20,01,70,20)
  TELEPORT_REGION:levregion(01,00,12,20),levregion(20,01,70,20)
  # Wall "ruins"
! OBJECT:'`',"boulder",(19,02)
! OBJECT:'`',"boulder",(20,02)
! OBJECT:'`',"boulder",(21,02)
! OBJECT:'`',"boulder",(36,02)
! OBJECT:'`',"boulder",(36,03)
! OBJECT:'`',"boulder",(06,04)
! OBJECT:'`',"boulder",(05,05)
! OBJECT:'`',"boulder",(06,05)
! OBJECT:'`',"boulder",(07,05)
! OBJECT:'`',"boulder",(39,05)
! OBJECT:'`',"boulder",(08,08)
! OBJECT:'`',"boulder",(09,08)
! OBJECT:'`',"boulder",(10,08)
! OBJECT:'`',"boulder",(11,08)
! OBJECT:'`',"boulder",(06,10)
! OBJECT:'`',"boulder",(05,11)
! OBJECT:'`',"boulder",(06,11)
! OBJECT:'`',"boulder",(07,11)
! OBJECT:'`',"boulder",(21,11)
! OBJECT:'`',"boulder",(21,12)
! OBJECT:'`',"boulder",(13,13)
! OBJECT:'`',"boulder",(14,13)
! OBJECT:'`',"boulder",(15,13)
! OBJECT:'`',"boulder",(14,14)
  # Doors
  DOOR:closed,(23,02)
  DOOR:open,(31,03)
--- 303,332 ----
  BRANCH:levregion(01,00,12,20),levregion(20,01,70,20)
  TELEPORT_REGION:levregion(01,00,12,20),levregion(20,01,70,20)
  # Wall "ruins"
! OBJECT:'0',"boulder",(19,02)
! OBJECT:'0',"boulder",(20,02)
! OBJECT:'0',"boulder",(21,02)
! OBJECT:'0',"boulder",(36,02)
! OBJECT:'0',"boulder",(36,03)
! OBJECT:'0',"boulder",(06,04)
! OBJECT:'0',"boulder",(05,05)
! OBJECT:'0',"boulder",(06,05)
! OBJECT:'0',"boulder",(07,05)
! OBJECT:'0',"boulder",(39,05)
! OBJECT:'0',"boulder",(08,08)
! OBJECT:'0',"boulder",(09,08)
! OBJECT:'0',"boulder",(10,08)
! OBJECT:'0',"boulder",(11,08)
! OBJECT:'0',"boulder",(06,10)
! OBJECT:'0',"boulder",(05,11)
! OBJECT:'0',"boulder",(06,11)
! OBJECT:'0',"boulder",(07,11)
! OBJECT:'0',"boulder",(21,11)
! OBJECT:'0',"boulder",(21,12)
! OBJECT:'0',"boulder",(13,13)
! OBJECT:'0',"boulder",(14,13)
! OBJECT:'0',"boulder",(15,13)
! OBJECT:'0',"boulder",(14,14)
  # Doors
  DOOR:closed,(23,02)
  DOOR:open,(31,03)
diff -c -r nethack-3.3.1-orig/dat/medusa.des nethack-3.3.1/dat/medusa.des
*** nethack-3.3.1-orig/dat/medusa.des	Wed Mar  8 19:58:12 2000
--- nethack-3.3.1/dat/medusa.des	Sat Apr  7 20:30:54 2001
***************
*** 164,172 ****
  CONTAINER:'`',"statue",(65,10)
  CONTAINER:'`',"statue",(64,11)
  CONTAINER:'`',"statue",(65,11)
! OBJECT:'`',"boulder",(04,04)
  OBJECT:'/',random,(52,09)
! OBJECT:'`',"boulder",(52,09)
  OBJECT:random,random,random
  OBJECT:random,random,random
  OBJECT:random,random,random
--- 164,172 ----
  CONTAINER:'`',"statue",(65,10)
  CONTAINER:'`',"statue",(64,11)
  CONTAINER:'`',"statue",(65,11)
! OBJECT:'0',"boulder",(04,04)
  OBJECT:'/',random,(52,09)
! OBJECT:'0',"boulder",(52,09)
  OBJECT:random,random,random
  OBJECT:random,random,random
  OBJECT:random,random,random
diff -c -r nethack-3.3.1-orig/dat/sokoban.des nethack-3.3.1/dat/sokoban.des
*** nethack-3.3.1-orig/dat/sokoban.des	Wed Aug  9 13:44:22 2000
--- nethack-3.3.1/dat/sokoban.des	Sat Apr  7 20:31:28 2001
***************
*** 58,75 ****
  NON_PASSWALL:(00,00,13,12)

  # Boulders
! OBJECT:'`',"boulder",(02,02)
! OBJECT:'`',"boulder",(02,03)
  #
! OBJECT:'`',"boulder",(10,02)
! OBJECT:'`',"boulder",(09,03)
! OBJECT:'`',"boulder",(10,04)
! #
! OBJECT:'`',"boulder",(08,07)
! OBJECT:'`',"boulder",(09,08)
! OBJECT:'`',"boulder",(09,09)
! OBJECT:'`',"boulder",(08,10)
! OBJECT:'`',"boulder",(10,10)

  # Traps
  TRAP:"pit",(03,06)
--- 58,75 ----
  NON_PASSWALL:(00,00,13,12)

  # Boulders
! OBJECT:'0',"boulder",(02,02)
! OBJECT:'0',"boulder",(02,03)
  #
! OBJECT:'0',"boulder",(10,02)
! OBJECT:'0',"boulder",(09,03)
! OBJECT:'0',"boulder",(10,04)
! #
! OBJECT:'0',"boulder",(08,07)
! OBJECT:'0',"boulder",(09,08)
! OBJECT:'0',"boulder",(09,09)
! OBJECT:'0',"boulder",(08,10)
! OBJECT:'0',"boulder",(10,10)

  # Traps
  TRAP:"pit",(03,06)
***************
*** 119,138 ****
  NON_PASSWALL:(00,00,14,10)

  # Boulders
! OBJECT:'`',"boulder",(05,02)
! OBJECT:'`',"boulder",(06,02)
! OBJECT:'`',"boulder",(06,03)
! OBJECT:'`',"boulder",(07,03)
! #
! OBJECT:'`',"boulder",(09,05)
! OBJECT:'`',"boulder",(10,03)
! OBJECT:'`',"boulder",(11,02)
! OBJECT:'`',"boulder",(12,03)
! #
! OBJECT:'`',"boulder",(07,08)
! OBJECT:'`',"boulder",(08,08)
! OBJECT:'`',"boulder",(09,08)
! OBJECT:'`',"boulder",(10,08)

  # Traps
  TRAP:"pit",(01,02)
--- 119,138 ----
  NON_PASSWALL:(00,00,14,10)

  # Boulders
! OBJECT:'0',"boulder",(05,02)
! OBJECT:'0',"boulder",(06,02)
! OBJECT:'0',"boulder",(06,03)
! OBJECT:'0',"boulder",(07,03)
! #
! OBJECT:'0',"boulder",(09,05)
! OBJECT:'0',"boulder",(10,03)
! OBJECT:'0',"boulder",(11,02)
! OBJECT:'0',"boulder",(12,03)
! #
! OBJECT:'0',"boulder",(07,08)
! OBJECT:'0',"boulder",(08,08)
! OBJECT:'0',"boulder",(09,08)
! OBJECT:'0',"boulder",(10,08)

  # Traps
  TRAP:"pit",(01,02)
***************
*** 186,214 ****
  NON_PASSWALL:(00,00,28,11)

  # Boulders
! OBJECT:'`',"boulder",(03,02)
! OBJECT:'`',"boulder",(04,02)
  #
! OBJECT:'`',"boulder",(06,02)
! OBJECT:'`',"boulder",(06,03)
! OBJECT:'`',"boulder",(07,02)
! #
! OBJECT:'`',"boulder",(03,06)
! OBJECT:'`',"boulder",(02,07)
! OBJECT:'`',"boulder",(03,07)
! OBJECT:'`',"boulder",(03,08)
! OBJECT:'`',"boulder",(02,09)
! OBJECT:'`',"boulder",(03,09)
! OBJECT:'`',"boulder",(04,09)
! #
! OBJECT:'`',"boulder",(06,07)
! OBJECT:'`',"boulder",(06,09)
! OBJECT:'`',"boulder",(08,07)
! OBJECT:'`',"boulder",(08,10)
! OBJECT:'`',"boulder",(09,08)
! OBJECT:'`',"boulder",(09,09)
! OBJECT:'`',"boulder",(10,07)
! OBJECT:'`',"boulder",(10,10)

  # Traps
  TRAP:"hole",(12,10)
--- 186,214 ----
  NON_PASSWALL:(00,00,28,11)

  # Boulders
! OBJECT:'0',"boulder",(03,02)
! OBJECT:'0',"boulder",(04,02)
  #
! OBJECT:'0',"boulder",(06,02)
! OBJECT:'0',"boulder",(06,03)
! OBJECT:'0',"boulder",(07,02)
! #
! OBJECT:'0',"boulder",(03,06)
! OBJECT:'0',"boulder",(02,07)
! OBJECT:'0',"boulder",(03,07)
! OBJECT:'0',"boulder",(03,08)
! OBJECT:'0',"boulder",(02,09)
! OBJECT:'0',"boulder",(03,09)
! OBJECT:'0',"boulder",(04,09)
! #
! OBJECT:'0',"boulder",(06,07)
! OBJECT:'0',"boulder",(06,09)
! OBJECT:'0',"boulder",(08,07)
! OBJECT:'0',"boulder",(08,10)
! OBJECT:'0',"boulder",(09,08)
! OBJECT:'0',"boulder",(09,09)
! OBJECT:'0',"boulder",(10,07)
! OBJECT:'0',"boulder",(10,10)

  # Traps
  TRAP:"hole",(12,10)
***************
*** 264,285 ****
  NON_PASSWALL:(00,00,25,13)

  # Boulders
! OBJECT:'`',"boulder",(02,03)
! OBJECT:'`',"boulder",(08,03)
! OBJECT:'`',"boulder",(09,04)
! OBJECT:'`',"boulder",(02,05)
! OBJECT:'`',"boulder",(04,05)
! OBJECT:'`',"boulder",(09,05)
! OBJECT:'`',"boulder",(02,06)
! OBJECT:'`',"boulder",(05,06)
! OBJECT:'`',"boulder",(06,07)
! OBJECT:'`',"boulder",(03,08)
! OBJECT:'`',"boulder",(07,08)
! OBJECT:'`',"boulder",(05,09)
! OBJECT:'`',"boulder",(10,09)
! OBJECT:'`',"boulder",(07,10)
! OBJECT:'`',"boulder",(10,10)
! OBJECT:'`',"boulder",(03,11)

  # Traps
  TRAP:"hole",(12,10)
--- 264,285 ----
  NON_PASSWALL:(00,00,25,13)

  # Boulders
! OBJECT:'0',"boulder",(02,03)
! OBJECT:'0',"boulder",(08,03)
! OBJECT:'0',"boulder",(09,04)
! OBJECT:'0',"boulder",(02,05)
! OBJECT:'0',"boulder",(04,05)
! OBJECT:'0',"boulder",(09,05)
! OBJECT:'0',"boulder",(02,06)
! OBJECT:'0',"boulder",(05,06)
! OBJECT:'0',"boulder",(06,07)
! OBJECT:'0',"boulder",(03,08)
! OBJECT:'0',"boulder",(07,08)
! OBJECT:'0',"boulder",(05,09)
! OBJECT:'0',"boulder",(10,09)
! OBJECT:'0',"boulder",(07,10)
! OBJECT:'0',"boulder",(10,10)
! OBJECT:'0',"boulder",(03,11)

  # Traps
  TRAP:"hole",(12,10)
***************
*** 331,353 ****
  NON_PASSWALL:(00,00,19,11)

  # Boulders
! OBJECT:'`',"boulder",(02,02)
! OBJECT:'`',"boulder",(03,02)
  #
! OBJECT:'`',"boulder",(05,03)
! OBJECT:'`',"boulder",(07,03)
! OBJECT:'`',"boulder",(07,02)
! OBJECT:'`',"boulder",(08,02)
! #
! OBJECT:'`',"boulder",(10,03)
! OBJECT:'`',"boulder",(11,03)
! #
! OBJECT:'`',"boulder",(02,07)
! OBJECT:'`',"boulder",(02,08)
! OBJECT:'`',"boulder",(03,09)
  #
! OBJECT:'`',"boulder",(05,07)
! OBJECT:'`',"boulder",(06,06)

  # Traps
  TRAP:"hole",(08,09)
--- 331,353 ----
  NON_PASSWALL:(00,00,19,11)

  # Boulders
! OBJECT:'0',"boulder",(02,02)
! OBJECT:'0',"boulder",(03,02)
  #
! OBJECT:'0',"boulder",(05,03)
! OBJECT:'0',"boulder",(07,03)
! OBJECT:'0',"boulder",(07,02)
! OBJECT:'0',"boulder",(08,02)
! #
! OBJECT:'0',"boulder",(10,03)
! OBJECT:'0',"boulder",(11,03)
! #
! OBJECT:'0',"boulder",(02,07)
! OBJECT:'0',"boulder",(02,08)
! OBJECT:'0',"boulder",(03,09)
  #
! OBJECT:'0',"boulder",(05,07)
! OBJECT:'0',"boulder",(06,06)

  # Traps
  TRAP:"hole",(08,09)
***************
*** 397,418 ****
  NON_PASSWALL:(00,00,19,12)

  # Boulders
! OBJECT:'`',"boulder",(04,02)
! OBJECT:'`',"boulder",(04,03)
! OBJECT:'`',"boulder",(05,03)
! OBJECT:'`',"boulder",(07,03)
! OBJECT:'`',"boulder",(08,03)
! OBJECT:'`',"boulder",(02,04)
! OBJECT:'`',"boulder",(03,04)
! OBJECT:'`',"boulder",(05,05)
! OBJECT:'`',"boulder",(06,06)
! OBJECT:'`',"boulder",(09,06)
! OBJECT:'`',"boulder",(03,07)
! OBJECT:'`',"boulder",(04,07)
! OBJECT:'`',"boulder",(07,07)
! OBJECT:'`',"boulder",(06,09)
! OBJECT:'`',"boulder",(05,10)
! OBJECT:'`',"boulder",(05,11)

  # Traps
  TRAP:"hole",(07,11)
--- 397,418 ----
  NON_PASSWALL:(00,00,19,12)

  # Boulders
! OBJECT:'0',"boulder",(04,02)
! OBJECT:'0',"boulder",(04,03)
! OBJECT:'0',"boulder",(05,03)
! OBJECT:'0',"boulder",(07,03)
! OBJECT:'0',"boulder",(08,03)
! OBJECT:'0',"boulder",(02,04)
! OBJECT:'0',"boulder",(03,04)
! OBJECT:'0',"boulder",(05,05)
! OBJECT:'0',"boulder",(06,06)
! OBJECT:'0',"boulder",(09,06)
! OBJECT:'0',"boulder",(03,07)
! OBJECT:'0',"boulder",(04,07)
! OBJECT:'0',"boulder",(07,07)
! OBJECT:'0',"boulder",(06,09)
! OBJECT:'0',"boulder",(05,10)
! OBJECT:'0',"boulder",(05,11)

  # Traps
  TRAP:"hole",(07,11)
***************
*** 468,494 ****
  NON_PASSWALL:(00,00,25,17)

  # Boulders
! OBJECT:'`',"boulder",(03,05)
! OBJECT:'`',"boulder",(05,05)
! OBJECT:'`',"boulder",(07,05)
! OBJECT:'`',"boulder",(09,05)
! OBJECT:'`',"boulder",(11,05)
! #
! OBJECT:'`',"boulder",(04,07)
! OBJECT:'`',"boulder",(04,08)
! OBJECT:'`',"boulder",(06,07)
! OBJECT:'`',"boulder",(09,07)
! OBJECT:'`',"boulder",(11,07)
! #
! OBJECT:'`',"boulder",(03,12)
! OBJECT:'`',"boulder",(04,10)
! OBJECT:'`',"boulder",(05,12)
! OBJECT:'`',"boulder",(06,10)
! OBJECT:'`',"boulder",(07,11)
! OBJECT:'`',"boulder",(08,10)
! OBJECT:'`',"boulder",(09,12)
  #
! OBJECT:'`',"boulder",(03,14)

  # Traps
  TRAP:"hole",(08,01)
--- 468,494 ----
  NON_PASSWALL:(00,00,25,17)

  # Boulders
! OBJECT:'0',"boulder",(03,05)
! OBJECT:'0',"boulder",(05,05)
! OBJECT:'0',"boulder",(07,05)
! OBJECT:'0',"boulder",(09,05)
! OBJECT:'0',"boulder",(11,05)
! #
! OBJECT:'0',"boulder",(04,07)
! OBJECT:'0',"boulder",(04,08)
! OBJECT:'0',"boulder",(06,07)
! OBJECT:'0',"boulder",(09,07)
! OBJECT:'0',"boulder",(11,07)
! #
! OBJECT:'0',"boulder",(03,12)
! OBJECT:'0',"boulder",(04,10)
! OBJECT:'0',"boulder",(05,12)
! OBJECT:'0',"boulder",(06,10)
! OBJECT:'0',"boulder",(07,11)
! OBJECT:'0',"boulder",(08,10)
! OBJECT:'0',"boulder",(09,12)
  #
! OBJECT:'0',"boulder",(03,14)

  # Traps
  TRAP:"hole",(08,01)
***************
*** 556,583 ****
  NON_PASSWALL:(00,00,25,16)

  # Boulders
! OBJECT:'`',"boulder",(04,04)
! OBJECT:'`',"boulder",(02,06)
! OBJECT:'`',"boulder",(03,06)
! OBJECT:'`',"boulder",(04,07)
! OBJECT:'`',"boulder",(05,07)
! OBJECT:'`',"boulder",(02,08)
! OBJECT:'`',"boulder",(05,08)
! OBJECT:'`',"boulder",(03,09)
! OBJECT:'`',"boulder",(04,09)
! OBJECT:'`',"boulder",(03,10)
! OBJECT:'`',"boulder",(05,10)
! OBJECT:'`',"boulder",(06,12)
! #
! OBJECT:'`',"boulder",(07,14)
! #
! OBJECT:'`',"boulder",(11,05)
! OBJECT:'`',"boulder",(12,06)
! OBJECT:'`',"boulder",(10,07)
! OBJECT:'`',"boulder",(11,07)
! OBJECT:'`',"boulder",(10,08)
! OBJECT:'`',"boulder",(12,09)
! OBJECT:'`',"boulder",(11,10)

  # Traps
  TRAP:"hole",(05,01)
--- 556,583 ----
  NON_PASSWALL:(00,00,25,16)

  # Boulders
! OBJECT:'0',"boulder",(04,04)
! OBJECT:'0',"boulder",(02,06)
! OBJECT:'0',"boulder",(03,06)
! OBJECT:'0',"boulder",(04,07)
! OBJECT:'0',"boulder",(05,07)
! OBJECT:'0',"boulder",(02,08)
! OBJECT:'0',"boulder",(05,08)
! OBJECT:'0',"boulder",(03,09)
! OBJECT:'0',"boulder",(04,09)
! OBJECT:'0',"boulder",(03,10)
! OBJECT:'0',"boulder",(05,10)
! OBJECT:'0',"boulder",(06,12)
! #
! OBJECT:'0',"boulder",(07,14)
! #
! OBJECT:'0',"boulder",(11,05)
! OBJECT:'0',"boulder",(12,06)
! OBJECT:'0',"boulder",(10,07)
! OBJECT:'0',"boulder",(11,07)
! OBJECT:'0',"boulder",(10,08)
! OBJECT:'0',"boulder",(12,09)
! OBJECT:'0',"boulder",(11,10)

  # Traps
  TRAP:"hole",(05,01)
diff -c -r nethack-3.3.1-orig/src/dog.c nethack-3.3.1/src/dog.c
*** nethack-3.3.1-orig/src/dog.c	Sun Jul 16 17:15:50 2000
--- nethack-3.3.1/src/dog.c	Mon Apr  9 00:06:28 2001
***************
*** 652,658 ****
  		/* Non-rustproofed ferrous based metals are preferred. */
  		return(objects[obj->otyp].oc_material == IRON &&
  		       !obj->oerodeproof ? DOGFOOD : ACCFOOD);
! 	    if(!obj->cursed && obj->oclass != BALL_CLASS &&
  						obj->oclass != CHAIN_CLASS)
  		return(APPORT);
  	    /* fall into next case */
--- 652,658 ----
  		/* Non-rustproofed ferrous based metals are preferred. */
  		return(objects[obj->otyp].oc_material == IRON &&
  		       !obj->oerodeproof ? DOGFOOD : ACCFOOD);
! 	    if(!obj->cursed && obj->otyp != HEAVY_IRON_BALL &&
  						obj->oclass != CHAIN_CLASS)
  		return(APPORT);
  	    /* fall into next case */
diff -c -r nethack-3.3.1-orig/src/drawing.c nethack-3.3.1/src/drawing.c
*** nethack-3.3.1-orig/src/drawing.c	Fri Jul 21 19:59:06 2000
--- nethack-3.3.1/src/drawing.c	Sat Apr  7 18:26:18 2001
***************
*** 64,71 ****
  	"wand",
  	"pile of coins",
  	"gem or rock",
! 	"boulder or statue",
! /*15*/	"iron ball",
  	"iron chain",
  	"splash of venom"
  };
--- 64,71 ----
  	"wand",
  	"pile of coins",
  	"gem or rock",
! 	"statue",
! /*15*/	"boulder or iron ball",
  	"iron chain",
  	"splash of venom"
  };
***************
*** 86,93 ****
  	"wands",
  	"coins",
  	"rocks",
! 	"large stones",
! /*15*/	"iron balls",
  	"chains",
  	"venoms"
  };
--- 86,93 ----
  	"wands",
  	"coins",
  	"rocks",
! 	"statues",
! /*15*/	"heavy round things",
  	"chains",
  	"venoms"
  };
diff -c -r nethack-3.3.1-orig/src/eat.c nethack-3.3.1/src/eat.c
*** nethack-3.3.1-orig/src/eat.c	Fri Aug  4 18:31:40 2000
--- nethack-3.3.1/src/eat.c	Sat Apr  7 20:24:02 2001
***************
*** 1694,1700 ****
  	    if (otmp->oclass == GOLD_CLASS)
  		basenutrit = ((otmp->quan > 200000L) ? 2000
  			: (int)(otmp->quan/100L));
! 	    else if(otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS)
  		basenutrit = weight(otmp);
  	    /* oc_nutrition is usually weight anyway */
  	    else basenutrit = objects[otmp->otyp].oc_nutrition;
--- 1694,1700 ----
  	    if (otmp->oclass == GOLD_CLASS)
  		basenutrit = ((otmp->quan > 200000L) ? 2000
  			: (int)(otmp->quan/100L));
! 	    else if(otmp->otyp == HEAVY_IRON_BALL || otmp->oclass == CHAIN_CLASS)
  		basenutrit = weight(otmp);
  	    /* oc_nutrition is usually weight anyway */
  	    else basenutrit = objects[otmp->otyp].oc_nutrition;
diff -c -r nethack-3.3.1-orig/src/invent.c nethack-3.3.1/src/invent.c
*** nethack-3.3.1-orig/src/invent.c	Fri Aug  4 18:37:26 2000
--- nethack-3.3.1/src/invent.c	Thu May  3 00:29:14 2001
***************
*** 2162,2168 ****
  STATIC_VAR NEARDATA const char *names[] = { 0,
  	"Illegal objects", "Weapons", "Armor", "Rings", "Amulets",
  	"Tools", "Comestibles", "Potions", "Scrolls", "Spellbooks",
! 	"Wands", "Coins", "Gems", "Boulders/Statues", "Iron balls",
  	"Chains", "Venoms"
  };

--- 2162,2168 ----
  STATIC_VAR NEARDATA const char *names[] = { 0,
  	"Illegal objects", "Weapons", "Armor", "Rings", "Amulets",
  	"Tools", "Comestibles", "Potions", "Scrolls", "Spellbooks",
! 	"Wands", "Coins", "Gems", "Statues", "Boulders/Iron balls",
  	"Chains", "Venoms"
  };

diff -c -r nethack-3.3.1-orig/src/lock.c nethack-3.3.1/src/lock.c
*** nethack-3.3.1-orig/src/lock.c	Fri Apr 21 21:31:54 2000
--- nethack-3.3.1/src/lock.c	Sat Apr  7 18:45:04 2001
***************
*** 439,445 ****
  	    uwep->oclass != ROCK_CLASS) ||
  	   (objects[uwep->otyp].oc_skill < P_DAGGER) ||
  	   (objects[uwep->otyp].oc_skill > P_LANCE) ||
! 	   uwep->otyp == FLAIL || uwep->otyp == AKLYS
  #ifdef KOPS
  	   || uwep->otyp == RUBBER_HOSE
  #endif
--- 439,446 ----
  	    uwep->oclass != ROCK_CLASS) ||
  	   (objects[uwep->otyp].oc_skill < P_DAGGER) ||
  	   (objects[uwep->otyp].oc_skill > P_LANCE) ||
! 	   uwep->otyp == FLAIL || uwep->otyp == AKLYS ||
! 	   uwep->otyp == BOULDER
  #ifdef KOPS
  	   || uwep->otyp == RUBBER_HOSE
  #endif
diff -c -r nethack-3.3.1-orig/src/makemon.c nethack-3.3.1/src/makemon.c
*** nethack-3.3.1-orig/src/makemon.c	Sat Jul 15 20:45:22 2000
--- nethack-3.3.1/src/makemon.c	Sat Apr  7 18:51:58 2001
***************
*** 1528,1534 ****
  static NEARDATA char syms[] = {
  	MAXOCLASSES, MAXOCLASSES+1, RING_CLASS, WAND_CLASS, WEAPON_CLASS,
  	FOOD_CLASS, GOLD_CLASS, SCROLL_CLASS, POTION_CLASS, ARMOR_CLASS,
! 	AMULET_CLASS, TOOL_CLASS, ROCK_CLASS, GEM_CLASS, SPBOOK_CLASS,
  	S_MIMIC_DEF, S_MIMIC_DEF, S_MIMIC_DEF,
  };

--- 1528,1534 ----
  static NEARDATA char syms[] = {
  	MAXOCLASSES, MAXOCLASSES+1, RING_CLASS, WAND_CLASS, WEAPON_CLASS,
  	FOOD_CLASS, GOLD_CLASS, SCROLL_CLASS, POTION_CLASS, ARMOR_CLASS,
! 	AMULET_CLASS, TOOL_CLASS, ROCK_CLASS, BALL_CLASS, GEM_CLASS,
SPBOOK_CLASS,
  	S_MIMIC_DEF, S_MIMIC_DEF, S_MIMIC_DEF,
  };

diff -c -r nethack-3.3.1-orig/src/mon.c nethack-3.3.1/src/mon.c
*** nethack-3.3.1-orig/src/mon.c	Thu Aug  3 14:30:14 2000
--- nethack-3.3.1/src/mon.c	Sat Apr  7 20:48:02 2001
***************
*** 688,694 ****
  		/* in case it polymorphed or died */
  		if (ptr != &mons[PM_GELATINOUS_CUBE])
  		    return !ptr ? 2 : 1;
! 	    } else if (otmp->oclass != ROCK_CLASS &&
  				    otmp != uball && otmp != uchain) {
  		++ecount;
  		if (ecount == 1) {
--- 688,694 ----
  		/* in case it polymorphed or died */
  		if (ptr != &mons[PM_GELATINOUS_CUBE])
  		    return !ptr ? 2 : 1;
! 	    } else if (otmp->oclass != ROCK_CLASS && otmp->otyp != BOULDER &&
  				    otmp != uball && otmp != uchain) {
  		++ecount;
  		if (ecount == 1) {
***************
*** 757,762 ****
--- 757,764 ----
  			&& !acidic(&mons[otmp->corpsenm]))
  		   ))
  			continue;
+ 		/* Some mons can pick up iron ball but not if it's attached! */
+ 		if (otmp == uball) continue;
  		if (!touch_artifact(otmp,mtmp)) continue;
  		if (!can_carry(mtmp,otmp)) continue;
  		if (is_pool(mtmp->mx,mtmp->my)) continue;
***************
*** 860,866 ****

  	/* nymphs deal in stolen merchandise, but not boulders or statues */
  	if (mdat->mlet == S_NYMPH)
! 		return (boolean)(otmp->oclass != ROCK_CLASS);

  	if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return FALSE;

--- 862,868 ----

  	/* nymphs deal in stolen merchandise, but not boulders or statues */
  	if (mdat->mlet == S_NYMPH)
! 		return (boolean)(otmp->otyp != BOULDER && otmp->otyp != STATUE);

  	if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return FALSE;

diff -c -r nethack-3.3.1-orig/src/monmove.c nethack-3.3.1/src/monmove.c
*** nethack-3.3.1-orig/src/monmove.c	Thu Aug  3 14:30:14 2000
--- nethack-3.3.1/src/monmove.c	Sat Apr  7 19:22:22 2001
***************
*** 495,501 ****
  	AMULET_CLASS, POTION_CLASS, SCROLL_CLASS, WAND_CLASS, RING_CLASS,
  	SPBOOK_CLASS, 0 };
  static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 };
! static NEARDATA const char boulder_class[] = { ROCK_CLASS, 0 };
  static NEARDATA const char gem_class[] = { GEM_CLASS, 0 };

  boolean
--- 495,501 ----
  	AMULET_CLASS, POTION_CLASS, SCROLL_CLASS, WAND_CLASS, RING_CLASS,
  	SPBOOK_CLASS, 0 };
  static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 };
! static NEARDATA const char boulder_class[] = { BALL_CLASS, 0 };
  static NEARDATA const char gem_class[] = { GEM_CLASS, 0 };

  boolean
diff -c -r nethack-3.3.1-orig/src/objects.c nethack-3.3.1/src/objects.c
*** nethack-3.3.1-orig/src/objects.c	Mon Feb 21 17:36:26 2000
--- nethack-3.3.1/src/objects.c	Sun Apr  8 15:16:28 2001
***************
*** 931,949 ****
  #undef ROCK

  /* miscellaneous ... */
! /* Note: boulders and rocks are not normally created at random; the
!  * probabilities only come into effect when you try to polymorph them.
!  * Boulders weigh more than MAX_CARR_CAP; statues use corpsenm to take
!  * on a specific type and may act as containers (both affect weight).
!  */
! OBJECT(OBJ("boulder",(char *)0),
BITS(1,0,0,0,0,0,0,0,1,0,0,P_NONE,MINERAL), 0,
! 		ROCK_CLASS,   100, 0, 6000,  0, 20, 20, 0, 0, 2000, HI_MINERAL),
  OBJECT(OBJ("statue", (char *)0),
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", (char *)0),
BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
! 		BALL_CLASS,  1000, 0,  480, 10, 25, 25, 0, 0,  200, HI_METAL),
  						/* +d4 when "very heavy" */
  OBJECT(OBJ("iron chain", (char *)0),
BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
  		CHAIN_CLASS, 1000, 0,  120,  0,  4,  4, 0, 0,  200, HI_METAL),
  						/* +1 both l & s */
--- 931,952 ----
  #undef ROCK

  /* miscellaneous ... */
!
! /* statues use corpsenm to take
!  * on a specific type and may act as containers (both affect weight). */
  OBJECT(OBJ("statue", (char *)0),
BITS(1,0,0,1,0,0,0,0,0,0,0,P_NONE,MINERAL), 0,
! 		ROCK_CLASS,  1000, 0, 2500,  0, 20, 20, 0, 0, 2500, CLR_WHITE),

+ /* Note: boulders and iron balls are not normally created at random;
+  * the probabilities only come into effect when you try to polymorph them.
+  * Boulders weigh more than MAX_CARR_CAP.
+  */
+ OBJECT(OBJ("boulder",(char *)0),
BITS(1,0,0,0,0,0,0,0,1,0,0,P_NONE,MINERAL), 0,
+ 		BALL_CLASS,   900, 0, 6000,  0, 20, 20, 0, 0, 2000, HI_MINERAL),
  OBJECT(OBJ("heavy iron ball", (char *)0),
BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
! 		BALL_CLASS,   100, 0,  480, 10, 25, 25, 0, 0,  200, HI_METAL),
  						/* +d4 when "very heavy" */
+
  OBJECT(OBJ("iron chain", (char *)0),
BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
  		CHAIN_CLASS, 1000, 0,  120,  0,  4,  4, 0, 0,  200, HI_METAL),
  						/* +1 both l & s */
diff -c -r nethack-3.3.1-orig/src/objnam.c nethack-3.3.1/src/objnam.c
*** nethack-3.3.1-orig/src/objnam.c	Thu Aug  3 14:25:24 2000
--- nethack-3.3.1/src/objnam.c	Sat Apr  7 20:10:08 2001
***************
*** 335,354 ****
  		Strcpy(buf, actualn);
  		break;
  	    case ROCK_CLASS:
! 		if (typ == STATUE)
! 		    Sprintf(buf, "%s%s of %s%s",
! 			(Role_if(PM_ARCHEOLOGIST) && obj->spe) ? "historic " : "" ,
! 			actualn,
! 			type_is_pname(&mons[obj->corpsenm]) ? "" :
! 			  (mons[obj->corpsenm].geno & G_UNIQ) ? "the " :
! 			    (index(vowels,*(mons[obj->corpsenm].mname)) ?
! 								"an " : "a "),
! 			mons[obj->corpsenm].mname);
! 		else Strcpy(buf, actualn);
  		break;
  	    case BALL_CLASS:
! 		Sprintf(buf, "%sheavy iron ball",
  			(obj->owt > ocl->oc_weight) ? "very " : "");
  		break;
  	    case POTION_CLASS:
  		if (obj->dknown && obj->odiluted)
--- 335,354 ----
  		Strcpy(buf, actualn);
  		break;
  	    case ROCK_CLASS:
! 		Sprintf(buf, "%s%s of %s%s",
! 		(Role_if(PM_ARCHEOLOGIST) && obj->spe) ? "historic " : "" ,
! 		actualn,
! 		type_is_pname(&mons[obj->corpsenm]) ? "" :
! 		  (mons[obj->corpsenm].geno & G_UNIQ) ? "the " :
! 			(index(vowels,*(mons[obj->corpsenm].mname)) ?
! 							"an " : "a "),
! 		mons[obj->corpsenm].mname);
  		break;
  	    case BALL_CLASS:
! 		if (typ == HEAVY_IRON_BALL)
! 			Sprintf(buf, "%sheavy iron ball",
  			(obj->owt > ocl->oc_weight) ? "very " : "");
+ 		else Strcpy(buf, actualn);
  		break;
  	    case POTION_CLASS:
  		if (obj->dknown && obj->odiluted)
***************
*** 690,699 ****
  		break;
  	case BALL_CLASS:
  	case CHAIN_CLASS:
  		add_erosion_words(obj, prefix);
  		if(obj->owornmask & W_BALL)
  			Strcat(bp, " (chained to you)");
! 			break;
  	}

  	if((obj->owornmask & W_WEP) && !mrg_to_wielded) {
--- 690,700 ----
  		break;
  	case BALL_CLASS:
  	case CHAIN_CLASS:
+ 		if (obj->otyp == BOULDER) break;
  		add_erosion_words(obj, prefix);
  		if(obj->owornmask & W_BALL)
  			Strcat(bp, " (chained to you)");
! 		break;
  	}

  	if((obj->owornmask & W_WEP) && !mrg_to_wielded) {
***************
*** 756,763 ****
  	*/
      if (otmp->rknown || (otmp->oclass != ARMOR_CLASS &&
  			 otmp->oclass != WEAPON_CLASS &&
! 			 !is_weptool(otmp) &&		    /* (redunant) */
! 			 otmp->oclass != BALL_CLASS))	    /* (useless) */
  	return FALSE;
      else	/* lack of `rknown' only matters for vulnerable objects */
  	return (boolean)(is_rustprone(otmp) ||
--- 757,764 ----
  	*/
      if (otmp->rknown || (otmp->oclass != ARMOR_CLASS &&
  			 otmp->oclass != WEAPON_CLASS &&
! 			 !is_weptool(otmp) &&		    /* (redundant) */
! 			 otmp->otyp != HEAVY_IRON_BALL))	    /* (useless) */
  	return FALSE;
      else	/* lack of `rknown' only matters for vulnerable objects */
  	return (boolean)(is_rustprone(otmp) ||
diff -c -r nethack-3.3.1-orig/src/read.c nethack-3.3.1/src/read.c
*** nethack-3.3.1-orig/src/read.c	Sat Jul 22 17:04:06 2000
--- nethack-3.3.1/src/read.c	Mon Apr  9 03:11:34 2001
***************
*** 1643,1653 ****
  	}
  	if (amorphous(youmonst.data) || is_whirly(youmonst.data) ||
unsolid(youmonst.data)) {
  		pline("A ball and chain appears, then falls away.");
! 		dropy(mkobj(BALL_CLASS, TRUE));
  		return;
  	}
  	setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
! 	setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
  	uball->spe = 1;		/* special ball (see save) */

  	/*
--- 1643,1653 ----
  	}
  	if (amorphous(youmonst.data) || is_whirly(youmonst.data) ||
unsolid(youmonst.data)) {
  		pline("A ball and chain appears, then falls away.");
! 		dropy(mksobj(HEAVY_IRON_BALL, TRUE, TRUE));
  		return;
  	}
  	setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
! 	setworn(mksobj(HEAVY_IRON_BALL, TRUE, TRUE), W_BALL);
  	uball->spe = 1;		/* special ball (see save) */

  	/*
diff -c -r nethack-3.3.1-orig/src/shk.c nethack-3.3.1/src/shk.c
*** nethack-3.3.1-orig/src/shk.c	Sat Jul 15 20:49:54 2000
--- nethack-3.3.1/src/shk.c	Sat Apr  7 20:21:54 2001
***************
*** 1622,1628 ****
  	    /* the "top" container is evaluated by caller */
  	    if (usell) {
  		if (saleable(shkp, otmp) &&
! 			!otmp->unpaid && otmp->oclass != BALL_CLASS &&
  			!(otmp->oclass == FOOD_CLASS && otmp->oeaten) &&
  			!(Is_candle(otmp) && otmp->age <
  				20L * (long)objects[otmp->otyp].oc_cost))
--- 1622,1628 ----
  	    /* the "top" container is evaluated by caller */
  	    if (usell) {
  		if (saleable(shkp, otmp) &&
! 			!otmp->unpaid && otmp->otyp != HEAVY_IRON_BALL &&
  			!(otmp->oclass == FOOD_CLASS && otmp->oeaten) &&
  			!(Is_candle(otmp) && otmp->age <
  				20L * (long)objects[otmp->otyp].oc_cost))
***************
*** 2105,2111 ****
  			price += get_cost(otmp, shkp);
  		} else {
  		    if(!otmp->no_charge) {
! 			if(!(otmp->oclass == BALL_CLASS ||
  			    (otmp->oclass == FOOD_CLASS && otmp->oeaten) ||
  			    (Is_candle(otmp) && otmp->age <
  				  20L * (long)objects[otmp->otyp].oc_cost))
--- 2105,2111 ----
  			price += get_cost(otmp, shkp);
  		} else {
  		    if(!otmp->no_charge) {
! 			if(!(otmp->otyp == HEAVY_IRON_BALL ||
  			    (otmp->oclass == FOOD_CLASS && otmp->oeaten) ||
  			    (Is_candle(otmp) && otmp->age <
  				  20L * (long)objects[otmp->otyp].oc_cost))
***************
*** 2322,2328 ****
  move_on:
  	if((!saleitem && !(container && cltmp > 0L))
  	   || eshkp->billct == BILLSZ
! 	   || obj->oclass == BALL_CLASS
  	   || obj->oclass == CHAIN_CLASS || offer == 0L
  	   || (obj->oclass == FOOD_CLASS && obj->oeaten)
  	   || (Is_candle(obj) &&
--- 2322,2328 ----
  move_on:
  	if((!saleitem && !(container && cltmp > 0L))
  	   || eshkp->billct == BILLSZ
! 	   || obj->otyp == HEAVY_IRON_BALL
  	   || obj->oclass == CHAIN_CLASS || offer == 0L
  	   || (obj->oclass == FOOD_CLASS && obj->oeaten)
  	   || (Is_candle(obj) &&
diff -c -r nethack-3.3.1-orig/src/weapon.c nethack-3.3.1/src/weapon.c
*** nethack-3.3.1-orig/src/weapon.c	Sun May 28 10:08:42 2000
--- nethack-3.3.1/src/weapon.c	Sat Apr  7 20:22:08 2001
***************
*** 278,284 ****

  /*	Put weapon vs. monster type damage bonuses in below:	*/
  	if (Is_weapon || otmp->oclass == GEM_CLASS ||
! 		otmp->oclass == BALL_CLASS || otmp->oclass == CHAIN_CLASS) {
  	    int bonus = 0;

  #ifdef STEED
--- 278,284 ----

  /*	Put weapon vs. monster type damage bonuses in below:	*/
  	if (Is_weapon || otmp->oclass == GEM_CLASS ||
! 		otmp->otyp == HEAVY_IRON_BALL || otmp->oclass == CHAIN_CLASS) {
  	    int bonus = 0;

  #ifdef STEED
diff -c -r nethack-3.3.1-orig/src/zap.c nethack-3.3.1/src/zap.c
*** nethack-3.3.1-orig/src/zap.c	Fri Aug  4 19:23:30 2000
--- nethack-3.3.1/src/zap.c	Sun Apr  8 15:14:18 2001
***************
*** 1086,1094 ****
  	boolean can_merge = (id == STRANGE_OBJECT);
  	int obj_location = obj->where;

  	if (id == STRANGE_OBJECT) { /* preserve symbol */
  	    int try_limit = 3;
! 	    /* Try up to 3 times to make the magic-or-not status of
  	       the new item be the same as it was for the old one. */
  	    otmp = (struct obj *)0;
  	    do {
--- 1086,1098 ----
  	boolean can_merge = (id == STRANGE_OBJECT);
  	int obj_location = obj->where;

+ 	/* Don't let punished player turn his HIB into a boulder!  That would be
+ 		interesting but there'd be a lot of cases to consider. */
+ 	if (obj == uball && id == STRANGE_OBJECT) return;
+
  	if (id == STRANGE_OBJECT) { /* preserve symbol */
  	    int try_limit = 3;
! 		/* Try up to 3 times to make the magic-or-not status of
  	       the new item be the same as it was for the old one. */
  	    otmp = (struct obj *)0;
  	    do {
***************
*** 1322,1327 ****
--- 1326,1332 ----
  struct obj *obj, *otmp;
  {
  	int res = 1;	/* affected object by default */
+ 	char ox, oy;    /* temp save obj->ox and obj->oy */

  	/*
  	 * Some parts of this function expect the object to on the floor
***************
*** 1450,1464 ****
  		    res = 0;
  		    break;
  		}
! 		/* add more if stone objects are added.. */
  		switch (objects[obj->otyp].oc_class) {
! 		    case ROCK_CLASS:	/* boulders and statues */
! 			if (obj->otyp == BOULDER) {
! 			    poly_obj(obj, HUGE_CHUNK_OF_MEAT);
! 			    if (In_sokoban(&u.uz))
! 				change_luck(-1);	/* Sokoban guilt */
! 			    goto smell;
! 			} else if (obj->otyp == STATUE) {
  			    xchar oox, ooy;

  			    (void) get_obj_location(obj, &oox, &ooy, 0);
--- 1457,1469 ----
  		    res = 0;
  		    break;
  		}
!
! 		ox = obj->ox;
! 		oy = obj->oy;
!
  		switch (objects[obj->otyp].oc_class) {
! 		    case ROCK_CLASS:	/* statues */
! 			if (obj->otyp == STATUE) {
  			    xchar oox, ooy;

  			    (void) get_obj_location(obj, &oox, &ooy, 0);
***************
*** 1480,1485 ****
--- 1485,1501 ----
  			    res = 0;
  			}
  			break;
+
+ 			case BALL_CLASS:
+ 			if (obj->otyp == BOULDER) {
+ 			    poly_obj(obj, HUGE_CHUNK_OF_MEAT);
+ 			    if (In_sokoban(&u.uz))
+ 				change_luck(-1);	/* Sokoban guilt */
+ 			    goto smell;
+ 			}
+ 			else res = 0;
+ 			break;
+
  		    case TOOL_CLASS:	/* figurine */
  		    {
  			struct monst *mon;


