-
Notifications
You must be signed in to change notification settings - Fork 0
/
monsters.rkt
176 lines (146 loc) · 6.67 KB
/
monsters.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#lang racket
(require "character.rkt" "ai.rkt" "utils.rkt")
(provide (all-defined-out))
(define monster%
(class character%
(field [encounter '()])
(super-new)))
(define all-themes '())
(define (add-theme! t)
(unless (member t all-themes)
(set! all-themes (cons t all-themes))))
(define theme+cr-table (make-hash))
(define (theme+cr->monsters theme cr)
(hash-ref theme+cr-table (cons theme cr) '()))
(define-syntax-rule (define-simple-monster
def-name ch n #:themes ts
#:max-hp hp #:speed sp
#:attack-bonus ab #:ac ac #:damage-die dmg
#:cr cr #:ai ai
init-args ...)
(begin
(define def-name
(class monster%
(define my-ai (new ai [monster this]))
(define/override (act state) (send my-ai act state))
(define/public (wake-up) (send my-ai wake-up))
(define/override (get-attack-bonus) ab)
(define/override (get-ac) ac)
(define/override (get-damage-die) dmg)
(super-new [name n] [char ch] [max-hp (hp)] [speed sp]
init-args ...)))
(for ([t (in-list ts)])
(add-theme! t)
(hash-update! theme+cr-table (cons t cr)
(lambda (l) (cons def-name l)) '()))))
(define-simple-monster rat% #\r "rat" #:themes '(vermin tomb)
#:max-hp (dice d4 -1) #:speed 4
#:attack-bonus 0 #:ac 10 #:damage-die (dice 1)
#:cr 0 #:ai wander-ai%)
(define-simple-monster giant-rat% #\R "giant rat" #:themes '(vermin)
#:max-hp (dice 2 d6) #:speed 6
#:attack-bonus 4 #:ac 12 #:damage-die (dice d4 2)
#:cr 1/8 #:ai rush-ai%)
;; TODO pack tactics, once I implement advantage
(define-simple-monster kobold% #\k "kobold" #:themes '(vermin)
#:max-hp (dice 2 d6 -2) #:speed 6
#:attack-bonus 4 #:ac 12 #:damage-die (dice d4 2)
#:cr 1/8 #:ai injury-shy-ai%)
;; TODO + slinger variant
;; TODO pack tactics, once I implement advantage
(define-simple-monster goblin% #\g "goblin" #:themes '(vermin)
#:max-hp (dice 2 d6) #:speed 6
#:attack-bonus 4 #:ac 15 #:damage-die (dice d6 2)
#:cr 1/4 #:ai injury-shy-ai%)
;; TODO + archer variant
(define-simple-monster wolf% #\w "wolf" #:themes '(vermin)
#:max-hp (dice 2 d8 2) #:speed 8
#:attack-bonus 4 #:ac 13 #:damage-die (dice 2 d4 2)
#:cr 1/4 #:ai rush-ai%)
;; TODO pack tactics, once I implement advantage. + knock prone from attack
(define-simple-monster orc% #\o "orc" #:themes '(vermin)
#:max-hp (dice 2 d8 6) #:speed 6
#:attack-bonus 5 #:ac 13 #:damage-die (dice d12 3)
#:cr 1/2 #:ai rush-ai%
[article "an"])
;; TODO javelin variant. aggressive trait
;; (define-simple-monster gnoll% #\n "gnoll" #:themes '(vermin)
;; #:max-hp (dice 5 d8) #:speed 6
;; #:attack-bonus 4 #:ac 15 #:damage-die (dice d6 2)
;; #:cr 1/2 #:ai injury-shy-ai%)
;; TODO + bite attack, and archer variant
(define-simple-monster hobgoblin% #\h "hobgoblin" #:themes '(vermin)
#:max-hp (dice 2 d8 2) #:speed 6
#:attack-bonus 3 #:ac 18 #:damage-die (dice d8 1)
#:cr 1/2 #:ai rush-ai%)
;; TODO martial advantage. archer variant
;; (define-simple-monster worg% #\W "worg" #:themes '(vermin)
;; #:max-hp (dice 4 d10 4) #:speed 10
;; #:attack-bonus 5 #:ac 13 #:damage-die (dice 2 d6 3)
;; #:cr 1/2 #:ai rush-ai%) ; TODO want #\W for dire wolf instead
(define-simple-monster bugbear% #\b "bugbear" #:themes '(vermin)
#:max-hp (dice 5 d8 5) #:speed 6
#:attack-bonus 4 #:ac 16 #:damage-die (dice 2 d8 2)
#:cr 1 #:ai rush-ai%)
;; TODO surprise attack. javelin variant
(define-simple-monster dire-wolf% #\W "dire wolf" #:themes '(vermin)
#:max-hp (dice 5 d10 10) #:speed 10
#:attack-bonus 5 #:ac 14 #:damage-die (dice 2 d6 3)
#:cr 1 #:ai rush-ai%)
;; TODO pack tactics, once I implement advantage. + knock prone from attack
;; TODO removing cult for now. not very interesting, esp. with acolyte
;; that has no spells
;; (define-simple-monster cultist% #\c "cultist" #:themes '(cult)
;; #:max-hp (dice 2 d8) #:speed 6
;; #:attack-bonus 4 #:ac 12 #:damage-die (dice d6 1)
;; #:cr 1/8 #:ai rush-ai%)
;; (define-simple-monster acolyte% #\a "acolyte" #:themes '(cult)
;; #:max-hp (dice 2 d8) #:speed 6
;; #:attack-bonus 2 #:ac 10 #:damage-die d4
;; #:cr 1/4 #:ai injury-shy-ai%)
;; ;; TODO has healing spells, plus misc other spells (o/w not worth 50 xp)
(define-simple-monster bat% #\b "bat" #:themes '(tomb)
#:max-hp (dice d4 -1) #:speed 6
#:attack-bonus 0 #:ac 12 #:damage-die (dice 1)
#:cr 0 #:ai wander-ai%)
(define-simple-monster skeleton% #\s "skeleton" #:themes '(tomb)
#:max-hp (dice 2 d8 4) #:speed 6
#:attack-bonus 4 #:ac 13 #:damage-die (dice d6 2)
#:cr 1/4 #:ai rush-ai%)
;; TODO + archer variant
(define-simple-monster zombie% #\z "zombie" #:themes '(tomb)
#:max-hp (dice 3 d8 9) #:speed 4
#:attack-bonus 3 #:ac 8 #:damage-die (dice d6 1)
#:cr 1/4 #:ai wander-ai%)
(define-simple-monster commoner% #\c "commoner" #:themes '(castle)
#:max-hp d8 #:speed 6
#:attack-bonus 2 #:ac 10 #:damage-die d4
#:cr 0 #:ai injury-shy-ai%)
(define-simple-monster bandit% #\b "bandit" #:themes '(castle)
#:max-hp (dice 2 d8 2) #:speed 6
#:attack-bonus 4 #:ac 12 #:damage-die (dice d6 1)
#:cr 1/8 #:ai injury-shy-ai%)
;; TODO crossbow variant
(define-simple-monster guard% #\g "guard" #:themes '(#|cult|# castle)
#:max-hp (dice 2 d8 2) #:speed 6
#:attack-bonus 3 #:ac 16 #:damage-die (dice d6 1)
#:cr 1/4 #:ai rush-ai%) ; rules say CR 1/8, but stronger than a goblin...
(define-simple-monster thug% #\t "thug" #:themes '(castle)
#:max-hp (dice 5 d8 10) #:speed 6
#:attack-bonus 4 #:ac 11 #:damage-die (dice d6 2)
#:cr 1/2 #:ai rush-ai%)
;; TODO pack tactics. multiattack. crossbow variant
;; TODO warhorse for CR 1/2? or is that just silly?
(define-simple-monster spider% #\s "spider" #:themes '(jungle)
#:max-hp (dice d4 -1) #:speed 4
#:attack-bonus 4 #:ac 12 #:damage-die (dice 1)
#:cr 0 #:ai wander-ai%)
;; TODO should ignore difficult terrain. and add poison to attack
;; TODO for tomb: animated armor? (1), ghoul (1)
;; TODO for castle: knight (3)
;; TODO for jungle: lizard (0), poisonous snake? (1/8), constrictor snake? (1/4), giant lizard (1/4), giant poisonous snake (1/4), giant wolf spider (1/4), crocodile? (1/2), lizardfolk (1/2) (the whole point of ruin), swarm of insects (1/2), giant spider? (1)
;; (have one snake or the other. probably constrictor, since I don't have poison rules, and that will also make it less likely we'll have lower-level ruin encounters, which would be boring)
;; TODO need to look at actual encounters / dungeons
;; or, for each theme+template pair, how much variety is there actually...
;; TODO looked at list up to CR2
;; TODO other monsters. see page 61 of DM Basic Rules for monster per CR