aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Pouar <pouar@pouar.net>2020-09-13 16:41:25 -0500
committerGravatar Pouar <pouar@pouar.net>2020-09-13 16:41:25 -0500
commit17e93e7afa72320c68cff7964655e6e8444f19c2 (patch)
treee3959a53f638b352f5cefee436eaef50fcd3f25a
parentupdate sbcl (diff)
refactor a bunch of stuff into mixins
doing it this way allows AI scripts to figure out the difference between itesm and moves easier while at the same time reducing the amount of code mods need to write
-rw-r--r--core/classes.lisp80
-rw-r--r--core/libexec/generic-functions.lisp76
-rw-r--r--data/enemies/raccoon-bandits.lisp2
-rw-r--r--data/items/consumable.lisp7
-rw-r--r--data/items/weapons.lisp50
-rw-r--r--data/moves/dbz.lisp8
-rw-r--r--data/moves/haunted.lisp4
-rw-r--r--data/moves/pokemon.lisp22
-rw-r--r--data/moves/regular.lisp38
-rw-r--r--packages.lisp12
10 files changed, 157 insertions, 142 deletions
diff --git a/core/classes.lisp b/core/classes.lisp
index 81fbd7c..639f15d 100644
--- a/core/classes.lisp
+++ b/core/classes.lisp
@@ -15,8 +15,6 @@
:type list
:documentation "Plist of attributes which are used instead of slots for stuff that aren't shared between slots"))
(:documentation "All the classes that are part of the game's core inherit this class"))
-(defclass battle-script-mixin () ())
-(defclass attack-mixin () ())
(defclass element-type-class (standard-class) ((name :initform nil)))
(defmethod name-of ((class element-type-class))
(or (slot-value class 'name) (class-name class)))
@@ -24,6 +22,18 @@
(defmethod c2mop:validate-superclass ((class standard-class) (superclass element-type-class))
(error 'simple-error :format-control "Either you didn't use ~s to define ~s or you tried to inherit a class not defined with ~s" :format-arguments `(define-type ,(class-name class) define-type)))
(defclass element-type () () (:metaclass element-type-class))
+(defclass buff () ()
+ (:documentation #.(f:fmt nil "mixin for " (ref move :class) " or " (ref item :class) " that sets specified " (ref status-condition :class) " that causes buffs also uses this mixin")))
+(defclass debuff () ()
+ (:documentation #.(f:fmt nil "mixin for " (ref move :class) " or " (ref item :class) " that sets specified " (ref status-condition :class) " that causes debuffs also uses this mixin")))
+(defclass clear-status-mixin ()
+ ((statuses-cleared
+ :initarg :statuses-cleared
+ :accessor statuses-cleared-of
+ :initform ()
+ :type list
+ :documentation "Status conditions that this move or item clears"))
+ (:documentation #.(f:fmt nil "mixin for " (ref move :class) " or " (ref item :class) " that clears specified " (ref status-condition :class))))
(defclass element-type-mixin ()
((element-types
:accessor element-types-of
@@ -133,7 +143,7 @@
:type (or null item)
:documentation "Item the character is wielding as a weapon"))
(:documentation "Base class for the characters in the game"))
-(defclass item (yadfa-class attack-mixin)
+(defclass item (yadfa-class)
((description
:initarg :description
:initform :?
@@ -176,18 +186,6 @@
:accessor value-of
:type (real 0)
:documentation "Value of item in bitcoins")
- (ai-flags
- :initarg :ai-flags
- :initform ()
- :accessor ai-flags-of
- :type list
- :documentation "List of flags that affect the AI")
- (power
- :initarg :power
- :initform 40
- :accessor power-of
- :type real
- :documentation "Attack base when used as a melee weapon")
(wear-stats
:initarg :wear-stats
:initform ()
@@ -207,7 +205,15 @@
:type list
:documentation "Plist of actions that the player sees as actions with a lambda with the lambda-list @code{(item user &key &allow-other-keys)} they can perform with the item, @var{ITEM} is the instance that this slot belongs to, @var{USER} is the user using the item"))
(:documentation "Something you can store in your inventory and use"))
-(defclass status-condition (yadfa-class battle-script-mixin)
+(defclass damage-item (item)
+ ((use-power
+ :initarg :use-power
+ :initform 40
+ :type real
+ :accessor use-power-of
+ :documentation "attack power of item when used instead of wielded"))
+ (:documentation "Item that deal damage when used"))
+(defclass status-condition (yadfa-class)
((name
:initarg :name
:initform nil
@@ -268,7 +274,7 @@
:accessor persistentp
:documentation "Whether items or moves that cure statuses cure this"))
(:documentation "Base class for all the status conditions "))
-(defclass move (yadfa-class attack-mixin element-type-mixin)
+(defclass move (yadfa-class element-type-mixin)
((name
:initarg :name
:initform :-
@@ -286,20 +292,28 @@
:initform 0
:type real
:accessor energy-cost-of
- :documentation "How much energy this move costs")
- (power
+ :documentation "How much energy this move costs"))
+ (:documentation "base class of moves used in battle"))
+(defclass health-inc-move (move)
+ ((health
+ :accessor health-of
+ :initform 0
+ :type real
+ :initarg :health)))
+(defclass energy-inc-move (move)
+ ((energy
+ :accessor energy-of
+ :initform 0
+ :type real
+ :initarg :energy)))
+(defclass damage-move (move)
+ ((power
:initarg :power
:initform 40
:type real
:accessor power-of
- :documentation "Number used to determine the damage of this attack")
- (ai-flags
- :initarg :ai-flags
- :initform ()
- :accessor ai-flags-of
- :type list
- :documentation "list containing flags that affect the behavior of the AI."))
- (:documentation "base class of moves used in battle"))
+ :documentation "Number used to determine the damage of this attack"))
+ (:documentation "Move that causes damage when used"))
(defclass mess-move-mixin (move) ()
(:documentation "Basically any move that involves messing"))
(defclass wet-move-mixin (move) ()
@@ -737,7 +751,15 @@
:type real
:documentation "Attack base when using this as ammo."))
(:documentation "Ammo is typically inherited by this class, but nothing in the code actually enforces this and is meant to make filtering easier"))
-(defclass weapon (item)
+(defclass damage-wield (item)
+ ((power
+ :initarg :power
+ :initform 40
+ :accessor power-of
+ :type real
+ :documentation "Attack base when used as a melee weapon"))
+ (:documentation "Items that cause damage when wielded"))
+(defclass weapon (damage-wield)
((ammo-type
:initarg :ammo-type
:initform nil
@@ -762,7 +784,7 @@
:type unsigned-byte
:accessor ammo-capacity-of
:documentation "How much ammo this thing can hold"))
- (:documentation "Weapons typically inherited this class, but nothing in the code actually enforces this and is meant to make filtering easier"))
+ (:documentation "Items intended to be wielded as a weapon"))
(defclass clothing (item)
())
(defclass top (clothing)
diff --git a/core/libexec/generic-functions.lisp b/core/libexec/generic-functions.lisp
index ec2bb37..64aa467 100644
--- a/core/libexec/generic-functions.lisp
+++ b/core/libexec/generic-functions.lisp
@@ -107,7 +107,12 @@
(attack selected-target character a))
t))))
(defgeneric use-script (item user target)
- (:documentation "Function that runs when @var{USER} uses @var{ITEM} on @var{TARGET}. @var{ITEM} is the instance of the item and @var{USER} and @var{TARGET} are instances of base-character"))
+ (:documentation "Function that runs when @var{USER} uses @var{ITEM} on @var{TARGET}. @var{ITEM} is the instance of the item and @var{USER} and @var{TARGET} are instances of base-character")
+ (:method :before ((item damage-item) (user base-character) (target base-character))
+ (decf (health-of target) (calculate-damage target user (use-power-of item))))
+ (:method :after ((item damage-item) (user base-character) (target base-character))
+ (format t "~a received ~a damage~%" (name-of target) (calculate-damage target user (use-power-of item))))
+ (:method ((item damage-item) (user base-character) (target base-character))))
(defgeneric wield-script (item user)
(:documentation "Function that runs when @var{USER} is wielding @var{ITEM}. @var{ITEM} is the instance of the item and @var{USER} is the user you're using it on.")
(:method ((item item) (user base-character))))
@@ -126,6 +131,43 @@
(:method ((element zone)) (resolve-team-npc-spawn-list (team-npc-spawn-list-of element))))
(defgeneric attack (target user attack)
(:documentation #.(f:fmt nil "Method run when attacking. @var{ATTACK} is @code{NIL} when it is the default attack without any weapons. is an instance of " (ref move :class) " when it is an attack using a move and is an instance of " (ref item :class) " when that instance is being used as a weapon"))
+ (:method :before ((target base-character) (user base-character) (attack damage-move))
+ (decf (health-of target) (calculate-damage target user attack)))
+ (:method :around ((target base-character) (user base-character) (item weapon))
+ (apply #'format t
+ (if (first (ammo-of item))
+ (list "~a fires ~a ~a at ~a~%"
+ (name-of user)
+ (if (malep user) "his" "her")
+ (name-of item)
+ (name-of target))
+ (list "~a whacks ~a ~a at ~a~%"
+ (name-of user)
+ (if (malep user) "his" "her")
+ (name-of item)
+ (name-of target)))))
+ (:method :before ((target base-character) (user base-character) (item weapon))
+ (decf (health-of target) (calculate-damage target user
+ (if (first (ammo-of item))
+ (ammo-power-of (first (ammo-of item)))
+ (power-of item)))))
+ (:method :before ((target base-character) (user base-character) (item damage-wield))
+ (decf (health-of target) (calculate-damage target user (power-of item))))
+ (:method :before ((target base-character) (user base-character) (attack move))
+ (format t "~a used ~a~%" (name-of user) (name-of attack)))
+ (:method :before ((target base-character) (user base-character) (attack clear-status-mixin))
+ (when *battle*
+ (a:deletef (getf (status-conditions-of *battle*) target) (statuses-cleared-of attack)
+ :test (lambda (o e) (typep e o)))))
+ (:method :after ((target base-character) (user base-character) (attack damage-move))
+ (format t "~a received ~a damage~%" (name-of target) (calculate-damage target user attack)))
+ (:method :after ((target base-character) (user base-character) (item weapon))
+ (format t "~a received ~a damage~%" (name-of target) (calculate-damage target user
+ (if (first (ammo-of item))
+ (ammo-power-of (first (ammo-of item)))
+ (power-of item)))))
+ (:method :after ((target base-character) (user base-character) (item damage-wield))
+ (format t "~a received ~a damage~%" (name-of target) (calculate-damage target user (power-of item))))
(:method ((target base-character) (user base-character) (attack null))
(declare (ignore attack))
(let ((a (calculate-damage target user (default-attack-power-of user))))
@@ -133,31 +175,27 @@
(decf (health-of target) a)
(format t "~a received ~a damage~%" (name-of target) a)
a))
- (:method ((target base-character) (user base-character) (attack move))
- (let ((a (calculate-damage target user attack)))
- (format t "~a used ~a~%" (name-of user) (name-of attack))
- (decf (health-of target) a)
- (format t "~a received ~a damage~%" (name-of target) a)
- a))
(:method ((target base-character) (user base-character) (item item))
(declare (ignorable target user item))
- (let ((a (calculate-damage target user
- (if (first (ammo-of item))
- (ammo-power-of (first (ammo-of item)))
- (power-of item)))))
- (format t "~a whacks ~a with ~a ~a~%"
- (name-of user)
- (name-of target)
- (if (malep user) "his" "her")
- (name-of item))
- (decf (health-of target) a)
- (format t "~a received ~a damage~%" (name-of target) a))))
+ (format t "~a whacks ~a with ~a ~a~%"
+ (name-of user)
+ (name-of target)
+ (if (malep user) "his" "her")
+ (name-of item))
+ (format t "It had no effect~%"))
+ (:method ((target base-character) (user base-character) (item damage-wield))
+ (declare (ignorable target user item))
+ (format t "~a whacks ~a with ~a ~a~%"
+ (name-of user)
+ (name-of target)
+ (if (malep user) "his" "her")
+ (name-of item))))
(defgeneric battle-script (npc target)
(:documentation #.(f:fmt nil "function that runs when it's time for @var{NPC} to attack @var{TARGET} and what @var{NPC} does to attack. Basically the \"AI\""))
(:method ((self npc) (target base-character))
(let ((moves-with-health
(iter (for i in (moves-of self))
- (when (and (>= (energy-of self) (energy-cost-of i)) (position :ai-health-inc (ai-flags-of i)))
+ (when (and (>= (energy-of self) (energy-cost-of i)) (typep i 'health-inc-move))
(collect i))))
(moves-can-use (iter (for i in (moves-of self))
(when (>= (energy-of self) (energy-cost-of i))
diff --git a/data/enemies/raccoon-bandits.lisp b/data/enemies/raccoon-bandits.lisp
index 28c733c..b6d6ff1 100644
--- a/data/enemies/raccoon-bandits.lisp
+++ b/data/enemies/raccoon-bandits.lisp
@@ -19,7 +19,7 @@
:bitcoins-per-level 40))
(defmethod battle-script ((self diapered-raccoon-bandit) (target base-character))
(let ((moves-with-health (iter (for i in (moves-of self))
- (when (and (>= (energy-of self) (energy-cost-of i)) (position :ai-health-inc (ai-flags-of i)))
+ (when (and (>= (energy-of self) (energy-cost-of i)) (typep i 'health-inc-move))
(collect i))))
(moves-can-use (iter (for i in (moves-of self))
(when (>= (energy-of self) (energy-cost-of i))
diff --git a/data/items/consumable.lisp b/data/items/consumable.lisp
index 44307a2..64ee9e4 100644
--- a/data/items/consumable.lisp
+++ b/data/items/consumable.lisp
@@ -126,7 +126,7 @@
(defmethod use-script ((item maximum-tomato) (user base-character) (target base-character))
(declare (ignore item))
(setf (health-of target) (calculate-stat target :health)))
-(defclass holy-hand-grenade (consumable) ()
+(defclass holy-hand-grenade (consumable damage-item) ()
(:default-initargs
:name "Holy Hand Grenade of Antioch"
:description "And Saint Attila raised the hand grenade up on high, saying, “O Lord, bless this thy hand grenade. That with it, thou mayest blow thine enemies to tiny bits, in thy mercy” And the Lord did grin, and the people did feast upon the lambs, and sloths, and carp, and anchovies, and orangutans, and breakfast cereals, and fruit bats, and..."
@@ -135,8 +135,7 @@
(defmethod cant-use-p ((item holy-hand-grenade) (user base-character) (target base-character) action &key &allow-other-keys)
(unless *battle*
(values t `(:format-control "You can only use that in battle"))))
-(defmethod use-script ((item holy-hand-grenade) (user base-character) (target base-character))
- (declare (ignore item))
+(defmethod use-script :around ((item holy-hand-grenade) (user base-character) (target base-character))
(if (or (and (typep target 'team-member) (cdr (team-of *game*)))
(and (typep target 'enemy) (cdr (enemies-of *battle*))))
(progn
@@ -154,4 +153,4 @@
(iter (for i in (if (typep target 'team-member)
(enemies-of *battle*)
(team-of *game*)))
- (decf (health-of i) 120)))
+ (decf (health-of i) (use-power-of item))))
diff --git a/data/items/weapons.lisp b/data/items/weapons.lisp
index b375c0a..95263f9 100644
--- a/data/items/weapons.lisp
+++ b/data/items/weapons.lisp
@@ -30,24 +30,6 @@
:ammo-type '7.62×39mm
:ammo-capacity 3
:power 40))
-(defmethod attack ((target base-character) (user base-character) (self ak47))
- (let ((a (calculate-damage target user (if (first (ammo-of self))
- (ammo-power-of (first (ammo-of self)))
- (power-of self)))))
- (apply #'format t
- (if (first (ammo-of self))
- (list "~a fires ~a ~a at ~a~%"
- (name-of user)
- (if (malep user) "his" "her")
- (name-of self)
- (name-of target))
- (list "~a whacks ~a ~a at ~a~%"
- (name-of user)
- (if (malep user) "his" "her")
- (name-of self)
- (name-of target))))
- (decf (health-of target) a)
- (format t "~a received ~a damage~%" (name-of target) a)))
(defclass exterminator-ammo (ammo) ()
(:default-initargs
:name "Exterminator Ammo"
@@ -65,20 +47,15 @@
:ammo-capacity 1
:power 0))
(defmethod attack ((target base-character) (user base-character) (self exterminator))
- (let ((a (calculate-damage target user (if (first (ammo-of self))
- (ammo-power-of (first (ammo-of self)))
- (power-of self)))))
- (apply #'format t
- (if (first (ammo-of self))
- (list "*BOOOMKSSSHHH!!!!!*~%")
- (list "~a struggles to whack ~a with ~a ~a but barely taps ~a~%"
- (name-of user)
- (name-of target)
- (if (malep user) "his" "her")
- (name-of self)
- (if (malep target) "his" "her"))))
- (decf (health-of target) a)
- (format t "~a received ~a damage~%" (name-of target) a)))
+ (apply #'format t
+ (if (first (ammo-of self))
+ (list "*BOOOMKSSSHHH!!!!!*~%")
+ (list "~a struggles to whack ~a with ~a ~a but barely taps ~a~%"
+ (name-of user)
+ (name-of target)
+ (if (malep user) "his" "her")
+ (name-of self)
+ (if (malep target) "his" "her")))))
(defclass pink-sword (weapon) ()
(:default-initargs
:name "Pink Sword"
@@ -110,18 +87,13 @@
:power 150
:description "You're just like Roronoa Zoro with these"))
(defmethod attack ((target base-character) (user base-character) (self three-swords))
- (let ((a (calculate-damage target user (if (first (ammo-of self))
- (ammo-power-of (first (ammo-of self)))
- (power-of self)))))
- (format t "Three Sword Style!!!!~%")
- (decf (health-of target) a)
- (format t "~a received ~a damage~%" (name-of target) a)))
+ (format t "Three Sword Style!!!!~%"))
(defclass messing-laser (weapon) ()
(:default-initargs
:name "Messing Laser"
:description "Causes enemies to mess themselves"
:values 8000))
-(defmethod attack ((target base-character) (user base-character) (weapon messing-laser))
+(defmethod attack :around ((target base-character) (user base-character) (weapon messing-laser))
(f:fmt t (name-of user) " fires " (if (malep user) "his" "her") " laser at " (name-of target) #\Newline)
(use-script weapon user target))
(defmethod use-script ((weapon messing-laser) (user base-character) (target base-character))
diff --git a/data/moves/dbz.lisp b/data/moves/dbz.lisp
index e7ee486..9bd2c0b 100644
--- a/data/moves/dbz.lisp
+++ b/data/moves/dbz.lisp
@@ -1,14 +1,10 @@
;;;; -*- mode: Common-Lisp; sly-buffer-package: "yadfa-moves"; coding: utf-8-unix; -*-
(in-package :yadfa-moves)
-(defclass kamehameha (move) ()
+(defclass kamehameha (damage-move) ()
(:default-initargs
:name "Kamehameha Wave"
:description "Say “Kamehameha!!!” and fire a huge burst of energy"
:energy-cost 12
:power 200))
(defmethod attack ((target base-character) (user base-character) (attack kamehameha))
- (let ((a (calculate-damage target user attack)))
- (format t "~a used ~a~%" (name-of user) (name-of attack))
- (format t "KAM-E-HAM-E-HA!!! *loud energy blast noise*~%OK, not as dramatic in a text based game~%")
- (decf (health-of target) a)
- a))
+ (format t "KAM-E-HAM-E-HA!!! *loud energy blast noise*~%OK, not as dramatic in a text based game~%"))
diff --git a/data/moves/haunted.lisp b/data/moves/haunted.lisp
index 76f650c..4f95765 100644
--- a/data/moves/haunted.lisp
+++ b/data/moves/haunted.lisp
@@ -4,17 +4,15 @@
(:default-initargs
:name "Ghost Tickle"))
(defmethod attack ((target base-character) (user base-character) (attack ghost-tickle))
- (format t "~a used ~a~%" (name-of user) (name-of attack))
(if (getf (attributes-of target) :not-ticklish)
(write-line "It has no effect")
(progn (f:fmt t "A bunch of ghost hands come out and start tickling " (name-of target) #\Newline)
(set-status-condition 'yadfa-status-conditions:laughing target))))
-(defclass ghost-squish (move) ()
+(defclass ghost-squish (move debuff) ()
(:default-initargs
:name "Ghost Tickle"
:description "Tickle the enemy"))
(defmethod attack ((target base-character) (user base-character) (attack ghost-squish))
- (format t "~a used ~a~%" (name-of user) (name-of attack))
(if (filter-items (wear-of user) 'incontinence-product)
(progn
(format t "a ghost hand comes out and squishes ~a's diaper!~%" (name-of target))
diff --git a/data/moves/pokemon.lisp b/data/moves/pokemon.lisp
index b7c998e..af22b06 100644
--- a/data/moves/pokemon.lisp
+++ b/data/moves/pokemon.lisp
@@ -1,11 +1,11 @@
;;;; -*- mode: Common-Lisp; sly-buffer-package: "yadfa-moves"; coding: utf-8-unix; -*-
(in-package :yadfa-moves)
-(defclass superglitch (move) ()
+(defclass superglitch (damage-move) ()
(:default-initargs
:name "Superglitch"
:description "Classic glitch move from the Pokémon games, but without the undefined behavior and unwanted side effects."))
-(defmethod attack ((target base-character) (user base-character) (attack superglitch)
- &aux (name (name-of user)))
+(defmethod attack :around ((target base-character) (user base-character) (attack superglitch)
+ &aux (name (name-of user)))
(declare (ignore attack))
(format t
"TMTRAINER ~a is frozen solid~%TMTRAINER ~a is hurt by the burn~%"
@@ -20,7 +20,6 @@
(defmethod attack ((target base-character) (user base-character) (attack watersport)
&aux (name (name-of user)))
(declare (ignore target))
- (format t "~a used ~a~%" name (name-of attack))
(if (< (bowels/contents-of user) (bowels/need-to-potty-limit-of user))
(format t "But it failed~%")
(progn (wet :wetter user)
@@ -33,26 +32,23 @@
(defmethod attack ((target base-character) (user base-character) (attack mudsport)
&aux (name (name-of user)))
(declare (ignore target))
- (format t "~a used ~a~%" name (name-of attack))
(if (< (bowels/contents-of user) (bowels/need-to-potty-limit-of user))
(format t "But it failed~%")
(progn (mess :messer user)
(format t "~a messed ~a~%"
name
(if (malep user) "himself" "herself")))))
-(defclass mudbomb (mess-move-mixin) ()
+(defclass mudbomb (mess-move-mixin debuff) ()
(:default-initargs
:name "Mud Bomb"
:description "massively mess your diapers, never fails"
:energy-cost 5
:element-types (list (make-instance 'yadfa-element-types:abdl) (make-instance 'yadfa-element-types:poison))))
(defmethod attack ((target base-character) (user base-character) (attack mudbomb))
- (format t "~a used ~a~%" (name-of user) (name-of attack))
(write-line "But it failed."))
(defmethod attack ((target base-character) (user bowels-character) (attack mudbomb)
&aux (bowels/fill-rate (* 30 24 (bowels/fill-rate-of user))) (bowels/maximum-limit (bowels/maximum-limit-of user))
(name (name-of user)))
- (format t "~a used ~a~%" name (name-of attack))
(mess :force-fill-amount (if (< bowels/fill-rate bowels/maximum-limit) bowels/maximum-limit bowels/fill-rate) :messer user)
(format t "~a messed ~a massively~%"
name
@@ -62,29 +58,27 @@
(team-of *game*)))
(set-status-condition 'yadfa-status-conditions:skunked i)
(format t "~a is grossed out by the smell~%" (name-of i))))
-(defclass tickle (move) ()
+(defclass tickle (move debuff) ()
(:default-initargs
:name "Tickle"
:description "Tickle the enemy"))
(defmethod attack ((target base-character) (user base-character) (attack tickle))
- (format t "~a used ~a~%" (name-of user) (name-of attack))
(if (getf (attributes-of target) :not-ticklish)
(write-line "It has no effect")
(progn (format t "~a starts laughing helplessly~%" (name-of target))
(set-status-condition 'yadfa-status-conditions:laughing target))))
-(defclass tackle (move) ()
+(defclass tackle (damage-move) ()
(:default-initargs
:name "Tackle"
:description "Tackles the enemy"
:element-types (list (make-instance 'yadfa-element-types:normal))))
-(defclass roar (move) ()
+(defclass roar (move debuff) ()
(:default-initargs
:name "Roar"
:energy-cost 2
:description "Scares enemies into flooding themselves"))
(defmethod attack ((target base-character) (user base-character) (attack roar))
(declare (ignore target))
- (format t "~a used ~a~%" (name-of user) (name-of attack))
(unless (iter (for i in (if (typep user 'team-member)
(enemies-of *battle*)
(team-of *game*)))
@@ -96,7 +90,7 @@
(setf j t))
(finally (return j)))
(write-line "it had no effect")))
-(defclass bite (move) ()
+(defclass bite (damage-move) ()
(:default-initargs
:name "Bite"
:description "Bites the enemy"
diff --git a/data/moves/regular.lisp b/data/moves/regular.lisp
index 7bc1d09..7f2696d 100644
--- a/data/moves/regular.lisp
+++ b/data/moves/regular.lisp
@@ -1,6 +1,6 @@
;;;; -*- mode: Common-Lisp; sly-buffer-package: "yadfa-moves"; coding: utf-8-unix; -*-
(in-package :yadfa-moves)
-(defclass mush (move) ()
+(defclass mush (move debuff) ()
(:default-initargs
:name "Mush"
:description "Mush the target's diaper"
@@ -15,7 +15,7 @@
(progn (format t "~a's diaper has been mushed~%" (name-of target))
(set-status-condition 'yadfa-status-conditions:mushed target))))
(f:fmt t "it has no effect on " (name-of target) #\Newline)))
-(defclass pants (move) ()
+(defclass pants (move debuff) ()
(:default-initargs
:name "Pants"
:description "Pants the enemy"))
@@ -84,7 +84,7 @@
(progn
(format t "~a tries to pants ~a~%" (name-of user) (name-of target))
(format t "The attack has no effect on ~a~%" (name-of target))))))
-(defclass spray (move) ()
+(defclass spray (move debuff) ()
(:default-initargs
:name "Spray"
:description "Spray the target with skunk spray. Also fills your pamps with skunk spray while you're at it."
@@ -117,7 +117,7 @@
(name-of user)))))
(format t "~a is grossed out by the smell~%" (name-of target))
(set-status-condition 'yadfa-status-conditions:skunked target))
-(defclass boop (move) ()
+(defclass boop (move debuff) ()
(:default-initargs
:name "Boop"
:description "Boops da target on da snoot"
@@ -135,19 +135,14 @@
"It's like a mess button." #\Newline)
(mess :force-fill-amount (bowels/maximum-limit-of target))
(set-status-condition 'yadfa-status-conditions:messing target)))
-(defclass fire-breath (move) ()
+(defclass fire-breath (damage-move) ()
(:default-initargs
:name "Fire Breath"
:energy-cost 5
:power 60
:description "Breathes fire at the enemy"
:element-types (list (make-instance 'yadfa-element-types:fire))))
-(defmethod attack ((target base-character) (user base-character) (self fire-breath))
- (let ((a (calculate-damage target user self)))
- (format t "~a used ~a~%" (name-of user) (name-of self))
- (decf (health-of target) a)
- a))
-(defclass face-sit (mess-move-mixin) ()
+(defclass face-sit (mess-move-mixin damage-move debuff) ()
(:default-initargs
:name "Face Sit"
:energy-cost 3
@@ -155,26 +150,21 @@
:description "Sits on the enemy's face and messes"
:element-types (list (make-instance 'yadfa-element-types:abdl) (make-instance 'yadfa-element-types:poison))))
(defmethod attack ((target base-character) (user base-character) (self face-sit))
- (format t "~a used ~a~%" (name-of user) (name-of self))
(let* ((m (mess :messer user))
- (c (calculate-diaper-usage user))
- (a (calculate-damage target user self)))
+ (c (calculate-diaper-usage user)))
(if (> (getf m :mess-amount) 0)
(format t "~a sits on ~a's face and messes~%" (name-of user) (name-of target))
(format t "~a sits on ~a's face~%" (name-of user) (name-of target)))
(when (>= (getf c :messiness) 2000)
(format t "~a is grossed out by the smell~%" (name-of target))
(set-status-condition 'yadfa-status-conditions:skunked target))
- (format t "~a is damaged by the impact~%" (name-of target))
- (decf (health-of target) a)
- a))
+ (format t "~a is damaged by the impact~%" (name-of target))))
(defclass teleporting-flood (wet-move-mixin) ()
(:default-initargs
:name "Teleporting Flood"
:description "Flood your diapers, but enchants the diaper so it all teleports into someone else's diaper."
:element-types (list (make-instance 'yadfa-element-types:abdl))))
(defmethod attack ((target base-character) (user base-character) (self teleporting-flood))
- (format t "~a used ~a~%" (name-of user) (name-of self))
(if (< (bladder/contents-of user) (bladder/need-to-potty-limit-of user))
(format t "But it failed~%")
(progn (wet :wetter user :clothes (wear-of target))
@@ -186,22 +176,20 @@
:description "Mess your diapers, but enchants the diaper so it all teleports into someone else's diaper."
:element-types (list (make-instance 'yadfa-element-types:abdl) (make-instance 'yadfa-element-types:poison))))
(defmethod attack ((target base-character) (user base-character) (self teleporting-mess))
- (format t "~a used ~a~%" (name-of user) (name-of self))
(if (< (bowels/contents-of user) (bowels/need-to-potty-limit-of user))
(format t "But it failed~%")
(progn (mess :messer user :clothes (wear-of target))
(format t "~a gets a freaked expression on ~a face as ~a messes ~a's pamps~%" (name-of target) (if (malep target) "his" "her")
(name-of user) (name-of target)))))
-(defclass fart (mess-move-mixin) ()
+(defclass fart (mess-move-mixin debuff) ()
(:default-initargs
:name "fart"
:description "Grosses out the enemies with gas. If poisoned or if desperate, you may end up messing yourself instead."
:energy-cost 10
:element-types (list (make-instance 'yadfa-element-types:abdl) (make-instance 'yadfa-element-types:poison))))
(defmethod attack ((target base-character) (user base-character) (attack fart))
- (f:fmt t (name-of user) " used " (name-of attack) #\Newline
- "But it failed." #\Newline))
-(defmethod attack ((target base-character) (user bowels-character) (attack fart))
+ (f:fmt t "But it failed." #\Newline))
+(defmethod attack :around ((target base-character) (user bowels-character) (attack fart))
(let* ((padding (get-babyish-padding user))
(name (name-of user))
(malep (malep user))
@@ -241,13 +229,13 @@
(set-status-condition 'yadfa-status-conditions:skunked i)
(f:fmt* t (name-of i) " is grossed out by the smell" #\Newline)))
(:fail (fail)))))))))
-(defclass spank (move) ()
+(defclass spank (damage-move) ()
(:default-initargs
:name "Spank"
:energy-cost 5
:power 10
:description "Spanks the enemy"))
-(defmethod attack ((target base-character) (user base-character) (self spank))
+(defmethod attack :around ((target base-character) (user base-character) (self spank))
(let ((a (calculate-damage target user self))
(times (random 10)))
(f:fmt t
diff --git a/packages.lisp b/packages.lisp
index c4f5482..82ae505 100644
--- a/packages.lisp
+++ b/packages.lisp
@@ -158,6 +158,14 @@
#:player
#:zone
#:move
+ #:buff
+ #:debuff
+ #:clear-status-mixin
+ #:health-inc-move
+ #:energy-inc-move
+ #:damage-move
+ #:damage-item
+ #:damage-wield
#:mess-move-mixin
#:wet-move-mixin
#:prop
@@ -207,6 +215,7 @@
#:stairs-of
#:element-types-of
#:last-process-potty-time-of
+ #:statuses-cleared-of
#:blocks-turn-of
#:duration-of
#:stat-delta-of
@@ -273,8 +282,7 @@
#:team-npc-spawn-list-of
#:energy-cost-of
#:power-of
- #:ai-flags-of
- #:attack-of
+ #:use-power-of
#:reload-count-of
#:ammo-power-of
#:ammo-of