aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Pouar <pouar@pouar.net>2020-10-02 12:04:27 -0500
committerGravatar Pouar <pouar@pouar.net>2020-10-02 12:04:27 -0500
commitde45953aecdada6a5d1868df2315f5f9163e7c81 (patch)
tree4d7c0cfa09c802774591ba23d78630ec8eaccf5b
parentthis is already done (diff)
add new function for getting the effective type effectiveness
used in dialog and damage calculation
-rw-r--r--core/libexec/declares.lisp1
-rw-r--r--core/libexec/functions.lisp18
-rw-r--r--core/libexec/generic-functions.lisp6
-rw-r--r--core/libexec/methods.lisp16
-rw-r--r--packages.lisp1
5 files changed, 28 insertions, 14 deletions
diff --git a/core/libexec/declares.lisp b/core/libexec/declares.lisp
index 66ea27c..f2dd246 100644
--- a/core/libexec/declares.lisp
+++ b/core/libexec/declares.lisp
@@ -47,4 +47,5 @@
process-battle)
(ftype (function (ally) (values (eql t) &optional)) ally-join)
(ftype (function (simple-string boolean simple-string) (values (eql t) &optional)) set-player)
+ (ftype (function (list list) (values (member :super-effective :not-very-effective :no-effect nil) real &optional)) effective-type-effectiveness)
(ftype (function (t) (values list &optional)) coerce-element-types))
diff --git a/core/libexec/functions.lisp b/core/libexec/functions.lisp
index 4dfe6a0..a1b143d 100644
--- a/core/libexec/functions.lisp
+++ b/core/libexec/functions.lisp
@@ -1428,6 +1428,24 @@
* (level-of user))
/ 100)
+ 5))))
+(defun effective-type-effectiveness (source-element-types target-element-types)
+ (iter (with (the fixnum super-effective) = 0)
+ (with (the fixnum not-very-effective) = 0)
+ (with (the fixnum no-effect) = 0)
+ (for source-element-type in source-element-types)
+ (iter (for target-element-type in target-element-types)
+ (case (type-match source-element-type target-element-type)
+ (:super-effective (incf super-effective))
+ (:not-very-effective (incf not-very-effective))
+ (:no-effect (incf no-effect))))
+ (finally (return (apply 'values (if (> no-effect 0)
+ '(:no-effect 0)
+ (let ((magnitude (- super-effective not-very-effective)))
+ (a:switch (magnitude :test (lambda (o e)
+ (funcall e o 0)))
+ ('< `(:not-very-effective ,magnitude))
+ ('> `(:super-effective ,magnitude))
+ ('= '(nil 0))))))))))
(defun present-stats (user)
(updating-present-with-effective-frame (*query-io* :unique-id `(stats% ,user) :id-test #'equal)
(clim:updating-output (*query-io*)
diff --git a/core/libexec/generic-functions.lisp b/core/libexec/generic-functions.lisp
index adc693f..0cb2c8a 100644
--- a/core/libexec/generic-functions.lisp
+++ b/core/libexec/generic-functions.lisp
@@ -162,7 +162,11 @@
(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)))
+ (f:fmt t (name-of target) " received " (calculate-damage target user attack) " damage" #\Newline
+ (:esc (case (effective-type-effectiveness (element-types-of attack) (element-types-of target))
+ (:not-very-effective (:fmt "It's not very effective" #\Newline))
+ (:super-effective (:fmt "It's super effective" #\Newline))
+ (:no-effect (:fmt "It had no effect" #\Newline))))))
(: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))
diff --git a/core/libexec/methods.lisp b/core/libexec/methods.lisp
index 9baff63..088e414 100644
--- a/core/libexec/methods.lisp
+++ b/core/libexec/methods.lisp
@@ -1605,25 +1605,15 @@ randomrange is @code{(random-from-range 85 100)}"
(let ((attack-element-types (element-types-of attack))
(target-element-types (element-types-of target))
(user-element-types (element-types-of user)))
- (s:mvlet ((super-effective not-very-effective no-effect (funcall (lambda ()
- (iter (with (the fixnum super-effective) = 0)
- (with (the fixnum not-very-effective) = 0)
- (with (the fixnum no-effect) = 0)
- (for attack-element-type in attack-element-types)
- (iter (for target-element-type in target-element-types)
- (case (type-match attack-element-type target-element-type)
- (:super-effective (incf super-effective))
- (:not-very-effective (incf not-very-effective))
- (:no-effect (incf no-effect))))
- (finally (return (values super-effective not-very-effective no-effect))))))))
+ (s:mvlet ((type-effectiveness magnitude (effective-type-effectiveness attack-element-types target-element-types)))
(round (u:$ (u:$ (u:$ (u:$ (u:$ (u:$ (u:$ 2 * (level-of user)) / 5) + 2) * (power-of attack) *
(u:$ (calculate-stat user :attack) / (calculate-stat target :defense)))
/ 50)
+ 2)
* (* (u:$ (s:random-in-range 85 101) / 100)
- (if (> no-effect 0)
+ (if (eq type-effectiveness :no-effect)
0
- (expt 2 (- super-effective not-very-effective)))
+ (expt 2 magnitude))
(if (intersection user-element-types attack-element-types
:key (lambda (o)
(class-of (coerce-element-type o)))
diff --git a/packages.lisp b/packages.lisp
index dd64c18..57389db 100644
--- a/packages.lisp
+++ b/packages.lisp
@@ -90,6 +90,7 @@
#:get-props-from-zone
#:get-items-from-prop
#:get-bitcoins-from-prop
+ #:effective-type-effectiveness
#:calculate-diaper-usage
#:calculate-diaper-usage*
#:calculate-level-to-exp