feat: Activate state can now activate UtilityLock nodes

This commit is contained in:
Sara 2024-09-04 10:51:20 +02:00
parent 7f6be4c48e
commit 428d42b672
4 changed files with 42 additions and 9 deletions

View file

@ -1,4 +1,6 @@
#include "rts_states.hpp"
#include "unit.hpp"
#include "utility_lock.hpp"
#include "utils/util_functions.hpp"
#include <godot_cpp/core/math.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
@ -8,7 +10,7 @@ void MoveTo::_bind_methods() {}
void MoveTo::_ready() {
this->parent_unit = Object::cast_to<Unit>(this->get_parent());
this->agent = this->get_node<gd::NavigationAgent3D>("../NavigationAgent3D");
this->agent = this->parent_unit->get_node<gd::NavigationAgent3D>("%NavigationAgent3D");
if(this->target_node == nullptr) {
this->end_state();
gd::UtilityFunctions::push_warning("failed to start MoveTo state due to missing target");
@ -73,16 +75,36 @@ double MoveTo::get_repath_interval() const {
void Activate::_bind_methods() {}
void Activate::_ready() {
this->anim = this->get_parent()->get_node<gd::AnimationPlayer>("%AnimationPlayer");
if(!this->anim->has_animation(this->animation))
this->parent_unit = gd::Object::cast_to<Unit>(this->get_parent());
if(this->parent_unit == nullptr) {
gd::UtilityFunctions::push_error(this->get_path(), " parent is not a Unit");
this->end_state();
else this->anim->play(this->animation);
return;
}
// start activating the lock
this->lock->begin_activate(this->using_item, this->parent_unit);
// play activate animation
this->anim = this->parent_unit->get_node<gd::AnimationPlayer>("%AnimationPlayer");
if(!this->anim->has_animation(this->animation)) {
this->end_state();
return;
}
this->anim->play(this->animation);
}
void Activate::_process(double) {
bool const animation_finished{!this->anim->is_playing() || this->anim->get_current_animation() != this->animation};
if(this->is_action_done_interrupt() || animation_finished)
if(animation_finished) {
this->lock->finish_activate(this->using_item, this->parent_unit);
this->end_state();
} else if(this->is_action_done_interrupt()) {
this->end_state();
}
}
void Activate::_end_state() {
if(!this->is_action_done())
this->lock->interrupt_activate();
}
void Animate::_bind_methods() {}

View file

@ -6,6 +6,8 @@
#include <godot_cpp/classes/animation_player.hpp>
#include <godot_cpp/classes/navigation_agent3d.hpp>
class UtilityLock;
/*! Uses navigation to chase the desired target node.
*/
class MoveTo : public goap::State {
@ -36,10 +38,13 @@ class Activate : public goap::State {
public:
virtual void _ready() override;
virtual void _process(double) override;
gd::Node3D *target_node{nullptr};
virtual void _end_state() override;
UtilityLock *lock{nullptr};
gd::String animation{};
private:
Item const *using_item{nullptr};
gd::AnimationPlayer *anim{nullptr};
Unit *parent_unit{nullptr};
};
class Animate : public goap::State {

View file

@ -1,6 +1,7 @@
#include "unit_world_state.hpp"
#include "entity_health.hpp"
#include "unit.hpp"
#include "utility_lock.hpp"
#include "utils/godot_macros.hpp"
#include "utils/util_functions.hpp"
#include <godot_cpp/classes/physics_ray_query_parameters3d.hpp>
@ -19,6 +20,7 @@ void UnitWorldState::_bind_methods() {
GDFUNCTION(get_has_target);
GDFUNCTION(get_target_node);
GDFUNCTION(get_is_target_enemy);
GDFUNCTION(get_is_target_activated);
GDFUNCTION(get_is_in_range);
GDFUNCTION(get_is_health_safe);
GDFUNCTION(get_parent_global_position);
@ -35,9 +37,8 @@ void UnitWorldState::_enter_tree() {
gd::Variant UnitWorldState::get_world_property(gd::String property) {
if(this->cache.has(property)) {
CachedWorldProperty prop{this->cache[property]};
if(prop.auto_invalidate_time > utils::time_seconds()) {
if(prop.auto_invalidate_time > utils::time_seconds())
return prop.value;
}
}
return ActorWorldState::get_world_property(property);
}
@ -57,7 +58,6 @@ bool UnitWorldState::get_can_see_node(gd::Node3D *node) const {
gd::Node3D *vision_target{node->get_node<gd::Node3D>("VisionTarget")};
gd::Transform3D const eyes{this->eye_location->get_global_transform()};
gd::Vector3 const target_position{vision_target ? vision_target->get_global_position() : node->get_global_position()};
// construct list for ignored objects including target node and parent unit
gd::TypedArray<gd::RID> ignore_list{this->parent_unit->get_rid()};
// ignore target if it is a collision object that might obstruct it's own collision test
@ -105,6 +105,11 @@ bool UnitWorldState::get_is_unit_enemy(Unit *unit) const {
&& unit->get_team() != this->parent_unit->get_team();
}
bool UnitWorldState::get_is_target_activated() const {
UtilityLock *lock{gd::Object::cast_to<UtilityLock>(this->target_node)};
return lock != nullptr && lock->get_activation_state() == UtilityLock::ActivationState::Done;
}
bool UnitWorldState::get_is_in_range() const {
return this->target_node != nullptr
&& this->target_node->get_global_position().distance_squared_to(this->parent_unit->get_global_position()) <= 2.f * 2.f;

View file

@ -32,6 +32,7 @@ public:
bool get_is_target_unit() const;
bool get_is_target_enemy() const;
bool get_is_unit_enemy(Unit *unit) const;
bool get_is_target_activated() const;
virtual bool get_is_in_range() const;
bool get_is_health_safe() const;
gd::Vector3 get_parent_global_position() const;