feat: added interactions, demo packs and destructables
This commit is contained in:
parent
d66c999039
commit
5a4ac26c72
12 changed files with 369 additions and 23 deletions
33
modules/wave_survival/interactable.cpp
Normal file
33
modules/wave_survival/interactable.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include "interactable.h"
|
||||
#include "macros.h"
|
||||
|
||||
void Interactable::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("activate", "interactor"), &self_type::activate);
|
||||
ClassDB::bind_method(D_METHOD("set_highlighted", "value"), &self_type::set_highlighted);
|
||||
ClassDB::bind_method(D_METHOD("get_highlighted"), &self_type::get_highlighted);
|
||||
GDVIRTUAL_BIND(_activated, "interactor");
|
||||
GDVIRTUAL_BIND(_highlight_changed, "interactor", "value");
|
||||
}
|
||||
|
||||
void Interactable::activate(PlayerInteractor *interactor) {
|
||||
activated(interactor);
|
||||
GDVIRTUAL_CALL(_activated, interactor);
|
||||
}
|
||||
|
||||
void Interactable::set_highlighted(PlayerInteractor *interactor, bool value) {
|
||||
this->highlighted = value;
|
||||
highlight_changed(interactor, value);
|
||||
GDVIRTUAL_CALL(_highlight_changed, interactor, value);
|
||||
}
|
||||
|
||||
bool Interactable::get_highlighted() const {
|
||||
return this->highlighted;
|
||||
}
|
||||
|
||||
void Interactable::set_highlight_tooltip(String value) {
|
||||
this->highlight_tooltip = value;
|
||||
}
|
||||
|
||||
String Interactable::get_highlight_tooltip() const {
|
||||
return this->highlight_tooltip;
|
||||
}
|
||||
30
modules/wave_survival/interactable.h
Normal file
30
modules/wave_survival/interactable.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef INTERACTABLE_H
|
||||
#define INTERACTABLE_H
|
||||
|
||||
#include "player_interactor.h"
|
||||
#include "scene/main/node.h"
|
||||
|
||||
class Interactable : public Node {
|
||||
GDCLASS(Interactable, Node);
|
||||
static void _bind_methods();
|
||||
|
||||
protected:
|
||||
virtual void activated(PlayerInteractor *interactor) {}
|
||||
GDVIRTUAL1_REQUIRED(_activated, PlayerInteractor *);
|
||||
virtual void highlight_changed(PlayerInteractor *interactor, bool new_value) {}
|
||||
GDVIRTUAL2(_highlight_changed, PlayerInteractor *, bool);
|
||||
|
||||
public:
|
||||
void activate(PlayerInteractor *interactor);
|
||||
|
||||
void set_highlighted(PlayerInteractor *interactor, bool value);
|
||||
bool get_highlighted() const;
|
||||
void set_highlight_tooltip(String value);
|
||||
String get_highlight_tooltip() const;
|
||||
|
||||
private:
|
||||
bool highlighted{ false };
|
||||
String highlight_tooltip{ "Activate" };
|
||||
};
|
||||
|
||||
#endif // !INTERACTABLE_H
|
||||
|
|
@ -9,6 +9,7 @@ String PlayerInput::sig_switch_weapon{ "switch_weapon" };
|
|||
String PlayerInput::sig_run{ "run" };
|
||||
String PlayerInput::sig_jump{ "jump" };
|
||||
String PlayerInput::sig_crouch{ "crouch" };
|
||||
String PlayerInput::sig_activate{ "activate" };
|
||||
|
||||
void PlayerInput::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo(sig_movement_input, PropertyInfo(Variant::VECTOR2, "axes")));
|
||||
|
|
@ -19,6 +20,7 @@ void PlayerInput::_bind_methods() {
|
|||
ADD_SIGNAL(MethodInfo(sig_run, PropertyInfo(Variant::BOOL, "is_running")));
|
||||
ADD_SIGNAL(MethodInfo(sig_jump));
|
||||
ADD_SIGNAL(MethodInfo(sig_crouch, PropertyInfo(Variant::BOOL, "is_crouching")));
|
||||
ADD_SIGNAL(MethodInfo(sig_activate));
|
||||
}
|
||||
|
||||
void PlayerInput::normalize_input() {
|
||||
|
|
@ -83,4 +85,7 @@ void PlayerInput::unhandled_input(Ref<InputEvent> const &event) {
|
|||
if (event->is_action("switch_weapon") && event->is_pressed()) {
|
||||
emit_signal(sig_switch_weapon);
|
||||
}
|
||||
if (event->is_action("activate") && event->is_pressed()) {
|
||||
emit_signal(sig_activate);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public:
|
|||
static String sig_run;
|
||||
static String sig_jump;
|
||||
static String sig_crouch;
|
||||
static String sig_activate;
|
||||
|
||||
private:
|
||||
bool was_paused{ false };
|
||||
|
|
|
|||
87
modules/wave_survival/player_interactor.cpp
Normal file
87
modules/wave_survival/player_interactor.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#include "player_interactor.h"
|
||||
#include "interactable.h"
|
||||
#include "player_body.h"
|
||||
#include "player_input.h"
|
||||
|
||||
void PlayerInteractor::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("pickup_demo_pack"), &self_type::pickup_demo_pack);
|
||||
ClassDB::bind_method(D_METHOD("try_use_demo_pack"), &self_type::try_use_demo_pack);
|
||||
}
|
||||
|
||||
void PlayerInteractor::highlight_removed() {
|
||||
this->interactable->disconnect("tree_exiting", this->on_highlight_removed);
|
||||
this->interactable->set_highlighted(this, false);
|
||||
this->interactable = nullptr;
|
||||
}
|
||||
|
||||
void PlayerInteractor::activate() {
|
||||
if (interactable != nullptr) {
|
||||
interactable->activate(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerInteractor::ready() {
|
||||
PlayerInput *input{ cast_to<PlayerInput>(get_node(NodePath("%PlayerInput"))) };
|
||||
input->connect(PlayerInput::sig_activate, callable_mp(this, &self_type::activate));
|
||||
}
|
||||
|
||||
void PlayerInteractor::process(double delta) {
|
||||
Interactable *new_interactable{ nullptr };
|
||||
if (is_colliding()) {
|
||||
if (Node * hit{ cast_to<Node>(this->get_collider(0)) }) {
|
||||
TypedArray<Node> interactables = hit->find_children("*", Interactable::get_class_static());
|
||||
new_interactable = interactables.size() > 0 ? cast_to<Interactable>(interactables[0]) : nullptr;
|
||||
}
|
||||
}
|
||||
if (new_interactable != this->interactable) {
|
||||
if (this->interactable != nullptr) {
|
||||
this->interactable->set_highlighted(this, false);
|
||||
this->interactable->disconnect("tree_exiting", this->on_highlight_removed);
|
||||
}
|
||||
this->interactable = new_interactable;
|
||||
if (this->interactable != nullptr) {
|
||||
this->interactable->set_highlighted(this, true);
|
||||
this->interactable->connect("tree_exiting", this->on_highlight_removed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerInteractor::_notification(int what) {
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
switch (what) {
|
||||
default:
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
set_process(true);
|
||||
ready();
|
||||
return;
|
||||
case NOTIFICATION_PROCESS:
|
||||
process(get_process_delta_time());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PackedStringArray PlayerInteractor::get_configuration_warnings() const {
|
||||
PackedStringArray warnings{ super_type::get_configuration_warnings() };
|
||||
if (cast_to<PlayerBody>(get_owner()) == nullptr) {
|
||||
warnings.push_back("PlayerInteractor should be part of and owned by a PlayerBody node to work properly.");
|
||||
}
|
||||
if (get_node(NodePath("%PlayerInput")) == nullptr) {
|
||||
warnings.push_back("PlayerInteractor should have a node named '%PlayerInput' in the same scene as it");
|
||||
}
|
||||
return warnings;
|
||||
}
|
||||
|
||||
void PlayerInteractor::pickup_demo_pack() {
|
||||
++this->num_demo_packs;
|
||||
}
|
||||
|
||||
bool PlayerInteractor::try_use_demo_pack() {
|
||||
if (this->num_demo_packs > 0) {
|
||||
--this->num_demo_packs;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
30
modules/wave_survival/player_interactor.h
Normal file
30
modules/wave_survival/player_interactor.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef PLAYER_INTERACTOR_H
|
||||
#define PLAYER_INTERACTOR_H
|
||||
|
||||
#include "scene/3d/physics/shape_cast_3d.h"
|
||||
class Interactable;
|
||||
|
||||
class PlayerInteractor : public ShapeCast3D {
|
||||
GDCLASS(PlayerInteractor, ShapeCast3D);
|
||||
static void _bind_methods();
|
||||
void highlight_removed();
|
||||
void activate();
|
||||
void ready();
|
||||
void process(double delta);
|
||||
|
||||
protected:
|
||||
void _notification(int what);
|
||||
|
||||
public:
|
||||
virtual PackedStringArray get_configuration_warnings() const override;
|
||||
void pickup_demo_pack();
|
||||
bool try_use_demo_pack();
|
||||
|
||||
private:
|
||||
int num_demo_packs{ 0 };
|
||||
Interactable *interactable{ nullptr };
|
||||
Callable on_highlight_removed{ callable_mp(this, &self_type::highlight_removed) };
|
||||
static String activate_method_name;
|
||||
};
|
||||
|
||||
#endif // !PLAYER_INTERACTOR_H
|
||||
|
|
@ -7,12 +7,14 @@
|
|||
#include "wave_survival/health_status.h"
|
||||
#include "wave_survival/hitbox.h"
|
||||
#include "wave_survival/hitscan_muzzle.h"
|
||||
#include "wave_survival/interactable.h"
|
||||
#include "wave_survival/npc_unit.h"
|
||||
#include "wave_survival/patrol_path.h"
|
||||
#include "wave_survival/player_body.h"
|
||||
#include "wave_survival/player_camera.h"
|
||||
#include "wave_survival/player_detector.h"
|
||||
#include "wave_survival/player_input.h"
|
||||
#include "wave_survival/player_interactor.h"
|
||||
#include "wave_survival/state.h"
|
||||
#include "wave_survival/state_machine.h"
|
||||
#include "wave_survival/weapon_base.h"
|
||||
|
|
@ -43,6 +45,8 @@ void initialize_wave_survival_module(ModuleInitializationLevel p_level) {
|
|||
GDREGISTER_CLASS(PlayerDetector);
|
||||
GDREGISTER_CLASS(Hitbox);
|
||||
GDREGISTER_CLASS(DamageBox);
|
||||
GDREGISTER_CLASS(PlayerInteractor);
|
||||
GDREGISTER_CLASS(Interactable);
|
||||
}
|
||||
|
||||
void uninitialize_wave_survival_module(ModuleInitializationLevel p_level) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ public:
|
|||
void set_starting_weapon(Ref<PackedScene> weapon_scene);
|
||||
Ref<PackedScene> get_starting_weapon() const;
|
||||
|
||||
void pickup_demo_pack();
|
||||
bool try_use_demo_pack();
|
||||
|
||||
private:
|
||||
Node3D *weapon_parent{ nullptr };
|
||||
unsigned current{ 0 };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue