rlm@162: (ns com.aurellem.gb.moves rlm@162: (:use (com.aurellem.gb gb-driver util constants)) rlm@162: (:import [com.aurellem.gb.gb_driver SaveState])) rlm@162: rlm@162: (def move-code->move-name rlm@162: { rlm@190: 0x00 :end-of-moves rlm@162: 0x01 :pound rlm@162: 0x02 :karate-chop rlm@162: 0x03 :doubleslap rlm@162: 0x04 :comet-punch rlm@162: 0x05 :mega-punch rlm@162: 0x06 :pay-day rlm@162: 0x07 :fire-punch rlm@162: 0x08 :ice-punch rlm@162: 0x09 :thunderpunch rlm@162: 0x0A :scratch rlm@162: 0x0B :vicegrip rlm@162: 0x0C :guillotine rlm@162: 0x0D :razor-wind rlm@162: 0x0E :swords-dance rlm@162: 0x0F :cut rlm@162: 0x10 :gust rlm@162: 0x11 :wing-attack rlm@162: 0x12 :whirlwind rlm@162: 0x13 :fly rlm@162: 0x14 :bind rlm@162: 0x15 :slam rlm@162: 0x16 :vine-whip rlm@162: 0x17 :stomp rlm@162: 0x18 :double-kick rlm@162: 0x19 :mega-kick rlm@162: 0x1A :jump-kick rlm@162: 0x1B :rolling-kick rlm@162: 0x1C :sand-attack rlm@162: 0x1D :headbutt rlm@162: 0x1E :horn-attack rlm@162: 0x1F :fury-attack rlm@162: 0x20 :horn-drill rlm@162: 0x21 :tackle rlm@162: 0x22 :body-slam rlm@162: 0x23 :wrap rlm@162: 0x24 :take-down rlm@162: 0x25 :thrash rlm@162: 0x26 :double-edge rlm@162: 0x27 :tail-whip rlm@162: 0x28 :poison-sting rlm@162: 0x29 :twinneedle rlm@162: 0x2A :pin-missle rlm@162: 0x2B :leer rlm@162: 0x2C :bite rlm@162: 0x2D :growl rlm@162: 0x2E :roar rlm@162: 0x2F :sing rlm@162: 0x30 :supersonic rlm@162: 0x31 :sonicboom rlm@162: 0x32 :disable rlm@162: 0x33 :acid rlm@162: 0x34 :ember rlm@162: 0x35 :flamethrower rlm@162: 0x36 :mist rlm@162: 0x37 :water-gun rlm@162: 0x38 :hydro-pump rlm@162: 0x39 :surf rlm@162: 0x3A :ice-beam rlm@162: 0x3B :blizzard rlm@162: 0x3C :psybeam rlm@162: 0x3D :bubblebeam rlm@162: 0x3E :aurora-beam rlm@162: 0x3F :hyper-beam rlm@162: 0x40 :peck rlm@162: 0x41 :drill-peck rlm@162: 0x42 :submission rlm@162: 0x43 :low-kick rlm@162: 0x44 :counter rlm@162: 0x45 :seismic-toss rlm@162: 0x46 :strength rlm@162: 0x47 :absorb rlm@162: 0x48 :mega-drain rlm@162: 0x49 :leech-seed rlm@162: 0x4A :growth rlm@162: 0x4B :razor-leaf rlm@162: 0x4C :solarbeam rlm@162: 0x4D :poisonpowder rlm@162: 0x4E :stun-spore rlm@162: 0x4F :sleep-powder rlm@162: 0x50 :petal-dance rlm@162: 0x51 :string-shot rlm@162: 0x52 :dragon-rage rlm@162: 0x53 :fire-spin rlm@162: 0x54 :thundershock rlm@162: 0x55 :thunderbolt rlm@162: 0x56 :thunder-wave rlm@162: 0x57 :thunder rlm@162: 0x58 :rock-throw rlm@162: 0x59 :earthquake rlm@162: 0x5A :fissure rlm@162: 0x5B :dig rlm@162: 0x5C :toxic rlm@162: 0x5D :confusion rlm@162: 0x5E :psychic rlm@162: 0x5F :hypnosis rlm@162: 0x60 :meditate rlm@162: 0x61 :agility rlm@162: 0x62 :quick-attack rlm@162: 0x63 :rage rlm@162: 0x64 :teleport rlm@162: 0x65 :night-shade rlm@162: 0x66 :mimic rlm@162: 0x67 :screech rlm@162: 0x68 :double-team rlm@162: 0x69 :recover rlm@162: 0x6A :harden rlm@162: 0x6B :minimize rlm@162: 0x6C :smokescreen rlm@162: 0x6D :confuse-ray rlm@162: 0x6E :withdraw rlm@162: 0x6F :defense-curl rlm@162: 0x70 :barrier rlm@162: 0x71 :light-screen rlm@162: 0x72 :haze rlm@162: 0x73 :reflect rlm@162: 0x74 :focus-energy rlm@162: 0x75 :bide rlm@162: 0x76 :metronome rlm@162: 0x77 :mirror-move rlm@162: 0x78 :selfdestruct rlm@162: 0x79 :egg-bomb rlm@162: 0x7A :lick rlm@162: 0x7B :smog rlm@162: 0x7C :sludge rlm@162: 0x7D :bone-club rlm@162: 0x7E :fire-blast rlm@162: 0x7F :waterfall rlm@162: 0x80 :clamp rlm@162: 0x81 :swift rlm@162: 0x82 :skull-bash rlm@162: 0x83 :spike-cannon rlm@162: 0x84 :constrict rlm@162: 0x85 :amnesia rlm@162: 0x86 :kinesis rlm@162: 0x87 :softboiled rlm@162: 0x88 :hi-jump-kick rlm@162: 0x89 :glare rlm@162: 0x8A :dream-eater rlm@162: 0x8B :poison-gas rlm@162: 0x8C :barrage rlm@162: 0x8D :leech-life rlm@162: 0x8E :lovely-kiss rlm@162: 0x8F :sky-attack rlm@162: 0x90 :transform rlm@162: 0x91 :bubble rlm@162: 0x92 :dizzy-punch rlm@162: 0x93 :spore rlm@162: 0x94 :flash rlm@162: 0x95 :psywave rlm@162: 0x96 :splash rlm@162: 0x97 :acid-armor rlm@162: 0x98 :crabhammer rlm@162: 0x99 :explosion rlm@162: 0x9A :fury-swipes rlm@162: 0x9B :bonemerang rlm@162: 0x9C :rest rlm@162: 0x9D :rock-slide rlm@162: 0x9E :hyper-fang rlm@162: 0x9F :sharpen rlm@162: 0xA0 :conversion rlm@162: 0xA1 :tri-attack rlm@162: 0xA2 :super-fang rlm@162: 0xA3 :slash rlm@162: 0xA4 :substitute rlm@197: 0xA5 :struggle }) rlm@162: rlm@190: (def move-name->move-code rlm@190: (zipmap (vals move-code->move-name) rlm@190: (keys move-code->move-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@197: rlm@197: (def move-name->move-pp rlm@197: { rlm@197: :absorb 20 rlm@197: :acid 30 rlm@197: :acid-armor 40 ;; WTF happens with 3 PP-UPs??! rlm@197: :agility 30 rlm@197: :amnesia 20 rlm@197: :aurora-beam 20 rlm@197: :barrage 20 rlm@197: :barrier 30 rlm@197: :bide 10 rlm@197: :bind 20 rlm@197: :bite 25 rlm@197: :blizzard 5 rlm@197: :body-slam 15 rlm@197: :bone-club 20 rlm@197: :bonemerang 10 rlm@197: :bubble 30 rlm@197: :bubblebeam 20 rlm@197: :clamp 10 rlm@197: :comet-punch 15 rlm@197: :confuse-ray 10 rlm@197: :confusion 25 rlm@197: :constrict 35 rlm@197: :conversion 30 rlm@197: :counter 20 rlm@197: :crabhammer 10 rlm@197: :cut 30 rlm@197: :defense-curl 40 rlm@197: :dig 10 rlm@197: :disable 20 rlm@197: :dizzy-punch 10 rlm@197: :double-edge 15 rlm@197: :double-kick 30 rlm@197: :double-team 10 rlm@197: :doubleslap 15 rlm@197: :dragon-rage 10 rlm@197: :dream-eater 15 rlm@197: :drill-peck 20 rlm@197: :earthquake 10 rlm@197: :egg-bomb 10 rlm@197: :ember 25 rlm@197: :explosion 5 rlm@197: :fire-blast 5 rlm@197: :fire-punch 15 rlm@197: :fire-spin 15 rlm@197: :fissure 5 rlm@197: :flamethrower 15 rlm@197: :flash 20 rlm@197: :fly 15 rlm@197: :focus-energy 30 rlm@197: :fury-attack 20 rlm@197: :fury-swipes 15 rlm@197: :glare 30 rlm@197: :growl 40 rlm@197: :growth 40 rlm@197: :guillotine 5 rlm@197: :gust 35 rlm@197: :harden 30 rlm@197: :haze rlm@197: :headbutt rlm@197: :hi-jump-kick rlm@197: :horn-attack rlm@197: :horn-drill rlm@197: :hydro-pump rlm@197: :hyper-beam rlm@197: :hyper-fang rlm@197: :hypnosis rlm@197: :ice-beam rlm@197: :ice-punch rlm@197: :jump-kick rlm@197: :karate-chop rlm@197: :kinesis rlm@197: :leech-life rlm@197: :leech-seed rlm@197: :leer rlm@197: :lick rlm@197: :light-screen rlm@197: :lovely-kiss rlm@197: :low-kick rlm@197: :meditate rlm@197: :mega-drain rlm@197: :mega-kick rlm@197: :mega-punch rlm@197: :metronome rlm@197: :mimic rlm@197: :minimize rlm@197: :mirror-move rlm@197: :mist rlm@197: :night-shade rlm@197: :pay-day rlm@197: :peck rlm@197: :petal-dance rlm@197: :pin-missle rlm@197: :poison-gas rlm@197: :poison-sting rlm@197: :poisonpowder rlm@197: :pound rlm@197: :psybeam rlm@197: :psychic rlm@197: :psywave rlm@197: :quick-attack rlm@197: :rage rlm@197: :razor-leaf rlm@197: :razor-wind rlm@197: :recover rlm@197: :reflect rlm@197: :rest rlm@197: :roar rlm@197: :rock-slide rlm@197: :rock-throw rlm@197: :rolling-kick rlm@197: :sand-attack rlm@197: :scratch rlm@197: :screech rlm@197: :seismic-toss rlm@197: :selfdestruct rlm@197: :sharpen rlm@197: :sing rlm@197: :skull-bash rlm@197: :sky-attack rlm@197: :slam rlm@197: :slash rlm@197: :sleep-powder rlm@197: :sludge rlm@197: :smog rlm@197: :smokescreen rlm@197: :softboiled rlm@197: :solarbeam rlm@197: :sonicboom rlm@197: :spike-cannon rlm@197: :splash rlm@197: :spore rlm@197: :stomp rlm@197: :strength rlm@197: :string-shot rlm@197: :struggle rlm@197: :stun-spore rlm@197: :submission rlm@197: :substitute rlm@197: :super-fang rlm@197: :supersonic rlm@197: :surf rlm@197: :swift rlm@197: :swords-dance rlm@197: :tackle rlm@197: :tail-whip rlm@197: :take-down rlm@197: :teleport rlm@197: :thrash rlm@197: :thunder rlm@197: :thunder-wave rlm@197: :thunderbolt rlm@197: :thunderpunch rlm@197: :thundershock rlm@197: :toxic rlm@197: :transform rlm@197: :tri-attack rlm@197: :twinneedle rlm@197: :vicegrip rlm@197: :vine-whip rlm@197: :water-gun rlm@197: :waterfall rlm@197: :whirlwind rlm@197: :wing-attack rlm@197: :withdraw rlm@197: :wrap