summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common.hpp19
-rw-r--r--src/game.cpp110
-rw-r--r--src/interface.cpp4
-rw-r--r--src/main.cpp3
-rw-r--r--src/render.cpp47
-rw-r--r--src/text.cpp14
-rw-r--r--src/world.cpp7
7 files changed, 139 insertions, 65 deletions
diff --git a/src/common.hpp b/src/common.hpp
index ecdb549..043323a 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -128,9 +128,12 @@ namespace world {
size_t cookie = 0;
public:
+ int type;
cmodel_t cmodel;
rectf_t render_bounds;
+ entity_t(int type_);
+
void link(world_t *world);
void unlink();
@@ -169,7 +172,11 @@ namespace world {
namespace game {
bool load_assets(void);
+ class unit_t;
+
class state_t {
+ std::unordered_set<unit_t*> selected_units;
+
public:
world::world_t world;
@@ -203,7 +210,7 @@ namespace interface {
public:
state_t(sf::RenderWindow *window_, game::state_t *game);
void tick(void);
- void render(void);
+ void render_to(render::state_t *render);
};
}
@@ -247,7 +254,6 @@ namespace render {
sf::RenderWindow *window;
double now;
- void drender_rect(rectf_t rect, sf::Color color);
void drender_text(rectf_t rect, std::string str);
void drender_entity(world::entity_t *ent);
public:
@@ -259,6 +265,8 @@ namespace render {
void render(animated_texture_t *anim, rectf_t bounds, bool mirror = false);
void render(oriented_sprite_t *sprite, rectf_t bounds, float angle);
+ void render_hlrect(rectf_t rect, sf::Color color);
+
void debug_path(std::list<v2f_t> *path);
};
}
@@ -276,6 +284,13 @@ namespace assets {
void load(void);
};
+namespace text {
+ extern std::string unit_no_path;
+ extern std::string unit_blocked;
+
+ void load_strings(std::string lang);
+}
+
// Divide and round to minus infinity.
template <typename T>
T divide_rmi(T x, T y, T *rem)
diff --git a/src/game.cpp b/src/game.cpp
index f5341d1..48047a4 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -2,6 +2,12 @@
namespace game {
+static size_t selection_cookie = 1;
+
+enum {
+ ET_UNIT
+};
+
class unit_t : public world::entity_t {
world::world_t *world;
@@ -26,6 +32,11 @@ public:
v2f_t x;
rectf_t size, render_size;
world::cflags_t cflags;
+ size_t selected = 0;
+
+ unit_t() : entity_t(ET_UNIT)
+ {
+ }
struct {
bool moving = false;
@@ -33,8 +44,18 @@ public:
float angle = 0.0f;
std::list<v2f_t> path;
+
+ bool blocked;
+ size_t attempts_left;
+ float next_attempt;
} move;
+ void say(std::string str)
+ {
+ //TODO
+ std::cout << (void*)this << ": " << str << "\n";
+ }
+
void place(world::world_t *world_, v2f_t x_)
{
world = world_;
@@ -48,14 +69,17 @@ public:
link(world);
}
- void keep_moving(void)
+ void keep_moving(double now)
{
float time;
if (!move.moving)
return;
- time = 0.15;
+ if (move.blocked && now < move.next_attempt)
+ return;
+
+ time = 0.15; // FIXME
while (time > 0.0f) {
v2f_t delta, next, x_new;
@@ -80,13 +104,22 @@ public:
}
cmodel_next = make_cmodel(x_new);
- if (world->test_rect(&cmodel_next, this)) {
- move.moving = false;
- break;
+ if (!world->test_rect(&cmodel_next, this)) {
+ x = x_new;
+ cmodel = cmodel_next;
+ continue;
}
- x = x_new;
- cmodel = cmodel_next;
+ if (move.attempts_left) {
+ move.blocked = true;
+ move.attempts_left--;
+ move.next_attempt = now + 0.5f;
+ } else {
+ if ((x - move.dst).len() > 1.5f)
+ say(text::unit_blocked);
+ move.moving = false;
+ }
+ break;
}
@@ -105,12 +138,19 @@ public:
move.dst = dst_;
move.path.clear();
- if (world->find_path(x, move.dst, &cmodel, this, &move.path))
- move.moving = true;
- else
+ if (!world->find_path(x, move.dst, &cmodel, this, &move.path)) {
+ say(text::unit_no_path);
move.moving = false;
+ return false;
+ }
+
+ move.moving = true;
+
+ move.blocked = false;
+ move.attempts_left = 10;
+ move.next_attempt = -INFINITY;
- return move.moving;
+ return true;
}
};
@@ -120,7 +160,14 @@ public:
void render_to(render::state_t *render)
{
- render->render((move.moving ? &assets::human.legs_walking :
+ bool moving;
+
+ if (selected == selection_cookie)
+ render->render_hlrect(render_bounds, sf::Color::Blue);
+
+ moving = move.moving && !move.blocked;
+
+ render->render((moving ? &assets::human.legs_walking :
&assets::human.legs_idle), render_bounds, move.angle);
render->render(&assets::human.body_idle, render_bounds, move.angle);
render->render(&assets::human.head_idle, render_bounds, move.angle);
@@ -145,40 +192,35 @@ void state_t::start(void)
human2.render_size[0] = v2f_t(-0.5f, -1.0f);
human2.render_size[1] = v2f_t(+0.5f, +0.5f);
human2.place(&world, v2f_t(3.5f, 0.5f));
-
}
void state_t::select(rectf_t x)
{
-
+ selection_cookie++;
+ selected_units.clear();
+
+ for (world::entity_t *ent : world.get_render_entities(x, -1)) {
+ unit_t *unit;
+
+ if (ent->type != ET_UNIT)
+ continue;
+
+ unit = (unit_t*)ent;
+ unit->selected = selection_cookie;
+ selected_units.insert(unit);
+ }
}
void state_t::command(v2f_t x)
{
-
+ for (unit_t *unit : selected_units)
+ unit->start_moving(x);
}
void state_t::tick(double now)
{
- if ((human2.x - human.x).len() > 3) {
- if (now > human2.last_follow + 0.5) {
- for (size_t i = 0; i < 8; i++) {
- float angle;
- v2f_t offset;
-
- angle = (float)i / 8 * 2 * M_PI;
- offset[0] = cos(angle);
- offset[1] = sin(angle);
-
- if (human2.start_moving(human.x + offset))
- break;
- }
- human2.last_follow = now;
- }
- }
-
- human.keep_moving();
- human2.keep_moving();
+ human.keep_moving(now);
+ human2.keep_moving(now);
}
} //namespace game
diff --git a/src/interface.cpp b/src/interface.cpp
index d6137fd..11e297e 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -59,6 +59,10 @@ void state_t::tick(void)
select.rect[1] = wmouse;
break;
+ case sf::Mouse::Button::Right:
+ game->command(wmouse);
+ break;
+
case sf::Mouse::Button::Middle:
camera.panning = true;
camera.pan_ref = wmouse;
diff --git a/src/main.cpp b/src/main.cpp
index 01c1df4..8b3eef7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -23,6 +23,7 @@ int main()
window.setVerticalSyncEnabled(true);
+ text::load_strings("en");
assets::load();
game.start();
@@ -38,7 +39,7 @@ int main()
window.clear();
render.begin_frame(now);
render.render(&game);
- interface.render();
+ interface.render_to(&render);
render.end_frame();
}
diff --git a/src/render.cpp b/src/render.cpp
index 41bcd4b..80ed2b6 100644
--- a/src/render.cpp
+++ b/src/render.cpp
@@ -23,7 +23,7 @@ static void draw_tile(sf::RenderWindow *window, v2f_t x, world::tile_t *tile,
break;
}
- wot_rect.setTexture(texture);
+ wot_rect.setTexture(texture, true);
wot_rect.setSize(sf::Vector2f(1.0f, 1.0f));
wot_rect.setPosition(x);
wot_rect.setFillColor(sf::Color::White);
@@ -50,16 +50,10 @@ static void draw_sector(sf::RenderWindow *window, world::sector_t *sector)
world::tile_index_t(x, y));
}
-void interface::state_t::render()
+void interface::state_t::render_to(render::state_t *render)
{
- if (select.selecting) {
- wot_rect.setSize(select.rect.dims());
- wot_rect.setPosition(select.rect[0]);
- wot_rect.setFillColor(sf::Color(200, 100, 50, 100));
- wot_rect.setOutlineThickness(0.02f);
- wot_rect.setOutlineColor(sf::Color(200, 100, 50, 255));
- window->draw(wot_rect);
- }
+ if (select.selecting)
+ render->render_hlrect(select.rect, sf::Color(200, 100, 50));
}
namespace render {
@@ -82,21 +76,6 @@ void state_t::end_frame(void)
window->display();
}
-void state_t::drender_rect(rectf_t rect, sf::Color color)
-{
- sf::Color fill;
-
-
- fill = sf::Color(color.r, color.g, color.b, 50);
-
- wot_rect.setSize(rect.dims());
- wot_rect.setPosition(rect[0]);
- wot_rect.setFillColor(fill);
- wot_rect.setOutlineThickness(0.01);
- wot_rect.setOutlineColor(color);
- window->draw(wot_rect);
-}
-
void state_t::drender_text(rectf_t rect, std::string str)
{
sf::Text text(str, font, 20);
@@ -121,8 +100,8 @@ void state_t::drender_entity(world::entity_t *ent)
{
std::stringstream ss;
- drender_rect(ent->render_bounds, sf::Color::Red);
- drender_rect(ent->cmodel.bounds, sf::Color::Yellow);
+ render_hlrect(ent->render_bounds, sf::Color::Red);
+ render_hlrect(ent->cmodel.bounds, sf::Color::Yellow);
ss << (void*)ent << "\n";
ss << "CF=" << ent->cmodel.cflags;
@@ -202,6 +181,20 @@ void state_t::render(oriented_sprite_t *sprite, rectf_t bounds, float angle)
render(sprite->textures + index, bounds, mirror);
}
+void state_t::render_hlrect(rectf_t rect, sf::Color color)
+{
+ sf::Color fill;
+
+ fill = sf::Color(color.r, color.g, color.b, 50);
+ wot_rect.setSize(rect.dims());
+ wot_rect.setPosition(rect[0]);
+ wot_rect.setFillColor(fill);
+ wot_rect.setOutlineThickness(0.01);
+ wot_rect.setOutlineColor(color);
+ window->draw(wot_rect);
+ wot_rect.setOutlineColor(sf::Color::Transparent);
+}
+
void state_t::debug_path(std::list<v2f_t> *path)
{
bool first = true;
diff --git a/src/text.cpp b/src/text.cpp
new file mode 100644
index 0000000..baeabcd
--- /dev/null
+++ b/src/text.cpp
@@ -0,0 +1,14 @@
+#include "common.hpp"
+
+namespace text {
+
+std::string unit_no_path;
+std::string unit_blocked;
+
+void load_strings(std::string lang)
+{
+ unit_no_path = "Cannot find a path.";
+ unit_blocked = "The path is blocked.";
+}
+
+}
diff --git a/src/world.cpp b/src/world.cpp
index 004f03f..ef056db 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -113,7 +113,7 @@ bool world_t::find_path(v2f_t src, v2f_t dst, cmodel_t *cmodel, entity_t *ignore
if (ent != ignore)
finder.eliminate_nodes(ent->cmodel.bounds);
- if (finder.find())
+ if (!finder.find())
return false;
finder.export_path(path);
@@ -270,6 +270,11 @@ void world_t::debug_point(sf::Vector2f point)
printf("sector (%zd, %zd)\n", index[0], index[1]);
}
+entity_t::entity_t(int type_)
+{
+ type = type_;
+}
+
void entity_t::link_to_sector(sector_t *sector)
{
parents.push_back(sector);