Compare commits
No commits in common. "6c0fc171969de62038c09ef7bac5c66fab6ffed5" and "96b5be405c814b5dba66294ec98f362bf2fe7b40" have entirely different histories.
6c0fc17196
...
96b5be405c
|
@ -22,7 +22,7 @@ void EnemyBody::ready() {
|
||||||
|
|
||||||
void EnemyBody::physics_process(double delta) {
|
void EnemyBody::physics_process(double delta) {
|
||||||
GETSET(velocity, {
|
GETSET(velocity, {
|
||||||
velocity = Vector3{ this->movement_direction.x * this->movement_speed, velocity.y, this->movement_direction.y * this->movement_speed } + (velocity * delta);
|
velocity = Vector3{ this->movement_direction.x * this->movement_speed, velocity.y, this->movement_direction.y * this->movement_speed };
|
||||||
});
|
});
|
||||||
if (!this->movement_direction.is_zero_approx()) {
|
if (!this->movement_direction.is_zero_approx()) {
|
||||||
look_at(get_global_position() + Vector3{ this->movement_direction.x, 0.f, this->movement_direction.y });
|
look_at(get_global_position() + Vector3{ this->movement_direction.x, 0.f, this->movement_direction.y });
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
#include "enemy_spawner.h"
|
|
||||||
#include "core/io/resource.h"
|
|
||||||
#include "core/object/object.h"
|
|
||||||
#include "macros.h"
|
|
||||||
#include "map_region.h"
|
|
||||||
#include "npc_unit.h"
|
|
||||||
#include "patrol_path.h"
|
|
||||||
#include "scene/resources/packed_scene.h"
|
|
||||||
|
|
||||||
void SpawnData::_bind_methods() {
|
|
||||||
BIND_HPROPERTY(Variant::DICTIONARY, difficulty_spawns, PROPERTY_HINT_DICTIONARY_TYPE, vformat("int;%s/%s:PackedScene", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpawnData::set_difficulty_spawns(Dictionary dict) {
|
|
||||||
this->difficulty_spawns.clear();
|
|
||||||
for (KeyValue<Variant, Variant> const &kvp : dict) {
|
|
||||||
Ref<PackedScene> scene{ kvp.value };
|
|
||||||
if (scene.is_null() || !scene.is_valid()) {
|
|
||||||
continue;
|
|
||||||
} else if (!kvp.key.is_num()) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
this->difficulty_spawns.insert(kvp.key, scene);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary SpawnData::get_difficulty_spawns() const {
|
|
||||||
Dictionary r{};
|
|
||||||
for (KeyValue<int, Ref<PackedScene>> const &kvp : this->difficulty_spawns) {
|
|
||||||
r.set(kvp.key, kvp.value);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnemySpawner::_bind_methods() {
|
|
||||||
BIND_HPROPERTY(Variant::OBJECT, spawn_data, PROPERTY_HINT_RESOURCE_TYPE, "SpawnData");
|
|
||||||
BIND_HPROPERTY(Variant::OBJECT, patrol_path, PROPERTY_HINT_NODE_TYPE, "PatrolPath");
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnemySpawner::on_phase_change(bool hunt) {
|
|
||||||
Ref<PackedScene> scene{ Ref<PackedScene>() };
|
|
||||||
int const idx{ this->region->get_current_difficulty() };
|
|
||||||
if (this->spawn_data->difficulty_spawns.has(idx)) {
|
|
||||||
scene = this->spawn_data->difficulty_spawns[idx];
|
|
||||||
}
|
|
||||||
if (!scene.is_valid()) {
|
|
||||||
print_error("EnemySpawner::on_phase_change: Spawn data scene is invalid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Node *instantiated{ scene->instantiate() };
|
|
||||||
if (instantiated == nullptr) {
|
|
||||||
print_error("EnemySpawner::on_phase_change: Spawn data instantiated a nullptr node");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NpcUnit *unit_3d{ cast_to<NpcUnit>(instantiated) };
|
|
||||||
if (unit_3d == nullptr) {
|
|
||||||
instantiated->queue_free();
|
|
||||||
print_error("EnemySpawner::on_phase_change: Spawn data instantiated an invalid unit that cannot be cast to NpcUnit");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
unit_3d->set_patrol_path(this->patrol_path);
|
|
||||||
add_child(unit_3d);
|
|
||||||
unit_3d->set_global_transform(this->get_global_transform());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnemySpawner::ready() {
|
|
||||||
if (MapRegion * region{ cast_to<MapRegion>(this->get_parent()) }) {
|
|
||||||
this->region = region;
|
|
||||||
region->connect(MapRegion::sig_phase_changed, callable_mp(this, &self_type::on_phase_change));
|
|
||||||
} else {
|
|
||||||
print_error("EnemySpawner::ready: Failed to find region in parent");
|
|
||||||
}
|
|
||||||
if (!this->spawn_data.is_valid()) {
|
|
||||||
this->spawn_data = ResourceLoader::load("res://data/spawn_data/default.tres");
|
|
||||||
}
|
|
||||||
if (this->spawn_data.is_valid()) {
|
|
||||||
on_phase_change(false);
|
|
||||||
} else {
|
|
||||||
print_error("EnemySpawner::ready: No spawn data found, default spawn data is invalid, consider setting up a default spawn data");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnemySpawner::_notification(int what) {
|
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (what) {
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
case NOTIFICATION_READY:
|
|
||||||
ready();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnemySpawner::set_spawn_data(Ref<SpawnData> data) {
|
|
||||||
this->spawn_data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<SpawnData> EnemySpawner::get_spawn_data() const {
|
|
||||||
return this->spawn_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnemySpawner::set_patrol_path(PatrolPath *path) {
|
|
||||||
this->patrol_path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
PatrolPath *EnemySpawner::get_patrol_path() const {
|
|
||||||
return this->patrol_path;
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
#ifndef ENEMY_SPAWNER_H
|
|
||||||
#define ENEMY_SPAWNER_H
|
|
||||||
|
|
||||||
#include "core/io/resource.h"
|
|
||||||
#include "core/templates/hash_map.h"
|
|
||||||
#include "scene/3d/node_3d.h"
|
|
||||||
class MapRegion;
|
|
||||||
class PatrolPath;
|
|
||||||
|
|
||||||
class SpawnData : public Resource {
|
|
||||||
GDCLASS(SpawnData, Resource);
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
public:
|
|
||||||
void set_difficulty_spawns(Dictionary dict);
|
|
||||||
Dictionary get_difficulty_spawns() const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
HashMap<int, Ref<PackedScene>> difficulty_spawns{};
|
|
||||||
};
|
|
||||||
|
|
||||||
class EnemySpawner : public Node3D {
|
|
||||||
GDCLASS(EnemySpawner, Node3D);
|
|
||||||
static void _bind_methods();
|
|
||||||
void on_phase_change(bool hunt);
|
|
||||||
void ready();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _notification(int what);
|
|
||||||
|
|
||||||
public:
|
|
||||||
void set_spawn_data(Ref<SpawnData> data);
|
|
||||||
Ref<SpawnData> get_spawn_data() const;
|
|
||||||
void set_patrol_path(PatrolPath *path);
|
|
||||||
PatrolPath *get_patrol_path() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ref<SpawnData> spawn_data{};
|
|
||||||
PatrolPath *patrol_path{ nullptr };
|
|
||||||
MapRegion *region{ nullptr };
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // !ENEMY_SPAWNER_H
|
|
|
@ -1,12 +1,10 @@
|
||||||
#include "map_region.h"
|
#include "map_region.h"
|
||||||
#include "enemy_body.h"
|
#include "enemy_body.h"
|
||||||
|
|
||||||
String const MapRegion::sig_difficulty_increased{ "difficulty_increased" };
|
String const MapRegion::sig_phase_changed{ "phase_changed" };
|
||||||
String const MapRegion::sig_phase_changed{ "hunt_phase" };
|
|
||||||
|
|
||||||
void MapRegion::_bind_methods() {
|
void MapRegion::_bind_methods() {
|
||||||
ADD_SIGNAL(MethodInfo(sig_difficulty_increased));
|
ADD_SIGNAL(MethodInfo(sig_phase_changed, PropertyInfo(Variant::BOOL, "hunt_phase")));
|
||||||
ADD_SIGNAL(MethodInfo(sig_phase_changed, PropertyInfo(Variant::BOOL, "hunt")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRegion::on_node_entered(Node *node) {
|
void MapRegion::on_node_entered(Node *node) {
|
||||||
|
@ -45,22 +43,3 @@ void MapRegion::remove_unit(NpcUnit *unit) {
|
||||||
this->units.erase(unit);
|
this->units.erase(unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRegion::raise_difficulty(double amount) {
|
|
||||||
if (this->hunt_phase) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
double const new_difficulty{ this->difficulty + amount };
|
|
||||||
int const new_trunc{ (int)Math::floor(new_difficulty) };
|
|
||||||
int const old_trunc{ (int)Math::floor(this->difficulty) };
|
|
||||||
if (new_trunc != old_trunc) {
|
|
||||||
emit_signal(sig_difficulty_increased);
|
|
||||||
emit_signal(sig_phase_changed, true);
|
|
||||||
this->hunt_phase = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int MapRegion::get_current_difficulty() const {
|
|
||||||
int difficulty{ (int)Math::floor(this->difficulty) };
|
|
||||||
return difficulty;
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,16 +17,13 @@ protected:
|
||||||
public:
|
public:
|
||||||
void register_unit(NpcUnit *unit);
|
void register_unit(NpcUnit *unit);
|
||||||
void remove_unit(NpcUnit *unit);
|
void remove_unit(NpcUnit *unit);
|
||||||
void raise_difficulty(double amount);
|
|
||||||
int get_current_difficulty() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double difficulty{ 0.f };
|
float awareness{ 0.f };
|
||||||
bool hunt_phase{ false };
|
bool hunt_phase{ false };
|
||||||
HashSet<NpcUnit *> units{ nullptr };
|
HashSet<NpcUnit *> units{ nullptr };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static String const sig_difficulty_increased;
|
|
||||||
static String const sig_phase_changed;
|
static String const sig_phase_changed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "wave_survival/damage_box.h"
|
#include "wave_survival/damage_box.h"
|
||||||
#include "wave_survival/enemies/enemy_wretched.h"
|
#include "wave_survival/enemies/enemy_wretched.h"
|
||||||
#include "wave_survival/enemy_body.h"
|
#include "wave_survival/enemy_body.h"
|
||||||
#include "wave_survival/enemy_spawner.h"
|
|
||||||
#include "wave_survival/heads_up_display.h"
|
#include "wave_survival/heads_up_display.h"
|
||||||
#include "wave_survival/health_status.h"
|
#include "wave_survival/health_status.h"
|
||||||
#include "wave_survival/hitbox.h"
|
#include "wave_survival/hitbox.h"
|
||||||
|
@ -60,8 +59,6 @@ void initialize_wave_survival_module(ModuleInitializationLevel p_level) {
|
||||||
GDREGISTER_CLASS(MuzzleEffect);
|
GDREGISTER_CLASS(MuzzleEffect);
|
||||||
GDREGISTER_RUNTIME_CLASS(HeadsUpDisplay);
|
GDREGISTER_RUNTIME_CLASS(HeadsUpDisplay);
|
||||||
GDREGISTER_RUNTIME_CLASS(MapRegion);
|
GDREGISTER_RUNTIME_CLASS(MapRegion);
|
||||||
GDREGISTER_RUNTIME_CLASS(SpawnData);
|
|
||||||
GDREGISTER_RUNTIME_CLASS(EnemySpawner);
|
|
||||||
|
|
||||||
memnew(SoundEventPatchboard);
|
memnew(SoundEventPatchboard);
|
||||||
Engine::get_singleton()->add_singleton(Engine::Singleton(SoundEventPatchboard::get_class_static(), SoundEventPatchboard::get_singleton()));
|
Engine::get_singleton()->add_singleton(Engine::Singleton(SoundEventPatchboard::get_class_static(), SoundEventPatchboard::get_singleton()));
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,59 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="scene"
|
|
||||||
importer_version=1
|
|
||||||
type="PackedScene"
|
|
||||||
uid="uid://bcy5dxdvkkq4y"
|
|
||||||
path="res://.godot/imported/rifleman.blend-337a40d56611f3a26c5a0fd4a9f9ba8c.scn"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://assets/models/enemies/rifleman.blend"
|
|
||||||
dest_files=["res://.godot/imported/rifleman.blend-337a40d56611f3a26c5a0fd4a9f9ba8c.scn"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
nodes/root_type=""
|
|
||||||
nodes/root_name=""
|
|
||||||
nodes/root_script=null
|
|
||||||
nodes/apply_root_scale=true
|
|
||||||
nodes/root_scale=1.0
|
|
||||||
nodes/import_as_skeleton_bones=false
|
|
||||||
nodes/use_name_suffixes=true
|
|
||||||
nodes/use_node_type_suffixes=true
|
|
||||||
meshes/ensure_tangents=true
|
|
||||||
meshes/generate_lods=true
|
|
||||||
meshes/create_shadow_meshes=true
|
|
||||||
meshes/light_baking=1
|
|
||||||
meshes/lightmap_texel_size=0.2
|
|
||||||
meshes/force_disable_compression=false
|
|
||||||
skins/use_named_skins=true
|
|
||||||
animation/import=true
|
|
||||||
animation/fps=30
|
|
||||||
animation/trimming=false
|
|
||||||
animation/remove_immutable_tracks=true
|
|
||||||
animation/import_rest_as_RESET=false
|
|
||||||
import_script/path=""
|
|
||||||
materials/extract=0
|
|
||||||
materials/extract_format=0
|
|
||||||
materials/extract_path=""
|
|
||||||
_subresources={}
|
|
||||||
blender/nodes/visible=0
|
|
||||||
blender/nodes/active_collection_only=false
|
|
||||||
blender/nodes/punctual_lights=true
|
|
||||||
blender/nodes/cameras=true
|
|
||||||
blender/nodes/custom_properties=true
|
|
||||||
blender/nodes/modifiers=1
|
|
||||||
blender/meshes/colors=false
|
|
||||||
blender/meshes/uvs=true
|
|
||||||
blender/meshes/normals=true
|
|
||||||
blender/meshes/export_geometry_nodes_instances=false
|
|
||||||
blender/meshes/tangents=true
|
|
||||||
blender/meshes/skins=2
|
|
||||||
blender/meshes/export_bones_deforming_mesh_only=false
|
|
||||||
blender/materials/unpack_enabled=true
|
|
||||||
blender/materials/export_materials=1
|
|
||||||
blender/animation/limit_playback=true
|
|
||||||
blender/animation/always_sample=true
|
|
||||||
blender/animation/group_tracks=true
|
|
||||||
gltf/naming_version=2
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,8 +0,0 @@
|
||||||
[gd_resource type="SpawnData" load_steps=2 format=3 uid="uid://jya2iftfk0f6"]
|
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://5hg5eirw7v8n" path="res://objects/units/unit_4_wretched.tscn" id="1_0y836"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
difficulty_spawns = {
|
|
||||||
0: ExtResource("1_0y836")
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue