annotate clojure/com/aurellem/gb/hxc.clj @ 272:a60ea8632ff4

beginning work on hxc-pokemon-base, the collection of base stats, battle sprite data, etc.
author Dylan Holmes <ocsenave@gmail.com>
date Tue, 27 Mar 2012 00:59:43 -0500
parents 82ee2704c973
children 69184558fcf3
rev   line source
rlm@218 1 (ns com.aurellem.gb.hxc
rlm@218 2 (:use (com.aurellem.gb assembly characters gb-driver util
rlm@218 3 constants))
rlm@218 4 (:use (com.aurellem.world practice))
rlm@218 5 (:import [com.aurellem.gb.gb_driver SaveState]))
rlm@218 6
rlm@218 7
ocsenave@243 8
ocsenave@249 9
ocsenave@249 10 ; ************* HANDWRITTEN CONSTANTS
ocsenave@249 11
ocsenave@259 12
ocsenave@259 13
ocsenave@259 14 (defn low-high
ocsenave@259 15 [low high]
ocsenave@259 16 (+ low (* 256 high)))
ocsenave@259 17
ocsenave@259 18
ocsenave@259 19 (defn format-name
ocsenave@259 20 "Convert the string of alphabetic/space characters into a keyword by
ocsenave@259 21 replacing spaces with hyphens and converting to lowercase."
ocsenave@259 22 [s]
ocsenave@259 23 (keyword (.toLowerCase
ocsenave@259 24 (apply str
ocsenave@259 25 (map #(if (= % \space) "-" %) s)))))
ocsenave@259 26
ocsenave@259 27
ocsenave@259 28
ocsenave@243 29 (def pkmn-types
ocsenave@272 30 [:normal ;;0
ocsenave@272 31 :fighting ;;1
ocsenave@272 32 :flying ;;2
ocsenave@272 33 :poison ;;3
ocsenave@272 34 :ground ;;4
ocsenave@272 35 :rock ;;5
ocsenave@272 36 :bird ;;6
ocsenave@272 37 :bug ;;7
ocsenave@272 38 :ghost ;;8
ocsenave@244 39 :A
ocsenave@244 40 :B
ocsenave@244 41 :C
ocsenave@244 42 :D
ocsenave@244 43 :E
ocsenave@244 44 :F
ocsenave@244 45 :G
ocsenave@244 46 :H
ocsenave@244 47 :I
ocsenave@244 48 :J
ocsenave@244 49 :K
ocsenave@272 50 :fire ;;20 (0x14)
ocsenave@272 51 :water ;;21 (0x15)
ocsenave@272 52 :grass ;;22 (0x16)
ocsenave@272 53 :electric ;;23 (0x17)
ocsenave@272 54 :psychic ;;24 (0x18)
ocsenave@272 55 :ice ;;25 (0x19)
ocsenave@272 56 :dragon ;;26 (0x1A)
ocsenave@244 57 ])
ocsenave@243 58
ocsenave@243 59
ocsenave@246 60 ;; question: when status effects claim to take
ocsenave@246 61 ;; their accuracy from the move accuracy, does
ocsenave@246 62 ;; this mean that the move always "hits" but the
ocsenave@246 63 ;; status effect may not?
ocsenave@246 64
ocsenave@246 65 (def move-effects
ocsenave@246 66 ["normal damage"
ocsenave@246 67 "no damage, just opponent sleep" ;; how many turns? is atk power ignored?
ocsenave@246 68 "0x4C chance of poison"
ocsenave@246 69 "leech half of inflicted damage"
ocsenave@246 70 "0x19 chance of burn"
ocsenave@246 71 "0x19 chance of freeze"
ocsenave@246 72 "0x19 chance of paralyze"
ocsenave@259 73 "user faints; opponent defense halved during attack."
ocsenave@246 74 "leech half of inflicted damage ONLY if sleeping opponent."
ocsenave@246 75 "imitate last attack"
ocsenave@246 76 "user atk +1"
ocsenave@246 77 "user def +1"
ocsenave@246 78 "user spd +1"
ocsenave@246 79 "user spc +1"
ocsenave@246 80 "user acr +1" ;; unused?!
ocsenave@246 81 "user evd +1"
ocsenave@246 82 "get post-battle $ = 2*level*uses"
ocsenave@246 83 "0xFE acr, no matter what."
ocsenave@246 84 "opponent atk -1" ;; acr taken from move acr?
ocsenave@246 85 "opponent def -1" ;;
ocsenave@246 86 "opponent spd -1" ;;
ocsenave@246 87 "opponent spc -1" ;;
ocsenave@246 88 "opponent acr -1";;
ocsenave@246 89 "opponent evd -1"
ocsenave@246 90 "converts user's type to opponent's."
ocsenave@246 91 "(haze)"
ocsenave@246 92 "(bide)"
ocsenave@246 93 "(thrash)"
ocsenave@246 94 "(teleport)"
ocsenave@246 95 "(fury swipes)"
ocsenave@246 96 "attacks 2-5 turns" ;; unused? like rollout?
ocsenave@246 97 "0x19 chance of flinch"
ocsenave@246 98 "opponent sleep for 1-7 turns"
ocsenave@246 99 "0x66 chance of poison"
ocsenave@246 100 "0x4D chance of burn"
ocsenave@246 101 "0x4D chance of freeze"
ocsenave@246 102 "0x4D chance of paralyze"
ocsenave@246 103 "0x4D chance of flinch"
ocsenave@246 104 "one-hit KO"
ocsenave@246 105 "charge one turn, atk next."
ocsenave@246 106 "fixed damage, leaves 1HP." ;; how is dmg determined?
ocsenave@246 107 "fixed damage." ;; cf seismic toss, dragon rage, psywave.
ocsenave@246 108 "atk 2-5 turns; opponent can't attack" ;; unnormalized? (0 0x60 0x60 0x20 0x20)
ocsenave@246 109 "charge one turn, atk next. (can't be hit when charging)"
ocsenave@246 110 "atk hits twice."
ocsenave@246 111 "user takes 1 damage if misses."
ocsenave@246 112 "evade status-lowering effects" ;;caused by you or also your opponent?
ocsenave@246 113 "(broken) if user is slower than opponent, makes critical hit impossible, otherwise has no effect"
ocsenave@246 114 "atk causes recoil dmg = 1/4 dmg dealt"
ocsenave@246 115 "confuses opponent" ;; acr taken from move acr
ocsenave@246 116 "user atk +2"
ocsenave@246 117 "user def +2"
ocsenave@246 118 "user spd +2"
ocsenave@246 119 "user spc +2"
ocsenave@246 120 "user acr +2" ;; unused!
ocsenave@246 121 "user evd +2" ;; unused!
ocsenave@246 122 "restores up to half of user's max hp." ;; broken: fails if the difference
ocsenave@246 123 ;; b/w max and current hp is one less than a multiple of 256.
ocsenave@246 124 "(transform)"
ocsenave@246 125 "opponent atk -2"
ocsenave@246 126 "opponent def -2"
ocsenave@246 127 "opponent spd -2"
ocsenave@246 128 "opponent spc -2"
ocsenave@246 129 "opponent acr -2"
ocsenave@246 130 "opponent evd -2"
ocsenave@246 131 "doubles user spc when attacked"
ocsenave@246 132 "doubles user def when attacked"
ocsenave@249 133 "just poisons opponent" ;;acr taken from move acr
ocsenave@249 134 "just paralyzes opponent" ;;
ocsenave@246 135 "0x19 chance opponent atk -1"
ocsenave@246 136 "0x19 chance opponent def -1"
ocsenave@246 137 "0x19 chance opponent spd -1"
ocsenave@246 138 "0x4C chance opponent spc -1" ;; context suggest chance is 0x19
ocsenave@246 139 "0x19 chance opponent acr -1"
ocsenave@246 140 "0x19 chance opponent evd -1"
ocsenave@246 141 "???" ;; unused? no effect?
ocsenave@246 142 "???" ;; unused? no effect?
ocsenave@246 143 "0x19 chance opponent confused"
ocsenave@246 144 "atk hits twice. 0x33 chance opponent poisioned."
ocsenave@246 145 "broken. crash the game after attack."
ocsenave@246 146 "(substitute)"
ocsenave@246 147 "unless opponent faints, user must recharge after atk. some
ocsenave@246 148 exceptions apply."
ocsenave@246 149 "(rage)"
ocsenave@246 150 "(mimic)"
ocsenave@246 151 "(metronome)"
ocsenave@246 152 "(leech seed)"
ocsenave@246 153 "does nothing (splash)"
ocsenave@246 154 "(disable)"
ocsenave@246 155 ])
ocsenave@246 156
ocsenave@246 157
ocsenave@249 158 ;; ************** HARDCODED DATA
ocsenave@246 159
ocsenave@249 160 (defn hxc-thunk
ocsenave@259 161 "Creates a thunk (nullary fn) that grabs data in a certain region of rom and
ocsenave@249 162 splits it into a collection by 0x50. If rom is not supplied, uses the
ocsenave@249 163 original rom data."
ocsenave@249 164 [start length]
ocsenave@249 165 (fn self
ocsenave@249 166 ([rom]
ocsenave@249 167 (take-nth 2
ocsenave@249 168 (partition-by #(= % 0x50)
ocsenave@249 169 (take length
ocsenave@249 170 (drop start rom)))))
ocsenave@249 171 ([]
ocsenave@249 172 (self com.aurellem.gb.gb-driver/original-rom))))
ocsenave@246 173
ocsenave@249 174 (def hxc-thunk-words
ocsenave@249 175 "Same as hxc-thunk, except it interprets the rom data as characters,
ocsenave@249 176 returning a collection of strings."
ocsenave@249 177 (comp
ocsenave@249 178 (partial comp (partial map character-codes->str))
ocsenave@249 179 hxc-thunk))
ocsenave@249 180
ocsenave@249 181
ocsenave@249 182 ;; --------------------------------------------------
ocsenave@246 183
ocsenave@246 184 (def hxc-items
ocsenave@249 185 "The hardcoded names of the items in memory. List begins at
ocsenave@249 186 ROM@045B7"
ocsenave@249 187 (hxc-thunk-words 0x45B7 870))
ocsenave@246 188
ocsenave@246 189 (def hxc-types
ocsenave@246 190 "The hardcoded type names in memory. List begins at ROM@27D99,
ocsenave@246 191 shortly before hxc-titles."
ocsenave@249 192 (hxc-thunk-words 0x27D99 102))
ocsenave@246 193
ocsenave@246 194 (def hxc-titles
ocsenave@246 195 "The hardcoded names of the trainer titles in memory. List begins at
ocsenave@246 196 ROM@27E77"
ocsenave@249 197 (hxc-thunk-words 0x27E77 196))
ocsenave@246 198
ocsenave@259 199
ocsenave@259 200 (def hxc-pokedex-text
ocsenave@259 201 "The hardcoded pokedex entries in memory. List begins at
ocsenave@259 202 ROM@B8000, shortly before move names."
ocsenave@259 203 (hxc-thunk-words 0xB8000 14754))
ocsenave@259 204
ocsenave@259 205
ocsenave@272 206
ocsenave@272 207 (defn hxc-pokemon-base
ocsenave@272 208 ([] (hxc-pokemon-base com.aurellem.gb.gb-driver/original-rom))
ocsenave@272 209 ([rom]
ocsenave@272 210 (let [entry-size 28
ocsenave@272 211 pkmn-count (count (hxc-pokedex-text rom))
ocsenave@272 212 types (apply assoc {}
ocsenave@272 213 (interleave
ocsenave@272 214 (range)
ocsenave@272 215 pkmn-types)) ;;!! softcoded
ocsenave@272 216 moves (apply assoc {}
ocsenave@272 217 (interleave
ocsenave@272 218 (range)
ocsenave@272 219 (map format-name
ocsenave@272 220 (hxc-move-names rom))))
ocsenave@272 221
ocsenave@272 222 ]
ocsenave@272 223 (map
ocsenave@272 224
ocsenave@272 225 (fn [[n
ocsenave@272 226 rating-hp
ocsenave@272 227 rating-atk
ocsenave@272 228 rating-def
ocsenave@272 229 rating-speed
ocsenave@272 230 rating-special
ocsenave@272 231 type-1
ocsenave@272 232 type-2
ocsenave@272 233 rarity
ocsenave@272 234 rating-xp
ocsenave@272 235 _
ocsenave@272 236 ptr-pic-obverse-1
ocsenave@272 237 ptr-pic-obverse-2
ocsenave@272 238 ptr-pic-reverse-1
ocsenave@272 239 ptr-pic-reverse-2
ocsenave@272 240 move-1
ocsenave@272 241 move-2
ocsenave@272 242 move-3
ocsenave@272 243 move-4
ocsenave@272 244 &
ocsenave@272 245 TMs]]
ocsenave@272 246 {:dex# n
ocsenave@272 247 :base-moves
ocsenave@272 248 (mapv moves
ocsenave@272 249 ((comp
ocsenave@272 250 ;; since the game uses zero as a delimiter,
ocsenave@272 251 ;; it must also increment all move indices by 1.
ocsenave@272 252 ;; here we decrement to correct this.
ocsenave@272 253 (partial map dec)
ocsenave@272 254 (partial take-while (comp not zero?)))
ocsenave@272 255 [move-1 move-2 move-3 move-4]))
ocsenave@272 256
ocsenave@272 257 :types (set (list (types type-1)
ocsenave@272 258 (types type-2)))})
ocsenave@272 259
ocsenave@272 260 (partition entry-size
ocsenave@272 261 (take (* entry-size pkmn-count)
ocsenave@272 262 (drop 0x383DE
ocsenave@272 263 rom)))))))
ocsenave@272 264
ocsenave@272 265
ocsenave@272 266
ocsenave@272 267 ;; In red/blue, pokedex stats are in internal order.
ocsenave@272 268 ;; In yellow, pokedex stats are in pokedex order.
ocsenave@259 269
ocsenave@259 270 (defn hxc-pokedex-stats
ocsenave@272 271 "The hardcoded pokedex stats (species height weight) in memory. List
ocsenave@272 272 begins at ROM@40687"
ocsenave@259 273 ;; uses hxc-pokedex-text to count pokemon
ocsenave@259 274 ;; since hxc-pokenames includes several missingno"
ocsenave@259 275 ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom))
ocsenave@259 276 ([rom]
ocsenave@259 277 (let [poketext (hxc-pokedex-text)
ocsenave@259 278 pkmn-count (count poketext)
ocsenave@259 279 ]
ocsenave@259 280 ((fn capture-stats
ocsenave@259 281 [n stats data]
ocsenave@259 282 (if (zero? n) stats
ocsenave@259 283 (let [[species
ocsenave@259 284 [_
ocsenave@259 285 height-ft
ocsenave@259 286 height-in
ocsenave@259 287 weight-1
ocsenave@259 288 weight-2
ocsenave@259 289 _
ocsenave@259 290 dex-ptr-1
ocsenave@259 291 dex-ptr-2
ocsenave@259 292 dex-bank
ocsenave@259 293 _
ocsenave@259 294 & data]]
ocsenave@259 295 (split-with (partial not= 0x50) data)]
ocsenave@259 296 (recur (dec n)
ocsenave@259 297 (assoc stats
ocsenave@259 298 (- pkmn-count n)
ocsenave@259 299 {:species
ocsenave@259 300 (character-codes->str species)
ocsenave@259 301 :height-ft
ocsenave@259 302 height-ft
ocsenave@259 303 :height-in
ocsenave@259 304 height-in
ocsenave@259 305 :weight
ocsenave@259 306 (/ (low-high weight-1 weight-2) 10.)
ocsenave@259 307
ocsenave@259 308 ;; :text
ocsenave@259 309 ;; (character-codes->str
ocsenave@259 310 ;; (take-while
ocsenave@259 311 ;; (partial not= 0x50)
ocsenave@259 312 ;; (drop
ocsenave@259 313 ;; (+ 0xB8000
ocsenave@259 314 ;; -0x4000
ocsenave@259 315 ;; (low-high dex-ptr-1 dex-ptr-2))
ocsenave@259 316 ;; rom)))
ocsenave@259 317 })
ocsenave@259 318
ocsenave@259 319 data)
ocsenave@259 320
ocsenave@259 321
ocsenave@259 322 )))
ocsenave@259 323
ocsenave@259 324 pkmn-count
ocsenave@259 325 {}
ocsenave@259 326 (drop 0x40687 rom))) ))
ocsenave@259 327
ocsenave@259 328
ocsenave@259 329
ocsenave@259 330
ocsenave@259 331
ocsenave@259 332
ocsenave@259 333
ocsenave@246 334 (def hxc-places
ocsenave@246 335 "The hardcoded place names in memory. List begins at
ocsenave@249 336 ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated."
ocsenave@249 337 (hxc-thunk-words 0x71500 560))
ocsenave@246 338
ocsenave@246 339
ocsenave@249 340 (defn hxc-dialog
ocsenave@249 341 "The hardcoded dialogue in memory, including in-game alerts. Dialog
ocsenave@249 342 seems to be separated by 0x57 instead of 0x50 (END). Begins at ROM@98000."
ocsenave@249 343 ([rom]
ocsenave@249 344 (map character-codes->str
ocsenave@249 345 (take-nth 2
ocsenave@249 346 (partition-by #(= % 0x57)
ocsenave@249 347 (take 0x0F728
ocsenave@249 348 (drop 0x98000 rom))))))
ocsenave@249 349 ([]
ocsenave@249 350 (hxc-dialog com.aurellem.gb.gb-driver/original-rom)))
ocsenave@249 351
ocsenave@246 352
ocsenave@259 353
ocsenave@249 354
ocsenave@246 355 (def hxc-move-names
ocsenave@246 356 "The hardcoded move names in memory. List begins at ROM@BC000"
ocsenave@249 357 (hxc-thunk-words 0xBC000 1551))
ocsenave@246 358
ocsenave@249 359
ocsenave@249 360 (defn hxc-move-data
ocsenave@246 361 "The hardcoded (basic (move effects)) in memory. List begins at
ocsenave@249 362 0x38000. Returns a map of {:name :power :accuracy :pp :fx-id
ocsenave@249 363 :fx-txt}. The move descriptions are handwritten, not hardcoded."
ocsenave@249 364 ([]
ocsenave@249 365 (hxc-move-data com.aurellem.gb.gb-driver/original-rom))
ocsenave@249 366 ([rom]
ocsenave@249 367 (let [names (vec (hxc-move-names rom))
ocsenave@249 368 move-count (count names)
ocsenave@259 369 move-size 6]
ocsenave@249 370 (zipmap (map format-name names)
ocsenave@249 371 (map
ocsenave@249 372 (fn [[idx effect power type accuracy pp]]
ocsenave@249 373 {:name (names (dec idx))
ocsenave@249 374 :power power
ocsenave@249 375 :accuracy accuracy
ocsenave@249 376 :pp pp
ocsenave@249 377 :fx-id effect
ocsenave@249 378 :fx-txt (get move-effects effect)
ocsenave@249 379 }
ocsenave@249 380 )
ocsenave@249 381
ocsenave@249 382 (partition move-size
ocsenave@249 383 (take (* move-size move-count)
ocsenave@249 384 (drop 0x38000 rom))))))))
ocsenave@246 385
ocsenave@246 386
ocsenave@246 387
ocsenave@249 388 (defn hxc-move-data*
ocsenave@249 389 "Like hxc-move-data, but reports numbers as hexadecimal symbols instead."
ocsenave@249 390 ([]
ocsenave@249 391 (hxc-move-data* com.aurellem.gb.gb-driver/original-rom))
ocsenave@249 392 ([rom]
ocsenave@249 393 (let [names (vec (hxc-move-names rom))
ocsenave@249 394 move-count (count names)
ocsenave@249 395 move-size 6
ocsenave@249 396 format-name (fn [s]
ocsenave@249 397 (keyword (.toLowerCase
ocsenave@249 398 (apply str
ocsenave@249 399 (map #(if (= % \space) "-" %) s)))))
ocsenave@249 400 ]
ocsenave@249 401 (zipmap (map format-name names)
ocsenave@249 402 (map
ocsenave@249 403 (fn [[idx effect power type accuracy pp]]
ocsenave@249 404 {:name (names (dec idx))
ocsenave@249 405 :power power
ocsenave@249 406 :accuracy (hex accuracy)
ocsenave@249 407 :pp pp
ocsenave@249 408 :fx-id (hex effect)
ocsenave@249 409 :fx-txt (get move-effects effect)
ocsenave@249 410 }
ocsenave@249 411 )
ocsenave@249 412
ocsenave@249 413 (partition move-size
ocsenave@249 414 (take (* move-size move-count)
ocsenave@249 415 (drop 0x38000 rom))))))))
ocsenave@243 416
ocsenave@243 417
ocsenave@243 418
ocsenave@249 419 (defn hxc-pokenames
ocsenave@249 420 "The hardcoded names of the 190 species in memory. List begins at
ocsenave@249 421 ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters
ocsenave@249 422 long, these names are stripped of padding."
ocsenave@249 423 ([]
ocsenave@249 424 (hxc-pokenames com.aurellem.gb.gb-driver/original-rom))
ocsenave@249 425 ([rom]
ocsenave@249 426 (let [count-species 190
ocsenave@249 427 name-length 10]
ocsenave@249 428 (map character-codes->str
ocsenave@249 429 (partition name-length
ocsenave@249 430 (map #(if (= 0x50 %) 0x00 %)
ocsenave@249 431 (take (* count-species name-length)
ocsenave@249 432 (drop 0xE8000
ocsenave@249 433 rom))))))))
ocsenave@243 434
ocsenave@259 435
ocsenave@259 436
ocsenave@259 437
ocsenave@259 438 (defn internal-id
ocsenave@259 439 ([rom]
ocsenave@259 440 (zipmap
ocsenave@259 441 (map format-name (hxc-pokenames rom))
ocsenave@259 442 (range)))
ocsenave@259 443 ([]
ocsenave@259 444 (internal-id com.aurellem.gb.gb-driver/original-rom)))
ocsenave@259 445
ocsenave@259 446
ocsenave@259 447
ocsenave@263 448 ;; nidoran gender change upon levelup
ocsenave@263 449 ;; (->
ocsenave@263 450 ;; @current-state
ocsenave@263 451 ;; rom
ocsenave@263 452 ;; vec
ocsenave@263 453 ;; (rewrite-memory
ocsenave@263 454 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♂))
ocsenave@263 455 ;; [1 1 15])
ocsenave@263 456 ;; (rewrite-memory
ocsenave@263 457 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♀))
ocsenave@263 458 ;; [1 1 3])
ocsenave@263 459 ;; (write-rom!)
ocsenave@263 460
ocsenave@263 461 ;; )
ocsenave@263 462
ocsenave@259 463
ocsenave@259 464
ocsenave@259 465
ocsenave@249 466 (defn hxc-advantage
ocsenave@249 467 "The hardcoded type advantages in memory, returned as tuples of atk-type def-type multiplier. By default (i.e. if not listed here),
ocsenave@249 468 the multiplier is 1."
ocsenave@249 469 ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom))
ocsenave@249 470 ([rom]
ocsenave@249 471 (map
ocsenave@249 472 (fn [[atk def mult]] [(get pkmn-types atk (hex atk))
ocsenave@249 473 (get pkmn-types def (hex def))
ocsenave@249 474 (/ mult 10)])
ocsenave@249 475 (partition 3
ocsenave@249 476 (take-while (partial not= 0xFF)
ocsenave@249 477 (drop 0x3E62D rom))))))
ocsenave@243 478
ocsenave@243 479
ocsenave@263 480 (defn format-evo
ocsenave@263 481 [coll]
ocsenave@263 482 (let [method (first coll)]
ocsenave@263 483 (cond (empty? coll) []
ocsenave@263 484 (= 0 method) [] ;; just in case
ocsenave@263 485 (= 1 method) ;; level-up evolution
ocsenave@263 486 (conj (format-evo (drop 3 coll))
ocsenave@263 487 {:method :level-up
ocsenave@263 488 :min-level (nth coll 1)
ocsenave@263 489 :into (dec (nth coll 2))})
ocsenave@263 490
ocsenave@263 491 (= 2 method) ;; item evolution
ocsenave@263 492 (conj (format-evo (drop 4 coll))
ocsenave@263 493 {:method :item
ocsenave@263 494 :item (dec (nth coll 1))
ocsenave@263 495 :min-level (nth coll 2)
ocsenave@263 496 :into (dec (nth coll 3))})
ocsenave@243 497
ocsenave@263 498 (= 3 method) ;; trade evolution
ocsenave@263 499 (conj (format-evo (drop 3 coll))
ocsenave@263 500 {:method :trade
ocsenave@263 501 :min-level (nth coll 1) ;; always 1 for trade.
ocsenave@263 502 :into (dec (nth coll 2))}))))
ocsenave@243 503
ocsenave@243 504
ocsenave@263 505 (defn hxc-ptrs-evolve
ocsenave@267 506 "A hardcoded collection of 190 pointers to alternating evolution/learnset data,
ocsenave@263 507 in internal order."
ocsenave@263 508 ([]
ocsenave@263 509 (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom))
ocsenave@259 510 ([rom]
ocsenave@259 511 (let [names (hxc-pokenames rom)
ocsenave@259 512 pkmn-count (count names)
ocsenave@259 513 ptrs
ocsenave@263 514 (map (fn [[a b]] (low-high a b))
ocsenave@259 515 (partition 2
ocsenave@259 516 (take (* 2 pkmn-count)
ocsenave@263 517 (drop 0x3b1e5 rom))))]
ocsenave@263 518 (map (partial + 0x34000) ptrs)
ocsenave@263 519
ocsenave@263 520 )))
ocsenave@263 521
ocsenave@267 522
ocsenave@267 523 (defn hxc-learnsets
ocsenave@267 524 "Hardcoded map associating pokemon names to lists of pairs [lvl
ocsenave@267 525 move] of abilities they learn as they level up. The data
ocsenave@267 526 exists at ROM@3400, sorted by internal order. Pointers to the data
ocsenave@267 527 exist at ROM@3B1E5; see also, hxc-ptrs-evolve"
ocsenave@267 528 ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom))
ocsenave@267 529 ([rom]
ocsenave@267 530 (apply assoc
ocsenave@267 531 {}
ocsenave@267 532 (interleave
ocsenave@267 533 (map format-name (hxc-pokenames rom))
ocsenave@267 534 (map (comp
ocsenave@268 535 (partial map
ocsenave@268 536 (fn [[lvl mv]] [lvl (dec mv)]))
ocsenave@267 537 (partial partition 2)
ocsenave@267 538 ;; keep the learnset data
ocsenave@267 539 (partial take-while (comp not zero?))
ocsenave@267 540 ;; skip the evolution data
ocsenave@267 541 rest
ocsenave@267 542 (partial drop-while (comp not zero?)))
ocsenave@267 543 (map #(drop % rom)
ocsenave@267 544 (hxc-ptrs-evolve rom)))))))
ocsenave@267 545
ocsenave@267 546 (defn hxc-learnsets-pretty
ocsenave@267 547 "Live hxc-learnsets except it reports the name of each move --- as
ocsenave@267 548 it appears in rom --- rather than the move index."
ocsenave@267 549 ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom))
ocsenave@267 550 ([rom]
ocsenave@267 551 (let [moves (vec(map format-name (hxc-move-names)))]
ocsenave@267 552 (into {}
ocsenave@267 553 (map (fn [[pkmn learnset]]
ocsenave@268 554 [pkmn (map (fn [[lvl mv]] [lvl (moves mv)])
ocsenave@267 555 learnset)])
ocsenave@267 556 (hxc-learnsets rom))))))
ocsenave@267 557
ocsenave@267 558
ocsenave@267 559
ocsenave@267 560
ocsenave@263 561 (defn hxc-evolution
ocsenave@263 562 "Hardcoded evolution data in memory. The data exists at ROM@34000,
ocsenave@263 563 sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve."
ocsenave@263 564 ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom))
ocsenave@263 565 ([rom]
ocsenave@259 566 (apply assoc {}
ocsenave@259 567 (interleave
ocsenave@267 568 (map format-name (hxc-pokenames rom))
ocsenave@259 569 (map
ocsenave@259 570 (comp
ocsenave@259 571 format-evo
ocsenave@263 572 (partial take-while (comp not zero?))
ocsenave@263 573 #(drop % rom))
ocsenave@263 574 (hxc-ptrs-evolve rom)
ocsenave@263 575 )))))
ocsenave@259 576
ocsenave@263 577 (defn hxc-evolution-pretty
ocsenave@263 578 "Like hxc-evolution, except it uses the names of items and pokemon
ocsenave@263 579 --- grabbed from ROM --- rather than their numerical identifiers."
ocsenave@263 580 ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom))
ocsenave@263 581 ([rom]
ocsenave@263 582 (let
ocsenave@263 583 [poke-names (vec (map format-name (hxc-pokenames rom)))
ocsenave@263 584 item-names (vec (map format-name (hxc-items rom)))
ocsenave@263 585 use-names
ocsenave@263 586 (fn [m]
ocsenave@263 587 (loop [ks (keys m) new-map m]
ocsenave@263 588 (let [k (first ks)]
ocsenave@263 589 (cond (nil? ks) new-map
ocsenave@263 590 (= k :into)
ocsenave@263 591 (recur
ocsenave@263 592 (next ks)
ocsenave@263 593 (assoc new-map
ocsenave@263 594 :into
ocsenave@263 595 (poke-names
ocsenave@263 596 (:into
ocsenave@263 597 new-map))))
ocsenave@263 598 (= k :item)
ocsenave@263 599 (recur
ocsenave@263 600 (next ks)
ocsenave@263 601 (assoc new-map
ocsenave@263 602 :item
ocsenave@263 603 (item-names
ocsenave@263 604 (:item new-map))))
ocsenave@263 605 :else
ocsenave@263 606 (recur
ocsenave@263 607 (next ks)
ocsenave@263 608 new-map)
ocsenave@263 609 ))))]
ocsenave@259 610
ocsenave@263 611 (into {}
ocsenave@263 612 (map (fn [[pkmn evo-coll]]
ocsenave@263 613 [pkmn (map use-names evo-coll)])
ocsenave@263 614 (hxc-evolution rom))))))
ocsenave@263 615
ocsenave@243 616
ocsenave@243 617
ocsenave@243 618
ocsenave@243 619
ocsenave@249 620 ;; ********************** MANIPULATION FNS
ocsenave@249 621
ocsenave@249 622
ocsenave@249 623
ocsenave@249 624
ocsenave@249 625 (defn submap?
ocsenave@249 626 "Compares the two maps. Returns true if map-big has the same associations as map-small, otherwise false."
ocsenave@249 627 [map-small map-big]
ocsenave@249 628 (cond (empty? map-small) true
ocsenave@249 629 (and
ocsenave@249 630 (contains? map-big (ffirst map-small))
ocsenave@249 631 (= (get map-big (ffirst map-small))
ocsenave@249 632 (second (first map-small))))
ocsenave@249 633 (recur (next map-small) map-big)
ocsenave@249 634
ocsenave@249 635 :else false))
ocsenave@249 636
ocsenave@249 637
ocsenave@249 638 (defn search-map [proto-map maps]
ocsenave@249 639 "Returns all the maps that make the same associations as proto-map."
ocsenave@249 640 (some (partial submap? proto-map) maps))
ocsenave@249 641
rlm@252 642 (defn filter-vals
rlm@252 643 "Returns a map consisting of all the pairs [key val] for
rlm@252 644 which (pred key) returns true."
rlm@252 645 [pred map]
rlm@252 646 (reduce (partial apply assoc) {}
rlm@252 647 (filter (fn [[k v]] (pred v)) map)))
ocsenave@249 648
ocsenave@249 649
ocsenave@249 650 (defn search-moves
rlm@252 651 "Returns a subcollection of all hardcoded moves with the
rlm@252 652 given attributes. Attributes consist of :name :power
rlm@252 653 :accuracy :pp :fx-id
rlm@252 654 (and also :fx-txt, but it contains the same information
rlm@252 655 as :fx-id)"
ocsenave@249 656 ([attribute-map]
rlm@252 657 (search-moves
rlm@252 658 com.aurellem.gb.gb-driver/original-rom attribute-map))
ocsenave@249 659 ([rom attribute-map]
rlm@252 660 (filter-vals (partial submap? attribute-map)
rlm@252 661 (hxc-move-data rom))))
ocsenave@249 662
ocsenave@249 663
ocsenave@249 664
ocsenave@249 665
ocsenave@243 666
ocsenave@246 667 ;; note for later: credits start at F1290
ocsenave@243 668
ocsenave@243 669
ocsenave@243 670
ocsenave@246 671 (comment
ocsenave@243 672
rlm@218 673 (def hxc-later
rlm@218 674 "Running this code produces, e.g. hardcoded names NPCs give
rlm@218 675 their pokemon. Will sort through it later."
rlm@218 676 (print (character-codes->str(take 10000
rlm@218 677 (drop 0x71597
rlm@218 678 (rom (root)))))))
rlm@218 679
rlm@218 680 (let [dex
rlm@218 681 (partition-by #(= 0x50 %)
rlm@218 682 (take 2540
rlm@218 683 (drop 0x40687
rlm@218 684 (rom (root)))))]
rlm@218 685 (def dex dex)
rlm@218 686 (def hxc-species
rlm@218 687 (map character-codes->str
rlm@218 688 (take-nth 4 dex))))
ocsenave@259 689 )
ocsenave@259 690
ocsenave@259 691
ocsenave@259 692
ocsenave@259 693