feat: added test level complete objective

This commit is contained in:
Sara 2025-03-14 17:36:00 +01:00
parent 567c5fbe15
commit 3abb328c48
10 changed files with 141 additions and 7 deletions

View file

@ -20,7 +20,7 @@ rings = 3
[sub_resource type="BoxMesh" id="BoxMesh_p8wvo"]
size = Vector3(0.2, 0.2, 0.5)
[node name="Tank" type="TankUnit"]
[node name="Tank" type="TankUnit" groups=["enemy_unit"]]
configure_team = 3
movement_speed = 1.5
collision_layer = 6
@ -35,7 +35,6 @@ actions_inspector = [3, 2, 4, 1]
unique_name_in_owner = true
[node name="EntityHealth" type="EntityHealth" parent="."]
injury_max = 100
unique_name_in_owner = true
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]

View file

@ -17,7 +17,7 @@ rings = 3
[sub_resource type="BoxMesh" id="BoxMesh_p8wvo"]
size = Vector3(0.2, 0.2, 0.5)
[node name="Player" type="CharacterUnit"]
[node name="Player" type="CharacterUnit" groups=["player_unit"]]
configure_team = 1
collision_layer = 6
collision_mask = 0

View file

@ -0,0 +1,22 @@
[gd_scene load_steps=2 format=3 uid="uid://wlejteovfj8v"]
[ext_resource type="PackedScene" uid="uid://cljn3tou8pxjt" path="res://menu_game_mode.tscn" id="1_ce5im"]
[node name="Level3D" type="Level3D"]
game_mode_prototype = ExtResource("1_ce5im")
[node name="LevelComplete" type="Control" parent="."]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Label" type="Label" parent="LevelComplete"]
layout_mode = 0
offset_left = 23.0
offset_top = 27.0
offset_right = 447.0
offset_bottom = 163.0
text = "Test Level Complete"

View file

@ -1,4 +1,4 @@
[gd_scene load_steps=16 format=3 uid="uid://c62s1jmtgajjk"]
[gd_scene load_steps=19 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"]
@ -7,6 +7,7 @@
[ext_resource type="PackedScene" uid="uid://c82s8vpaethtv" path="res://GameObjects/nav_marker.tscn" id="5_ta2oq"]
[ext_resource type="PackedScene" uid="uid://duuvete30t8sv" path="res://GameObjects/LevelProps/modern_train.tscn" id="6_favl6"]
[ext_resource type="PackedScene" uid="uid://ulvv4o73s48a" path="res://Environments/Models/KenneyTrains/track.glb" id="7_8fuqb"]
[ext_resource type="Material" uid="uid://dluo26ixa4p8o" path="res://Assets/Models/movement_marker.tres" id="8_wyjwf"]
[sub_resource type="NavigationMesh" id="NavigationMesh_8a2j6"]
vertices = PackedVector3Array(-49.9439, 6.15874, -50.0795, -47.9439, 6.15874, -50.0795, -47.9439, 6.15874, -66.0795, -71.4439, 6.15874, -48.0795, -49.9439, 6.15874, -48.0795, -71.4439, 6.15874, -66.0795, 50.0561, 6.15874, -50.0795, 50.0561, 6.15874, -48.0795, 52.0561, 6.15874, -48.0795, 52.0561, 6.15874, -66.0795, -71.4439, 6.15874, 47.9205, -49.9439, 6.15874, 47.9205, 50.0561, 6.15874, 47.9205, 52.0561, 6.15874, 47.9205, -5.44388, 0.408735, -1.57945, -5.19388, 0.408735, -2.82945, -6.94388, 0.408735, -3.07945, -8.94388, 0.408735, -1.57945, -6.69388, 0.408735, -6.57945, -8.94388, 0.408735, -9.32945, 7.55612, 0.408735, -6.57945, 7.80612, 0.408735, -4.57945, 9.30612, 0.408735, -4.57945, 9.30612, 0.408735, -9.32945, -5.69388, 0.408735, -5.32945, -5.69388, 0.408735, -4.07945, -0.443878, 0.408735, -4.07945, -0.443878, 0.408735, -5.32945, 1.30612, 0.408735, -5.32945, 1.30612, 0.408735, -4.07945, 6.55612, 0.408735, -4.07945, 6.55612, 0.408735, -5.32945, 7.55612, 0.408735, -2.82945, 2.55612, 0.408735, -2.82945, 2.55612, 0.408735, -1.57945, 4.80612, 0.408735, -1.32945, 4.80612, 0.408735, 0.920547, 7.05612, 0.408735, 5.17055, 9.30612, 0.408735, 8.17055, 7.30612, 0.408735, 8.17055, 2.55612, 0.408735, 1.17055, 2.55612, 0.408735, 5.17055, -3.94388, 0.408735, -1.32945, 0.306122, 0.408735, -1.32945, -3.94388, 0.408735, 0.920547, 0.306122, 0.408735, 0.920547, -5.69388, 0.408735, 1.17055, -5.69388, 0.408735, 5.17055, -29.1939, 0.408735, 1.17055, -29.1939, 0.408735, 2.92055, -27.1939, 0.408735, 2.92055, -26.9439, 0.408735, 1.42055, -12.6939, 0.408735, 1.42055, -12.4439, 0.408735, 4.92055, -12.9439, 0.408735, 5.17055, -12.9439, 0.408735, 8.17055, -7.44388, 0.408735, 8.17055, -7.44388, 0.408735, 5.42055, -26.9439, 0.408735, 5.17055, -29.1939, 0.408735, 8.17055, -25.9439, 0.408735, 2.67055, -25.9439, 0.408735, 3.92055, -20.6939, 0.408735, 3.92055, -20.6939, 0.408735, 2.67055, -18.9439, 0.408735, 2.67055, -18.9439, 0.408735, 3.92055, -13.6939, 0.408735, 3.92055, -13.6939, 0.408735, 2.67055, -6.19388, 0.408735, 6.42055, -6.19388, 0.408735, 7.92055, -0.943878, 0.408735, 7.92055, -0.943878, 0.408735, 6.42055, 0.806122, 0.408735, 6.42055, 0.806122, 0.408735, 7.92055, 6.05612, 0.408735, 7.92055, 6.05612, 0.408735, 6.42055, -47.9439, 6.15874, 67.9205, -47.9439, 6.15874, 49.9205, -49.9439, 6.15874, 49.9205, -71.4439, 6.15874, 67.9205, 50.0561, 6.15874, 49.9205, 52.0561, 6.15874, 67.9205)
@ -47,9 +48,19 @@ albedo_color = Color(0, 1, 0.823529, 0.760784)
[sub_resource type="BoxMesh" id="BoxMesh_bl5l6"]
size = Vector3(7, 1, 1)
[sub_resource type="BoxShape3D" id="BoxShape3D_c8xhj"]
size = Vector3(2.58594, 1, 8.92188)
[sub_resource type="BoxMesh" id="BoxMesh_mq8af"]
material = ExtResource("8_wyjwf")
size = Vector3(2.035, 1, 8.225)
[node name="TestLevel" type="Level3D"]
game_mode_prototype = ExtResource("1_4nchg")
[node name="SpawnPoint3D" type="SpawnPoint3D" parent="."]
transform = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, -7.12546, 0, -8.38951)
[node name="NavRoom" type="NavRoom" parent="."]
[node name="CoverMarker" parent="NavRoom" instance=ExtResource("5_ta2oq")]
@ -233,10 +244,10 @@ use_collision = true
size = Vector3(5.654, 10.5501, 2.79883)
[node name="CSGBox3D3" type="CSGBox3D" parent="WorldEnvironment/NavigationRegion3D/brushwork"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.87437, 5.23133, 4.5963)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.95075, 5.23133, 4.5963)
operation = 2
use_collision = true
size = Vector3(39.7404, 10.5501, 8.32035)
size = Vector3(39.8932, 10.5501, 8.32035)
[node name="NavigationObstacle3D" type="NavigationObstacle3D" parent="WorldEnvironment/NavigationRegion3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.008, 0)
@ -430,4 +441,18 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.0413, -7.63685e-07, 2.867
[node name="Tank4" parent="." instance=ExtResource("4_0o33v")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.4329, -7.63685e-07, 6.82909)
[node name="AreaTransfer" type="AreaTransfer" parent="."]
next_scene = "res://Levels/level_complete.tscn"
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -28.8374, -0.138102, 4.6354)
collision_layer = 4
collision_mask = 6
monitorable = false
[node name="CollisionShape3D" type="CollisionShape3D" parent="AreaTransfer"]
shape = SubResource("BoxShape3D_c8xhj")
[node name="MeshInstance3D" type="MeshInstance3D" parent="AreaTransfer"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.635551, 0)
mesh = SubResource("BoxMesh_mq8af")
[connection signal="finish_activate" from="WorldEnvironment/NavigationRegion3D/UtilityLock" to="WorldEnvironment/NavigationRegion3D/UtilityLock" method="_on_finish_activate"]

View file

@ -0,0 +1,3 @@
[gd_scene format=3 uid="uid://cljn3tou8pxjt"]
[node name="GameMode" type="GameMode"]

View file

@ -35,6 +35,11 @@ folder_colors={
"res://bin/": "gray"
}
[global_group]
player_unit=""
enemy_unit=""
[input]
lclick={

51
src/area_transfer.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "area_transfer.hpp"
#include "godot_cpp/classes/resource_loader.hpp"
#include "godot_cpp/classes/scene_tree.hpp"
#include "godot_cpp/variant/string.hpp"
#include "utils/game_root.hpp"
#include "utils/godot_macros.hpp"
void AreaTransfer::_bind_methods() {
#define CLASSNAME AreaTransfer
GDPROPERTY_HINTED(next_scene, gd::Variant::STRING, gd::PROPERTY_HINT_FILE, "*.tscn,*.scn");
}
void AreaTransfer::_ready() {
this->connect("body_entered", callable_mp(this, &self_type::_on_body_entered));
this->connect("body_exited", callable_mp(this, &self_type::_on_body_exited));
}
void AreaTransfer::_on_body_entered(gd::Node3D *body) {
if(CharacterUnit *character{gd::Object::cast_to<CharacterUnit>(body)}) {
this->ready_units.insert(character);
}
this->check_all_ready();
}
void AreaTransfer::_on_body_exited(gd::Node3D *body) {
CharacterUnit *unit{gd::Object::cast_to<CharacterUnit>(body)};
if(unit && this->ready_units.has(unit)) {
this->ready_units.erase(unit);
}
}
void AreaTransfer::check_all_ready() {
gd::TypedArray<gd::Node> units = this->get_tree()->get_nodes_in_group("player_unit");
for(int i{0}; i < units.size(); ++i) {
CharacterUnit *unit{gd::Object::cast_to<CharacterUnit>(units[i])};
if(unit && unit->get_entity_health()->is_conscious() && !this->ready_units.has(unit)) {
return; // fail
}
}
// no missing units found, switch scenes
gd::Ref<gd::PackedScene> level{gd::ResourceLoader::get_singleton()->load(this->next_scene)};
utils::GameRoot3D::get_singleton()->replace_levels(level);
}
void AreaTransfer::set_next_scene(gd::String path) {
this->next_scene = path;
}
gd::String AreaTransfer::get_next_scene() const {
return this->next_scene;
}

25
src/area_transfer.hpp Normal file
View file

@ -0,0 +1,25 @@
#ifndef AREA_TRANSFER_HPP
#define AREA_TRANSFER_HPP
#include "character_unit.hpp"
#include <godot_cpp/templates/hash_set.hpp>
#include <godot_cpp/classes/area3d.hpp>
namespace gd = godot;
class AreaTransfer : public gd::Area3D {
GDCLASS(AreaTransfer, gd::Area3D);
static void _bind_methods();
public:
virtual void _ready() override;
void _on_body_entered(gd::Node3D *body);
void _on_body_exited(gd::Node3D *body);
void check_all_ready();
void set_next_scene(gd::String path);
gd::String get_next_scene() const;
private:
gd::String next_scene{};
gd::HashSet<CharacterUnit *> ready_units{};
};
#endif // !AREA_TRANSFER_HPP

View file

@ -1,4 +1,5 @@
#include "register_types.h"
#include "area_transfer.hpp"
#include "character_unit.hpp"
#include "character_world_state.hpp"
#include "enemy_world_state.hpp"
@ -75,6 +76,7 @@ void initialize_gdextension_types(gd::ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(Inventory);
GDREGISTER_RUNTIME_CLASS(RTSGameMode);
GDREGISTER_RUNTIME_CLASS(RTSPlayer);
GDREGISTER_RUNTIME_CLASS(AreaTransfer);
}
extern "C" {

View file

@ -113,12 +113,14 @@ void Unit::on_death(Unit *damage_source) {
void Unit::on_velocity_computed(gd::Vector3 vel) {
gd::Vector3 const pos{this->get_global_position()};
gd::Vector3 const flattened{vel.x, 0.f, vel.z};
if(vel.x == 0 && vel.z == 0) {
this->set_velocity({0.f, 0.f, 0.f});
return;
}
this->set_velocity(vel.normalized() * this->movement_speed);
this->look_at(pos - gd::Vector3{vel.x, 0.f, vel.z});
if(!flattened.is_zero_approx())
this->look_at(pos - flattened);
}
void Unit::destroy_state() {