the rest of the fucking owl
This commit is contained in:
parent
f89d2ccf53
commit
7f63584f7c
Binary file not shown.
Binary file not shown.
BIN
.cache/clangd/index/actor_state_machine.cpp.AEBD1F5B3A3BA6BD.idx
Normal file
BIN
.cache/clangd/index/actor_state_machine.cpp.AEBD1F5B3A3BA6BD.idx
Normal file
Binary file not shown.
BIN
.cache/clangd/index/actor_state_machine.h.8F19423C17C722EB.idx
Normal file
BIN
.cache/clangd/index/actor_state_machine.h.8F19423C17C722EB.idx
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
justfile
2
justfile
|
@ -1,6 +1,6 @@
|
||||||
set export
|
set export
|
||||||
|
|
||||||
BUILD_NAME := "change_me"
|
BUILD_NAME := "tabtargeting"
|
||||||
|
|
||||||
build:
|
build:
|
||||||
cd engine/ && scons target=editor symbols=yes optimization=debug dev_build=yes linker=mold use_llvm=yes compiledb=yes custom_modules="../modules"
|
cd engine/ && scons target=editor symbols=yes optimization=debug dev_build=yes linker=mold use_llvm=yes compiledb=yes custom_modules="../modules"
|
||||||
|
|
|
@ -1,10 +1,49 @@
|
||||||
#include "actor_body.h"
|
#include "actor_body.h"
|
||||||
|
#include "core/object/class_db.h"
|
||||||
#include "core/string/print_string.h"
|
#include "core/string/print_string.h"
|
||||||
|
|
||||||
void ActorBody::_bind_methods() {
|
void ActorBody::_bind_methods() {
|
||||||
|
ClassDB::bind_method(D_METHOD("request_attack"), &self_type::request_attack, "target");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBody::_notification(int what) {
|
||||||
|
if(Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(what) {
|
||||||
|
case NOTIFICATION_READY:
|
||||||
|
this->equipment = Object::cast_to<Equipment>(this->get_node(NodePath("Equipment")));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBody::_attack() {
|
||||||
|
if(this->attack_requested != nullptr) {
|
||||||
|
this->attack_requested->receive_damage(this->equipment->apply(this->equipment->get_weapon()->create_base_damage_event(this), this));
|
||||||
|
this->attack_requested = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ActorBody::is_attack_requested() {
|
||||||
|
return this->attack_requested != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActorBody::receive_damage(DamageEvent event) {
|
void ActorBody::receive_damage(DamageEvent event) {
|
||||||
this->health -= event.compound_damage;
|
this->health -= this->equipment->apply(event, this).compound_damage;
|
||||||
print_line(vformat("Damage dealth (%d to %s, %d remaining", event.compound_damage, this->get_name(), this->health));
|
print_line(vformat("Damage dealth (%d to %s, %d remaining", event.compound_damage, this->get_name(), this->health));
|
||||||
|
if(this->health < 0) {
|
||||||
|
this->queue_free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBody::request_attack(ActorBody *target) {
|
||||||
|
this->attack_requested = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorBody::set_health(int health) {
|
||||||
|
this->health = health;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ActorBody::get_health() const {
|
||||||
|
return this->health;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,19 @@ class ActorBody;
|
||||||
class ActorBody : public CharacterBody3D {
|
class ActorBody : public CharacterBody3D {
|
||||||
GDCLASS(ActorBody, CharacterBody3D);
|
GDCLASS(ActorBody, CharacterBody3D);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
void _notification(int what);
|
||||||
public:
|
public:
|
||||||
|
void _attack();
|
||||||
|
bool is_attack_requested();
|
||||||
void receive_damage(DamageEvent event);
|
void receive_damage(DamageEvent event);
|
||||||
void send_damage(int amount, ActorBody *target);
|
void request_attack(ActorBody *target);
|
||||||
|
void set_health(int health);
|
||||||
|
int get_health() const;
|
||||||
private:
|
private:
|
||||||
int health{10};
|
int health{50};
|
||||||
int max_health{10};
|
int max_health{10};
|
||||||
|
ActorBody *attack_requested{nullptr};
|
||||||
|
|
||||||
class Equipment *equipment{nullptr};
|
Equipment *equipment{nullptr};
|
||||||
};
|
};
|
||||||
#endif // !ACTOR_BODY_H
|
#endif // !ACTOR_BODY_H
|
||||||
|
|
84
modules/tabtargeting/actor_state_machine.cpp
Normal file
84
modules/tabtargeting/actor_state_machine.cpp
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
#include "actor_state_machine.h"
|
||||||
|
#include "core/config/engine.h"
|
||||||
|
#include "tabtargeting/actor_body.h"
|
||||||
|
|
||||||
|
void ActorState::_bind_methods() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorStateMachine::_bind_methods() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorStateMachine::_notification(int what) {
|
||||||
|
if(Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch(what) {
|
||||||
|
case NOTIFICATION_READY:
|
||||||
|
this->ready();
|
||||||
|
break;
|
||||||
|
case NOTIFICATION_PROCESS:
|
||||||
|
this->process(this->get_process_delta_time());
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorStateMachine::ready() {
|
||||||
|
this->set_process(true);
|
||||||
|
this->body = Object::cast_to<ActorBody>(this->get_parent());
|
||||||
|
this->add_state<IdleState>();
|
||||||
|
this->add_state<ActingState>();
|
||||||
|
this->current_state->state_entered();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorStateMachine::process(double delta) {
|
||||||
|
this->current_state->process(delta);
|
||||||
|
this->try_next_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorStateMachine::try_next_state() {
|
||||||
|
StringName name{this->current_state->next_state()};
|
||||||
|
if(name != this->current_state->get_class()) {
|
||||||
|
this->switch_state(this->states[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActorStateMachine::switch_state(ActorState *state) {
|
||||||
|
this->current_state->state_exited();
|
||||||
|
this->current_state = state;
|
||||||
|
this->current_state->state_entered();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdleState::_bind_methods() {}
|
||||||
|
|
||||||
|
void IdleState::state_exited() {
|
||||||
|
print_line("state idle exited");
|
||||||
|
if(this->body->is_attack_requested()) {
|
||||||
|
this->body->_attack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringName IdleState::next_state() const {
|
||||||
|
if(this->body->is_attack_requested()) {
|
||||||
|
return ActingState::get_class_static();
|
||||||
|
}
|
||||||
|
return this->get_class_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActingState::_bind_methods() {}
|
||||||
|
|
||||||
|
void ActingState::state_entered() {
|
||||||
|
print_line("state acting exited");
|
||||||
|
this->timer = this->seconds_to_wait;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActingState::process(double delta) {
|
||||||
|
this->timer -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringName ActingState::next_state() const {
|
||||||
|
if(this->timer <= 0) {
|
||||||
|
return IdleState::get_class_static();
|
||||||
|
}
|
||||||
|
return this->get_class();
|
||||||
|
}
|
|
@ -1,13 +1,70 @@
|
||||||
#ifndef ACTOR_STATE_MACHINE_H
|
#ifndef ACTOR_STATE_MACHINE_H
|
||||||
#define ACTOR_STATE_MACHINE_H
|
#define ACTOR_STATE_MACHINE_H
|
||||||
|
|
||||||
|
#include "core/string/string_name.h"
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
|
#include "core/object/ref_counted.h"
|
||||||
|
class ActorBody;
|
||||||
|
|
||||||
|
class ActorState : public RefCounted {
|
||||||
|
GDCLASS(ActorState, Object);
|
||||||
|
static void _bind_methods();
|
||||||
|
public:
|
||||||
|
virtual void state_entered() {}
|
||||||
|
virtual void process(double delta) {}
|
||||||
|
virtual StringName next_state() const {
|
||||||
|
return this->get_class();
|
||||||
|
}
|
||||||
|
virtual void state_exited() {}
|
||||||
|
protected:
|
||||||
|
ActorBody *body{nullptr};
|
||||||
|
friend class ActorStateMachine;
|
||||||
|
};
|
||||||
|
|
||||||
class ActorStateMachine : public Node {
|
class ActorStateMachine : public Node {
|
||||||
GDCLASS(ActorStateMachine, Node);
|
GDCLASS(ActorStateMachine, Node);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
public:
|
void _notification(int what);
|
||||||
|
void ready();
|
||||||
|
void process(double delta);
|
||||||
|
template <class TState>
|
||||||
|
void add_state();
|
||||||
|
void try_next_state();
|
||||||
|
void switch_state(ActorState *state);
|
||||||
private:
|
private:
|
||||||
|
ActorBody *body{nullptr};
|
||||||
|
ActorState *current_state{};
|
||||||
|
HashMap<StringName, ActorState*> states{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class TState>
|
||||||
|
void ActorStateMachine::add_state() {
|
||||||
|
ActorState *state{memnew(TState)};
|
||||||
|
state->body = this->body;
|
||||||
|
this->states.insert(TState::get_class_static(), state);
|
||||||
|
if(current_state == nullptr) {
|
||||||
|
this->current_state = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IdleState : public ActorState {
|
||||||
|
GDCLASS(IdleState, ActorState);
|
||||||
|
static void _bind_methods();
|
||||||
|
public:
|
||||||
|
virtual void state_exited() override;
|
||||||
|
virtual StringName next_state() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActingState : public ActorState {
|
||||||
|
GDCLASS(ActingState, ActorState);
|
||||||
|
static void _bind_methods();
|
||||||
|
public:
|
||||||
|
virtual void state_entered() override;
|
||||||
|
virtual void process(double delta) override;
|
||||||
|
virtual StringName next_state() const override;
|
||||||
|
private:
|
||||||
|
double const seconds_to_wait{1.0};
|
||||||
|
double timer{0.0};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !ACTOR_STATE_MACHINE_H
|
#endif // !ACTOR_STATE_MACHINE_H
|
||||||
|
|
|
@ -8,6 +8,14 @@ DamageEvent::DamageEvent(int damage, ActorBody *source)
|
||||||
, source{source}
|
, source{source}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
int DamageEvent::get_initial_damage() const {
|
||||||
|
return this->initial_damage;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActorBody *DamageEvent::get_source() const {
|
||||||
|
return this->source;
|
||||||
|
}
|
||||||
|
|
||||||
void DamageStats::_bind_methods() {
|
void DamageStats::_bind_methods() {
|
||||||
BIND_PROPERTY(Variant::INT, damage_add);
|
BIND_PROPERTY(Variant::INT, damage_add);
|
||||||
BIND_PROPERTY(Variant::INT, damage_mul);
|
BIND_PROPERTY(Variant::INT, damage_mul);
|
||||||
|
@ -101,7 +109,15 @@ void Equipment::_bind_methods() {
|
||||||
}
|
}
|
||||||
|
|
||||||
DamageEvent Equipment::apply(DamageEvent event, ActorBody *target) {
|
DamageEvent Equipment::apply(DamageEvent event, ActorBody *target) {
|
||||||
|
if(this->weapon.is_valid())
|
||||||
|
event = this->weapon->apply(event, target);
|
||||||
|
if(this->helmet.is_valid())
|
||||||
|
event = this->helmet->apply(event, target);
|
||||||
|
if(this->chest.is_valid())
|
||||||
|
event = this->chest->apply(event, target);
|
||||||
|
if(this->legs.is_valid())
|
||||||
|
event = this->legs->apply(event, target);
|
||||||
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Equipment::set_weapon(Ref<Weapon> weapon) {
|
void Equipment::set_weapon(Ref<Weapon> weapon) {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#define EQUIPMENT_H
|
#define EQUIPMENT_H
|
||||||
|
|
||||||
#include "core/io/resource.h"
|
#include "core/io/resource.h"
|
||||||
#include "core/templates/vector.h"
|
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
class ActorBody;
|
class ActorBody;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "register_types.h"
|
#include "register_types.h"
|
||||||
|
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
|
#include "tabtargeting/actor_state_machine.h"
|
||||||
#include "tabtargeting/equipment.h"
|
#include "tabtargeting/equipment.h"
|
||||||
#include "tabtargeting/actor_body.h"
|
#include "tabtargeting/actor_body.h"
|
||||||
|
|
||||||
|
@ -9,6 +10,10 @@ void initialize_tabtargeting_module(ModuleInitializationLevel p_level) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClassDB::register_class<ActorBody>();
|
ClassDB::register_class<ActorBody>();
|
||||||
|
ClassDB::register_class<ActorStateMachine>();
|
||||||
|
ClassDB::register_class<ActorState>();
|
||||||
|
ClassDB::register_class<ActingState>();
|
||||||
|
ClassDB::register_class<IdleState>();
|
||||||
ClassDB::register_class<DamageStats>();
|
ClassDB::register_class<DamageStats>();
|
||||||
ClassDB::register_class<EquipItem>();
|
ClassDB::register_class<EquipItem>();
|
||||||
ClassDB::register_class<Weapon>();
|
ClassDB::register_class<Weapon>();
|
||||||
|
|
7
project/buttons.gd
Normal file
7
project/buttons.gd
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
extends CanvasLayer
|
||||||
|
|
||||||
|
func _on_button1_down() -> void:
|
||||||
|
$"../Actor1".request_attack($"../Actor2")
|
||||||
|
|
||||||
|
func _on_button2_down() -> void:
|
||||||
|
$"../Actor2".request_attack($"../Actor1")
|
1
project/buttons.gd.uid
Normal file
1
project/buttons.gd.uid
Normal file
|
@ -0,0 +1 @@
|
||||||
|
uid://cikkvrxl0xfut
|
3
project/equip_items/chestplate.tres
Normal file
3
project/equip_items/chestplate.tres
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[gd_resource type="Armor" format=3 uid="uid://ciqakeu7a82fw"]
|
||||||
|
|
||||||
|
[resource]
|
9
project/equip_items/weapon1.tres
Normal file
9
project/equip_items/weapon1.tres
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[gd_resource type="Weapon" load_steps=2 format=3 uid="uid://rkcmcib35uj7"]
|
||||||
|
|
||||||
|
[sub_resource type="DamageStats" id="DamageStats_jtxwa"]
|
||||||
|
damage_add = 1
|
||||||
|
damage_mul = 2.0
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
stats = SubResource("DamageStats_jtxwa")
|
||||||
|
base_damage = 5
|
|
@ -11,5 +11,6 @@ config_version=5
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="tabtargeting"
|
config/name="tabtargeting"
|
||||||
config/features=PackedStringArray("4.4", "Forward Plus")
|
run/main_scene="uid://b7klcvxm3e578"
|
||||||
|
config/features=PackedStringArray("4.5", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
95
project/scene.tscn
Normal file
95
project/scene.tscn
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
[gd_scene load_steps=9 format=3 uid="uid://b7klcvxm3e578"]
|
||||||
|
|
||||||
|
[ext_resource type="Weapon" uid="uid://rkcmcib35uj7" path="res://equip_items/weapon1.tres" id="1_nxogm"]
|
||||||
|
[ext_resource type="Script" uid="uid://cikkvrxl0xfut" path="res://buttons.gd" id="1_ulcgi"]
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_nxogm"]
|
||||||
|
sky_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||||
|
ground_horizon_color = Color(0.662243, 0.671743, 0.686743, 1)
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_3253y"]
|
||||||
|
sky_material = SubResource("ProceduralSkyMaterial_nxogm")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_u3cyc"]
|
||||||
|
background_mode = 2
|
||||||
|
sky = SubResource("Sky_3253y")
|
||||||
|
tonemap_mode = 2
|
||||||
|
glow_enabled = true
|
||||||
|
|
||||||
|
[sub_resource type="SphereShape3D" id="SphereShape3D_drvgu"]
|
||||||
|
|
||||||
|
[sub_resource type="CylinderMesh" id="CylinderMesh_drvgu"]
|
||||||
|
|
||||||
|
[sub_resource type="BoxMesh" id="BoxMesh_nxogm"]
|
||||||
|
size = Vector3(-5, -5, -5)
|
||||||
|
|
||||||
|
[node name="Scene" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_u3cyc")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(0.433659, -0.651449, 0.622538, 0, 0.690882, 0.722967, -0.901077, -0.313521, 0.299607, 0, 0, 0)
|
||||||
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="Actor1" type="ActorBody" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1.59845)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Actor1"]
|
||||||
|
shape = SubResource("SphereShape3D_drvgu")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Actor1"]
|
||||||
|
mesh = SubResource("CylinderMesh_drvgu")
|
||||||
|
|
||||||
|
[node name="Equipment" type="Equipment" parent="Actor1"]
|
||||||
|
weapon = ExtResource("1_nxogm")
|
||||||
|
|
||||||
|
[node name="ActorStateMachine" type="ActorStateMachine" parent="Actor1"]
|
||||||
|
|
||||||
|
[node name="Actor2" type="ActorBody" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.66257)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Actor2"]
|
||||||
|
shape = SubResource("SphereShape3D_drvgu")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Actor2"]
|
||||||
|
mesh = SubResource("CylinderMesh_drvgu")
|
||||||
|
|
||||||
|
[node name="Equipment" type="Equipment" parent="Actor2"]
|
||||||
|
weapon = ExtResource("1_nxogm")
|
||||||
|
|
||||||
|
[node name="ActorStateMachine" type="ActorStateMachine" parent="Actor2"]
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
|
transform = Transform3D(0.251056, -0.361214, 0.898051, 0, 0.927765, 0.373166, -0.967973, -0.0936855, 0.232921, 1.89697, 0.912457, 1.11904)
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
script = ExtResource("1_ulcgi")
|
||||||
|
|
||||||
|
[node name="Button" type="Button" parent="CanvasLayer"]
|
||||||
|
anchors_preset = 2
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = -113.0
|
||||||
|
offset_right = 327.0
|
||||||
|
grow_vertical = 0
|
||||||
|
text = "Attack (Actor 1)"
|
||||||
|
|
||||||
|
[node name="Button2" type="Button" parent="CanvasLayer"]
|
||||||
|
anchors_preset = 3
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = -327.0
|
||||||
|
offset_top = -113.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
grow_vertical = 0
|
||||||
|
text = "Attack (Actor 2)"
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.57152, 0)
|
||||||
|
mesh = SubResource("BoxMesh_nxogm")
|
||||||
|
|
||||||
|
[connection signal="button_down" from="CanvasLayer/Button" to="CanvasLayer" method="_on_button1_down"]
|
||||||
|
[connection signal="button_down" from="CanvasLayer/Button2" to="CanvasLayer" method="_on_button2_down"]
|
Loading…
Reference in a new issue