--- 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))))
--- 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)
--- 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 {}