feat: implemented enemy spawning
This commit is contained in:
		
							parent
							
								
									4071964a41
								
							
						
					
					
						commit
						3e8c8a08f2
					
				
							
								
								
									
										47
									
								
								src/enemy_spawnpoint.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/enemy_spawnpoint.cpp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										26
									
								
								src/enemy_spawnpoint.hpp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										123
									
								
								src/spawner.cpp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										49
									
								
								src/spawner.hpp
									
									
									
									
									
										Normal 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
 | 
			
		||||
		Loading…
	
		Reference in a new issue