From 336754d5595d62a1de3261d7117c9c6ac2cff18c Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 20 Mar 2024 09:50:10 +0100 Subject: [PATCH] feat: implemented a zero-volume pellet projectile --- src/pellet_projectile.cpp | 43 +++++++++++++++++++++++++++++++++++++++ src/pellet_projectile.hpp | 22 ++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/pellet_projectile.cpp create mode 100644 src/pellet_projectile.hpp diff --git a/src/pellet_projectile.cpp b/src/pellet_projectile.cpp new file mode 100644 index 0000000..b9a537c --- /dev/null +++ b/src/pellet_projectile.cpp @@ -0,0 +1,43 @@ +#include "pellet_projectile.hpp" +#include "health.hpp" +#include "utils/godot_macros.h" +#include +#include +#include +#include + +namespace godot { +void PelletProjectile::_bind_methods() { +#define CLASSNAME PelletProjectile +} + +void PelletProjectile::_enter_tree() { + this->distance_traveled = 0; +} + +void PelletProjectile::_physics_process(double delta_time) { GDGAMEONLY(); + float const speed = this->data->get_projectile_speed()->sample(distance_traveled / this->data->get_range()); + this->distance_traveled += speed; + Vector3 const next_position{this->get_global_position() + this->get_global_transform().basis.get_column(2) * speed}; + if(this->check_hit(next_position) || this->distance_traveled > this->data->get_range()) { + this->return_to_pool(); + } else { + this->set_global_position(next_position); + } +} + +bool PelletProjectile::check_hit(Vector3 next_position) { + Ref query{PhysicsRayQueryParameters3D::create(this->get_global_position(), next_position, 0x4)}; + Dictionary hit = this->get_world_3d()->get_direct_space_state()->intersect_ray(query); + if(hit.is_empty()) + return false; + Node *collider = Object::cast_to(hit.get("collider", nullptr)); + if(collider == nullptr) + return false; + IHealthEntity *health_entity = dynamic_cast(collider); + if(health_entity == nullptr) + return false; + health_entity->get_health()->damage(this->data->get_damage()); + return true; +} +} diff --git a/src/pellet_projectile.hpp b/src/pellet_projectile.hpp new file mode 100644 index 0000000..b86b532 --- /dev/null +++ b/src/pellet_projectile.hpp @@ -0,0 +1,22 @@ +#ifndef PELLET_PROJECTILE_HPP +#define PELLET_PROJECTILE_HPP + +#include "weapon_data.hpp" +#include "projectile.hpp" +#include + +namespace godot { +class PelletProjectile : public Projectile { + GDCLASS(PelletProjectile, Projectile); + static void _bind_methods(); +public: + virtual void _enter_tree() override; + virtual void _physics_process(double delta_time) override; + + bool check_hit(Vector3 next_position); +private: + float distance_traveled{0.f}; +}; +} + +#endif // !PELLET_PROJECTILE_HPP