feat: implemented enemy spawning

This commit is contained in:
Sara 2024-05-22 10:22:12 +02:00
parent 4071964a41
commit 3e8c8a08f2
4 changed files with 245 additions and 0 deletions

47
src/enemy_spawnpoint.cpp Normal file
View file

@ -0,0 +1,47 @@
#include "enemy_spawnpoint.hpp"
#include "spawner.hpp"
#include "utils/godot_macros.h"
#include <godot_cpp/classes/physics_ray_query_parameters3d.hpp>
#include <godot_cpp/classes/viewport.hpp>
#include <godot_cpp/classes/camera3d.hpp>
#include <godot_cpp/classes/world3d.hpp>
#include <godot_cpp/classes/physics_direct_space_state3d.hpp>
namespace godot {
void EnemySpawnpoint::_bind_methods() {
#define CLASSNAME EnemySpawnpoint
GDPROPERTY(keys, Variant::BOOL);
GDPROPERTY(cars, Variant::BOOL);
GDPROPERTY(drones, Variant::BOOL);
}
bool EnemySpawnpoint::player_can_see() const {
Dictionary result = this->get_world_3d()->get_direct_space_state()
->intersect_ray(PhysicsRayQueryParameters3D::create(this->get_global_position(), this->get_viewport()->get_camera_3d()->get_global_position()));
return result.is_empty();
}
void EnemySpawnpoint::set_keys(bool val) {
this->keys = val;
}
bool EnemySpawnpoint::get_keys() const {
return this->keys;
}
void EnemySpawnpoint::set_cars(bool val) {
this->cars = val;
}
bool EnemySpawnpoint::get_cars() const {
return this->cars;
}
void EnemySpawnpoint::set_drones(bool val) {
this->drones = val;
}
bool EnemySpawnpoint::get_drones() const {
return this->drones;
}
}

26
src/enemy_spawnpoint.hpp Normal file
View file

@ -0,0 +1,26 @@
#ifndef ENEMY_SPAWNPOINT_HPP
#define ENEMY_SPAWNPOINT_HPP
#include <godot_cpp/classes/node3d.hpp>
namespace godot {
class EnemySpawnpoint : public Node3D {
GDCLASS(EnemySpawnpoint, Node3D);
static void _bind_methods();
public:
bool player_can_see() const;
public:
void set_keys(bool val);
bool get_keys() const;
void set_cars(bool val);
bool get_cars() const;
void set_drones(bool val);
bool get_drones() const;
private:
bool keys{false};
bool cars{true};
bool drones{true};
};
}
#endif // !ENEMY_SPAWNPOINT_HPP

123
src/spawner.cpp Normal file
View file

@ -0,0 +1,123 @@
#include "spawner.hpp"
#include "enemy_spawnpoint.hpp"
#include "godot_cpp/classes/time.hpp"
#include "rally_rush_game_mode.hpp"
#include "utils/game_root.hpp"
#include "utils/godot_macros.h"
namespace godot {
void Spawner::_bind_methods() {
#define CLASSNAME Spawner
GDPROPERTY_HINTED(drone_scene, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
GDPROPERTY_HINTED(car_scene, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
GDPROPERTY_HINTED(key_scene, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
}
void Spawner::_ready() {
this->game_mode = Object::cast_to<RallyRushGameMode>(GameRoot3D::get_singleton()->get_game_mode().ptr());
this->spawn_key();
this->spawn_key();
this->spawn_key();
}
void Spawner::_process(double delta_time) {
if(Time::get_singleton()->get_ticks_msec() * 0.001f > next) {
if(num_cars < this->max_enemy_cars() && tick % 2 == 0) this->spawn_enemy_car();
else if(num_drones < this->max_enemy_drones()) this->spawn_enemy_drone();
}
}
int Spawner::max_enemy_cars() {
return this->game_mode->get_num_found_keys() * 3;
}
int Spawner::max_enemy_drones() {
return this->game_mode->get_num_found_keys() * 3;
}
void Spawner::spawn_enemy_car() {
int const child_count{this->get_child_count()};
int iter_count{0};
int child_index{int(this->rng.get_state()) % child_count};
while(iter_count++ < child_count) {
EnemySpawnpoint *spawnpoint = Object::cast_to<EnemySpawnpoint>(this->get_child(child_index));
child_index++;
if(!spawnpoint) continue;
if(!spawnpoint->get_cars()) continue;
if(spawnpoint->player_can_see()) continue;
Node3D *node = Object::cast_to<Node3D>(this->car_scene->instantiate());
this->get_parent()->add_child(node);
node->set_global_transform(spawnpoint->get_global_transform());
this->num_cars++;
node->connect("tree_exited", callable_mp(this, &Spawner::decrement_cars));
return;
}
}
void Spawner::spawn_enemy_drone() {
int const child_count{this->get_child_count()};
int iter_count{0};
int child_index{int(this->rng.get_state()) % child_count};
while(iter_count++ < child_count) {
EnemySpawnpoint *spawnpoint = Object::cast_to<EnemySpawnpoint>(this->get_child(child_index));
child_index++;
if(!spawnpoint) continue;
if(!spawnpoint->get_drones()) continue;
if(spawnpoint->player_can_see()) continue;
Node3D *node = Object::cast_to<Node3D>(this->drone_scene->instantiate());
this->get_parent()->add_child(node);
node->set_global_transform(spawnpoint->get_global_transform());
this->num_drones++;
node->connect("tree_exited", callable_mp(this, &Spawner::decrement_drones));
return;
}
}
void Spawner::spawn_key() {
int const child_count{this->get_child_count()};
int iter_count{0};
int child_index{int(this->rng.get_state()) % child_count};
while(iter_count++ < child_count) {
EnemySpawnpoint *spawnpoint = Object::cast_to<EnemySpawnpoint>(this->get_child(child_index));
child_index++;
if(!spawnpoint) continue;
if(!spawnpoint->get_keys()) continue;
Node3D *node = Object::cast_to<Node3D>(this->key_scene->instantiate());
this->get_parent()->add_child(node);
node->set_global_transform(spawnpoint->get_global_transform());
return;
}
}
void Spawner::decrement_cars() {
this->num_cars--;
}
void Spawner::decrement_drones() {
this->num_drones--;
}
void Spawner::set_drone_scene(Ref<PackedScene> scene) {
this->drone_scene = scene;
}
Ref<PackedScene> Spawner::get_drone_scene() const {
return this->drone_scene;
}
void Spawner::set_car_scene(Ref<PackedScene> scene) {
this->car_scene = scene;
}
Ref<PackedScene> Spawner::get_car_scene() const {
return this->car_scene;
}
void Spawner::set_key_scene(Ref<PackedScene> scene) {
this->key_scene = scene;
}
Ref<PackedScene> Spawner::get_key_scene() const {
return this->key_scene;
}
}

49
src/spawner.hpp Normal file
View file

@ -0,0 +1,49 @@
#ifndef SPAWNER_HPP
#define SPAWNER_HPP
#include "enemy_spawnpoint.hpp"
#include "godot_cpp/classes/packed_scene.hpp"
#include "godot_cpp/classes/random_number_generator.hpp"
#include "godot_cpp/templates/vector.hpp"
#include "rally_rush_game_mode.hpp"
#include <godot_cpp/classes/node.hpp>
namespace godot {
class EnemySpawnpoint;
class Spawner : public Node {
GDCLASS(Spawner, Node);
static void _bind_methods();
public:
virtual void _ready() override;
virtual void _process(double delta_time) override;
int max_enemy_cars();
int max_enemy_drones();
protected:
void spawn_enemy_car();
void spawn_enemy_drone();
void spawn_key();
void decrement_cars();
void decrement_drones();
void set_drone_scene(Ref<PackedScene> scene);
Ref<PackedScene> get_drone_scene() const;
void set_car_scene(Ref<PackedScene> scene);
Ref<PackedScene> get_car_scene() const;
void set_key_scene(Ref<PackedScene> scene);
Ref<PackedScene> get_key_scene() const;
private:
double next{0};
unsigned tick{0};
RallyRushGameMode *game_mode;
Vector<EnemySpawnpoint *> spawnpoints{};
Ref<PackedScene> drone_scene{};
Ref<PackedScene> car_scene{};
Ref<PackedScene> key_scene{};
RandomNumberGenerator rng{};
unsigned num_cars{0};
unsigned num_drones{0};
};
}
#endif // !SPAWNER_HPP