feat: defined utility lock

This commit is contained in:
Sara 2024-09-02 21:28:53 +02:00
parent 5242deee1f
commit d8a3000b13
4 changed files with 144 additions and 1 deletions

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=17 format=3 uid="uid://c62s1jmtgajjk"]
[gd_scene load_steps=24 format=3 uid="uid://c62s1jmtgajjk"]
[ext_resource type="PackedScene" uid="uid://dsalxxq3xs842" path="res://rts_game_mode.tscn" id="1_4nchg"]
[ext_resource type="Environment" uid="uid://cnfk8yrvklysq" path="res://Environments/default_environment.tres" id="2_jq6bw"]
@ -38,6 +38,39 @@ size = Vector3(0.445312, 3, 40)
[sub_resource type="BoxMesh" id="BoxMesh_4sjak"]
size = Vector3(0.445, 5, 40)
[sub_resource type="Goal" id="Goal_yju55"]
desired_state_dict = {
"is_target_activated": true
}
[sub_resource type="GDScript" id="GDScript_2bv87"]
script/source = "extends UtilityLock
func _on_finish_activate(_item: int, _unit: Unit):
self.queue_free()
self.get_parent().remove_child(self)
"
[sub_resource type="SphereShape3D" id="SphereShape3D_pptgx"]
radius = 1.22941
[sub_resource type="BoxShape3D" id="BoxShape3D_3h2p0"]
size = Vector3(6.10718, 2.48376, 1.63379)
[sub_resource type="CylinderMesh" id="CylinderMesh_r0j0v"]
top_radius = 1.0
bottom_radius = 1.0
height = 1.0
cap_bottom = false
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_emsq8"]
transparency = 1
shading_mode = 0
albedo_color = Color(0, 1, 0.823529, 0.760784)
[sub_resource type="BoxMesh" id="BoxMesh_bl5l6"]
size = Vector3(7, 1, 1)
[node name="TestLevel" type="Level3D"]
game_mode_prototype = ExtResource("1_4nchg")
@ -219,6 +252,38 @@ transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -23.14
[node name="ModernTrain6" parent="WorldEnvironment/NavigationRegion3D" instance=ExtResource("6_favl6")]
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, -16.443, 0.268182, 3.2886)
[node name="UtilityLock" type="UtilityLock" parent="WorldEnvironment"]
allowed_items = [3]
goal = SubResource("Goal_yju55")
transform = Transform3D(0.0142588, 0, 0.999898, 0, 1, 0, -0.999898, 0, 0.0142588, -4.68514, 1.8999e-07, 2.96901)
collision_layer = 4
collision_mask = 0
script = SubResource("GDScript_2bv87")
[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldEnvironment/UtilityLock"]
shape = SubResource("SphereShape3D_pptgx")
[node name="StaticBody3D" type="StaticBody3D" parent="WorldEnvironment/UtilityLock"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldEnvironment/UtilityLock/StaticBody3D"]
transform = Transform3D(1, 0, 3.1664e-08, 0, 1, 0, -3.1664e-08, 0, 1, 0.0699434, 0.984067, -2.11005)
shape = SubResource("BoxShape3D_3h2p0")
[node name="NavigationObstacle3D" type="NavigationObstacle3D" parent="WorldEnvironment/UtilityLock/StaticBody3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0515832, 0.0826392, -2.12334)
height = 2.0
vertices = PackedVector3Array(-1, 0, 3, -1, 0, -3, 1, 0, -3, 1, 0, 3)
carve_navigation_mesh = true
[node name="MeshInstance3D" type="MeshInstance3D" parent="WorldEnvironment/UtilityLock"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.136569, 0)
mesh = SubResource("CylinderMesh_r0j0v")
surface_material_override/0 = SubResource("StandardMaterial3D_emsq8")
[node name="MeshInstance3D2" type="MeshInstance3D" parent="WorldEnvironment/UtilityLock"]
transform = Transform3D(0.984294, -0.176535, 0, 0.176535, 0.984294, 0, 0, 0, 1, 0, 0.857907, -1.99146)
mesh = SubResource("BoxMesh_bl5l6")
[node name="Tracks" type="Node3D" parent="WorldEnvironment"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 7.25984)

View file

@ -15,6 +15,7 @@
#include "tank_unit.hpp"
#include "unit.hpp"
#include "unit_world_state.hpp"
#include "utility_lock.hpp"
#include "goap/action.hpp"
#include "goap/action_db.hpp"
#include "goap/actor_world_state.hpp"
@ -64,6 +65,7 @@ void initialize_gdextension_types(gd::ModuleInitializationLevel p_level)
GDREGISTER_RUNTIME_CLASS(EnemyWorldState);
GDREGISTER_RUNTIME_CLASS(CharacterWorldState);
GDREGISTER_RUNTIME_CLASS(GoalMarker);
GDREGISTER_CLASS(UtilityLock);
GDREGISTER_RUNTIME_CLASS(Unit);
GDREGISTER_RUNTIME_CLASS(TankUnit)
GDREGISTER_RUNTIME_CLASS(CharacterUnit);

48
src/utility_lock.cpp Normal file
View file

@ -0,0 +1,48 @@
#include "utility_lock.hpp"
#include "item_db.hpp"
#include "utils/godot_macros.hpp"
void UtilityLock::_bind_methods() {
#define CLASSNAME UtilityLock
GDPROPERTY_HINTED(allowed_items, gd::Variant::ARRAY, gd::PROPERTY_HINT_ARRAY_TYPE, ItemDB::get_array_hint());
GDSIGNAL("begin_activate", gd::PropertyInfo(gd::Variant::INT, "with_item"), gd::PropertyInfo(gd::Variant::OBJECT, "by_unit", gd::PROPERTY_HINT_NODE_TYPE, "Unit"));
GDSIGNAL("finish_activate", gd::PropertyInfo(gd::Variant::INT, "with_item"), gd::PropertyInfo(gd::Variant::OBJECT, "by_unit", gd::PROPERTY_HINT_NODE_TYPE, "Unit"));
}
bool UtilityLock::can_use(Item const *with, Unit *by) const {
return this->allowed_items.has(with);
}
bool UtilityLock::begin_activate(Item const *with, Unit *by) {
if(this->can_use(with, by)) {
this->user = by;
this->emit_signal("begin_activate", with->get_id(), by);
this->_begin_activate(with, by);
return true;
} else return false;
}
bool UtilityLock::finish_activate(Item const *with, Unit *by) {
if(this->user != nullptr && this->user == by) {
this->user = nullptr;
this->emit_signal("finish_activate", with->get_id(), by);
this->_finish_activate(with, by);
return true;
} else return false;
}
void UtilityLock::set_allowed_items(gd::Array array) {
this->allowed_items.clear();
for(int i{0}; i < array.size(); ++i) {
Item const *item{ItemDB::get_item(array[i])};
if(item == nullptr || item->has_capability(ItemCapability::UtilityEquip))
this->allowed_items.insert(item);
}
}
gd::Array UtilityLock::get_allowed_items() const {
gd::Array array{};
for(Item const *item : this->allowed_items)
array.push_back(item == nullptr ? 0 : item->get_id());
return array;
}

28
src/utility_lock.hpp Normal file
View file

@ -0,0 +1,28 @@
#ifndef UTILITY_LOCK_HPP
#define UTILITY_LOCK_HPP
#include "goal_marker.hpp"
#include "item.hpp"
#include <godot_cpp/variant/utility_functions.hpp>
#include <godot_cpp/templates/hash_set.hpp>
namespace gd = godot;
class UtilityLock : public GoalMarker {
GDCLASS(UtilityLock, GoalMarker)
static void _bind_methods();
public:
bool can_use(Item const *with, Unit *by) const;
bool begin_activate(Item const *with, Unit *by);
bool finish_activate(Item const *with, Unit *by);
virtual void _begin_activate(Item const *with, Unit *by) {}
virtual void _finish_activate(Item const *with, Unit *by) {}
void set_allowed_items(gd::Array array);
gd::Array get_allowed_items() const;
private:
gd::HashSet<Item const *> allowed_items{};
Unit *user{nullptr};
};
#endif // !UTILITY_LOCK_HPP