--- a/src/clojurecraft/chunks.clj Tue Aug 16 20:22:42 2011 -0400
+++ b/src/clojurecraft/chunks.clj Thu Aug 18 23:15:13 2011 -0400
@@ -4,6 +4,14 @@
(:require [clojurecraft.data])
(:import [clojurecraft.data Block]))
+(defn- get-chunk
+ "Get a chunk, making sure it has been forced."
+ [chunks coords]
+ (let [possible-chunk (@chunks coords)]
+ (when possible-chunk
+ (force @possible-chunk)
+ possible-chunk)))
+
(defn coords-of-chunk-containing [x z]
[(bit-shift-right x 4)
(bit-shift-right z 4)])
@@ -18,10 +26,10 @@
(defn block-from-chunk [x y z chunk]
(let [i (block-index-in-chunk x y z)
- block-type (aget (:types @chunk) i)
- block-meta (aget (:metadata @chunk) i)
- block-light (aget (:light @chunk) i)
- block-sky-light (aget (:sky-light @chunk) i)]
+ block-type (aget ^bytes (:types (force @chunk)) i)
+ block-meta (aget ^bytes (:metadata (force @chunk)) i)
+ block-light (aget ^bytes (:light (force @chunk)) i)
+ block-sky-light (aget ^bytes (:sky-light (force @chunk)) i)]
(Block. [x y z]
(block-types (int block-type))
block-meta
@@ -29,7 +37,7 @@
block-sky-light)))
(defn chunk-containing [x z chunks]
- (@chunks (coords-of-chunk-containing x z)))
+ (get-chunk chunks (coords-of-chunk-containing x z)))
(defn- -block [x y z chunks]
(block-from-chunk x y z (chunk-containing x z chunks)))
--- a/src/clojurecraft/core.clj Tue Aug 16 20:22:42 2011 -0400
+++ b/src/clojurecraft/core.clj Thu Aug 18 23:15:13 2011 -0400
@@ -52,7 +52,8 @@
(loop [prevs [nil nil nil]]
(when (nil? (:exit @conn))
(recur (read-packet bot (get prevs 0) (get prevs 1) (get prevs 2))))))
- (println "done - input handler"))
+ (println "done - input handler")
+ (println "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"))
(defn update-location [bot]
@@ -78,7 +79,8 @@
(.put outqueue [:playerpositionlook location])
(update-location bot))
(Thread/sleep 50))))
- (println "done - location handler"))
+ (println "done - location handler")
+ (println "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"))
(defn output-handler [bot]
(let [conn (:connection bot)
@@ -88,7 +90,8 @@
(when packet
(let [[packet-type, payload] packet]
(write-packet bot packet-type payload))))))
- (println "done - output handler"))
+ (println "done - output handler")
+ (println "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"))
(defn action-handler [bot]
(let [conn (:connection bot)
@@ -97,7 +100,8 @@
(let [action (.poll actionqueue 1 TimeUnit/SECONDS)]
(when action
(force action)))))
- (println "done - action handler"))
+ (println "done - action handler")
+ (println "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"))
(defn connect [server username]
--- a/src/clojurecraft/in.clj Tue Aug 16 20:22:42 2011 -0400
+++ b/src/clojurecraft/in.clj Thu Aug 18 23:15:13 2011 -0400
@@ -8,6 +8,9 @@
(:import [clojurecraft.data Location Entity Chunk])
(:import (java.util.zip Inflater)))
+(def FULL-CHUNK (* 16 16 128))
+(def BLANK-CHUNK-ARRAY (byte-array FULL-CHUNK))
+
; Reading Data ---------------------------------------------------------------------
(defn- -read-byte-bare [conn]
(io!
@@ -367,31 +370,6 @@
(conj nibbles bottom-byte top-byte)
(subvec data 1))))))
-(defn- -read-packet-mapchunk-decode [predata data-ba]
- (let [len (* (:sizex predata) (:sizey predata) (:sizez predata))
- data (into (vector-of :byte) data-ba) ; Make the data a vector for easier parsing.
- block-types (byte-array (subvec data 0 len))
- data (subvec data len)]
- (let [[block-metadata data] (-parse-nibbles len data)
- [block-light data] (-parse-nibbles len data)
- [sky-light data] (-parse-nibbles len data)]
- [block-types block-metadata block-light sky-light])))
-
-(defn- -read-packet-mapchunk-chunkdata [conn predata]
- (let [raw-data (-read-bytearray-bare conn (:compressedsize predata))
- buffer (byte-array (/ (* 5
- (:sizex predata)
- (:sizey predata)
- (:sizez predata)) 2))
- decompressor (Inflater.)]
- (.setInput decompressor raw-data 0 (:compressedsize predata))
- (.inflate decompressor buffer)
- (.end decompressor)
- buffer))
-
-
-(def FULL-CHUNK (* 16 16 128))
-(def BLANK-CHUNK-ARRAY (byte-array FULL-CHUNK))
(defn- -get-or-make-chunk [chunks coords]
(or (@chunks coords)
(let [chunk (ref (Chunk. BLANK-CHUNK-ARRAY
@@ -401,47 +379,82 @@
(alter chunks assoc coords chunk)
chunk)))
-(defn- -update-world-with-data [{{chunks :chunks} :world} x y z ^bytes types meta light sky]
- (dosync (let [chunk-coords (coords-of-chunk-containing x z)
- chunk (-get-or-make-chunk chunks chunk-coords)
- start-index (block-index-in-chunk x y z)]
- (if (= (alength types) FULL-CHUNK)
- (alter chunk assoc ; Short-circuit for speed if we have a full chunk.
- :types types
- :metadata meta
- :light light
- :skylight sky)
- (alter chunk assoc ; Otherwise: sadness.
- :types (replace-array-slice (:types @chunk) start-index types)
- :metadata (replace-array-slice (:metadata @chunk) start-index meta)
- :light (replace-array-slice (:light @chunk) start-index light)
- :skylight (replace-array-slice (:sky-light @chunk) start-index sky))))))
+(defn- -decode-mapchunk [postdata data-ba]
+ (let [len (* (:sizex postdata) (:sizey postdata) (:sizez postdata))
+ data (into (vector-of :byte) data-ba) ; Make the data a vector for easier parsing.
+ block-types (byte-array (subvec data 0 len))
+ data (subvec data len)]
+ (let [[block-metadata data] (-parse-nibbles len data)
+ [block-light data] (-parse-nibbles len data)
+ [sky-light data] (-parse-nibbles len data)]
+ [block-types block-metadata block-light sky-light])))
+
+(defn- -decompress-mapchunk [postdata]
+ (let [buffer (byte-array (/ (* 5
+ (:sizex postdata)
+ (:sizey postdata)
+ (:sizez postdata)) 2))
+ decompressor (Inflater.)]
+ (.setInput decompressor (:raw-data postdata) 0 (:compressedsize postdata))
+ (.inflate decompressor buffer)
+ (.end decompressor)
+ buffer))
+
+(defn- -read-mapchunk-predata [conn]
+ (assoc {}
+ :x (-read-int conn)
+ :y (-read-short conn)
+ :z (-read-int conn)
+ :sizex (+ 1 (-read-byte conn))
+ :sizey (+ 1 (-read-byte conn))
+ :sizez (+ 1 (-read-byte conn))
+ :compressedsize (-read-int conn)))
+
+
+(defn- -chunk-from-full-data [postdata]
+ (let [decompressed-data (-decompress-mapchunk postdata)
+ [types meta light sky] (-decode-mapchunk postdata decompressed-data)] ; Note: These are all byte-array's!
+ (Chunk. types meta light sky)))
+
+(defn- -chunk-from-partial-data [{{chunks :chunks} :world} postdata]
+ (let [x (:x postdata)
+ y (:y postdata)
+ z (:z postdata)
+ decompressed-data (-decompress-mapchunk postdata)
+ [types meta light sky] (-decode-mapchunk postdata decompressed-data) ; Note: These are all byte-array's!
+ chunk-coords (coords-of-chunk-containing x z)
+ chunk (force (-get-or-make-chunk chunks chunk-coords))
+ start-index (block-index-in-chunk x y z)]
+ (Chunk. (replace-array-slice (:types (force @chunk)) start-index types)
+ (replace-array-slice (:metadata (force @chunk)) start-index meta)
+ (replace-array-slice (:light (force @chunk)) start-index light)
+ (replace-array-slice (:sky-light (force @chunk)) start-index sky))))
(defn- read-packet-mapchunk [bot conn]
- (time (let [predata (assoc {}
- :x (-read-int conn)
- :y (-read-short conn)
- :z (-read-int conn)
- :sizex (+ 1 (-read-byte conn))
- :sizey (+ 1 (-read-byte conn))
- :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)
- [types meta light sky] decoded-data] ; Note: These are all byte-array's!
- (-update-world-with-data bot
- (:x predata) (:y predata) (:z predata)
- types meta light sky)
- (assoc predata :data decompressed-data)))))
+ (time (let [predata (-read-mapchunk-predata conn)
+ postdata (assoc predata :raw-data (-read-bytearray-bare conn (:compressedsize predata)))
+ chunk-size (* (:sizex postdata) (:sizey postdata) (:sizez postdata))
+ is-full-chunk (= FULL-CHUNK chunk-size)
+ chunk-coords (coords-of-chunk-containing (:x postdata) (:z postdata))]
+ (dosync (alter (:chunks (:world bot))
+ assoc chunk-coords (if is-full-chunk
+ (ref (delay (-chunk-from-full-data postdata)))
+ (ref (-chunk-from-partial-data bot postdata))))))))
+
+(defn update-delayed [chunk index type meta]
+ (let [chunk (force chunk)]
+ (assoc chunk
+ :types (replace-array-index (:types chunk) index type)
+ :metadata (replace-array-index (:metadata chunk) index meta))))
+
(defn -update-single-block [bot x y z type meta]
- (dosync (let [chunk (chunk-containing x z (:chunks (:world bot)))
- i (block-index-in-chunk x y z)]
- (when chunk
- (alter chunk assoc
- :types (replace-array-index (:types @chunk) i type)
- :metadata (replace-array-index (:metadata @chunk) i meta))))))
+ (dosync
+ (let [chunk (chunk-containing x z (:chunks (:world bot)))
+ i (block-index-in-chunk x y z)]
+ (when chunk
+ (alter chunk update-delayed i type meta)))))
(defn- read-packet-blockchange [bot conn]
(let [data (assoc {}
--- a/src/clojurecraft/physics.clj Tue Aug 16 20:22:42 2011 -0400
+++ b/src/clojurecraft/physics.clj Thu Aug 18 23:15:13 2011 -0400
@@ -17,7 +17,7 @@
(defn player-bounds [{x :x y :y z :z}]
- [(map floorint [(- x CHAR-RADIUS) y (- z CHAR-RADIUS)])
+ [(map floorint [(- x CHAR-RADIUS) y (- z CHAR-RADIUS)])
(map floorint [(+ x CHAR-RADIUS) (+ y CHAR-HEIGHT-TOP) (+ z CHAR-RADIUS)])])
@@ -32,14 +32,15 @@
(max velocity (* -1 MAX-HORIZONTAL-VELOCITY))))
+(def is-solid (comp not non-solid-blocks :type))
+(defn coords-are-solid [bot [x y z]]
+ (is-solid (chunks/block bot x y z)))
+
(defn collision [bot [min-x min-y min-z] [max-x max-y max-z]]
(let [block-coords (cartesian-product (range min-x (+ 1 max-x))
(range min-y (+ 1 max-y))
- (range min-z (+ 1 max-z)))
- is-solid (comp not non-solid-blocks :type)
- coords-are-solid (fn [[x y z]]
- (is-solid (chunks/block bot x y z)))]
- (any? (map coords-are-solid block-coords))))
+ (range min-z (+ 1 max-z)))]
+ (any? (map coords-are-solid (cycle [bot]) block-coords))))
(defn resolve-collision-y [y velocity]
--- a/src/clojurecraft/util.clj Tue Aug 16 20:22:42 2011 -0400
+++ b/src/clojurecraft/util.clj Thu Aug 18 23:15:13 2011 -0400
@@ -3,13 +3,18 @@
; Logging---------------------------------------------------------------------------
(defmacro l [& body]
`(let [result# (~@body)]
+ (println "=====================================================")
(println result#)
+ (println "=====================================================")
result#))
(defmacro lc [& body]
`(let [result# (~@body)]
+ (println "=====================================================")
(println result#)
+ (println "-----------------------------------------------------")
(println (class result#))
+ (println "=====================================================")
result#))
@@ -40,7 +45,7 @@
(int (Math/floor f)))
(defn any? [s]
- (not (empty? (filter identity s))))
+ (seq (filter identity s)))
; Bytes ----------------------------------------------------------------------------