diff options
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | src/common.hpp | 19 | ||||
| -rw-r--r-- | src/game.cpp | 110 | ||||
| -rw-r--r-- | src/interface.cpp | 4 | ||||
| -rw-r--r-- | src/main.cpp | 3 | ||||
| -rw-r--r-- | src/render.cpp | 47 | ||||
| -rw-r--r-- | src/text.cpp | 14 | ||||
| -rw-r--r-- | src/world.cpp | 7 | 
8 files changed, 140 insertions, 65 deletions
@@ -16,6 +16,7 @@ SRC := src/assets.cpp \         src/path_finder.cpp \         src/procgen.cpp \         src/render.cpp \ +       src/text.cpp \         src/world.cpp  OBJ := $(SRC:src/%.cpp=obj/%.o) 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);  | 
