summaryrefslogtreecommitdiff
path: root/src/game/game.hpp
blob: 57dbb0734b157cb7505f7bdb364ea7fa998a0be4 (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
140
141
142
#include "../common.hpp"

namespace game {
	enum {
		ET_UNIT
	};

	enum {
		TILE_NONE,
		TILE_DIRT,
		TILE_WALL
	};

	enum {
		CF_SOLID      = 1,
		CF_BODY       = 2,
		CF_BODY_SMALL = 4
	};

	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_4M_t body_aiming, body_firing;
			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;
			render::animated_texture_t dead;
		} 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();

		double next_targetting = -INFINITY;
		double last_attack = -INFINITY;

	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, world::cflags_t cflags);

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

		struct {
			size_t armor_class;
			roll_params_t hit_roll;
			roll_params_t damage_roll;
		} cs;

		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 {
		double last_target_time = -INFINITY;
		v2f_t last_target_x;

	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;

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