;;;; model.lisp -- bknr.datastore class definitions for dnd (in-package :dnd) (deftype title () `(member :noob)) (deftype character-class () `(member :hero)) (deftype priority () `(member :low :medium :high)) (defun hero-class (h) "barGaryan") ; TODO: real implementation (defun hero-title (h) "Scouse Chef") ; TODO: real implementation (defun renown (hero) (experience hero)) ; TODO: real implementaiton ;;; persistent mixins (defclass has-uid () ((nuid :reader uid :initform (nuid) :index-type idx:string-unique-index :index-reader object-with-uid)) (:metaclass db:persistent-class)) (defclass can-equip () ((equipment-table :initform nil :type cons :documentation "A PLIST mapping 'equipment slots' to instances of LOOT. Equipment slots are things like :head, :torso, :left-ring, etc") (equipment-slot-names :initform +standard-humanoid-equipment+ :initarg :slot-names :type (list keyword) :documentation "The list of slots available to this entity.")) (:metaclass db:persistent-class)) (defclass has-chronicle () ((chronicle :accessor chronicle :initform nil)) (:metaclass db:persistent-class) (:documentation "A chronicle is a general purpose log of events. It stores a single slot that")) (defparameter +standard-humanoid-equipment+ '(:head :neck :torso :waist :legs :feet :arms :left-fingers :right-fingers :left-holding :right-holding :cloak) "The equipment slots for standard humanoids") ;; abstract class (defclass game-object (db:store-object has-uid has-chronicle) () (:metaclass db:persistent-class)) ;; a user (defclass hero (game-object can-equip) ((name :accessor hero-name :initarg :name :initform (error "Heroes must be named") :type string :index-type idx:string-unique-index :index-reader hero-known-as) (experience :accessor experience :initform 0 :type integer) (pwhash :accessor pwhash :type string :initarg :pwhash :documentation "A hash of the password, hashed with the value of the pwsalt slot.") (pwsalt :reader pwsalt :initform (nuid) :type string :documentation "Salt for this hero's password hash.")) (:metaclass db:persistent-class)) (defun all-heroes () (db:store-objects-with-class 'hero)) ;; TODO expiration? (defclass session (db:store-object) ((hero :reader session-hero :initarg :hero) (id :reader session-id :initform (nuid) :index-type idx:string-unique-index :index-reader session-with-id)) (:metaclass db:persistent-class)) (defclass campaign (game-object) ((creator :reader campaign-creator :initarg :creator :initform (error "campaigns must have a creator") :documentation "The hero instance of the user who made this campaign.") (seers :accessor campaign-seers :initarg :seers :initform nil :documentation "Seers are the people who peer out into their instruments of divination that heroes may go on quests.") (title :accessor campaign-title :initarg :title :initform (error "A campaign needs a title")) (rumors :accessor campaign-rumors :initarg nil :documentation "Beasts, Monsters, and Hazards rumored to be lurking about.")) (:metaclass db:persistent-class) (:documentation "A campaign is a container of quests. Campaigns are expected to be engaged with on a particular schedule, and are run by particular people.")) (defclass quest (game-object) ((campaign :reader quest-campaign :initarg :campaign :initform (error "No quest can fall outside the scope of a campaign.") :index-type idx:hash-list-index :index-reader quests-in-campaign :documentation "The campaign to which this quest belongs") (name :accessor quest-name :initarg :name :initform (format nil "~a" (gensym "QUEST"))) (horizon-of-hope :accessor horizon-of-hope :initarg :deadline :initform nil :documentation "When all hope becomes lost.") (heroes :accessor heroes-in-quest :initarg :heroes :initform nil :documentation "A list of heroes in this quest. Join and flight dates are logged in the chronicle.") (startedp :accessor quest-startedp :initform nil :documentation "Indication of whether the quest is active or not - i.e. whether heroes are on this quest.")) (:metaclass db:persistent-class) (:documentation "A collection of hazards")) (defclass hazard (game-object) ((quest :accessor quest-of :index-type idx:hash-list-index :index-reader hazards-in-quest :documentation "The quest to which this hazard belongs. Initially it is unbound. It becomes boudn when the hazard is added to a quest.") (overcomep :accessor is-overcome :initform nil :documentation "indicates whether or not this hazard has been overcome.") (imminence :accessor imminence-of :type priority :documentation "") (menace ;; difficulty :accessor menace-of :type integer :documentation "How dangerous the hazard is." )) (:metaclass db:persistent-class) (:documentation "Hazard is a superclass for all hazards encountered in a quest. It's chronicle includes data about which heroes fought and which overcame.")) ;; (defclass monster ())