- Increased minimum version to 4.3 for compatibility with physics bones.
- Added an interface for nodes that can be damaged. - Character3D implements the above interface to make itself sliceable. - Added a hurtbox base class. - MeshEditingLibrary::slice_mesh now uses Godot references when possible. - Removed semicolon from print macros to enforce placing them in code.
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
[configuration]
|
[configuration]
|
||||||
|
|
||||||
entry_symbol = "orng_library_init"
|
entry_symbol = "orng_library_init"
|
||||||
compatibility_minimum = "4.2"
|
compatibility_minimum = "4.3"
|
||||||
reloadable = true
|
reloadable = true
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
env = SConscript("godot-cpp/SConstruct")
|
env = SConscript("godot-cpp/SConstruct")
|
||||||
env.Append(CPPPATH="liborng/")
|
env.Append(CPPPATH="liborng/")
|
||||||
env.Append(CPPPATH="liborng/data_assets")
|
env.Append(CPPPATH="liborng/data_assets")
|
||||||
|
env.Append(CPPPATH="liborng/nodes/interfaces")
|
||||||
env.Append(CPPPATH="liborng/nodes")
|
env.Append(CPPPATH="liborng/nodes")
|
||||||
env.Append(CPPPATH="liborng/nodes/character_nodes")
|
env.Append(CPPPATH="liborng/nodes/character_nodes")
|
||||||
env.Append(CPPPATH="liborng/resources")
|
env.Append(CPPPATH="liborng/resources")
|
||||||
|
|||||||
+1
-1
Submodule src/godot-cpp updated: 4bc6e67d51...d5cc777a89
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* If this source code makes it to the public internet, this software can be
|
||||||
|
* considered to be protected by the MIT licence. Have fun with it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "i_damageable.h"
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* If this source code makes it to the public internet, this software can be
|
||||||
|
* considered to be protected by the MIT licence. Have fun with it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <godot_cpp/variant/dictionary.hpp>
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
|
||||||
|
class IDamageable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void take_damage(const Dictionary &hit_data) = 0;
|
||||||
|
};
|
||||||
@@ -9,7 +9,10 @@
|
|||||||
|
|
||||||
#include "orng_macros.h"
|
#include "orng_macros.h"
|
||||||
|
|
||||||
|
#include "nodes/mesh_editing_library.h"
|
||||||
|
|
||||||
#include <godot_cpp/classes/engine.hpp>
|
#include <godot_cpp/classes/engine.hpp>
|
||||||
|
#include <godot_cpp/classes/physical_bone3d.hpp>
|
||||||
#include <godot_cpp/variant/utility_functions.hpp>
|
#include <godot_cpp/variant/utility_functions.hpp>
|
||||||
|
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
@@ -17,14 +20,51 @@ using namespace godot;
|
|||||||
|
|
||||||
void Character3D::_ready()
|
void Character3D::_ready()
|
||||||
{
|
{
|
||||||
set_animation_tree_path(this->animation_tree_path);
|
TypedArray<Node> child_mesh_candidates = this->skeleton->get_children();
|
||||||
|
const uint32_t num_children = child_mesh_candidates.size();
|
||||||
|
for (uint32_t i = 0; i < num_children; i++)
|
||||||
|
{
|
||||||
|
if (MeshInstance3D *mesh = cast_to<MeshInstance3D>(child_mesh_candidates[i]))
|
||||||
|
{
|
||||||
|
this->meshes.emplace_back(mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Character3D::set_animation_tree_path(NodePath at)
|
void Character3D::take_damage(const Dictionary &hit_data)
|
||||||
{
|
{
|
||||||
this->animation_tree_path = at;
|
PRINT_LOG(CHARACTER3D_TAG, "Taking damage: ", hit_data["hit_points"]);
|
||||||
this->animation_tree = cast_to<AnimationTree>(Node::get_node_or_null(this->animation_tree_path));
|
PRINT_LOG(CHARACTER3D_TAG, "Hit bones: ", hit_data["bone_hits"]);
|
||||||
|
|
||||||
|
const Transform3D &global_hit_transform = (Transform3D)hit_data["hit_transform"];
|
||||||
|
const Plane &slice_plane = this->skeleton->get_global_transform().inverse().xform(Plane(global_hit_transform.get_basis().get_column(1), global_hit_transform.origin));
|
||||||
|
const uint32_t num_meshes = this->meshes.size();
|
||||||
|
for (uint32_t i = 0; i < num_meshes; i++)
|
||||||
|
{
|
||||||
|
MeshInstance3D *original_mesh_instance = this->meshes[i];
|
||||||
|
Ref<ArrayMesh> first_half; first_half.instantiate();
|
||||||
|
Ref<ArrayMesh> other_half; other_half.instantiate();
|
||||||
|
PackedVector3Array &impact_points = MeshEditingLibrary::slice_mesh(original_mesh_instance, this->skeleton, slice_plane, first_half, other_half, MeshEditingLibrary::CAP_UV_FILL_MESH_BOUNDS, original_mesh_instance->get_active_material(0));
|
||||||
|
|
||||||
|
if (other_half.is_valid())
|
||||||
|
original_mesh_instance->set_mesh(other_half);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Character3D::_activate_ragdoll()
|
||||||
|
{
|
||||||
|
const TypedArray<Node> &physical_bones = this->physical_bone_simulator->get_children();
|
||||||
|
const uint32_t num_physical_bones = physical_bones.size();
|
||||||
|
for (uint32_t i = 0; i < num_physical_bones; i++)
|
||||||
|
{
|
||||||
|
if (PhysicalBone3D *bone = cast_to<PhysicalBone3D>(physical_bones[i]))
|
||||||
|
{
|
||||||
|
bone->set_collision_layer(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->physical_bone_simulator->physical_bones_start_simulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,33 +9,49 @@
|
|||||||
|
|
||||||
#include "orng_macros.h"
|
#include "orng_macros.h"
|
||||||
|
|
||||||
|
#include "interfaces/i_damageable.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <godot_cpp/classes/animation_tree.hpp>
|
#include <godot_cpp/classes/animation_tree.hpp>
|
||||||
#include <godot_cpp/classes/character_body3d.hpp>
|
#include <godot_cpp/classes/character_body3d.hpp>
|
||||||
|
#include <godot_cpp/classes/mesh_instance3d.hpp>
|
||||||
|
#include <godot_cpp/classes/physical_bone_simulator3d.hpp>
|
||||||
|
#include <godot_cpp/classes/skeleton3d.hpp>
|
||||||
|
#include <godot_cpp/variant/dictionary.hpp>
|
||||||
using namespace godot;
|
using namespace godot;
|
||||||
|
|
||||||
#define CHARACTER3D_TAG "Character3D"
|
#define CHARACTER3D_TAG "Character3D"
|
||||||
|
|
||||||
|
|
||||||
class Character3D : public CharacterBody3D
|
class Character3D : public CharacterBody3D, public IDamageable
|
||||||
{
|
{
|
||||||
GDCLASS(Character3D, CharacterBody3D);
|
GDCLASS(Character3D, CharacterBody3D);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void _ready() override;
|
virtual void _ready() override;
|
||||||
|
|
||||||
|
virtual void take_damage(const Dictionary &hit_data) override;
|
||||||
|
|
||||||
|
Skeleton3D *get_skeleton() const { return this->skeleton; }
|
||||||
|
PhysicalBoneSimulator3D *get_physical_bone_simulator() const { return this->physical_bone_simulator; }
|
||||||
|
AnimationTree *get_animation_tree() const { return this->animation_tree; }
|
||||||
|
|
||||||
virtual void _on_fell_out_of_world();
|
virtual void _on_fell_out_of_world();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void set_animation_tree_path(NodePath at);
|
void set_skeleton(Skeleton3D *s) { this->skeleton = s; }
|
||||||
NodePath get_animation_tree_path() const { return this->animation_tree_path; }
|
void set_physical_bone_simulator(PhysicalBoneSimulator3D *pbs) { this->physical_bone_simulator = pbs; }
|
||||||
|
void set_animation_tree(AnimationTree *at) { this->animation_tree = at; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AnimationTree *get_animation_tree() const { return this->animation_tree; }
|
void _activate_ragdoll();
|
||||||
|
|
||||||
NodePath animation_tree_path;
|
Skeleton3D *skeleton = nullptr;
|
||||||
|
PhysicalBoneSimulator3D *physical_bone_simulator = nullptr;
|
||||||
AnimationTree *animation_tree = nullptr;
|
AnimationTree *animation_tree = nullptr;
|
||||||
|
|
||||||
|
std::vector<MeshInstance3D*> meshes;
|
||||||
|
|
||||||
// Godot boilerplate below
|
// Godot boilerplate below
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods()
|
static void _bind_methods()
|
||||||
@@ -44,10 +60,16 @@ protected:
|
|||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("fell_out_of_world"));
|
ADD_SIGNAL(MethodInfo("fell_out_of_world"));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_animation_tree_path"), &Character3D::get_animation_tree_path);
|
ClassDB::bind_method(D_METHOD("get_skeleton"), &Character3D::get_skeleton);
|
||||||
ClassDB::bind_method(D_METHOD("set_animation_tree_path", "animation_tree"), &Character3D::set_animation_tree_path);
|
ClassDB::bind_method(D_METHOD("set_skeleton", "skeleton"), &Character3D::set_skeleton);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_tree", PROPERTY_HINT_NODE_TYPE, "AnimationTree"), "set_animation_tree_path", "get_animation_tree_path");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton", PROPERTY_HINT_NODE_TYPE, "Skeleton3D"), "set_skeleton", "get_skeleton");
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("get_physical_bone_simulator"), &Character3D::get_physical_bone_simulator);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_physical_bone_simulator", "physical_bone_simulator"), &Character3D::set_physical_bone_simulator);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physical_bone_simulator", PROPERTY_HINT_NODE_TYPE, "PhysicalBoneSimulator3D"), "set_physical_bone_simulator", "get_physical_bone_simulator");
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_animation_tree"), &Character3D::get_animation_tree);
|
ClassDB::bind_method(D_METHOD("get_animation_tree"), &Character3D::get_animation_tree);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_animation_tree", "animation_tree"), &Character3D::set_animation_tree);
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "animation_tree", PROPERTY_HINT_NODE_TYPE, "AnimationTree"), "set_animation_tree", "get_animation_tree");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* If this source code makes it to the public internet, this software can be
|
||||||
|
* considered to be protected by the MIT licence. Have fun with it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hurtbox_base.h"
|
||||||
|
#include "orng_macros.h"
|
||||||
|
|
||||||
|
#include "character_3d.h"
|
||||||
|
|
||||||
|
#include <godot_cpp/classes/physical_bone3d.hpp>
|
||||||
|
#include <godot_cpp/classes/scene_tree.hpp>
|
||||||
|
#include <godot_cpp/classes/scene_tree_timer.hpp>
|
||||||
|
#include <godot_cpp/variant/utility_functions.hpp>
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
|
||||||
|
void HurtboxBase::_ready()
|
||||||
|
{
|
||||||
|
this->set_process(false);
|
||||||
|
this->remaining_life = this->lifetime;
|
||||||
|
|
||||||
|
CALL_NEXT_FRAME(callable_mp(this, &HurtboxBase::_send_next_in_queue));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HurtboxBase::_physics_process(double delta)
|
||||||
|
{
|
||||||
|
if (this->remaining_life <= 0.0f)
|
||||||
|
{
|
||||||
|
this->collision_shape->set_disabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedArray<Character3D> characters_hit_this_frame;
|
||||||
|
|
||||||
|
const TypedArray<Node3D> &bodies = this->get_overlapping_bodies();
|
||||||
|
const uint32_t num_bodies = bodies.size();
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < num_bodies; i++)
|
||||||
|
{
|
||||||
|
if (Character3D *body = cast_to<Character3D>(bodies[i]))
|
||||||
|
{
|
||||||
|
if (!this->hit_character_bodies.has(body))
|
||||||
|
{
|
||||||
|
characters_hit_this_frame.append(body);
|
||||||
|
TypedArray<int32_t> bone_hits;
|
||||||
|
|
||||||
|
for (uint32_t bone_index = 0; bone_index < num_bodies; bone_index++)
|
||||||
|
{
|
||||||
|
if (PhysicalBone3D *bone = cast_to<PhysicalBone3D>(bodies[bone_index]))
|
||||||
|
{
|
||||||
|
if (String(bone->get_path()).begins_with(String(body->get_path())))
|
||||||
|
{
|
||||||
|
bone_hits.append(bone->get_bone_id());
|
||||||
|
PRINT_LOG(HURTBOX_BASE_TAG, "Bone hit: ", bone->get_name(), " (", bone->get_class(), " : ", bone->get_rid(), ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT_LOG(HURTBOX_BASE_TAG, "Character hit: ", body->get_name(), " (", body->get_class(), " : ", body->get_rid(), ")");
|
||||||
|
|
||||||
|
Dictionary hit_data;
|
||||||
|
hit_data["body"] = body;
|
||||||
|
hit_data["bone_hits"] = bone_hits;
|
||||||
|
hit_data["hit_points"] = this->hit_points;
|
||||||
|
hit_data["hit_transform"] = this->get_global_transform();
|
||||||
|
|
||||||
|
this->hit_data_queue.emplace_back(hit_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->hit_character_bodies.append_array(characters_hit_this_frame);
|
||||||
|
|
||||||
|
this->remaining_life -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HurtboxBase::_send_next_in_queue()
|
||||||
|
{
|
||||||
|
if (!this->hit_data_queue.empty())
|
||||||
|
{
|
||||||
|
const Dictionary &hit_data = this->hit_data_queue.front();
|
||||||
|
Character3D *body = cast_to<Character3D>(hit_data["body"]);
|
||||||
|
body->take_damage(hit_data);
|
||||||
|
this->hit_data_queue.erase(this->hit_data_queue.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->remaining_life > 0.0f)
|
||||||
|
{
|
||||||
|
CALL_NEXT_FRAME(callable_mp(this, &HurtboxBase::_send_next_in_queue));
|
||||||
|
}
|
||||||
|
else if (this->hit_data_queue.empty())
|
||||||
|
{
|
||||||
|
this->queue_free();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* If this source code makes it to the public internet, this software can be
|
||||||
|
* considered to be protected by the MIT licence. Have fun with it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "orng_macros.h"
|
||||||
|
|
||||||
|
#include "character_3d.h"
|
||||||
|
|
||||||
|
#include <godot_cpp/classes/collision_shape3d.hpp>
|
||||||
|
#include <godot_cpp/classes/area3d.hpp>
|
||||||
|
using namespace godot;
|
||||||
|
|
||||||
|
#define HURTBOX_BASE_TAG "HurtboxBase"
|
||||||
|
|
||||||
|
|
||||||
|
class HurtboxBase : public Area3D
|
||||||
|
{
|
||||||
|
GDCLASS(HurtboxBase, Area3D);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void _ready() override;
|
||||||
|
virtual void _physics_process(double delta) override;
|
||||||
|
|
||||||
|
void set_collision_shape(CollisionShape3D *cs) { this->collision_shape = cs; }
|
||||||
|
CollisionShape3D *get_collision_shape() const { return this->collision_shape; }
|
||||||
|
|
||||||
|
void set_lifetime(const float lt) { this->lifetime = lt; }
|
||||||
|
float get_lifetime() const { return this->lifetime; }
|
||||||
|
|
||||||
|
void set_hit_points(const int32_t points) { this->hit_points = points; }
|
||||||
|
int32_t get_hit_points() const { return this->hit_points; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<Dictionary> hit_data_queue;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Dictionary _create_hit_data_struct() const;
|
||||||
|
void _send_next_in_queue();
|
||||||
|
|
||||||
|
CollisionShape3D *collision_shape = nullptr;
|
||||||
|
|
||||||
|
float lifetime = 0.05f;
|
||||||
|
float remaining_life = 0.0f;
|
||||||
|
int32_t hit_points = 0;
|
||||||
|
|
||||||
|
TypedArray<Character3D> hit_character_bodies;
|
||||||
|
|
||||||
|
|
||||||
|
// Godot boilerplate below
|
||||||
|
protected:
|
||||||
|
static void _bind_methods()
|
||||||
|
{
|
||||||
|
ADD_GETTER_SETTER_HINTED(HurtboxBase, collision_shape, Variant::OBJECT, PROPERTY_HINT_NODE_TYPE, "CollisionShape3D");
|
||||||
|
|
||||||
|
ADD_GETTER_SETTER(HurtboxBase, lifetime, Variant::FLOAT);
|
||||||
|
ADD_GETTER_SETTER(HurtboxBase, hit_points, Variant::INT);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_send_next_in_queue"), &HurtboxBase::_send_next_in_queue);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -24,7 +24,7 @@ MeshEditingLibrary::~MeshEditingLibrary()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedVector3Array MeshEditingLibrary::slice_mesh(const MeshInstance3D *original_mesh_instance, const Skeleton3D *original_skeleton, const Plane &local_plane, ArrayMesh *out_first_half, ArrayMesh *out_other_half, const MeshEditCapUV cap_option, const Ref<StandardMaterial3D> cap_material)
|
PackedVector3Array MeshEditingLibrary::slice_mesh(const MeshInstance3D *original_mesh_instance, const Skeleton3D *original_skeleton, const Plane &local_plane, Ref<ArrayMesh> out_first_half, Ref<ArrayMesh> out_other_half, const MeshEditCapUV cap_option, const Ref<StandardMaterial3D> cap_material)
|
||||||
{
|
{
|
||||||
const Time *time = Time::get_singleton();
|
const Time *time = Time::get_singleton();
|
||||||
|
|
||||||
@@ -535,6 +535,9 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(const MeshInstance3D *original
|
|||||||
polygon_centroid += position;
|
polygon_centroid += position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
||||||
|
impact_points.append(polygon_centroid);
|
||||||
|
|
||||||
earcut_polygon.push_back(sub_polygon);
|
earcut_polygon.push_back(sub_polygon);
|
||||||
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(earcut_polygon);
|
std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(earcut_polygon);
|
||||||
for (uint32_t i = 0; (i+2) < indices.size(); i += 3)
|
for (uint32_t i = 0; (i+2) < indices.size(); i += 3)
|
||||||
@@ -543,9 +546,6 @@ PackedVector3Array MeshEditingLibrary::slice_mesh(const MeshInstance3D *original
|
|||||||
cap_section_indices.append(indices[i] + polygon_vertex_base);
|
cap_section_indices.append(indices[i] + polygon_vertex_base);
|
||||||
cap_section_indices.append(indices[i+2] + polygon_vertex_base);
|
cap_section_indices.append(indices[i+2] + polygon_vertex_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
polygon_centroid /= polygon_set[polygon_index].vertices.size();
|
|
||||||
impact_points.append(polygon_centroid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
CAP_UV_TILED
|
CAP_UV_TILED
|
||||||
};
|
};
|
||||||
|
|
||||||
static PackedVector3Array slice_mesh(const MeshInstance3D *original_mesh_instance, const Skeleton3D *original_skeleton, const Plane &local_plane, ArrayMesh *out_first_half, ArrayMesh *out_other_half, const MeshEditCapUV cap_option, const Ref<StandardMaterial3D> cap_material);
|
static PackedVector3Array slice_mesh(const MeshInstance3D *original_mesh_instance, const Skeleton3D *original_skeleton, const Plane &local_plane, Ref<ArrayMesh> out_first_half, Ref<ArrayMesh> out_other_half, const MeshEditCapUV cap_option, const Ref<StandardMaterial3D> cap_material);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum MeshSlicePlaneOrientation
|
enum MeshSlicePlaneOrientation
|
||||||
|
|||||||
@@ -52,9 +52,9 @@
|
|||||||
* Logging helpers
|
* Logging helpers
|
||||||
*/
|
*/
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
#define PRINT_LOG(tag, ...) UtilityFunctions::print("[" tag "] " __VA_ARGS__);
|
#define PRINT_LOG(tag, ...) UtilityFunctions::print("[" tag "] ", __VA_ARGS__)
|
||||||
#define PRINT_WARNING(tag, ...) UtilityFunctions::push_warning("[" tag "] " __VA_ARGS__);
|
#define PRINT_WARNING(tag, ...) UtilityFunctions::push_warning("[" tag "] ", __VA_ARGS__)
|
||||||
#define PRINT_ERROR(tag, ...) UtilityFunctions::printerr("[" tag "] " __VA_ARGS__);
|
#define PRINT_ERROR(tag, ...) UtilityFunctions::printerr("[" tag "] ", __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define PRINT_LOG(tag, ...)
|
#define PRINT_LOG(tag, ...)
|
||||||
#define PRINT_WARNING(tag, ...)
|
#define PRINT_WARNING(tag, ...)
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include "nodes/sublevel_scene.h"
|
#include "nodes/sublevel_scene.h"
|
||||||
#include "nodes/character_nodes/character_3d.h"
|
#include "nodes/character_nodes/character_3d.h"
|
||||||
|
|
||||||
|
#include "nodes/hurtbox/hurtbox_base.h"
|
||||||
|
|
||||||
#include "resources/level_metadata_map.h"
|
#include "resources/level_metadata_map.h"
|
||||||
#include "resources/level_metadata_resource.h"
|
#include "resources/level_metadata_resource.h"
|
||||||
|
|
||||||
@@ -69,6 +71,8 @@ void initialize_orng_module(ModuleInitializationLevel p_level) {
|
|||||||
ClassDB::register_class<PlayerOrigin>();
|
ClassDB::register_class<PlayerOrigin>();
|
||||||
ClassDB::register_class<PlayerSpawn>();
|
ClassDB::register_class<PlayerSpawn>();
|
||||||
|
|
||||||
|
ClassDB::register_class<HurtboxBase>();
|
||||||
|
|
||||||
ClassDB::register_class<SaveFileData>();
|
ClassDB::register_class<SaveFileData>();
|
||||||
|
|
||||||
ClassDB::register_class<MeshEditingLibrary>();
|
ClassDB::register_class<MeshEditingLibrary>();
|
||||||
|
|||||||
Reference in New Issue
Block a user