going/modules/going/player_states.h

94 lines
2.4 KiB
C++

#ifndef PLAYER_STATES_H
#define PLAYER_STATES_H
#include "core/object/object.h"
#include "core/templates/hash_map.h"
#include "scene/main/node.h"
class PlayerBody;
class PlayerState : public Object {
GDCLASS(PlayerState, Object);
friend class PlayerStateMachine;
public:
typedef StringName StateID;
public:
virtual StateID get_next_state() const {
return this->get_class();
}
virtual void state_entered() {}
virtual void process(double delta) {}
virtual void physics_process(double delta) {}
virtual void state_exited() {}
PlayerBody *get_body() const;
private:
PlayerBody *body{nullptr};
};
class StandingState : public PlayerState {
GDCLASS(StandingState, PlayerState);
public:
virtual StateID get_next_state() const override;
virtual void state_entered() override;
virtual void physics_process(double delta) override;
};
class RunningState : public PlayerState {
GDCLASS(RunningState, PlayerState);
public:
virtual StateID get_next_state() const override;
virtual void state_entered() override;
virtual void process(double delta) override;
virtual void physics_process(double delta) override;
virtual void state_exited() override;
private:
float lean_modifier{0.f};
};
class SplitStepState : public PlayerState {
GDCLASS(SplitStepState, PlayerState);
public:
virtual StateID get_next_state() const override;
virtual void state_entered() override;
virtual void process(double delta) override;
virtual void state_exited() override;
private:
Vector3 last_velocity{0.f, 0.f, 0.f};
double timer{0.0};
};
class FallingState : public PlayerState {
GDCLASS(FallingState, PlayerState);
public:
virtual StateID get_next_state() const override;
virtual void state_entered() override;
virtual void process(double delta) override;
};
class PlayerStateMachine : public Node {
GDCLASS(PlayerStateMachine, Node);
static void _bind_methods();
void _notification(int what);
void ready();
void try_transition();
template <class TState>
void add_state();
PlayerBody *body{nullptr};
PlayerState *current_state{nullptr};
HashMap<PlayerState::StateID, PlayerState*> states;
};
template <class TState>
void PlayerStateMachine::add_state() {
PlayerState *state{new TState()};
state->body = this->body;
this->states.insert(TState::get_class_static(), state);
if(this->current_state == nullptr) {
this->current_state = state;
state->state_entered();
}
}
#endif // !PLAYER_STATES_H