rlm@162: (ns com.aurellem.gb.moves ocsenave@281: (:use (com.aurellem.gb gb-driver util constants hxc)) rlm@162: (:import [com.aurellem.gb.gb_driver SaveState])) rlm@162: rlm@162: ocsenave@281: ;;; grab the move data directly from the rom ocsenave@281: (def move-code->move-name ;; alternate name: moves ocsenave@281: ((comp vec cons) ocsenave@281: :end-of-moves ocsenave@289: (map format-name (hxc-move-names)))) ocsenave@281: ocsenave@281: (def move-name->move-code ;; alternate name: move-id ocsenave@281: (zipmap ocsenave@289: move-code->move-name ocsenave@281: (range))) ocsenave@281: ocsenave@281: (def move-name->move-pp ocsenave@281: (comp :pp (hxc-move-data))) ocsenave@281: ocsenave@281: (defn max-pp [name pp-ups] ocsenave@281: (if (= 40 (move-name->move-pp name)) ocsenave@281: (+ 40 (* 7 pp-ups)) ocsenave@281: (int (* (+ 1 (* (/ 1 5) pp-ups)) ocsenave@281: (move-name->move-pp name))))) rlm@190: rlm@163: (def moves-codes-pokemon-1 0xD172) rlm@163: rlm@163: (defn moves-codes-start [pokemon-num] rlm@163: (assert (<= 0 pokemon-num 5)) rlm@163: (+ moves-codes-pokemon-1 rlm@163: (* pokemon-num pokemon-record-width))) rlm@163: rlm@190: (defn read-moves rlm@190: ([^SaveState state poke-num] rlm@190: (let [start (moves-codes-start poke-num)] rlm@190: (vec rlm@190: (take-while rlm@191: (partial not= :end-of-moves) rlm@190: (map rlm@190: move-code->move-name rlm@190: (subvec (vec (memory state)) rlm@192: start (+ start 4))))))) rlm@190: ([poke-num] rlm@190: (read-moves @current-state poke-num))) rlm@190: rlm@162: (defn give-moves rlm@162: ([^SaveState state pokemon-num moves] rlm@191: (assert (<= (count moves) 4)) rlm@162: (set-memory-range rlm@162: state rlm@162: (moves-codes-start pokemon-num) rlm@191: (map #(move-name->move-code % %) rlm@191: (concat moves rlm@191: (repeat (- 4 (count moves)) :end-of-moves))))) rlm@162: ([pokemon-num moves] rlm@162: (give-moves @current-state pokemon-num moves)) rlm@162: ([moves] rlm@162: (give-moves 0 moves))) rlm@162: rlm@162: ;; Note regarding PP of moves -- both the current PP and the rlm@162: ;; total PP are stored in the same value. rlm@162: ;; they are bit-packed, with the first 2 bits containing the rlm@162: ;; number of pp-ups that have been applied, and the next rlm@162: ;; six bits containing the current pp of the move. rlm@162: ;; thus, a move can have up to 63 current pp and up to rlm@162: ;; three pp-ups applied. rlm@162: rlm@162: (def pokemon-1-pp-start 0xD187) rlm@162: rlm@162: (defn moves-pp-start [pokemon-num] rlm@162: (assert (<= 0 pokemon-num 5)) rlm@162: (+ pokemon-1-pp-start (* pokemon-num pokemon-record-width))) rlm@162: rlm@162: (defn read-pp rlm@162: ([^SaveState state pokemon-num move-num] rlm@162: (assert (<= 0 move-num 3)) rlm@162: (assert (<= 0 pokemon-num 5)) rlm@162: (let [pp-raw rlm@162: (aget (memory state) rlm@162: (+ (moves-pp-start pokemon-num) rlm@162: move-num)) rlm@162: pp-up rlm@162: (bit-shift-right rlm@162: (bit-and rlm@162: pp-raw rlm@162: (Integer/parseInt "11000000" 2)) 6) rlm@162: current-pp rlm@162: (bit-and rlm@162: pp-raw rlm@162: (Integer/parseInt "00111111" 2))] rlm@192: {:pp-ups pp-up :current-pp current-pp})) rlm@162: ([pokemon-num move-num] rlm@162: (read-pp @current-state pokemon-num move-num))) rlm@162: rlm@162: (defn give-pp rlm@162: ([^SaveState state pokemon-num move-num pp-ups current-pp] rlm@162: (assert (<= 0 move-num 3)) rlm@162: (assert (<= 0 pokemon-num 5)) rlm@162: (assert (<= 0 pp-ups 3)) rlm@162: (assert (<= 0 current-pp 63)) rlm@162: rlm@162: (set-memory rlm@162: state rlm@162: (+ (moves-pp-start pokemon-num) rlm@162: move-num) rlm@162: (+ rlm@162: (bit-shift-left pp-ups 6) rlm@162: (bit-and (Integer/parseInt rlm@162: "00111111" 2) rlm@162: current-pp)))) rlm@162: ([pokemon-num move-num pp-ups current-pp] rlm@163: (give-pp @current-state rlm@162: pokemon-num move-num pp-ups current-pp))) rlm@190: rlm@209: (defn give-moves-pps rlm@209: ([^SaveState state poke-num moves-pps] rlm@209: (let [new-moves rlm@209: (-> state rlm@214: ;; zero out the pp of the pokemon's moves rlm@214: (give-pp poke-num 0 0 0) rlm@214: (give-pp poke-num 1 0 0) rlm@214: (give-pp poke-num 2 0 0) rlm@214: (give-pp poke-num 3 0 0) rlm@209: (give-moves poke-num (map first moves-pps)))] rlm@209: (reduce (fn [state move-num] rlm@209: (let [pp (second (nth moves-pps move-num))] rlm@209: (give-pp state poke-num move-num rlm@209: (:pp-ups pp) rlm@209: (:current-pp pp)))) rlm@209: new-moves (range (count moves-pps))))) rlm@209: ([poke-num moves-pps] rlm@209: (give-moves-pps @current-state poke-num moves-pps))) rlm@209: rlm@197: