view clojure/com/aurellem/gb/hxc.clj @ 307:872e032949ff

completed cry functions.
author Dylan Holmes <ocsenave@gmail.com>
date Sat, 31 Mar 2012 03:54:21 -0500
parents 2873f50b7291
children de172acc5a03
line wrap: on
line source
1 (ns com.aurellem.gb.hxc
2 (:use (com.aurellem.gb assembly characters gb-driver util
3 constants species))
4 (:use (com.aurellem.world practice))
5 (:import [com.aurellem.gb.gb_driver SaveState]))
10 ; ************* HANDWRITTEN CONSTANTS
14 (def pkmn-types
15 [:normal ;;0
16 :fighting ;;1
17 :flying ;;2
18 :poison ;;3
19 :ground ;;4
20 :rock ;;5
21 :bird ;;6
22 :bug ;;7
23 :ghost ;;8
24 :A
25 :B
26 :C
27 :D
28 :E
29 :F
30 :G
31 :H
32 :I
33 :J
34 :K
35 :fire ;;20 (0x14)
36 :water ;;21 (0x15)
37 :grass ;;22 (0x16)
38 :electric ;;23 (0x17)
39 :psychic ;;24 (0x18)
40 :ice ;;25 (0x19)
41 :dragon ;;26 (0x1A)
42 ])
45 ;; question: when status effects claim to take
46 ;; their accuracy from the move accuracy, does
47 ;; this mean that the move always "hits" but the
48 ;; status effect may not?
50 (def move-effects
51 ["normal damage"
52 "no damage, just opponent sleep" ;; how many turns? is atk power ignored?
53 "0x4C chance of poison"
54 "leech half of inflicted damage"
55 "0x19 chance of burn"
56 "0x19 chance of freeze"
57 "0x19 chance of paralyze"
58 "user faints; opponent defense halved during attack."
59 "leech half of inflicted damage ONLY if sleeping opponent."
60 "imitate last attack"
61 "user atk +1"
62 "user def +1"
63 "user spd +1"
64 "user spc +1"
65 "user acr +1" ;; unused?!
66 "user evd +1"
67 "get post-battle $ = 2*level*uses"
68 "0xFE acr, no matter what."
69 "opponent atk -1" ;; acr taken from move acr?
70 "opponent def -1" ;;
71 "opponent spd -1" ;;
72 "opponent spc -1" ;;
73 "opponent acr -1";;
74 "opponent evd -1"
75 "converts user's type to opponent's."
76 "(haze)"
77 "(bide)"
78 "(thrash)"
79 "(teleport)"
80 "(fury swipes)"
81 "attacks 2-5 turns" ;; unused? like rollout?
82 "0x19 chance of flinch"
83 "opponent sleep for 1-7 turns"
84 "0x66 chance of poison"
85 "0x4D chance of burn"
86 "0x4D chance of freeze"
87 "0x4D chance of paralyze"
88 "0x4D chance of flinch"
89 "one-hit KO"
90 "charge one turn, atk next."
91 "fixed damage, leaves 1HP." ;; how is dmg determined?
92 "fixed damage." ;; cf seismic toss, dragon rage, psywave.
93 "atk 2-5 turns; opponent can't attack" ;; unnormalized? (0 0x60 0x60 0x20 0x20)
94 "charge one turn, atk next. (can't be hit when charging)"
95 "atk hits twice."
96 "user takes 1 damage if misses."
97 "evade status-lowering effects" ;;caused by you or also your opponent?
98 "(broken) if user is slower than opponent, makes critical hit impossible, otherwise has no effect"
99 "atk causes recoil dmg = 1/4 dmg dealt"
100 "confuses opponent" ;; acr taken from move acr
101 "user atk +2"
102 "user def +2"
103 "user spd +2"
104 "user spc +2"
105 "user acr +2" ;; unused!
106 "user evd +2" ;; unused!
107 "restores up to half of user's max hp." ;; broken: fails if the difference
108 ;; b/w max and current hp is one less than a multiple of 256.
109 "(transform)"
110 "opponent atk -2"
111 "opponent def -2"
112 "opponent spd -2"
113 "opponent spc -2"
114 "opponent acr -2"
115 "opponent evd -2"
116 "doubles user spc when attacked"
117 "doubles user def when attacked"
118 "just poisons opponent" ;;acr taken from move acr
119 "just paralyzes opponent" ;;
120 "0x19 chance opponent atk -1"
121 "0x19 chance opponent def -1"
122 "0x19 chance opponent spd -1"
123 "0x4C chance opponent spc -1" ;; context suggest chance is 0x19
124 "0x19 chance opponent acr -1"
125 "0x19 chance opponent evd -1"
126 "???" ;; unused? no effect?
127 "???" ;; unused? no effect?
128 "0x19 chance opponent confused"
129 "atk hits twice. 0x33 chance opponent poisioned."
130 "broken. crash the game after attack."
131 "(substitute)"
132 "unless opponent faints, user must recharge after atk. some
133 exceptions apply."
134 "(rage)"
135 "(mimic)"
136 "(metronome)"
137 "(leech seed)"
138 "does nothing (splash)"
139 "(disable)"
140 ])
143 ;; ************** HARDCODED DATA
145 (defn hxc-thunk
146 "Creates a thunk (nullary fn) that grabs data in a certain region of rom and
147 splits it into a collection by 0x50. If rom is not supplied, uses the
148 original rom data."
149 [start length]
150 (fn self
151 ([rom]
152 (take-nth 2
153 (partition-by #(= % 0x50)
154 (take length
155 (drop start rom)))))
156 ([]
157 (self com.aurellem.gb.gb-driver/original-rom))))
159 (def hxc-thunk-words
160 "Same as hxc-thunk, except it interprets the rom data as characters,
161 returning a collection of strings."
162 (comp
163 (partial comp (partial map character-codes->str))
164 hxc-thunk))
167 ;; --------------------------------------------------
171 (defn hxc-pokenames-raw
172 "The hardcoded names of the 190 species in memory. List begins at
173 ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters
174 long, these names are stripped of padding. See also, hxc-pokedex-names"
175 ([]
176 (hxc-pokenames-raw com.aurellem.gb.gb-driver/original-rom))
177 ([rom]
178 (let [count-species 190
179 name-length 10]
180 (map character-codes->str
181 (partition name-length
182 (map #(if (= 0x50 %) 0x00 %)
183 (take (* count-species name-length)
184 (drop 0xE8000
185 rom))))))))
186 (def hxc-pokenames
187 (comp
188 (partial map format-name)
189 hxc-pokenames-raw))
194 (defn hxc-pokedex-names
195 "The names of the pokemon in hardcoded pokedex order. List begins at
196 ROM@410B1. See also, hxc-pokenames."
197 ([] (hxc-pokedex-names
198 com.aurellem.gb.gb-driver/original-rom))
199 ([rom]
200 (let [names (hxc-pokenames rom)]
201 (#(mapv %
202 ((comp range count keys) %))
203 (zipmap
204 (take (count names)
205 (drop 0x410b1 rom))
207 names)))))
211 ;; http://hax.iimarck.us/topic/581/
212 (defn hxc-cry
213 "The pokemon cry data in internal order. List begins at ROM@39462"
214 ([](hxc-cry com.aurellem.gb.gb-driver/original-rom)
215 ([rom]
216 (zipmap
217 (hxc-pokenames rom)
218 (map
219 (fn [[cry-id pitch length]]
220 {:cry-id cry-id
221 :pitch pitch
222 :length length}
223 )
224 (partition 3
225 (drop 0x39462 rom)))))))
227 (defn hxc-cry-groups
228 ([] (hxc-cry-ids com.aurellem.gb.gb-driver/original-rom))
229 ([rom]
230 (map #(mapv first
231 (filter
232 (fn [[k v]]
233 (= % (:cry-id v)))
234 (hxc-cry rom)))
235 ((comp
236 range
237 count
238 set
239 (partial map :cry-id)
240 vals
241 hxc-cry)
242 rom))))
245 (defn cry-conversion!
246 "Convert Porygon's cry in ROM to be the cry of the given pokemon."
247 [pkmn]
248 (write-rom!
249 (rewrite-memory
250 (vec(rom))
251 0x3965D
252 (map second
253 ((hxc-cry) pkmn)))))
255 (def hxc-items-raw
256 "The hardcoded names of the items in memory. List begins at
257 ROM@045B7"
258 (hxc-thunk-words 0x45B7 870))
260 (def hxc-types
261 "The hardcoded type names in memory. List begins at ROM@27D99,
262 shortly before hxc-titles."
263 (hxc-thunk-words 0x27D99 102))
265 (def hxc-titles
266 "The hardcoded names of the trainer titles in memory. List begins at
267 ROM@27E77"
268 (hxc-thunk-words 0x27E77 196))
271 (def hxc-pokedex-text-raw
272 "The hardcoded pokedex entries in memory. List begins at
273 ROM@B8000, shortly before move names."
274 (hxc-thunk-words 0xB8000 14754))
278 (def hxc-items
279 "The hardcoded names of the items in memory, presented as
280 keywords. List begins at ROM@045B7. See also, hxc-items-raw."
281 (comp (partial map format-name) hxc-items-raw))
283 (defn hxc-pokedex-text
284 "The hardcoded pokedex entries in memory, presented as an
285 associative hash map. List begins at ROM@B8000."
286 ([] (hxc-pokedex-text com.aurellem.gb.gb-driver/original-rom))
287 ([rom]
288 (zipmap
289 (hxc-pokedex-names rom)
290 (cons nil ;; for missingno.
291 (hxc-pokedex-text-raw rom)))))
293 ;; In red/blue, pokedex stats are in internal order.
294 ;; In yellow, pokedex stats are in pokedex order.
296 (defn hxc-pokedex-stats
297 "The hardcoded pokedex stats (species height weight) in memory. List
298 begins at ROM@40687"
299 ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom))
300 ([rom]
301 (let [pokedex-names (zipmap (range) (hxc-pokedex-names rom))
302 pkmn-count (count pokedex-names)
303 ]
304 ((fn capture-stats
305 [n stats data]
306 (if (zero? n) stats
307 (let [[species
308 [_
309 height-ft
310 height-in
311 weight-1
312 weight-2
313 _
314 dex-ptr-1
315 dex-ptr-2
316 dex-bank
317 _
318 & data]]
319 (split-with (partial not= 0x50) data)]
320 (recur (dec n)
321 (assoc stats
322 (pokedex-names (- pkmn-count (dec n)))
323 {:species
324 (format-name (character-codes->str species))
325 :height-ft
326 height-ft
327 :height-in
328 height-in
329 :weight
330 (/ (low-high weight-1 weight-2) 10.)
332 ;; :text
333 ;; (character-codes->str
334 ;; (take-while
335 ;; (partial not= 0x50)
336 ;; (drop
337 ;; (+ 0xB8000
338 ;; -0x4000
339 ;; (low-high dex-ptr-1 dex-ptr-2))
340 ;; rom)))
341 })
343 data)
346 )))
348 pkmn-count
349 {}
350 (drop 0x40687 rom))) ))
358 (def hxc-places
359 "The hardcoded place names in memory. List begins at
360 ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated."
361 (hxc-thunk-words 0x71500 560))
364 (defn hxc-dialog
365 "The hardcoded dialogue in memory, including in-game alerts. Dialog
366 seems to be separated by 0x57 instead of 0x50 (END). Begins at ROM@98000."
367 ([rom]
368 (map character-codes->str
369 (take-nth 2
370 (partition-by #(= % 0x57)
371 (take 0x0F728
372 (drop 0x98000 rom))))))
373 ([]
374 (hxc-dialog com.aurellem.gb.gb-driver/original-rom)))
377 (def hxc-move-names
378 "The hardcoded move names in memory. List begins at ROM@BC000"
379 (hxc-thunk-words 0xBC000 1551))
382 (defn hxc-move-data
383 "The hardcoded (basic (move effects)) in memory. List begins at
384 0x38000. Returns a map of {:name :power :accuracy :pp :fx-id
385 :fx-txt}. The move descriptions are handwritten, not hardcoded."
386 ([]
387 (hxc-move-data com.aurellem.gb.gb-driver/original-rom))
388 ([rom]
389 (let [names (vec (hxc-move-names rom))
390 move-count (count names)
391 move-size 6
392 types pkmn-types ;;; !! hardcoded types
393 ]
394 (zipmap (map format-name names)
395 (map
396 (fn [[idx effect power type-id accuracy pp]]
397 {:name (names (dec idx))
398 :power power
399 :accuracy accuracy
400 :pp pp
401 :type (types type-id)
402 :fx-id effect
403 :fx-txt (get move-effects effect)
404 }
405 )
407 (partition move-size
408 (take (* move-size move-count)
409 (drop 0x38000 rom))))))))
413 (defn hxc-move-data*
414 "Like hxc-move-data, but reports numbers as hexadecimal symbols instead."
415 ([]
416 (hxc-move-data* com.aurellem.gb.gb-driver/original-rom))
417 ([rom]
418 (let [names (vec (hxc-move-names rom))
419 move-count (count names)
420 move-size 6
421 format-name (fn [s]
422 (keyword (.toLowerCase
423 (apply str
424 (map #(if (= % \space) "-" %) s)))))
425 ]
426 (zipmap (map format-name names)
427 (map
428 (fn [[idx effect power type accuracy pp]]
429 {:name (names (dec idx))
430 :power power
431 :accuracy (hex accuracy)
432 :pp pp
433 :fx-id (hex effect)
434 :fx-txt (get move-effects effect)
435 }
436 )
438 (partition move-size
439 (take (* move-size move-count)
440 (drop 0x38000 rom))))))))
443 (defn hxc-machines
444 "The hardcoded moves taught by TMs and HMs. List begins at ROM@0x1232D."
445 ([] (hxc-machines
446 com.aurellem.gb.gb-driver/original-rom))
447 ([rom]
448 (let [moves (hxc-move-names rom)]
449 (zipmap
450 (range)
451 (take-while
452 (comp not nil?)
453 (map (comp
454 format-name
455 (zipmap
456 (range)
457 moves)
458 dec)
459 (take 100
460 (drop 0x1232D rom))))))))
464 (defn internal-id
465 ([rom]
466 (zipmap
467 (hxc-pokenames rom)
468 (range)))
469 ([]
470 (internal-id com.aurellem.gb.gb-driver/original-rom)))
476 ;; nidoran gender change upon levelup
477 ;; (->
478 ;; @current-state
479 ;; rom
480 ;; vec
481 ;; (rewrite-memory
482 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♂))
483 ;; [1 1 15])
484 ;; (rewrite-memory
485 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♀))
486 ;; [1 1 3])
487 ;; (write-rom!)
489 ;; )
494 (defn hxc-advantage
495 ;; in-game multipliers are stored as 10x their effective value
496 ;; to allow for fractional multipliers like 1/2
498 "The hardcoded type advantages in memory, returned as tuples of
499 atk-type def-type multiplier. By default (i.e. if not listed here),
500 the multiplier is 1. List begins at 0x3E62D."
501 ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom))
502 ([rom]
503 (map
504 (fn [[atk def mult]] [(get pkmn-types atk (hex atk))
505 (get pkmn-types def (hex def))
506 (/ mult 10)])
507 (partition 3
508 (take-while (partial not= 0xFF)
509 (drop 0x3E62D rom))))))
513 (defn format-evo
514 [coll]
515 (let [method (first coll)]
516 (cond (empty? coll) []
517 (= 0 method) [] ;; just in case
518 (= 1 method) ;; level-up evolution
519 (conj (format-evo (drop 3 coll))
520 {:method :level-up
521 :min-level (nth coll 1)
522 :into (dec (nth coll 2))})
524 (= 2 method) ;; item evolution
525 (conj (format-evo (drop 4 coll))
526 {:method :item
527 :item (dec (nth coll 1))
528 :min-level (nth coll 2)
529 :into (dec (nth coll 3))})
531 (= 3 method) ;; trade evolution
532 (conj (format-evo (drop 3 coll))
533 {:method :trade
534 :min-level (nth coll 1) ;; always 1 for trade.
535 :into (dec (nth coll 2))}))))
538 (defn hxc-ptrs-evolve
539 "A hardcoded collection of 190 pointers to alternating evolution/learnset data,
540 in internal order."
541 ([]
542 (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom))
543 ([rom]
544 (let [
545 pkmn-count (count (hxc-pokenames-raw)) ;; 190
546 ptrs
547 (map (fn [[a b]] (low-high a b))
548 (partition 2
549 (take (* 2 pkmn-count)
550 (drop 0x3b1e5 rom))))]
551 (map (partial + 0x34000) ptrs)
553 )))
556 (defn hxc-learnsets
557 "Hardcoded map associating pokemon names to lists of pairs [lvl
558 move] of abilities they learn as they level up. The data
559 exists at ROM@3400, sorted by internal order. Pointers to the data
560 exist at ROM@3B1E5; see also, hxc-ptrs-evolve"
561 ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom))
562 ([rom]
563 (apply assoc
564 {}
565 (interleave
566 (hxc-pokenames rom)
567 (map (comp
568 (partial map
569 (fn [[lvl mv]] [lvl (dec mv)]))
570 (partial partition 2)
571 ;; keep the learnset data
572 (partial take-while (comp not zero?))
573 ;; skip the evolution data
574 rest
575 (partial drop-while (comp not zero?)))
576 (map #(drop % rom)
577 (hxc-ptrs-evolve rom)))))))
579 (defn hxc-learnsets-pretty
580 "Live hxc-learnsets except it reports the name of each move --- as
581 it appears in rom --- rather than the move index."
582 ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom))
583 ([rom]
584 (let [moves (vec(map format-name (hxc-move-names)))]
585 (into {}
586 (map (fn [[pkmn learnset]]
587 [pkmn (map (fn [[lvl mv]] [lvl (moves mv)])
588 learnset)])
589 (hxc-learnsets rom))))))
594 (defn hxc-evolution
595 "Hardcoded evolution data in memory. The data exists at ROM@34000,
596 sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve."
597 ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom))
598 ([rom]
599 (apply assoc {}
600 (interleave
601 (hxc-pokenames rom)
602 (map
603 (comp
604 format-evo
605 (partial take-while (comp not zero?))
606 #(drop % rom))
607 (hxc-ptrs-evolve rom)
608 )))))
610 (defn hxc-evolution-pretty
611 "Like hxc-evolution, except it uses the names of items and pokemon
612 --- grabbed from ROM --- rather than their numerical identifiers."
613 ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom))
614 ([rom]
615 (let
616 [poke-names (vec (hxc-pokenames rom))
617 item-names (vec (hxc-items rom))
618 use-names
619 (fn [m]
620 (loop [ks (keys m) new-map m]
621 (let [k (first ks)]
622 (cond (nil? ks) new-map
623 (= k :into)
624 (recur
625 (next ks)
626 (assoc new-map
627 :into
628 (poke-names
629 (:into
630 new-map))))
631 (= k :item)
632 (recur
633 (next ks)
634 (assoc new-map
635 :item
636 (item-names
637 (:item new-map))))
638 :else
639 (recur
640 (next ks)
641 new-map)
642 ))))]
644 (into {}
645 (map (fn [[pkmn evo-coll]]
646 [pkmn (map use-names evo-coll)])
647 (hxc-evolution rom))))))
650 (defn hxc-pokemon-base
651 ([] (hxc-pokemon-base com.aurellem.gb.gb-driver/original-rom))
652 ([rom]
653 (let [entry-size 28
654 pkmn-count (count (hxc-pokedex-text rom))
655 pokemon (rest (hxc-pokedex-names))
656 types (apply assoc {}
657 (interleave
658 (range)
659 pkmn-types)) ;;!! softcoded
660 moves (apply assoc {}
661 (interleave
662 (range)
663 (map format-name
664 (hxc-move-names rom))))
665 machines (hxc-machines)
666 ]
667 (zipmap
668 pokemon
669 (map
670 (fn [[n
671 rating-hp
672 rating-atk
673 rating-def
674 rating-speed
675 rating-special
676 type-1
677 type-2
678 rarity
679 rating-xp
680 pic-dimensions ;; tile_width|tile_height (8px/tile)
681 ptr-pic-obverse-1
682 ptr-pic-obverse-2
683 ptr-pic-reverse-1
684 ptr-pic-reverse-2
685 move-1
686 move-2
687 move-3
688 move-4
689 growth-rate
690 &
691 TMs|HMs]]
692 (let
693 [base-moves
694 (mapv moves
695 ((comp
696 ;; since the game uses zero as a delimiter,
697 ;; it must also increment all move indices by 1.
698 ;; heren we decrement to correct this.
699 (partial map dec)
700 (partial take-while (comp not zero?)))
701 [move-1 move-2 move-3 move-4]))
703 types
704 (set (list (types type-1)
705 (types type-2)))
706 TMs|HMs
707 (map
708 (comp
709 (partial map first)
710 (partial remove (comp zero? second)))
711 (split-at
712 50
713 (map vector
714 (rest(range))
715 (reduce concat
716 (map
717 #(take 8
718 (concat (bit-list %)
719 (repeat 0)))
721 TMs|HMs)))))
723 TMs (vec (first TMs|HMs))
724 HMs (take 5 (map (partial + -50) (vec (second TMs|HMs))))
727 ]
730 {:dex# n
731 :base-moves base-moves
732 :types types
733 :TMs TMs
734 :HMs HMs
735 :base-hp rating-hp
736 :base-atk rating-atk
737 :base-def rating-def
738 :base-speed rating-speed
739 :base-special rating-special
740 }))
742 (partition entry-size
743 (take (* entry-size pkmn-count)
744 (drop 0x383DE
745 rom))))))))
749 (defn hxc-item-prices
750 "The hardcoded list of item prices in memory. List begins at ROM@4495"
751 ([] (hxc-item-prices com.aurellem.gb.gb-driver/original-rom))
752 ([rom]
753 (let [items (hxc-items rom)
754 price-size 3]
755 (zipmap items
756 (map (comp
757 ;; zero-cost items are "priceless"
758 #(if (zero? %) :priceless %)
759 decode-bcd butlast)
760 (partition price-size
761 (take (* price-size (count items))
762 (drop 0x4495 rom))))))))
764 (defn hxc-shops
765 ([] (hxc-shops com.aurellem.gb.gb-driver/original-rom))
766 ([rom]
767 (let [items (zipmap (range) (hxc-items rom))
769 ;; temporarily softcode the TM items
770 items (into
771 items
772 (map (juxt identity
773 (comp keyword
774 (partial str "tm-")
775 (partial + 1 -200)
776 ))
777 (take 200 (drop 200 (range)))))
779 ]
781 ((fn parse-shop [coll [num-items & items-etc]]
782 (let [inventory (take-while
783 (partial not= 0xFF)
784 items-etc)
785 [separator & items-etc] (drop num-items (rest items-etc))]
786 (if (= separator 0x50)
787 (map (partial mapv (comp items dec)) (conj coll inventory))
788 (recur (conj coll inventory) items-etc)
789 )
790 ))
792 '()
793 (drop 0x233C rom))
796 )))
802 (defn hxc-ptrs-wild
803 "A list of the hardcoded wild encounter data in memory. Pointers
804 begin at ROM@0CB95; data begins at ROM@0x04D89"
805 ([] (hxc-ptrs-wild com.aurellem.gb.gb-driver/original-rom))
806 ([rom]
807 (let [ptrs
808 (map (fn [[a b]] (+ a (* 0x100 b)))
809 (take-while (partial not= (list 0xFF 0xFF))
810 (partition 2 (drop 0xCB95 rom))))]
811 ptrs)))
815 (defn hxc-wilds
816 "A list of the hardcoded wild encounter data in memory. Pointers
817 begin at ROM@0CB95; data begins at ROM@0x04D89"
818 ([] (hxc-wilds com.aurellem.gb.gb-driver/original-rom))
819 ([rom]
820 (let [pokenames (zipmap (range) (hxc-pokenames rom))]
821 (map
822 (partial map (fn [[a b]] {:species (pokenames (dec b)) :level
823 a}))
824 (partition 10
826 (take-while (comp (partial not= 1)
827 first)
828 (partition 2
829 (drop 0xCD8C rom))
831 ))))))
846 ;; ********************** MANIPULATION FNS
849 (defn same-type
850 ([pkmn move]
851 (same-type
852 com.aurellem.gb.gb-driver/original-rom pkmn move))
853 ([rom pkmn move]
854 (((comp :types (hxc-pokemon-base rom)) pkmn)
855 ((comp :type (hxc-move-data rom)) move))))
860 (defn submap?
861 "Compares the two maps. Returns true if map-big has the same associations as map-small, otherwise false."
862 [map-small map-big]
863 (cond (empty? map-small) true
864 (and
865 (contains? map-big (ffirst map-small))
866 (= (get map-big (ffirst map-small))
867 (second (first map-small))))
868 (recur (next map-small) map-big)
870 :else false))
873 (defn search-map [proto-map maps]
874 "Returns all the maps that make the same associations as proto-map."
875 (some (partial submap? proto-map) maps))
877 (defn filter-vals
878 "Returns a map consisting of all the pairs [key val] for
879 which (pred key) returns true."
880 [pred map]
881 (reduce (partial apply assoc) {}
882 (filter (fn [[k v]] (pred v)) map)))
885 (defn search-moves
886 "Returns a subcollection of all hardcoded moves with the
887 given attributes. Attributes consist of :name :power
888 :accuracy :pp :fx-id
889 (and also :fx-txt, but it contains the same information
890 as :fx-id)"
891 ([attribute-map]
892 (search-moves
893 com.aurellem.gb.gb-driver/original-rom attribute-map))
894 ([rom attribute-map]
895 (filter-vals (partial submap? attribute-map)
896 (hxc-move-data rom))))
902 ;; note: 0x2f31 contains the names "TM" "HM"?
904 ;; note for later: credits start at F1290
908 (comment
910 (def hxc-later
911 "Running this code produces, e.g. hardcoded names NPCs give
912 their pokemon. Will sort through it later."
913 (print (character-codes->str(take 10000
914 (drop 0x71597
915 (rom (root)))))))
917 (let [dex
918 (partition-by #(= 0x50 %)
919 (take 2540
920 (drop 0x40687
921 (rom (root)))))]
922 (def dex dex)
923 (def hxc-species
924 (map character-codes->str
925 (take-nth 4 dex))))
926 )