src/robots/rpg-shopkeeper.lisp @ 496f6e33e468
Update to compiling version of Chancery
| author | Steve Losh <steve@stevelosh.com> | 
|---|---|
| date | Wed, 18 Jan 2017 18:07:55 +0000 | 
| parents | d5c110b938cb | 
| children | 8163984906d6 | 
(in-package :magitek.robots.rpg-shopkeeper) (named-readtables:in-readtable :chancery) ;;;; General ------------------------------------------------------------------ (define-rule (bonus :distribution (:zipf :exponent 1.8)) 1 2 3 4 5) ;;;; Materials ---------------------------------------------------------------- (defclass* material () (name multiplier)) (defun make-material (name multiplier) (make-instance 'material :name name :multiplier multiplier)) (defmethod print-object ((o material) s) (print-unreadable-object (o s :type t) (princ (material-name o) s))) (defmacro define-material (name multiplier) `(defparameter ,(symb '* (string-upcase (substitute #\- #\space name)) '*) (make-material ,name ,multiplier))) (define-material "iron" 1.0) (define-material "steel" 1.5) (define-material "silver" 2.0) (define-material "meteoric iron" 4.0) (define-material "mithril" 10.0) (define-material "adamantine" 11.0) (define-material "cloth" 1.0) (define-material "leather" 1.5) (define-material "silk" 2.0) (define-material "spider silk" 6.0) (define-material "pine" 1.0) ; http://www.wood-database.com/wood-articles/bow-woods/ (define-material "poplar" 1.2) (define-material "walnut" 1.3) (define-material "maple" 2.0) (define-material "oak" 3.0) (define-material "yew" 5.0) (define-material "rosewood" 10.0) (define-rule (metal :distribution :zipf) !*iron* !*steel* !*silver* !*meteoric-iron* !*mithril* !*adamantine*) (define-rule (textile :distribution :weighted) (1.00 !*cloth*) (1.00 !*leather*) (0.80 !*silk*) (0.01 !*spider-silk*)) (define-rule (wood :distribution (:zipf :exponent 0.8)) !*pine* !*poplar* !*walnut* !*maple* !*oak* !*yew* !*rosewood*) ;;;; Monsters ----------------------------------------------------------------- (defclass* monster () (singular multiplier plural adjective)) (defun make-monster (singular multiplier plural adjective) (make-instance 'monster :singular singular :multiplier multiplier :plural plural :adjective adjective)) (defmethod print-object ((o monster) s) (print-unreadable-object (o s :type t) (princ (monster-singular o) s))) (defmacro define-monster (singular multiplier plural adjective) `(defparameter ,(symb '* (string-upcase singular) '*) (make-monster ,singular ,multiplier ,plural ,adjective))) (define-monster "goblin" 1.00 "goblins" "goblin") (define-monster "kobold" 1.00 "kobolds" "kobold") (define-monster "elf" 1.00 "elves" "elven") (define-monster "dwarf" 1.00 "dwarves" "dwarven") (define-monster "halfling" 1.00 "halflings" "halfling") (define-monster "gnome" 1.00 "gnomes" "gnomish") (define-monster "gnoll" 1.10 "gnolls" "gnollish") (define-monster "ogre" 1.20 "ogres" "ogre") (define-monster "troll" 1.60 "trolls" "troll") (define-monster "vampire" 5.00 "vampires" "vampire") (define-monster "dragon" 9.00 "dragons" "dragon") (define-rule (monster :distribution :weighted) (1.00 !*goblin*) (1.00 !*kobold*) (1.00 !*elf*) (1.00 !*dwarf*) (1.00 !*halfling*) (1.00 !*gnome*) (1.00 !*ogre*) (1.00 !*troll*) (1.00 !*gnoll*) (0.10 !*vampire*) (0.01 !*dragon*)) ;;;; Roles -------------------------------------------------------------------- (define-rule role "cleric" "warrior" "wizard" "rogue") ;;;; Elements ----------------------------------------------------------------- (define-rule element ("ice" "icy") ("fire" "flaming") ("electricity" "electrified") ("poison" "venomous")) ;;;; Armor -------------------------------------------------------------------- (define-rule armor-piece "scale mail" "ring mail" "chain mail" "plate mail") (define-rule clothing-piece "robe" "shirt" "pants" "dress" "skirt") (define-rule armor-enchantment (:protection-from monster) (:resistance element) (:bonus bonus)) (define-rule vanilla-armor (metal armor-piece) (textile clothing-piece)) (define-rule (armor :distribution :weighted) (2 (vanilla-armor nil)) (1 (vanilla-armor armor-enchantment))) (defgeneric enchanted-armor-description (base enchantment-type enchantment-arguments)) (defmethod enchanted-armor-description (base (e (eql :protection-from)) enchantment-args) (destructuring-bind (monster) enchantment-args (format nil "~A of protection from ~A" base (monster-plural monster)))) (defmethod enchanted-armor-description (base (e (eql :resistance)) enchantment-args) (destructuring-bind ((noun adjective)) enchantment-args (declare (ignore adjective)) (format nil "~A of ~A resistance" base noun))) (defmethod enchanted-armor-description (base (e (eql :bonus)) enchantment-args) (destructuring-bind (val) enchantment-args (format nil "+~D ~A" val base))) (defun vanilla-armor-description (vanilla-armor) (destructuring-bind (material piece) vanilla-armor (format nil "~A ~A" (material-name material) piece))) (defun armor-description (armor) (destructuring-bind (vanilla enchant) armor (let ((vanilla-description (vanilla-armor-description vanilla))) (if enchant (enchanted-armor-description vanilla-description (first enchant) (rest enchant)) vanilla-description)))) ;;;; Weapons ------------------------------------------------------------------ (define-rule melee-weapon "dagger" "longsword" "short sword" "hand axe" "battleaxe" "spear" "halberd" "scythe" "scimitar" "lance" "hammer" "staff" "mace" "flail") (define-rule (bow-weapon :distribution :weighted) (2 "shortbow") (2 "longbow") (1 "crossbow") (1 "compound bow")) (define-rule weapon-enchantment (:slaying monster) (:element element) (:bonus bonus)) (define-rule vanilla-weapon (metal melee-weapon) (wood bow-weapon)) (define-rule (weapon :distribution :weighted) (1 (vanilla-weapon nil)) (1 (vanilla-weapon weapon-enchantment))) (defgeneric enchanted-weapon-description (base enchantment-type enchantment-arguments)) (defmethod enchanted-weapon-description (base (e (eql :slaying)) enchantment-args) (destructuring-bind (monster) enchantment-args (format nil "~A of ~A-slaying" base (monster-singular monster)))) (defmethod enchanted-weapon-description (base (e (eql :element)) enchantment-args) (destructuring-bind (element) enchantment-args (format nil "~A ~A" (second element) base))) (defmethod enchanted-weapon-description (base (e (eql :bonus)) enchantment-args) (destructuring-bind (val) enchantment-args (format nil "+~D ~A" val base))) (defun vanilla-weapon-description (vanilla-weapon) (destructuring-bind (material piece) vanilla-weapon (format nil "~A ~A" (material-name material) piece))) (defun weapon-description (weapon) (destructuring-bind (vanilla enchant) weapon (let ((vanilla-description (vanilla-weapon-description vanilla))) (if enchant (enchanted-weapon-description vanilla-description (first enchant) (rest enchant)) vanilla-description)))) ;;;; Flavor ------------------------------------------------------------------- (define-string scene ("images of" [monster monster-plural] "fighting" [monster monster-plural]) ("a picture of a famous" [monster monster-singular] role)) (define-string picture "painted with" "adorned with") (define-string flavor (picture scene)) (define-string sales-pitch "Only used once!" "Brand new!" ("I bought it from" [monster monster-adjective a] role :. ".") "Look at the workmanship!" "This is gonna go fast!") ;;;; Main --------------------------------------------------------------------- (define-rule base-item !(weapon-description @weapon) !(armor-description @armor)) (define-string (item :distribution :weighted) (2 base-item) (1 (base-item :. "," flavor))) (define-string offer ("FOR SALE:" [item cap] :. #\newline #\newline :. sales-pitch)) ;;;; API ---------------------------------------------------------------------- (defun random-string () (offer))