diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/game.cpp | 3 | ||||
| -rw-r--r-- | src/game/game.hpp | 18 | ||||
| -rw-r--r-- | src/game/interface.cpp | 31 | ||||
| -rw-r--r-- | src/game/units.cpp | 63 | 
4 files changed, 96 insertions, 19 deletions
diff --git a/src/game/game.cpp b/src/game/game.cpp index c2c2c19..f5f57bf 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -70,7 +70,8 @@ void state_t::command(v2f_t x)  		if (unit->dead)  			continue; -		unit->start_moving(snap); +		if (!unit->start_moving(snap)) +			unit->say(text::get(text::SAY_NO_PATH));  	}  } diff --git a/src/game/game.hpp b/src/game/game.hpp index 107bfbf..55e3c45 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -59,6 +59,7 @@ namespace game {  		} type_t;  		type_t type; +		std::string name;  		unit_t(game::state_t *game_, type_t type_); @@ -88,12 +89,13 @@ namespace game {  		bool dead = false;  		double death_time = -INFINITY;  		int health = 1, max_health = 1; -		void damage(int points); +		void damage(int points, unit_t *attacker); +		void try_attack(unit_t *target);  		virtual void die() = 0; -		const wchar_t *say_text; +		std::string say_text;  		double say_time = -INFINITY; -		void say(const wchar_t *wstr); +		void say(std::string str);  		void render_to(render::state_t *render); @@ -124,4 +126,14 @@ namespace game {  		void think(void);  		void die(void);  	}; + +	static inline size_t roll(size_t count, size_t sides) +	{ +		size_t total = 0; + +		for (size_t i = 0; i < count; i++) +			total += rand() % sides + 1; + +		return total; +	}  }; diff --git a/src/game/interface.cpp b/src/game/interface.cpp index 854b620..a367607 100644 --- a/src/game/interface.cpp +++ b/src/game/interface.cpp @@ -131,4 +131,35 @@ void state_t::tick(double dt)  		select.rect[1] = wmouse;  } +void state_t::print(std::string str) +{ +	log.push_back((log_entry_t){game->now, str}); +	std::cout << str << std::endl; +} + +void state_t::render_to(render::state_t *render) +{ +	size_t w = window->getSize().x, h = window->getSize().y; +	v2f_t x; + +	window->setView(sf::View(sf::FloatRect(0, 0, w, h))); +	em = std::min(w, h) * 0.04; + +	if (select.selecting) +		render->render_hlrect(select.rect, sf::Color(200, 100, 50)); + +	for (auto i = log.begin(); i != log.end(); ) { +		if (i->time + 3 < game->now) +			i = log.erase(i); +		else +			i++; +	} + +	x = v2f_t(0.0f, 0.0f); +	for (log_entry_t &entry : log) { +		render->render_text(x, em, entry.text, render::ALIGN_LEFT_TOP, sf::Color::White); +		x[1] += em; +	} +} +  } // namespace interface diff --git a/src/game/units.cpp b/src/game/units.cpp index 5563124..5efab65 100644 --- a/src/game/units.cpp +++ b/src/game/units.cpp @@ -60,11 +60,11 @@ void unit_t::render_to(render::state_t *render)  		render->debug_path(&move.path);  } -void unit_t::say(const wchar_t *wstr) +void unit_t::say(std::string str)  { -	say_text = wstr; +	say_text = str;  	say_time = game->now; -	std::cout << (void*)this << ": " << wstr << "\n"; +	game->interface->print(name + ": " + str);  }  void unit_t::place(world::world_t *world_, v2f_t x_) @@ -82,12 +82,13 @@ void unit_t::place(world::world_t *world_, v2f_t x_)  bool unit_t::keep_moving(double speed)  {  	float time; +	bool rv = true;  	if (!move.moving) -		return false; +		return true;  	if (move.blocked && game->now < move.next_attempt) -		return false; +		return true;  	time = game->dt * speed; @@ -126,7 +127,7 @@ bool unit_t::keep_moving(double speed)  			move.next_attempt = game->now + 0.2f;  		} else {  			if ((x - move.dst).len() > 1.5f) -				say(text::unit_blocked); +				rv = false;  			move.moving = false;  		}  		break; @@ -135,7 +136,7 @@ bool unit_t::keep_moving(double speed)  	unlink();  	compute_bounds();  	link(world); -	return true; +	return rv;  }  bool unit_t::start_moving(v2f_t dst) @@ -149,7 +150,6 @@ bool unit_t::start_moving(v2f_t dst)  	move.path.clear();  	if (!world->find_path(x, move.dst, &cmodel, this, &move.path)) { -		say(text::unit_no_path);  		move.moving = false;  		return false;  	} @@ -159,15 +159,14 @@ bool unit_t::start_moving(v2f_t dst)  	move.blocked = false;  	move.attempts_left = 10;  	move.next_attempt = -INFINITY; -  	return true;  } -void unit_t::damage(int points) +void unit_t::damage(int points, unit_t *attacker)  {  	health -= points;  	if (health < 0) { -		printf("%p died\n", this); +		game->interface->print(name + ": " + text::get(text::UNIT_DEATH) + ".");  		dead = true;  		death_time = game->now;  		cflags = 0; @@ -175,6 +174,38 @@ void unit_t::damage(int points)  	}  } +void unit_t::try_attack(unit_t *target) +{ +	std::stringstream ss; +	int hit_roll, hit_dc = 10 /* FIXME */; +	int dmg_roll, dmg_bonus, dmg_total; + +	ss << name << " " << text::get(text::UNIT_ATTACK) << " " << target->name << ": "; + +	hit_roll = roll(1, 20); +	ss << hit_roll << " vs " << hit_dc; + +	if (hit_roll == 1 || hit_roll < hit_dc) { +		ss << " (" << text::get((hit_roll == 1 ? text::UNIT_CRITICAL_MISS : text::UNIT_MISS)) << ")"; +		game->interface->print(ss.str()); +		return; +	} + +	ss << " (" << text::get((hit_roll == 20 ? text::UNIT_CRITICAL_HIT : text::UNIT_HIT)) << ")"; +	game->interface->print(ss.str()); + +	dmg_roll = roll(2, 6); +	dmg_bonus = 2; +	dmg_total = dmg_roll + dmg_bonus; + +	ss.str(std::string()); +	ss << name << " " << text::get(text::UNIT_DAMAGE) << " " << target->name << ": "; +	ss << dmg_roll << " + " << dmg_bonus << " = " << dmg_total; +	game->interface->print(ss.str()); + +	target->damage(dmg_total, this); +} +  human_t::human_t(game::state_t *game) : unit_t(game, UNIT_HUMAN)  {  	cflags = CF_HUMAN; @@ -184,6 +215,7 @@ human_t::human_t(game::state_t *game) : unit_t(game, UNIT_HUMAN)  	render_size[0] = v2f_t(-0.5f, -1.0f);  	render_size[1] = v2f_t(+0.5f, +0.5f);  	render_layer = -1; +	name = text::get(text::UNIT_HUMAN);  }  void human_t::wake(unit_t *by_whom) @@ -196,7 +228,8 @@ void human_t::sleep(void)  void human_t::think(void)  { -	keep_moving(4.0); +	if (!keep_moving(4.0)) +		say(text::get(text::SAY_BLOCKED));  }  void human_t::die(void) @@ -244,6 +277,7 @@ alien_t::alien_t(game::state_t *game) : unit_t(game, UNIT_ALIEN)  	size[1] = v2f_t(+0.2f, +0.2f);  	render_size[0] = v2f_t(-0.3f, -0.3f);  	render_size[1] = v2f_t(+0.3f, +0.3f); +	name = text::get(text::UNIT_ALIEN);  }  void alien_t::wake(unit_t *by_whom) @@ -258,7 +292,6 @@ void alien_t::sleep(void)  void alien_t::die(void)  { -	  }  static unit_t *find_target(world::world_t *world, v2f_t x, float r, @@ -308,9 +341,9 @@ void alien_t::attack(unit_t *target, float range)  	trace = world->trace(x, target->x, CF_SOLID);  	if (!trace.hit) -		target->damage(rand() % 6 + rand() % 6 + 2); +		try_attack(target); -	next_attack = game->now + 0.4; +	next_attack = game->now + 1.0;  }  void alien_t::think(void)  | 
