summaryrefslogtreecommitdiff
path: root/src/game/game.hpp
blob: 55e3c45b963d519d7eca95d6cf688d16a9d561b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "../common.hpp"

namespace game {
	enum {
		ET_UNIT
	};

	enum {
		TILE_NONE,
		TILE_DIRT,
		TILE_WALL
	};

	enum {
		CF_NONE  = 0,
		CF_SOLID = 1,
		CF_HUMAN = 2
	};

	extern size_t selection_cookie;

	void worldgen(world::tile_t *tile, world::tile_index_t x,
	              procgen::perlin_noise_t *perlin);

	namespace assets {
		typedef struct {
			render::oriented_sprite_4M_t head_idle, body_idle;
			render::oriented_sprite_4M2_t legs_idle, legs_walking;
			render::animated_texture_t dead;
		} human_assets_t;

		typedef struct {
			render::oriented_sprite_4M_t idle, walking;
		} alien_assets_t;

		extern human_assets_t human;
		extern alien_assets_t alien;

		void load(void);
	}

	class unit_t : public world::entity_t {
	protected:
		game::state_t *game;
		world::world_t *world;

		world::cmodel_t make_cmodel(v2f_t at);
		void compute_bounds();

	public:
		v2f_t x;
		rectf_t size, render_size;
		world::cflags_t cflags;
		size_t selected = 0;

		typedef enum {
			UNIT_HUMAN,
			UNIT_ALIEN
		} type_t;

		type_t type;
		std::string name;

		unit_t(game::state_t *game_, type_t type_);

		virtual void think(void) = 0;

		struct {
			bool moving = false;
			v2f_t dst;
			float angle = 0.0f;

			std::list<v2f_t> path;

			bool blocked;
			size_t attempts_left;
			float next_attempt;
		} move;

		void place(world::world_t *world_, v2f_t x_);
		bool keep_moving(double speed);
		bool start_moving(v2f_t dst);

		bool awake = false;
		double wake_time = -INFINITY;
		virtual void wake(unit_t *by_whom) = 0;
		virtual void sleep(void) = 0;

		bool dead = false;
		double death_time = -INFINITY;
		int health = 1, max_health = 1;
		void damage(int points, unit_t *attacker);
		void try_attack(unit_t *target);
		virtual void die() = 0;

		std::string say_text;
		double say_time = -INFINITY;
		void say(std::string str);

		void render_to(render::state_t *render);

	};

	class human_t : public unit_t {
	public:
		human_t(game::state_t *game);
		void render_to(render::state_t *render);

		void wake(unit_t *by_whom);
		void sleep(void);
		void think(void);
		void die(void);
	};

	class alien_t : public unit_t {
		double next_targetting = -INFINITY;
		double next_attack = -INFINITY;

		void attack(unit_t *target, float range);
	public:
		alien_t(game::state_t *game);
		void render_to(render::state_t *render);

		void wake(unit_t *by_whom);
		void sleep(void);
		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;
	}
};