rlm@162
|
1 (ns com.aurellem.gb.moves
|
rlm@162
|
2 (:use (com.aurellem.gb gb-driver util constants))
|
rlm@162
|
3 (:import [com.aurellem.gb.gb_driver SaveState]))
|
rlm@162
|
4
|
rlm@162
|
5 (def move-code->move-name
|
rlm@162
|
6 {
|
rlm@190
|
7 0x00 :end-of-moves
|
rlm@162
|
8 0x01 :pound
|
rlm@162
|
9 0x02 :karate-chop
|
rlm@162
|
10 0x03 :doubleslap
|
rlm@162
|
11 0x04 :comet-punch
|
rlm@162
|
12 0x05 :mega-punch
|
rlm@162
|
13 0x06 :pay-day
|
rlm@162
|
14 0x07 :fire-punch
|
rlm@162
|
15 0x08 :ice-punch
|
rlm@162
|
16 0x09 :thunderpunch
|
rlm@162
|
17 0x0A :scratch
|
rlm@162
|
18 0x0B :vicegrip
|
rlm@162
|
19 0x0C :guillotine
|
rlm@162
|
20 0x0D :razor-wind
|
rlm@162
|
21 0x0E :swords-dance
|
rlm@162
|
22 0x0F :cut
|
rlm@162
|
23 0x10 :gust
|
rlm@162
|
24 0x11 :wing-attack
|
rlm@162
|
25 0x12 :whirlwind
|
rlm@162
|
26 0x13 :fly
|
rlm@162
|
27 0x14 :bind
|
rlm@162
|
28 0x15 :slam
|
rlm@162
|
29 0x16 :vine-whip
|
rlm@162
|
30 0x17 :stomp
|
rlm@162
|
31 0x18 :double-kick
|
rlm@162
|
32 0x19 :mega-kick
|
rlm@162
|
33 0x1A :jump-kick
|
rlm@162
|
34 0x1B :rolling-kick
|
rlm@162
|
35 0x1C :sand-attack
|
rlm@162
|
36 0x1D :headbutt
|
rlm@162
|
37 0x1E :horn-attack
|
rlm@162
|
38 0x1F :fury-attack
|
rlm@162
|
39 0x20 :horn-drill
|
rlm@162
|
40 0x21 :tackle
|
rlm@162
|
41 0x22 :body-slam
|
rlm@162
|
42 0x23 :wrap
|
rlm@162
|
43 0x24 :take-down
|
rlm@162
|
44 0x25 :thrash
|
rlm@162
|
45 0x26 :double-edge
|
rlm@162
|
46 0x27 :tail-whip
|
rlm@162
|
47 0x28 :poison-sting
|
rlm@162
|
48 0x29 :twinneedle
|
rlm@162
|
49 0x2A :pin-missle
|
rlm@162
|
50 0x2B :leer
|
rlm@162
|
51 0x2C :bite
|
rlm@162
|
52 0x2D :growl
|
rlm@162
|
53 0x2E :roar
|
rlm@162
|
54 0x2F :sing
|
rlm@162
|
55 0x30 :supersonic
|
rlm@162
|
56 0x31 :sonicboom
|
rlm@162
|
57 0x32 :disable
|
rlm@162
|
58 0x33 :acid
|
rlm@162
|
59 0x34 :ember
|
rlm@162
|
60 0x35 :flamethrower
|
rlm@162
|
61 0x36 :mist
|
rlm@162
|
62 0x37 :water-gun
|
rlm@162
|
63 0x38 :hydro-pump
|
rlm@162
|
64 0x39 :surf
|
rlm@162
|
65 0x3A :ice-beam
|
rlm@162
|
66 0x3B :blizzard
|
rlm@162
|
67 0x3C :psybeam
|
rlm@162
|
68 0x3D :bubblebeam
|
rlm@162
|
69 0x3E :aurora-beam
|
rlm@162
|
70 0x3F :hyper-beam
|
rlm@162
|
71 0x40 :peck
|
rlm@162
|
72 0x41 :drill-peck
|
rlm@162
|
73 0x42 :submission
|
rlm@162
|
74 0x43 :low-kick
|
rlm@162
|
75 0x44 :counter
|
rlm@162
|
76 0x45 :seismic-toss
|
rlm@162
|
77 0x46 :strength
|
rlm@162
|
78 0x47 :absorb
|
rlm@162
|
79 0x48 :mega-drain
|
rlm@162
|
80 0x49 :leech-seed
|
rlm@162
|
81 0x4A :growth
|
rlm@162
|
82 0x4B :razor-leaf
|
rlm@162
|
83 0x4C :solarbeam
|
rlm@162
|
84 0x4D :poisonpowder
|
rlm@162
|
85 0x4E :stun-spore
|
rlm@162
|
86 0x4F :sleep-powder
|
rlm@162
|
87 0x50 :petal-dance
|
rlm@162
|
88 0x51 :string-shot
|
rlm@162
|
89 0x52 :dragon-rage
|
rlm@162
|
90 0x53 :fire-spin
|
rlm@162
|
91 0x54 :thundershock
|
rlm@162
|
92 0x55 :thunderbolt
|
rlm@162
|
93 0x56 :thunder-wave
|
rlm@162
|
94 0x57 :thunder
|
rlm@162
|
95 0x58 :rock-throw
|
rlm@162
|
96 0x59 :earthquake
|
rlm@162
|
97 0x5A :fissure
|
rlm@162
|
98 0x5B :dig
|
rlm@162
|
99 0x5C :toxic
|
rlm@162
|
100 0x5D :confusion
|
rlm@162
|
101 0x5E :psychic
|
rlm@162
|
102 0x5F :hypnosis
|
rlm@162
|
103 0x60 :meditate
|
rlm@162
|
104 0x61 :agility
|
rlm@162
|
105 0x62 :quick-attack
|
rlm@162
|
106 0x63 :rage
|
rlm@162
|
107 0x64 :teleport
|
rlm@162
|
108 0x65 :night-shade
|
rlm@162
|
109 0x66 :mimic
|
rlm@162
|
110 0x67 :screech
|
rlm@162
|
111 0x68 :double-team
|
rlm@162
|
112 0x69 :recover
|
rlm@162
|
113 0x6A :harden
|
rlm@162
|
114 0x6B :minimize
|
rlm@162
|
115 0x6C :smokescreen
|
rlm@162
|
116 0x6D :confuse-ray
|
rlm@162
|
117 0x6E :withdraw
|
rlm@162
|
118 0x6F :defense-curl
|
rlm@162
|
119 0x70 :barrier
|
rlm@162
|
120 0x71 :light-screen
|
rlm@162
|
121 0x72 :haze
|
rlm@162
|
122 0x73 :reflect
|
rlm@162
|
123 0x74 :focus-energy
|
rlm@162
|
124 0x75 :bide
|
rlm@162
|
125 0x76 :metronome
|
rlm@162
|
126 0x77 :mirror-move
|
rlm@162
|
127 0x78 :selfdestruct
|
rlm@162
|
128 0x79 :egg-bomb
|
rlm@162
|
129 0x7A :lick
|
rlm@162
|
130 0x7B :smog
|
rlm@162
|
131 0x7C :sludge
|
rlm@162
|
132 0x7D :bone-club
|
rlm@162
|
133 0x7E :fire-blast
|
rlm@162
|
134 0x7F :waterfall
|
rlm@162
|
135 0x80 :clamp
|
rlm@162
|
136 0x81 :swift
|
rlm@162
|
137 0x82 :skull-bash
|
rlm@162
|
138 0x83 :spike-cannon
|
rlm@162
|
139 0x84 :constrict
|
rlm@162
|
140 0x85 :amnesia
|
rlm@162
|
141 0x86 :kinesis
|
rlm@162
|
142 0x87 :softboiled
|
rlm@162
|
143 0x88 :hi-jump-kick
|
rlm@162
|
144 0x89 :glare
|
rlm@162
|
145 0x8A :dream-eater
|
rlm@162
|
146 0x8B :poison-gas
|
rlm@162
|
147 0x8C :barrage
|
rlm@162
|
148 0x8D :leech-life
|
rlm@162
|
149 0x8E :lovely-kiss
|
rlm@162
|
150 0x8F :sky-attack
|
rlm@162
|
151 0x90 :transform
|
rlm@162
|
152 0x91 :bubble
|
rlm@162
|
153 0x92 :dizzy-punch
|
rlm@162
|
154 0x93 :spore
|
rlm@162
|
155 0x94 :flash
|
rlm@162
|
156 0x95 :psywave
|
rlm@162
|
157 0x96 :splash
|
rlm@162
|
158 0x97 :acid-armor
|
rlm@162
|
159 0x98 :crabhammer
|
rlm@162
|
160 0x99 :explosion
|
rlm@162
|
161 0x9A :fury-swipes
|
rlm@162
|
162 0x9B :bonemerang
|
rlm@162
|
163 0x9C :rest
|
rlm@162
|
164 0x9D :rock-slide
|
rlm@162
|
165 0x9E :hyper-fang
|
rlm@162
|
166 0x9F :sharpen
|
rlm@162
|
167 0xA0 :conversion
|
rlm@162
|
168 0xA1 :tri-attack
|
rlm@162
|
169 0xA2 :super-fang
|
rlm@162
|
170 0xA3 :slash
|
rlm@162
|
171 0xA4 :substitute
|
rlm@197
|
172 0xA5 :struggle })
|
rlm@162
|
173
|
rlm@190
|
174 (def move-name->move-code
|
rlm@190
|
175 (zipmap (vals move-code->move-name)
|
rlm@190
|
176 (keys move-code->move-name)))
|
rlm@190
|
177
|
rlm@163
|
178 (def moves-codes-pokemon-1 0xD172)
|
rlm@163
|
179
|
rlm@163
|
180 (defn moves-codes-start [pokemon-num]
|
rlm@163
|
181 (assert (<= 0 pokemon-num 5))
|
rlm@163
|
182 (+ moves-codes-pokemon-1
|
rlm@163
|
183 (* pokemon-num pokemon-record-width)))
|
rlm@163
|
184
|
rlm@190
|
185 (defn read-moves
|
rlm@190
|
186 ([^SaveState state poke-num]
|
rlm@190
|
187 (let [start (moves-codes-start poke-num)]
|
rlm@190
|
188 (vec
|
rlm@190
|
189 (take-while
|
rlm@191
|
190 (partial not= :end-of-moves)
|
rlm@190
|
191 (map
|
rlm@190
|
192 move-code->move-name
|
rlm@190
|
193 (subvec (vec (memory state))
|
rlm@192
|
194 start (+ start 4)))))))
|
rlm@190
|
195 ([poke-num]
|
rlm@190
|
196 (read-moves @current-state poke-num)))
|
rlm@190
|
197
|
rlm@162
|
198 (defn give-moves
|
rlm@162
|
199 ([^SaveState state pokemon-num moves]
|
rlm@191
|
200 (assert (<= (count moves) 4))
|
rlm@162
|
201 (set-memory-range
|
rlm@162
|
202 state
|
rlm@162
|
203 (moves-codes-start pokemon-num)
|
rlm@191
|
204 (map #(move-name->move-code % %)
|
rlm@191
|
205 (concat moves
|
rlm@191
|
206 (repeat (- 4 (count moves)) :end-of-moves)))))
|
rlm@162
|
207 ([pokemon-num moves]
|
rlm@162
|
208 (give-moves @current-state pokemon-num moves))
|
rlm@162
|
209 ([moves]
|
rlm@162
|
210 (give-moves 0 moves)))
|
rlm@162
|
211
|
rlm@162
|
212 ;; Note regarding PP of moves -- both the current PP and the
|
rlm@162
|
213 ;; total PP are stored in the same value.
|
rlm@162
|
214 ;; they are bit-packed, with the first 2 bits containing the
|
rlm@162
|
215 ;; number of pp-ups that have been applied, and the next
|
rlm@162
|
216 ;; six bits containing the current pp of the move.
|
rlm@162
|
217 ;; thus, a move can have up to 63 current pp and up to
|
rlm@162
|
218 ;; three pp-ups applied.
|
rlm@162
|
219
|
rlm@162
|
220 (def pokemon-1-pp-start 0xD187)
|
rlm@162
|
221
|
rlm@162
|
222 (defn moves-pp-start [pokemon-num]
|
rlm@162
|
223 (assert (<= 0 pokemon-num 5))
|
rlm@162
|
224 (+ pokemon-1-pp-start (* pokemon-num pokemon-record-width)))
|
rlm@162
|
225
|
rlm@162
|
226 (defn read-pp
|
rlm@162
|
227 ([^SaveState state pokemon-num move-num]
|
rlm@162
|
228 (assert (<= 0 move-num 3))
|
rlm@162
|
229 (assert (<= 0 pokemon-num 5))
|
rlm@162
|
230 (let [pp-raw
|
rlm@162
|
231 (aget (memory state)
|
rlm@162
|
232 (+ (moves-pp-start pokemon-num)
|
rlm@162
|
233 move-num))
|
rlm@162
|
234 pp-up
|
rlm@162
|
235 (bit-shift-right
|
rlm@162
|
236 (bit-and
|
rlm@162
|
237 pp-raw
|
rlm@162
|
238 (Integer/parseInt "11000000" 2)) 6)
|
rlm@162
|
239 current-pp
|
rlm@162
|
240 (bit-and
|
rlm@162
|
241 pp-raw
|
rlm@162
|
242 (Integer/parseInt "00111111" 2))]
|
rlm@192
|
243 {:pp-ups pp-up :current-pp current-pp}))
|
rlm@162
|
244 ([pokemon-num move-num]
|
rlm@162
|
245 (read-pp @current-state pokemon-num move-num)))
|
rlm@162
|
246
|
rlm@162
|
247 (defn give-pp
|
rlm@162
|
248 ([^SaveState state pokemon-num move-num pp-ups current-pp]
|
rlm@162
|
249 (assert (<= 0 move-num 3))
|
rlm@162
|
250 (assert (<= 0 pokemon-num 5))
|
rlm@162
|
251 (assert (<= 0 pp-ups 3))
|
rlm@162
|
252 (assert (<= 0 current-pp 63))
|
rlm@162
|
253
|
rlm@162
|
254 (set-memory
|
rlm@162
|
255 state
|
rlm@162
|
256 (+ (moves-pp-start pokemon-num)
|
rlm@162
|
257 move-num)
|
rlm@162
|
258 (+
|
rlm@162
|
259 (bit-shift-left pp-ups 6)
|
rlm@162
|
260 (bit-and (Integer/parseInt
|
rlm@162
|
261 "00111111" 2)
|
rlm@162
|
262 current-pp))))
|
rlm@162
|
263 ([pokemon-num move-num pp-ups current-pp]
|
rlm@163
|
264 (give-pp @current-state
|
rlm@162
|
265 pokemon-num move-num pp-ups current-pp)))
|
rlm@190
|
266
|
rlm@209
|
267 (defn give-moves-pps
|
rlm@209
|
268 ([^SaveState state poke-num moves-pps]
|
rlm@209
|
269 (let [new-moves
|
rlm@209
|
270 (-> state
|
rlm@214
|
271 ;; zero out the pp of the pokemon's moves
|
rlm@214
|
272 (give-pp poke-num 0 0 0)
|
rlm@214
|
273 (give-pp poke-num 1 0 0)
|
rlm@214
|
274 (give-pp poke-num 2 0 0)
|
rlm@214
|
275 (give-pp poke-num 3 0 0)
|
rlm@209
|
276 (give-moves poke-num (map first moves-pps)))]
|
rlm@209
|
277 (reduce (fn [state move-num]
|
rlm@209
|
278 (let [pp (second (nth moves-pps move-num))]
|
rlm@209
|
279 (give-pp state poke-num move-num
|
rlm@209
|
280 (:pp-ups pp)
|
rlm@209
|
281 (:current-pp pp))))
|
rlm@209
|
282 new-moves (range (count moves-pps)))))
|
rlm@209
|
283 ([poke-num moves-pps]
|
rlm@209
|
284 (give-moves-pps @current-state poke-num moves-pps)))
|
rlm@209
|
285
|
rlm@197
|
286
|
rlm@197
|
287 (def move-name->move-pp
|
rlm@197
|
288 {
|
rlm@197
|
289 :absorb 20
|
rlm@197
|
290 :acid 30
|
rlm@225
|
291 :acid-armor 40 ;; WTF happens with 3 PP-UPs??! (answer: 61PP!)
|
rlm@197
|
292 :agility 30
|
rlm@197
|
293 :amnesia 20
|
rlm@197
|
294 :aurora-beam 20
|
rlm@197
|
295 :barrage 20
|
rlm@197
|
296 :barrier 30
|
rlm@197
|
297 :bide 10
|
rlm@197
|
298 :bind 20
|
rlm@197
|
299 :bite 25
|
rlm@197
|
300 :blizzard 5
|
rlm@197
|
301 :body-slam 15
|
rlm@197
|
302 :bone-club 20
|
rlm@197
|
303 :bonemerang 10
|
rlm@197
|
304 :bubble 30
|
rlm@197
|
305 :bubblebeam 20
|
rlm@197
|
306 :clamp 10
|
rlm@197
|
307 :comet-punch 15
|
rlm@197
|
308 :confuse-ray 10
|
rlm@197
|
309 :confusion 25
|
rlm@197
|
310 :constrict 35
|
rlm@197
|
311 :conversion 30
|
rlm@197
|
312 :counter 20
|
rlm@197
|
313 :crabhammer 10
|
rlm@197
|
314 :cut 30
|
rlm@197
|
315 :defense-curl 40
|
rlm@197
|
316 :dig 10
|
rlm@197
|
317 :disable 20
|
rlm@197
|
318 :dizzy-punch 10
|
rlm@197
|
319 :double-edge 15
|
rlm@197
|
320 :double-kick 30
|
rlm@197
|
321 :double-team 10
|
rlm@197
|
322 :doubleslap 15
|
rlm@197
|
323 :dragon-rage 10
|
rlm@197
|
324 :dream-eater 15
|
rlm@197
|
325 :drill-peck 20
|
rlm@197
|
326 :earthquake 10
|
rlm@197
|
327 :egg-bomb 10
|
rlm@197
|
328 :ember 25
|
rlm@197
|
329 :explosion 5
|
rlm@197
|
330 :fire-blast 5
|
rlm@197
|
331 :fire-punch 15
|
rlm@197
|
332 :fire-spin 15
|
rlm@197
|
333 :fissure 5
|
rlm@197
|
334 :flamethrower 15
|
rlm@197
|
335 :flash 20
|
rlm@197
|
336 :fly 15
|
rlm@197
|
337 :focus-energy 30
|
rlm@197
|
338 :fury-attack 20
|
rlm@197
|
339 :fury-swipes 15
|
rlm@197
|
340 :glare 30
|
rlm@197
|
341 :growl 40
|
rlm@197
|
342 :growth 40
|
rlm@197
|
343 :guillotine 5
|
rlm@197
|
344 :gust 35
|
rlm@197
|
345 :harden 30
|
rlm@198
|
346 :haze 30
|
rlm@198
|
347 :headbutt 15
|
rlm@198
|
348 :hi-jump-kick 20
|
rlm@198
|
349 :horn-attack 25
|
rlm@198
|
350 :horn-drill 5
|
rlm@198
|
351 :hydro-pump 5
|
rlm@198
|
352 :hyper-beam 5
|
rlm@198
|
353 :hyper-fang 15
|
rlm@198
|
354 :hypnosis 20
|
rlm@198
|
355 :ice-beam 10
|
rlm@198
|
356 :ice-punch 15
|
rlm@198
|
357 :jump-kick 25
|
rlm@198
|
358 :karate-chop 25
|
rlm@198
|
359 :kinesis 15
|
rlm@198
|
360 :leech-life 15
|
rlm@198
|
361 :leech-seed 10
|
rlm@198
|
362 :leer 30
|
rlm@198
|
363 :lick 30
|
rlm@198
|
364 :light-screen 30
|
rlm@198
|
365 :lovely-kiss 10
|
rlm@198
|
366 :low-kick 20
|
rlm@198
|
367 :meditate 40
|
rlm@198
|
368 :mega-drain 10
|
rlm@198
|
369 :mega-kick 5
|
rlm@198
|
370 :mega-punch 20
|
rlm@198
|
371 :metronome 10
|
rlm@198
|
372 :mimic 10
|
rlm@198
|
373 :minimize 20
|
rlm@198
|
374 :mirror-move 20
|
rlm@198
|
375 :mist 30
|
rlm@198
|
376 :night-shade 15
|
rlm@198
|
377 :pay-day 20
|
rlm@198
|
378 :peck 35
|
rlm@198
|
379 :petal-dance 20
|
rlm@198
|
380 :pin-missle 20
|
rlm@198
|
381 :poison-gas 40
|
rlm@198
|
382 :poison-sting 35
|
rlm@198
|
383 :poisonpowder 35
|
rlm@198
|
384 :pound 35
|
rlm@198
|
385 :psybeam 20
|
rlm@198
|
386 :psychic 10
|
rlm@198
|
387 :psywave 15
|
rlm@198
|
388 :quick-attack 30
|
rlm@198
|
389 :rage 20
|
rlm@198
|
390 :razor-leaf 25
|
rlm@198
|
391 :razor-wind 10
|
rlm@198
|
392 :recover 20
|
rlm@198
|
393 :reflect 20
|
rlm@198
|
394 :rest 10
|
rlm@198
|
395 :roar 20
|
rlm@198
|
396 :rock-slide 10
|
rlm@198
|
397 :rock-throw 15
|
rlm@198
|
398 :rolling-kick 15
|
rlm@198
|
399 :sand-attack 15
|
rlm@209
|
400 :scratch 35
|
rlm@198
|
401 :screech 40
|
rlm@198
|
402 :seismic-toss 20
|
rlm@198
|
403 :selfdestruct 5
|
rlm@198
|
404 :sharpen 30
|
rlm@198
|
405 :sing 15
|
rlm@198
|
406 :skull-bash 15
|
rlm@198
|
407 :sky-attack 5
|
rlm@198
|
408 :slam 20
|
rlm@198
|
409 :slash 20
|
rlm@198
|
410 :sleep-powder 15
|
rlm@198
|
411 :sludge 20
|
rlm@198
|
412 :smog 20
|
rlm@198
|
413 :smokescreen 20
|
rlm@198
|
414 :softboiled 10
|
rlm@198
|
415 :solarbeam 10
|
rlm@198
|
416 :sonicboom 20
|
rlm@198
|
417 :spike-cannon 15
|
rlm@198
|
418 :splash 40
|
rlm@198
|
419 :spore 15
|
rlm@198
|
420 :stomp 20
|
rlm@198
|
421 :strength 15
|
rlm@198
|
422 :string-shot 40
|
rlm@198
|
423 :struggle 1
|
rlm@198
|
424 :stun-spore 30
|
rlm@198
|
425 :submission 25
|
rlm@198
|
426 :substitute 10
|
rlm@198
|
427 :super-fang 10
|
rlm@198
|
428 :supersonic 20
|
rlm@198
|
429 :surf 15
|
rlm@198
|
430 :swift 20
|
rlm@198
|
431 :swords-dance 30
|
rlm@198
|
432 :tackle 35
|
rlm@198
|
433 :tail-whip 30
|
rlm@198
|
434 :take-down 20
|
rlm@198
|
435 :teleport 20
|
rlm@198
|
436 :thrash 20
|
rlm@198
|
437 :thunder 10
|
rlm@198
|
438 :thunder-wave 20
|
rlm@198
|
439 :thunderbolt 15
|
rlm@198
|
440 :thunderpunch 15
|
rlm@198
|
441 :thundershock 30
|
rlm@198
|
442 :toxic 10
|
rlm@198
|
443 :transform 10
|
rlm@198
|
444 :tri-attack 10
|
rlm@198
|
445 :twinneedle 20
|
rlm@198
|
446 :vicegrip 30
|
rlm@198
|
447 :vine-whip 10
|
rlm@198
|
448 :water-gun 25
|
rlm@198
|
449 :waterfall 15
|
rlm@198
|
450 :whirlwind 20
|
rlm@198
|
451 :wing-attack 35
|
rlm@198
|
452 :withdraw 40
|
rlm@198
|
453 :wrap 20})
|
rlm@198
|
454
|
rlm@198
|
455 (defn max-pp [name pp-ups]
|
rlm@225
|
456 (if (= 40 (move-name->move-pp name))
|
rlm@225
|
457 (+ 40 (* 7 pp-ups))
|
rlm@225
|
458 (int (* (+ 1 (* (/ 1 5) pp-ups))
|
rlm@225
|
459 (move-name->move-pp name))))) |