rlm@98
|
1 (ns com.aurellem.items
|
rlm@98
|
2 (:use (com.aurellem gb-driver vbm title))
|
rlm@99
|
3 ;; this is bullshit
|
rlm@98
|
4 (:import [com.aurellem.gb_driver SaveState]))
|
rlm@98
|
5
|
rlm@98
|
6 (defn game-name []
|
rlm@98
|
7 (map char (subvec (vec (memory)) 0x134 0x142)))
|
rlm@98
|
8
|
rlm@99
|
9 (def item-list-start 0xD31C)
|
rlm@98
|
10
|
rlm@99
|
11 (defn item-list [^SaveState state]
|
rlm@99
|
12 (subvec
|
rlm@99
|
13 (vec (memory state))
|
rlm@99
|
14 item-list-start
|
rlm@100
|
15 (+ item-list-start 150)))
|
rlm@98
|
16
|
rlm@98
|
17 (def item-hack-3 (read-state 77557))
|
rlm@98
|
18
|
rlm@99
|
19 (def item-code->item-name
|
rlm@99
|
20 (hash-map
|
rlm@99
|
21 1 :master-ball
|
rlm@99
|
22 2 :ultra-ball
|
rlm@99
|
23 3 :great-ball
|
rlm@99
|
24 4 :poke-ball
|
rlm@99
|
25 5 :town-map
|
rlm@99
|
26 6 :bicycle
|
rlm@99
|
27 8 :safari-ball
|
rlm@99
|
28 9 :pokedex
|
rlm@99
|
29 10 :moon-stone
|
rlm@99
|
30 11 :antidote
|
rlm@99
|
31 12 :burn-heal
|
rlm@99
|
32 13 :ice-heal
|
rlm@99
|
33 14 :awakening
|
rlm@99
|
34 15 :parlyz-heal
|
rlm@99
|
35 16 :full-restore
|
rlm@99
|
36 17 :max-potion
|
rlm@99
|
37 18 :hyper-potion
|
rlm@99
|
38 19 :super-potion
|
rlm@99
|
39 20 :potion
|
rlm@99
|
40 21 :boulderbadge
|
rlm@99
|
41 22 :cascadebadge
|
rlm@99
|
42 23 :thunderbadge
|
rlm@99
|
43 24 :rainbowbadge
|
rlm@99
|
44 25 :soulbadge
|
rlm@99
|
45 26 :marshbadge
|
rlm@99
|
46 27 :volcanobadge
|
rlm@99
|
47 28 :earthbadge
|
rlm@99
|
48 29 :escape-rope
|
rlm@99
|
49 30 :repel
|
rlm@99
|
50 31 :old-amber
|
rlm@99
|
51 32 :fire-stone
|
rlm@99
|
52 33 :thunderstone
|
rlm@99
|
53 34 :water-stone
|
rlm@99
|
54 35 :hp-up
|
rlm@99
|
55 36 :protein
|
rlm@99
|
56 37 :iron
|
rlm@99
|
57 38 :carbos
|
rlm@99
|
58 39 :calcium
|
rlm@99
|
59 40 :rare-candy
|
rlm@99
|
60 41 :dome-fossil
|
rlm@99
|
61 42 :helix-fossil
|
rlm@99
|
62 43 :secret-key
|
rlm@99
|
63 45 :bike-voucher
|
rlm@99
|
64 46 :x-accuracy
|
rlm@99
|
65 47 :leaf-stone
|
rlm@99
|
66 48 :card-key
|
rlm@99
|
67 49 :nugget
|
rlm@99
|
68 50 :pp-up
|
rlm@99
|
69 51 :poke-doll
|
rlm@99
|
70 52 :full-heal
|
rlm@99
|
71 53 :revive
|
rlm@99
|
72 54 :max-revive
|
rlm@99
|
73 55 :guard-spec
|
rlm@99
|
74 56 :super-repel
|
rlm@99
|
75 57 :max-repel
|
rlm@99
|
76 58 :dire-hit
|
rlm@99
|
77 59 :coin
|
rlm@99
|
78 60 :fresh-water
|
rlm@99
|
79 61 :soda-pop
|
rlm@99
|
80 62 :lemonade
|
rlm@99
|
81 63 :s.s.ticket
|
rlm@99
|
82 64 :gold-teeth
|
rlm@99
|
83 65 :x-attach
|
rlm@99
|
84 66 :x-defend
|
rlm@99
|
85 67 :x-speed
|
rlm@99
|
86 68 :x-special
|
rlm@99
|
87 69 :coin-case
|
rlm@99
|
88 70 :oaks-parcel
|
rlm@99
|
89 71 :itemfinder
|
rlm@99
|
90 72 :silph-scope
|
rlm@99
|
91 73 :poke-flute
|
rlm@99
|
92 74 :lift-key
|
rlm@99
|
93 75 :exp.all
|
rlm@99
|
94 76 :old-rod
|
rlm@99
|
95 77 :good-rod
|
rlm@99
|
96 78 :super-rod
|
rlm@99
|
97 79 :pp-up
|
rlm@99
|
98 80 :ether
|
rlm@99
|
99 81 :max-ether
|
rlm@99
|
100 82 :elixer
|
rlm@99
|
101 83 :max-elixer
|
rlm@102
|
102 196 :HM01 ;; cut
|
rlm@102
|
103 197 :HM02 ;; fly
|
rlm@102
|
104 198 :HM03 ;; surf
|
rlm@102
|
105 199 :HM04 ;; strength
|
rlm@102
|
106 200 :HM05 ;; flash
|
rlm@102
|
107 201 :TM01 ;; mega punch
|
rlm@102
|
108 202 :TM02 ;; razor wind
|
rlm@102
|
109 203 :TM03 ;; swords dance
|
rlm@102
|
110 204 :TM04 ;; whirlwind
|
rlm@102
|
111 205 :TM05 ;; mega kick
|
rlm@102
|
112 206 :TM06 ;; toxic
|
rlm@102
|
113 207 :TM07 ;; horn drill
|
rlm@102
|
114 208 :TM08 ;; body slam
|
rlm@102
|
115 209 :TM09 ;; take down
|
rlm@102
|
116 210 :TM10 ;; double-edge
|
rlm@102
|
117 211 :TM11 ;; bubblebeam
|
rlm@102
|
118 212 :TM12 ;; water gun
|
rlm@102
|
119 213 :TM13 ;; ice beam
|
rlm@102
|
120 214 :TM14 ;; blizzard
|
rlm@102
|
121 215 :TM15 ;; hyper beam
|
rlm@102
|
122 216 :TM16 ;; pay day
|
rlm@102
|
123 217 :TM17 ;; submission
|
rlm@102
|
124 218 :TM18 ;; counter
|
rlm@102
|
125 219 :TM19 ;; seismic toss
|
rlm@102
|
126 220 :TM20 ;; rage
|
rlm@102
|
127 221 :TM21 ;; mega drain
|
rlm@102
|
128 222 :TM22 ;; solarbeam
|
rlm@102
|
129 223 :TM23 ;; dragon rage
|
rlm@102
|
130 224 :TM24 ;; thunderbolt
|
rlm@102
|
131 225 :TM25 ;; thunder
|
rlm@102
|
132 226 :TM26 ;; earthquake
|
rlm@102
|
133 227 :TM27 ;; fissure
|
rlm@102
|
134 228 :TM28 ;; dig
|
rlm@102
|
135 229 :TM29 ;; psychic
|
rlm@102
|
136 230 :TM30 ;; teleport
|
rlm@102
|
137 231 :TM31 ;; mimic
|
rlm@102
|
138 232 :TM32 ;; double team
|
rlm@102
|
139 233 :TM33 ;; reflect
|
rlm@102
|
140 234 :TM34 ;; bide
|
rlm@102
|
141 235 :TM35 ;; metronome
|
rlm@102
|
142 236 :TM36 ;; self destruct
|
rlm@102
|
143 237 :TM37 ;; eggbomb
|
rlm@102
|
144 238 :TM38 ;; fire blast
|
rlm@102
|
145 239 :TM39 ;; swift
|
rlm@102
|
146 240 :TM40 ;; skull bash
|
rlm@102
|
147 241 :TM41 ;; softboiled
|
rlm@102
|
148 242 :TM42 ;; dream eater
|
rlm@102
|
149 243 :TM43 ;; sky attack
|
rlm@102
|
150 244 :TM44 ;; rest
|
rlm@102
|
151 245 :TM45 ;; thunder wave
|
rlm@102
|
152 246 :TM46 ;; psywave
|
rlm@102
|
153 247 :TM47 ;; explosion
|
rlm@102
|
154 248 :TM48 ;; rock slide
|
rlm@102
|
155 249 :TM49 ;; tri attack
|
rlm@102
|
156 250 :TM50 ;; substitute
|
rlm@102
|
157 251 :TM51 ;; "cut"
|
rlm@102
|
158 252 :TM52 ;; "fly"
|
rlm@102
|
159 253 :TM53 ;; "surf"
|
rlm@102
|
160 254 :TM54 ;; "strength"
|
rlm@99
|
161 255 :end-of-list-sentinel))
|
rlm@98
|
162
|
rlm@99
|
163 (def item-name->item-code
|
rlm@99
|
164 (zipmap (vals item-code->item-name)
|
rlm@99
|
165 (keys item-code->item-name)))
|
rlm@98
|
166
|
rlm@99
|
167 (defn inventory [^SaveState state]
|
rlm@99
|
168 (let [items (item-list state)]
|
rlm@99
|
169 (map
|
rlm@99
|
170 (fn [[item-code quantity]]
|
rlm@99
|
171 [(item-code->item-name item-code)
|
rlm@99
|
172 quantity])
|
rlm@99
|
173 (partition
|
rlm@99
|
174 2
|
rlm@99
|
175 (next (take-while (partial not= 255) items))))))
|
rlm@98
|
176
|
rlm@102
|
177 (defn print-inventory
|
rlm@102
|
178 ([] (print-inventory @current-state))
|
rlm@102
|
179 ([^SaveState state]
|
rlm@102
|
180 (println
|
rlm@102
|
181 (let [inv (inventory state)]
|
rlm@102
|
182 (reduce
|
rlm@102
|
183 str
|
rlm@102
|
184 (concat
|
rlm@102
|
185 ["+-------------------+----------+\n"
|
rlm@102
|
186 "|##| Item | Quantity |\n"
|
rlm@102
|
187 "+--+----------------+----------+\n"]
|
rlm@98
|
188
|
rlm@102
|
189 (map
|
rlm@102
|
190 (fn [index [item-name quantity]]
|
rlm@102
|
191 (str
|
rlm@102
|
192 (format "|%-2d| %-14s | %3d |\n" index
|
rlm@102
|
193 (apply str (rest (str item-name)))
|
rlm@102
|
194 quantity)))
|
rlm@102
|
195 (range 0 (count inv)) inv)
|
rlm@102
|
196 ["+--+----------------+----------+\n"]))))))
|
rlm@98
|
197
|
rlm@99
|
198 (defn inventory-codes [inventory]
|
rlm@99
|
199 (flatten
|
rlm@99
|
200 (concat [(count inventory)]
|
rlm@99
|
201 (map (fn [[item-name quantity]]
|
rlm@99
|
202 [(item-name->item-code item-name)
|
rlm@99
|
203 quantity]) inventory)
|
rlm@99
|
204 [(item-name->item-code :end-of-list-sentinel)])))
|
rlm@98
|
205
|
rlm@99
|
206 (defn set-inventory [^SaveState state new-inventory]
|
rlm@99
|
207 (set-state! state)
|
rlm@99
|
208 (let [mem (memory state)
|
rlm@99
|
209 inv (inventory-codes new-inventory)]
|
rlm@98
|
210
|
rlm@99
|
211 (dorun (map (fn [index val]
|
rlm@99
|
212 (aset mem index val))
|
rlm@99
|
213 (range item-list-start
|
rlm@99
|
214 (+ item-list-start (count inv))) inv))
|
rlm@99
|
215 (write-memory! mem)
|
rlm@99
|
216 (update-state)))
|
rlm@102
|
217
|
rlm@102
|
218 (def gliched-tms
|
rlm@102
|
219 [[:TM51 1]
|
rlm@102
|
220 [:TM52 1]
|
rlm@102
|
221 [:TM53 1]
|
rlm@102
|
222 [:TM54 1]])
|
rlm@102
|
223
|
rlm@102
|
224 (def good-items
|
rlm@102
|
225 [[:bicycle 1]
|
rlm@102
|
226 [:ultra-ball 15]
|
rlm@102
|
227 [:pp-up 1]
|
rlm@102
|
228 [:master-ball 5]
|
rlm@102
|
229 [:rare-candy 99]
|
rlm@102
|
230 [:full-restore 25]
|
rlm@102
|
231 [:max-revive 8]
|
rlm@102
|
232 [:max-repel 40]
|
rlm@102
|
233 [:TM25 1]
|
rlm@102
|
234 [:TM11 1]
|
rlm@102
|
235 [:TM15 1]
|
rlm@102
|
236 ])
|
rlm@98
|
237
|
rlm@102
|
238 (def some-badges
|
rlm@102
|
239 [[:cascadebadge 1]
|
rlm@102
|
240 [:thunderbadge 1]
|
rlm@102
|
241 [:rainbowbadge 1]
|
rlm@102
|
242 [:soulbadge 1]
|
rlm@102
|
243 ])
|
rlm@102
|
244
|
rlm@102
|
245 (defn run-item-program
|
rlm@102
|
246 "This is my first assembly/item program!
|
rlm@102
|
247 it just increments BC by one.
|
rlm@102
|
248
|
rlm@102
|
249 The code places a single 'great ball' at the beginning of the
|
rlm@102
|
250 inventory, then directly sets the program counter to start
|
rlm@102
|
251 executing at the position of the 'great ball' in memory.
|
rlm@102
|
252
|
rlm@102
|
253 Since a 'great ball' is represented in memory as 0x03, which
|
rlm@102
|
254 corresponts to the opcode which increments BC by one, that is
|
rlm@102
|
255 what happens.
|
rlm@102
|
256
|
rlm@102
|
257 Obviously, the game crashes more or less immediately after the
|
rlm@102
|
258 program counter advances past the 'great ball' into the next items
|
rlm@102
|
259 in the inventory."
|
rlm@102
|
260 []
|
rlm@102
|
261 (set-inventory (read-state 578544) [[:great-ball 1]])
|
rlm@102
|
262 (print-inventory)
|
rlm@102
|
263 (println "3 ticks") (tick) (tick) (tick)
|
rlm@102
|
264 (println "PC before:" (PC))
|
rlm@102
|
265 (println "BC before:" (BC))
|
rlm@102
|
266 (PC! (inc item-list-start))
|
rlm@102
|
267 (println "PC after setting:" (PC))
|
rlm@102
|
268 (println "data at PC:" (aget (memory) (PC)))
|
rlm@102
|
269 (println "one tick")
|
rlm@102
|
270 (tick)
|
rlm@102
|
271 (println "PC after one tick:" (PC))
|
rlm@102
|
272 (println "BC after one tick:" (BC)))
|
rlm@102
|
273 |