#include "level_end.h" #include "break_utopia/level_status.h" #include "break_utopia/player_body.h" #include "core/config/engine.h" #include "core/error/error_macros.h" #include "core/input/input.h" #include "scene/main/scene_tree.h" void LevelResult::_bind_methods() { BIND_PROPERTY(Variant::INT, style); BIND_PROPERTY(Variant::INT, score); BIND_PROPERTY(Variant::INT, destroyed); BIND_PROPERTY(Variant::INT, total_objects); BIND_HPROPERTY(Variant::OBJECT, next_level, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); } void LevelResult::store_current_state() { ERR_FAIL_COND_EDMSG(!LevelStatus::get_instance(), "attempt to store current level status with no extant instance"); LevelStatus *status{ LevelStatus::get_instance() }; this->style = (int)Math::floor(status->get_style()); this->score = status->get_score(); this->total_objects = status->get_total_objects(); this->destroyed = status->get_destroyed_objects(); } void LevelEnd::_bind_methods() { BIND_HPROPERTY(Variant::OBJECT, intermission_screen, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); BIND_HPROPERTY(Variant::OBJECT, next_level, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"); } void LevelEnd::body_entered(Node *body) { if (cast_to(body) != nullptr) { Node *scene{ this->intermission_screen->instantiate() }; Ref result{ memnew(LevelResult) }; result->store_current_state(); result->set_next_level(this->next_level); if (IntermissionScreen * intermission{ cast_to(scene->get_node(NodePath("%IntermissionScreen"))) }) { intermission->set_result(result); } callable_mp(get_tree(), &SceneTree::change_scene_to_node).call_deferred(scene); } } void LevelEnd::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; } switch (what) { default: return; case NOTIFICATION_READY: connect("body_entered", callable_mp(this, &self_type::body_entered)); return; } } void IntermissionScreen::_bind_methods() { BIND_HPROPERTY(Variant::OBJECT, result, PROPERTY_HINT_RESOURCE_TYPE, "LevelResult"); ClassDB::bind_method(D_METHOD("next_level"), &self_type::next_level); } void IntermissionScreen::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; } switch (what) { default: return; case NOTIFICATION_ENTER_TREE: if (get_tree()->is_paused()) { get_tree()->set_pause(true); } return; case NOTIFICATION_READY: Input::get_singleton()->set_mouse_mode(Input::MouseMode::MOUSE_MODE_VISIBLE); return; } } void IntermissionScreen::next_level() { Ref scene{ this->result->get_next_level() }; ERR_FAIL_COND_EDMSG(!scene.is_valid(), "Level exit did not set a valid next level"); callable_mp(get_tree(), &SceneTree::change_scene_to_packed).call_deferred(scene); }