Merge commit 'nc/master' into temp
authorMark Wooding <mdw@distorted.org.uk>
Sat, 12 May 2007 23:03:44 +0000 (00:03 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 12 May 2007 23:03:44 +0000 (00:03 +0100)
* commit 'nc/master':
  Updates

Conflicts:

dice.lisp
monsters.tex
spells.tex
tables.cls
treasure.tex

1  2 
dice.lisp
monsters.tex
spells.tex
treasure.tex

diff --combined dice.lisp
+++ b/dice.lisp
        (when (< (random n) 1)
          (setf it (car things))))))
  
- (defmacro pick (&rest clauses)
+ (defmacro pick (&body clauses)
    `(funcall (choose ,@(loop for (n . clause) in clauses
                           collect n
                           collect `(lambda () ,@clause)))))
  
- (defconstant druid-spells
-   #((detect-danger faerie-fire locate predict-weather)
-     (heat-metal obscure produce-fire warp-wood)
-     (call-lightning hold-animal protection-from-poison water-breathing)
-     (control-temperature-10-ft-radius plant-door protection-from-lightning
-      summon-animals)
-     (anti-plant-shell control-winds dissolve pass-plant)
-     (anti-animal-shell summon-weather transport-through-plants turn-wood)
-     (creeping-doom metal-to-wood summon-elemental weather-control)))
++(defmacro pick-matching ((form &key) &body clauses)
++  (let ((formtemp (gensym "FORM")))
++    `(let ((,formtemp ,form))
++       (pick ,@(loop for (prob assertion . code) in clauses
++                   collect `((if (assertion-match-p ,formtemp ',assertion)
++                                 ,prob
++                                 0)
++                             ,@code))))))
 +
  (defconstant cleric-spells
    #((cure-light-wounds detect-evil detect-magic light protection-from-evil
       purify-food-and-water remove-fear resist-cold)
      (earthquake holy-word raise-dead-fully restore survival travel wish
       wizardry)))
  
+ (defconstant druid-only-spells
+   #((detect-danger faerie-fire locate predict-weather)
+     (heat-metal obscure produce-fire warp-wood)
+     (call-lightning hold-animal protection-from-poison water-breathing)
+     (control-temperature-10-ft-radius plant-door protection-from-lightning
+      summon-animals)
+     (anti-plant-shell control-winds dissolve pass-plant)
+     (anti-animal-shell summon-weather transport-through-plants turn-wood)
+     (creeping-doom metal-to-wood summon-elemental weather-control)))
+ (defconstant druid-spells
+   (make-array 7 :initial-contents (loop for cs across cleric-spells
+                                       for ds across druid-only-spells
+                                       collect (append cs ds))))
  (defconstant magic-user-spells
    #((analyse charm-person detect-magic floating-disc hold-portal light
       magic-missile protection-from-evil read-languages read-magic shield
      (contingency create-any-monster gate heal immunity maze meteor-swarm
       power-word-kill prismatic-wall shapechange survival timestop wish)))
  
- (defun spell-caster-type ()
-   (choose 25 :cleric 5 :druid 70 :magic-user))
+ (defun spell-caster-type (&optional (form :any))
+   (pick-matching (form)
+     (5 (:user (:cleric :druid :paladin)) :cleric)
+     (1 (:user :druid) :druid)
+     (14 (:user (:magic-user :elf :thief)) :magic-user)))
  
  (defun random-spell (&optional (caster (spell-caster-type))
                               (level (ecase caster
    (let ((list (aref (ecase caster
                      ((:magic-user) magic-user-spells)
                      ((:cleric) cleric-spells)
-                     ((:druid) druid-spells))
+                     ((:druid) druid-only-spells))
                    level)))
      (values (elt list (random (length list)))
            caster
            level)))
  
- (defun symbol-match-p (form sym)
-   (cond ((eq form t) t)
-       ((eq form nil) nil)
-       ((eq form sym) t)
-       ((atom form) nil)
-       (t (ecase (car form)
-            ((and) (every (lambda (f) (symbol-match-p f sym)) (cdr form)))
-            ((or) (some (lambda (f) (symbol-match-p f sym)) (cdr form)))
-            ((not) (not (symbol-match-p (cadr form) sym)))))))
+ (let ((magic (list :magic)))
+   (defun assertion-match-p (form assertions)
+     (cond ((eq form :any) t)
+         ((eq form :none) nil)
+         ((atom form) (if (atom assertions)
+                          (eql form assertions)
+                          (member form assertions)))
+         (t (case (car form)
+              ((and) (every (lambda (f)
+                              (assertion-match-p f assertions))
+                            (cdr form)))
+              ((or) (some (lambda (f)
+                            (assertion-match-p f assertions))
+                          (cdr form)))
+              ((not) (not (assertion-match-p (cadr form) assertions)))
+              (t (let ((sub (getf assertions (car form) magic)))
+                   (if (eq sub magic)
+                       t
+                       (assertion-match-p (cadr form) sub)))))))))
  
  (defun choose-distinct-items (n seq)
    (let* ((copy (subseq (coerce seq 'vector) 0))
        (decf len)
        (setf (aref copy j) (aref copy len))))))
  
 -(defmacro pick-matching ((form &key) &body clauses)
 -  (let ((formtemp (gensym "FORM")))
 -    `(let ((,formtemp ,form))
 -       (pick ,@(loop for (prob assertion . code) in clauses
 -                   collect `((if (assertion-match-p ,formtemp ',assertion)
 -                                 ,prob
 -                                 0)
 -                             ,@code))))))
 -
  (defun magic-item (form)
-   (labels ((potion (&key recursivep)
-            (pick (2 `(:potion agility))
-                  (1 `(:potion animal-control))
-                  (3 `(:potion antidote))
-                  (2 `(:potion blending))
-                  (2 `(:potion bug-repellent))
-                  (2 `(:potion clairaudience))
-                  (2 `(:potion clairvoyance))
-                  (2 `(:potion climbing))
-                  (2 `(:potion defence :bonus ,(choose 3 1
-                                                        2 2
-                                                        2 3
-                                                        2 4
-                                                        1 5)))
-                  ((if recursivep 0 4)
-                   `(:potion delusion
-                     :fakes ,@(cdr (potion :recursivep t))))
-                  (2 `(:potion diminution))
-                  (1 `(:potion ,(choose 35 'white-dragon-control
-                                        15 'crystal-dragon-control
-                                        35 'black-dragon-control
-                                        15 'onyx-dragon-control
-                                        28 'green-dragon-control
-                                        12 'jade-dragon-control
-                                        21 'blue-dragon-control
-                                         9 'sapphire-dragon-control
-                                        14 'red-dragon-control
-                                         6 'ruby-dragon-control
-                                         7 'gold-dragon-control
-                                         3 'amber-dragon-control)))
-                  (2 `(:potion dreamspeech))
-                  (1 `(:potion elasicity))
-                  (2 `(:potion ,(choose-uniformly 'air-form
-                                                  'water-form
-                                                  'earth-form
-                                                  'fire-form)))
-                  (2 `(:potion esp))
-                  (1 `(:potion ethereality))
-                  (3 `(:potion fire-resistance))
-                  (3 `(:potion flying))
-                  (2 `(:potion fortitude))
-                  (1 `(:potion freedom))
-                  (3 `(:potion gaseous-form))
-                  (1 `(:potion ,(choose 5 'hill-giant-control
-                                        5 'stone-giant-control
-                                        4 'frost-giant-control
-                                        2 'fire-giant-control
-                                        1 'mountain-giant-control
-                                        1 'sea-giant-control
-                                        1 'cloud-giant-control
-                                        1 'storm-giant-control)))
-                  (3 `(:potion giant-strength))
-                  (2 `(:potion growth))
-                  (6 `(:potion healing))
-                  (3 `(:potion heroism))
-                  (1 `(:potion human-control))
-                  (3 `(:potion invisibility))
-                  (2 `(:potion invulnerability))
-                  (2 `(:potion levitation))
-                  (2 `(:potion longevity))
-                  (1 `(:potion luck))
-                  (1 `(:potion merging))
-                  (2 `(:potion plant-control))
-                  (3 `(:potion poison))
-                  (3 `(:potion polymorph-self))
-                  (2 `(:potion sight))
-                  (2 `(:potion speech))
-                  (4 `(:potion speed))
-                  (2 `(:potion strength))
-                  (3 `(:potion super-healing))
-                  (3 `(:potion swimming))
-                  (1 `(:potion treasure-finding))
-                  (1 `(:potion undead-control))
-                  (2 `(:potion water-breathing))))
+   (labels ((cursedp (&optional (prob 10))
+            (cond ((assertion-match-p form '(:cursed :unspecified))
+                   (zerop (random prob)))
+                  ((assertion-match-p form '(:cursed nil))
+                   nil)
+                  (t t)))
+          (potion (&key recursivep)
+            (pick-matching (form)
+              (2 (:cursed nil) `(:potion agility))
+              (1 (:cursed nil) `(:potion animal-control))
+              (3 (:cursed nil) `(:potion antidote))
+              (2 (:cursed nil) `(:potion blending))
+              (2 (:cursed nil) `(:potion bug-repellent))
+              (2 (:cursed nil) `(:potion clairaudience))
+              (2 (:cursed nil) `(:potion clairvoyance))
+              (2 (:cursed nil) `(:potion climbing))
+              (2 (:cursed nil) `(:potion defence :bonus ,(choose 3 1
+                                                                 2 2
+                                                                 2 3
+                                                                 2 4
+                                                                 1 5)))
+              ((if recursivep 0 4) (:cursed t)
+               (setf form :any)
+               `(:potion delusion
+                 :fakes ,@(cdr (potion :recursivep t))))
+              (2 (:cursed nil) `(:potion diminution))
+              (1 (:cursed nil) `(:potion ,(choose 35 'white-dragon-control
+                                                  15 'crystal-dragon-control
+                                                  35 'black-dragon-control
+                                                  15 'onyx-dragon-control
+                                                  28 'green-dragon-control
+                                                  12 'jade-dragon-control
+                                                  21 'blue-dragon-control
+                                                  9 'sapphire-dragon-control
+                                                  14 'red-dragon-control
+                                                  6 'ruby-dragon-control
+                                                  7 'gold-dragon-control
+                                                  3 'amber-dragon-control)))
+              (2 (:cursed nil) `(:potion dreamspeech))
+              (1 (:cursed nil) `(:potion elasicity))
+              (2 (:cursed nil) `(:potion ,(choose-uniformly 'air-form
+                                                            'water-form
+                                                            'earth-form
+                                                            'fire-form)))
+              (2 (:cursed nil) `(:potion esp))
+              (1 (:cursed nil) `(:potion ethereality))
+              (3 (:cursed nil) `(:potion fire-resistance))
+              (3 (:cursed nil) `(:potion flying))
+              (2 (:cursed nil) `(:potion fortitude))
+              (1 (:cursed nil) `(:potion freedom))
+              (3 (:cursed nil) `(:potion gaseous-form))
+              (1 (:cursed nil) `(:potion ,(choose 5 'hill-giant-control
+                                                  5 'stone-giant-control
+                                                  4 'frost-giant-control
+                                                  2 'fire-giant-control
+                                                  1 'mountain-giant-control
+                                                  1 'sea-giant-control
+                                                  1 'cloud-giant-control
+                                                  1 'storm-giant-control)))
+              (3 (:cursed nil) `(:potion giant-strength))
+              (2 (:cursed nil) `(:potion growth))
+              (6 (:cursed nil) `(:potion healing))
+              (3 (:cursed nil) `(:potion heroism))
+              (1 (:cursed nil) `(:potion human-control))
+              (3 (:cursed nil) `(:potion invisibility))
+              (2 (:cursed nil) `(:potion invulnerability))
+              (2 (:cursed nil) `(:potion levitation))
+              (2 (:cursed nil) `(:potion longevity))
+              (1 (:cursed nil) `(:potion luck))
+              (1 (:cursed nil) `(:potion merging))
+              (2 (:cursed nil) `(:potion plant-control))
+              (3 (:cursed t) `(:potion poison))
+              (3 (:cursed nil) `(:potion polymorph-self))
+              (2 (:cursed nil) `(:potion sight))
+              (2 (:cursed nil) `(:potion speech))
+              (4 (:cursed nil) `(:potion speed))
+              (2 (:cursed nil) `(:potion strength))
+              (3 (:cursed nil) `(:potion super-healing))
+              (3 (:cursed nil) `(:potion swimming))
+              (1 (:cursed nil) `(:potion treasure-finding))
+              (1 (:cursed nil) `(:potion undead-control))
+              (2 (:cursed nil) `(:potion water-breathing))))
           (scroll ()
-            (pick (3 `(:scroll communication))
-                  (2 `(:scroll creation))
-                  (8 `(:scroll curse))
-                  (1 (multiple-value-bind
-                         (spell caster level)
-                         (random-spell)
-                       (declare (ignore level))
-                       `(:scroll delay :caster ,caster :spells (,spell))))
-                  (3 `(:scroll equipment
-                       :items ,(choose-distinct-items 6
-                                                      '(grappling-hook
-                                                        hammer
-                                                        iron-spikes
-                                                        lantern
-                                                        mirror
-                                                        wooden-pole
-                                                        rope
-                                                        saddle
-                                                        backpack
-                                                        saddle-bags
-                                                        stakes-and-mallet
-                                                        wolfsbane))))
-                  (2 `(:scroll illumination))
-                  (2 `(:scroll mages))
-                  (4 `(:map normal-treasure))
-                  (3 `(:map magical-treasure))
-                  (2 `(:map combined-treasure))
-                  (1 `(:map special-treasure))
-                  (3 `(:scroll mapping))
-                  (2 `(:scroll portals))
-                  (6 `(:scroll protection-from-elementals))
-                  (8 `(:scroll protection-from-lycanthropes))
-                  (4 `(:scroll protection-from-magic))
-                  (7 `(:scroll protection-from-undead))
-                  (2 `(:scroll questioning))
-                  (1 (multiple-value-bind
-                         (spell caster level)
-                         (random-spell)
-                       `(:scroll repetition
-                         :caster ,caster
-                         :level ,level
-                         :spells (,spell))))
-                  (2 `(:scroll seeing))
-                  (2 `(:scroll shelter))
-                  (3 `(:scroll spell-catching :max-level ,(choose 4 1
-                                                                  3 2
-                                                                  2 3
-                                                                  1 8)))
-                  (25 (let ((caster (spell-caster-type))
-                            (spells (choose 50 1  33 2  17 3)))
-                        `(:scroll spell
-                          :caster ,caster
-                          :spells ,(loop repeat spells
-                                         collect (random-spell caster)))))
-                  (2 `(:scroll trapping))
-                  (2 `(:scroll truth))))
+            (pick-matching (form)
+              (3 (:cursed nil) `(:scroll communication))
+              (2 (:cursed nil) `(:scroll creation))
+              (8 (:cursed t) `(:scroll curse))
+              (1 (:user (:cleric :druid :magic-user :elf :thief :paladin)
+                  :cursed nil)
+                 (multiple-value-bind
+                     (spell caster level)
+                     (random-spell (spell-caster-type form))
+                   (declare (ignore level))
+                   `(:scroll delay :caster ,caster :spells (,spell))))
+              (3 (:cursed nil)
+                 `(:scroll equipment
+                   :items ,(choose-distinct-items 6
+                                                  '(grappling-hook
+                                                    hammer
+                                                    iron-spikes
+                                                    lantern
+                                                    mirror
+                                                    wooden-pole
+                                                    rope
+                                                    saddle
+                                                    backpack
+                                                    saddle-bags
+                                                    stakes-and-mallet
+                                                    wolfsbane))))
+              (2 (:cursed nil) `(:scroll illumination))
+              (2 (:cursed nil :user (:magic-user :cleric :druid :elf))
+                 `(:scroll mages))
+              (4 (:cursed nil) `(:map normal-treasure))
+              (3 (:cursed nil) `(:map magical-treasure))
+              (2 (:cursed nil) `(:map combined-treasure))
+              (1 (:cursed nil) `(:map special-treasure))
+              (3 (:cursed nil) `(:scroll mapping))
+              (2 (:cursed nil) `(:scroll portals))
+              (6 (:cursed nil) `(:scroll protection-from-elementals))
+              (8 (:cursed nil) `(:scroll protection-from-lycanthropes))
+              (4 (:cursed nil) `(:scroll protection-from-magic))
+              (7 (:cursed nil) `(:scroll protection-from-undead))
+              (2 (:cursed nil) `(:scroll questioning))
+              (1 (:cursed nil
+                  :user (:cleric :druid :magic-user :elf :thief :paladin))
+                 (multiple-value-bind
+                     (spell caster level)
+                     (random-spell (spell-caster-type form))
+                   `(:scroll repetition
+                     :caster ,caster
+                     :level ,level
+                     :spells (,spell))))
+              (2 (:cursed nil) `(:scroll seeing))
+              (2 (:cursed nil) `(:scroll shelter))
+              (3 (:cursed nil)
+                 `(:scroll spell-catching :max-level ,(choose 4 1
+                                                              3 2
+                                                              2 3
+                                                              1 8)))
+              (25 (:cursed nil
+                   :user (:cleric :druid :magic-user :elf :thief :paladin))
+                  (let ((caster (spell-caster-type form))
+                        (spells (choose 50 1  33 2  17 3)))
+                    `(:scroll spell
+                      :caster ,caster
+                      :spells ,(loop repeat spells
+                                     collect (random-spell caster)))))
+              (2 (:cursed nil) `(:scroll trapping))
+              (2 (:cursed nil) `(:scroll truth))))
           (wand-charges () (d 10 3))
           (staff-charges () (d 20 2))
           (wandlike ()
-            (pick (5 `(:wand cold :charges ,(wand-charges)))
-                  (5 `(:wand enemy-detection :charges ,(wand-charges)))
-                  (4 `(:wand fear :charges ,(wand-charges)))
-                  (5 `(:wand fireballs :charges ,(wand-charges)))
-                  (4 `(:wand illusion :charges ,(wand-charges)))
-                  (5 `(:wand lightning-bolts :charges ,(wand-charges)))
-                  (5 `(:wand magic-detection :charges ,(wand-charges)))
-                  (5 `(:wand metal-detection :charges ,(wand-charges)))
-                  (4 `(:wand negation :charges ,(wand-charges)))
-                  (5 `(:wand paralysation :charges ,(wand-charges)))
-                  (5 `(:wand polymorphing :charges ,(wand-charges)))
-                  (4 `(:wand secret-door-detection
-                       :charges ,(wand-charges)))
-                  (4 `(:wand trap-detection :charges ,(wand-charges)))
-                  (1 `(:staff commanding :charges nil))
-                  (2 `(:staff dispelling :charges ,(staff-charges)))
-                  (3 `(:staff druids :charges ,(staff-charges)))
-                  (3 `(:staff ,(choose 19 'air
-                                       19 'earth
-                                       19 'fire
-                                       19 'water
-                                        6 'air-and-water
-                                        6 'earth-and-fire
-                                        2 'elemental-power)
-                       :charges ,(staff-charges)))
-                  (2 `(:staff harming :charges ,(staff-charges)))
-                  (7 `(:staff healing :charges ,(staff-charges)))
-                  (1 `(:staff power :charges ,(staff-charges)))
-                  (3 `(:staff snake :charges ,(staff-charges)))
-                  (3 `(:staff striking :charges ,(staff-charges)))
-                  (2 `(:staff withering :charges ,(staff-charges)))
-                  (1 `(:staff wizardry :charges ,(staff-charges)))
-                  (2 `(:rod cancellation))
-                  (1 `(:rod dominion))
-                  (1 `(:rod health))
-                  (2 `(:rod inertia))
-                  (1 `(:rod parrying))
-                  (1 `(:rod victory))
-                  (3 `(:rod weaponry))
-                  (1 `(:rod wyrm :colour ,(choose 5 'gold
-                                                  3 'blue
-                                                  2 'black)))))
-          (ring ()
-            (pick (2 `(:ring animal-control))
-                  (6 `(:ring delusion))
-                  (1 `(:ring djinni-summoning))
-                  (4 `(:ring ear))
-                  (4 `(:ring ,(choose 19 'air-adaptation
-                                      19 'earth-adaptation
-                                      19 'fire-adaptation
-                                      19 'water-adaptation
-                                       6 'air-and-water-adaptation
-                                       6 'earth-and-fire-adaptation
-                                       2 'elemental-adaptation)))
-                  (6 `(:ring fire-resistance))
-                  (3 `(:ring holiness))
-                  (1 `(:ring human-control))
-                  (5 `(:ring invisibility))
-                  (3 `(:ring life-protection :charges ,(d 6)))
-                  (3 `(:ring memory))
-                  (2 `(:ring plant-control))
-                  (1 `(:ring protection :bonus 1 :radius 5))
-                  (10 `(:ring protection :bonus ,(choose 4 1
-                                                         3 2
-                                                         2 3
-                                                         1 4)))
-                  (4 `(:ring quickness))
-                  (1 `(:ring regeneration))
-                  (3 `(:ring remedies))
-                  (2 `(:ring safety :charges ,(d 4)))
-                  (3 `(:ring seeing))
-                  (3 `(:ring spell-eating))
-                  (2 (let* ((caster (spell-caster-type))
-                            (spells (loop repeat (d 6)
-                                          collect (random-spell caster))))
-                       `(:ring spell-storing
-                         :caster ,caster
-                         :spells ,(remove-duplicates (sort spells
-                                                           #'string<)))))
-                  (2 `(:ring spell-turning))
-                  (4 `(:ring survival :charges ,(+ 100 (d 100))))
-                  (2 `(:ring telekinesis))
-                  (4 `(:ring truth))
-                  (3 `(:ring truthfulness))
-                  (2 `(:ring truthlessness))
-                  (5 `(:ring water-walking))
-                  (5 `(:ring weakness))
-                  (2 `(:ring wishes :charges ,(choose 4 1
-                                                      3 2
-                                                      2 3
-                                                      1 4)))
-                  (2 `(:ring x-ray-vision))))
+            (pick-matching (form)
+              (5 (:user (:magic-user :elf))
+                 `(:wand cold :charges ,(wand-charges)))
+              (5 (:user (:magic-user :elf))
+                 `(:wand enemy-detection :charges ,(wand-charges)))
+              (4 (:user (:magic-user :elf))
+                 `(:wand fear :charges ,(wand-charges)))
+              (5 (:user (:magic-user :elf))
+                 `(:wand fireballs :charges ,(wand-charges)))
+              (4 (:user (:magic-user :elf))
+                 `(:wand illusion :charges ,(wand-charges)))
+              (5 (:user (:magic-user :elf))
+                 `(:wand lightning-bolts :charges ,(wand-charges)))
+              (5 (:user (:magic-user :elf))
+                 `(:wand magic-detection :charges ,(wand-charges)))
+              (5 (:user (:magic-user :elf))
+                 `(:wand metal-detection :charges ,(wand-charges)))
+              (4 (:user (:magic-user :elf))
+                 `(:wand negation :charges ,(wand-charges)))
+              (5 (:user (:magic-user :elf))
+                 `(:wand paralysation :charges ,(wand-charges)))
+              (5 (:user (:magic-user :elf))
+                 `(:wand polymorphing :charges ,(wand-charges)))
+              (4 (:user (:magic-user :elf))
+                 `(:wand secret-door-detection :charges ,(wand-charges)))
+              (4 (:user (:magic-user :elf))
+                 `(:wand trap-detection :charges ,(wand-charges)))
+              (1 (:user (:magic-user :elf :cleric :druid :palatin))
+                 `(:staff commanding :charges nil))
+              (2 nil
+                 `(:staff dispelling :charges ,(staff-charges)))
+              (3 (:user :druid)
+                 `(:staff druids :charges ,(staff-charges)))
+              (3 (:user (:magic-user :elf))
+                 `(:staff ,(choose 19 'air
+                                   19 'earth
+                                   19 'fire
+                                   19 'water
+                                   6 'air-and-water
+                                   6 'earth-and-fire
+                                   2 'elemental-power)
+                   :charges ,(staff-charges)))
+              (2 (:user (:cleric :druid :paladin))
+                 `(:staff harming :charges ,(staff-charges)))
+              (7 (:user (:cleric :druid :paladin))
+                 `(:staff healing :charges ,(staff-charges)))
+              (1 (:user (:cleric :druid :magic-user :elf :paladin))
+                 `(:staff power :charges ,(staff-charges)))
+              (3 (:user (:cleric :druid :paladin))
+                 `(:staff snake :charges ,(staff-charges)))
+              (3 (:user (:cleric :druid :magic-user :elf :paladin))
+                 `(:staff striking :charges ,(staff-charges)))
+              (2 (:user (:cleric :druid :paladin))
+                 `(:staff withering :charges ,(staff-charges)))
+              (1 (:user (:magic-user :elf))
+                 `(:staff wizardry :charges ,(staff-charges)))
+              (2 nil `(:rod cancellation))
+              (1 nil `(:rod dominion))
+              (1 (:user (:cleric :druid :paladin)) `(:rod health))
+              (2 (:user (:dwarf :halfling :elf :fighter
+                         :paladin :thief :mystic))
+                 `(:rod inertia))
+              (1 nil `(:rod parrying))
+              (1 nil `(:rod victory))
+              (3 (:user (:dwarf :halfling :elf :fighter
+                         :paladin :thief :mystic))
+                 `(:rod weaponry))
+              (1 nil
+                 `(:rod wyrm :colour ,(choose 5 'gold
+                                              3 'blue
+                                              2 'black)))))
+          (ring (&optional (recursivep nil))
+            (pick-matching (form)
+              (2 (:cursed nil) `(:ring animal-control))
+              ((if recursivep 0 6)
+               (:cursed t)
+               (setf form :any)
+               `(:ring delusion :fakes ,@(cdr (ring t))))
+              (1 (:cursed nil) `(:ring djinni-summoning))
+              (4 (:cursed nil) `(:ring ear))
+              (4 (:cursed nil) `(:ring ,(choose 19 'air-adaptation
+                                                19 'earth-adaptation
+                                                19 'fire-adaptation
+                                                19 'water-adaptation
+                                                6 'air-and-water-adaptation
+                                                6 'earth-and-fire-adaptation
+                                                2 'elemental-adaptation)))
+              (6 (:cursed nil) `(:ring fire-resistance))
+              (3 (:cursed nil :user (:cleric :druid :paladin))
+                 `(:ring holiness))
+              (1 (:cursed nil) `(:ring human-control))
+              (5 (:cursed nil) `(:ring invisibility))
+              (3 (:cursed nil) `(:ring life-protection :charges ,(d 6)))
+              (3 (:cursed nil
+                  :user (:cleric :druid :magic-user :elf :paladin))
+                 `(:ring memory))
+              (2 (:cursed nil) `(:ring plant-control))
+              (1 (:cursed nil) `(:ring protection :bonus 1 :radius 5))
+              (10 (:cursed nil) `(:ring protection :bonus ,(choose 4 1
+                                                                   3 2
+                                                                   2 3
+                                                                   1 4)))
+              (4 (:cursed nil) `(:ring quickness))
+              (1 (:cursed nil) `(:ring regeneration))
+              (3 (:cursed nil) `(:ring remedies))
+              (2 (:cursed nil) `(:ring safety :charges ,(d 4)))
+              (3 (:cursed nil) `(:ring seeing))
+              (3 (:cursed t) `(:ring spell-eating))
+              (2 (:cursed nil)
+                 (let* ((caster (spell-caster-type))
+                        (spells (loop repeat (d 6)
+                                      collect (random-spell caster))))
+                   `(:ring spell-storing
+                     :caster ,caster
+                     :spells ,(remove-duplicates (sort spells
+                                                       #'string<)))))
+              (2 (:cursed nil) `(:ring spell-turning))
+              (4 (:cursed nil) `(:ring survival :charges ,(+ 100 (d 100))))
+              (2 (:cursed nil) `(:ring telekinesis))
+              (4 (:cursed nil) `(:ring truth))
+              (3 (:cursed t) `(:ring truthfulness))
+              (2 (:cursed t) `(:ring truthlessness))
+              (5 (:cursed nil) `(:ring water-walking))
+              (5 (:cursed t) `(:ring weakness))
+              (2 (:cursed nil) `(:ring wishes :charges ,(choose 4 1
+                                                                3 2
+                                                                2 3
+                                                                1 4)))
+              (2 (:cursed nil) `(:ring x-ray-vision))))
           (misc-item ()
-            (pick (2 `(:amulet protection-from-crystal-balls-and-esp))
-                  (2 `(:bag devouring))
-                  (5 `(:bag holding))
-                  (3 `(:boat undersea))
-                  (2 `(:boots levitation))
-                  (3 `(:boots speed))
-                  (2 `(:boots travelling-and-leaping))
-                  (1 `(:bowl commanding-water-elementals))
-                  (1 `(:brazier commanding-fire-elementals))
-                  (2 `(:broom flying))
-                  (1 `(:censer controlling-air-elementals))
-                  (3 `(:chime time))
-                  (2 `(:crystal-ball normal))
-                  (1 `(:crystal-ball clairaudience))
-                  (1 `(:crystal-ball esp))
-                  (2 `(:cloak displacer))
-                  (1 `(:drums panic))
-                  (1 `(:bottle efreeti))
-                  (3 `(:egg ,(choose-uniformly 'rock-baboon
-                                               'giant-bat
-                                               'black-bear
-                                               'grizzly-bear
-                                               'boar
-                                               'mountain-lion
-                                               'panther
-                                               'giant-ferret
-                                               'gecko
-                                               'draco
-                                               'racer-snake
-                                               'wolf)))
-                  (2 `(:boots elven))
-                  (2 `(:cloak elven))
-                  (1 `(:carpet flying))
-                  (2 `(:gauntlets ogre-power))
-                  (2 `(:girdle giant-strength))
-                  (2 `(:helm ,(choose-uniformly 'lawful-alignment
-                                                'neutral-alignment
-                                                'chaotic-alignment)))
-                  (2 `(:helm reading))
-                  (1 `(:helm telepathy))
-                  (1 `(:helm teleportation))
-                  (1 `(:horn blasting))
-                  (2 `(:lamp hurricane))
-                  (3 `(:lamp long-burning))
-                  (2 `(:medallion esp-30-ft-range))
-                  (1 `(:medallion esp-90-ft-range))
-                  (1 `(:mirror life-trapping)) ;;; fixme include contents
-                  (3 `(:muzzle training))
-                  (2 `(:nail finger))
-                  (3 `(:nail pointing))
-                  (5 `(:ointment ,(choose-uniformly 'blessing
-                                                    'healing
-                                                    'poison
-                                                    'scarring
-                                                    'soothing
-                                                    'tanning)))
-                  (3 `(:pouch security))
-                  (3 `(:quill copying))
-                  (4 `(:rope climbing))
-                  (2 `(:scarab protection :charges ,(d 6 2)))
-                  (3 `(:slate identification))
-                  (1 `(:stone controlling-earth-elementals))
-                  (2 `(:talisman ,(choose-uniformly 'air-travel
-                                                    'earth-travel
-                                                    'fire-travel
-                                                    'water-travel
-                                                    'elemental-travel)))
-                  (3 `(:wheel floating))
-                  (1 `(:wheel fortune))
-                  (2 `(:wheel square))))
+            (pick-matching (form)
+              (2 (:cursed nil)
+                 `(:amulet protection-from-crystal-balls-and-esp))
+              (2 (:cursed t) `(:bag devouring))
+              (5 (:cursed nil) `(:bag holding))
+              (3 (:cursed nil) `(:boat undersea))
+              (2 (:cursed nil) `(:boots levitation))
+              (3 (:cursed nil) `(:boots speed))
+              (2 (:cursed nil) `(:boots travelling-and-leaping))
+              (1 (:cursed nil) `(:bowl commanding-water-elementals))
+              (1 (:cursed nil) `(:brazier commanding-fire-elementals))
+              (2 (:cursed nil) `(:broom flying))
+              (1 (:cursed nil) `(:censer controlling-air-elementals))
+              (3 (:cursed nil) `(:chime time))
+              (2 (:cursed nil :user (:magic-user :elf))
+                 `(:crystal-ball normal))
+              (1 (:cursed nil :user (:magic-user :elf))
+                 `(:crystal-ball clairaudience))
+              (1 (:cursed nil :user (:magic-user :elf))
+                 `(:crystal-ball esp))
+              (2 (:cursed nil) `(:cloak displacer))
+              (1 (:cursed nil) `(:drums panic))
+              (1 (:cursed nil) `(:bottle efreeti))
+              (3 (:cursed nil) `(:egg ,(choose-uniformly 'rock-baboon
+                                                         'giant-bat
+                                                         'black-bear
+                                                         'grizzly-bear
+                                                         'boar
+                                                         'mountain-lion
+                                                         'panther
+                                                         'giant-ferret
+                                                         'gecko
+                                                         'draco
+                                                         'racer-snake
+                                                         'wolf)))
+              (2 (:cursed nil) `(:boots elven))
+              (2 (:cursed nil) `(:cloak elven))
+              (1 (:cursed nil) `(:carpet flying))
+              (2 (:cursed nil) `(:gauntlets ogre-power))
+              (2 (:cursed nil) `(:girdle giant-strength))
+              (2 (:cursed t)
+                 `(:helm ,(choose-uniformly 'lawful-alignment
+                                            'neutral-alignment
+                                            'chaotic-alignment)))
+              (2 (:cursed nil) `(:helm reading))
+              (1 (:cursed nil) `(:helm telepathy))
+              (1 (:cursed nil) `(:helm teleportation))
+              (1 (:cursed nil) `(:horn blasting))
+              (2 (:cursed t) `(:lamp hurricane))
+              (3 (:cursed nil) `(:lamp long-burning))
+              (2 (:cursed nil) `(:medallion esp-30-ft-range))
+              (1 (:cursed nil) `(:medallion esp-90-ft-range))
+              (1 (:cursed nil) `(:mirror life-trapping))
+                                       ; fixme include contents
+              (3 (:cursed nil) `(:muzzle training))
+              (2 (:cursed nil) `(:nail finger))
+              (3 (:cursed nil) `(:nail pointing))
+              (5 nil `(:ointment ,(pick-matching (form)
+                                    (1 (:cursed nil) 'blessing)
+                                    (1 (:cursed nil) 'healing)
+                                    (1 (:cursed t) 'poison)
+                                    (1 (:cursed t) 'scarring)
+                                    (1 (:cursed nil) 'soothing)
+                                    (1 (:cursed t) 'tanning))))
+              (3 (:cursed nil) `(:pouch security))
+              (3 (:cursed nil :user (:cleric :druid :magic-user :elf))
+                 `(:quill copying))
+              (4 (:cursed nil) `(:rope climbing))
+              (2 (:cursed nil) `(:scarab protection :charges ,(d 6 2)))
+              (3 (:cursed nil :user (:cleric :druid :magic-user :elf))
+                 `(:slate identification))
+              (1 (:cursed nil) `(:stone controlling-earth-elementals))
+              (2 (:cursed nil)
+                 `(:talisman ,(choose-uniformly 'air-travel
+                                                'earth-travel
+                                                'fire-travel
+                                                'water-travel
+                                                'elemental-travel)))
+              (3 (:cursed nil) `(:wheel floating))
+              (1 (:cursed nil) `(:wheel fortune))
+              (2 (:cursed nil) `(:wheel square))))
           (weapon-bonus (class)
             (loop for bonus from 1
                   for roll = (random 100) then (- roll item)
                                 ((d) '(70 18 8 3 1)))
                   when (< roll item) return bonus))
           (armour-size ()
-            (choose 68 'human
-                    13 'dwarf
-                    10 'elf
-                     7 'halfling
-                     2 'giant))
+            (pick-matching (form)
+              (68 (:user (:cleric :fighter :paladin :druid :thief)) 'human)
+              (13 (:user :dwarf) 'dwarf)
+              (10 (:user :elf) 'elf)
+              (7 (:user :halfling) 'halfling)
+              (2 (:user nil) 'giant)))
           (armour-piece (class)
             (let* ((bonus (weapon-bonus class))
                    (power (and (percentp (* 5 (1+ bonus)))
                                      (7 `(remove-curse :charges ,(d 3))))))
                    (cursedp (if (and power (eq (car power) 'remove-curse))
                                 nil
-                                (zerop (random 8)))))
+                                (cursedp 8))))
               `(:bonus ,bonus
                 ,@(and power (cons :power power))
                 :size ,(armour-size)
                 ,@(and cursedp `(:cursed t)))))
           (armour ()
-            (pick (10 `((:leather ,@(armour-piece 'd))))
-                  ( 7 `((:scale-mail ,@(armour-piece 'd))))
-                  (13 `((:chain-mail ,@(armour-piece 'c))))
-                  ( 9 `((:banded-mail ,@(armour-piece 'd))))
-                  (11 `((:plate-mail ,@(armour-piece 'b))))
-                  ( 5 `((:suit-armour ,@(armour-piece 'b))))
-                  (20 `((:shield ,@(armour-piece 'a))))
-                  ( 2 `((:scale-mail ,@(armour-piece 'd))
-                        (:shield ,@(armour-piece 'a))))
-                  ( 8 `((:chain-mail ,@(armour-piece 'c))
-                        (:shield ,@(armour-piece 'a))))
-                  ( 5 `((:banded-mail ,@(armour-piece 'd))
-                        (:shield ,@(armour-piece 'a))))
-                  (10 `((:plate-mail ,@(armour-piece 'b))
-                        (:shield ,@(armour-piece 'a))))))
+            (pick-matching (form)
+              (10 (:user (:cleric :fighter :paladin :druid :thief
+                          :dwarf :elf :halfling))
+                  `((:armour leather ,@(armour-piece 'd))))
+              ( 7 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour scale-mail ,@(armour-piece 'd))))
+              (13 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour chain-mail ,@(armour-piece 'c))))
+              ( 9 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour banded-mail ,@(armour-piece 'd))))
+              (11 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour plate-mail ,@(armour-piece 'b))))
+              ( 5 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour suit ,@(armour-piece 'b))))
+              (20 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:shield ,@(armour-piece 'a))))
+              ( 2 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour scale-mail ,@(armour-piece 'd))
+                    (:shield ,@(armour-piece 'a))))
+              ( 8 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour chain-mail ,@(armour-piece 'c))
+                    (:shield ,@(armour-piece 'a))))
+              ( 5 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour banded-mail ,@(armour-piece 'd))
+                    (:shield ,@(armour-piece 'a))))
+              (10 (:user (:cleric :fighter :paladin :dwarf :elf :halfling))
+                  `((:armour plate-mail ,@(armour-piece 'b))
+                    (:shield ,@(armour-piece 'a))))))
           (opponent ()
             (choose 6 'bugs
                     3 'constructs
           (missile ()
             (multiple-value-bind
                 (item class)
-                (pick (37 (values :arrow 'a))
-                      (22 (values :quarrel 'a))
-                      (11 (values :sling-stone 'a))
-                      (2 (values :blowgun 'd))
-                      (8 (values :long-bow 'd))
-                      (5 (values :short-bow 'd))
-                      (2 (values :heavy-crossbow 'd))
-                      (5 (values :light-crossbow 'd))
-                      (8 (values :sling 'd)))
+                (pick-matching (form)
+                  (37 (:user (:thief :fighter :paladin :mystic
+                             :dwarf :elf :halfling))
+                      (values :arrow 'a))
+                  (22 (:user (:thief :fighter :paladin :mystic
+                                     :dwarf :elf :halfling))
+                      (values :quarrel 'a))
+                  (11 (:user (:cleric :druid :thief :fighter :paladin
+                              :mystic :dwarf :elf :halfling))
+                      (values :sling-stone 'a))
+                  (2 (:user (:thief :fighter :paladin :mystic
+                             :dwarf :elf :halfling))
+                     (values :blowgun 'd))
+                  (8 (:user (:thief :fighter :paladin :mystic
+                             :dwarf :elf :halfling))
+                     (values :long-bow 'd))
+                  (5 (:user (:thief :fighter :paladin :mystic
+                             :dwarf :elf :halfling))
+                     (values :short-bow 'd))
+                  (2 (:user (:thief :fighter :paladin :mystic
+                             :dwarf :elf :halfling))
+                     (values :heavy-crossbow 'd))
+                  (5 (:user (:thief :fighter :paladin :mystic
+                             :dwarf :elf :halfling))
+                     (values :light-crossbow 'd))
+                  (8 (:user (:cleric :druid :thief :fighter :paladin
+                             :mystic :dwarf :elf :halfling))
+                     (values :sling 'd)))
               (ecase class
                 ((a) (let* ((bonus (weapon-bonus 'a))
                             (cursedp (zerop (random 10)))
                             (talent (and (percentp (* 5 (- 7 bonus)))
--                                        (choose 4 'biting
--                                                5 'blinking
--                                                5 'charming
--                                                7 'climbing
--                                                10 'curing
--                                                3 'disarming
--                                                4 'dispelling
--                                                7 'flying
--                                                7 'lightning
--                                                5 'penetrating
--                                                4 'refilling
--                                                6 'screaming
--                                                5 'seeking
--                                                4 'sinking
--                                                2 'slaying
--                                                7 'speaking
--                                                4 'stunning
--                                                2 'teleporting
--                                                5 'transporting
--                                                4 'wounding)))
++                                        (pick (4 'biting)
++                                              (5 'blinking)
++                                              (5 'charming)
++                                              (7 'climbing)
++                                              (10 'curing)
++                                              (3 'disarming)
++                                              (4 'dispelling)
++                                              (7 'flying)
++                                              (7 'lightning)
++                                              (5 'penetrating)
++                                              (4 'refilling)
++                                              (6 'screaming)
++                                              (5 'seeking)
++                                              (4 'sinking)
++                                              (2 `(slaying
++                                                   :opponent ,(opponent)))
++                                              (7 'speaking)
++                                              (4 'stunning)
++                                              (2 'teleporting)
++                                              (5 'transporting)
++                                              (4 'wounding))))
                             (number (ecase bonus
                                       ((1) (d 10 2))
                                       ((2) (d 8 2))
                          :number ,number
                          ,@(and cursedp `(:cursed t)))))
                 ((d) (let* ((bonus (weapon-bonus 'd))
-                            (cursedp (zerop (random 10)))
+                            (cursedp (cursedp 10))
                             (modifier (weapon-modifier bonus :missilep t))
                             (range (ecase (+ bonus (d 4))
                                      ((2 3 4) nil)
           (sword ()
             (multiple-value-bind
                 (type class)
-                (pick (65 (values :normal-sword 'c))
-                      (19 (values :short-sword 'c))
-                      (8 (values :two-handed-sword 'd))
-                      (8 (values :bastard-sword 'd)))
+                (pick-matching (form)
+                  (65 nil (values :normal-sword 'c))
+                  (19 nil (values :short-sword 'c))
+                  (8 (:user (:fighter :paladin :dwarf :mystic :elf))
+                     (values :two-handed-sword 'd))
+                  (8 (:user (:fighter :paladin :dwarf
+                             :mystic :elf :halfling))
+                     (values :bastard-sword 'd)))
               (let* ((bonus (weapon-bonus class))
                      (cursedp (zerop (random 10)))
                      (modifier (sword-modifier bonus))
                   ,@(and cursedp `(:cursed t))))))
           (weapon ()
             (multiple-value-bind
-                (type returnsp class)
-                (pick (7 (values :battle-axe nil 'd))
-                      (8 (values :hand-axe (choose 3 nil 1 t) 'b))
-                      (3 (values :blackjack nil 'c))
-                      (3 (values :bola (choose 2 nil 1 t) 'b))
-                      (5 (values :club nil 'c))
-                      (14 (values :dagger (choose 11 nil 3 t) 'b))
-                      (4 (values :one-handed-flail nil 'c))
-                      (2 (values :two-handed-flail nil 'd))
-                      (3 (values :halberd nil 'd))
-                      (8 (values :war-hammer nil 'c))
-                      (4 (values :javelin (choose 3 nil 1 t) 'b))
-                      (4 (values :lance nil 'd))
-                      (7 (values :mace nil 'c))
-                      (5 (values :morning-star nil 'c))
-                      (3 (values :net (choose 2 nil 1 t) 'b))
-                      (3 (values :pike nil 'd))
-                      (2 (values :pole-axe nil 'd))
-                      (12 (values :spear (choose 3 nil 1 t) 'b))
-                      (3 (values :whip nil 'c)))
+                (type returnsp intelpc class)
+                (pick-matching (form)
+                  (7 (:user (:fighter :paladin :mystic :dwarf :elf))
+                     (values :battle-axe nil 30 'd))
+                  (8 (:user (:fighter :paladin :mystic :dwarf :thief
+                             :elf :halfling))
+                     (values :hand-axe (choose 3 nil 1 t) nil 'b))
+                  (3 (:user (:fighter :paladin :mystic :dwarf :cleric
+                             :elf :halfling))
+                     (values :blackjack nil nil 'c))
+                  (3 (:user (:fighter :paladin :mystic :dwarf :cleric
+                             :thief :elf :halfling))
+                     (values :bola (choose 2 nil 1 t) nil 'b))
+                  (5 (:user (:fighter :paladin :mystic :dwarf
+                             :thief :cleric :druid :elf :halfling))
+                     (values :club nil nil 'c))
+                  (14 (:user (:fighter :paladin :mystic :dwarf :magic-user
+                              :thief :elf :halfling))
+                      (values :dagger (choose 11 nil 3 t) 50 'b))
+                  (4 (:user (:fighter :paladin :mystic :dwarf :cleric
+                             :elf :halfling :thief))
+                     (values :one-handed-flail nil nil 'c))
+                  (2 (:user (:fighter :paladin :mystic :dwarf :cleric :elf))
+                     (values :two-handed-flail nil nil 'd))
+                  (3 (:user (:fighter :paladin :mystic :dwarf :elf))
+                     (values :halberd nil 20 'd))
+                  (8 (:user (:fighter :paladin :mystic :dwarf :cleric
+                             :druid :elf :halfling :thief))
+                     (values :war-hammer nil 30 'c))
+                  (4 (:user (:fighter :paladin :mystic :dwarf :thief
+                             :elf :halfling))
+                     (values :javelin (choose 3 nil 1 t) nil 'b))
+                  (4 (:user (:fighter :paladin :mystic :dwarf :elf))
+                     (values :lance nil nil 'd))
+                  (7 (:user (:fighter :paladin :mystic :dwarf :cleric :thief
+                             :elf :halfling :druid))
+                     (values :mace nil 35 'c))
+                  (5 (:user (:fighter :paladin :mystic :dwarf :cleric :thief
+                             :elf :halfling))
+                     (values :morning-star nil nil 'c))
+                  (3 (:user (:fighter :paladin :mystic :dwarf :cleric :thief
+                             :druid :elf :halfling))
+                     (values :net (choose 2 nil 1 t) nil 'b))
+                  (3 (:user (:fighter :paladin :mystic :dwarf :elf))
+                     (values :pike nil 20 'd))
+                  (2 (:user (:fighter :paladin :mystic :dwarf :elf))
+                     (values :pole-axe nil 20 'd))
+                  (12 (:user (:fighter :paladin :mystic :dwarf :thief
+                              :elf :halfling))
+                      (values :spear (choose 3 nil 1 t) nil 'b))
+                  (4 (:user (:fighter :paladin :mystic :dwarf :thief :cleric
+                             :druid :elf :halfling :magic-user))
+                     (values :staff nil 20 'd))
+                  (3 (:user (:fighter :paladin :mystic :dwarf :thief :cleric
+                             :druid :elf :halfling))
+                     (values :whip nil nil 'c)))
               (let* ((bonus (weapon-bonus class))
-                     (cursedp (zerop (random 10)))
+                     (cursedp (cursedp 10))
                      (modifier (sword-modifier bonus))
-                     (intel (and (percentp 40)
+                     (intel (and intelpc
+                                 (percentp intelpc)
                                  (weapon-intelligence))))
                 `(,type
                   ,@(and returnsp `(:returning t))
                   ,@modifier
                   ,@intel
                   ,@(and cursedp `(:cursed t)))))))
-     (pick ((if (symbol-match-p form :potion) 25 0) (list (potion)))
-         ((if (symbol-match-p form :scroll) 12 0) (list (scroll)))
-         ((if (symbol-match-p form :wandlike) 9 0) (list (wandlike)))
-         ((if (symbol-match-p form :ring) 6 0) (list (ring)))
-         ((if (symbol-match-p form :misc) 10 0) (list (misc-item)))
-         ((if (symbol-match-p form :armour) 10 0) (armour))
-         ((if (symbol-match-p form :missile) 11 0) (list (missile)))
-         ((if (symbol-match-p form :sword) 9 0) (list (sword)))
-         ((if (symbol-match-p form :weapon) 8 0) (list (weapon))))))
+     (pick-matching (form)
+       (25 (:type :potion) (list (potion)))
+       (12 (:type :scroll) (list (scroll)))
+       (9 (:type :wandlike :cursed nil) (list (wandlike)))
+       (6 (:type :ring) (list (ring)))
+       (10 (:type :misc) (list (misc-item)))
+       (10 (:type :armour
+          :user (:cleric :druid :fighter :paladin
+                 :thief :dwarf :elf :halfling))
+         (armour))
+       (11 (:type :missile) (list (missile)))
+       (9 (:type :sword
+         :user (:fighter :paladin :mystic :thief :dwarf :elf :halfling))
+        (list (sword)))
+       (8 (:type :weapon) (list (weapon))))))
  
  (defun treasure-type (type-code)
    (labels ((common-fur-type ()
                               'mink
                               'sable))
           (special (n)
-            (tagged-bag
+            (cons
              :special
              (loop repeat n
                    collect
                              (intern (format nil "STAR-~A"
                                              (string kind))))))))
           (gems (n)
-            (tagged-bag
+            (cons
              :gems
              (loop while (plusp n)
                    for i = (min n (d 5))
                                    (2 (values 'good 4))
                                    (1 (values 'very-good 8)))
                            (setf mod-list
-                                 (append `(:size ,mod) mod-list))
+                                 (append `(:quality ,mod) mod-list))
                            (setf value (* value mult))))
                      `(:kind ,kind
                        :value ,(max 1 (round value))
                        ,@mod-list
                        ,@(and (> i 1) `(:quantity ,i))))))))
           (jewellery (n)
-            (tagged-bag
+            (cons
              :jewellery
              (loop while (plusp n)
                    for i = (min n (d 5))
                          :encumbrance ,enc
                          ,@(and (> i 1) `(:quantity ,i))))))))
           (magic (&rest forms)
-            (tagged-bag :magic
-                        (loop with list = nil
-                              for (form n) on forms by #'cddr do
-                              (loop repeat n do
-                                    (dolist (item (magic-item form))
-                                      (push item list)))
-                              finally (return list)))))
+            (cons :magic
+                  (loop with list = nil
+                        for (form n) on forms by #'cddr do
+                        (loop repeat n do
+                              (dolist (item (magic-item (list :type form)))
+                                (push item list)))
+                        finally (return list)))))
      (ecase type-code
  
        ;; treasure in lair
                (and (percentp 50) (gems (d 6 6)))
                (and (percentp 50) (jewellery (d 6 6)))
                (and (percentp 10) (special (d 2)))
-               (and (percentp 30) (magic t 3))))
+               (and (percentp 30) (magic :any 3))))
        ((b) (bag (tagged-bag :coins
                            (and (percentp 50) `(:cp ,(* 1000 (d 8))))
                            (and (percentp 25) `(:sp ,(* 1000 (d 6))))
                (and (percentp 50) (gems (d 6 6)))
                (and (percentp 50) (jewellery (d 6 6)))
                (and (percentp 5) (special (d 2)))
-               (and (percentp 10) (magic t 2))))
+               (and (percentp 10) (magic :any 2))))
        ((d) (bag (tagged-bag :coins
                            (and (percentp 10) `(:cp ,(* 1000 (d 8))))
                            (and (percentp 15) `(:sp ,(* 1000 (d 12))))
                (and (percentp 30) (gems (d 8)))
                (and (percentp 30) (jewellery (d 8)))
                (and (percentp 10) (special (d 2)))
-               (and (percentp 10) (magic t 1 :potion 1))))
+               (and (percentp 10) (magic :any 1 :potion 1))))
        ((e) (bag (tagged-bag :coins
                            (and (percentp 5) `(:cp ,(* 1000 (d 10))))
                            (and (percentp 30) `(:sp ,(* 1000 (d 12))))
                (and (percentp 10) (gems (d 10)))
                (and (percentp 10) (jewellery (d 10)))
                (and (percentp 15) (special (d 2)))
-               (and (percentp 25) (magic t 3 :scroll 1))))
+               (and (percentp 25) (magic :any 3 :scroll 1))))
        ((f) (bag (tagged-bag :coins
                            (and (percentp 30) `(:sp ,(* 1000 (d 10 2))))
                            (and (percentp 20) `(:ep ,(* 1000 (d 8))))
                (and (percentp 25) (gems (d 6 3)))
                (and (percentp 25) (jewellery (d 10)))
                (and (percentp 30) (special (d 3)))
-               (and (percentp 35) (magic t 4 :scroll 1))))
+               (and (percentp 35) (magic :any 4 :scroll 1))))
        ((h) (bag (tagged-bag :coins
                            (and (percentp 25) `(:cp ,(* 1000 (d 8 3))))
                            (and (percentp 50) `(:sp ,(* 1000 (d 100))))
                (and (percentp 50) (gems (d 100)))
                (and (percentp 50) (jewellery (* 10 (d 4))))
                (and (percentp 10) (special (d 2)))
-               (and (percentp 15) (magic t 4 :potion 1 :scroll 1))))
+               (and (percentp 15) (magic :any 4 :potion 1 :scroll 1))))
        ((i) (bag (tagged-bag :coins
                            (and (percentp 30) `(:pp ,(* 1000 (d 8)))))
                (and (percentp 50) (gems (d 6 2)))
                (and (percentp 50) (jewellery (d 6 2)))
                (and (percentp 5) (special (d 2)))
-               (and (percentp 15) (magic t 1))))
+               (and (percentp 15) (magic :any 1))))
        ((j) (bag (tagged-bag :coins
                            (and (percentp 25) `(:cp ,(* 1000 (d 4))))
                            (and (percentp 10) `(:sp ,(* 1000 (d 3)))))))
                (and (percentp 5) (gems (d 2)))
                (and (percentp 5) (gems (d 4)))
                (and (percentp 2) (special 1))
-               (and (percentp 2) (magic t 1))))
+               (and (percentp 2) (magic :any 1))))
        ((v) (bag (tagged-bag :coins
                            (and (percentp 10) `(:sp ,(d 100)))
                            (and (percentp 5) `(:ep ,(d 100)))
                (and (percentp 10) (gems (d 2)))
                (and (percentp 10) (gems (d 4)))
                (and (percentp 5) (special 1))
-               (and (percentp 5) (magic t 1))))
+               (and (percentp 5) (magic :any 1))))
  
        ;; unguarded treasures
        ((unguarded-1)
                        (and (percentp 50) `(:gp ,(* 10 (d 6)))))
            (and (percentp 5) (gems (d 6)))
            (and (percentp 2) (jewellery (d 6)))
-           (and (percentp 2) (magic t 1))))
+           (and (percentp 2) (magic :any 1))))
        ((unguarded-2 unguarded-3)
         (bag (tagged-bag :coins
                        `(:sp ,(* 100 (d 12)))
                        (and (percentp 50) `(:gp ,(* 100 (d 6)))))
            (and (percentp 10) (gems (d 6)))
            (and (percentp 5) (jewellery (d 6)))
-           (and (percentp 8) (magic t 1))))
+           (and (percentp 8) (magic :any 1))))
        ((unguarded-4 unguarded-5)
         (bag (tagged-bag :coins
                        `(:sp ,(* 1000 (d 6)))
                        `(:gp ,(* 200 (d 6))))
            (and (percentp 20) (gems (d 8)))
            (and (percentp 10) (jewellery (d 8)))
-           (and (percentp 10) (magic t 1))))
+           (and (percentp 10) (magic :any 1))))
        ((unguarded-6 unguarded-7)
         (bag (tagged-bag :coins
                        `(:sp ,(* 2000 (d 6)))
                        `(:gp ,(* 500 (d 6))))
            (and (percentp 30) (gems (d 10)))
            (and (percentp 15) (jewellery (d 10)))
-           (and (percentp 15) (magic t 1))))
+           (and (percentp 15) (magic :any 1))))
        ((unguarded-8 unguarded-9)
         (bag (tagged-bag :coins
                        `(:sp ,(* 5000 (d 6)))
                        `(:gp ,(* 1000 (d 6))))
            (and (percentp 40) (gems (d 12)))
            (and (percentp 20) (jewellery (d 12)))
-           (and (percentp 20) (magic t 1)))))))
+           (and (percentp 20) (magic :any 1)))))))
+ (defconstant combine-treasures
+   '((:coins (t . +))
+     (t . append)))
+ (defun combine2 (spec a b)
+   (labels ((comb (tag x y)
+            (dolist (pair spec)
+              (let ((label (car pair)))
+                (when (or (eq label t)
+                          (eq label tag))
+                  (return-from comb
+                    (let ((method (cdr pair)))
+                      (etypecase method
+                        (list (combine2 method x y))
+                        ((member +) (list (+ (car x) (car y))))
+                        ((or symbol function)
+                         (funcall method x y))))))))
+            (error "No combiner found for ~S." tag)))
+     (let ((list nil))
+       (dolist (pair a)
+       (let* ((tag (car pair))
+              (match (assoc tag b)))
+         (push (if (null match)
+                   pair
+                   (cons tag
+                         (comb tag (cdr pair) (cdr match))))
+               list)))
+       (dolist (pair b)
+       (let* ((tag (car pair))
+              (match (assoc tag a)))
+         (unless match
+           (push pair list))))
+       (nreverse list))))
+ (defun combine (spec &rest lists)
+   (reduce (lambda (x y) (combine2 spec x y)) lists))
+ (defun treasure (types)
+   (apply #'combine
+        combine-treasures
+        (loop for type in types
+              collect (treasure-type type))))
+ (defun select-spells (table spells)
+   (loop for n in spells
+       for list across table
+       collect (sort (loop repeat n collect (apply #'choose-uniformly list))
+                     #'string<)))
diff --combined monsters.tex
  
  \fi
  
 -\def\swimming{\unskip\penalty100/\ignorespaces}
 -\def\flying{\unskip\penalty100/$\!\!\!$/\ignorespaces}
 -
  \begin{document}
  
  \twocolumn[\sect{Monsters}\bigskip]
@@@ -1624,7 -1627,18 +1624,18 @@@ turns; with colour change)
  
  \begin{monster}{Harpy}{
      60 \flying 150 &
-     3*(M), F6, XP50 d{1d4} \times 10$ years) &
+     3*(M), F6, XP50 &
+     AC7, T17; claw ($2 \times \d{1d4}$) \emph{or} weapon &
+     M, R(H,M); 1d6~(2d4) &
+     I7, C, ML7; C}
+   Singing: hearers SvS or are \emph{charmed}.
+ \end{monster}
+ \begin{monster}[3]{Haunt**}{
+     \h Banshee &
+     \flying 60 &
+     13$^4$*(M), ---, XP5150 &
+     AC$^-3$, T9; touch (age $\d{1d4} \times 10$ years) &
      U, VR(R); 1~(1) &
      I12, C, ML9; E, N, O \\
      \h Ghost &
diff --combined spells.tex
@@@ -43,6 -43,7 +43,7 @@@
  \newenvironment{spells}[1]{%
    \raggedright%
    \begin{multicols}{2}[\sect{#1}]%
+   \small%
    \itemcount1%
    \def\levelstart{%
      \medskip%
@@@ -53,8 -54,8 +54,8 @@@
        \let\makelabel\hbox%
        \desclabelstyle{\nextlinelabel}%
        \desclabelwidth{2em}%
-       \parsep\z@%
-       \itemsep\medskipamount%
+       \parsep\smallskipamount%
+       \itemsep\smallskipamount%
      }%
      \ignorespaces%
    }%
@@@ -429,8 -430,7 +430,8 @@@ Allows SvS against \emph{fear} attacks
  \emph{cause fear} ($120'$, 2T, 1 creature): SvS or flee.
  
  \spell{Resist cold}{0, 6T, $30'$}
 -Withstand normal cold; $+2$ on saves against cold and damage biased by $-1$.
 +Unharmed by normal cold; $+2$ on saves against cold and damage biased by $-1$
 +per die.
  
  \level
  
@@@ -446,8 -446,7 +447,8 @@@ SvS or paralysed.  Penalty $-2$ on sav
  Cancelled by \emph{dispel magic} or reverse.  Reverse \emph{free person}.
  
  \spell{Resist fire}{$30'$, 2T, 1 creature}
 -Withstand normal fire; $+2$ on saves against fire and damaged biased by $-1$.
 +Unharmed by normal fire; $+2$ on saves against fire and damaged biased by
 +$-1$ per die.
  
  \spell{Silence 15$'$ radius}{$180'$, 12T, $30'\phi$}
  Area cannot cause sound (sound may still enter from outside); effect moves
@@@ -516,7 -515,7 +517,14 @@@ Water springs from ground or wall.  Wat
  Heals $\d{2d6} + 2$\,hp.  Reverse \emph{cause serious wounds}: causes damage.
  
  \spell{Dispel magic}{$120'$, P, $20'$ cube}
--Destroys spells in area; fails $L' - L$ in 20.  FIXME touch dispel
++Destroys spells in area; fails $L' - L$ in 20.  Also \emph{touch dispel} (T,
++P, 1 spell effect): must be used within 1T, cannot cast other spells until
++used; nonmagical containers double effective level of contained items, max
++distance to item $5'$, random selection between contained items; item levels
++and effects are: potions (6, destroyed), scroll (as level needed to cast,
++destroyed), wand or staff (12; drains $L$ charges), misc (36 or as maker,
++drains $L$ charges or deactivated for 1d10 rounds); other permanent (18,
++deactivated for 1d10 rounds).
  
  \spell{Neutralize poison*}{T, P, 1 creature/container/object}
  Makes poison harmless; revives victim killed by poison in previous 10
@@@ -533,7 -532,8 +541,8 @@@ communication with treants
  
  \spell{Sticks to snakes}{$120'$, 6T, 2d8 sticks}
  Turns sticks into snakes (3 in 6 chance per snake of being poisonous).
- Stats: MV90, HD1(S), F1, XP10/13, AT bite (1d4, poison), I2, N, ML12.
+ MV90; HD1(S), 20\,hp, F1, XP10/13; AC6, T19; bite (1d4, poison); A; I2, N,
+ ML12.
  
  \level
  
@@@ -555,9 -555,9 +564,9 @@@ for as long as the caster concentrates 
  \emph{curse} from an item, or a \emph{charm} effect.
  
  \spell{Insect plague}{$480'$, 1D, swarm $60'\phi$}
 -Swarm obscures vision; drives off creatures with 3HD or less; MV60.  Caster
 -must concentrate without moving to control swarm, otherwise the insects
 -scatter.  Only works outdoors.
 +Swarm obscures vision; drives off creatures with 3HD or less; MV\flying60.
 +Caster must concentrate without moving to control swarm, otherwise the
 +insects scatter.  Only works outdoors.
  
  \spell{Quest*}{$30'$, until completed, 1 creature}
  Compels creature to perform quest; \emph{curse} applies until performed.
@@@ -572,7 -572,7 +581,7 @@@ undead with 9HD or less, target must Sv
  half).  Reverse \emph{finger of death} ($60'$, I, 1 creature): SvDR or die;
  against undead with more than 9HD, cures 3d10\,hp damage.
  
- \spell{Truesight}{0, $1\textrm{T} + L\textrm{R}$}
+ \spell{Truesight}{0, $1\textrm{T} + L\textrm{R}$, $120'$}
  Caster can see all hidden, invisible and Ethereal objects in range, in their
  true forms, undisguised; experience and power (level/HD) and basic character
  traits (alignment-ish) detected.
@@@ -650,11 -650,11 +659,11 @@@ for 2d10 days.  Reverse \emph{life drai
  Protects target from all non-magical environmental damage.
  
  \spell{Travel}{0, $L$T}
- Allows free travel.  Flying (MV\flying360); move between planes by one
- round's concentration (at most 1 per turn), bringing along $\lfloor L/5
- \rfloor$ others touched; assume gaseous form by one round's concentration
- (with all equipment; MV\flying720, AC$^-2$, cannot pass \emph{protection from
evil} or \emph{anti-magic shell}).
+ Allows free travel.  MV\flying360; move between planes by one round's
+ concentration (at most 1 per turn), bringing along $\lfloor L/5 \rfloor$
+ others touched; assume gaseous form by one round's concentration (with all
+ equipment; MV\flying720, cannot pass \emph{protection from evil} or
+ \emph{anti-magic shell}).
  
  \spell{Wish}{special}
  See notes in rules.
@@@ -796,7 -796,7 +805,7 @@@ others must use \emph{dispel magic} or 
  
  \spell{Weather control}{0, C, weather within $240'$}
  Caster can create a weather condition; must be outdoors.  Possible effects:
- \begin{description*}
+ \begin{description}
  \item[Rain] Missile hit rolls have $-2$ penalty; after 3 turns, ground
    muddy, movement halved.
  \item[Snow] Visibility $20'$; half movement; water may
    move 50\% faster; sandstorm in desert ($20'$ visibility).
  \item[Tornado] Inland, whirlwind as 12HD air elemental; at sea, storm or
    gale.
- \end{description*}
+ \end{description}
  
  \end{spells}
  
@@@ -941,16 -941,17 +950,24 @@@ turn
  
  \spell{Create air}{$10'$, $6L$T, $20'$ cube of air}
  Cast on area to move effect with area; cast on person to allow breathing (and
- flight) in hostile environments.
+ flight) in hostile environments (e.g., under water, in poison gas).  Cannot
+ negate effects of breath weapon.
  
  \spell{Dispel magic}{$120'$, P, $20'$ cube}
--Destroys spells in area; fails $L' - L$ in 20.  FIXME touch dispel
++Destroys spells in area; fails $L' - L$ in 20.  Also \emph{touch dispel} (T,
++P, 1 spell effect): must be used within 1T, cannot cast other spells until
++used; nonmagical containers double effective level of contained items, max
++distance to item $5'$, random selection between contained items; item levels
++and effects are: potions (6, destroyed), scroll (as level needed to cast,
++destroyed), wand or staff (12; drains $L$ charges), misc (36 or as maker,
++drains $L$ charges or deactivated for 1d10 rounds); other permanent (18,
++deactivated for 1d10 rounds).
  
  \spell{Fire ball}{$240'$, I, $40'\phi$}
  Causes $L$d6 damage to all in effect (max 20d6, SvS for half damage).
  
  \spell{Fly}{T, $\d{1d6} + L$T, 1 creature}
 -Allows flight, MV360.  Hovering does not require concentration.
 +Allows flight, MV\flying360.  Hovering does not require concentration.
  
  \spell{Haste*}{$240'$, 3T, up to 24 creatures in $60'\phi$}
  Targets may move at twice normal speed, two attacks per round, etc.  Reverse
@@@ -1045,8 -1046,8 +1062,8 @@@ creatures of less than 4HD; breaking th
  cold-type creatures take 2d6 damage breaking through.
  
  \spell{Wizard eye}{$240'$, 6T}
 -Creates invisible eye (MV120) with infravision ($60'$ range); caster must
 -concentrate to see through the eye.
 +Creates invisible eye (MV\flying120) with infravision ($60'$ range); caster
 +must concentrate to see through the eye.
  
  \level
  
@@@ -1190,14 -1191,14 +1207,14 @@@ at unfinished ends.  Casting time up t
  \emph{stoneformed} objects.  Final casting to `lock' item down.  Can be used
  to create transparent and translucent stones.
  
--\spell{Wall of iron}{$120'$, P, 500\,sq,ft}
++\spell{Wall of iron}{$120'$, P, 500\,sq\,ft}
  Creates a $2'$ thick vertical wall; must be vertical and supported.  When
  toppled, cases 10d10 damage to anyone underneath.  Wall has hp equal to the
  caster.
  
  \spell{Weather control}{0, C, weather within $240'$}
  Caster can create a weather condition; must be outdoors.  Possible effects:
- \begin{description*}
+ \begin{description}
  \item[Rain] Missile hit rolls have $-2$ penalty; after 3 turns, ground
    muddy, movement halved.
  \item[Snow] Visibility $20'$; half movement; water may
    move 50\% faster; sandstorm in desert ($20'$ visibility).
  \item[Tornado] Inland, whirlwind as 12HD air elemental; at sea, storm or
    gale.
- \end{description*}
+ \end{description}
  
  \level
  
@@@ -1268,8 -1269,8 +1285,8 @@@ at the time, the caster will know who a
  not need to be on the same plane of existence.
  
  \spell{Sword}{$30'$, $L$R}
--Sword does 1d10 damage against any opponent in range.  Caster must
--concentrate for sword to attack.
++Sword does 1d10 damage against any opponent in range; two attacks per round;
++hit rolls as caster.  Caster must concentrate for sword to attack.
  
  \spell{Teleport any object}{T, I, 1 500\,cn object}
  Teleports an object, with normal chances of error.  Unwilling creature or
@@@ -1318,7 -1319,8 +1335,8 @@@ etc.  Can only be removed by \emph{wish
    {$120'$, as \emph{charm person}, 30HD of creatures in $20'$ cube}
  Charms up to 30HD or levels of creatures; each may save at $-2$.  If caster
  attacks a charmed creature, its charm is broken; others seeing attack may
- save again.
+ save again.  Reverse \emph{remove charm} ($120'$, 1T, $20'$ cube): removes
+ and prevents all charm effects in volume.
  
  \spell{Mind barrier*}{$10'$, $6L$T, 1 creature}
  Prevents \emph{ESP}, \emph{clairvoyance}, \emph{clairaudience}, \emph{crystal
@@@ -1356,7 -1358,7 +1374,7 @@@ item down
  Place symbol on object or in mid-air.  When creature passes over or through
  the symbol, or touches or reads it, effect occurs (SvS only for magic-users,
  elves etc., if touched or read but not passed).
- \begin{description*}
+ \begin{description}
  \item[Death] Slays creature with 75\,hp or less.
  \item[Discord] Attacks allies, or is otherwise \emph{confused} until
    dispelled or cured (e.g., by \emph{cureall}).
    abilities until dispelled or cured (e.g., by \emph{cureall}).
  \item[Sleep] Falls asleep for $\d{1d10} + 10$ hours or until dispelled.
  \item[Stunning] Stuns creature with 150\,hp or less for 2d6 rounds.
- \end{description*}
+ \end{description}
  
  \spell{Travel}{0, $L$T}
- Allows free travel.  Flying (MV\flying360); move between planes by one
- round's concentration (at most 1 per turn), bringing along $\lfloor L/5
- \rfloor$ others touched; assume gaseous form by one round's concentration
- (with all equipment; MV\flying720, AC$^-2$, cannot pass \emph{protection from
evil} or \emph{anti-magic shell}).
+ Allows free travel.  MV\flying360); move between planes by one round's
+ concentration (at most 1 per turn), bringing along $\lfloor L/5 \rfloor$
+ others touched; assume gaseous form by one round's concentration (with all
+ equipment; MV\flying720, cannot pass \emph{protection from evil} or
+ \emph{anti-magic shell}).
  
  \level
  
diff --combined treasure.tex
@@@ -4,16 -4,13 +4,13 @@@
  \def\nil{\multicolumn{2}{c}{---}}
  \def\lnil{\multicolumn{2}{l}{---}}
  
- \makeatletter
- \def\subsect#1{\goodbreak\medskip\textbf{#1}\par\nobreak\@nobreaktrue}
  \renewenvironment{description}{%
    \basedescript{%
      \let\makelabel\textit%
      \desclabelstyle{\pushlabel}%
      \desclabelwidth{2em}%
      \parsep\z@%
-     \itemsep\medskipamount%
+     \itemsep\smallskipamount%
    }%
  }{%
    \endbasedescript%
    97--98   & Wishes               \\ \hlx{+}
    99--00   & X-ray vision         \\ \hlx*{vh}
  \end{tabular}
+ \line
+ \begin{tabular}{\shade cl} \hlx*{hv}
+   \tt{Elements (for staff/ring)} \\
+   \th{d\%} & \th{Element}    \\ \hlx{vhv}
+    01--21  & Air             \\ \hlx{+}
+    22--42  & Earth           \\ \hlx{+}
+    43--63  & Fire            \\ \hlx{+}
+    64--84  & Water           \\ \hlx{+}
+    85--91  & Air and Water   \\ \hlx{+}
+    92--98  & Earth and Fire  \\ \hlx{+}
+    99--00  & All elements    \\ \hlx*{vh}
+ \end{tabular}
  \end{set}
  
  \begin{set}
  \end{tabular}
  \colgap
  \begin{tabular}{\shade cl} \hlx*{hv}
-   \tt{Opponents} \\
-   \th{d\%} & \th{Type}                \\ \hlx{vhv}
-    00--06  & Bugs                     \\ \hlx{+}
-    05--09  & Constructs               \\ \hlx{+}
-    10--15  & Dragonkind               \\ \hlx{+}
-    16--24  & Enchanted monsters       \\ \hlx{+}
-    25--36  & Giantkind                \\ \hlx{+}
-    37--48  & Lycanthropes             \\ \hlx{+}
-    49--52  & Planar monsters          \\ \hlx{+}
-    53--58  & Regenerating monsters    \\ \hlx{+}
-    59--67  & Reptiles, dinosaurs      \\ \hlx{+}
-    68--70  & Spell-immune monsters    \\ \hlx{+}
-    71--76  & Spellcasters             \\ \hlx{+}
-    77--88  & Undead                   \\ \hlx{+}
-    89--94  & Water-breathing monsters \\ \hlx{+}
-    95--00  & Weapon-using monsters    \\ \hlx*{vh}
- \end{tabular}
- \colgap
- \begin{tabular}{\shade cl} \hlx*{hv}
    \tt{Missile talents} \\
-   \th{d\%} & \th{Talent}  \\ \hlx{vhv}
-     01--04 & Biting       \\ \hlx{+}
-     05--09 & Blinking     \\ \hlx{+}
-     10--14 & Charming     \\ \hlx{+}
-     15--21 & Climbing     \\ \hlx{+}
-     22--31 & Curing       \\ \hlx{+}
-     32--34 & Disarming    \\ \hlx{+}
-     35--38 & Dispelling   \\ \hlx{+}
-     39--45 & Flying       \\ \hlx{+}
-     46--52 & Lightning    \\ \hlx{+}
-     53--57 & Penetrating  \\ \hlx{+}
-     58--61 & Refilling    \\ \hlx{+}
-     62--67 & Screaming    \\ \hlx{+}
-     68--72 & Seeking      \\ \hlx{+}
-     73--76 & Sinking      \\ \hlx{+}
-     77--78 & Slaying      \\ \hlx{+}
-     79--85 & Speaking     \\ \hlx{+}
-     86--89 & Stunning     \\ \hlx{+}
-     90--91 & Teleporting  \\ \hlx{+}
-     92--96 & Transporting \\ \hlx{+}
-     97--00 & Wounding     \\ \hlx*{vh}
+   \th{d\%} & \th{Talent}              \\ \hlx{vhv}
+     01--04 & Biting                   \\ \hlx{+}
+     05--09 & Blinking                 \\ \hlx{+}
+     10--14 & Charming                 \\ \hlx{+}
+     15--21 & Climbing                 \\ \hlx{+}
+     22--31 & Curing                   \\ \hlx{+}
+     32--34 & Disarming                \\ \hlx{+}
+     35--38 & Dispelling               \\ \hlx{+}
+     39--45 & Flying                   \\ \hlx{+}
+     46--52 & Lightning                \\ \hlx{+}
+     53--57 & Penetrating              \\ \hlx{+}
+     58--61 & Refilling                \\ \hlx{+}
+     62--67 & Screaming                \\ \hlx{+}
+     68--72 & Seeking                  \\ \hlx{+}
+     73--76 & Sinking                  \\ \hlx{+}
+     77--78 & Slaying \emph{opp.}      \\ \hlx{+}
+     79--85 & Speaking                 \\ \hlx{+}
+     86--89 & Stunning                 \\ \hlx{+}
+     90--91 & Teleporting              \\ \hlx{+}
+     92--96 & Transporting             \\ \hlx{+}
+     97--00 & Wounding                 \\ \hlx*{vh}
  \end{tabular}
  \quad
  \begin{tabular}{\shade cl} \hlx*{hv}
     95--99  & Watching      \\ \hlx{+}
       00    & Wishing       \\ \hlx*{vh}
  \end{tabular}
+ \colgap
+ \begin{tabular}{\shade cl} \hlx*{hv}
+   \tt{Opponents} \\
+   \th{d\%} & \th{Type}                \\ \hlx{vhv}
+    00--06  & Bugs                     \\ \hlx{+}
+    05--09  & Constructs               \\ \hlx{+}
+    10--15  & Dragonkind               \\ \hlx{+}
+    16--24  & Enchanted monsters       \\ \hlx{+}
+    25--36  & Giantkind                \\ \hlx{+}
+    37--48  & Lycanthropes             \\ \hlx{+}
+    49--52  & Planar monsters          \\ \hlx{+}
+    53--58  & Regenerating monsters    \\ \hlx{+}
+    59--67  & Reptiles, dinosaurs      \\ \hlx{+}
+    68--70  & Spell-immune monsters    \\ \hlx{+}
+    71--76  & Spellcasters             \\ \hlx{+}
+    77--88  & Undead                   \\ \hlx{+}
+    89--94  & Water-breathing monsters \\ \hlx{+}
+    95--00  & Weapon-using monsters    \\ \hlx*{vh}
+ \end{tabular}
  \quad
  \end{set}
  
     01--10  & Clairaudience                                  \\ \hlx{+}
     11--20  & Clairvoyance                                   \\ \hlx{+}
     21--30  & ESP                                            \\ \hlx{+}
-    31--35  & Extra damage ($\times\,5$ or more)\s d
+    31--35  & Extra damage ($\times\,4$ or more)\s d
                                                              \\ \hlx{+}
     36--40  & Flying                                         \\ \hlx{+}
     41--45  & Healing (6\,hp)\s d                            \\ \hlx{+}
  \end{tabular}
  \end{set}
  
- \sect{Magical items}
- \begin{multicols}{2}
+ \begin{multicols}{2}[\sect{Magical items}]
 -%%\twocolumn[\sect{Magical items}\medskip]
 -
  \raggedright
  
  \subsect{Potions}
  
- \begin{itemize*}
- \item \textbf{Level:} Treat as 6th level.
- \item \textbf{Duration:} Usually $\d{1d6} + 6$ turns.
- \item \textbf{Control:} User must concentrate to control victims: cannot
-   fight, half movement; victim allowed SvS, but attempt may be repeated each
-   round.  Range is $60'$.
- \end{itemize*}
+ Treat as 6th level magic.  Duration usually $\d{1d6} + 6$ turns.
+ \textbf{Control potions:} User must concentrate to control victims: cannot
+ fight, half movement; victim allowed SvS, but attempt may be repeated each
+ round.  Range is $60'$.
  
  \begin{description}
  
  
  \subsect{Wands}
  
- \begin{itemize*}
- \item \textbf{Charges:} Usually 2d10.
- \item \textbf{Level:} Treat as 6th level.
- \end{itemize*}
+ Usually 2d10 charges.  Treat as 6th level magic.
  
  \begin{description}
  
  
  \subsect{Staves}
  
- \begin{itemize*}
- \item \textbf{Charges:} Usually 3d10.
- \item \textbf{Level:} Treat as 8th level.
- \end{itemize*}
+ Usually 3d10 charges.  Treat as 8th level magic.
  
  \begin{description}
  
  
    Usable as $+2$ weapon.
  
-   \begin{tabular}[C]{\shade cl} \hlx*{hv}
-      \th{d\%} & \th{Element}    \\ \hlx{vhv}
-       01--21  & Air             \\ \hlx{+}
-       22--42  & Earth           \\ \hlx{+}
-       43--63  & Fire            \\ \hlx{+}
-       64--84  & Water           \\ \hlx{+}
-       85--91  & Air and Water   \\ \hlx{+}
-       92--98  & Earth and Fire  \\ \hlx{+}
-       99--00  & Elemental power \\ \hlx*{vh}
-   \end{tabular}
  \item[Harming] Does $\d{1d6} + 1$ extra damage (uses charge).  Also
    \emph{cause blindness} (2), \emph{cause disease} (2), \emph{cause serious
    wounds} (3), \emph{create poison} (4).
  
  \item[Power] As \emph{staff of striking}; also \emph{fire ball},
    \emph{lightning bolt}, \emph{ice storm}, \emph{continual light}, or
-   \emph{telekinesis} (up to 2400\,cn, 6 rounds), one charge each.
+   \emph{telekinesis} (inanimate objects up to 2400\,cn, 6 rounds), one charge
+   each.
  
  \item[Snake staff] Usable as $+1$ weapon.  Turns into snake on command; SvS
-   or coils round man-size target for 1d4 turns or commanded.  MV60; HD3,
-   20\,hp, C3, XP6; AC5, T17, coil; ML12.  Spend charges to improve hit roll,
-   or transfer \emph{cure} (no range limit).
+   or coils round man-size target for 1d4 turns or commanded.  MV60; HD3(M),
+   20\,hp, C3, XP6; AC5, T17, coil; A; ML12.  Spend charges to improve hit
+   roll, or transfer \emph{cure} (no range limit).
  
  \item[Striking] Causes 2d6 damage per hit (uses charge).
  
  \item[Inertia] Spear $+3$.  Stops or releases on command; stores momentum
    while stopped.
  
 -  spells.
+ \item[Parrying] Rod $+5$ (does $\d{1d8} + 5$ damage, no $\delta S$); may
+   \emph{parry} attacks ($+5$ to AC in mel\'ee).
+ \item[Victory] Combat Results roll biased by $+25$; combat results difference
+   capped at 100.
+ \item[Weaponry] Rod $+5$; may split into two $+2$ rods which may each split
+   into two $+1$ rods.  Cannot divide by accident; easily reassembled.  All
+   rods do $\d{1d8} + \delta G$ damage (no $\delta S$).
+ \item[Wyrm] Rod $+5$ (does $\d{1d8} + 5$ damage, no $\delta S$).  On command,
+   once per day, changes into small dragon (d10: 1--5 10 gold, 6--8 blue,
+   9--10 black) with 30\,hp, harmed only by magic; may be magically healed.
+ \end{description}
+ \subsect{Rings}
+ Maximum one ring per hand.
+ \begin{description}
+ \item[Animal control] Command 1d6 normal or one giant animal; no save;
+   requires concentration; animals may flee or attack afterwards.  Usable once
+   per turn.
+ \item[Delusion] Believed to be some other kind of ring.
+ \item[Djinni summoning] Summon djinni to serve for one day.  Usable once per
+   week.
+ \item[Ear] Worn as earring.  Placed against surface; user hears sounds within
+   $60'$ of surface.  Usable three times per day.
+ \item[Elemental adaptation] Permits vision and breathing on elemental plane.
+ \item[Fire resistance] Withstand normal fire; $+2$ to save against fire and
+   damage biased by $-1$ per die.
+ \item[Holiness] Worn during meditation for spells; gain 1 spell each of
+   levels 1--3.  Cleric gains $+1$ on Turning rolls.
+ \item[Human control] Control up to 6HD (NM is $\tfrac{1}{2}$), similar to
+   \emph{charm person}.  Lasts until cancelled, ring removed, or charm removed
+   by \emph{dispel magic} or \emph{remove charm}.
+ \item[Invisibility] Wearer becomes invisible (with items carried) while ring
+   worn; becomes visible if attacking or casting spells.  Usable once per
+   turn; no duration limit.
+ \item[Life protection] Negates 1d6 energy drain attacks.  At zero, becomes
+   \emph{ring of protection $+1$}; at $-1$, disintegrates.
+ \item[Memory] Recall one spell cast within 1 turn.  Usable once per day.
+ \item[Plant control] Control plants (and plantlike monsters) in $30'$ square
+   within $60'$; plants can entangle but not damage.  Requires concentration.
+ \item[Protection] Bonus to AC and saving throws.  A \emph{ring of protection
+     $+1$, 5$'$ radius} applies to all within area.
+ \item[Quickness] Move and attack at double speed for one turn.  Usable once
+   per day.
+ \item[Regeneration] Regenerates 1\,hp per turn; fingers regrow in 24 hours,
+   limbs in 1 week.  Cannot regenerate fire or acid damage.  Will revive dead
+   characters.
+ \item[Remedies] Once per day, \emph{cure blindness}, \emph{cure disease},
+   \emph{remove curse} or \emph{neutralize poison}, as C25.
+ \item[Safety] Can retrospectively make saving throws; works 1d4 times and
+   disintegrates.
+ \item[Seeing] Can see all hidden, invisible and Ethereal objects within
+   $120'$, in their true forms, undisguised; experience and power (level/HD)
+   and basic character traits (alignment-ish) detected.  Duration 3 turns;
+   usable once per day.
+ \item[Spell eating] As \emph{ring of spell turning}, but `eats' user's memory
+   of spells after first one cast.  A \emph{remove curse} from C25 allows
+   removal of ring; from C36 turns it into a \emph{ring of spell turning}.
+ \item[Spell storing] Contains 1d6 spells; wearer knows spells and effects.
+   Spells replaced by casting at ring.  About 20\% of rings contain cleric
++  spells.  Effects dispelled as M5 or C8.
+ \item[Spell turning] Reflects 2d6 spells back to caster per day.
+ \item[Survival] Contains $\d{1d\%} + 100$ charges; one charge for survival
+   without food or water for 24 hours, or without air for 1 hour; turns black
+   when 5 charges left.
+ \item[Telekinesis] Move inanimate objects of up to 2000\,cn by concentration,
+   for distance of $50'$.
+ \item[Truth] Detects lies, three times per day.  Ring informs wearer of power
+   telepathically.
+ \item[Truthfulness] Ring informs wearer it is \emph{ring of truth}; when
+   activated, wearer cannot lie (or evade).  A \emph{remove curse} by C26
+   allows removal.
+ \item[Truthlessness] Ring informs wearer it is \emph{ring of truth}; when
+   activated, wearer cannot tell the truth.  A \emph{remove curse} by C26
+   allows removal.
+ \item[Water walking] Allows walking on any body of water without sinking.
+ \item[Weakness] Strength becomes 3 within 1d6 rounds; \emph{remove curse}
+   allows removal.
+ \item[Wishes] Grants 1--4 wishes (1d10: 1--4 1, 5--7 2, 8--9 3, 10 4).
+ \item[X-ray vision] See $30'$ through stone walls (or $60'$ through wood,
+   cloth or water) by concentrating, detecting traps and secret doors; blocked
+   by gold or lead; inspect $10' \times 10'$ area per turn.  Usable once per
+   hour.
+ \end{description}
+ \subsect{Miscellaneous items}
+ \begin{description}
+ \item[Amulet of protection from crystal balls and ESP] Wearer cannot be spied
+   upon by a crystal ball or any form of \emph{ESP}.
+ \item[Bag of devouring] Looks like small sack.  Items in the bag are lost
+   forever after $\d{1d6} + 6$ turns.
+ \item[Bag of holding] Looks like small sack.  Holds up to 10\,000\,cn of $10'
+   \times 5' \times 3'$ items; weighs only 600\,cn when full.
+ \item[Boat, undersea] Looks like riverboat; AC4, 40 hull points.  Obeys
+   commands to start, stop, turn, submerge, level off, and surface; bestows
+   \emph{water breathing} on passengers and crew.
+ \item[Boots of levitation] Move up and down (only) at $20'$ per round,
+   carrying up to 2000\,cn.  No duration limit.
+ \item[Boots of speed] Move at 240 for 12 hours (must rest for 1 day
+   afterwards).
+ \item[Boots of travelling and leaping] Need no rest during normal movement;
+   may jump $10'$ and $30'$ across.
+ \item[Bowl of commanding water elementals] $3'\phi$; summons a 12HD water
+   elemental (takes 1 turn), allowing control (requires concentration;
+   elemental is hostile afterwards).  Usable once per day.
+ \item[Brazier of commanding fire elementals] Summons a 12HD fire elemental
+   (takes 1 turn), allowing control (requires concentration; elemental is
+   hostile afterwards).  Usable once per day.
+ \item[Broom of flying] On command, carries owner at MV\flying240 (can carry
+   2000\,cn at MV\flying180).
+ \item[Censer of controlling air elementals] Summons a 12HD air elemental
+   (takes 1 turn), allowing control (requires concentration; elemental is
+   hostile afterwards).  Usable once per day.
+ \item[Chime of time] $3''$ silvery metal stick.  On command keeps track of
+   time, chiming every hour (audible by all within $60'$; a \emph{silence
+   15$'$ radius} spell dampens it to $30'$, but is dispelled).  On command,
+   shows time as gold colour extending from one end to other.
+ \item[Crystal ball] See any place or object thought about; image clarity
+   depends on familiarity with target.  Image lasts 1 turn; usable three times
+   per day.
+ \item[Crystal ball with clairaudience] As \emph{crystal ball}, but can hear
+   sound through ears of creature in area viewed.
+ \item[Crystal ball with ESP] As \emph{crystal ball}, but can listen to
+   thoughts of creature in area viewed.
+ \item[Displacer cloak] Wearer appears to be $5'$ from actual position; $+2$
+   on saves against spells, wands, turn-to-stone; $-2$ to hit in mel\'ee;
+   most missile attacks fail automatically.
+ \item[Drums of panic] Hearers $10'$--$240'$ away must SvS or flee for 3
+   turns.
+ \item[Efreeti bottle] Heavy jug $3'$ high.  When unsealed and unstoppered,
+   efreeti emerges to serve once per day for 101 days.
+ \item[Egg of wonder] Thrown up to $60'$ range; creature emerges and grows to
+   full size, obeys thrower's commands; disappears after one hour.
+   \begin{tabular}[C]{\shade cl|cl} \hlx*{hv}
+     \th{1d12} & \th{Animal} & \th{1d12} & \th{Animal} \\ \hlx{vhv}
+        \01    & Baboon, rock        & \07 & Cat, leopard  \\ \hlx{+}
+        \02    & Bat, giant          & \08 & Ferret, giant \\ \hlx{+}
+        \03    & Bear, black         & \09 & Lizard, gecko \\ \hlx{+}
+        \04    & Bear, grizzly       &  10 & Lizard, draco \\ \hlx{+}
+        \05    & Boar                &  11 & Snake, racer  \\ \hlx{+}
+        \06    & Cat, mountain lion  &  12 & Wolf, normal  \\ \hlx*{vh}
+   \end{tabular}
+ \item[Elven cloak] Wearer almost invisible (detectable 1 in 6); becomes
+   visible when attacking or casting spell, cannot become invisible for 1
+   turn.
+ \item[Elven boots] Move almost completely silently (detectable 1 in 10).
+ \item[Flying carpet] Carry one passenger at MV\flying300, two at MV\flying
+   240 or three at MV\flying180.
+ \item[Gauntlets of ogre power] Strength of 18.
+ \item[Girdle of giant strength] THAC0 12, double damage with weapon.
+ \item[Helm of alignment changing] Changes wearer's alignment; \emph{remove
+     curse} allows removal but wearer will resist.
+ \item[Helm of reading] Wearer can read any writings (strange languages,
+   magical writing, codes, etc.).  May (1 in 10) be destroyed when wearer hit;
+   destroyed if wearer killed.
+ \item[Helm of telepathy] Send messages by thought to creature within $90'$,
+   may read thoughts (requires concentration, SvS allowed to avoid thought
+   reading).
+ \item[Helm of teleportation] Allows \emph{teleport} as spell.  After first
+   use, or any use to teleport another creature, stops working until user
+   casts \emph{teleport} on it.
+ \item[Horn of blasting] Cone of sound $100' \times 20'$; 2d6 damage to those
+   in area, SvS or deafened for 1 turn.  Usable once per turn.
+ \item[Lamp, hurricane] As \emph{lamp of long burning}.  Shutters closed when
+   found; when opened the first time each day, emits gusts of wind and rain,
+   drenching all within $30'$.  All must SvS (holder automatically fails) or
+   be knocked over with carried items scattered within $60'$.
+ \item[Lamp of long burning] Burns and illuminates without using oil.  Becomes
+   nonmagical if flame doused with water.
+ \item[Metallion of ESP] Read thoughts of one creature within range by
+   concentrating for 1 round (SvS to avoid); 1 in 6 chance broadcasts thoughts
+   to all in range.
+ \item[Mirror of life trapping] If looking into mirror, SvS or be sucked into
+   it with all items.  Stores up to 20 man-size or smaller creatures, who do
+   not need food or air.  Can communicate with those trapped inside.  Breaking
+   mirror or \emph{wish} (one each) releases those trapped.
+ \item[Muzzle of training] Adjusts to fit any monster with bite attack.
+   Victim can breathe but not bite or talk.  Locks in place (as if
+   \emph{wizard lock} by M15) and unlocks by command.
+ \item[Nail, finger] Looks like $1''$--$4''$ carpentry nail.  Disappears if
+   commanded as \emph{nail of pointing}; thereafter, if user attempts to hide
+   from enemy (e.g., by using \emph{invisibility}), may appear (always first
+   time, 1 in 4 chance thereafter) as glowing finger pointing at user for 1d6
+   rounds.  A \emph{remove curse} removes the nail forever.
+ \item[Nail of pointing] Looks like $1''$--$4''$ carpentry nail.  If
+   commanded, turns into bony finger and points to named nonmagical item.
+   Cannot detect living or undead creatures; no range limit.  Usable once per
+   day.
+ \item[Ointment] Salve in small box.
+   \begin{enumerate*}
+   \item \emph{Blessing:} Bonus $+2$ on AC and saves for 1 turn.
+   \item \emph{Healing:} Cures $\d{2d6} + 2$\,hp damage.
+   \item \emph{Poison:} Seems like \emph{blessing}; SvPn at $-2$ or die.
+   \item \emph{Scarring:} Seems like \emph{healing}; causes $\d{2d6} + 2$\,hp
+     burn damage curable by \emph{ointment of soothing}, \emph{cureall},
+     \emph{heal} or \emph{wish}.
+   \item \emph{Soothing:} Cures all burn damage.
+   \item \emph{Tanning:} Skin turns bright colour; wears off in 1d4 months.
+   \end{enumerate*}
+ \item[Pouch of security] Size of large sack.  Attempts to steal cause it to
+   scream `I am being stolen!' for 1 hour or until held by owner and commanded
+   to stop.
+ \item[Quill of copying] Copies spell on scroll: burn original scroll, mix
+   ashes with rare ink (1000\,gp cost), place on blank scroll with inkwell and
+   command to write; quill writes two copies of the spell.  Only copies one
+   spell (one of lowest level on original scroll).  Blots 1 in 4, ruining
+   scroll unless fixed with \emph{wish}.
+ \item[Rope of climbing] Thin rope $50'$ long: climbs in any direction on
+   command, fastens to any protruding surface and supports 10\,000\,cn.
+ \item[Scarab of protection] Absorbs curses, or \emph{finger of death}; usable
+   2d6 times.
+ \item[Slate of identification] Identifies magical items placed on it, with a
+   (new, if possible) command word; cannot detect \emph{cursed} items or
+   numbers of charges.  Ten charges usable per day; uses: potion~(2),
+   missile~(3), wand~(4), staff~(5), permanent weapon~(6), armour or
+   shield~(7), miscellaneous item~(10 or more).
+ \item[Stone of controlling earth elementals] $3''\phi$; summons a 12HD earth
+   elemental (takes 1 turn), allowing control (requires concentration;
+   elemental is hostile afterwards).  Usable once per day.
+ \item[Talisman of elemental travel] Cast \emph{conjure elemental} while
+   touching elemental symbol on talisman to enter elemental plane; talisman
+   allows clear vision ($120'$--$1200'$ range) and breathing.  Talisman may be
+   of any element or greater talisman with all four symbols (equal chances for
+   all five).  Greater talisman can (on command) be used to control
+   elementals, usable ten times per trip.
+ \item[Wheel of floating] Allows wagon to be towed across river or stream.
+   First wheel allows 10\,000\,cn to be carried; each extra wheel allows extra
+   5000\,cn, up to maximum of four.
+ \item[Wheel of fortune] Wheel, $10'\phi$, mounted on wall and easily rotated,
+   contains black (with white skull) and white (with red heart) wedges.  When
+   spun, rotates for 3 rounds.  Cannot be affected by magic; a \emph{wish}
+   will make the wheel disappear.  Requires 26HD to move, weighs 20\,000\,cn.
+   Usable by each person once per day; cannot be used by \emph{charmed}
+   creatures.
+   \begin{tabular}[C]{\shade c>{\raggedright}p{5pc}|c>{\raggedright}p{5pc}}
+     \hlx*{hv}
+     \th{1d12} & \th{Effect} &
+     \th{1d12} & \th{Effect} \\ \hlx{vhv}
+     \01 & 1000\,gp appear &
+     \07 & ability score drops by 1 \\ \hlx{+}
+     \02 & 10 garnets (100\,gp each) appear &
+     \08 & PR drops by 1 \\ \hlx{+}
+     \03 & 1 brooch (1000\,gp) appears &
+     \09 & $C$ drops by 1 \\ \hlx{+}
+     \04 & 1 misc magic item appears &
+      10 & least valuable magic item disintegrates \\ \hlx{+}
+     \05 & ability score rises by 1 &
+      11 & nonmagical items disintegrate \\ \hlx{+}
+     \06 & PR or $C$ rises by 1 &
+      12 & die \\ \hlx*{vh}
+   \end{tabular}
+ \item[Wheel, square] Useless on roads or flat terrain.  Allows movement on
+   mountains and deserts (MV20 with one, MV30 with two, MV40 with three and
+   MV60 with four).
+ \end{description}
+ \subsect{Armour and shields}
+ Cursed 1 in 8: revealed in earnest combat; \emph{remove curse} allows
+ removal, C36 removes curse entirely.
+ Special powers usable once per day.
+ \begin{description}
+ \item[Absorption] Energy drains lose one `plus' instead of affecting wearer;
+   armour disintegrates at zero; no daily limit.
+ \item[Charm] When hit, opponent must SvS or be \emph{charmed} ($+4$ bonus if
+   using weapon).  Only one \emph{charm} per day.
+ \item[Cure wounds] Cures half wearer's damage.
+ \item[Electricity] When charged by command, inflicts 6d6 damage (SvS for
+   half, $+4$ bonus if using weapon) against next attacker to hit.  Only one
+   blast per day.
+ \item[Energy drain] When charged by command, inflicts 1ED:Wt (SvS to avoid,
+   $+4$ bonus if using weapon) against next attacker to hit.  Only one drain
+   per day.
+ \item[Ethereality] Become ethereal or return to prime by command, once each
+   once per day.
+ \item[Fly] On command allows flight (MV\flying360, for 12 turns).  Usable
+   once per day.
+ \item[Gaseous form] Assume gaseous form (with items carried) for up to 6
+   turns.  Usable once per day.
+ \item[Haste] Double movement and attacks for 1 turn.  Usable once per day.
+ \item[Invisibility] Become invisible on command with all items carried, until
+   attacking or casting spell.  Usable three times per day.
+ \item[Reflection] Reflects \emph{light} or \emph{continual light} at caster
+   (who may SvS to avoid), three times per day.  Meet gaze attacks as if using
+   mirror, but without $-2$ to hit.
+ \item[Remove curse] Cannot be \emph{cursed}; removes curses as if C36.
+   Usable three times in total.
+ \end{description}
+ \subsect{Missiles}
+ \begin{description}
+ \item[Biting] On hit, becomes poisonous snake: SvPn or die.
+ \item[Blinking] Blinks in and out of existence to pass allies.
+ \item[Charming] Target must SvS or be \emph{charmed}.
+ \item[Climbing] If shot at object, fastens securely and creates $50'$ rope
+   supporting any number of climbers.  Disappears with rope after 1 turn.
+ \item[Curing] Obviously blunt and inscribed with holy symbol: cures $\d{2d6}
+   + 2\delta G$ damage.
+ \item[Disarming] SvS or drop weapon.
+ \item[Dispelling] Creates \emph{dispel magic} (by M15) on target.
+ \item[Flying] Ranges increased by factor of 5.
+ \item[Lighting] Creates \emph{light} ($30'$ radius, 12 turns) on demand or
+   on hit (SvS or blinded) and disintegrates.
+ \item[Penetrating] Not slowed by underbrush, webs, or other cover; no hit
+   modification for cover.
+ \item[Refilling] If left in container with normal missiles, creates 1d20 more
+   normal missiles each day.
+ \item[Screaming] Emits screams as it flies; all within $30'$ of path must
+   check morale or retreat for 1d8 rounds.
+ \item[Seeking] Automatically hits target object (misses creatures).  Can be
+   used for disarming.
+ \item[Sinking] Causes $\d{1d10} + 10$ hull points damage to ships.
+ \item[Slaying] Designated \emph{opponent}s must SvDR or die.
+ \item[Speaking] Misses creatures: may be shot at target or named place within
+   10 miles; repeats 20 word spoken message.
+ \item[Stunning] Target must SvS or be stunned for 1d6 rounds.
+ \item[Teleporting] Target must SvS (with $+2$ bonus) or be \emph{teleported}
+   1d\% miles in random direction; will land safely.
+ \item[Transporting] Target must SvS or be sent $360'$ to place of user's
+   choosing.
+ \item[Wounding] Causes 1\,hp damage per round until magically cured; cannot
+   affect constructs or undead.
+ \end{description}
+ \subsect{Sword primary powers}
+ Usually usable once per round as often as desired.
+ \begin{description}
+ \item[Detect evil/good] Detects good or ill intentions within $20'$.
+ \item[Detect gems] Points to gems within $60'$, detecting amounts.
+ \item[Detect magic] Detects magical items and effects within $20'$.  Usable
+   three times per day.
+ \item[Detect metal] Points to metal of requested type within $60'$, but
+   cannot detect amount.
+ \item[Detect shifting walls] Within $10'$.
+ \item[Detect slopes] Within $10'$.
+ \item[Find secret doors] Within $10'$.  Usable three times per day.
+ \item[Find traps] Within $10'$.  Usable three times per day.
+ \item[See invisible] Find invisible and hidden creatures and objects (not
+   secret doors) within $20'$.
+ \end{description}
+ \subsect{Sword extraordinary powers}
+ Usually usable once per round, up to three times per day.
+ \begin{description}
+ \item[Clairaudience] Hear sound through ears of creature within $60'$.
+ \item[Clairvoyance] See through eyes of creature within $60'$.
+ \item[ESP] Listen to thoughts of creature within $60'$.
+ \item[Extra damage] Damage multiplied by 4 (or 5, 6, \dots\ for duplicates).
+   Duration 1d10 rounds.
+ \item[Flying] Allows flight MV\flying360 for 3 turns.
+ \item[Healing] Heals 6\,hp (or 12, 18, \dots\ for duplicates) per day, at
+   1\,hp per round.
+ \item[Illusion] Creates illusion in $20'$ cube within $240'$ while user
+   concentrates.  Monsters are AC9 and disappear when hit.  Victim may SvS to
+   disbelieve the illusion.  Never causes damage; effects wear off in 1d4
+   turns.
+ \item[Levitation] Move up and down (only) at $20'$ per round, carrying up to
+   2000\,cn, for 3 turns.
+ \item[Telekinesis] Move inanimate objects of up to 2000\,cn by concentration,
+   for distance of $50'$.
+ \item[Telepathy] Send messages by thought to creature within $90'$, may read
+   thoughts (requires concentration, SvS allowed to avoid thought reading).
+ \item[Teleportation] As spell.  Usable once per day.
+ \item[X-ray vision] See $30'$ through stone walls (or $60'$ through wood,
+   cloth or water) by concentrating, detecting traps and secret doors; blocked
+   by gold or lead; inspect $10' \times 10'$ area per use.
+ \end{description}
+ \subsect{Weapon talents}
+ Usually usable once per day.  Missile weapon talents usually apply to
+ missiles fired.
+ \begin{description}
+ \item[Breathing] Allows \emph{water breathing} (for 1 day) or \emph{create
+     air} (for one hour).
+ \item[Charming] Can \emph{charm} one humanoid within $120'$.
+ \item[Deceiving] Change appearance of user (facial features, equipment, but
+   not size) while carried (unsheathed); cannot disguise itself.
+ \item[Defending] Bonus can be applied to AC instead of hit/damage.
+ \item[Deflecting] Optionally used to deflect energy drain, losing one `plus';
+   disintegrates at $-1$.  Applies to missile weapon itself.
+ \item[Draining] Can drain $\d{1d4} + 4$ levels, as 1ED:Wh.  Missile weapons
+   lose one `plus' per drain.
+ \item[Extinguishing] Cool to touch.  Double $\delta G$ against fire-using
+   creatures.  Douses normal fire.
+ \item[Finding] Sense direction of one known object within $120'$ (but not
+   distance).  Will not locate creatures.
+ \item[Flaming] Harmless to weapon and user.  Bonus $+2$ to hit and damage
+   hippogriff, pegasis, roc and troll, $+3$ to hit and damage treant and
+   undead.  Usable as required.
+ \item[Flying] Must first be used normally in each battle; on command attacks
+   by itself for three rounds (or on command).  Missile weapons create
+   ammunition as needed.
+ \item[Healing] Cures $\d{2d6} + 2$\,hp of the user only.
+ \item[Hiding] Can render the user invisible (with all items, becomes visible
+   when attacking or casting spells).  Additionally, weapon only can become
+   invisible three times per day.
+ \item[Holding] Up to four humanoids within $180'$ SvS or paralysed for 9
+   turns.  Penalty $-2$ on save if cast on single individual.  Cancelled by
+   \emph{dispel magic} or \emph{free person}.
+ \item[Lighting] Create \emph{light} at $120'$ range.
+ \item[Silencing] Cause \emph{silence} in $15'$ radius, at $180'$ range, for
+   12 turns.
+ \item[Slicing] (Only edged weapons.)  If $\textrm{hit roll} + \delta G \ge
+   19$, opponent must SvDR or be killed.  Doesn't work against constructs or
+   undead.
+ \item[Slowing] Opponent hit moves and attacks at half speed for 1 turn (no
+   save).
+ \item[Speeding] Doubles user's movement and attack rate for 1 turn.
+ \item[Translating] User can understand any languages heard for 6 turns.
+ \item[Watching] On command, weapon will watch for monster type and vibrate
+   slightly if any come within $60'$.
+ \item[Wishing] Grants 1d3 wishes.
  \end{description}
  
  \end{multicols}