# HG changeset patch # User Steve Losh # Date 1312659538 14400 # Node ID 669045aca6f9ca750f65a669760117180783a3cb # Parent c41de2845803065ec9f400799ebb33fd731c96c2 Moar. diff -r c41de2845803 -r 669045aca6f9 src/clojurecraft/chunks.clj --- a/src/clojurecraft/chunks.clj Thu Aug 04 00:22:22 2011 -0400 +++ b/src/clojurecraft/chunks.clj Sat Aug 06 15:38:58 2011 -0400 @@ -8,18 +8,20 @@ [(bit-shift-right x 4) (bit-shift-right z 4)]) -(defn block-index-in-chunk [x y z] - [(bit-and x 15) - (bit-and y 127) - (bit-and z 15)]) +(defn block-index-in-chunk + "Return the index of the block at given world coordinates in the chunk data arrays." + [x y z] + (let [ix (bit-and x 15) + iy (bit-and y 127) + iz (bit-and z 15)] + (+ iy (* iz 128) (* ix 128 16)))) (defn block-from-chunk [x y z chunk] - (let [[ix iy iz] (block-index-in-chunk x y z) - i (+ y (* z 128) (* x 128 16)) - block-type (get (:types chunk) i) - block-meta (get (:metadata chunk) i) - block-light (get (:light chunk) i) - block-sky-light (get (:sky-light chunk) i)] + (let [i (block-index-in-chunk x y z) + block-type (get (:types @chunk) i) + block-meta (get (:metadata @chunk) i) + block-light (get (:light @chunk) i) + block-sky-light (get (:sky-light @chunk) i)] (Block. [x y z] (block-types (int block-type)) block-meta @@ -27,9 +29,9 @@ block-sky-light))) (defn chunk-containing [x z chunks] - (chunks (coords-of-chunk-containing x z))) + (@chunks (coords-of-chunk-containing x z))) -(defn -block [x y z chunks] +(defn- -block [x y z chunks] (block-from-chunk x y z (chunk-containing x z chunks))) (defn block [bot x y z] @@ -38,17 +40,17 @@ (defn block-rel [bot x y z] (block bot (int (+ (:x (:loc @(:player bot))) x)) - (int (+ (:y (:loc @(:player bot))) y)) + (+ 1 (int (+ (:y (:loc @(:player bot))) y))) (int (+ (:z (:loc @(:player bot))) z)))) -(defn block-standing [bot] +(defn block-standing-in [bot] (block bot (int (:x (:loc @(:player bot)))) - (int (- (:y (:loc @(:player bot))) 0)) + (int (:y (:loc @(:player bot)))) (int (:z (:loc @(:player bot)))))) (defn current [bot] (chunk-containing (int (:x (:loc @(:player bot)))) (int (:z (:loc @(:player bot)))) - @(:chunks (:world bot)))) + (:chunks (:world bot)))) diff -r c41de2845803 -r 669045aca6f9 src/clojurecraft/core.clj --- a/src/clojurecraft/core.clj Thu Aug 04 00:22:22 2011 -0400 +++ b/src/clojurecraft/core.clj Sat Aug 06 15:38:58 2011 -0400 @@ -69,7 +69,7 @@ new-velocity])) (defn should-apply-gravity? [bot] - (non-solid-blocks (l :type (chunks/block-standing bot)))) + (non-solid-blocks (:type (chunks/block-standing-in bot)))) (defn update-location [bot] (when (chunks/current bot) diff -r c41de2845803 -r 669045aca6f9 src/clojurecraft/in.clj --- a/src/clojurecraft/in.clj Thu Aug 04 00:22:22 2011 -0400 +++ b/src/clojurecraft/in.clj Sat Aug 06 15:38:58 2011 -0400 @@ -371,7 +371,7 @@ (defn- -read-packet-mapchunk-decode [predata data-ba] (let [len (* (:sizex predata) (:sizey predata) (:sizez predata)) data (into [] data-ba) - block-types (subvec data 0 len) + block-types (byte-array (map byte (subvec data 0 len))) data (subvec data len)] (let [[block-metadata data] (-parse-nibbles len data) [block-light data] (-parse-nibbles len data) @@ -390,6 +390,41 @@ (.end decompressor) buffer)) +(defn- -update-chunk-data-array [arr new-data start-index] + (println "Updating chunk data array of size " (alength arr) " with new data of size " (count new-data) " beginning at " start-index) + (let [update-slot #(aset arr %1 (get new-data %2))] + (dorun (map update-slot + (range start-index (count new-data)) + (range (count new-data)))))) + + +(defn- -get-or-make-chunk [chunks coords] + (let [CHUNK-ARRAY-LEN (* 16 16 128)] + (or (@chunks coords) + (let [chunk (ref (Chunk. (byte-array CHUNK-ARRAY-LEN) + (byte-array CHUNK-ARRAY-LEN) + (byte-array CHUNK-ARRAY-LEN) + (byte-array CHUNK-ARRAY-LEN)))] + (alter chunks assoc coords chunk) + chunk)))) + +(defn- -update-world-with-data [{{chunks :chunks} :world} x y z types meta light sky] + (dosync (let [chunk-coords (coords-of-chunk-containing x z) + chunk (-get-or-make-chunk chunks chunk-coords) + new-types (byte-array (:types @chunk)) + new-meta (byte-array (:metadata @chunk)) + new-light (byte-array (:light @chunk)) + new-sky (byte-array (:sky-light @chunk)) + start-index (block-index-in-chunk x y z)] + (-update-chunk-data-array new-types types start-index) + (-update-chunk-data-array new-meta meta start-index) + (-update-chunk-data-array new-light light start-index) + (-update-chunk-data-array new-sky sky start-index) + (alter chunk assoc :types new-types) + (alter chunk assoc :metadata new-meta) + (alter chunk assoc :light new-light) + (alter chunk assoc :skylight new-sky)))) + (defn- read-packet-mapchunk [bot conn] (let [predata (assoc {} :x (-read-int conn) @@ -400,17 +435,26 @@ :sizez (+ 1 (-read-byte conn)) :compressedsize (-read-int conn))] (let [decompressed-data (-read-packet-mapchunk-chunkdata conn predata) - decoded-data (-read-packet-mapchunk-decode predata decompressed-data)] - (when (and (= (:sizex predata) 16) ; TODO: Handle partial chunks at some point. - (= (:sizey predata) 128) - (= (:sizez predata) 16)) - (let [[types meta light sky] decoded-data - chunk (Chunk. types meta light sky) - chunk-coords (coords-of-chunk-containing (:x predata) (:z predata))] - (dosync (alter (:chunks (:world bot)) assoc chunk-coords chunk)))) + decoded-data (-read-packet-mapchunk-decode predata decompressed-data) + [types meta light sky] decoded-data] + (-update-world-with-data bot + (:x predata) (:y predata) (:z predata) + types meta light sky) (assoc predata :data decompressed-data)))) +(defn -update-single-block [bot x y z type meta] + (println "Altering block " x y z " to be " (block-types (int type))) + (dosync (let [chunk (chunk-containing x z (:chunks (:world bot))) + new-types (byte-array (:types @chunk)) + new-meta (byte-array (:metadata @chunk)) + idx (block-index-in-chunk x y z)] + (when chunk + (aset new-types idx (byte type)) + (aset new-meta idx (byte meta)) + (alter chunk assoc :types new-types) + (alter chunk assoc :meta new-meta))))) + (defn- read-packet-multiblockchange [bot conn] (let [prearrays (assoc {} :chunkx (-read-int conn) @@ -422,12 +466,17 @@ :metadataarray (-read-bytearray conn (:arraysize prearrays))))) (defn- read-packet-blockchange [bot conn] - (assoc {} - :x (-read-int conn) - :y (-read-byte conn) - :z (-read-int conn) - :blocktype (-read-byte conn) - :blockmetadata (-read-byte conn))) + (let [data (assoc {} + :x (-read-int conn) + :y (-read-byte conn) + :z (-read-int conn) + :blocktype (-read-byte conn) + :blockmetadata (-read-byte conn))] + (-update-single-block bot + (:x data) (:y data) (:z data) + (:blocktype data) (:blockmetadata data)) + data)) + (defn- read-packet-playnoteblock [bot conn] (assoc {}