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