equipment-test/modules/tabtargeting/actor_state_machine.h
2025-06-13 15:12:22 +02:00

71 lines
1.7 KiB
C++

#ifndef ACTOR_STATE_MACHINE_H
#define ACTOR_STATE_MACHINE_H
#include "core/string/string_name.h"
#include "scene/main/node.h"
#include "core/object/ref_counted.h"
class ActorBody;
class ActorState : public RefCounted {
GDCLASS(ActorState, Object);
static void _bind_methods();
public:
virtual void state_entered() {}
virtual void process(double delta) {}
virtual StringName next_state() const {
return this->get_class();
}
virtual void state_exited() {}
protected:
ActorBody *body{nullptr};
friend class ActorStateMachine;
};
class ActorStateMachine : public Node {
GDCLASS(ActorStateMachine, Node);
static void _bind_methods();
void _notification(int what);
void ready();
void process(double delta);
template <class TState>
void add_state();
void try_next_state();
void switch_state(ActorState *state);
private:
ActorBody *body{nullptr};
ActorState *current_state{};
HashMap<StringName, ActorState*> states{};
};
template <class TState>
void ActorStateMachine::add_state() {
ActorState *state{memnew(TState)};
state->body = this->body;
this->states.insert(TState::get_class_static(), state);
if(current_state == nullptr) {
this->current_state = state;
}
}
class IdleState : public ActorState {
GDCLASS(IdleState, ActorState);
static void _bind_methods();
public:
virtual void state_exited() override;
virtual StringName next_state() const override;
};
class ActingState : public ActorState {
GDCLASS(ActingState, ActorState);
static void _bind_methods();
public:
virtual void state_entered() override;
virtual void process(double delta) override;
virtual StringName next_state() const override;
private:
double const seconds_to_wait{1.0};
double timer{0.0};
};
#endif // !ACTOR_STATE_MACHINE_H