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