view clojure/com/aurellem/gb/moves.clj @ 603:b3e5006e23f0

cache advanced moves.
author Robert McIntyre <rlm@mit.edu>
date Sun, 02 Sep 2012 09:33:40 -0500
parents df9cad9909d2
children
line wrap: on
line source
1 (ns com.aurellem.gb.moves
2 (:use (com.aurellem.gb gb-driver util constants hxc))
3 (:import [com.aurellem.gb.gb_driver SaveState]))
6 ;;; grab the move data directly from the rom
7 (def move-code->move-name ;; alternate name: moves
8 ((comp vec cons)
9 :end-of-moves
10 (map format-name (hxc-move-names))))
12 (def move-name->move-code ;; alternate name: move-id
13 (zipmap
14 move-code->move-name
15 (range)))
17 (def move-name->move-pp
18 (comp :pp (hxc-move-data)))
20 (defn max-pp [name pp-ups]
21 (if (= 40 (move-name->move-pp name))
22 (+ 40 (* 7 pp-ups))
23 (int (* (+ 1 (* (/ 1 5) pp-ups))
24 (move-name->move-pp name)))))
26 (def moves-codes-pokemon-1 0xD172)
28 (defn moves-codes-start [pokemon-num]
29 (assert (<= 0 pokemon-num 5))
30 (+ moves-codes-pokemon-1
31 (* pokemon-num pokemon-record-width)))
33 (defn read-moves
34 ([^SaveState state poke-num]
35 (let [start (moves-codes-start poke-num)]
36 (vec
37 (take-while
38 (partial not= :end-of-moves)
39 (map
40 move-code->move-name
41 (subvec (vec (memory state))
42 start (+ start 4)))))))
43 ([poke-num]
44 (read-moves @current-state poke-num)))
46 (defn give-moves
47 ([^SaveState state pokemon-num moves]
48 (assert (<= (count moves) 4))
49 (set-memory-range
50 state
51 (moves-codes-start pokemon-num)
52 (map #(move-name->move-code % %)
53 (concat moves
54 (repeat (- 4 (count moves)) :end-of-moves)))))
55 ([pokemon-num moves]
56 (give-moves @current-state pokemon-num moves))
57 ([moves]
58 (give-moves 0 moves)))
60 ;; Note regarding PP of moves -- both the current PP and the
61 ;; total PP are stored in the same value.
62 ;; they are bit-packed, with the first 2 bits containing the
63 ;; number of pp-ups that have been applied, and the next
64 ;; six bits containing the current pp of the move.
65 ;; thus, a move can have up to 63 current pp and up to
66 ;; three pp-ups applied.
68 (def pokemon-1-pp-start 0xD187)
70 (defn moves-pp-start [pokemon-num]
71 (assert (<= 0 pokemon-num 5))
72 (+ pokemon-1-pp-start (* pokemon-num pokemon-record-width)))
74 (defn read-pp
75 ([^SaveState state pokemon-num move-num]
76 (assert (<= 0 move-num 3))
77 (assert (<= 0 pokemon-num 5))
78 (let [pp-raw
79 (aget (memory state)
80 (+ (moves-pp-start pokemon-num)
81 move-num))
82 pp-up
83 (bit-shift-right
84 (bit-and
85 pp-raw
86 (Integer/parseInt "11000000" 2)) 6)
87 current-pp
88 (bit-and
89 pp-raw
90 (Integer/parseInt "00111111" 2))]
91 {:pp-ups pp-up :current-pp current-pp}))
92 ([pokemon-num move-num]
93 (read-pp @current-state pokemon-num move-num)))
95 (defn give-pp
96 ([^SaveState state pokemon-num move-num pp-ups current-pp]
97 (assert (<= 0 move-num 3))
98 (assert (<= 0 pokemon-num 5))
99 (assert (<= 0 pp-ups 3))
100 (assert (<= 0 current-pp 63))
102 (set-memory
103 state
104 (+ (moves-pp-start pokemon-num)
105 move-num)
106 (+
107 (bit-shift-left pp-ups 6)
108 (bit-and (Integer/parseInt
109 "00111111" 2)
110 current-pp))))
111 ([pokemon-num move-num pp-ups current-pp]
112 (give-pp @current-state
113 pokemon-num move-num pp-ups current-pp)))
115 (defn give-moves-pps
116 ([^SaveState state poke-num moves-pps]
117 (let [new-moves
118 (-> state
119 ;; zero out the pp of the pokemon's moves
120 (give-pp poke-num 0 0 0)
121 (give-pp poke-num 1 0 0)
122 (give-pp poke-num 2 0 0)
123 (give-pp poke-num 3 0 0)
124 (give-moves poke-num (map first moves-pps)))]
125 (reduce (fn [state move-num]
126 (let [pp (second (nth moves-pps move-num))]
127 (give-pp state poke-num move-num
128 (:pp-ups pp)
129 (:current-pp pp))))
130 new-moves (range (count moves-pps)))))
131 ([poke-num moves-pps]
132 (give-moves-pps @current-state poke-num moves-pps)))