summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Redman <pawel.redman@gmail.com>2017-11-07 12:06:19 +0100
committerPaweł Redman <pawel.redman@gmail.com>2017-11-07 12:06:19 +0100
commit7471347839f30a85e985891b945a721967fcfb86 (patch)
tree762a37e4792672b0af7a0878b41b828508c91e2a
parentf951af3cfdef3d23fd5875078a29c15ebf9120e9 (diff)
Avoid walking into walls.
-rw-r--r--src/common.hpp2
-rw-r--r--src/game.cpp36
-rw-r--r--src/render.cpp8
-rw-r--r--src/world.cpp53
4 files changed, 88 insertions, 11 deletions
diff --git a/src/common.hpp b/src/common.hpp
index 10fafcf..a301881 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -113,7 +113,7 @@ namespace world {
std::list<entity_t*> get_entities(rectf_t rect, cflags_t cflags);
std::list<entity_t*> get_render_entities(rectf_t rect);
- bool test_rect(rectf_t rect, cflags_t cflags);
+ bool test_rect(const cmodel_t *cmodel, const entity_t *ignore);
void debug_point(sf::Vector2f point);
};
diff --git a/src/game.cpp b/src/game.cpp
index a2f4bbc..e8c179a 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -5,10 +5,19 @@ namespace game {
class unit_t : public world::entity_t {
world::world_t *world;
+ world::cmodel_t make_cmodel(v2f_t at)
+ {
+ world::cmodel_t cmodel;
+
+ cmodel.bounds[0] = at + size[0];
+ cmodel.bounds[1] = at + size[1];
+ cmodel.cflags = cflags;
+
+ return cmodel;
+ }
+
void compute_bounds()
{
- cmodel.bounds[0] = x + size[0];
- cmodel.bounds[1] = x + size[1];
render_bounds[0] = x + render_size[0];
render_bounds[1] = x + render_size[1];
}
@@ -16,6 +25,7 @@ class unit_t : public world::entity_t {
public:
v2f_t x;
rectf_t size, render_size;
+ world::cflags_t cflags;
struct {
bool moving = false;
@@ -30,9 +40,10 @@ public:
world = world_;
x = x_;
move.moving = false;
- cmodel.cflags = 1;
+ cflags = 1;
unlink();
+ cmodel = make_cmodel(x);
compute_bounds();
link(world);
}
@@ -47,7 +58,8 @@ public:
time = 0.15;
while (time > 0.0f) {
- v2f_t delta, next;
+ v2f_t delta, next, x_new;
+ world::cmodel_t cmodel_next;
if (!move.path.size()) {
move.moving = false;
@@ -59,15 +71,25 @@ public:
move.angle = delta.angle();
if (delta.len() >= time) {
- x += delta * time / delta.len();
- break;
+ x_new = x + delta * time / delta.len();
+ time -= delta.len();
} else {
- x = next;
+ x_new = next;
time -= delta.len();
move.path.pop_front();
}
+
+ cmodel_next = make_cmodel(x_new);
+ if (world->test_rect(&cmodel_next, this)) {
+ move.moving = false;
+ break;
+ }
+
+ x = x_new;
+ cmodel = cmodel_next;
}
+
unlink();
compute_bounds();
link(world);
diff --git a/src/render.cpp b/src/render.cpp
index 9fb1625..313bc4d 100644
--- a/src/render.cpp
+++ b/src/render.cpp
@@ -5,7 +5,8 @@
static sf::RectangleShape wot_rect;
static sf::Font font;
-static void draw_tile(sf::RenderWindow *window, v2f_t x, world::tile_t *tile)
+static void draw_tile(sf::RenderWindow *window, v2f_t x, world::tile_t *tile,
+ world::tile_index_t local)
{
sf::Texture *texture;
@@ -30,7 +31,7 @@ static void draw_tile(sf::RenderWindow *window, v2f_t x, world::tile_t *tile)
window->draw(wot_rect);
std::stringstream ss;
- ss << tile->type << ":" << tile->neighbors;
+ ss << "L=" << local;
sf::Text text(ss.str(), font, 20);
text.setPosition(x);
text.setScale(0.005, 0.005);
@@ -42,7 +43,8 @@ static void draw_sector(sf::RenderWindow *window, world::sector_t *sector)
for (ssize_t y = 0; y < SECTOR_SIZE; y++)
for (ssize_t x = 0; x < SECTOR_SIZE; x++)
draw_tile(window, sector->bounds.v[0] + v2f_t(x, y),
- sector->tiles + y * SECTOR_SIZE + x);
+ sector->tiles + y * SECTOR_SIZE + x,
+ world::tile_index_t(x, y));
}
void interface::state_t::render()
diff --git a/src/world.cpp b/src/world.cpp
index 778e463..2339dbf 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -230,6 +230,59 @@ std::list<entity_t*> world_t::get_render_entities(rectf_t rect)
return list;
}
+bool world_t::test_rect(const cmodel_t *cmodel, const entity_t *ignore)
+{
+ static size_t cookie = 0;
+
+ cookie++;
+
+ for (sector_t *sector : get_sectors(cmodel->bounds)) {
+ rect_t<coord_t, 2> bounds;
+ tile_index_t index;
+
+ bounds[0] = (cmodel->bounds[0] - sector->bounds[0]).floor();
+ bounds[1] = (cmodel->bounds[1] - sector->bounds[0]).floor();
+
+ if (bounds[0][0] < 0)
+ bounds[0][0] = 0;
+ if (bounds[0][1] < 0)
+ bounds[0][1] = 0;
+ if (bounds[1][0] >= (coord_t)SECTOR_SIZE)
+ bounds[1][0] = SECTOR_SIZE - 1;
+ if (bounds[1][1] >= (coord_t)SECTOR_SIZE)
+ bounds[1][1] = SECTOR_SIZE - 1;
+
+ for (index[1] = bounds[0][1]; index[1] <= bounds[1][1]; index[1]++)
+ for (index[0] = bounds[0][0]; index[0] <= bounds[1][0]; index[0]++) {
+ tile_t *tile;
+
+ tile = sector->tiles + index[1] * SECTOR_SIZE + index[0];
+ if (tile->type != TILE_DIRT)
+ return true;
+ }
+
+ for (entity_t *ent : sector->ents) {
+ if (ent == ignore)
+ continue;
+
+ if (ent->cookie == cookie)
+ continue;
+
+ ent->cookie = cookie;
+
+ if (!(ent->cmodel.cflags & cmodel->cflags))
+ continue;
+
+ if (!(cmodel->bounds && ent->cmodel.bounds))
+ continue;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
void world_t::debug_point(sf::Vector2f point)
{
sector_index_t index = sector_index_at(point);