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

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() {