Created
January 26, 2010 20:54
-
-
Save tmountain/287215 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns combat) | |
(defn roll | |
"roll the dice (roll 1 6) => 1d6, (roll 2 6) => 2d6" | |
[dice max] | |
(apply + (for [x (range dice)] (inc (rand-int max))))) | |
(defn weapon-dmg | |
"calculates a damage roll for the given weapon" | |
[weapon] | |
(let [dice (first (:dmg weapon)) | |
max (second (:dmg weapon)) | |
mod (or (:modifier weapon) 0)] | |
(+ (roll dice max) mod))) | |
(defn armor-class | |
"calculates the total AC for the given set of armor" | |
[armor] | |
(if (empty? armor) | |
0 | |
; 10 is the base AC, so subtract the gear from that | |
(let [armor-vals (map #(:ac %1) armor)] | |
(- 10 (apply + armor-vals))))) | |
(defn dmg-reduction | |
"calculates the damage reduction from the current AC" | |
[armor-class] | |
(if (< armor-class 0) | |
(inc (rand-int (Math/abs armor-class))) | |
0)) | |
(defn hit? | |
"returns true if an attack hits. false if it misses | |
When a monster attacks you, 1d20 is rolled. Rolling a target number | |
or lower results in a hit. In simple situations at low levels, | |
this target number is equal to: | |
10 + your AC + the monster's level | |
At higher levels and in funny circumstances, things become more complex. | |
If your AC is negative, the formula for the target number is: | |
10 + (a random number from -1 to your AC) + the monster's level." | |
[attacker-level defender-armor-class] | |
(let [ac (if (< defender-armor-class 0) | |
(+ attacker-level | |
(+ 10 | |
(- (inc (rand-int (Math/abs defender-armor-class)))))) | |
(+ attacker-level (+ 10 defender-armor-class))) | |
; If the final target number is so good that it would be | |
; less than or equal to zero, set it to 1. | |
real-ac (if (< ac 0) | |
1 | |
ac)] | |
(if (< (roll 1 20) real-ac) | |
true | |
false))) | |
(defn dmg [attacker-level weapon armor] | |
"returns the damage for an attack | |
weapon should be a map representing the attacker's weapon | |
armor is a list of maps representing the defender's armor" | |
(let [ac (armor-class armor) | |
base-dmg (weapon-dmg weapon) | |
net-dmg (- base-dmg (dmg-reduction ac))] | |
(if (hit? attacker-level ac) | |
(if (< net-dmg 0) | |
1 ; if hit, minimum damage is one | |
net-dmg) | |
0))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment