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@244
|
30 [:normal
|
ocsenave@244
|
31 :fighting
|
ocsenave@244
|
32 :flying
|
ocsenave@244
|
33 :poison
|
ocsenave@244
|
34 :ground
|
ocsenave@244
|
35 :rock
|
ocsenave@245
|
36 :bird
|
ocsenave@244
|
37 :bug
|
ocsenave@244
|
38 :ghost
|
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@244
|
50 :fire
|
ocsenave@244
|
51 :water
|
ocsenave@244
|
52 :grass
|
ocsenave@244
|
53 :electric
|
ocsenave@244
|
54 :psychic
|
ocsenave@244
|
55 :ice
|
ocsenave@244
|
56 :dragon
|
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@259
|
206 ;; In red/blue, pokemon are in internal order.
|
ocsenave@259
|
207 ;; In yellow, pokemon are in pokedex order.
|
ocsenave@259
|
208
|
ocsenave@259
|
209 (defn hxc-pokedex-stats
|
ocsenave@259
|
210 ;; uses hxc-pokedex-text to count pokemon
|
ocsenave@259
|
211 ;; since hxc-pokenames includes several missingno"
|
ocsenave@259
|
212 ([] (hxc-pokedex-stats com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@259
|
213 ([rom]
|
ocsenave@259
|
214 (let [poketext (hxc-pokedex-text)
|
ocsenave@259
|
215 pkmn-count (count poketext)
|
ocsenave@259
|
216 ]
|
ocsenave@259
|
217 ((fn capture-stats
|
ocsenave@259
|
218 [n stats data]
|
ocsenave@259
|
219 (if (zero? n) stats
|
ocsenave@259
|
220 (let [[species
|
ocsenave@259
|
221 [_
|
ocsenave@259
|
222 height-ft
|
ocsenave@259
|
223 height-in
|
ocsenave@259
|
224 weight-1
|
ocsenave@259
|
225 weight-2
|
ocsenave@259
|
226 _
|
ocsenave@259
|
227 dex-ptr-1
|
ocsenave@259
|
228 dex-ptr-2
|
ocsenave@259
|
229 dex-bank
|
ocsenave@259
|
230 _
|
ocsenave@259
|
231 & data]]
|
ocsenave@259
|
232 (split-with (partial not= 0x50) data)]
|
ocsenave@259
|
233 (recur (dec n)
|
ocsenave@259
|
234 (assoc stats
|
ocsenave@259
|
235 (- pkmn-count n)
|
ocsenave@259
|
236 {:species
|
ocsenave@259
|
237 (character-codes->str species)
|
ocsenave@259
|
238 :height-ft
|
ocsenave@259
|
239 height-ft
|
ocsenave@259
|
240 :height-in
|
ocsenave@259
|
241 height-in
|
ocsenave@259
|
242 :weight
|
ocsenave@259
|
243 (/ (low-high weight-1 weight-2) 10.)
|
ocsenave@259
|
244
|
ocsenave@259
|
245 ;; :text
|
ocsenave@259
|
246 ;; (character-codes->str
|
ocsenave@259
|
247 ;; (take-while
|
ocsenave@259
|
248 ;; (partial not= 0x50)
|
ocsenave@259
|
249 ;; (drop
|
ocsenave@259
|
250 ;; (+ 0xB8000
|
ocsenave@259
|
251 ;; -0x4000
|
ocsenave@259
|
252 ;; (low-high dex-ptr-1 dex-ptr-2))
|
ocsenave@259
|
253 ;; rom)))
|
ocsenave@259
|
254 })
|
ocsenave@259
|
255
|
ocsenave@259
|
256 data)
|
ocsenave@259
|
257
|
ocsenave@259
|
258
|
ocsenave@259
|
259 )))
|
ocsenave@259
|
260
|
ocsenave@259
|
261 pkmn-count
|
ocsenave@259
|
262 {}
|
ocsenave@259
|
263 (drop 0x40687 rom))) ))
|
ocsenave@259
|
264
|
ocsenave@259
|
265
|
ocsenave@259
|
266
|
ocsenave@259
|
267
|
ocsenave@259
|
268
|
ocsenave@259
|
269
|
ocsenave@259
|
270
|
ocsenave@246
|
271 (def hxc-places
|
ocsenave@246
|
272 "The hardcoded place names in memory. List begins at
|
ocsenave@249
|
273 ROM@71500. [Cinnabar] Mansion seems to be dynamically calculated."
|
ocsenave@249
|
274 (hxc-thunk-words 0x71500 560))
|
ocsenave@246
|
275
|
ocsenave@246
|
276
|
ocsenave@249
|
277 (defn hxc-dialog
|
ocsenave@249
|
278 "The hardcoded dialogue in memory, including in-game alerts. Dialog
|
ocsenave@249
|
279 seems to be separated by 0x57 instead of 0x50 (END). Begins at ROM@98000."
|
ocsenave@249
|
280 ([rom]
|
ocsenave@249
|
281 (map character-codes->str
|
ocsenave@249
|
282 (take-nth 2
|
ocsenave@249
|
283 (partition-by #(= % 0x57)
|
ocsenave@249
|
284 (take 0x0F728
|
ocsenave@249
|
285 (drop 0x98000 rom))))))
|
ocsenave@249
|
286 ([]
|
ocsenave@249
|
287 (hxc-dialog com.aurellem.gb.gb-driver/original-rom)))
|
ocsenave@249
|
288
|
ocsenave@246
|
289
|
ocsenave@259
|
290
|
ocsenave@249
|
291
|
ocsenave@246
|
292 (def hxc-move-names
|
ocsenave@246
|
293 "The hardcoded move names in memory. List begins at ROM@BC000"
|
ocsenave@249
|
294 (hxc-thunk-words 0xBC000 1551))
|
ocsenave@246
|
295
|
ocsenave@249
|
296
|
ocsenave@249
|
297 (defn hxc-move-data
|
ocsenave@246
|
298 "The hardcoded (basic (move effects)) in memory. List begins at
|
ocsenave@249
|
299 0x38000. Returns a map of {:name :power :accuracy :pp :fx-id
|
ocsenave@249
|
300 :fx-txt}. The move descriptions are handwritten, not hardcoded."
|
ocsenave@249
|
301 ([]
|
ocsenave@249
|
302 (hxc-move-data com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@249
|
303 ([rom]
|
ocsenave@249
|
304 (let [names (vec (hxc-move-names rom))
|
ocsenave@249
|
305 move-count (count names)
|
ocsenave@259
|
306 move-size 6]
|
ocsenave@249
|
307 (zipmap (map format-name names)
|
ocsenave@249
|
308 (map
|
ocsenave@249
|
309 (fn [[idx effect power type accuracy pp]]
|
ocsenave@249
|
310 {:name (names (dec idx))
|
ocsenave@249
|
311 :power power
|
ocsenave@249
|
312 :accuracy accuracy
|
ocsenave@249
|
313 :pp pp
|
ocsenave@249
|
314 :fx-id effect
|
ocsenave@249
|
315 :fx-txt (get move-effects effect)
|
ocsenave@249
|
316 }
|
ocsenave@249
|
317 )
|
ocsenave@249
|
318
|
ocsenave@249
|
319 (partition move-size
|
ocsenave@249
|
320 (take (* move-size move-count)
|
ocsenave@249
|
321 (drop 0x38000 rom))))))))
|
ocsenave@246
|
322
|
ocsenave@246
|
323
|
ocsenave@246
|
324
|
ocsenave@249
|
325 (defn hxc-move-data*
|
ocsenave@249
|
326 "Like hxc-move-data, but reports numbers as hexadecimal symbols instead."
|
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@249
|
332 move-size 6
|
ocsenave@249
|
333 format-name (fn [s]
|
ocsenave@249
|
334 (keyword (.toLowerCase
|
ocsenave@249
|
335 (apply str
|
ocsenave@249
|
336 (map #(if (= % \space) "-" %) s)))))
|
ocsenave@249
|
337 ]
|
ocsenave@249
|
338 (zipmap (map format-name names)
|
ocsenave@249
|
339 (map
|
ocsenave@249
|
340 (fn [[idx effect power type accuracy pp]]
|
ocsenave@249
|
341 {:name (names (dec idx))
|
ocsenave@249
|
342 :power power
|
ocsenave@249
|
343 :accuracy (hex accuracy)
|
ocsenave@249
|
344 :pp pp
|
ocsenave@249
|
345 :fx-id (hex effect)
|
ocsenave@249
|
346 :fx-txt (get move-effects effect)
|
ocsenave@249
|
347 }
|
ocsenave@249
|
348 )
|
ocsenave@249
|
349
|
ocsenave@249
|
350 (partition move-size
|
ocsenave@249
|
351 (take (* move-size move-count)
|
ocsenave@249
|
352 (drop 0x38000 rom))))))))
|
ocsenave@243
|
353
|
ocsenave@243
|
354
|
ocsenave@243
|
355
|
ocsenave@249
|
356 (defn hxc-pokenames
|
ocsenave@249
|
357 "The hardcoded names of the 190 species in memory. List begins at
|
ocsenave@249
|
358 ROM@E8000. Although names in memory are padded with 0x50 to be 10 characters
|
ocsenave@249
|
359 long, these names are stripped of padding."
|
ocsenave@249
|
360 ([]
|
ocsenave@249
|
361 (hxc-pokenames com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@249
|
362 ([rom]
|
ocsenave@249
|
363 (let [count-species 190
|
ocsenave@249
|
364 name-length 10]
|
ocsenave@249
|
365 (map character-codes->str
|
ocsenave@249
|
366 (partition name-length
|
ocsenave@249
|
367 (map #(if (= 0x50 %) 0x00 %)
|
ocsenave@249
|
368 (take (* count-species name-length)
|
ocsenave@249
|
369 (drop 0xE8000
|
ocsenave@249
|
370 rom))))))))
|
ocsenave@243
|
371
|
ocsenave@259
|
372
|
ocsenave@259
|
373
|
ocsenave@259
|
374
|
ocsenave@259
|
375 (defn internal-id
|
ocsenave@259
|
376 ([rom]
|
ocsenave@259
|
377 (zipmap
|
ocsenave@259
|
378 (map format-name (hxc-pokenames rom))
|
ocsenave@259
|
379 (range)))
|
ocsenave@259
|
380 ([]
|
ocsenave@259
|
381 (internal-id com.aurellem.gb.gb-driver/original-rom)))
|
ocsenave@259
|
382
|
ocsenave@259
|
383
|
ocsenave@259
|
384
|
ocsenave@263
|
385 ;; nidoran gender change upon levelup
|
ocsenave@263
|
386 ;; (->
|
ocsenave@263
|
387 ;; @current-state
|
ocsenave@263
|
388 ;; rom
|
ocsenave@263
|
389 ;; vec
|
ocsenave@263
|
390 ;; (rewrite-memory
|
ocsenave@263
|
391 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♂))
|
ocsenave@263
|
392 ;; [1 1 15])
|
ocsenave@263
|
393 ;; (rewrite-memory
|
ocsenave@263
|
394 ;; (nth (hxc-ptrs-evolve) ((internal-id) :nidoran♀))
|
ocsenave@263
|
395 ;; [1 1 3])
|
ocsenave@263
|
396 ;; (write-rom!)
|
ocsenave@263
|
397
|
ocsenave@263
|
398 ;; )
|
ocsenave@263
|
399
|
ocsenave@259
|
400
|
ocsenave@259
|
401
|
ocsenave@259
|
402
|
ocsenave@249
|
403 (defn hxc-advantage
|
ocsenave@249
|
404 "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
|
405 the multiplier is 1."
|
ocsenave@249
|
406 ([] (hxc-advantage com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@249
|
407 ([rom]
|
ocsenave@249
|
408 (map
|
ocsenave@249
|
409 (fn [[atk def mult]] [(get pkmn-types atk (hex atk))
|
ocsenave@249
|
410 (get pkmn-types def (hex def))
|
ocsenave@249
|
411 (/ mult 10)])
|
ocsenave@249
|
412 (partition 3
|
ocsenave@249
|
413 (take-while (partial not= 0xFF)
|
ocsenave@249
|
414 (drop 0x3E62D rom))))))
|
ocsenave@243
|
415
|
ocsenave@243
|
416
|
ocsenave@263
|
417 (defn format-evo
|
ocsenave@263
|
418 [coll]
|
ocsenave@263
|
419 (let [method (first coll)]
|
ocsenave@263
|
420 (cond (empty? coll) []
|
ocsenave@263
|
421 (= 0 method) [] ;; just in case
|
ocsenave@263
|
422 (= 1 method) ;; level-up evolution
|
ocsenave@263
|
423 (conj (format-evo (drop 3 coll))
|
ocsenave@263
|
424 {:method :level-up
|
ocsenave@263
|
425 :min-level (nth coll 1)
|
ocsenave@263
|
426 :into (dec (nth coll 2))})
|
ocsenave@263
|
427
|
ocsenave@263
|
428 (= 2 method) ;; item evolution
|
ocsenave@263
|
429 (conj (format-evo (drop 4 coll))
|
ocsenave@263
|
430 {:method :item
|
ocsenave@263
|
431 :item (dec (nth coll 1))
|
ocsenave@263
|
432 :min-level (nth coll 2)
|
ocsenave@263
|
433 :into (dec (nth coll 3))})
|
ocsenave@243
|
434
|
ocsenave@263
|
435 (= 3 method) ;; trade evolution
|
ocsenave@263
|
436 (conj (format-evo (drop 3 coll))
|
ocsenave@263
|
437 {:method :trade
|
ocsenave@263
|
438 :min-level (nth coll 1) ;; always 1 for trade.
|
ocsenave@263
|
439 :into (dec (nth coll 2))}))))
|
ocsenave@243
|
440
|
ocsenave@243
|
441
|
ocsenave@263
|
442 (defn hxc-ptrs-evolve
|
ocsenave@267
|
443 "A hardcoded collection of 190 pointers to alternating evolution/learnset data,
|
ocsenave@263
|
444 in internal order."
|
ocsenave@263
|
445 ([]
|
ocsenave@263
|
446 (hxc-ptrs-evolve com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@259
|
447 ([rom]
|
ocsenave@259
|
448 (let [names (hxc-pokenames rom)
|
ocsenave@259
|
449 pkmn-count (count names)
|
ocsenave@259
|
450 ptrs
|
ocsenave@263
|
451 (map (fn [[a b]] (low-high a b))
|
ocsenave@259
|
452 (partition 2
|
ocsenave@259
|
453 (take (* 2 pkmn-count)
|
ocsenave@263
|
454 (drop 0x3b1e5 rom))))]
|
ocsenave@263
|
455 (map (partial + 0x34000) ptrs)
|
ocsenave@263
|
456
|
ocsenave@263
|
457 )))
|
ocsenave@263
|
458
|
ocsenave@267
|
459
|
ocsenave@267
|
460 (defn hxc-learnsets
|
ocsenave@267
|
461 "Hardcoded map associating pokemon names to lists of pairs [lvl
|
ocsenave@267
|
462 move] of abilities they learn as they level up. The data
|
ocsenave@267
|
463 exists at ROM@3400, sorted by internal order. Pointers to the data
|
ocsenave@267
|
464 exist at ROM@3B1E5; see also, hxc-ptrs-evolve"
|
ocsenave@267
|
465 ([] (hxc-learnsets com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@267
|
466 ([rom]
|
ocsenave@267
|
467 (apply assoc
|
ocsenave@267
|
468 {}
|
ocsenave@267
|
469 (interleave
|
ocsenave@267
|
470 (map format-name (hxc-pokenames rom))
|
ocsenave@267
|
471 (map (comp
|
ocsenave@267
|
472 (partial map vec)
|
ocsenave@267
|
473 (partial partition 2)
|
ocsenave@267
|
474 ;; keep the learnset data
|
ocsenave@267
|
475 (partial take-while (comp not zero?))
|
ocsenave@267
|
476 ;; skip the evolution data
|
ocsenave@267
|
477 rest
|
ocsenave@267
|
478 (partial drop-while (comp not zero?)))
|
ocsenave@267
|
479 (map #(drop % rom)
|
ocsenave@267
|
480 (hxc-ptrs-evolve rom)))))))
|
ocsenave@267
|
481
|
ocsenave@267
|
482 (defn hxc-learnsets-pretty
|
ocsenave@267
|
483 "Live hxc-learnsets except it reports the name of each move --- as
|
ocsenave@267
|
484 it appears in rom --- rather than the move index."
|
ocsenave@267
|
485 ([] (hxc-learnsets-pretty com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@267
|
486 ([rom]
|
ocsenave@267
|
487 (let [moves (vec(map format-name (hxc-move-names)))]
|
ocsenave@267
|
488 (into {}
|
ocsenave@267
|
489 (map (fn [[pkmn learnset]]
|
ocsenave@267
|
490 [pkmn (map (fn [[lvl mv]] [lvl (moves (dec mv))])
|
ocsenave@267
|
491 learnset)])
|
ocsenave@267
|
492 (hxc-learnsets rom))))))
|
ocsenave@267
|
493
|
ocsenave@267
|
494
|
ocsenave@267
|
495
|
ocsenave@267
|
496
|
ocsenave@263
|
497 (defn hxc-evolution
|
ocsenave@263
|
498 "Hardcoded evolution data in memory. The data exists at ROM@34000,
|
ocsenave@263
|
499 sorted by internal order. Pointers to the data exist at ROM@3B1E5; see also, hxc-ptrs-evolve."
|
ocsenave@263
|
500 ([] (hxc-evolution com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@263
|
501 ([rom]
|
ocsenave@259
|
502 (apply assoc {}
|
ocsenave@259
|
503 (interleave
|
ocsenave@267
|
504 (map format-name (hxc-pokenames rom))
|
ocsenave@259
|
505 (map
|
ocsenave@259
|
506 (comp
|
ocsenave@259
|
507 format-evo
|
ocsenave@263
|
508 (partial take-while (comp not zero?))
|
ocsenave@263
|
509 #(drop % rom))
|
ocsenave@263
|
510 (hxc-ptrs-evolve rom)
|
ocsenave@263
|
511 )))))
|
ocsenave@259
|
512
|
ocsenave@263
|
513 (defn hxc-evolution-pretty
|
ocsenave@263
|
514 "Like hxc-evolution, except it uses the names of items and pokemon
|
ocsenave@263
|
515 --- grabbed from ROM --- rather than their numerical identifiers."
|
ocsenave@263
|
516 ([] (hxc-evolution-pretty com.aurellem.gb.gb-driver/original-rom))
|
ocsenave@263
|
517 ([rom]
|
ocsenave@263
|
518 (let
|
ocsenave@263
|
519 [poke-names (vec (map format-name (hxc-pokenames rom)))
|
ocsenave@263
|
520 item-names (vec (map format-name (hxc-items rom)))
|
ocsenave@263
|
521 use-names
|
ocsenave@263
|
522 (fn [m]
|
ocsenave@263
|
523 (loop [ks (keys m) new-map m]
|
ocsenave@263
|
524 (let [k (first ks)]
|
ocsenave@263
|
525 (cond (nil? ks) new-map
|
ocsenave@263
|
526 (= k :into)
|
ocsenave@263
|
527 (recur
|
ocsenave@263
|
528 (next ks)
|
ocsenave@263
|
529 (assoc new-map
|
ocsenave@263
|
530 :into
|
ocsenave@263
|
531 (poke-names
|
ocsenave@263
|
532 (:into
|
ocsenave@263
|
533 new-map))))
|
ocsenave@263
|
534 (= k :item)
|
ocsenave@263
|
535 (recur
|
ocsenave@263
|
536 (next ks)
|
ocsenave@263
|
537 (assoc new-map
|
ocsenave@263
|
538 :item
|
ocsenave@263
|
539 (item-names
|
ocsenave@263
|
540 (:item new-map))))
|
ocsenave@263
|
541 :else
|
ocsenave@263
|
542 (recur
|
ocsenave@263
|
543 (next ks)
|
ocsenave@263
|
544 new-map)
|
ocsenave@263
|
545 ))))]
|
ocsenave@259
|
546
|
ocsenave@263
|
547 (into {}
|
ocsenave@263
|
548 (map (fn [[pkmn evo-coll]]
|
ocsenave@263
|
549 [pkmn (map use-names evo-coll)])
|
ocsenave@263
|
550 (hxc-evolution rom))))))
|
ocsenave@263
|
551
|
ocsenave@243
|
552
|
ocsenave@243
|
553
|
ocsenave@243
|
554
|
ocsenave@243
|
555
|
ocsenave@249
|
556 ;; ********************** MANIPULATION FNS
|
ocsenave@249
|
557
|
ocsenave@249
|
558
|
ocsenave@249
|
559
|
ocsenave@249
|
560
|
ocsenave@249
|
561 (defn submap?
|
ocsenave@249
|
562 "Compares the two maps. Returns true if map-big has the same associations as map-small, otherwise false."
|
ocsenave@249
|
563 [map-small map-big]
|
ocsenave@249
|
564 (cond (empty? map-small) true
|
ocsenave@249
|
565 (and
|
ocsenave@249
|
566 (contains? map-big (ffirst map-small))
|
ocsenave@249
|
567 (= (get map-big (ffirst map-small))
|
ocsenave@249
|
568 (second (first map-small))))
|
ocsenave@249
|
569 (recur (next map-small) map-big)
|
ocsenave@249
|
570
|
ocsenave@249
|
571 :else false))
|
ocsenave@249
|
572
|
ocsenave@249
|
573
|
ocsenave@249
|
574 (defn search-map [proto-map maps]
|
ocsenave@249
|
575 "Returns all the maps that make the same associations as proto-map."
|
ocsenave@249
|
576 (some (partial submap? proto-map) maps))
|
ocsenave@249
|
577
|
rlm@252
|
578 (defn filter-vals
|
rlm@252
|
579 "Returns a map consisting of all the pairs [key val] for
|
rlm@252
|
580 which (pred key) returns true."
|
rlm@252
|
581 [pred map]
|
rlm@252
|
582 (reduce (partial apply assoc) {}
|
rlm@252
|
583 (filter (fn [[k v]] (pred v)) map)))
|
ocsenave@249
|
584
|
ocsenave@249
|
585
|
ocsenave@249
|
586 (defn search-moves
|
rlm@252
|
587 "Returns a subcollection of all hardcoded moves with the
|
rlm@252
|
588 given attributes. Attributes consist of :name :power
|
rlm@252
|
589 :accuracy :pp :fx-id
|
rlm@252
|
590 (and also :fx-txt, but it contains the same information
|
rlm@252
|
591 as :fx-id)"
|
ocsenave@249
|
592 ([attribute-map]
|
rlm@252
|
593 (search-moves
|
rlm@252
|
594 com.aurellem.gb.gb-driver/original-rom attribute-map))
|
ocsenave@249
|
595 ([rom attribute-map]
|
rlm@252
|
596 (filter-vals (partial submap? attribute-map)
|
rlm@252
|
597 (hxc-move-data rom))))
|
ocsenave@249
|
598
|
ocsenave@249
|
599
|
ocsenave@249
|
600
|
ocsenave@249
|
601
|
ocsenave@243
|
602
|
ocsenave@246
|
603 ;; note for later: credits start at F1290
|
ocsenave@243
|
604
|
ocsenave@243
|
605
|
ocsenave@243
|
606
|
ocsenave@246
|
607 (comment
|
ocsenave@243
|
608
|
rlm@218
|
609 (def hxc-later
|
rlm@218
|
610 "Running this code produces, e.g. hardcoded names NPCs give
|
rlm@218
|
611 their pokemon. Will sort through it later."
|
rlm@218
|
612 (print (character-codes->str(take 10000
|
rlm@218
|
613 (drop 0x71597
|
rlm@218
|
614 (rom (root)))))))
|
rlm@218
|
615
|
rlm@218
|
616 (let [dex
|
rlm@218
|
617 (partition-by #(= 0x50 %)
|
rlm@218
|
618 (take 2540
|
rlm@218
|
619 (drop 0x40687
|
rlm@218
|
620 (rom (root)))))]
|
rlm@218
|
621 (def dex dex)
|
rlm@218
|
622 (def hxc-species
|
rlm@218
|
623 (map character-codes->str
|
rlm@218
|
624 (take-nth 4 dex))))
|
ocsenave@259
|
625 )
|
ocsenave@259
|
626
|
ocsenave@259
|
627
|
ocsenave@259
|
628
|
ocsenave@259
|
629
|