Mercurial > vba-clojure
view clojure/com/aurellem/run/bootstrap_0.clj @ 303:5bcda2d6d135
item manipulation program works!
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 31 Mar 2012 00:33:35 -0500 |
parents | 0b3e89103dc2 |
children | fefe5ce49b21 |
line wrap: on
line source
1 (ns com.aurellem.run.bootstrap-02 (:use (com.aurellem.gb gb-driver util items vbm characters money))3 (:use (com.aurellem.run title save-corruption))4 (:use (com.aurellem.exp item-bridge))5 (:import [com.aurellem.gb.gb_driver SaveState]))7 (defn-memo boot-root []8 [ [] (root)])10 (defn-memo to-rival-name11 ([] (to-rival-name (boot-root)))12 ([script]13 (-> script14 title15 oak16 name-entry-rlm17 scroll-text18 scroll-text19 scroll-text20 scroll-text21 scroll-text)))23 (defn-memo name-rival-bootstrap24 ([] (name-rival-bootstrap (to-rival-name)))25 ([script]26 (->> script27 (advance [] [:a])28 (advance [] [:r] DE)29 (play-moves30 [[]31 [:r] [] [:r] [] [:r] [] [:r] []32 [:r] [] [:r] [] [:r] [] [:d] []33 [:d] [:a] ;; space34 [:l] [] [:d] [:a] ;; [PK]35 [:u] [] [:u] [] [:u] [] [:l] [:a] ;; G36 [:d] [] [:d] [] [:d] [] [:r] [:a] ;; [PK]37 [:u] [] [:u] [] [:u] [] [:l] [:a] ;; G38 [:d] [] [:d] [] [:d] [] [:r] [:a] ;; [PK]40 [:d] [] [:r] [:a] ;; finish41 ]))))43 (defn walk44 "Move the character along the given directions."45 [directions script]46 (reduce (fn [script direction]47 (move direction script))48 script directions))50 (def ↑ [:u])51 (def ↓ [:d])52 (def ← [:l])53 (def → [:r])55 (defn-memo leave-house56 ([] (leave-house (name-rival-bootstrap)))57 ([script]58 (->> script59 finish-title60 start-walking61 walk-to-stairs62 walk-to-door63 (walk [↓ ↓]))))65 (defn-memo to-pallet-town-edge66 ([] (to-pallet-town-edge (leave-house)))67 ([script]68 (->> script69 start-walking70 (walk [→ → → → →71 ↑ ↑ ↑ ↑ ↑ ↑]))))73 (defn end-text [script]74 (->> script75 (scroll-text)76 (play-moves [[] [:a]])))78 (defn-memo start-pikachu-battle79 ([] (start-pikachu-battle80 (to-pallet-town-edge)))81 ([script]82 (->> script83 (advance [:b] [:b :a] DE)84 (scroll-text)85 (play-moves [[:b]])86 (scroll-text)87 (end-text) ;; battle begins88 (scroll-text))))90 (defn-memo capture-pikachu91 ([] (capture-pikachu (start-pikachu-battle)))92 ([script]93 (->> script94 (scroll-text 2)95 (end-text))))97 (defn-memo go-to-lab98 ([] (go-to-lab (capture-pikachu)))99 ([script]100 (->> script101 (scroll-text 5)102 (end-text)103 (scroll-text)104 (end-text)105 (scroll-text 8)106 (end-text)107 (scroll-text)108 (end-text))))110 (defn-memo obtain-pikachu111 ([] (obtain-pikachu (go-to-lab)))112 ([script]113 (->> script114 (scroll-text)115 (play-moves116 (concat117 (repeat 51 [])118 [[:a] []]))119 (walk [↓ ↓ → → ↑])120 (play-moves121 (concat [[] [:a]]122 (repeat 100 [])))123 (scroll-text 9)124 (end-text)125 (scroll-text 7)127 (play-moves128 (concat129 (repeat 42 [])130 [[:b] [:b] [:b] [:b]])))))132 (defn-memo begin-battle-with-rival133 ([] (begin-battle-with-rival134 (obtain-pikachu)))135 ([script]136 (->> script137 (walk [↓ ↓ ↓ ↓])138 (scroll-text 3)139 (end-text)140 (scroll-text))))142 (defn search-string143 [array string]144 (let [codes145 (str->character-codes string)146 codes-length (count codes)147 mem (vec array)148 mem-length (count mem)]149 (loop [idx 0]150 (if (< (- mem-length idx) codes-length)151 nil152 (if (= (subvec mem idx (+ idx codes-length))153 codes)154 idx155 (recur (inc idx)))))))157 (defn critical-hit158 "Put the cursor over the desired attack. This program will159 determine the appropriate amount of blank frames to160 insert before pressing [:a] to ensure that the attack is161 a critical hit."162 [script]163 (loop [blanks 6]164 (let [new-script165 (->> script166 (play-moves167 (concat (repeat blanks [])168 [[:a][]])))]169 (if (let [future-state170 (run-moves (second new-script)171 (repeat 400 []))173 result (search-string (memory future-state)174 "Critical")]175 (if result176 (println "critical hit with" blanks "blank frames"))177 result)178 new-script179 (recur (inc blanks))))))181 (defn-memo battle-with-rival182 ([] (battle-with-rival183 (begin-battle-with-rival)))184 ([script]185 (->> script186 (play-moves (repeat 381 []))187 (play-moves [[:a]])188 (critical-hit)189 (play-moves (repeat 100 []))190 (scroll-text)191 (play-moves192 (concat (repeat 275 []) [[:a]]))193 (critical-hit)194 (play-moves (repeat 100 []))195 (scroll-text)196 (play-moves197 (concat (repeat 270 []) [[:a]]))198 (play-moves [[][][][][][][][][:a]]))))200 (defn-memo finish-rival-text201 ([] (finish-rival-text202 (battle-with-rival)))203 ([script]204 (->> script205 (scroll-text 2)206 (end-text)207 (scroll-text 9)208 (end-text))))210 (defn do-nothing [n script]211 (->> script212 (play-moves213 (repeat n []))))215 (defn-memo pikachu-comes-out216 ([] (pikachu-comes-out217 (finish-rival-text)))218 ([script]219 (->> script220 (do-nothing 177)221 (end-text)222 (scroll-text 7)223 (end-text))))225 (defn-memo leave-oaks-lab226 ([] (leave-oaks-lab227 (pikachu-comes-out)))228 ([script]229 (->> script230 (walk [← ← ↓ ↓ ↓ ↓ ↓ ↓]))))232 (defn-memo oaks-lab->pallet-town-edge233 ([] (oaks-lab->pallet-town-edge234 (leave-oaks-lab)))235 ([script]236 (->> script237 (walk [← ← ← ←238 ↑ ↑ ↑ ↑239 ↑ ↑ ↑ ↑ ↑ ↑240 → ↑]))))242 (defn move-thru-grass243 [direction script]244 (loop [blanks 0]245 (let [new-script246 (->> script247 (play-moves (repeat blanks []))248 (move direction))250 future-state251 (run-moves (second new-script)252 (repeat 600 []))254 result (search-string (memory future-state)255 "Wild")]256 (if (nil? result)257 (do258 (if (< 0 blanks)259 (do(println "avoided pokemon with" blanks "blank frames")))260 new-script)261 (recur (inc blanks))))))263 (defn walk-thru-grass264 [directions script]265 (reduce (fn [script direction]266 (move-thru-grass direction script))267 script directions))269 (defn-memo pallet-edge->viridian-mart270 ([] (pallet-edge->viridian-mart true271 (oaks-lab->pallet-town-edge)))272 ([dodge-stupid-guy? script]273 (let [dodge-1 (if dodge-stupid-guy?274 [→ →]275 [→])276 dodge-2 (if dodge-stupid-guy?277 [↑ ↑ ←]278 [↑ ↑ ←])]280 (->> script281 ;; leave straight grass282 (walk-thru-grass283 [↑ ↑ ↑ ↑ ↑])285 (walk [↑ ↑ ↑ ↑])287 (walk-thru-grass288 [← ← ↑])289 (walk [↑ ↑ ↑ ↑ → → → ])291 (walk-thru-grass292 [→ ↑ ↑ ←])294 (walk295 [← ←296 ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑297 → → → → ])299 ;; this part is dependent on that300 ;; stupid NPC in the grass patch301 (walk-thru-grass302 (concat dodge-1303 [↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ]))305 (walk306 (concat307 dodge-2308 [← ← ←309 ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑310 ← ←311 ↑ ↑ ↑ ↑312 → → → → → → → → → →313 ↑ ↑ ↑ ↑ ↑ ↑ ↑]))))))315 (defn-memo get-oaks-parcel316 ([] (get-oaks-parcel317 (pallet-edge->viridian-mart)))318 ([script]319 (->> script320 (end-text)321 (scroll-text 3)322 (do-nothing 197)323 (play-moves [[:a] []])324 (walk [↓ ↓ → ↓]))))326 (defn-memo viridian-store->oaks-lab327 ([] (viridian-store->oaks-lab328 (get-oaks-parcel)))329 ([script]330 (->> script331 (walk [↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓332 ← ← ← ← ← ← ← ← ← ←333 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓334 ← ←335 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓336 ↓ ↓ ↓ ↓ ↓ ↓ ↓337 → → → → → → → →338 ↓ ↓ ↓ ↓339 ← ← ← ← ←340 ↓ ↓ ↓ ↓])342 (walk-thru-grass343 [↓ ↓ ↓ ↓ ↓ ↓ ↓])345 (walk [↓ ↓ ← ↓ ↓ ↓ ←346 ↓ ↓ ↓ ↓ ↓347 → → → ↑]))))349 (defn-memo viridian-store->oaks-lab-like-a-boss350 ([] (viridian-store->oaks-lab-like-a-boss351 (get-oaks-parcel)))352 ([script]353 (->> script354 (walk [↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓355 ← ← ← ← ← ← ← ← ← ←356 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓])358 (walk-thru-grass359 [↓ ↓ ↓ ↓ ↓])361 (walk362 [↓ ↓ ← ↓363 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓364 → →])366 (walk-thru-grass367 [→ ↓ ↓ ↓])369 (walk [↓ ← ← ↓ ↓ ↓ ↓ ↓ ↓])371 (walk-thru-grass372 [↓ ↓ ↓ ↓ ↓ ↓ ↓])374 (walk [↓ ↓ ← ↓ ↓ ↓ ←375 ↓ ↓ ↓ ↓ ↓376 → → → ↑]))))378 (defn-memo deliver-oaks-parcel379 ([] (deliver-oaks-parcel380 (viridian-store->oaks-lab-like-a-boss)))381 ([script]382 (->> script383 (walk [↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑])384 (play-moves [[:a]])385 (scroll-text 11)386 (end-text)387 (end-text)388 (do-nothing 200)389 (end-text)390 (scroll-text 3)391 (end-text)392 (scroll-text 2)393 (end-text)394 (scroll-text 5)395 (end-text)396 (scroll-text 2)397 (end-text)398 (scroll-text 9)399 (end-text)400 (scroll-text 7)401 (end-text)402 (walk [← ← ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓]))))404 (defn-memo return-to-viridian-mart405 ([] (return-to-viridian-mart406 (deliver-oaks-parcel)))407 ([script]408 (->> script409 oaks-lab->pallet-town-edge410 (pallet-edge->viridian-mart false))))412 (defn-memo walk-to-counter413 ([] (walk-to-counter414 (return-to-viridian-mart)))415 ([script]416 (->> script417 (walk [↑ ↑ ← ←]))))419 (defn buy-item420 "Assumes that the main item-screen is up, and buys421 quantity of the nth item in the list, assuming that you422 have enough money."423 [n quantity script]424 (if (= 0 quantity)425 script426 (let [after-initial-pause427 (do-nothing 20 script)428 move-to-item429 (reduce (fn [script _]430 (->> script431 (play-moves [[:d]])432 (do-nothing 3)))433 after-initial-pause434 (range n))435 select-item436 (play-moves [[:a]] move-to-item)437 request-items438 (reduce (fn [script _]439 (->> script440 (play-moves [[:u]])441 (do-nothing 1)))442 select-item443 (range (dec quantity)))444 buy-items445 (->> request-items446 (do-nothing 10)447 (play-moves [[:a]])448 (scroll-text)449 (scroll-text)450 (do-nothing 10)451 (play-moves [[:a]])452 (scroll-text))]453 buy-items)))456 (defn buy-items457 "Given a list of [item-no quantity], buys the quantity458 from the shop's list. Assumes that the item list is459 already up."460 [item-pairs script]461 (let [item-lookup (into {0 0 1 0 2 0 3 0 4 0} item-pairs)462 initial-purchase463 (->> script464 (buy-item 0 (item-lookup 0))465 (buy-item 1 (item-lookup 1))466 (buy-item 2 (item-lookup 2)))]467 (cond468 (and469 (not= 0 (item-lookup 3))470 (not= 0 (item-lookup 4)))471 (->> initial-purchase472 (do-nothing 20)473 (play-moves [[:d]])474 (do-nothing 3)475 (play-moves [[:d]])476 (do-nothing 3)477 (play-moves [[:d]])478 (do-nothing 10)479 (buy-item 0 (item-lookup 3))480 (do-nothing 20)481 (play-moves [[:d]])482 (do-nothing 3)483 (play-moves [[:d]])484 (do-nothing 3)485 (play-moves [[:d]])486 (do-nothing 10)487 (buy-item 0 (item-lookup 4)))488 (and (= 0 (item-lookup 3))489 (not= 0 (item-lookup 4)))490 (->> initial-purchase491 (do-nothing 20)492 (play-moves [[:d]])493 (do-nothing 3)494 (play-moves [[:d]])495 (do-nothing 3)496 (play-moves [[:d]])497 (do-nothing 10)498 (play-moves [[:d]])499 (do-nothing 10)500 (buy-item 0 (item-lookup 4)))501 (and (not= 0 (item-lookup 3))502 (= 0 (item-lookup 4)))503 (->> initial-purchase504 (do-nothing 20)505 (play-moves [[:d]])506 (do-nothing 3)507 (play-moves [[:d]])508 (do-nothing 3)509 (play-moves [[:d]])510 (do-nothing 10)511 (buy-item 0 (item-lookup 3)))512 (and (= 0 (item-lookup 3))513 (= 0 (item-lookup 4)))514 initial-purchase)))517 (defn test-buy-items518 ([] (test-buy-items519 (walk-to-counter)))520 ([script]521 (->> [(first script) (set-money (second script)522 999999)]523 (play-moves524 [[] [:a] []])525 (scroll-text)526 (do-nothing 100)527 (play-moves [[:a]])528 (do-nothing 100)529 (buy-items530 [[0 1]531 [1 15]532 [2 1]533 [3 20]534 [4 95]535 ]))))537 (defn-memo buy-initial-items538 ([] (buy-initial-items539 (walk-to-counter)))540 ([script]541 (->> script542 (play-moves543 [[] [:a] []])544 (scroll-text)545 (do-nothing 100)546 (play-moves [[:a]])547 (do-nothing 100)548 (buy-items549 [[0 1]550 [1 1]551 [2 1]552 [3 1]553 [4 1]])554 (do-nothing 100)555 (play-moves [[:b]])556 (do-nothing 100)557 (play-moves [[:b]])558 (do-nothing 100)559 (play-moves [[:b] []])560 (advance [:b] [:b :start]))))563 (defn-memo do-save-corruption564 ([] (do-save-corruption565 (buy-initial-items)))566 ([script]567 (->> script568 (advance [] [:d])569 (play-moves [[] [] [] [:d]570 [] [] [] [:d]571 [] [] [] [:d]572 [] [] [:a]])573 scroll-text574 (play-moves575 ;; this section is copied from speedrun-2942 and corrupts576 ;; the save so that the total number of pokemon is set to577 ;; 0xFF, allowing manipulation of non-pokemon data in RAM578 ;; via the pokemon interface.579 [[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []580 [] [] [] [] [] [] [] [] [] [] [] [:select] [:restart]])581 (title)582 (advance [] [:start])583 (advance [] [:a])584 (advance [:a] [:a :start]))))586 (def menu walk)588 (defn-memo corrupt-item-list589 ([] (corrupt-item-list590 (do-save-corruption)))591 ([script]592 (->> script593 (do-nothing 200)594 (menu [↓ [:a]]) ; select "POKEMON" from595 ; from main menu596 (menu [↓ ↓ ↓ ↓ ↓ ↓ ; go to 6th pokemon597 [:a] ↓ [:a] ; select "switch"598 ↓ ↓ ↓ [:a]]) ; switch with 9th "pokemon"600 (do-nothing 1))))603 (defn slowly604 [delay moves script]605 (reduce606 (fn [script move]607 (->> script608 (do-nothing delay)609 (play-moves (vector move))))610 script moves))612 (defn-memo get-burn-heals613 ([] (get-burn-heals614 (corrupt-item-list)))615 ([script]616 (->> script617 (menu [[:b] [:b]])618 (menu [[:a]])619 (do-nothing 100)620 (menu [↓ [:a]])621 (do-nothing 100)622 (menu [[:a] ↓ [:a]])623 (scroll-text)624 (menu [[:b][:b]])625 (menu [[:a]])627 (do-nothing 50)628 (buy-items [[0 1]])629 (do-nothing 60)630 (menu [[:a]])631 (scroll-text)633 (do-nothing 50)634 (buy-items [[0 1]])635 (do-nothing 60)636 ;;(menu [[:a]])637 ;;(scroll-text)639 ;;(do-nothing 300)640 ;;(menu [[:b] [:b]])641 ;;(do-nothing 300)643 (buy-items [[0 1]644 [1 1]645 [1 1]646 [2 1]647 [3 1]648 [4 97]])650 (do-nothing 10))))652 (defn save-game-properly653 [number-down script]654 (->>655 (reduce (fn [script _]656 (->> script657 (advance [] [:d])))658 script659 (range number-down))660 (play-moves [[] [] [:a]])661 (scroll-text)662 (do-nothing 300)))664 (defn-memo corrupt-item-list-again665 ([] (corrupt-item-list-again (get-burn-heals)))666 ([script]667 (->> script668 (do-nothing 10)669 (play-moves [[:b]])670 (do-nothing 100)671 (play-moves [[:b]])672 (do-nothing 40)673 (play-moves [[:b]])674 (advance [:b] [:start :b])675 (menu [[:a] ↑ ↑ ↑ ↑ ↑ ; get fifth pokemon676 [:a] ↓ [:a] ; and corrupt the677 ↓ ↓ ↓ ↓ ↓ [:a]]) ; item list again by678 ; switching it to679 ))) ; tenth place.683 (defn-memo viridian-store->viridian-poke-center684 ([] (viridian-store->viridian-poke-center685 (corrupt-item-list-again)))686 ([script]687 (->> script688 (do-nothing 100)689 (play-moves [[:b]])690 (do-nothing 100)691 (play-moves [[:b]])692 (do-nothing 40)693 ;; leave store694 (walk [↓ ↓695 → ↓ ↓])696 (walk [← ← ← ←697 ↓ ↓ ↓ ↓ ↓ ↓698 ← ← ← ↑]))))700 (defn-memo to-poke-center-computer701 ([] (to-poke-center-computer702 (viridian-store->viridian-poke-center)))703 ([script]704 (->> script705 (walk [→ →706 ↑ ↑ ↑707 → → → → → → → → → ↑])708 (do-nothing 1))))710 (defn-memo begin-deposits711 ([] (begin-deposits712 (to-poke-center-computer)))713 ([script]714 (->> script715 ;; access PC716 (scroll-text 2)718 ;; access item storage719 (menu [[:a] [:d] [:a]])720 (scroll-text 2)722 ;; begin deposit723 (menu [[:d] [:a]])724 (do-nothing 40))))727 (defn multiple-times728 ([n command args script]729 (reduce (fn [script _]730 (apply command (concat args [script])))731 script732 (range n)))733 ([n command script]734 (multiple-times n command [] script)))736 (defn deposit-n-items737 [n script]738 (->> script739 (do-nothing 100)740 (play-moves [[:a]])741 (do-nothing 80)742 (multiple-times743 (dec n)744 (fn [script]745 (->> script746 (play-moves [[:u]])747 (do-nothing 1))))748 (play-moves [[:a]])749 (scroll-text)))751 (defn deposit-one-item752 [script]753 (->> script754 (do-nothing 100)755 (play-moves [[:a]])756 (do-nothing 80)757 (play-moves [[:a]])758 (scroll-text)))760 (defn-memo create-header761 ([] (create-header (begin-deposits)))762 ([script]763 (->> script764 (multiple-times 33 deposit-one-item)765 (do-nothing 1))))767 (defn bootstrap-init []768 [(read-moves "bootstrap-init")769 (read-state "bootstrap-init")])771 (defn create-bootstrap-program772 ([] (create-bootstrap-program773 (create-header)))774 ([script]775 (->> script776 (do-nothing 120)777 (menu [↓ ↓ ↓ ↓ ↓ ↓ ↓])778 ;;(deposit-n-items 33)780 (menu (repeat 17 ↓))784 (do-nothing 1))))787 ("d572" "d573" "d574" "d575" "d576" "d577" "d58b" "d58e" "d58f" "ff80" "ff82" "ff84" "ff86" "ff87" "ff89")790 (defn test-pc-item-program []791 (-> (read-state "bootstrap-init")792 (set-memory pc-item-list-start 50)793 (set-memory-range795 (inc pc-item-list-start)796 (flatten797 [798 (repeat799 28800 [0xFF 0x01])801 [;; second part of item manipulation program802 0x00 ;; this starts at address 0xD56C803 0x2A ;; save (HL)=(target) to A, increment HL805 0x00806 0x47 ;; save A to B808 0x00809 0x3A ;; save (target+1) to A, decrement HL811 0x00812 0x22 ;; A -> target, increment HL [(target+1) -> target]814 0x00815 0x70 ;; load B into target+1 [(target) -> target+1]817 0x00818 0xC3 ;; first part of absolute jump820 0x0C ;; return control to pokemon kernel821 0x5F]822 (repeat823 5824 [0xFF 0x01])826 [;; first part of item manipulation program827 0x00828 0x21 ;; load target into HL830 0x94 ;; this is the target address831 0xD5833 0x00 ;; relative jump back to first part834 0x18836 0xE1 ;; of program837 0x01839 0xFF ;; spacer840 0x01842 0x04 ;; target ID (pokeball)843 0x3E ;; target Quantity (lemonade)844 ]]))))