# HG changeset patch # User Robert McIntyre # Date 1334058967 18000 # Node ID 143a2dfb31773b3eb826b7bfdf88c11d605e01e9 # Parent abcc522a3242735d84ffde8724f7d617bc8cd3c3# Parent a6f212ae29a3dfabe155a26b6fd3a98d9bbd8427 merge diff -r a6f212ae29a3 -r 143a2dfb3177 clojure/com/aurellem/gb/items.clj --- a/clojure/com/aurellem/gb/items.clj Mon Apr 09 03:46:04 2012 -0500 +++ b/clojure/com/aurellem/gb/items.clj Tue Apr 10 06:56:07 2012 -0500 @@ -179,7 +179,7 @@ 0xFC :TM52 ;; "fly" 0xFD :TM53 ;; "surf" 0xFE :TM54 ;; "strength" - 0xFF :end-of-list-sentinel ;; also "flash" + 0xFF :TM55 ;; "flash" (also end-of-list-sentinel) )) (def item-name->item-code @@ -198,10 +198,15 @@ 2 raw-inventory))) -(defn inventory [^SaveState state] - (let [items (item-list state)] - (raw-inventory->inventory - (next (take-while (partial not= 255) items))))) +(defn total-held-items [state] + (aget (memory state) item-list-start)) + +(defn inventory + ([^SaveState state] + (let [items (item-list state)] + (raw-inventory->inventory + (take (* 2 (total-held-items state)) (next items))))) + ([] (inventory @current-state))) (defn print-inventory ([] (print-inventory @current-state)) @@ -231,7 +236,7 @@ (map (fn [[item-name quantity]] [(item-name->item-code item-name item-name) quantity]) inventory) - [(item-name->item-code :end-of-list-sentinel)]))) + [(item-name->item-code :TM55)]))) (defn set-inv-mem [^SaveState state inv-codes] (set-memory-range state item-list-start diff -r a6f212ae29a3 -r 143a2dfb3177 clojure/com/aurellem/run/bootstrap_0.clj --- a/clojure/com/aurellem/run/bootstrap_0.clj Mon Apr 09 03:46:04 2012 -0500 +++ b/clojure/com/aurellem/run/bootstrap_0.clj Tue Apr 10 06:56:07 2012 -0500 @@ -370,6 +370,16 @@ (aget (memory state) item-quantity-selected-address)) ([] (item-quantity-selected @current-state))) +(defn wait-until + ([script-fn default-key script] + (let [wait-time + (- (dec (count (first (script-fn script)))) + (count (first script)))] + (println "wait-time" wait-time) + (play-moves (repeat wait-time default-key) script))) + ([script-fn script] + (wait-until script-fn [] script))) + (defn set-cursor-relative "Assumes the arrow keys currently control the cursor. Moves the cursor n steps relative to its current @@ -382,21 +392,32 @@ [] key list-offset) script))) +(defn set-cursor* + [n [moves state :as script]] + (let [current-position (list-offset state) + difference (- n current-position)] + (set-cursor-relative difference script))) + (defn set-cursor "Assumes the arrow keys currently control the cursor. Sets the cursor to the desired position. Works for any menu that uses a cursor including the start menu, item menu, pokemon menu, and battle menu." [n [moves state :as script]] - (let [current-position (list-offset state) - difference (- n current-position)] - (println difference) - (set-cursor-relative difference script))) + (->> script + (wait-until (partial set-cursor-relative 1)) + (set-cursor* n))) -(defn set-quantity +(defn first-character [state] + (aget (memory state) text-address)) + +(defn first-20-characters [state] + (subvec (vec (memory state)) text-address (+ 20 text-address))) + +(defn set-quantity* "Set the quantity of an item to buy or sell to the desired value using the fewest possible button presses." - ([total-quantity desired-quantity [moves state :as script]] + [total-quantity desired-quantity [moves state :as script]] (cond (= desired-quantity 1) (do (println "1 of 1") script) (= total-quantity desired-quantity) (do (println "get everything!") @@ -421,19 +442,19 @@ script)) script (range (Math/abs best-path)))))) + +(defn set-quantity + ([total-quantity desired-quantity [moves state :as script]] + (->> script (wait-until (partial delayed-difference [] [:a] 100 + first-20-characters)) + (set-quantity* total-quantity desired-quantity))) ([desired-quantity [moves state :as script]] (set-quantity 99 desired-quantity script))) + (defn activate-start-menu [script] (first-difference [:b] [:b :start] AF script)) -(defn wait-until [script-fn script] - (let [wait-time - (- (dec (count (first (script-fn script)))) - (count (first script)))] - (println "wait-time" wait-time) - (do-nothing wait-time script))) - (defn select-menu-entry ([test-direction [moves state :as script]] (->> script diff -r a6f212ae29a3 -r 143a2dfb3177 clojure/com/aurellem/run/bootstrap_1.clj --- a/clojure/com/aurellem/run/bootstrap_1.clj Mon Apr 09 03:46:04 2012 -0500 +++ b/clojure/com/aurellem/run/bootstrap_1.clj Tue Apr 10 06:56:07 2012 -0500 @@ -108,7 +108,7 @@ 0x01 ;; (item-hack) will never reach this instruction ] - (repeat 8 [0x00 0x01]) + (repeat 8 [0x00 0x01]);; these can be anything [;; jump to actual program 0x00 @@ -130,7 +130,7 @@ 0xE9 ;; jump to (HL) ]]))) -(defn view-desired-item-layout [] +(defn print-desired-item-layout [] (clojure.pprint/pprint (raw-inventory->inventory (pc-item-writer-program)))) @@ -182,35 +182,20 @@ finish-title (walk [← ← ↑ ← ↑ ↑ ↑])))) -(defn-memo bootstrap-corrupt-save - ([] (bootstrap-corrupt-save (to-room-pc))) - ([script] - (->> script - (do-save-corruption 2) - (corrupt-item-list 0) - close-all-menus))) +;; (defn wait-for-quantity +;; [[moves state :as script]] +;; (if (not= (item-quantity-selected state) 1) +;; (repeat-until-different [] item-quantity-selected script) +;; script)) -(defn-memo begin-initial-deposits - ([] (begin-initial-deposits - (bootstrap-corrupt-save))) - ([script] - (->> script - (first-difference [] [:a] AF) - (scroll-text) - (set-cursor 1) - select-menu-entry))) +;; TODO use this: +;;(wait-until (partial set-cursor-relative 1)) -(defn wait-for-quantity - [[moves state :as script]] - (if (not= (item-quantity-selected state) 1) - (repeat-until-different [] item-quantity-selected script) - script)) - -(defn wait-for-cursor - [[moves state :as script]] - (if (not= (list-offset state) 0) - (repeat-until-different [] list-offset script) - script)) +;; (defn wait-for-cursor +;; [[moves state :as script]] +;; (if (not= (list-offset state) 0) +;; (repeat-until-different [] list-offset script) +;; script)) (defn deposit-held-item [n quantity [moves state :as script]] (let [total-quantity (second (nth-item state n))] @@ -218,7 +203,7 @@ (->> script (set-cursor n) (select-menu-entry 1) - (wait-for-quantity) + ;;(wait-for-quantity) (set-quantity total-quantity quantity) (delayed-difference [] [:a] 100 #(search-string % "stored")) (scroll-text)))) @@ -226,10 +211,10 @@ (defn sell-held-item [n quantity [moves state :as script]] (let [total-quantity (second (nth-item state n))] (->> script - (wait-for-cursor) ;; when selling, the cursor always + ;;(wait-for-cursor) ;; when selling, the cursor always (set-cursor n) ;; returns to the top of the list. (select-menu-entry 1) - (wait-for-quantity) + ;;(wait-for-quantity) (set-quantity total-quantity quantity) (delayed-difference [] [:a] 100 current-depth) (play-moves (repeat 20 [:b])) @@ -241,7 +226,7 @@ (->> script (set-cursor n) (select-menu-entry 1) - (wait-for-quantity) + ;;(wait-for-quantity) (set-quantity total-quantity quantity) (delayed-difference [] [:a] 100 #(search-string % "Withdrew")) (scroll-text)))) @@ -253,7 +238,7 @@ (select-menu-entry 1) (set-cursor-relative 1) (select-menu-entry -1) - (wait-for-quantity) + ;;(wait-for-quantity) (set-quantity total-quantity quantity) (play-moves [[:a]]) (scroll-text) @@ -266,11 +251,57 @@ (set-cursor n) (purchase-item quantity))) +(defn switch-items [item-fn idx-1 idx-2 script] + (->> script + (wait-until select-menu-entry) + (set-cursor idx-1) + (wait-until select-menu-entry) + (play-moves [[][:select][]]) + (set-cursor idx-2) + (delayed-difference [] [:select] 100 + #(item-fn % (list-offset %))))) + +(def switch-pc-items (partial switch-items nth-pc-item)) +(def switch-held-items (partial switch-items nth-item)) + +(defn combine-pc-items [idx-1 script] + (->> script + (switch-pc-items idx-1 (inc idx-1)))) (def desired-zero-quantities (map second (filter (comp (partial = 0) first) (partition 2 (pc-item-writer-program))))) - + +(defn-memo bootstrap-corrupt-save + ([] (bootstrap-corrupt-save (to-room-pc))) + ([script] + (->> script + (do-save-corruption 3) + (corrupt-item-list 0) + close-all-menus))) + +(defn-memo prepare-celadon-warp + ([] (prepare-celadon-warp (bootstrap-corrupt-save))) + ([script] + (->> script + (activate-start-menu) + (set-cursor-relative 1) + (select-menu-entry) + ;; vastly increase text speed while we're here. + (switch-held-items 21 27) + (toss-held-item 35 0xFA) + (close-all-menus)))) + +(defn-memo begin-initial-deposits + ([] (begin-initial-deposits + (prepare-celadon-warp))) + ([script] + (->> script + (first-difference [] [:a] AF) + (scroll-text) + (set-cursor 1) + select-menu-entry))) + (defn-memo initial-deposits ([] (initial-deposits (begin-initial-deposits))) ([script] @@ -284,28 +315,23 @@ close-all-menus))) -(defn-memo prepare-celadon-warp - ([] (prepare-celadon-warp (initial-deposits))) - ([script] - (->> script - (activate-start-menu) - (set-cursor-relative 1) - (select-menu-entry) - (toss-held-item 35 0xFA) - (close-all-menus)))) - - ;;0 -- 256 ;;1 -- 254 ;;2 -- 254 ;;3 -- 255 +(defn activate-home-pc + [script] + (->> script + (delayed-difference [] [:a] + 200 first-character) + (scroll-text))) + (defn-memo restore-items - ([] (restore-items (prepare-celadon-warp))) + ([] (restore-items (initial-deposits))) ([script] (->> script - (first-difference [] [:a] AF) - (scroll-text) + activate-home-pc (select-menu-entry) (widthdraw-pc-item 0 1) ;;(widthdraw-pc-item 0 99) @@ -384,7 +410,7 @@ [script] (->> script (delayed-difference [] [:a] 100 - #(aget (memory %) text-address)))) + first-character))) (defn-memo get-money-floor-two ([] (get-money-floor-two (go-to-floor-two))) @@ -401,7 +427,7 @@ ([] (floor-two-TMs (get-money-floor-two))) ([script] (->> script - (wait-for-cursor) + (set-cursor 0) (select-menu-entry) (buy-item 2 98) ;; TM02 (razor-wind) (buy-item 4 71) ;; TM37 (doubleteam) @@ -421,7 +447,6 @@ ([] (floor-two-more-money (floor-two-TMs))) ([script] (->> script - (wait-for-cursor) (set-cursor 1) (select-menu-entry) (sell-held-item 0 1) @@ -524,7 +549,6 @@ (do-nothing 20) (play-moves [[:a][:a]]) scroll-text - (wait-for-cursor) (set-cursor n) select-menu-entry close-menu)) @@ -542,19 +566,21 @@ ([] (get-TM13 (roof-drinks))) ([script] (->> script - (walk [← ← ← ← ← ← ↓]) - (play-moves [[][:a][:a][]]) + ;;(walk [← ← ← ← ← ← ↓]) + (walk [↓ ↓ ↓ ← ← ← ← ← ←]) + (play-moves [[][][][][:a][:a][]]) (scroll-text 3) select-menu-entry select-menu-entry (scroll-text 6) close-menu))) -(defn to-celadon-poke-center +(defn-memo to-celadon-poke-center ([] (to-celadon-poke-center (get-TM13))) ([script] (->> script - (walk [↑ → → → → → → → → → ↑]) ; leave roof + ;;(walk [↑ → → → → → → → → → ↑]) ; leave roof + (walk [→ → → → → → → → → ↑ ↑ ↑ ↑]) (walk [↓ ← ← ← ← ↓ ↓ ↓ ← ← ← ← ← ↑ ↑ ↑ ← ← ↑]) ; to elevator @@ -568,3 +594,333 @@ (walk [↑ ↑ ↑ ↑]) ; enter poke center (walk [↑ ↑ ↑ → → → → → → → → → →]) ; to computer (turn ↑)))) + +(defn activate-rlm-pc [script] + (->> script + talk + scroll-text + ;;wait-for-cursor + (set-cursor 1) + select-menu-entry + (scroll-text 2))) + +(defn begin-deposit [script] + (->> script + (set-cursor 1) + select-menu-entry)) + +(defn begin-withdraw [script] + (->> script + (set-cursor 0) + (select-menu-entry))) + +(defn deposit-held-item-named + [item-name quantity [moves state :as script]] + (let [index (count + (take-while + (fn [[name quant]] + (or (not= name item-name) + (< quant quantity))) + (inventory state)))] + (println "index" index) + (deposit-held-item index quantity script))) + +(defn open-held-items + [script] + (->> script + select-menu-entry)) + +(defn to-held-items + [script] + (->> script + close-menu + close-menu + end-text;;; grr + + activate-start-menu + open-held-items)) + +(defn toss-pc-item [n quantity [moves state :as script]] + (let [total-quantity (second (nth-pc-item state n))] + (->> script + (set-cursor n) + (select-menu-entry 1) + (set-quantity total-quantity quantity) + (delayed-difference [] [:a] 100 #(search-string % "Is")) + (scroll-text) + select-menu-entry + (scroll-text)))) + +(defn-memo hacking-1 + ([] (hacking-1 (to-celadon-poke-center))) + ([script] + (->> script + activate-rlm-pc + begin-deposit + (deposit-held-item-named 0x00 30) + (deposit-held-item-named :TM01 63) + (deposit-held-item-named :awakening 4) + (deposit-held-item-named :thunderstone 98) + (deposit-held-item-named :TM09 55) + (deposit-held-item-named 0x00 55)))) + +(defn-memo hacking-2 + ([] (hacking-2 (hacking-1))) + ([script] + (->> script + (to-held-items) + (toss-held-item 0 166) ;; discard cruft + close-menu + close-menu))) + +(defn-memo hacking-3 + ([] (hacking-3 (hacking-2))) + ([script] + (->> script + activate-rlm-pc + begin-withdraw + (widthdraw-pc-item 0 99) + (widthdraw-pc-item 0 1) + (widthdraw-pc-item 2 0xFE) + (widthdraw-pc-item 3 0xFE) + close-menu))) + +(defn-memo hacking-4 + ([] (hacking-4 (hacking-3))) + ([script] + (->> script + begin-deposit + (deposit-held-item 19 243) + (deposit-held-item-named :lemonade 16) + (deposit-held-item 18 224)))) + +(defn-memo hacking-5 + "clean out the held-item list again" + ([] (hacking-5 (hacking-4))) + ([script] + (->> script + (to-held-items) + (toss-held-item 18 30) + (toss-held-item 17 1) + close-menu + close-menu))) + +(defn-memo hacking-6 + ([] (hacking-6 (hacking-5))) + ([script] + (->> script + activate-rlm-pc + begin-withdraw + (widthdraw-pc-item 4 0xFE) + (widthdraw-pc-item 5 0xFE) + (widthdraw-pc-item 6 0xFE) + close-menu))) + +(defn-memo hacking-7 + ([] (hacking-7 (hacking-6))) + ([script] + (->> script + begin-deposit + (deposit-held-item 19 240) + (deposit-held-item 18 230) + (deposit-held-item-named :parlyz-heal 55) + (deposit-held-item 17 184) + (deposit-held-item 17 40) + (deposit-held-item-named :TM37 71) + (deposit-held-item-named :ice-heal 55) + (deposit-held-item-named :fire-stone 23) + (deposit-held-item-named :burn-heal 12) + ;; as a special case, /don't/ close the menu. + ))) + +(defn-memo hacking-8 + "Clear cruft away from held item list." + ([] (hacking-8 (hacking-7))) + ([script] + (->> script + to-held-items + (toss-held-item 15 1) + (toss-held-item 14 1) + (toss-held-item 13 1) + close-menu + close-menu))) + +(defn-memo hacking-9 + ([] (hacking-9 (hacking-8))) + ([script] + (->> script + activate-rlm-pc + begin-withdraw + (widthdraw-pc-item 7 0xFE) + (widthdraw-pc-item 8 0xFC) + (widthdraw-pc-item 8 1) + (widthdraw-pc-item 8 1) + (widthdraw-pc-item 9 0xFE) + (multiple-times + 7 + (partial combine-pc-items 2)) + close-menu))) + +(defn-memo hacking-10 + ([] (hacking-10 (hacking-9))) + ([script] + (->> script + begin-deposit + (deposit-held-item 17 230) + (deposit-held-item-named :parlyz-heal 55) + (deposit-held-item 14 178) + (deposit-held-item-named :water-stone 29) + (deposit-held-item 14 32) + (deposit-held-item-named :TM18 1) + (deposit-held-item 13 1) + (deposit-held-item 13 191) + (deposit-held-item-named :TM02 98) + (deposit-held-item-named :TM09 1) + close-menu))) + +(defn-memo hacking-11 + ([] (hacking-11 (hacking-10))) + ([script] + (->> script + begin-withdraw + (widthdraw-pc-item 3 0xFE) + (widthdraw-pc-item 4 0xFE) + (widthdraw-pc-item 5 1) + (widthdraw-pc-item 5 1) + (widthdraw-pc-item 5 1) + (widthdraw-pc-item 5 0xFB) + (multiple-times + 3 + (partial combine-pc-items 2)) + close-menu))) + +(defn-memo hacking-12 + ([] (hacking-12 (hacking-11))) + ([script] + (->> script + begin-deposit + (deposit-held-item 18 203) + (deposit-held-item-named :guard-spec 87) + (deposit-held-item-named :guard-spec 24) + (deposit-held-item-named :TM05 1) + (multiple-times + 8 + (partial deposit-held-item 14 1)) + (deposit-held-item 14 55) + (deposit-held-item-named :x-accuracy 58) + (deposit-held-item 14 38) + (deposit-held-item-named :TM13 1) + (deposit-held-item 13 1) + (deposit-held-item 13 233) + close-menu))) + +(defn-memo hacking-13 + ([] (hacking-13 (hacking-12))) + ([script] + (->> script + (set-cursor-relative 1) + (select-menu-entry) + (toss-pc-item 1 1) + (toss-pc-item 0 156) + (toss-pc-item 0 11)))) + +(defn confirm-pattern [] + (let [start-address (inc pc-item-list-start) + target-pattern (pc-item-writer-program) + actual-pattern + (subvec (vec (memory (second (hacking-13)))) + start-address + (+ start-address (count target-pattern)))] + (println target-pattern) + (println actual-pattern) + (= target-pattern actual-pattern))) + +(defn-memo go-to-mansion-for-the-lulz + ([] (go-to-mansion-for-the-lulz (hacking-13))) + ([script] + (->> script + close-menu + close-menu + end-text ;;grr + (walk [↓ ← ← ← ← ← ← ← ← ← ↓ ↓ ↓]) + (walk (repeat 17 ←)) + (walk [↑ → → → → ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑]) + (walk [↓ ← ↑]) + (walk [↓ ↓ ↓ ↓ ↓ ↓ ↓ + ← ← ← ← ↑ ↑ ↑ ← ↑]) + (talk) + (scroll-text 2) + (do-nothing 100) + close-menu))) + +(defn-memo launch-bootstrap-program + ([] (launch-bootstrap-program + (go-to-mansion-for-the-lulz))) + ([script] + (->> script + ;; must corrupt item list again by switching pokemon + activate-start-menu ;; \ + (set-cursor 0) ;; | + select-menu-entry ;; | + select-menu-entry ;; | + (set-cursor 1) ;; | -- switch 9th pokemon + select-menu-entry ;; | with 4th pokemon + (set-cursor 3) ;; | + select-menu-entry ;; | + close-menu ;; / + ;; now, open items and set map-function to + ;; the program inside the item-computer. + (set-cursor 1) + (select-menu-entry) + (toss-held-item 22 12) + (switch-held-items 22 40) + close-all-menus))) + +(defn no-consecutive-repeats? [seq] + (not (contains? (set(map - seq (rest seq))) 0))) + +(defn byte->nybbles [byte] + [(bit-shift-right byte 4) (bit-and byte 0x0F)]) + +(defn bootstrap-pattern + "Given an assembly sequence, generate the keypresses required to + create that sequence in memory using the pc-item-writer + program. The assembly must not have any consecutive repeating + nybbles." + [assembly] + (let [nybbles (flatten (map byte->nybbles assembly)) + moves (map (comp buttons (partial - 15)) nybbles) + header (map buttons + (concat (repeat + 50 + (- 15 (first nybbles))) + [(first nybbles)])) + tail (map buttons + (take + (- 201 (count moves)) + (interleave (repeat 100 (last nybbles)) + (repeat 1000 (- 15 (last nybbles))))))] + (assert (no-consecutive-repeats? nybbles)) + (concat header moves tail))) + +(def increasing-pattern [0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF]) + +(defn test-pattern-writing + ([] (test-pattern-writing increasing-pattern)) + ([pattern] + (let [moves (bootstrap-pattern pattern) + pattern-insertion + (->> (launch-bootstrap-program) + (play-moves + (take 100 moves)))] + (println "Input Pattern:") + (apply println (map #(format "0x%02X" %) pattern)) + (println "\nMemory Listing:") + (print-listing (second pattern-insertion) + 0xD162 (+ 0xD162 (count pattern))) + (= (subvec (vec (memory (second pattern-insertion))) + 0xD162 (+ 0xD162 (count pattern))) + pattern)))) + + + \ No newline at end of file diff -r a6f212ae29a3 -r 143a2dfb3177 moves/temp.vbm Binary file moves/temp.vbm has changed