enemy_system.cpp 5.52 KB
Newer Older
1
2
#include "enemy_system.hpp"

3
#include "beat_system.hpp"
4
#include "movement_comp.hpp"
5

6
#include <mirrage/ecs/components/transform_comp.hpp>
7
8
9

namespace phase_shifter::gameplay {
	
10
11
12
	using namespace mirrage::ecs;

	Enemy_system::Enemy_system(Entity_manager& entity_manager, const Beat_system& beat_system)
13
	  : _entity_manager(entity_manager), _beat_system(beat_system)
14
15
	{
		_entity_manager.register_component_type<Fixed_path_comp>();
16
		_entity_manager.register_component_type<Follow_target_comp>();
17
		_entity_manager.register_component_type<Continuous_path_comp>();
18
		_entity_manager.register_component_type<Shooting_comp>();
19
		_entity_manager.register_component_type<Target_comp>();
20
21
22
23
	}

	void Enemy_system::update(mirrage::util::Time dt)
	{
24
25
		auto beat = _beat_system.beat_state();

26
		for (auto&& [movement, fixed_path] : _entity_manager.list<Movement_comp, Fixed_path_comp>()) {
27
28
29
30
31
32
33
34
35
36
37
38
			if(beat.beat) {
				if(fixed_path.wait_beats == 0 && !movement.move) {
					float direction = fixed_path.next_direction();
					if(direction < 360) {
						float rad_direction = direction * mirrage::util::PI / 180.f;
						movement.aim.x = std::sin(rad_direction);
						movement.aim.y = -std::cos(rad_direction);
						movement.move  = true;
					}
					fixed_path.wait_beats = fixed_path.pause_between_steps;
				} else {
					fixed_path.wait_beats--;
39
40
41
				}
			}
		}
42
		
43
44
45
46
		for (auto&&[movement, follow_target, transform] : _entity_manager.list<Movement_comp, Follow_target_comp, components::Transform_comp>()) {
			if(beat.beat) {
				if(follow_target.wait_beats == 0 && !movement.move) {
					auto target_facet = _entity_manager.get(follow_target.target);
47

48
49
50
					if(target_facet.is_some()) {
						auto target_transform =
						        target_facet.get_or_throw().get<components::Transform_comp>();
51

52
53
54
55
56
57
58
59
60
61
62
						if(target_transform.is_some()) {
							auto& target_position = target_transform.get_or_throw().position;
							auto& my_position     = transform.position;
							movement.aim          = glm::vec2(
                                    {target_position.x - my_position.x, target_position.z - my_position.z});
							movement.move = true;
						}
					}
					follow_target.wait_beats = follow_target.pause_between_steps;
				} else {
					follow_target.wait_beats--;
63
64
65
				}
			}
		}
66
67

		for(auto&& [movement, cont_path] : _entity_manager.list<Movement_comp, Continuous_path_comp>()) {
68
69
70
71
72
73
74
75
76
77
			if(beat.beat) {
				if(cont_path.wait_beats == 0 && !movement.move) {
					float rad_direction = cont_path.next_direction() * mirrage::util::PI / 180.f;
					movement.aim.x      = std::sin(rad_direction);
					movement.aim.y      = -std::cos(rad_direction);
					movement.move       = true;
					cont_path.wait_beats = cont_path.pause_between_steps;
				} else {
					cont_path.wait_beats--;
				}
78
79
			}
		}
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
		for (auto&& [shooting, transform] : _entity_manager.list<Shooting_comp, components::Transform_comp>()) {
			auto my_position         = transform.position;
			glm::vec3 closest_target_pos;
			float     closest_dist = 999999999.f;

			for(auto&& [target, target_comp, target_transform] :
			    _entity_manager.list<Entity_facet, Target_comp, components::Transform_comp>()) {

				auto target_position     = target_transform.position;
				auto dist                = glm::length(glm::vec2(target_position.x, target_position.z)
                                        - glm::vec2(my_position.x, my_position.z));
				if(dist < closest_dist) {
					closest_dist = dist;
					closest_target_pos = target_position;
Tim Scheiber's avatar
Tim Scheiber committed
95
96
97
				}
			}

98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
			glm::vec2 t_direction(closest_target_pos.x - my_position.x, closest_target_pos.z - my_position.z);
			shooting.target_direction = std::acos(-t_direction.y / glm::length(t_direction)) * 180.f / mirrage::util::PI;
			if (t_direction.x < 0) {
				shooting.target_direction *= -1;
			}

			if (closest_dist <= shooting.attack_radius) {
				shooting.idle = false;
			} else {
				shooting.idle = true;
			}

			auto orientation = shooting.target_direction;
			if(shooting.idle) {
				orientation = shooting.default_orientation + shooting.rotation;
			}
			auto rad_orientation = orientation * mirrage::util::PI / 180.f;

116
			if (beat.beat) {
117
118
119
				if(shooting.idle && shooting.rotate) {
					shooting.do_rotation();
					shooting.rotate = false;
Tim Scheiber's avatar
Tim Scheiber committed
120
				}
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
				if(shooting.wait_beats == 0) {
					auto bullet_pattern = shooting.next_pattern();
					auto spawn_position =
					        transform.position
					        + shooting.spawn_offset
					                  * glm::vec3(std::sin(rad_orientation), 0, -std::cos(rad_orientation));

					for(auto bullet : bullet_pattern.bullets) {
						auto bullet_direction     = orientation + bullet.direction;
						auto rad_bullet_direction = bullet_direction * mirrage::util::PI / 180.f;
						_entity_manager.entity_builder("bullet")
						        .position(spawn_position)
						        .rotation(glm::rotation({0, 0, 1},
						                                glm::vec3(std::sin(rad_bullet_direction),
						                                          0,
						                                          -std::cos(rad_bullet_direction))))
						        .post_create([=](auto entity) {
							        entity.process([=](Continuous_path_comp& cont_path) {
								        cont_path.direction = bullet_direction;
								        cont_path.curvature = bullet.curvature;
							        });
						        })
						        .create();
					}

					shooting.wait_beats = shooting.pause_between_shots;
					shooting.rotate = true;
				} else {
					shooting.wait_beats--;
150
151
				}
			}
152
153
154

			transform.orientation = glm::rotation(
			        {0, 0, 1}, glm::vec3(std::sin(rad_orientation), 0, -std::cos(rad_orientation)));
155
		}
156
157
	}
}