]> git.localhorst.tv Git - blank.git/commitdiff
fix some inline TODOs
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 17 Aug 2015 09:23:27 +0000 (11:23 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 17 Aug 2015 13:30:52 +0000 (15:30 +0200)
src/ai/Spawner.cpp
src/io/WorldSave.cpp
src/io/token.cpp
src/model/geometry.hpp
src/model/shape.cpp
src/world/World.cpp

index e5bc68f9d97461d2396de2076b338f025c0d967e..fd449c9a99b8698d9250fe7e044bd09ba782ce11 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "Chaser.hpp"
 #include "RandomWalk.hpp"
+#include "../world/BlockLookup.hpp"
 #include "../world/BlockType.hpp"
 #include "../world/BlockTypeRegistry.hpp"
 #include "../world/Entity.hpp"
@@ -13,7 +14,7 @@ namespace blank {
 Spawner::Spawner(World &world)
 : world(world)
 , controllers()
-, timer(8096)
+, timer(64)
 , despawn_range(128 * 128)
 , spawn_distance(16 * 16)
 , max_entities(16)
@@ -86,12 +87,14 @@ void Spawner::TrySpawn() {
                return;
        }
 
-       // block check
-       // TODO: avoid force load, abort spawn if chunk unavailble
-       Chunk &tgt_chunk = world.Next(world.PlayerChunk(), chunk);
-       // TODO: don't use visibility for spawn check
-       //       also, check for more than one block space
-       if (tgt_chunk.Type(tgt_chunk.BlockAt(pos)).visible) {
+       // check if the spawn block and the one above it are loaded and inhabitable
+       BlockLookup spawn_block(&world.PlayerChunk(), chunk * Chunk::Extent() + pos);
+       if (!spawn_block || spawn_block.GetType().collide_block) {
+               return;
+       }
+
+       BlockLookup head_block(spawn_block.Next(Block::FACE_UP));
+       if (!head_block || head_block.GetType().collide_block) {
                return;
        }
 
index d90bce1654c4c5b0e1745043e328e8746d3e92c2..a08d69c3c288784ac312b84c32cdb461c209baa4 100644 (file)
@@ -30,8 +30,6 @@ bool WorldSave::Exists() const noexcept {
 
 
 void WorldSave::Read(World::Config &conf) const {
-       cout << "reading world save" << endl;
-
        ifstream in(conf_path);
        if (!in) {
                throw runtime_error("failed to open world config");
@@ -71,8 +69,6 @@ void WorldSave::Read(World::Config &conf) const {
 }
 
 void WorldSave::Write(const World::Config &conf) const {
-       cout << "writing world save" << endl;
-
        if (!make_dirs(root_path)) {
                throw runtime_error("failed to create world save directory");
        }
index db5c986fb32f5e53d71272d8cb21760f2ec67e0e..76a9c2f355e42a54f26f758b3bd76466160fc5aa 100644 (file)
@@ -32,7 +32,7 @@ void Tokenizer::ReadToken() {
 
        istream::sentry s(in);
        if (!s) {
-               // TODO: error?
+               throw runtime_error("read past the end of stream");
                return;
        }
 
@@ -47,7 +47,7 @@ void Tokenizer::ReadToken() {
                case ',': case '=':
                        current.type = Token::Type(c);
                        break;
-               case '+': case '-':
+               case '+': case '-': case '.':
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
                        in.putback(c);
@@ -71,7 +71,7 @@ void Tokenizer::ReadToken() {
 namespace {
 
 bool is_num_char(istream::char_type c) {
-       return isdigit(c)
+       return isxdigit(c)
                || c == '.'
                || c == '-'
                || c == '+'
index f1b3762d2905ff650ae44c435bd2b4cfdf1cfbaa..f9f87c4f9d14462f31af92b16247e5a6aad584e9 100644 (file)
@@ -25,6 +25,19 @@ constexpr float rad2deg(float r) {
 }
 
 
+template<class T>
+T manhattan_distance(const glm::tvec3<T> &a, const glm::tvec3<T> &b) {
+       glm::tvec3<T> diff(abs(a - b));
+       return diff.x + diff.y + diff.z;
+}
+
+template<class T>
+T manhattan_radius(const glm::tvec3<T> &v) {
+       glm::tvec3<T> a(abs(v));
+       return std::max(a.x, std::max(a.y, a.z));
+}
+
+
 struct AABB {
        glm::vec3 min;
        glm::vec3 max;
index aeea644431107535c9a687ff2de73d4a69a7c35f..c2d82613eff27d416fe7697d0a07da81eca183ed 100644 (file)
@@ -403,8 +403,6 @@ StairShape::StairShape(const AABB &bb, const glm::vec2 &clip)
                 8,  9,  9, 11, 11, 10, 10 , 8, // top
                 0,  8,  4, 10,  2,  6, // verticals, btf
                 1,  9,  5, 11,  3,  7,
-       //       5,  8,  7, 10,
-       //       1,  9,  3, 11,
        });
 }
 
@@ -448,11 +446,34 @@ bool StairShape::Intersects(
        const glm::mat4 &M,
        const AABB &box,
        const glm::mat4 &box_M,
-       float &depth,
+       float &dist,
        glm::vec3 &normal
 ) const noexcept {
-       // TODO: this is wrong, but simple. so for now will have to do
-       return Intersection(bot, M, box, box_M, depth, normal) || Intersection(top, M, box, box_M, depth, normal);
+       bool top_hit, bot_hit;
+       float top_dist, bot_dist;
+       glm::vec3 top_normal, bot_normal;
+
+       top_hit = Intersection(bot, M, box, box_M, top_dist, top_normal);
+       bot_hit = Intersection(top, M, box, box_M, bot_dist, bot_normal);
+
+       if (top_hit) {
+               if (bot_hit && bot_dist < top_dist) {
+                       dist = bot_dist;
+                       normal = bot_normal;
+                       return true;
+               } else {
+                       dist = top_dist;
+                       normal = top_normal;
+                       return true;
+               }
+               return true;
+       } else if (bot_hit) {
+               dist = bot_dist;
+               normal = bot_normal;
+               return true;
+       } else {
+               return false;
+       }
 }
 
 }
index 3d3eb6c3d9ba11a6aebc685e01480dca6b6e773f..1e372e753d8c82257fb7bcd34fe6295c11e70e78 100644 (file)
@@ -99,9 +99,12 @@ bool World::Intersection(const Entity &e, std::vector<WorldCollision> &col) {
        AABB box = e.Bounds();
        glm::mat4 M = e.Transform(player->ChunkCoords());
        bool any = false;
-       // TODO: this only needs to check the chunks surrounding the entity's chunk position
-       //       need find out if that is quicker than the rough chunk bounds test
        for (Chunk &cur_chunk : chunks.Loaded()) {
+               if (manhattan_radius(cur_chunk.Position() - e.ChunkCoords()) > 1) {
+                       // chunk is not one of the 3x3x3 surrounding the entity
+                       // since there's no entity which can extent over 16 blocks, they can be skipped
+                       continue;
+               }
                if (cur_chunk.Intersection(box, M, cur_chunk.Transform(player->ChunkCoords()), col)) {
                        any = true;
                }