# HG changeset patch # User Steve Losh # Date 1313723713 14400 # Node ID d8fa70c915850c483f70bded6abd06a7426d4131 # Parent b1007d01decd3a33cd5ec4e62fadf8745252fbc2 Delay and force chunks. diff -r b1007d01decd -r d8fa70c91585 src/clojurecraft/chunks.clj --- 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))) diff -r b1007d01decd -r d8fa70c91585 src/clojurecraft/core.clj --- 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] diff -r b1007d01decd -r d8fa70c91585 src/clojurecraft/in.clj --- 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 {} diff -r b1007d01decd -r d8fa70c91585 src/clojurecraft/physics.clj --- 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] diff -r b1007d01decd -r d8fa70c91585 src/clojurecraft/util.clj --- 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 ----------------------------------------------------------------------------