Compare commits
No commits in common. "c4bd5edb540a0bc4991a5ea1cc865a1a73f500e6" and "6153e73492ee9e03e09617d966267a348914b49f" have entirely different histories.
c4bd5edb54
...
6153e73492
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -22,6 +22,3 @@ build.zip
|
|||
wave-survival-fps.kdev4
|
||||
__pycache__
|
||||
modules/wave_survival/__pycache__
|
||||
|
||||
# blender auto backups
|
||||
*.blend1
|
||||
|
|
|
|||
2
engine
2
engine
|
|
@ -1 +1 @@
|
|||
Subproject commit 084d5d407e62efcd5be9de44148c5dedce3b9386
|
||||
Subproject commit c6d130abd9188f313e6701d01a0ddd6ea32166a0
|
||||
2
justfile
2
justfile
|
|
@ -4,7 +4,7 @@ BUILD_NAME := "wave_survival"
|
|||
|
||||
build: format
|
||||
# Compiling Editor
|
||||
cd engine/ && scons target=editor symbols=yes optimization=debug dev_build=yes linker=mold use_llvm=yes custom_modules="../modules" compiledb=yes
|
||||
cd engine/ && scons target=editor symbols=yes optimization=debug dev_build=yes linker=mold use_llvm=yes custom_modules="../modules"
|
||||
|
||||
run: build
|
||||
# Running Editor
|
||||
|
|
|
|||
|
|
@ -33,11 +33,9 @@ void DamageBox::_notification(int what) {
|
|||
default:
|
||||
return;
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
if (!is_ready()) {
|
||||
connect("body_entered", callable_mp(this, &self_type::on_body_entered));
|
||||
connect("area_entered", callable_mp(this, &self_type::on_body_entered));
|
||||
set_monitoring(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
#include "enemy_rifleman.h"
|
||||
|
||||
void EnemyRifleman::_bind_methods() {
|
||||
}
|
||||
|
||||
void EnemyRifleman::on_child_entered() {
|
||||
}
|
||||
|
||||
void EnemyRifleman::ready() {
|
||||
}
|
||||
|
||||
void EnemyRifleman::_notification(int what) {
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
switch (what) {
|
||||
default:
|
||||
return;
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
enter_tree();
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
ready();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,55 +2,10 @@
|
|||
#define ENEMY_RIFLEMAN_H
|
||||
|
||||
#include "wave_survival/enemy_body.h"
|
||||
#include "wave_survival/state.h"
|
||||
class AnimationPlayer;
|
||||
class NavigationAgent3D;
|
||||
|
||||
class EnemyRifleman : public EnemyBody {
|
||||
GDCLASS(EnemyRifleman, EnemyBody);
|
||||
static void _bind_methods();
|
||||
void on_child_entered();
|
||||
void enter_tree();
|
||||
void ready();
|
||||
|
||||
protected:
|
||||
void _notification(int what);
|
||||
};
|
||||
|
||||
/* ============================== STATES ============================== */
|
||||
|
||||
class RiflemanState : public State {
|
||||
GDCLASS(RiflemanState, State);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual void set_target(Node *target) override;
|
||||
EnemyRifleman *get_target() const;
|
||||
NpcUnit *get_unit() const;
|
||||
NavigationAgent3D *get_agent() const;
|
||||
AnimationPlayer *get_anim() const;
|
||||
|
||||
private:
|
||||
EnemyRifleman *target{ nullptr };
|
||||
};
|
||||
|
||||
class RiflemanPatrolState : public RiflemanState {
|
||||
GDCLASS(RiflemanPatrolState, RiflemanState);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
virtual void enter_state() override;
|
||||
virtual void process(double delta) override;
|
||||
};
|
||||
|
||||
class RiflemanSeekState : public RiflemanState {
|
||||
GDCLASS(RiflemanSeekState, RiflemanState);
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
class RiflemanFireState : public RiflemanState {
|
||||
GDCLASS(RiflemanFireState, RiflemanState);
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
#endif // !ENEMY_RIFLEMAN_H
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ void EnemyWretched::_notification(int what) {
|
|||
default:
|
||||
return;
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
if (!is_ready()) {
|
||||
connect("child_entered_tree", callable_mp(this, &self_type::on_child_entered));
|
||||
}
|
||||
return;
|
||||
case NOTIFICATION_READY:
|
||||
ready();
|
||||
|
|
|
|||
|
|
@ -19,15 +19,11 @@ void EnemyBody::on_child_added(Node *node) {
|
|||
void EnemyBody::ready() {
|
||||
this->fsm = cast_to<StateMachine>(get_node(NodePath("%StateMachine")));
|
||||
this->nav = cast_to<NavigationAgent3D>(get_node(NodePath("%NavigationAgent3D")));
|
||||
this->health = cast_to<HealthStatus>(get_node(NodePath("%HealthStatus")));
|
||||
}
|
||||
|
||||
void EnemyBody::physics_process(double delta) {
|
||||
GETSET(velocity, {
|
||||
velocity = Vector3{ this->movement_direction.x * this->movement_speed, velocity.y, this->movement_direction.y * this->movement_speed } + (velocity * delta);
|
||||
if (!is_on_floor() && this->health->get_health() > 0) {
|
||||
velocity += get_gravity() * delta;
|
||||
}
|
||||
});
|
||||
if (!this->movement_direction.is_zero_approx()) {
|
||||
look_at(get_global_position() + Vector3{ this->movement_direction.x, 0.f, this->movement_direction.y });
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "core/io/resource.h"
|
||||
#include "core/templates/hash_map.h"
|
||||
#include "scene/3d/marker_3d.h"
|
||||
#include "scene/3d/node_3d.h"
|
||||
class MapRegion;
|
||||
class PatrolPath;
|
||||
|
||||
|
|
@ -19,8 +19,8 @@ public:
|
|||
HashMap<int, Ref<PackedScene>> difficulty_spawns{};
|
||||
};
|
||||
|
||||
class EnemySpawner : public Marker3D {
|
||||
GDCLASS(EnemySpawner, Marker3D);
|
||||
class EnemySpawner : public Node3D {
|
||||
GDCLASS(EnemySpawner, Node3D);
|
||||
static void _bind_methods();
|
||||
void on_phase_change(bool hunt);
|
||||
void ready();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "health_status.h"
|
||||
#include "core/config/engine.h"
|
||||
#include "macros.h"
|
||||
|
||||
String HealthStatus::sig_death{ "death" };
|
||||
|
|
|
|||
|
|
@ -11,28 +11,18 @@ void NpcUnit::_bind_methods() {
|
|||
BIND_HPROPERTY(Variant::OBJECT, region, PROPERTY_HINT_NODE_TYPE, "MapRegion");
|
||||
}
|
||||
|
||||
void NpcUnit::remove_npc(EnemyBody *npc) {
|
||||
Transform3D const tf{ npc->get_global_transform() };
|
||||
remove_child(npc);
|
||||
this->get_parent()->add_child(npc);
|
||||
npc->set_global_transform(tf);
|
||||
}
|
||||
|
||||
void NpcUnit::on_npc_death() {
|
||||
Vector<EnemyBody>::Size living{ this->npcs.size() };
|
||||
// remove any dead npcs from the list
|
||||
// leaving their bodies as separate nodes part of the tree
|
||||
for (Vector<EnemyBody>::Size i{ 0 }; i < this->npcs.size(); ++i) {
|
||||
EnemyBody *npc{ this->npcs[i] };
|
||||
for (EnemyBody *npc : this->npcs) {
|
||||
if (npc->get_health()->get_health() <= 0) {
|
||||
--living;
|
||||
this->get_parent()->add_child(npc);
|
||||
this->npcs.erase(npc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// remove unit from world once all npcs are dead
|
||||
if (living == 0) {
|
||||
for (EnemyBody *npc : this->npcs) {
|
||||
remove_npc(npc);
|
||||
}
|
||||
if (this->npcs.size() <= 0) {
|
||||
this->set_region(nullptr); // de-register from region
|
||||
this->queue_free();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ class MapRegion;
|
|||
class NpcUnit : public Node3D {
|
||||
GDCLASS(NpcUnit, Node3D);
|
||||
static void _bind_methods();
|
||||
void remove_npc(EnemyBody *unit);
|
||||
void on_npc_death();
|
||||
void on_npc_awareness_changed(bool seen);
|
||||
void child_added(Node *node);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#include "player_input.h"
|
||||
#include "core/config/engine.h"
|
||||
#include "core/input/input.h"
|
||||
#include "scene/main/scene_tree.h"
|
||||
|
||||
String PlayerInput::sig_movement_input{ "movement_input" };
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "state_machine.h"
|
||||
#include "core/config/engine.h"
|
||||
#include "state.h"
|
||||
|
||||
void StateMachine::_bind_methods() {}
|
||||
|
|
@ -19,7 +18,7 @@ void StateMachine::switch_to_state(State *state) {
|
|||
}
|
||||
|
||||
void StateMachine::process(double delta) {
|
||||
if (this->current_state && is_enabled()) {
|
||||
if (this->current_state) {
|
||||
this->current_state->process(delta);
|
||||
String new_state{ this->current_state->get_next_state() };
|
||||
if (new_state != this->current_state->get_class()) {
|
||||
|
|
|
|||
Binary file not shown.
BIN
project/assets/models/base_character.blend1
Normal file
BIN
project/assets/models/base_character.blend1
Normal file
Binary file not shown.
BIN
project/assets/models/first_person_arms.blend1
Normal file
BIN
project/assets/models/first_person_arms.blend1
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -7,43 +7,23 @@ script/source = "extends EnemyWretched
|
|||
|
||||
@export var difficulty_weight : float = 10
|
||||
|
||||
var is_dead := false
|
||||
|
||||
func on_death() -> void:
|
||||
func _on_health_status_death() -> void:
|
||||
%StateMachine.process_mode = Node.PROCESS_MODE_DISABLED
|
||||
%NavigationAgent3D.process_mode = Node.PROCESS_MODE_DISABLED
|
||||
$wretched/AnimationPlayer.play(\"death\")
|
||||
$CollisionShape3D.disabled = true
|
||||
set_movement_direction(Vector2())
|
||||
|
||||
func _on_health_status_death() -> void:
|
||||
$wretched/AnimationPlayer.play(\"death\")
|
||||
get_unit().region.raise_difficulty(1.0 / difficulty_weight)
|
||||
on_death.call_deferred()
|
||||
is_dead = true
|
||||
|
||||
func _enter_tree() -> void:
|
||||
if is_dead and $wretched/AnimationPlayer.current_animation != \"death\":
|
||||
$wretched/AnimationPlayer.play.call_deferred(\"death\")
|
||||
$wretched/AnimationPlayer.advance.call_deferred(INF)
|
||||
elif is_dead:
|
||||
$wretched/AnimationPlayer.play.call_deferred(\"death\")
|
||||
"
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ng1ul"]
|
||||
radius = 0.58691406
|
||||
radius = 0.26953125
|
||||
|
||||
[node name="EnemyWretched" type="EnemyWretched"]
|
||||
wall_min_slide_angle = 0.0
|
||||
script = SubResource("GDScript_qot2n")
|
||||
|
||||
[node name="wretched" parent="." instance=ExtResource("1_qot2n")]
|
||||
|
||||
[node name="Body" parent="wretched/Character/Skeleton3D" index="0"]
|
||||
gi_mode = 0
|
||||
|
||||
[node name="club" parent="wretched/Character/Skeleton3D" index="1"]
|
||||
gi_mode = 0
|
||||
|
||||
[node name="Hitbox" parent="wretched/Character/Skeleton3D" index="2" node_paths=PackedStringArray("health")]
|
||||
health = NodePath("../../../../HealthStatus")
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ config_version=5
|
|||
|
||||
config/name="wave_survival"
|
||||
run/main_scene="uid://dti7d1rslmhgp"
|
||||
config/features=PackedStringArray("4.6", "Forward Plus")
|
||||
config/features=PackedStringArray("4.5", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[display]
|
||||
|
|
@ -103,10 +103,13 @@ reload={
|
|||
3d_physics/layer_4="Hitbox(Player)"
|
||||
3d_physics/layer_5="Interactables"
|
||||
|
||||
[physics]
|
||||
|
||||
3d/physics_engine="Jolt Physics"
|
||||
|
||||
[rendering]
|
||||
|
||||
lights_and_shadows/directional_shadow/size=8192
|
||||
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=4
|
||||
lights_and_shadows/positional_shadow/soft_shadow_filter_quality=5
|
||||
global_illumination/voxel_gi/quality=1
|
||||
lights_and_shadows/positional_shadow/atlas_size=8192
|
||||
|
|
|
|||
Loading…
Reference in a new issue