summaryrefslogtreecommitdiff
path: root/src/game/game.hpp
blob: 107bfbfd9c89ee5a1351f33938e213fa289eb57a (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
#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;

		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);
		virtual void die() = 0;

		const wchar_t *say_text;
		double say_time = -INFINITY;
		void say(const wchar_t *wstr);

		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);
	};
};